- Major internal refactor to use PE user object

Folia:
- Fix sometimes NPEing on Disconnect

Fabric:
- Fix default client brand
This commit is contained in:
Axionize committed 2025-03-17 05:42:32 -04:00
1 parent 715013d90f
commit 25411ba54f
15 files changed
+77 -76

No files matched your search

@@ -5,6 +5,7 @@ import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.player.User;
import com.github.retrooper.packetevents.protocol.world.BoundingBox;
import com.github.retrooper.packetevents.util.Vector3d;
import com.google.common.base.Preconditions;
import me.caseload.knockbacksync.BukkitBase;
import me.caseload.knockbacksync.Platform;
import me.caseload.knockbacksync.world.FoliaWorld;
@@ -25,6 +26,7 @@ import java.util.UUID;
public class BukkitPlayer implements PlatformPlayer {
public final Player bukkitPlayer;
public final User user;
private String clientBrand = "vanilla";
// Reflection variables
@@ -74,6 +76,8 @@ public class BukkitPlayer implements PlatformPlayer {
public BukkitPlayer(Player player) {
this.bukkitPlayer = player;
this.user = PacketEvents.getAPI().getPlayerManager().getUser(bukkitPlayer);
Preconditions.checkArgument(user != null);
}
@Override
@@ -216,7 +220,7 @@ public class BukkitPlayer implements PlatformPlayer {
@Override
public User getUser() {
return PacketEvents.getAPI().getPlayerManager().getUser(bukkitPlayer);
return this.user;
}
@Override
@@ -87,12 +87,12 @@ public class PingCommand implements BuilderCommand {
}
if (isSelf) {
playerData = PlayerDataManager.getPlayerData(senderUUID);
playerData = PlayerDataManager.getPlayerData(Base.INSTANCE.getPlatformServer().getPlayer(senderUUID).getUser());
if (playerData == null) {
return ChatUtil.translateAlternateColorCodes('&', knockbacksyncDisabledForYouMessage);
}
} else {
playerData = PlayerDataManager.getPlayerData(targetUUID);
playerData = PlayerDataManager.getPlayerData(Base.INSTANCE.getPlatformServer().getPlayer(targetUUID).getUser());
if (playerData == null) {
return ChatUtil.translateAlternateColorCodes('&', knockbacksyncDisabledForTargetMessage);
}
@@ -86,8 +86,7 @@ public class StatusCommand implements BuilderCommand {
private void showPlayerStatus(Sender sender, PlatformPlayer target) {
boolean globalStatus = configManager.isToggled();
UUID uuid = target.getUUID();
boolean playerStatus = PlayerDataManager.containsPlayerData(uuid);
boolean playerStatus = PlayerDataManager.containsPlayerData(target.getUser());
String statusMessage;
if (!globalStatus) {
@@ -1,5 +1,6 @@
package me.caseload.knockbacksync.command.subcommand;
import com.github.retrooper.packetevents.protocol.player.Combat;
import com.github.retrooper.packetevents.protocol.player.User;
import me.caseload.knockbacksync.Base;
import me.caseload.knockbacksync.ConfigWrapper;
import me.caseload.knockbacksync.command.generic.BuilderCommand;
@@ -115,9 +116,9 @@ public class ToggleCommand implements BuilderCommand {
}
private static void togglePlayerKnockback(PlatformPlayer target, ConfigManager configManager, Sender sender) {
UUID uuid = target.getUUID();
User user = target.getUser();
if (PlayerDataManager.shouldExempt(uuid)) {
if (PlayerDataManager.shouldExempt(target.getUUID())) {
String message = ChatUtil.translateAlternateColorCodes('&',
configManager.getPlayerIneligibleMessage()
).replace("%player%", target.getName());
@@ -126,14 +127,14 @@ public class ToggleCommand implements BuilderCommand {
return;
}
boolean hasPlayerData = PlayerDataManager.containsPlayerData(uuid);
boolean hasPlayerData = PlayerDataManager.containsPlayerData(user);
if (hasPlayerData) {
if (CombatManager.getPlayers().contains(uuid)) {
CombatManager.removePlayer(uuid);
if (CombatManager.getPlayers().contains(user)) {
CombatManager.removePlayer(user);
}
PlayerDataManager.removePlayerData(uuid);
PlayerDataManager.removePlayerData(user);
} else {
PlayerDataManager.addPlayerData(uuid, new PlayerData(Base.INSTANCE.getPlatformServer().getPlayer(uuid)));
PlayerDataManager.addPlayerData(user, target);
}
String message = ChatUtil.translateAlternateColorCodes('&',
@@ -10,7 +10,7 @@ public abstract class PlayerDamageListener {
if (!Base.INSTANCE.getConfigManager().isToggled())
return;
PlayerData playerData = PlayerDataManager.getPlayerData(victim.getUUID());
PlayerData playerData = PlayerDataManager.getPlayerData(victim.getUser());
if (playerData == null)
return;
@@ -14,7 +14,7 @@ public abstract class PlayerKnockbackListener {
if (!Base.INSTANCE.getConfigManager().isToggled())
return;
PlayerData victimPlayerData = PlayerDataManager.getPlayerData(victim.getUUID());
PlayerData victimPlayerData = PlayerDataManager.getPlayerData(victim.getUser());
if (victimPlayerData == null)
return;
@@ -5,6 +5,7 @@ import com.github.retrooper.packetevents.event.PacketSendEvent;
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.player.User;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateAttributes;
import me.caseload.knockbacksync.Base;
import me.caseload.knockbacksync.manager.PlayerDataManager;
@@ -36,17 +37,16 @@ public class AttributeChangeListener extends PacketListenerAbstract {
WrapperPlayServerUpdateAttributes packet = new WrapperPlayServerUpdateAttributes(event);
UUID uuid = event.getUser().getUUID();
if (!PlayerDataManager.containsPlayerData(uuid))
return;
User user = event.getUser();
if (!PlayerDataManager.containsPlayerData(user)) return;
// Get the attributes from the packet
for (WrapperPlayServerUpdateAttributes.Property property : packet.getProperties()) {
// You can now check for specific attributes
if (property.getAttribute().equals(Attributes.GENERIC_GRAVITY)) {
onPlayerGravityChange(uuid, calculateValueWithModifiers(property));
onPlayerGravityChange(user, calculateValueWithModifiers(property));
} else if (property.getAttribute().equals(Attributes.GENERIC_KNOCKBACK_RESISTANCE)) {
onPlayerKnockBackChange(uuid, calculateValueWithModifiers(property));
onPlayerKnockBackChange(user, calculateValueWithModifiers(property));
}
}
}
@@ -87,8 +87,8 @@ public class AttributeChangeListener extends PacketListenerAbstract {
// Yes this is not properly latency compensated, that would require including a proper simulation engine
// Laggy players will just have to deal with being on the wrong gravity for a few hundred ms, too bad!
public void onPlayerGravityChange(UUID uuid, double newGravity) {
PlayerData playerData = PlayerDataManager.getPlayerData(uuid);
public void onPlayerGravityChange(User user, double newGravity) {
PlayerData playerData = PlayerDataManager.getPlayerData(user);
if (playerData.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_20_5)) {
playerData.setGravityAttribute(newGravity);
} else {
@@ -96,8 +96,8 @@ public class AttributeChangeListener extends PacketListenerAbstract {
}
}
private void onPlayerKnockBackChange(UUID uuid, double newKnockbackResistance) {
PlayerData playerData = PlayerDataManager.getPlayerData(uuid);
private void onPlayerKnockBackChange(User user, double newKnockbackResistance) {
PlayerData playerData = PlayerDataManager.getPlayerData(user);
playerData.setKnockbackResistanceAttribute(newKnockbackResistance);
}
}
@@ -3,6 +3,7 @@ package me.caseload.knockbacksync.listener.packetevents;
import com.github.retrooper.packetevents.event.PacketListenerAbstract;
import com.github.retrooper.packetevents.event.UserDisconnectEvent;
import com.github.retrooper.packetevents.event.UserLoginEvent;
import com.github.retrooper.packetevents.protocol.player.User;
import com.google.common.base.Preconditions;
import me.caseload.knockbacksync.Base;
import me.caseload.knockbacksync.manager.PlayerDataManager;
@@ -10,6 +11,7 @@ import me.caseload.knockbacksync.player.PlatformPlayer;
import me.caseload.knockbacksync.player.PlayerData;
import me.caseload.knockbacksync.util.ChatUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.UUID;
@@ -20,31 +22,30 @@ public class PacketPlayerJoinQuit extends PacketListenerAbstract {
Preconditions.checkArgument(nativePlayerObject != null);
@NotNull PlatformPlayer platformPlayer = Base.INSTANCE.getPlatformServer().getPlayer(nativePlayerObject);
onPlayerJoin(new PlayerData(platformPlayer));
onPlayerJoin(event.getUser(), platformPlayer);
}
@Override
public void onUserDisconnect(UserDisconnectEvent event) {
onPlayerQuit(event.getUser().getUUID());
onPlayerQuit(event.getUser());
}
public void onPlayerJoin(PlayerData player) {
PlayerDataManager.addPlayerData(player.getUuid(), player);
PlatformPlayer platformPlayer = player.getPlatformPlayer();
public void onPlayerJoin(User user, PlatformPlayer player) {
PlayerDataManager.addPlayerData(user, player);
if (Base.INSTANCE.getConfigManager().isUpdateAvailable() && Base.INSTANCE.getConfigManager().isNotifyUpdate() && Base.INSTANCE.getPermissionChecker().hasPermission(platformPlayer, "knockbacksync.update"))
platformPlayer.sendMessage(ChatUtil.translateAlternateColorCodes(
if (Base.INSTANCE.getConfigManager().isUpdateAvailable() && Base.INSTANCE.getConfigManager().isNotifyUpdate() && Base.INSTANCE.getPermissionChecker().hasPermission(player, "knockbacksync.update"))
player.sendMessage(ChatUtil.translateAlternateColorCodes(
'&',
"&6An updated version of &eKnockbackSync &6is now available for download at: &bhttps://github.com/CASELOAD7000/knockback-sync/releases/latest"
));
}
public void onPlayerQuit(UUID uuid) {
PlayerData playerData = PlayerDataManager.getPlayerData(uuid);
public void onPlayerQuit(@NotNull User user) {
PlayerData playerData = PlayerDataManager.getPlayerData(user);
if (playerData == null)
return;
playerData.quitCombat(true);
PlayerDataManager.removePlayerData(uuid);
PlayerDataManager.removePlayerData(user);
}
}
@@ -3,6 +3,7 @@ package me.caseload.knockbacksync.listener.packetevents;
import com.github.retrooper.packetevents.event.*;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.protocol.packettype.PacketTypeCommon;
import com.github.retrooper.packetevents.protocol.player.User;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientKeepAlive;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPong;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientWindowConfirmation;
@@ -27,9 +28,9 @@ public class PingReceiveListener extends PacketListenerAbstract {
// And then receive a response we have to ensure that if the packet was sent by us we cancel it
// otherwise the server will likely kick the player
PacketTypeCommon packetType = event.getPacketType();
UUID playerUUID = event.getUser().getUUID();
if (playerUUID == null) return;
PlayerData playerData = PlayerDataManager.getPlayerData(playerUUID);
User user = event.getUser();
if (user == null) return;
PlayerData playerData = PlayerDataManager.getPlayerData(user);
if (playerData == null) return;
if (playerData.pingStrategy == PingStrategy.KEEPALIVE && packetType == PacketType.Play.Client.KEEP_ALIVE) {
@@ -33,7 +33,7 @@ public class PingSendListener extends PacketListenerAbstract {
PacketTypeCommon packetType = event.getPacketType();
UUID playerUUID = event.getUser().getUUID();
if (playerUUID == null) return;
PlayerData playerData = PlayerDataManager.getPlayerData(playerUUID);
PlayerData playerData = PlayerDataManager.getPlayerData(event.getUser());
if (playerData == null) return;
if (playerData.pingStrategy == PingStrategy.KEEPALIVE && packetType.equals(PacketType.Play.Server.KEEP_ALIVE)) {
@@ -1,5 +1,6 @@
package me.caseload.knockbacksync.manager;
import com.github.retrooper.packetevents.protocol.player.User;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
@@ -8,17 +9,17 @@ import java.util.concurrent.ConcurrentHashMap;
public class CombatManager {
private static final Set<@NotNull UUID> combatPlayers = ConcurrentHashMap.newKeySet();
private static final Set<@NotNull User> combatPlayers = ConcurrentHashMap.newKeySet();
public static @NotNull Set<@NotNull UUID> getPlayers() {
public static @NotNull Set<@NotNull User> getPlayers() {
return combatPlayers;
}
public static void addPlayer(@NotNull UUID uuid) {
combatPlayers.add(uuid);
public static void addPlayer(@NotNull User user) {
combatPlayers.add(user);
}
public static void removePlayer(@NotNull UUID uuid) {
combatPlayers.remove(uuid);
public static void removePlayer(@NotNull User user) {
combatPlayers.remove(user);
}
}
@@ -1,6 +1,8 @@
package me.caseload.knockbacksync.manager;
import com.github.retrooper.packetevents.protocol.player.User;
import me.caseload.knockbacksync.Base;
import me.caseload.knockbacksync.player.PlatformPlayer;
import me.caseload.knockbacksync.player.PlayerData;
import me.caseload.knockbacksync.util.FloodgateUtil;
import me.caseload.knockbacksync.util.GeyserUtil;
@@ -12,27 +14,28 @@ import java.util.concurrent.ConcurrentHashMap;
public class PlayerDataManager {
private static final Map<UUID, PlayerData> playerDataMap = new ConcurrentHashMap<>();
private static final Map<User, PlayerData> playerDataMap = new ConcurrentHashMap<>();
public static PlayerData getPlayerData(@NotNull UUID uuid) {
return playerDataMap.get(uuid);
public static PlayerData getPlayerData(@NotNull User user) {
return playerDataMap.get(user);
}
public static void addPlayerData(@NotNull UUID uuid, @NotNull PlayerData playerData) {
if (!shouldExempt(uuid)) {
playerDataMap.put(uuid, playerData);
public static void addPlayerData(@NotNull User user, @NotNull PlatformPlayer platformPlayer) {
if (!shouldExempt(platformPlayer.getUUID())) {
PlayerData playerData = new PlayerData(user, platformPlayer);
playerDataMap.put(user, playerData);
Base.INSTANCE.getEventBus().registerListeners(playerData);
}
}
public static void removePlayerData(@NotNull UUID uuid) {
PlayerData playerData = playerDataMap.remove(uuid);
public static void removePlayerData(@NotNull User user) {
PlayerData playerData = playerDataMap.remove(user);
if (playerData != null)
Base.INSTANCE.getEventBus().unregisterListeners(playerData);
}
public static boolean containsPlayerData(@NotNull UUID uuid) {
return playerDataMap.containsKey(uuid);
public static boolean containsPlayerData(@NotNull User user) {
return playerDataMap.containsKey(user);
}
public static boolean shouldExempt(@NotNull UUID uuid) {
@@ -88,25 +88,10 @@ public class PlayerData {
@Setter private double knockbackResistanceAttribute = 0.0;
public PingStrategy pingStrategy; // this is currently shared between all instances, but can be made per-player later
public PlayerData(PlatformPlayer platformPlayer) {
public PlayerData(User user, PlatformPlayer platformPlayer) {
this.uuid = platformPlayer.getUUID();
this.user = user;
this.platformPlayer = platformPlayer;
User tempUser = null;
PlayerManager playerManager = PacketEvents.getAPI().getPlayerManager();
Object player = null;
try {
player = playerField.get(platformPlayer);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
if (player != null) {
tempUser = playerManager.getUser(player);
}
this.user = tempUser;
this.pingStrategy = loadPingStrategy(Base.INSTANCE.getConfigManager());
}
@@ -303,7 +288,7 @@ public class PlayerData {
combatTask.cancel();
}
combatTask = newCombatTask(channel);
CombatManager.addPlayer(uuid);
CombatManager.addPlayer(user);
});
}
@@ -319,7 +304,7 @@ public class PlayerData {
combatTask.cancel();
combatTask = null;
}
CombatManager.removePlayer(uuid);
CombatManager.removePlayer(user);
};
if (async) {
channel.eventLoop().execute(runnable);
@@ -1,5 +1,6 @@
package me.caseload.knockbacksync.runnable;
import com.github.retrooper.packetevents.protocol.player.User;
import me.caseload.knockbacksync.Base;
import me.caseload.knockbacksync.manager.CombatManager;
import me.caseload.knockbacksync.manager.PlayerDataManager;
@@ -14,8 +15,8 @@ public class PingRunnable implements Runnable {
if (!Base.INSTANCE.getConfigManager().isToggled())
return;
for (UUID uuid : CombatManager.getPlayers()) {
PlayerData playerData = PlayerDataManager.getPlayerData(uuid);
for (User user : CombatManager.getPlayers()) {
PlayerData playerData = PlayerDataManager.getPlayerData(user);
playerData.sendPing(true);
}
}
@@ -7,6 +7,8 @@ import com.github.retrooper.packetevents.protocol.world.Location;
import com.github.retrooper.packetevents.util.Vector3d;
import me.caseload.knockbacksync.world.FabricWorld;
import me.caseload.knockbacksync.world.PlatformWorld;
import net.fabricmc.fabric.api.entity.event.v1.ServerPlayerEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerEntityEvents;
import net.minecraft.core.Holder;
import net.minecraft.core.registries.Registries;
import net.minecraft.data.registries.VanillaRegistries;
@@ -27,10 +29,13 @@ import java.util.UUID;
public class FabricPlayer implements PlatformPlayer {
public final ServerPlayer fabricPlayer;
private String clientBrand = "fabric";
public final User user;
private String clientBrand = "vanilla";
public FabricPlayer(ServerPlayer player) {
this.fabricPlayer = player;
this.user = PacketEvents.getAPI().getPlayerManager().getUser(fabricPlayer);
}
@Override
@@ -157,7 +162,7 @@ public class FabricPlayer implements PlatformPlayer {
@Override
public User getUser() {
return PacketEvents.getAPI().getPlayerManager().getUser(fabricPlayer);
return user;
}
@Override