Skip to content

Commit

Permalink
Add SyncableData And SyncableData$Registry
Browse files Browse the repository at this point in the history
Breaking Changes: Remove LivingEntityNetworkingEvents And ClientLivingEntityNetworkingEvents
Add TrackedDataHandlerUtils#createTrackedDataMapHandler
Add MModdingPackets#SYNCABLE_DATA
Change CommonOperations And ClientOperations
Add EntitySyncableDataRegistry
Change IdentifierUtils
Add ObjectUtils
  • Loading branch information
FirstMegaGame4 committed Sep 30, 2023
1 parent 5b11f80 commit 89a6554
Show file tree
Hide file tree
Showing 18 changed files with 183 additions and 162 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.mmodding.mmodding_lib.networking.MModdingPackets;
import com.mmodding.mmodding_lib.networking.client.ClientOperations;
import net.minecraft.entity.Entity;
import org.jetbrains.annotations.ApiStatus;
import org.quiltmc.loader.api.minecraft.ClientOnly;
import org.quiltmc.qsl.networking.api.client.ClientPlayNetworking;
Expand All @@ -11,7 +12,17 @@
public class ClientPacketReceivers {

public static void register() {
ClientPlayNetworking.registerGlobalReceiver(MModdingPackets.LIVING_ENTITY_STUCK_ARROW_TYPES, (((client, handler, buf, sender) -> ClientOperations.receiveLivingEntityStuckArrowTypesToClient(client, buf))));

// Syncable Data Elements Networking
ClientPlayNetworking.registerGlobalReceiver(MModdingPackets.SYNCABLE_DATA, (((client, handler, buf, sender) -> {
int entityId = buf.readVarInt();
assert client.world != null;
Entity entity = client.world.getEntityById(entityId);
assert entity != null;
entity.getSyncableDataRegistry().accept(buf);
})));

// Client Operations Networking
ClientPlayNetworking.registerGlobalReceiver(MModdingPackets.CONFIGS, ((client, handler, buf, sender) -> ClientOperations.receiveConfigOnClient(buf)));
ClientPlayNetworking.registerGlobalReceiver(MModdingPackets.GLINT_PACKS, ((client, handler, buf, sender) -> ClientOperations.receiveGlintPackOnClient(buf)));
ClientPlayNetworking.registerGlobalReceiver(MModdingPackets.STELLAR_STATUS, (((client, handler, buf, sender) -> ClientOperations.receiveStellarStatusOnClient(handler, buf))));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

import net.minecraft.util.Identifier;

import java.util.Map;
import java.util.List;

public interface LivingEntityDuckInterface {

Map<Integer, Identifier> mmodding_lib$getStuckArrowTypes();
List<Identifier> mmodding_lib$getStuckArrowTypes();

void mmodding_lib$setStuckArrowTypes(Map<Integer, Identifier> stuckArrowTypes);
void mmodding_lib$setStuckArrowTypes(List<Identifier> stuckArrowTypes);

void mmodding_lib$putStuckArrowType(int index, Identifier arrowEntityId);
void mmodding_lib$addStuckArrowType(Identifier arrowEntityId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.mmodding.mmodding_lib.interface_injections;

import com.mmodding.mmodding_lib.library.entities.data.syncable.SyncableData;
import net.minecraft.entity.Entity;
import org.quiltmc.qsl.base.api.util.InjectedInterface;

@InjectedInterface(Entity.class)
public interface EntitySyncableDataRegistry {

default SyncableData.Registry getSyncableDataRegistry() {
throw new AssertionError();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.mmodding.mmodding_lib.library.entities.data.syncable;

import com.mmodding.mmodding_lib.networking.MModdingPackets;
import net.minecraft.entity.Entity;
import net.minecraft.entity.data.TrackedDataHandler;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier;
import net.minecraft.world.World;
import org.jetbrains.annotations.ApiStatus;
import org.quiltmc.qsl.networking.api.PacketByteBufs;
import org.quiltmc.qsl.networking.api.ServerPlayNetworking;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

public class SyncableData<V> extends AtomicReference<V> {

private final Entity entity;
private final Identifier identifier;
private final TrackedDataHandler<V> handler;

public SyncableData(V initialValue, Entity entity, Identifier identifier, TrackedDataHandler<V> handler) {
super(initialValue);
this.entity = entity;
this.identifier = identifier;
this.handler = handler;
this.entity.getSyncableDataRegistry().put(this.identifier, this);
}

public SyncableData(Entity entity, Identifier identifier, TrackedDataHandler<V> handler) {
super();
this.entity = entity;
this.identifier = identifier;
this.handler = handler;
this.entity.getSyncableDataRegistry().put(this.identifier, this);
}

public void synchronize() {
World world = this.entity.getWorld();
if (!world.isClient()) {
PacketByteBuf buf = PacketByteBufs.create();
buf.writeVarInt(this.entity.getId());
buf.writeIdentifier(this.identifier);
this.handler.write(buf, this.get());
this.entity.getWorld().getPlayers().forEach(playerEntity -> ServerPlayNetworking.send(
(ServerPlayerEntity) playerEntity, MModdingPackets.SYNCABLE_DATA, buf
));
}
}

public void accept(PacketByteBuf buf) {
this.set(this.handler.read(buf));
}

@ApiStatus.Internal
public static class Registry extends HashMap<Identifier, SyncableData<?>> implements Map<Identifier, SyncableData<?>> {

private final Entity syncedEntity;

public Registry(Entity syncedEntity) {
this.syncedEntity = syncedEntity;
}

public void accept(PacketByteBuf buf) {
World world = this.syncedEntity.getWorld();
if (world.isClient()) {
Identifier identifier = buf.readIdentifier();
this.get(identifier).accept(buf);
}
}
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@ public static Identifier extend(String extension, Identifier identifier) {
}

public static Identifier extend(Identifier identifier, String extension, boolean before) {
return IdentifierUtils.extend(identifier, extension, before, '_');
}

public static Identifier extend(Identifier identifier, String extension, boolean before, char separator) {
return !Objects.equals(extension, "") ? new Identifier(
identifier.getNamespace(),
!before ? identifier.getPath() + "_" + extension : extension + "_" + identifier.getPath()
!before ? identifier.getPath() + separator + extension : extension + separator + identifier.getPath()
) : identifier;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.mmodding.mmodding_lib.library.utils;


public class ObjectUtils {

public static void load(Object ignored) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import net.minecraft.network.PacketByteBuf;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TrackedDataHandlerUtils {

Expand Down Expand Up @@ -35,6 +37,27 @@ public List<T> copy(List<T> value) {
};
}

public static <K, V> TrackedDataHandler<Map<K, V>> createTrackedDataMapHandler(WriteAction<K> writeKeyAction, WriteAction<V> writeValueAction, ReadAction<K> readKeyAction, ReadAction<V> readValueAction) {

return new TrackedDataHandler<>() {

@Override
public void write(PacketByteBuf buf, Map<K, V> value) {
buf.writeMap(value, writeKeyAction::write, writeValueAction::write);
}

@Override
public Map<K, V> read(PacketByteBuf buf) {
return buf.readMap(readKeyAction::read, readValueAction::read);
}

@Override
public Map<K, V> copy(Map<K, V> value) {
return new HashMap<>(value);
}
};
}

public static <T> TrackedDataHandler<T> createTrackedDataHandler(WriteAction<T> writeAction, ReadAction<T> readAction, CopyAction<T> copyAction) {

return new TrackedDataHandler<>() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.mmodding.mmodding_lib.ducks.EntityDuckInterface;
import com.mmodding.mmodding_lib.ducks.PortalForcerDuckInterface;
import com.mmodding.mmodding_lib.ducks.ServerPlayerDuckInterface;
import com.mmodding.mmodding_lib.interface_injections.EntitySyncableDataRegistry;
import com.mmodding.mmodding_lib.library.entities.data.syncable.SyncableData;
import com.mmodding.mmodding_lib.library.portals.squared.CustomSquaredPortal;
import com.mmodding.mmodding_lib.library.portals.squared.CustomSquaredPortalBlock;
import net.minecraft.block.BlockState;
Expand Down Expand Up @@ -36,7 +38,10 @@
import java.util.function.Function;

@Mixin(Entity.class)
public abstract class EntityMixin implements EntityDuckInterface {
public abstract class EntityMixin implements EntitySyncableDataRegistry, EntityDuckInterface {

@Unique
protected final SyncableData.Registry syncableDataRegistry = new SyncableData.Registry((Entity) (Object) this);

@Unique
protected boolean inCustomPortal;
Expand Down Expand Up @@ -116,6 +121,11 @@ private void baseTickAfterTickNetherPortal(CallbackInfo ci) {
this.tickCustomPortal();
}

@Override
public SyncableData.Registry getSyncableDataRegistry() {
return this.syncableDataRegistry;
}

@Override
public boolean mmodding_lib$isInCustomPortal() {
return this.inCustomPortal;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,66 +1,62 @@
package com.mmodding.mmodding_lib.mixin.injectors;

import com.mmodding.mmodding_lib.ducks.LivingEntityDuckInterface;
import com.mmodding.mmodding_lib.networking.CommonOperations;
import com.mmodding.mmodding_lib.library.entities.data.MModdingTrackedDataHandlers;
import com.mmodding.mmodding_lib.library.entities.data.syncable.SyncableData;
import com.mmodding.mmodding_lib.library.utils.MModdingIdentifier;
import com.mmodding.mmodding_lib.library.utils.ObjectUtils;
import net.minecraft.entity.LivingEntity;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Mixin;
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.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;

@Mixin(LivingEntity.class)
public abstract class LivingEntityMixin extends EntityMixin implements LivingEntityDuckInterface {

@Unique
private Map<Integer, Identifier> stuckArrowTypes = new HashMap<>();
private final SyncableData<List<Identifier>> stuckArrowTypes = new SyncableData<>(
new ArrayList<>(),
(LivingEntity) (Object) this,
new MModdingIdentifier("stuck_arrow_types"),
MModdingTrackedDataHandlers.IDENTIFIER_LIST
);

@Inject(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;setStuckArrowCount(I)V"))
private void tick(CallbackInfo ci) {
this.deleteStuckArrowType();
}

@Override
public Map<Integer, Identifier> mmodding_lib$getStuckArrowTypes() {
return new HashMap<>(this.stuckArrowTypes);
public List<Identifier> mmodding_lib$getStuckArrowTypes() {
return new ArrayList<>(this.stuckArrowTypes.get());
}

@Override
public void mmodding_lib$setStuckArrowTypes(Map<Integer, Identifier> stuckArrowTypes) {
this.stuckArrowTypes = stuckArrowTypes;
this.syncStuckArrowTypes();
public void mmodding_lib$setStuckArrowTypes(List<Identifier> stuckArrowTypes) {
this.stuckArrowTypes.set(stuckArrowTypes);
this.stuckArrowTypes.synchronize();
}

@Override
public void mmodding_lib$putStuckArrowType(int index, Identifier arrowEntityId) {
this.stuckArrowTypes.put(index, arrowEntityId);
this.syncStuckArrowTypes();
public void mmodding_lib$addStuckArrowType(Identifier arrowEntityId) {
this.stuckArrowTypes.get().add(arrowEntityId);
this.stuckArrowTypes.synchronize();
}

@Unique
private void deleteStuckArrowType() {
Map<Integer, Identifier> oldStuckArrowTypes = this.mmodding_lib$getStuckArrowTypes();
Map<Integer, Identifier> newStuckArrowTypes = new HashMap<>();
int smallest = !oldStuckArrowTypes.isEmpty() ? Integer.MAX_VALUE : 0;
for (int current : oldStuckArrowTypes.keySet()) {
smallest = Math.min(smallest, current);
}
oldStuckArrowTypes.remove(smallest);
oldStuckArrowTypes.forEach((index, arrowEntityId) -> newStuckArrowTypes.put(index - 1, arrowEntityId));
this.mmodding_lib$setStuckArrowTypes(newStuckArrowTypes);
List<Identifier> stuckArrowTypes = this.mmodding_lib$getStuckArrowTypes();
stuckArrowTypes.remove(stuckArrowTypes.size() - 1);
this.mmodding_lib$setStuckArrowTypes(stuckArrowTypes);
}

@Unique
private void syncStuckArrowTypes() {
if (!this.world.isClient()) {
this.world.getPlayers().forEach(playerEntity -> CommonOperations.sendLivingEntityStuckArrowTypesToClient(
(LivingEntity) (Object) this, this.stuckArrowTypes, (ServerPlayerEntity) playerEntity
));
}
static {
ObjectUtils.load(MModdingTrackedDataHandlers.IDENTIFIER_LIST);
}
}
Loading

0 comments on commit 89a6554

Please sign in to comment.