Incorrect AutoSyncComponent
Sam-Chai opened this issue · 1 comments
I write a interface that improve players balance and count if player is first join the server.
And I also wrote a GUI that mixin InventoryScreen.class improve a text component to show player's balance.
The problem is, when I first started Minecraft Client then join the server immediately, in player inventory screen player balance shows zero dollars, but in fact when I use a command to get server sides, then back me 100$. In fact this player have 100$ in playerdata.
And I restart the games, and now I join to a singleplayer, they run very perfectly. THE WEIRED THINGS is this:
I exit the singleplayer, and rejoin the multiplayer server, then the client side can sync 100$ to player's screen. And I try to modify player‘s balance, but everything sync perfectly.
Also, when I dead in server, and respawn the player, then everything can sync perfectly.
This is what confuses me, the unsync issue only happends on when I first join the server. When I exit and rejoin or dead on server, then everything comes back.
Below is my classes:
- This is IPlayerEcoData interface
public interface IPlayerEcoData extends PlayerComponent {
Double getMoney();
Boolean getIsFirstJoin();
void setMoney(Double money);
void setIsFirstJoin(Boolean isFirstJoin);
}
- And this is Player Eco Data class:
public class PlayerEcoData implements IPlayerEcoData, AutoSyncedComponent {
private final Player provider;
private Double playerMoney;
private Boolean playerIsFirstJoin = true;
public PlayerEcoData(Player provider) {
this.provider = provider;
}
@Override
public Double getMoney() {
if (playerMoney == null) {
return 0.00;
}
return playerMoney;
}
@Override
public Boolean getIsFirstJoin() {
return playerIsFirstJoin;
}
@Override
public void setMoney(Double money) {
this.playerMoney = money;
CapabilityRegister.PLAYER_DATA.sync(this.provider);
}
@Override
public void setIsFirstJoin(Boolean isFirstJoin) {
this.playerIsFirstJoin = isFirstJoin;
CapabilityRegister.PLAYER_DATA.sync(this.provider);
}
@Override
public void readFromNbt(CompoundTag tag) {
playerMoney = tag.getDouble("money");
playerIsFirstJoin = tag.getBoolean("isFirstJoin");
}
@Override
public void writeToNbt(CompoundTag tag) {
if (playerMoney == null) {
playerMoney = 0.00;
}
tag.putDouble("money", playerMoney);
tag.putBoolean("isFirstJoin", playerIsFirstJoin);
}
}
- This is Registry:
public class CapabilityRegister implements EntityComponentInitializer {
public static final ComponentKey<IPlayerEcoData> PLAYER_DATA = ComponentRegistry.getOrCreate(new ResourceLocation(Economic.MODID, "player_eco_data"), IPlayerEcoData.class);
@Override
public void registerEntityComponentFactories(EntityComponentFactoryRegistry registry) {
registry.registerForPlayers(PLAYER_DATA, PlayerEcoData::new, RespawnCopyStrategy.ALWAYS_COPY);
}
}
- And this is my client side mixin to show player's balance:
@Environment(EnvType.CLIENT)
public class PlayerBalanceComponent {
public static void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float delta) {
Minecraft mc = Minecraft.getInstance();
String balance = "Balance: " + CapabilityRegister.PLAYER_DATA.get(mc.player).getMoney();
guiGraphics.drawString(mc.font, balance, guiGraphics.guiWidth() / 2 - mc.font.width(balance) / 2, 10, 0xFFFFFF);
}
}
I don't know where is wrong. Everything follow CCA doc and testmods.
Since your target interface does not directly implement AutoSyncedComponent
, you need to tell the library about it yourself.
see the relevant wiki entry: https://ladysnake.org/wiki/cardinal-components-api/synchronization#a-note-on-registration