@@ -21,7 +21,7 @@ import net.minecraft.nbt.Tag;
2121 </#if >
2222
2323 <#if w.hasVariablesOfScope("PLAYER_LIFETIME") || w.hasVariablesOfScope("PLAYER_PERSISTENT") >
24- ${JavaModName} .addNetworkMessage(PlayerVariablesSyncMessage.class, PlayerVariablesSyncMessage::buffer, PlayerVariablesSyncMessage::new, PlayerVariablesSyncMessage::handler );
24+ ${JavaModName} .addNetworkMessage(PlayerVariablesSyncMessage.class, PlayerVariablesSyncMessage::buffer, PlayerVariablesSyncMessage::new, PlayerVariablesSyncMessage::handleData );
2525 </#if >
2626 }
2727
@@ -31,64 +31,86 @@ import net.minecraft.nbt.Tag;
3131 }
3232 </#if >
3333
34- <#if w.hasVariablesOfScope("PLAYER_LIFETIME") || w.hasVariablesOfScope("PLAYER_PERSISTENT") || w.hasVariablesOfScope("GLOBAL_WORLD") || w.hasVariablesOfScope("GLOBAL_MAP") >
35- @Mod.EventBusSubscriber public static class EventBusVariableHandlers {
36-
34+ <#if w.hasVariablesOfScope("GLOBAL_WORLD") || w.hasVariablesOfScope("GLOBAL_MAP") || w.hasVariablesOfScope("PLAYER_LIFETIME") || w.hasVariablesOfScope("PLAYER_PERSISTENT") >
35+ @Mod.EventBusSubscriber public static class EventBusVariableHandlers {
3736 <#if w.hasVariablesOfScope("PLAYER_LIFETIME") || w.hasVariablesOfScope("PLAYER_PERSISTENT") >
38- @SubscribeEvent public static void onPlayerLoggedInSyncPlayerVariables(PlayerEvent.PlayerLoggedInEvent event) {
39- if (!event.getEntity().level().isClientSide())
40- ((PlayerVariables) event.getEntity().getCapability(PLAYER_VARIABLES_CAPABILITY, null).orElseGet(PlayerVariables::new)).syncPlayerVariables(event.getEntity());
41- }
42-
43- @SubscribeEvent public static void onPlayerRespawnedSyncPlayerVariables(PlayerEvent.PlayerRespawnEvent event) {
44- if (!event.getEntity().level().isClientSide())
45- ((PlayerVariables) event.getEntity().getCapability(PLAYER_VARIABLES_CAPABILITY, null).orElseGet(PlayerVariables::new)).syncPlayerVariables(event.getEntity());
46- }
47-
48- @SubscribeEvent public static void onPlayerChangedDimensionSyncPlayerVariables(PlayerEvent.PlayerChangedDimensionEvent event) {
49- if (!event.getEntity().level().isClientSide())
50- ((PlayerVariables) event.getEntity().getCapability(PLAYER_VARIABLES_CAPABILITY, null).orElseGet(PlayerVariables::new)).syncPlayerVariables(event.getEntity());
51- }
52-
53- @SubscribeEvent public static void clonePlayer(PlayerEvent.Clone event) {
37+ @SubscribeEvent public static void onPlayerLoggedInSyncPlayerVariables(PlayerEvent.PlayerLoggedInEvent event) {
38+ if (event.getEntity() instanceof ServerPlayer player)
39+ ${JavaModName} .PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> player), new PlayerVariablesSyncMessage(player.getCapability(PLAYER_VARIABLES).orElseGet(() -> null)));
40+ }
41+
42+ @SubscribeEvent public static void onPlayerRespawnedSyncPlayerVariables(PlayerEvent.PlayerRespawnEvent event) {
43+ if (event.getEntity() instanceof ServerPlayer player)
44+ ${JavaModName} .PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> player), new PlayerVariablesSyncMessage(player.getCapability(PLAYER_VARIABLES).orElseGet(() -> null)));
45+ }
46+
47+ @SubscribeEvent public static void onPlayerChangedDimensionSyncPlayerVariables(PlayerEvent.PlayerChangedDimensionEvent event) {
48+ if (event.getEntity() instanceof ServerPlayer player)
49+ ${JavaModName} .PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> player), new PlayerVariablesSyncMessage(player.getCapability(PLAYER_VARIABLES).orElseGet(() -> null)));
50+ }
51+
52+ @SubscribeEvent public static void onPlayerTickUpdateSyncPlayerVariables(TickEvent.PlayerTickEvent event) {
53+ if (event.phase == TickEvent.Phase.END && event.player instanceof ServerPlayer player && player.getCapability(PLAYER_VARIABLES).orElseGet(PlayerVariables::new)._syncDirty) {
54+ ${JavaModName} .PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> player), new PlayerVariablesSyncMessage(player.getCapability(PLAYER_VARIABLES).orElseGet(() -> null)));
55+ player.getCapability(PLAYER_VARIABLES).ifPresent(capability -> capability._syncDirty = false);
56+ }
57+ }
58+
59+ @SubscribeEvent public static void clonePlayer(PlayerEvent.Clone event) {
5460 event.getOriginal().revive();
5561
56- PlayerVariables original = ((PlayerVariables) event.getOriginal().getCapability(PLAYER_VARIABLES_CAPABILITY, null).orElseGet(PlayerVariables::new));
57- PlayerVariables clone = ((PlayerVariables) event.getEntity().getCapability(PLAYER_VARIABLES_CAPABILITY, null).orElseGet(PlayerVariables::new));
58- <#list variables as var >
59- <#if var.getScope().name() == "PLAYER_PERSISTENT" >
60- clone.${var.getName()} = original.${var.getName()} ;
61- </#if >
62- </#list >
63- if(!event.isWasDeath()) {
64- <#list variables as var >
65- <#if var.getScope().name() == "PLAYER_LIFETIME" >
66- clone.${var.getName()} = original.${var.getName()} ;
67- </#if >
68- </#list >
69- }
70- }
71- </#if >
72-
73- <#if w.hasVariablesOfScope("GLOBAL_WORLD") || w.hasVariablesOfScope("GLOBAL_MAP") >
74- @SubscribeEvent public static void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) {
75- if (!event.getEntity().level().isClientSide()) {
76- SavedData mapdata = MapVariables.get(event.getEntity().level());
77- SavedData worlddata = WorldVariables.get(event.getEntity().level());
78- if(mapdata != null)
79- ${JavaModName} .PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) event.getEntity()), new SavedDataSyncMessage(0, mapdata));
80- if(worlddata != null)
81- ${JavaModName} .PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) event.getEntity()), new SavedDataSyncMessage(1, worlddata));
82- }
83- }
84-
85- @SubscribeEvent public static void onPlayerChangedDimension(PlayerEvent.PlayerChangedDimensionEvent event) {
86- if (!event.getEntity().level().isClientSide()) {
87- SavedData worlddata = WorldVariables.get(event.getEntity().level());
88- if(worlddata != null)
89- ${JavaModName} .PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) event.getEntity()), new SavedDataSyncMessage(1, worlddata));
90- }
91- }
62+ PlayerVariables original = event.getOriginal().getCapability(PLAYER_VARIABLES).orElseGet(PlayerVariables::new);
63+ PlayerVariables clone = event.getEntity().getCapability(PLAYER_VARIABLES).orElseGet(PlayerVariables::new);
64+ <#list variables as var >
65+ <#if var.getScope().name() == "PLAYER_PERSISTENT" >
66+ clone.${var.getName()} = original.${var.getName()} ;
67+ </#if >
68+ </#list >
69+ if(!event.isWasDeath()) {
70+ <#list variables as var >
71+ <#if var.getScope().name() == "PLAYER_LIFETIME" >
72+ clone.${var.getName()} = original.${var.getName()} ;
73+ </#if >
74+ </#list >
75+ }
76+ }
77+ </#if >
78+
79+ <#if w.hasVariablesOfScope("GLOBAL_WORLD") || w.hasVariablesOfScope("GLOBAL_MAP") >
80+ @SubscribeEvent public static void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) {
81+ if (event.getEntity() instanceof ServerPlayer player) {
82+ SavedData mapdata = MapVariables.get(event.getEntity().level());
83+ SavedData worlddata = WorldVariables.get(event.getEntity().level());
84+ if(mapdata != null)
85+ ${JavaModName} .PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> player), new SavedDataSyncMessage(0, mapdata));
86+ if(worlddata != null)
87+ ${JavaModName} .PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> player), new SavedDataSyncMessage(1, worlddata));
88+ }
89+ }
90+
91+ @SubscribeEvent public static void onPlayerChangedDimension(PlayerEvent.PlayerChangedDimensionEvent event) {
92+ if (event.getEntity() instanceof ServerPlayer player) {
93+ SavedData worlddata = WorldVariables.get(event.getEntity().level());
94+ if(worlddata != null)
95+ ${JavaModName} .PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> player), new SavedDataSyncMessage(1, worlddata));
96+ }
97+ }
98+
99+ @SubscribeEvent public static void onWorldTick(TickEvent.LevelTickEvent event) {
100+ if (event.phase == TickEvent.Phase.END && event.level instanceof ServerLevel level) {
101+ WorldVariables worldVariables = WorldVariables.get(level);
102+ if (worldVariables._syncDirty) {
103+ ${JavaModName} .PACKET_HANDLER.send(PacketDistributor.DIMENSION.with(level::dimension), new SavedDataSyncMessage(1, worldVariables));
104+ worldVariables._syncDirty = false;
105+ }
106+
107+ MapVariables mapVariables = MapVariables.get(level);
108+ if (mapVariables._syncDirty) {
109+ ${JavaModName} .PACKET_HANDLER.send(PacketDistributor.ALL.noArg(), new SavedDataSyncMessage(0, mapVariables));
110+ mapVariables._syncDirty = false;
111+ }
112+ }
113+ }
92114 </#if >
93115 }
94116 </#if >
@@ -98,6 +120,8 @@ import net.minecraft.nbt.Tag;
98120
99121 public static final String DATA_NAME = "${modid} _worldvars";
100122
123+ boolean _syncDirty = false;
124+
101125 <#list variables as var >
102126 <#if var.getScope().name() == "GLOBAL_WORLD" >
103127 <@var.getType().getScopeDefinition(generator.getWorkspace(), "GLOBAL_WORLD")['init']?interpret/>
@@ -127,11 +151,9 @@ import net.minecraft.nbt.Tag;
127151 return nbt;
128152 }
129153
130- public void syncData(LevelAccessor world ) {
154+ public void markSyncDirty( ) {
131155 this.setDirty();
132-
133- if (world instanceof Level level && !level.isClientSide())
134- ${JavaModName} .PACKET_HANDLER.send(PacketDistributor.DIMENSION.with(level::dimension), new SavedDataSyncMessage(1, this));
156+ this._syncDirty = true;
135157 }
136158
137159 static WorldVariables clientSide = new WorldVariables();
@@ -143,13 +165,14 @@ import net.minecraft.nbt.Tag;
143165 return clientSide;
144166 }
145167 }
146-
147168 }
148169
149170 public static class MapVariables extends SavedData {
150171
151172 public static final String DATA_NAME = "${modid} _mapvars";
152173
174+ boolean _syncDirty = false;
175+
153176 <#list variables as var >
154177 <#if var.getScope().name() == "GLOBAL_MAP" >
155178 <@var.getType().getScopeDefinition(generator.getWorkspace(), "GLOBAL_MAP")['init']?interpret/>
@@ -179,11 +202,9 @@ import net.minecraft.nbt.Tag;
179202 return nbt;
180203 }
181204
182- public void syncData(LevelAccessor world ) {
205+ public void markSyncDirty( ) {
183206 this.setDirty();
184-
185- if (world instanceof Level && !world.isClientSide())
186- ${JavaModName} .PACKET_HANDLER.send(PacketDistributor.ALL.noArg(), new SavedDataSyncMessage(0, this));
207+ _syncDirty = true;
187208 }
188209
189210 static MapVariables clientSide = new MapVariables();
@@ -245,34 +266,33 @@ import net.minecraft.nbt.Tag;
245266 </#if >
246267
247268 <#if w.hasVariablesOfScope("PLAYER_LIFETIME") || w.hasVariablesOfScope("PLAYER_PERSISTENT") >
248- public static final Capability<PlayerVariables > PLAYER_VARIABLES_CAPABILITY = CapabilityManager.get(new CapabilityToken<PlayerVariables >() {});
249-
250- @Mod.EventBusSubscriber private static class PlayerVariablesProvider implements ICapabilitySerializable<Tag > {
269+ public static final Capability<PlayerVariables > PLAYER_VARIABLES = CapabilityManager.get(new CapabilityToken<PlayerVariables >(){});
251270
271+ @Mod.EventBusSubscriber private static class PlayerVariablesProvider implements ICapabilitySerializable<CompoundTag > {
252272 @SubscribeEvent public static void onAttachCapabilities(AttachCapabilitiesEvent<Entity > event) {
253273 if (event.getObject() instanceof Player && !(event.getObject() instanceof FakePlayer))
254274 event.addCapability(ResourceLocation.fromNamespaceAndPath("${modid} ", "player_variables"), new PlayerVariablesProvider());
255275 }
256276
257277 private final PlayerVariables playerVariables = new PlayerVariables();
258-
259278 private final LazyOptional<PlayerVariables > instance = LazyOptional.of(() -> playerVariables);
260279
261280 @Override public <T > LazyOptional<T > getCapability(Capability<T > cap, Direction side) {
262- return cap == PLAYER_VARIABLES_CAPABILITY ? instance.cast() : LazyOptional.empty();
281+ return cap == PLAYER_VARIABLES ? instance.cast() : LazyOptional.empty();
263282 }
264283
265- @Override public Tag serializeNBT() {
266- return playerVariables.writeNBT ();
284+ @Override public CompoundTag serializeNBT() {
285+ return playerVariables.serializeNBT ();
267286 }
268287
269- @Override public void deserializeNBT(Tag nbt) {
270- playerVariables.readNBT (nbt);
288+ @Override public void deserializeNBT(CompoundTag nbt) {
289+ playerVariables.deserializeNBT (nbt);
271290 }
272-
273291 }
274292
275- public static class PlayerVariables {
293+ public static class PlayerVariables implements INBTSerializable<CompoundTag > {
294+
295+ boolean _syncDirty = false;
276296
277297 <#list variables as var >
278298 <#if var.getScope().name() == "PLAYER_LIFETIME" >
@@ -282,12 +302,7 @@ import net.minecraft.nbt.Tag;
282302 </#if >
283303 </#list >
284304
285- public void syncPlayerVariables(Entity entity) {
286- if (entity instanceof ServerPlayer serverPlayer)
287- ${JavaModName} .PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new PlayerVariablesSyncMessage(this));
288- }
289-
290- public Tag writeNBT() {
305+ @Override public CompoundTag serializeNBT() {
291306 CompoundTag nbt = new CompoundTag();
292307 <#list variables as var >
293308 <#if var.getScope().name() == "PLAYER_LIFETIME" >
@@ -299,8 +314,7 @@ import net.minecraft.nbt.Tag;
299314 return nbt;
300315 }
301316
302- public void readNBT(Tag tag) {
303- CompoundTag nbt = (CompoundTag) tag;
317+ @Override public void deserializeNBT(CompoundTag nbt) {
304318 <#list variables as var >
305319 <#if var.getScope().name() == "PLAYER_LIFETIME" >
306320 <@var.getType().getScopeDefinition(generator.getWorkspace(), "PLAYER_LIFETIME")['read']?interpret/>
@@ -310,43 +324,30 @@ import net.minecraft.nbt.Tag;
310324 </#list >
311325 }
312326
327+ public void markSyncDirty() {
328+ _syncDirty = true;
329+ }
313330 }
314331
315- public static class PlayerVariablesSyncMessage {
316-
317- private final PlayerVariables data;
318-
332+ public record PlayerVariablesSyncMessage(PlayerVariables data) {
319333 public PlayerVariablesSyncMessage(FriendlyByteBuf buffer) {
320- this.data = new PlayerVariables();
321- this.data.readNBT(buffer.readNbt());
322- }
323-
324- public PlayerVariablesSyncMessage(PlayerVariables data) {
325- this.data = data;
334+ this(new PlayerVariables());
335+ data.deserializeNBT(buffer.readNbt());
326336 }
327337
328338 public static void buffer(PlayerVariablesSyncMessage message, FriendlyByteBuf buffer) {
329- buffer.writeNbt((CompoundTag) message.data.writeNBT ());
339+ buffer.writeNbt(message.data().serializeNBT ());
330340 }
331341
332- public static void handler( PlayerVariablesSyncMessage message, Supplier<NetworkEvent .Context > contextSupplier) {
342+ public static void handleData(final PlayerVariablesSyncMessage message, final Supplier<NetworkEvent .Context > contextSupplier) {
333343 NetworkEvent.Context context = contextSupplier.get();
334344 context.enqueueWork(() -> {
335- if (!context.getDirection().getReceptionSide().isServer()) {
336- PlayerVariables variables = ((PlayerVariables) Minecraft.getInstance().player.getCapability(PLAYER_VARIABLES_CAPABILITY, null).orElseGet(PlayerVariables::new));
337- <#list variables as var >
338- <#if var.getScope().name() == "PLAYER_LIFETIME" || var.getScope().name() == "PLAYER_PERSISTENT" >
339- variables.${var.getName()} = message.data.${var.getName()} ;
340- </#if >
341- </#list >
342- }
345+ if (!context.getDirection().getReceptionSide().isServer() && message.data != null)
346+ Minecraft.getInstance().player.getCapability(PLAYER_VARIABLES).ifPresent(cap -> cap.deserializeNBT(message.data.serializeNBT()));
343347 });
344348 context.setPacketHandled(true);
345349 }
346-
347350 }
348-
349351 </#if >
350-
351352}
352353<#-- @formatter:on -->
0 commit comments