Skip to content

Commit

Permalink
new: Metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
MATRIX-feather committed Dec 13, 2023
1 parent ecd2523 commit 814e51d
Show file tree
Hide file tree
Showing 21 changed files with 718 additions and 126 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,39 @@
import org.bukkit.entity.Player;
import xiamomc.morph.MorphPlugin;
import xiamomc.morph.MorphPluginObject;
import xiamomc.morph.backends.server.renderer.network.MorphPacketListener;
import xiamomc.morph.backends.server.renderer.network.ProtocolListener;
import xiamomc.morph.backends.server.renderer.network.RegistryParameters;
import xiamomc.morph.backends.server.renderer.network.RenderRegistry;
import xiamomc.morph.backends.server.renderer.network.listeners.SpawnPacketHandler;
import xiamomc.morph.backends.server.renderer.network.ProtocolHandler;
import xiamomc.morph.backends.server.renderer.network.datawatcher.watchers.Watchers;
import xiamomc.pluginbase.Managers.DependencyManager;

public class ServerRenderer extends MorphPluginObject
{
private final ProtocolListener protocolListener = new ProtocolListener();
private final ProtocolHandler protocolHandler;

private final RenderRegistry registry = new RenderRegistry();

public ServerRenderer()
{
var depMgr = DependencyManager.getManagerOrCreate(MorphPlugin.getInstance());
depMgr.cache(protocolListener.getPacketListener());
dependencies.cache(registry);
dependencies.cache(protocolHandler = new ProtocolHandler());
}

public void renderEntity(Player player, EntityType entityType, String name)
{
var packetListener = protocolListener.getPacketListener();

packetListener.register(player.getUniqueId(),
new MorphPacketListener.RegistryParameters(entityType, name));
registry.register(player.getUniqueId(),
new RegistryParameters(entityType, name, Watchers.getWatcherForType(player, entityType)));
}

public void unRenderEntity(Player player)
{
var packetListener = protocolListener.getPacketListener();

packetListener.unregister(player.getUniqueId());
registry.unregister(player.getUniqueId());
}

public void dispose()
{
protocolListener.dispose();
registry.reset();
protocolHandler.dispose();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package xiamomc.morph.backends.server.renderer.network;

import com.mojang.authlib.GameProfile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xiamomc.morph.backends.server.renderer.network.datawatcher.watchers.SingleWatcher;

public record DisplayParameters(@Nullable GameProfile gameProfile, @NotNull String playerDisguiseName,
org.bukkit.entity.EntityType bukkitType,
@NotNull SingleWatcher watcher)
{
public static DisplayParameters from(org.bukkit.entity.EntityType bukkitType, SingleWatcher watcher)
{
return new DisplayParameters(null, "Nil", bukkitType, watcher);
}

public static DisplayParameters fromRegistry(RegistryParameters registryParameters)
{
return new DisplayParameters(null, registryParameters.customName(), registryParameters.bukkitType(), registryParameters.singleWatcher());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.entity.EquipmentSlot;
import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemStack;
import org.bukkit.inventory.EntityEquipment;
import xiamomc.morph.misc.NmsRecord;

public class ProtocolEquipment
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
package xiamomc.morph.backends.server.renderer.network;

import com.comphenix.protocol.ProtocolLibrary;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xiamomc.morph.MorphPluginObject;
import xiamomc.morph.backends.server.renderer.network.datawatcher.watchers.SingleWatcher;
import xiamomc.morph.backends.server.renderer.network.datawatcher.watchers.Watchers;
import xiamomc.morph.backends.server.renderer.network.listeners.SpawnPacketHandler;
import xiamomc.pluginbase.Annotations.Initializer;
import xiamomc.pluginbase.Exceptions.NullDependencyException;

public class ProtocolListener extends MorphPluginObject
import java.util.Map;
import java.util.UUID;

public class ProtocolHandler extends MorphPluginObject
{
private final MorphPacketListener morphPacketListener = new MorphPacketListener();
private final SpawnPacketHandler morphPacketListener = new SpawnPacketHandler();

public MorphPacketListener getPacketListener()
public SpawnPacketHandler getPacketListener()
{
return morphPacketListener;
}
Expand Down Expand Up @@ -39,8 +52,6 @@ public void dispose()
t.printStackTrace();
}

morphPacketListener.reset();

disposed = true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package xiamomc.morph.backends.server.renderer.network;

import org.jetbrains.annotations.NotNull;
import xiamomc.morph.backends.server.renderer.network.datawatcher.watchers.SingleWatcher;
import xiamomc.pluginbase.Exceptions.NullDependencyException;

public record RegistryParameters(@NotNull org.bukkit.entity.EntityType bukkitType, String customName, @NotNull SingleWatcher singleWatcher)
{
public RegistryParameters(@NotNull org.bukkit.entity.EntityType bukkitType, String customName, @NotNull SingleWatcher singleWatcher)
{
this.bukkitType = bukkitType;
this.customName = customName;
this.singleWatcher = singleWatcher;

if (bukkitType == null)
throw new NullDependencyException("Null Bukkit Type");
}

public static RegistryParameters fromBukkitType(org.bukkit.entity.EntityType bukkitType, SingleWatcher watcher)
{
return new RegistryParameters(bukkitType, "Nil", watcher);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package xiamomc.morph.backends.server.renderer.network;

import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.minecraft.world.entity.PlayerRideable;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xiamomc.morph.MorphPluginObject;
import xiamomc.morph.backends.server.renderer.network.datawatcher.watchers.SingleWatcher;
import xiamomc.morph.backends.server.renderer.network.datawatcher.watchers.Watchers;
import xiamomc.pluginbase.Exceptions.NullDependencyException;

import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.function.Consumer;

public class RenderRegistry extends MorphPluginObject
{
public record EventParameters(Player player, RegistryParameters parameters)
{
}

private final Map<Object, Consumer<EventParameters>> onRegisterConsumers = new Object2ObjectOpenHashMap<>();
private final Map<Object, Consumer<Player>> unRegisterConsumers = new Object2ObjectOpenHashMap<>();

public void onRegister(Object source, Consumer<EventParameters> consumer)
{
onRegisterConsumers.put(source, consumer);
}

private void callRegister(Player player, RegistryParameters parameters)
{
var ep = new EventParameters(player, parameters);
onRegisterConsumers.forEach((source, consumer) -> consumer.accept(ep));
}

public void onUnRegister(Object source, Consumer<Player> consumer)
{
unRegisterConsumers.put(source, consumer);
}

private void callUnregister(Player player)
{
unRegisterConsumers.forEach((source, consumer) -> consumer.accept(player));
}

//region Registry

private final Map<UUID, RegistryParameters> registryParameters = new Object2ObjectOpenHashMap<>();

@Nullable
public RegistryParameters getParameters(UUID uuid)
{
return registryParameters.getOrDefault(uuid, null);
}

@Nullable
public SingleWatcher getWatcher(Entity entity)
{
return getWatcher(entity.getUniqueId());
}

@Nullable
public SingleWatcher getWatcher(UUID uuid)
{
var parameters = registryParameters.getOrDefault(uuid, null);

return parameters == null ? null : parameters.singleWatcher();
}

public void unregister(Player player)
{
unregister(player.getUniqueId());
}

public void unregister(UUID uuid)
{
registryParameters.remove(uuid);
callUnregister(Bukkit.getPlayer(uuid));
}

/**
* 注册玩家的伪装类型
* @param player 目标玩家
* @param bukkitType 伪装的Bukkit生物类型,为null则移除注册
*/
public void register(@NotNull Player player, @NotNull org.bukkit.entity.EntityType bukkitType)
{
var watcher = Watchers.getWatcherForType(player, bukkitType);
register(player.getUniqueId(), bukkitType, watcher);
}

/**
* 注册UUID对应的伪装类型
* @param uuid 目标玩家的UUID
* @param bukkitType 伪装的Bukkit生物类型,为null则移除注册
*/
public void register(@NotNull UUID uuid, @NotNull org.bukkit.entity.EntityType bukkitType, SingleWatcher watcher)
{
register(uuid, RegistryParameters.fromBukkitType(bukkitType, watcher));
}

public void register(@NotNull UUID uuid, @NotNull RegistryParameters parameters)
{
if (parameters == null)
{
throw new NullDependencyException("Null RegistryParameters!");
}
else
{
registryParameters.put(uuid, parameters);
callRegister(Bukkit.getPlayer(uuid), parameters);
}
}

public void reset()
{
var players = registryParameters.keySet().stream().toList();
registryParameters.clear();

players.forEach(uuid -> callUnregister(Bukkit.getPlayer(uuid)));
}

//endregion Registry
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package xiamomc.morph.backends.server.renderer.network.datawatcher;

public class PlayerWatcher
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package xiamomc.morph.backends.server.renderer.network.datawatcher;

import xiamomc.morph.backends.server.renderer.network.datawatcher.values.AbstractValues;
import xiamomc.morph.backends.server.renderer.network.datawatcher.values.EntityValues;
import xiamomc.morph.backends.server.renderer.network.datawatcher.values.LivingEntityValues;
import xiamomc.morph.backends.server.renderer.network.datawatcher.values.PlayerValues;

public class ValueIndex
{
public static final PlayerValues PLAYER = new PlayerValues();
public static final LivingEntityValues BASE_LIVING = new LivingEntityValues();
public static final EntityValues BASE_ENTITY = new EntityValues();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package xiamomc.morph.backends.server.renderer.network.datawatcher.values;

import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import xiamomc.morph.MorphPlugin;

import java.util.List;

public abstract class AbstractValues
{
protected final List<SingleValue<?>> values = new ObjectArrayList<>();

protected void registerValue(SingleValue<?>... value)
{
for (SingleValue<?> singleValue : value)
registerSingle(singleValue);
}

protected void registerSingle(SingleValue<?> value)
{
var duplicateValue = values.stream().filter(sv -> sv.index() == value.index()).findFirst().orElse(null);
if (duplicateValue != null)
throw new IllegalArgumentException("Already contains a value with index '%s'".formatted(value.index()));

try
{
WrappedDataWatcher.Registry.get(value.type());
}
catch (Throwable t)
{
MorphPlugin.getInstance().getSLF4JLogger().warn("No serializer for type '%s'!".formatted(value.type()));
}

values.add(value);
}

public List<SingleValue<?>> getValues()
{
return values;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package xiamomc.morph.backends.server.renderer.network.datawatcher.values;

import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.Pose;

import java.util.Optional;

public class EntityValues extends AbstractValues
{
public final SingleValue<Byte> GENERAL = SingleValue.of(0, (byte)0);
public final SingleValue<Integer> AIR_TICKS = SingleValue.of(1, 0);

@Deprecated
public final SingleValue<Optional<Component>> CUSTOMNAME = SingleValue.of(2, Optional.of(Component.empty()));

public final SingleValue<Boolean> CUSTOMNAME_VISIBLE = SingleValue.of(3, false);
public final SingleValue<Boolean> SILENT = SingleValue.of(4, false);
public final SingleValue<Boolean> NO_GRAVITY = SingleValue.of(5, false);
public final SingleValue<Pose> POSE = SingleValue.of(6, Pose.STANDING);
public final SingleValue<Integer> FROZEN_TICKS = SingleValue.of(7, 0);

public EntityValues()
{
registerValue(GENERAL, AIR_TICKS, CUSTOMNAME, CUSTOMNAME_VISIBLE, SILENT, NO_GRAVITY,
POSE, FROZEN_TICKS);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package xiamomc.morph.backends.server.renderer.network.datawatcher.values;

import net.minecraft.core.BlockPos;
import org.bukkit.Location;

import java.util.Optional;

public class LivingEntityValues extends AbstractValues
{
public final SingleValue<Byte> LIVING_FLAGS = SingleValue.of(8, (byte)0);
public final SingleValue<Float> HEALTH = SingleValue.of(9, 1f);
public final SingleValue<Integer> POTION_COLOR = SingleValue.of(10, 0);
public final SingleValue<Boolean> POTION_ISAMBIENT = SingleValue.of(11, false);
public final SingleValue<Integer> STUCKED_ARROWS = SingleValue.of(12, 0);
public final SingleValue<Integer> BEE_STINGERS = SingleValue.of(13, 0);
public final SingleValue<Optional<BlockPos>> BED_POS = SingleValue.of(14, Optional.of(new BlockPos(0,0,0)));

public LivingEntityValues()
{
super();

registerValue(LIVING_FLAGS, HEALTH, POTION_COLOR, POTION_ISAMBIENT, STUCKED_ARROWS, BED_POS, BEE_STINGERS);
}
}
Loading

0 comments on commit 814e51d

Please sign in to comment.