Skip to content

Commit

Permalink
misc: 让PacketFactory为产出的每一个数据包都打上标签
Browse files Browse the repository at this point in the history
add: fake equipments
  • Loading branch information
MATRIX-feather committed Dec 14, 2023
1 parent e502e3a commit 9aa1e86
Show file tree
Hide file tree
Showing 15 changed files with 192 additions and 34 deletions.
8 changes: 7 additions & 1 deletion src/main/java/xiamomc/morph/backends/DisguiseWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,13 @@ public TInstance getInstance()
* Sets displaying equipment to the giving value
* @param newEquipment A {@link EntityEquipment} that presents the new equipment
*/
public abstract void setDisplayingEquipments(@NotNull EntityEquipment newEquipment);
public abstract void setFakeEquipments(@NotNull EntityEquipment newEquipment);

/**
* Sets whether to display a fake equipment to the player
* @param newVal New State
*/
public abstract void setDisplayingFakeEquipments(boolean newVal);

/**
* Sets the state of server-side SelfView for the underlying disguise instance
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,18 @@ public EntityEquipment getDisplayingEquipments()
}

@Override
public void setDisplayingEquipments(@NotNull EntityEquipment newEquipment)
public void setFakeEquipments(@NotNull EntityEquipment newEquipment)
{
this.equipment.setArmorContents(newEquipment.getArmorContents());

this.equipment.setHandItems(newEquipment.getItemInMainHand(), newEquipment.getItemInOffHand());
}

@Override
public void setDisplayingFakeEquipments(boolean newVal)
{
}

@Override
public void setServerSelfView(boolean enabled)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public EntityEquipment getDisplayingEquipments()
}

@Override
public void setDisplayingEquipments(@NotNull EntityEquipment newEquipment)
public void setFakeEquipments(@NotNull EntityEquipment newEquipment)
{
watcher.setArmor(newEquipment.getArmorContents());
watcher.setItemInMainHand(newEquipment.getItemInMainHand());
Expand All @@ -69,6 +69,11 @@ public void setDisplayingEquipments(@NotNull EntityEquipment newEquipment)
invalidateCompound();
}

@Override
public void setDisplayingFakeEquipments(boolean newVal)
{
}

@Override
public void setServerSelfView(boolean enabled)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public EntityEquipment getDisplayingEquipments()
}

@Override
public void setDisplayingEquipments(@NotNull EntityEquipment newEquipment)
public void setFakeEquipments(@NotNull EntityEquipment newEquipment)
{
this.equipment.setArmorContents(newEquipment.getArmorContents());

Expand All @@ -112,6 +112,17 @@ public void setDisplayingEquipments(@NotNull EntityEquipment newEquipment)
bindingWatcher.write(EntryIndex.EQUIPMENT, this.equipment);
}

private boolean shouldDisplayCustomEquipment;

@Override
public void setDisplayingFakeEquipments(boolean newVal)
{
shouldDisplayCustomEquipment = newVal;

if (bindingWatcher != null)
bindingWatcher.write(EntryIndex.DISPLAY_FAKE_EQUIPMENT, newVal);
}

@Override
public void setServerSelfView(boolean enabled)
{
Expand Down Expand Up @@ -260,5 +271,7 @@ private void refreshRegistry()

//todo: 激活刷新时也刷新到玩家
bindingWatcher.write(EntryIndex.PROFILE, this.instance.profile);
bindingWatcher.write(EntryIndex.DISPLAY_FAKE_EQUIPMENT, shouldDisplayCustomEquipment);
bindingWatcher.write(EntryIndex.EQUIPMENT, this.equipment);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@
import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket;
import net.minecraft.world.level.GameType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.EntityEquipment;
import xiamomc.morph.MorphPluginObject;
import xiamomc.morph.backends.server.renderer.network.datawatcher.values.SingleValue;
import xiamomc.morph.backends.server.renderer.network.datawatcher.watchers.SingleWatcher;
import xiamomc.morph.backends.server.renderer.network.registries.EntryIndex;
import xiamomc.morph.backends.server.renderer.utilties.ProtocolRegistryUtils;
import xiamomc.morph.misc.DisguiseEquipment;
import xiamomc.morph.misc.MorphGameProfile;
import xiamomc.morph.misc.NmsRecord;
import xiamomc.morph.utilities.EntityTypeUtils;
Expand Down Expand Up @@ -85,7 +88,6 @@ public List<PacketContainer> buildSpawnPackets(Player player, DisplayParameters

var spawnPacket = PacketContainer.fromPacket(packetAdd);

spawnPacket.setMeta(MORPH_PACKET_METAKEY, true);
packets.add(spawnPacket);

//生成装备和Meta
Expand All @@ -97,6 +99,11 @@ public List<PacketContainer> buildSpawnPackets(Player player, DisplayParameters
watcher.sync();
packets.add(buildMetaPacket(player, watcher));

for (PacketContainer packet : packets)
{
packet.setMeta(MORPH_PACKET_METAKEY, true);
}

return packets;
}

Expand All @@ -107,13 +114,6 @@ public PacketContainer buildMetaPacket(Player player, SingleWatcher watcher)

var modifier = metaPacket.getDataValueCollectionModifier();

var entityWatcher = WrappedDataWatcher.getEntityWatcher(player);
entityWatcher.asMap().forEach((id, val) ->
{
//logger.info("Id '%s' is val '%s' raw '%s' class '%s'"
// .formatted(id, val.getValue(),val.getRawValue(),val.getRawValue().getClass()));
});

List<WrappedDataValue> wrappedDataValues = new ObjectArrayList<>();

Map<SingleValue<?>, Object> valuesToSent = new Object2ObjectOpenHashMap<>();
Expand All @@ -140,12 +140,27 @@ public PacketContainer buildMetaPacket(Player player, SingleWatcher watcher)

var value = new WrappedDataValue(single.index(), serializer, v);
wrappedDataValues.add(value);
//logger.info("Writing value '%s' index '%s'".formatted(v, single.index()));
});

modifier.write(0, wrappedDataValues);
metaPacket.setMeta(MORPH_PACKET_METAKEY, true);

return metaPacket;
}

public PacketContainer getEquipmentPacket(Player player, SingleWatcher watcher)
{
var shouldDisplayFakeEquip = watcher.getOrDefault(EntryIndex.DISPLAY_FAKE_EQUIPMENT, false);
EntityEquipment equipment = shouldDisplayFakeEquip
? watcher.getOrDefault(EntryIndex.EQUIPMENT, new DisguiseEquipment())
: player.getEquipment();

var rawPacket = new ClientboundSetEquipmentPacket(player.getEntityId(),
ProtocolEquipment.toPairs(equipment));

var container = PacketContainer.fromPacket(rawPacket);
container.setMeta(MORPH_PACKET_METAKEY, true);

return container;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.comphenix.protocol.ProtocolLibrary;
import xiamomc.morph.MorphPluginObject;
import xiamomc.morph.backends.server.renderer.network.listeners.EquipmentPacketListener;
import xiamomc.morph.backends.server.renderer.network.listeners.MetaPacketListener;
import xiamomc.morph.backends.server.renderer.network.listeners.SpawnPacketHandler;
import xiamomc.pluginbase.Annotations.Initializer;
Expand All @@ -24,6 +25,7 @@ private void load()

protocolMgr.addPacketListener(morphPacketListener);
protocolMgr.addPacketListener(new MetaPacketListener());
protocolMgr.addPacketListener(new EquipmentPacketListener());
//protocolMgr.addPacketListener(new TestPacketListener());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,13 @@ public SingleWatcher(Player bindingPlayer, EntityType entityType)

public <X> void write(RegistryKey<X> key, X value)
{
var prev = getOrDefault(key, null);
customRegistry.put(key.name, value);

onCustomWrite(key, value);
onCustomWrite(key, prev, value);
}

protected void onCustomWrite(RegistryKey<?> key, Object val)
protected void onCustomWrite(RegistryKey<?> key, @Nullable Object oldVal, Object newVal)
{
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
package xiamomc.morph.backends.server.renderer.network.datawatcher.watchers.types;

import com.comphenix.protocol.ProtocolLibrary;
import com.destroystokyo.paper.ClientOption;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.world.level.GameType;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import xiamomc.morph.backends.server.renderer.network.PacketFactory;
import xiamomc.morph.backends.server.renderer.network.datawatcher.ValueIndex;
import xiamomc.morph.backends.server.renderer.network.listeners.ProtocolListener;
import xiamomc.morph.backends.server.renderer.network.registries.EntryIndex;
import xiamomc.morph.backends.server.renderer.network.registries.RegistryKey;
import xiamomc.morph.misc.DisguiseEquipment;
import xiamomc.morph.misc.NmsRecord;
import xiamomc.pluginbase.Annotations.Resolved;

import java.util.List;
import java.util.Optional;

public class PlayerWatcher extends LivingEntityWatcher
Expand All @@ -36,9 +43,34 @@ protected void doSync()
super.doSync();
}

@Resolved(shouldSolveImmediately = true)
private PacketFactory packetFactory;

private List<Player> getAffectedPlayers(Player sourcePlayer)
{
var players = sourcePlayer.getWorld().getPlayers();
players.remove(sourcePlayer);
if (NmsRecord.ofPlayer(sourcePlayer).gameMode.getGameModeForPlayer() == GameType.SPECTATOR)
{
players.removeIf(bukkitPlayer ->
NmsRecord.ofPlayer(bukkitPlayer).gameMode.getGameModeForPlayer() != GameType.SPECTATOR);
}

return players;
}

@Override
protected void onCustomWrite(RegistryKey<?> key, Object val)
protected void onCustomWrite(RegistryKey<?> key, Object oldVal, Object newVal)
{
super.onCustomWrite(key, val);
super.onCustomWrite(key, oldVal, newVal);

if (key.equals(EntryIndex.DISPLAY_FAKE_EQUIPMENT) || key.equals(EntryIndex.EQUIPMENT))
{
var packet = packetFactory.getEquipmentPacket(getBindingPlayer(), this);
var players = getAffectedPlayers(getBindingPlayer());

var protocol = ProtocolLibrary.getProtocolManager();
players.forEach(p -> protocol.sendServerPacket(p, packet));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package xiamomc.morph.backends.server.renderer.network.listeners;

import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.ListeningWhitelist;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.injector.GamePhase;
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket;
import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket;
import org.bukkit.entity.Player;
import xiamomc.morph.MorphPlugin;
import xiamomc.morph.backends.server.renderer.network.PacketFactory;
import xiamomc.morph.backends.server.renderer.network.registries.EntryIndex;
import xiamomc.morph.backends.server.renderer.network.registries.RenderRegistry;
import xiamomc.morph.utilities.NmsUtils;
import xiamomc.pluginbase.Annotations.Resolved;

public class EquipmentPacketListener extends ProtocolListener
{
@Resolved(shouldSolveImmediately = true)
private RenderRegistry registry;

@Override
public void onPacketSending(PacketEvent event)
{
if (event.getPacketType() != PacketType.Play.Server.ENTITY_EQUIPMENT)
return;

var packet = event.getPacket();

//不要处理来自我们自己的包
if (packet.getMeta(PacketFactory.MORPH_PACKET_METAKEY).isPresent())
return;

onEquipmentPacket((ClientboundSetEquipmentPacket) event.getPacket().getHandle(), event);
}

private void onEquipmentPacket(ClientboundSetEquipmentPacket packet, PacketEvent event)
{
if (event.getPacket().getMeta(PacketFactory.MORPH_PACKET_METAKEY).isPresent())
return;

//获取此包的来源实体
var sourceNmsEntity = NmsUtils.getNmsLevel(event.getPlayer().getWorld()).getEntity(packet.getEntity());
if (!(sourceNmsEntity.getBukkitEntity() instanceof Player sourcePlayer)) return;

var watcher = registry.getWatcher(sourcePlayer.getUniqueId());

if (watcher == null)
return;

if (!watcher.getOrDefault(EntryIndex.DISPLAY_FAKE_EQUIPMENT, false))
return;

event.setPacket(getFactory().getEquipmentPacket(sourcePlayer, watcher));
}

@Override
public void onPacketReceiving(PacketEvent event)
{
}

@Override
public ListeningWhitelist getSendingWhitelist()
{
return ListeningWhitelist
.newBuilder()
.types(PacketType.Play.Server.ENTITY_EQUIPMENT)
.gamePhase(GamePhase.PLAYING)
.build();
}

@Override
public ListeningWhitelist getReceivingWhitelist()
{
return ListeningWhitelist.EMPTY_WHITELIST;
}

@Override
public org.bukkit.plugin.Plugin getPlugin()
{
return MorphPlugin.getInstance();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import xiamomc.morph.utilities.NmsUtils;
import xiamomc.pluginbase.Annotations.Resolved;

public class MetaPacketListener extends ProtocolListener implements PacketListener
public class MetaPacketListener extends ProtocolListener
{
@Resolved(shouldSolveImmediately = true)
private RenderRegistry registry;
Expand Down Expand Up @@ -50,13 +50,10 @@ private void onMetaPacket(ClientboundSetEntityDataPacket packet, PacketEvent pac
//只拦截其他人的Meta
if (targetPlayer == sourcePlayer)
return;
else
packetEvent.setCancelled(true);

//取得来源玩家的伪装后的Meta,发送给目标玩家
watcher.sync();
var meta = getFactory().buildMetaPacket(sourcePlayer, watcher);
protocolManager().sendServerPacket(targetPlayer, meta);
packetEvent.setPacket(getFactory().buildMetaPacket(sourcePlayer, watcher));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.PacketListener;
import xiamomc.morph.MorphPluginObject;
import xiamomc.morph.backends.server.renderer.network.PacketFactory;
import xiamomc.morph.backends.server.renderer.network.queue.PacketQueue;
import xiamomc.pluginbase.Annotations.Resolved;

public abstract class ProtocolListener extends MorphPluginObject
public abstract class ProtocolListener extends MorphPluginObject implements PacketListener
{
@Resolved(shouldSolveImmediately = true)
private PacketFactory packetFactory;
Expand Down
Loading

0 comments on commit 9aa1e86

Please sign in to comment.