Commit 3a76db63 authored by Ashijin's avatar Ashijin
Browse files
No related merge requests found
......@@ -20,7 +20,11 @@ public interface CosmeticProfile {
public void equip(Cosmetic cosmetic);
public void unequip(Cosmetic cosmetic);
void setHidden(Class<? extends Cosmetic> cosmetic, boolean flag);
public boolean isEquipped(Cosmetic cosmetic);
boolean isHidden(Class<? extends Cosmetic> cosmetic);
}
......@@ -197,8 +197,8 @@
</dependency>
<dependency>
<groupId>com.ticxo.playeranimator</groupId>
<artifactId>plugin</artifactId>
<version>plugin</version>
<artifactId>PlayerAnimator</artifactId>
<version>R1.0.0</version>
</dependency>
<!-- Spigot API -->
......
......@@ -37,11 +37,15 @@ public class BackManager extends MCCosmeticsManager<BackAccessory> implements Hi
public void hide(CosmeticProfile profile, Cosmetic request) {
if(!(request instanceof Gesture))
return;
profile.setHidden(getCosmeticClass(), true);
getHelper().unapply(profile);
}
@Override
public void show(CosmeticProfile profile) {
if(profile.getPlayer().isDead())
return;
profile.setHidden(getCosmeticClass(), false);
getHelper().apply(profile);
}
......
......@@ -12,6 +12,7 @@ import io.lumine.cosmetics.nms.cosmetic.VolatileEquipmentHelper;
import io.lumine.utils.Events;
import io.lumine.utils.files.Files;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerToggleSneakEvent;
......@@ -33,6 +34,8 @@ public class GestureManager extends MCCosmeticsManager<Gesture> {
loadGestures();
super.load(plugin);
Events.subscribe(PlayerJoinEvent.class).handler(event -> PlayerAnimator.api.injectPlayer(event.getPlayer())).bindWith(this);
Events.subscribe(PlayerQuitEvent.class).handler(event -> PlayerAnimator.api.removePlayer(event.getPlayer())).bindWith(this);
Events.subscribe(PlayerToggleSneakEvent.class).handler(event -> quit(event.getPlayer(), QuitMethod.SNEAK)).bindWith(this);
Events.subscribe(PlayerJumpEvent.class).handler(event -> quit(event.getPlayer(), QuitMethod.JUMP)).bindWith(this);
Events.subscribe(PlayerQuitEvent.class).handler(event -> quit(event.getPlayer(), null)).bindWith(this);
......
......@@ -6,6 +6,7 @@ import io.lumine.cosmetics.api.cosmetics.manager.HideableCosmetic;
import io.lumine.cosmetics.api.players.CosmeticProfile;
import io.lumine.cosmetics.managers.MCCosmeticsManager;
import io.lumine.cosmetics.managers.gestures.Gesture;
import io.lumine.cosmetics.managers.offhand.Offhand;
import io.lumine.cosmetics.nms.cosmetic.VolatileEquipmentHelper;
import io.lumine.cosmetics.players.Profile;
import io.lumine.utils.Events;
......@@ -29,28 +30,26 @@ public class HatManager extends MCCosmeticsManager<Hat> implements HideableCosme
Events.subscribe(InventoryCloseEvent.class)
.handler(event -> {
final Player player = (Player) event.getPlayer();
getProfiles().awaitProfile(player).thenAcceptAsync(maybeProfile -> {
if(maybeProfile.isEmpty())
return;
final Profile profile = maybeProfile.get();
equip(profile);
});
handleEquip((Player) event.getPlayer());
}).bindWith(this);
Events.subscribe(ArmorEquipEvent.class)
.handler(event -> {
final Player player = event.getPlayer();
getProfiles().awaitProfile(player).thenAcceptAsync(maybeProfile -> {
if(maybeProfile.isEmpty()) {
return;
}
final Profile profile = maybeProfile.get();
equip(profile);
});
handleEquip(event.getPlayer());
}).bindWith(this);
}
private void handleEquip(Player player) {
getProfiles().awaitProfile(player).thenAcceptAsync(maybeProfile -> {
if(maybeProfile.isEmpty())
return;
final Profile profile = maybeProfile.get();
if(profile.isHidden(Hat.class))
return;
equip(profile);
});
}
@Override
public Hat build(File file, String node) {
return new Hat(this, file, node);
......@@ -70,11 +69,13 @@ public class HatManager extends MCCosmeticsManager<Hat> implements HideableCosme
public void hide(CosmeticProfile profile, Cosmetic request) {
if(!(request instanceof Gesture))
return;
profile.setHidden(getCosmeticClass(), true);
getHelper().unapply(profile);
}
@Override
public void show(CosmeticProfile profile) {
profile.setHidden(getCosmeticClass(), false);
getHelper().apply(profile);
}
......
......@@ -30,39 +30,32 @@ public class OffhandManager extends MCCosmeticsManager<Offhand> implements Hidea
Events.subscribe(InventoryCloseEvent.class)
.handler(event -> {
final Player player = (Player) event.getPlayer();
getProfiles().awaitProfile(player).thenAcceptAsync(maybeProfile -> {
if(maybeProfile.isEmpty())
return;
final Profile profile = maybeProfile.get();
equip(profile);
});
handleEquip((Player) event.getPlayer());
}).bindWith(this);
Events.subscribe(PlayerRespawnEvent.class)
.handler(event -> {
final Player player = event.getPlayer();
getProfiles().awaitProfile(player).thenAcceptAsync(maybeProfile -> {
if(maybeProfile.isEmpty())
return;
final Profile profile = maybeProfile.get();
equip(profile);
});
handleEquip(event.getPlayer());
}).bindWith(this);
Events.subscribe(PlayerSwapHandItemsEvent.class)
.handler(event -> {
final Player player = event.getPlayer();
getProfiles().awaitProfile(player).thenAcceptAsync(maybeProfile -> {
if(maybeProfile.isEmpty())
return;
final Profile profile = maybeProfile.get();
equip(profile);
});
handleEquip(event.getPlayer());
}).bindWith(this);
}
private void handleEquip(Player player) {
getProfiles().awaitProfile(player).thenAcceptAsync(maybeProfile -> {
if(maybeProfile.isEmpty())
return;
final Profile profile = maybeProfile.get();
if(profile.isHidden(Offhand.class))
return;
equip(profile);
});
}
@Override
public Offhand build(File file, String node) {
return new Offhand(this, file, node);
......@@ -82,11 +75,13 @@ public class OffhandManager extends MCCosmeticsManager<Offhand> implements Hidea
public void hide(CosmeticProfile profile, Cosmetic request) {
if(!(request instanceof Gesture))
return;
profile.setHidden(getCosmeticClass(), true);
getHelper().unapply(profile);
}
@Override
public void show(CosmeticProfile profile) {
profile.setHidden(getCosmeticClass(), false);
getHelper().apply(profile);
}
......
......@@ -6,8 +6,8 @@ import java.util.List;
public interface VolatileCosmeticHelper {
default void read(Player sender, Object packet) {
default boolean read(Player sender, Object packet, boolean isCanceled) {
return true;
}
default List<Object> write(Player receiver, Object packet) {
......
......@@ -44,11 +44,24 @@ public class Profile implements CosmeticProfile,io.lumine.utils.storage.players.
cosmeticInventory.unequip(cosmetic.getClass());
}
@Override
public void setHidden(Class<? extends Cosmetic> cosmetic, boolean flag) {
if(flag)
cosmeticInventory.getHidden().add(cosmetic);
else
cosmeticInventory.getHidden().remove(cosmetic);
}
@Override
public boolean isEquipped(Cosmetic cosmetic) {
return cosmeticInventory.isEquipped(cosmetic);
}
@Override
public boolean isHidden(Class<? extends Cosmetic> cosmetic) {
return cosmeticInventory.getHidden().contains(cosmetic);
}
public void reloadCosmetics() {
cosmeticInventory.initialize(this);
}
......
......@@ -2,6 +2,7 @@ package io.lumine.cosmetics.players;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import io.lumine.cosmetics.MCCosmeticsPlugin;
import io.lumine.cosmetics.api.cosmetics.Cosmetic;
import io.lumine.cosmetics.api.players.CosmeticInventory;
......@@ -13,16 +14,14 @@ import io.lumine.cosmetics.managers.sprays.Spray;
import io.lumine.utils.serialize.Optl;
import lombok.Getter;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.*;
public class ProfileInventory implements CosmeticInventory {
@Getter private transient CosmeticProfile profile;
@Getter private transient final Map<Class<? extends Cosmetic>, Cosmetic> equipped = Maps.newConcurrentMap();
@Getter private transient final Set<Class<? extends Cosmetic>> hidden = Sets.newConcurrentHashSet();
@Getter private final Map<String,List<String>> unlockedCosmetics = Maps.newConcurrentMap();
@Getter private final Map<String,String> equippedCosmetics = Maps.newConcurrentMap();
......
......@@ -6,6 +6,7 @@ import io.lumine.cosmetics.MCCosmeticsPlugin;
import io.lumine.cosmetics.api.cosmetics.Cosmetic;
import io.lumine.cosmetics.api.cosmetics.ItemCosmetic;
import io.lumine.cosmetics.api.players.CosmeticProfile;
import io.lumine.cosmetics.logging.MCLogger;
import io.lumine.cosmetics.managers.back.BackAccessory;
import io.lumine.cosmetics.nms.VolatileCodeEnabled_v1_18_R2;
import io.lumine.cosmetics.nms.cosmetic.VolatileEquipmentHelper;
......@@ -18,6 +19,7 @@ import net.minecraft.network.protocol.game.*;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.decoration.ArmorStand;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack;
......@@ -50,12 +52,14 @@ public class VolatileBackImpl implements VolatileEquipmentHelper {
if (cosmetic.isEmpty() || !(cosmetic.get() instanceof ItemCosmetic back))
return;
var nmsPlayer = ((CraftPlayer) player).getHandle();
var nmsBack = CraftItemStack.asNMSCopy(back.getCosmetic());
ArmorStand stand = activeProfile.get(player);
if(stand == null) {
playerTracker.put(player.getEntityId(), player);
stand = new ArmorStand(EntityType.ARMOR_STAND, ((CraftWorld) player.getWorld()).getHandle());
stand.moveTo(nmsPlayer.getX(), nmsPlayer.getY() + nmsPlayer.getPassengersRidingOffset() + stand.getMyRidingOffset(), nmsPlayer.getZ(), nmsPlayer.getYRot(), 0);
stand.setMarker(true);
stand.setInvisible(true);
stand.setSilent(true);
......@@ -82,25 +86,28 @@ public class VolatileBackImpl implements VolatileEquipmentHelper {
ArmorStand stand = activeProfile.remove(player);
if(stand == null)
return;
playerTracker.remove(player.getEntityId());
ClientboundRemoveEntitiesPacket removePacket = new ClientboundRemoveEntitiesPacket(stand.getId());
nmsHandler.broadcastAroundAndSelf(player, removePacket);
}
@Override
public void read(Player sender, Object packet) {
public boolean read(Player sender, Object packet, boolean isCanceled) {
final var profile = MCCosmeticsPlugin.inst().getProfiles().getProfile(sender);
if(profile == null || profile.isHidden(BackAccessory.class))
return true;
if(packet instanceof ServerboundMovePlayerPacket) {
handleRotate(profile);
}else if(packet instanceof ServerboundAcceptTeleportationPacket) {
final var list = handleSpawn(profile);
if(list == null)
return;
return true;
final var connection = ((CraftPlayer) sender).getHandle().connection;
for(Object obj : list) {
connection.send((Packet<?>) obj);
}
}
return true;
}
@Override
......@@ -110,6 +117,8 @@ public class VolatileBackImpl implements VolatileEquipmentHelper {
if(playerTracker.containsKey(id)) {
final var spawnedPlayer = playerTracker.get(id);
final var profile = MCCosmeticsPlugin.inst().getProfiles().getProfile(spawnedPlayer);
if(profile == null || profile.isHidden(BackAccessory.class))
return null;
return handleSpawn(profile);
}
}else if(packet instanceof ClientboundRemoveEntitiesPacket removePacket) {
......@@ -119,6 +128,28 @@ public class VolatileBackImpl implements VolatileEquipmentHelper {
}
}
}
/*
else if(packet instanceof ClientboundMoveEntityPacket moveEntityPacket) {
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
moveEntityPacket.write(byteBuf);
int id = byteBuf.readVarInt();
if(playerTracker.containsKey(id)) {
final var spawnedPlayer = playerTracker.get(id);
final var profile = MCCosmeticsPlugin.inst().getProfiles().getProfile(spawnedPlayer);
if(profile == null || profile.isHidden(BackAccessory.class))
return null;
return handleMove(profile, moveEntityPacket);
}
}else if(packet instanceof ClientboundTeleportEntityPacket teleportEntityPacket) {
int id = teleportEntityPacket.getId();
if(playerTracker.containsKey(id)) {
final var spawnedPlayer = playerTracker.get(id);
final var profile = MCCosmeticsPlugin.inst().getProfiles().getProfile(spawnedPlayer);
if(profile == null || profile.isHidden(BackAccessory.class))
return null;
return handleTeleport(profile);
}
}*/
return null;
}
......@@ -158,6 +189,52 @@ public class VolatileBackImpl implements VolatileEquipmentHelper {
return List.of(removePacket);
}
private List<Object> handleMove(Profile profile, ClientboundMoveEntityPacket moveEntityPacket) {
if(!hasBack(profile))
return null;
final var wearer = profile.getPlayer();
final var stand = activeProfile.get(wearer);
ClientboundMoveEntityPacket move;
if(moveEntityPacket.hasPosition() && moveEntityPacket.hasRotation()) {
move = new ClientboundMoveEntityPacket.PosRot(
stand.getId(),
moveEntityPacket.getXa(),
moveEntityPacket.getYa(),
moveEntityPacket.getZa(),
moveEntityPacket.getyRot(),
moveEntityPacket.getxRot(),
false);
}else if(moveEntityPacket.hasPosition()) {
move = new ClientboundMoveEntityPacket.Pos(
stand.getId(),
moveEntityPacket.getXa(),
moveEntityPacket.getYa(),
moveEntityPacket.getZa(),
false);
}else {
move = new ClientboundMoveEntityPacket.Rot(
stand.getId(),
moveEntityPacket.getyRot(),
moveEntityPacket.getxRot(),
false);
}
return List.of(move);
}
private List<Object> handleTeleport(Profile profile) {
if(!hasBack(profile))
return null;
final var wearer = profile.getPlayer();
final var nmsPlayer = ((CraftPlayer) wearer).getHandle();
final var stand = activeProfile.get(wearer);
stand.moveTo(nmsPlayer.getX(), nmsPlayer.getY() + nmsPlayer.getPassengersRidingOffset() + stand.getMyRidingOffset(), nmsPlayer.getZ(), nmsPlayer.getYRot(), 0);
return List.of(new ClientboundTeleportEntityPacket(stand));
}
private boolean hasBack(Profile profile) {
if(profile == null)
return false;
......
package io.lumine.cosmetics.nms.v1_18_R2.cosmetic;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.mojang.datafixers.util.Pair;
import io.lumine.cosmetics.MCCosmeticsPlugin;
......@@ -25,10 +26,7 @@ import org.bukkit.craftbukkit.v1_18_R2.attribute.CraftAttributeMap;
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.*;
public class VolatileGestureImpl implements VolatileEquipmentHelper {
......@@ -43,6 +41,7 @@ public class VolatileGestureImpl implements VolatileEquipmentHelper {
private final MCCosmeticsPlugin plugin;
private final VolatileCodeEnabled_v1_18_R2 nmsHandler;
private final Set<Player> activeProfile = Sets.newConcurrentHashSet();
private final Map<Integer, Player> playerTracker = Maps.newConcurrentMap();
private Horse horse;
......@@ -63,6 +62,7 @@ public class VolatileGestureImpl implements VolatileEquipmentHelper {
if (cosmetic.isEmpty() || !(cosmetic.get() instanceof Gesture gesture))
return;
playerTracker.put(player.getEntityId(), player);
getHorsed(player);
player.setInvisible(true);
for(final var value : profile.getCosmeticInventory().getEquipped().values()) {
......@@ -71,6 +71,8 @@ public class VolatileGestureImpl implements VolatileEquipmentHelper {
continue;
hide.hide(profile, gesture);
}
ClientboundSetEquipmentPacket equipmentPacket = new ClientboundSetEquipmentPacket(player.getEntityId(), empty);
nmsHandler.broadcastAroundAndSelf(player, equipmentPacket);
}
@Override
......@@ -82,6 +84,7 @@ public class VolatileGestureImpl implements VolatileEquipmentHelper {
return;
activeProfile.remove(player);
playerTracker.remove(player.getEntityId());
nmsHandler.broadcast(player, new ClientboundRemoveEntitiesPacket(horse.getId()));
player.setInvisible(false);
......@@ -91,6 +94,13 @@ public class VolatileGestureImpl implements VolatileEquipmentHelper {
continue;
hide.show(profile);
}
final var nmsPlayer = ((CraftPlayer) player).getHandle();
List<Pair<EquipmentSlot, ItemStack>> equipment = new ArrayList<>();
for(EquipmentSlot slot : EquipmentSlot.values())
equipment.add(Pair.of(slot, nmsPlayer.getItemBySlot(slot)));
ClientboundSetEquipmentPacket equipmentPacket = new ClientboundSetEquipmentPacket(player.getEntityId(), equipment);
nmsHandler.broadcastAroundAndSelf(player, equipmentPacket);
}
private ClientboundSetPassengersPacket createPassengerPacket(int mount, int... driver) {
......@@ -122,13 +132,13 @@ public class VolatileGestureImpl implements VolatileEquipmentHelper {
}
@Override
public void read(Player sender, Object packet) {
public boolean read(Player sender, Object packet, boolean isCanceled) {
final var profile = MCCosmeticsPlugin.inst().getProfiles().getProfile(sender);
if(profile == null)
return;
return true;
final var opt = profile.getCosmeticInventory().getEquipped(Gesture.class);
if(opt.isEmpty() || !(opt.get() instanceof Gesture gesture))
return;
return true;
if(packet instanceof ServerboundPlayerInputPacket inputPacket) {
final var manager = (GestureManager) gesture.getManager();
......@@ -136,6 +146,27 @@ public class VolatileGestureImpl implements VolatileEquipmentHelper {
manager.quit(sender, QuitMethod.SNEAK);
if(inputPacket.isJumping())
manager.quit(sender, QuitMethod.JUMP);
}else if(packet instanceof ServerboundSetCarriedItemPacket setSlotPacket) {
int oSlot = sender.getInventory().getHeldItemSlot();
if(oSlot != setSlotPacket.getSlot()) {
nmsHandler.broadcast(sender, new ClientboundSetCarriedItemPacket(oSlot));
return false;
}
}
return true;
}
@Override
public List<Object> write(Player receiver, Object packet) {
if(packet instanceof ClientboundSetEquipmentPacket equipmentPacket) {
int id = equipmentPacket.getEntity();
final var spawnedPlayer = playerTracker.get(id);
if(spawnedPlayer == null)
return null;
final var profile = MCCosmeticsPlugin.inst().getProfiles().getProfile(spawnedPlayer);
if(profile != null)
return List.of(new ClientboundSetEquipmentPacket(id, empty));
}
return null;
}
}
......@@ -14,7 +14,6 @@ import lombok.Getter;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.*;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.ItemStack;
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack;
import org.bukkit.entity.Player;
......@@ -53,7 +52,6 @@ public class VolatileHatImpl implements VolatileEquipmentHelper {
ClientboundSetEquipmentPacket equipmentPacket = new ClientboundSetEquipmentPacket(player.getEntityId(), List.of(Pair.of(EquipmentSlot.HEAD, nmsHat)));
nmsHandler.broadcastAroundAndSelf(player, equipmentPacket);
}
@Override
......@@ -65,17 +63,22 @@ public class VolatileHatImpl implements VolatileEquipmentHelper {
}
@Override
public void read(Player sender, Object packet) {
public boolean read(Player sender, Object packet, boolean isCanceled) {
if(packet instanceof ServerboundAcceptTeleportationPacket) {
final var profile = MCCosmeticsPlugin.inst().getProfiles().getProfile(sender);
if(profile == null || profile.isHidden(Hat.class))
return true;
final var list = handleSpawn(profile);
if(list == null)
return;
return true;
final var connection = ((CraftPlayer) sender).getHandle().connection;
for(Object obj : list) {
connection.send((Packet<?>) obj);
}
}
return true;
}
@Override
......@@ -83,12 +86,12 @@ public class VolatileHatImpl implements VolatileEquipmentHelper {
if(packet instanceof ClientboundAddPlayerPacket playerPacket) {
int id = playerPacket.getEntityId();
Profile profile = getProfile(receiver, id);
if(profile != null)
if(profile != null && !profile.isHidden(Hat.class))
return handleSpawn(profile);
}else if(packet instanceof ClientboundSetEquipmentPacket equipmentPacket) {
int id = equipmentPacket.getEntity();
Profile profile = getProfile(receiver, id);
if(profile != null)
if(profile != null && !profile.isHidden(Hat.class))
return handleSpawn(profile);
}
......
......@@ -6,6 +6,8 @@ import io.lumine.cosmetics.MCCosmeticsPlugin;
import io.lumine.cosmetics.api.cosmetics.Cosmetic;
import io.lumine.cosmetics.api.cosmetics.ItemCosmetic;
import io.lumine.cosmetics.api.players.CosmeticProfile;
import io.lumine.cosmetics.logging.MCLogger;
import io.lumine.cosmetics.managers.hats.Hat;
import io.lumine.cosmetics.managers.offhand.Offhand;
import io.lumine.cosmetics.nms.VolatileCodeEnabled_v1_18_R2;
import io.lumine.cosmetics.nms.cosmetic.VolatileEquipmentHelper;
......@@ -70,17 +72,13 @@ public class VolatileOffhandImpl implements VolatileEquipmentHelper {
if(packet instanceof ClientboundAddPlayerPacket playerPacket) {
int id = playerPacket.getEntityId();
Profile profile = getProfile(receiver, id);
if(profile != null)
if(profile != null && !profile.isHidden(Offhand.class))
return handleSpawn(profile);
}else if(packet instanceof ClientboundSetEquipmentPacket equipmentPacket) {
int id = equipmentPacket.getEntity();
Profile profile = getProfile(receiver, id);
if(profile != null)
if(profile != null && !profile.isHidden(Offhand.class))
return handleSpawn(profile);
}else if(packet instanceof ClientboundEntityEventPacket entityEventPacket){
if(entityEventPacket.getEventId() == 55) {
// TODO: 20/4/2022 override this
}
}
return null;
......
......@@ -49,11 +49,13 @@ public class VolatileChannelHandler extends ChannelDuplexHandler {
@Override
public void channelRead(ChannelHandlerContext ctx, Object obj) throws Exception {
boolean isCanceled = false;
for(final var helper : nmsHandler.getCosmeticHelpers()) {
helper.read(player, obj);
isCanceled |= !helper.read(player, obj, isCanceled);
}
super.channelRead(ctx, obj);
if(!isCanceled)
super.channelRead(ctx, obj);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment