mirror of
https://github.com/HibiscusMC/HMCCosmetics.git
synced 2025-12-25 01:49:24 +00:00
Compare commits
57 Commits
1_11_2_dev
...
1_11_2_pli
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6e94d74990 | ||
|
|
5e3edd472c | ||
|
|
791fe53c48 | ||
|
|
c9f7762a26 | ||
|
|
1be95c78c2 | ||
|
|
2be06e3ad9 | ||
|
|
d4bf6f256b | ||
|
|
5ffe39cdba | ||
|
|
e6c81f8d1e | ||
|
|
0378b98967 | ||
|
|
a26edbfc9c | ||
|
|
19e8a3bf10 | ||
|
|
b8aefbacdb | ||
|
|
7a29aa8927 | ||
|
|
482aec27f1 | ||
|
|
007e5487e6 | ||
|
|
e7f077af7a | ||
|
|
99b1afd15c | ||
|
|
3f5acde838 | ||
|
|
2676505c9a | ||
|
|
f5d1a09d28 | ||
|
|
1b9e2ac531 | ||
|
|
b005614881 | ||
|
|
a41fb7df2b | ||
|
|
e0fbbc7f76 | ||
|
|
cb09da91fe | ||
|
|
cd7ed29522 | ||
|
|
f5a7c2f9f0 | ||
|
|
6af8e13dab | ||
|
|
e3f081f1c9 | ||
|
|
c7ba2f179a | ||
|
|
8f012f6c97 | ||
|
|
e95b30131c | ||
|
|
2dc068a938 | ||
|
|
7bdc122cb1 | ||
|
|
a3d57af18d | ||
|
|
235c0a9307 | ||
|
|
4d7e565c23 | ||
|
|
57d3110740 | ||
|
|
61e226b826 | ||
|
|
bd7b045c0f | ||
|
|
1ce28a9f66 | ||
|
|
70c2b79b6c | ||
|
|
39d485ddfe | ||
|
|
548a6bf4ec | ||
|
|
fb15919f52 | ||
|
|
9a5923bb7d | ||
|
|
02239396f0 | ||
|
|
942d48adf8 | ||
|
|
99ae2b765a | ||
|
|
6b59ba88a5 | ||
|
|
4d7dff885a | ||
|
|
f4bc6f1bc3 | ||
|
|
938dfe677d | ||
|
|
1c30924410 | ||
|
|
bd731c8b6b | ||
|
|
41f4f830d1 |
@@ -7,7 +7,7 @@ plugins {
|
||||
}
|
||||
|
||||
group = "io.github.fisher2911"
|
||||
version = "1.11.0-BETA-4"
|
||||
version = "1.12.0-BETA-5"
|
||||
description = "Intuitive, easy-to-use cosmetics plugin, designed for servers using resource packs.\n"
|
||||
|
||||
repositories {
|
||||
@@ -21,7 +21,13 @@ repositories {
|
||||
maven("https://mvnrepository.com/artifact/com.zaxxer/HikariCP")
|
||||
maven("https://repo.jeff-media.de/maven2/")
|
||||
maven("https://repo.citizensnpcs.co")
|
||||
maven("https://mvn.lumine.io/repository/maven-public")
|
||||
//maven("https://mvn.lumine.io/repository/maven-public")
|
||||
maven {
|
||||
url = uri("https://mvn.lumine.io/repository/maven-public")
|
||||
metadataSources {
|
||||
artifact()
|
||||
}
|
||||
}
|
||||
maven("https://jitpack.io/")
|
||||
}
|
||||
|
||||
@@ -32,22 +38,22 @@ dependencies {
|
||||
// implementation(project(":nms"))
|
||||
compileOnly("com.mojang:authlib:1.5.25")
|
||||
compileOnly("org.spigotmc:spigot:1.16.5-R0.1-SNAPSHOT")
|
||||
compileOnly("org.jetbrains:annotations:22.0.0")
|
||||
// compileOnly("com.comphenix.protocol:ProtocolLib:4.7.0")
|
||||
compileOnly("org.jetbrains:annotations:23.0.0")
|
||||
compileOnly("com.comphenix.protocol:ProtocolLib:5.0.0-SNAPSHOT")
|
||||
compileOnly("me.clip:placeholderapi:2.11.1")
|
||||
compileOnly("com.github.oraxen:oraxen:-SNAPSHOT")
|
||||
compileOnly("com.github.LoneDev6:API-ItemsAdder:2.5.4")
|
||||
compileOnly("net.citizensnpcs:citizens-main:2.0.29-SNAPSHOT")
|
||||
compileOnly("com.ticxo.modelengine:api:R2.5.0:")
|
||||
compileOnly("com.github.retrooper.packetevents:spigot:2.0-SNAPSHOT")
|
||||
implementation("net.kyori:adventure-api:4.10.0")
|
||||
implementation ("net.kyori:adventure-text-minimessage:4.10.0-SNAPSHOT")
|
||||
implementation("net.kyori:adventure-platform-bukkit:4.0.1")
|
||||
implementation("dev.triumphteam:triumph-gui:3.1.2")
|
||||
compileOnly("net.citizensnpcs:citizens-main:2.0.30-SNAPSHOT")
|
||||
compileOnly("com.ticxo.modelengine:api:R3.0.0")
|
||||
//compileOnly("com.github.retrooper.packetevents:spigot:2.0-SNAPSHOT")
|
||||
implementation("net.kyori:adventure-api:4.11.0")
|
||||
implementation ("net.kyori:adventure-text-minimessage:4.11.0")
|
||||
implementation("net.kyori:adventure-platform-bukkit:4.1.2")
|
||||
implementation("dev.triumphteam:triumph-gui:3.1.3")
|
||||
implementation("me.mattstudios.utils:matt-framework:1.4.6")
|
||||
implementation("org.spongepowered:configurate-yaml:4.1.2")
|
||||
implementation("org.bstats:bstats-bukkit:2.2.1")
|
||||
implementation("com.zaxxer:HikariCP:5.0.0")
|
||||
implementation("org.bstats:bstats-bukkit:3.0.0")
|
||||
implementation("com.zaxxer:HikariCP:5.0.1")
|
||||
implementation("com.j256.ormlite:ormlite-jdbc:6.1")
|
||||
implementation("com.j256.ormlite:ormlite-core:6.1")
|
||||
}
|
||||
@@ -105,7 +111,7 @@ bukkit {
|
||||
name = "HMCCosmetics"
|
||||
authors = listOf("MasterOfTheFish")
|
||||
softDepend = listOf("Multiverse", "PlaceholderAPI", "Oraxen", "ItemsAdder", "Citizens", "ModelEngine")
|
||||
depend = listOf("packetevents")
|
||||
depend = listOf("ProtocolLib")
|
||||
permissions {
|
||||
register("hmccosmetics.cmd.default") {
|
||||
default = BukkitPluginDescription.Permission.Default.OP
|
||||
@@ -141,3 +147,22 @@ bukkit {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val copyJar: String? by project
|
||||
val pluginPath = project.findProperty("hibiscusmc_plugin_path")
|
||||
|
||||
if(copyJar != "false" && pluginPath != null) {
|
||||
tasks {
|
||||
register<Copy>("copyJar") {
|
||||
from(findByName("reobfJar") ?: findByName("shadowJar") ?: findByName("jar"))
|
||||
into(pluginPath)
|
||||
doLast {
|
||||
println("Copied to plugin directory $pluginPath")
|
||||
}
|
||||
}
|
||||
|
||||
named<DefaultTask>("build") {
|
||||
dependsOn("copyJar")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.github.fisher2911.hmccosmetics;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.ProtocolManager;
|
||||
import io.github.fisher2911.hmccosmetics.command.CosmeticsCommand;
|
||||
import io.github.fisher2911.hmccosmetics.concurrent.Threads;
|
||||
import io.github.fisher2911.hmccosmetics.config.Settings;
|
||||
@@ -24,6 +25,7 @@ import io.github.fisher2911.hmccosmetics.listener.WardrobeListener;
|
||||
import io.github.fisher2911.hmccosmetics.message.MessageHandler;
|
||||
import io.github.fisher2911.hmccosmetics.message.Messages;
|
||||
import io.github.fisher2911.hmccosmetics.message.Translation;
|
||||
import io.github.fisher2911.hmccosmetics.packet.PacketManager;
|
||||
import io.github.fisher2911.hmccosmetics.task.TaskManager;
|
||||
import io.github.fisher2911.hmccosmetics.user.UserManager;
|
||||
import me.mattstudios.mf.base.CommandManager;
|
||||
@@ -57,6 +59,7 @@ public class HMCCosmetics extends JavaPlugin {
|
||||
private Database database;
|
||||
|
||||
private BukkitTask saveTask;
|
||||
private ProtocolManager manager;
|
||||
|
||||
/* // commented because PacketEvents is no longer shaded
|
||||
@Override
|
||||
@@ -77,6 +80,7 @@ public class HMCCosmetics extends JavaPlugin {
|
||||
this.cosmeticManager = new CosmeticManager(new HashMap<>(), new HashMap<>(), new HashMap<>());
|
||||
this.cosmeticsMenu = new CosmeticsMenu(this);
|
||||
this.tokenLoader = new TokenLoader(this);
|
||||
this.manager = ProtocolLibrary.getProtocolManager();
|
||||
|
||||
this.userManager.startTeleportTask();
|
||||
|
||||
@@ -86,6 +90,7 @@ public class HMCCosmetics extends JavaPlugin {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
|
||||
PacketManager.setupPackets();
|
||||
this.registerCommands();
|
||||
this.registerListeners();
|
||||
|
||||
@@ -107,7 +112,7 @@ public class HMCCosmetics extends JavaPlugin {
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
PacketEvents.getAPI().terminate();
|
||||
//PacketEvents.getAPI().terminate();
|
||||
this.saveTask.cancel();
|
||||
this.database.saveAll();
|
||||
this.messageHandler.close();
|
||||
@@ -241,6 +246,9 @@ public class HMCCosmetics extends JavaPlugin {
|
||||
public Database getDatabase() {
|
||||
return database;
|
||||
}
|
||||
public ProtocolManager getProtocolManager() {
|
||||
return manager;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
package io.github.fisher2911.hmccosmetics.config;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.sound.SoundCategory;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
||||
import net.minecraft.server.v1_16_R3.MinecraftKey;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class SoundData {
|
||||
|
||||
private final String name;
|
||||
private final SoundCategory soundCategory;
|
||||
private final EnumWrappers.SoundCategory soundCategory;
|
||||
private final float volume;
|
||||
private final float pitch;
|
||||
|
||||
public SoundData(final String name, final SoundCategory soundCategory, final float volume, final float pitch) {
|
||||
public SoundData(final String name, final EnumWrappers.SoundCategory soundCategory, final float volume, final float pitch) {
|
||||
this.name = name;
|
||||
this.soundCategory = soundCategory;
|
||||
this.volume = volume;
|
||||
@@ -30,7 +30,7 @@ public class SoundData {
|
||||
return pitch;
|
||||
}
|
||||
|
||||
public SoundCategory getSoundCategory() {
|
||||
public EnumWrappers.SoundCategory getSoundCategory() {
|
||||
return soundCategory;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.github.fisher2911.hmccosmetics.config;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.sound.SoundCategory;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
import org.spongepowered.configurate.serialize.SerializationException;
|
||||
@@ -37,7 +37,7 @@ public class SoundSerializer implements TypeSerializer<SoundData> {
|
||||
} else {
|
||||
soundData = new SoundData(
|
||||
soundName,
|
||||
SoundCategory.valueOf(category),
|
||||
EnumWrappers.SoundCategory.valueOf(category),
|
||||
volume,
|
||||
pitch
|
||||
);
|
||||
|
||||
@@ -27,6 +27,8 @@ public class WardrobeSettings {
|
||||
private static final String STATIC_LOCATION_PATH = "wardrobe-location";
|
||||
private static final String VIEWER_LOCATION_PATH = "viewer-location";
|
||||
private static final String LEAVE_LOCATION_PATH = "leave-location";
|
||||
private static final String EQUIP_PUMPKIN_WARDROBE = "equip-pumpkin";
|
||||
private static final String RETURN_LAST_LOCATION = "return-last-location";
|
||||
|
||||
private final HMCCosmetics plugin;
|
||||
|
||||
@@ -39,6 +41,8 @@ public class WardrobeSettings {
|
||||
private int spawnDelay;
|
||||
private int despawnDelay;
|
||||
private boolean applyCosmeticsOnClose;
|
||||
private boolean equipPumpkin;
|
||||
private boolean returnLastLocation;
|
||||
private SoundData openSound;
|
||||
private SoundData closeSound;
|
||||
private Location wardrobeLocation;
|
||||
@@ -71,6 +75,8 @@ public class WardrobeSettings {
|
||||
this.spawnDelay = source.node(SPAWN_DELAY_PATH).getInt();
|
||||
this.despawnDelay = source.node(DESPAWN_DELAY_PATH).getInt();
|
||||
this.applyCosmeticsOnClose = source.node(APPLY_COSMETICS_ON_CLOSE).getBoolean();
|
||||
this.equipPumpkin = source.node(EQUIP_PUMPKIN_WARDROBE).getBoolean();
|
||||
this.returnLastLocation = source.node(RETURN_LAST_LOCATION).getBoolean();
|
||||
this.openSound = source.node(OPEN_SOUND).get(SoundData.class);
|
||||
this.closeSound = source.node(CLOSE_SOUND).get(SoundData.class);
|
||||
this.wardrobeLocation = source.node(STATIC_LOCATION_PATH).get(Location.class);
|
||||
@@ -116,6 +122,12 @@ public class WardrobeSettings {
|
||||
public boolean isApplyCosmeticsOnClose() {
|
||||
return applyCosmeticsOnClose;
|
||||
}
|
||||
public boolean isEquipPumpkin() {
|
||||
return equipPumpkin;
|
||||
}
|
||||
public boolean isReturnLastLocation() {
|
||||
return returnLastLocation;
|
||||
}
|
||||
|
||||
public Location getWardrobeLocation() {
|
||||
return this.wardrobeLocation.clone();
|
||||
|
||||
@@ -96,6 +96,7 @@ public class CosmeticManager {
|
||||
|
||||
public void load() {
|
||||
this.clearItems();
|
||||
this.backpackParticleCounts.clear();
|
||||
try {
|
||||
final File file = ITEMS_PATH.toFile();
|
||||
if (!file.exists()) {
|
||||
@@ -115,7 +116,7 @@ public class CosmeticManager {
|
||||
if (item instanceof ArmorItem armorItem) {
|
||||
armorItem.setAction(null);
|
||||
if (armorItem.getType() == ArmorItem.Type.SELF_BACKPACK) {
|
||||
final int particleCount = node.node(PARTICLE_COUNT).getInt(0);
|
||||
final int particleCount = node.node(PARTICLE_COUNT).getInt(5);
|
||||
this.backpackParticleCounts.put(armorItem.getId(), particleCount);
|
||||
}
|
||||
this.armorItemMap.put(armorItem.getId(), armorItem);
|
||||
|
||||
@@ -16,13 +16,15 @@ import io.github.fisher2911.hmccosmetics.user.EntityIds;
|
||||
import io.github.fisher2911.hmccosmetics.user.NPCUser;
|
||||
import io.github.fisher2911.hmccosmetics.user.User;
|
||||
import io.github.fisher2911.hmccosmetics.user.Wardrobe;
|
||||
import io.github.retrooper.packetevents.util.SpigotReflectionUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class Database {
|
||||
@@ -234,6 +236,7 @@ public class Database {
|
||||
}
|
||||
|
||||
public static int getNextEntityId() {
|
||||
return SpigotReflectionUtil.generateEntityId();
|
||||
Random random = new Random();
|
||||
return random.nextInt(999999);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,18 +348,6 @@ public class ArmorItem extends WrappedGuiItem {
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Type fromPacketSlot(final com.github.retrooper.packetevents.protocol.player.EquipmentSlot slot) {
|
||||
return switch (slot) {
|
||||
case HELMET -> Type.HAT;
|
||||
case CHEST_PLATE -> Type.CHEST_PLATE;
|
||||
case LEGGINGS -> Type.PANTS;
|
||||
case BOOTS -> Type.BOOTS;
|
||||
case OFF_HAND -> Type.OFF_HAND;
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Type fromEquipmentSlot(final EquipmentSlot slot) {
|
||||
for (final Type type : values()) {
|
||||
|
||||
@@ -55,13 +55,19 @@ public class HookManager {
|
||||
this.listeners.add(itemsAdderHook);
|
||||
}
|
||||
if (pluginManager.getPlugin("Citizens") != null) {
|
||||
this.citizensHook = null;
|
||||
/*
|
||||
this.registerHook(citizensHook.getClass());
|
||||
this.listeners.add(citizensHook);
|
||||
this.citizensHook = citizensHook;
|
||||
this.plugin.getLogger().info("Successfully Hooked into Citizens!");
|
||||
*/
|
||||
} else {
|
||||
this.citizensHook = null;
|
||||
}
|
||||
if (pluginManager.getPlugin("ModelEngine") != null) {
|
||||
this.plugin.getLogger().info("ModelEngine has been detected and has been enabled.");
|
||||
// 3.0 Model Engine Beta
|
||||
final ModelEngineHook modelEngineHook = new ModelEngineHook();
|
||||
this.registerHook(modelEngineHook.getClass());
|
||||
this.modelEngineHook = modelEngineHook;
|
||||
|
||||
@@ -3,121 +3,105 @@ package io.github.fisher2911.hmccosmetics.hook.entity;
|
||||
import com.ticxo.modelengine.api.ModelEngineAPI;
|
||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||
import com.ticxo.modelengine.api.model.ModeledEntity;
|
||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BalloonEntity {
|
||||
|
||||
private final int balloonID;
|
||||
private final MEGEntity megEntity;
|
||||
// private final UUID uuid;
|
||||
// private final int entityId;
|
||||
// private EntityType entityType;
|
||||
// private Vector velocity;
|
||||
// private Location location;
|
||||
// private boolean alive;
|
||||
|
||||
public BalloonEntity(final UUID uuid, final int entityId, final EntityType entityType, final Vector velocity, final Location location, final boolean alive) {
|
||||
this.megEntity = new MEGEntity(uuid, entityId, entityType, velocity, location, alive);
|
||||
// this.uuid = uuid;
|
||||
// this.entityId = entityId;
|
||||
// this.entityType = entityType;
|
||||
// this.velocity = velocity;
|
||||
// this.location = location;
|
||||
// this.alive = alive;
|
||||
// this.megEntity = new MEGEntity(this);
|
||||
public BalloonEntity(int balloonID, Location location) {
|
||||
this.balloonID = balloonID;
|
||||
this.megEntity = new MEGEntity(UUID.randomUUID(), balloonID, new Vector(0, 0, 0), location, false);
|
||||
}
|
||||
|
||||
public BalloonEntity(final UUID uuid, final int entityId, final EntityType entityType) {
|
||||
// this.uuid = uuid;
|
||||
// this.entityId = entityId;
|
||||
// this.entityType = entityType;
|
||||
this.megEntity = new MEGEntity(uuid, entityId, entityType);
|
||||
public void updateModel() {
|
||||
final ModeledEntity model = ModelEngineAPI.api.getModeledEntity(megEntity.getUniqueId());
|
||||
|
||||
if (model == null) return;
|
||||
|
||||
if (model.getBase() instanceof final MEGEntity e) e.update(this);
|
||||
}
|
||||
|
||||
public UUID getUuid() {
|
||||
return this.megEntity.getUuid();
|
||||
public void spawnModel(final String id) {
|
||||
HMCCosmetics.getPlugin(HMCCosmetics.class).getLogger().info("Attempting Spawning");
|
||||
if (ModelEngineAPI.api.getModelRegistry().getBlueprint(id) == null) {
|
||||
HMCCosmetics.getPlugin(HMCCosmetics.class).getLogger().warning("Invalid Model Engine Blueprint " + id);
|
||||
HMCCosmetics.getPlugin(HMCCosmetics.class).getLogger().warning("Possible Blueprints" + ModelEngineAPI.api.getModelRegistry().getAllBlueprintId());
|
||||
return;
|
||||
}
|
||||
final ActiveModel model = ModelEngineAPI.api.createActiveModelImpl(ModelEngineAPI.getBlueprint(id));
|
||||
ModeledEntity modeledEntity = ModelEngineAPI.api.createModeledEntityImpl(megEntity);
|
||||
modeledEntity.addModel(model, false);
|
||||
HMCCosmetics.getPlugin(HMCCosmetics.class).getLogger().info("Spawned Model");
|
||||
}
|
||||
|
||||
public int getEntityId() {
|
||||
return this.megEntity.getEntityId();
|
||||
public void remove() {
|
||||
final ModeledEntity entity = ModelEngineAPI.api.getModeledEntity(megEntity.getUniqueId());
|
||||
|
||||
if (entity == null) return;
|
||||
|
||||
for (final Player player : entity.getRangeManager().getPlayerInRange()) {
|
||||
entity.hideFromPlayer(player);
|
||||
}
|
||||
|
||||
//ModelEngineAPI.removeModeledEntity(megEntity.getUniqueId());
|
||||
entity.destroy();
|
||||
}
|
||||
|
||||
public EntityType getType() {
|
||||
return this.megEntity.getType();
|
||||
public void addPlayerToModel(final Player player, final String id) {
|
||||
final ModeledEntity model = ModelEngineAPI.api.getModeledEntity(megEntity.getUniqueId());
|
||||
if (model == null) {
|
||||
this.spawnModel(id);
|
||||
return;
|
||||
}
|
||||
if (megEntity.getRangeManager().getPlayerInRange().contains(player)) return;
|
||||
model.showToPlayer(player);
|
||||
HMCCosmetics.getPlugin(HMCCosmetics.class).getLogger().info("Added " + player.getName() + " to " + id);
|
||||
}
|
||||
|
||||
public Vector getVelocity() {
|
||||
return this.megEntity.getVelocity();
|
||||
public void removePlayerFromModel(final Player player) {
|
||||
final ModeledEntity model = ModelEngineAPI.api.getModeledEntity(megEntity.getUniqueId());
|
||||
|
||||
if (model == null) return;
|
||||
|
||||
model.hideFromPlayer(player);
|
||||
}
|
||||
|
||||
public void setVelocity(final Vector velocity) {
|
||||
this.megEntity.setVelocity(velocity);
|
||||
|
||||
public int getBalloonID() {
|
||||
return balloonID;
|
||||
}
|
||||
|
||||
public UUID getUniqueID() {
|
||||
return megEntity.getUniqueId();
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
return this.megEntity.getLocation();
|
||||
}
|
||||
|
||||
public void setLocation(final Location location) {
|
||||
this.megEntity.setLocation(location);
|
||||
}
|
||||
|
||||
public boolean isAlive() {
|
||||
return this.megEntity.isAlive();
|
||||
}
|
||||
|
||||
public void setAlive(final boolean alive) {
|
||||
public void setLocation(Location location) {
|
||||
this.megEntity.setLocation(location);
|
||||
}
|
||||
|
||||
public void setVelocity(Vector vector) {
|
||||
this.megEntity.setVelocity(vector);
|
||||
}
|
||||
|
||||
public void setAlive(boolean alive) {
|
||||
this.megEntity.setAlive(alive);
|
||||
}
|
||||
|
||||
public void updateModel() {
|
||||
final ModeledEntity model = ModelEngineAPI.getModeledEntity(this.getUuid());
|
||||
|
||||
if (model == null) return;
|
||||
|
||||
if (model.getEntity() instanceof final MEGEntity e) e.update(this);
|
||||
}
|
||||
|
||||
public void spawnModel(final String id) {
|
||||
if (ModelEngineAPI.getModeledEntity(this.getUuid()) != null) return;
|
||||
final ActiveModel model = ModelEngineAPI.createActiveModel(id);
|
||||
ModeledEntity modeledEntity = ModelEngineAPI.api.getModelManager().createModeledEntity(this.megEntity);
|
||||
modeledEntity.addActiveModel(model);
|
||||
}
|
||||
|
||||
public void addPlayerToModel(final Player player, final String id) {
|
||||
final ModeledEntity model = ModelEngineAPI.getModeledEntity(this.getUuid());
|
||||
if (model == null) {
|
||||
this.spawnModel(id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (model.getPlayerInRange().contains(player)) return;
|
||||
model.addPlayerAsync(player);
|
||||
}
|
||||
|
||||
public void removePlayerFromModel(final Player player) {
|
||||
final ModeledEntity model = ModelEngineAPI.getModeledEntity(this.getUuid());
|
||||
|
||||
if (model == null) return;
|
||||
|
||||
model.removePlayerAsync(player);
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
final ModeledEntity entity = ModelEngineAPI.getModeledEntity(this.getUuid());
|
||||
|
||||
if (entity == null) return;
|
||||
|
||||
for (final Player player : entity.getPlayerInRange()) {
|
||||
entity.removePlayerAsync(player);
|
||||
}
|
||||
|
||||
ModelEngineAPI.api.getModelManager().removeModeledEntity(this.getUuid());
|
||||
entity.getEntity().remove();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,67 +1,64 @@
|
||||
package io.github.fisher2911.hmccosmetics.hook.entity;
|
||||
|
||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||
import com.ticxo.modelengine.api.model.ModeledEntity;
|
||||
import com.ticxo.modelengine.api.model.base.BaseEntity;
|
||||
import com.ticxo.modelengine.api.model.base.EntityData;
|
||||
import com.ticxo.modelengine.api.entity.BaseEntity;
|
||||
import com.ticxo.modelengine.api.generator.Hitbox;
|
||||
import com.ticxo.modelengine.api.model.IModel;
|
||||
import com.ticxo.modelengine.api.nms.entity.impl.DefaultBodyRotationController;
|
||||
import com.ticxo.modelengine.api.nms.entity.impl.EmptyRangeManager;
|
||||
import com.ticxo.modelengine.api.nms.entity.impl.ManualRangeManager;
|
||||
import com.ticxo.modelengine.api.nms.entity.wrapper.BodyRotationController;
|
||||
import com.ticxo.modelengine.api.nms.entity.wrapper.LookController;
|
||||
import com.ticxo.modelengine.api.nms.entity.wrapper.MoveController;
|
||||
import com.ticxo.modelengine.api.nms.entity.wrapper.RangeManager;
|
||||
import com.ticxo.modelengine.api.nms.world.IDamageSource;
|
||||
import com.ticxo.modelengine.api.utils.data.EntityData;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class MEGEntity implements BaseEntity<MEGEntity> {
|
||||
public class MEGEntity implements BaseEntity {
|
||||
|
||||
private final UUID uuid;
|
||||
private final int entityId;
|
||||
private final EntityType entityType;
|
||||
private Vector velocity = new Vector(0, 0, 0);
|
||||
private Location location;
|
||||
private boolean alive;
|
||||
private BodyRotationController rotationController;
|
||||
private List<Entity> passengers;
|
||||
private RangeManager rangeManager;
|
||||
|
||||
public MEGEntity(final BalloonEntity entity) {
|
||||
this.uuid = entity.getUuid();
|
||||
this.entityId = entity.getEntityId();
|
||||
this.entityType = entity.getType();
|
||||
this.velocity = entity.getVelocity();
|
||||
this.location = entity.getLocation();
|
||||
this.alive = entity.isAlive();
|
||||
}
|
||||
|
||||
protected MEGEntity(final UUID uuid, final int entityId, final EntityType entityType, final Vector velocity, final Location location, final boolean alive) {
|
||||
protected MEGEntity(final UUID uuid, final int entityId, final Vector velocity, final Location location, final boolean alive) {
|
||||
this.uuid = uuid;
|
||||
this.entityId = entityId;
|
||||
this.entityType = entityType;
|
||||
this.velocity = velocity;
|
||||
this.location = location;
|
||||
this.alive = alive;
|
||||
this.rotationController = new DefaultBodyRotationController(this);
|
||||
this.passengers = new ArrayList<>();
|
||||
this.rangeManager = new EmptyRangeManager();
|
||||
this.rangeManager.setRenderDistance(16);
|
||||
}
|
||||
|
||||
protected MEGEntity(final UUID uuid, final int entityId, final EntityType entityType) {
|
||||
protected MEGEntity(final UUID uuid, final int entityId) {
|
||||
this.uuid = uuid;
|
||||
this.entityId = entityId;
|
||||
this.entityType = entityType;
|
||||
this.alive = false;
|
||||
}
|
||||
|
||||
public void update(final BalloonEntity entity) {
|
||||
this.velocity = entity.getVelocity();
|
||||
this.velocity = entity.getLocation().toVector();
|
||||
this.location = entity.getLocation();
|
||||
this.alive = entity.isAlive();
|
||||
}
|
||||
|
||||
public UUID getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public void setVelocity(final Vector velocity) {
|
||||
this.velocity = velocity;
|
||||
}
|
||||
@@ -82,54 +79,96 @@ public class MEGEntity implements BaseEntity<MEGEntity> {
|
||||
return entityData;
|
||||
}
|
||||
|
||||
final EntityData entityData = new EntityData();
|
||||
|
||||
@Override
|
||||
public MEGEntity getBase() {
|
||||
return this;
|
||||
public Object getOriginal() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
return this.location;
|
||||
public MoveController wrapMoveControl() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector getVelocity() {
|
||||
return velocity;
|
||||
public LookController wrapLookControl() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnGround() {
|
||||
public BodyRotationController wrapBodyRotationControl() {
|
||||
return this.rotationController;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void wrapNavigation() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public RangeManager wrapRangeManager(IModel model) {
|
||||
return new ManualRangeManager(this, model);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RangeManager getRangeManager() {
|
||||
if (this.rangeManager == null) {
|
||||
RangeManager rangeMan = new EmptyRangeManager();
|
||||
rangeMan.setRenderDistance(16);
|
||||
return rangeMan;
|
||||
}
|
||||
return this.rangeManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onHurt(IDamageSource damageSource, float damage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getWorld() {
|
||||
return this.location.getWorld();
|
||||
public void onInteract(Player player, EquipmentSlot hand) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Entity> getNearbyEntities(final double v, final double v1, final double v2) {
|
||||
return Collections.emptyList();
|
||||
public void setHitbox(Hitbox hitbox) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hitbox getHitbox() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStepHeight(double height) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getStepHeight() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCollidableToLiving(LivingEntity living, boolean isRemove) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void broadcastSpawnPacket() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void broadcastDespawnPacket() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEntityId() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
this.alive = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCustomNameVisible() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDead() {
|
||||
return !this.alive;
|
||||
return this.entityId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -138,139 +177,66 @@ public class MEGEntity implements BaseEntity<MEGEntity> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getType() {
|
||||
return EntityType.PUFFERFISH;
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInvulnerable() {
|
||||
return true;
|
||||
public World getWorld() {
|
||||
return this.getWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasGravity() {
|
||||
public boolean isDead() {
|
||||
return alive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGlowing() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGravity(final boolean flag) {
|
||||
public boolean isOnGround() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMoving() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setYHeadRot(float rot) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getHealth() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getMaxHealth() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCustomName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomName(final String s) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getMovementSpeed() {
|
||||
public float getYHeadRot() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItemInMainHand() {
|
||||
return null;
|
||||
public float getXHeadRot() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItemInOffHand() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLivingEntity() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPotionEffect(final PotionEffect potion) {
|
||||
public void setYBodyRot(float rot) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePotionEffect(final PotionEffectType potion) {
|
||||
|
||||
public float getYBodyRot() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEntitySize(final float width, final float height, final float eye) {
|
||||
|
||||
public List<Entity> getPassengers() {
|
||||
return this.passengers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendDespawnPacket(final ModeledEntity modeledEntity) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSpawnPacket(final ModeledEntity modeledEntity) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getLastX() {
|
||||
return this.location.getX();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getLastY() {
|
||||
return this.location.getY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getLastZ() {
|
||||
return this.location.getZ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getWantedX() {
|
||||
return this.location.getX();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getWantedY() {
|
||||
return this.location.getY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getWantedZ() {
|
||||
return this.location.getZ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveModelList(final Map<String, ActiveModel> models) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveModelInfo(final ModeledEntity model) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getModelList() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final EntityData entityData = new EntityData();
|
||||
|
||||
@Override
|
||||
public EntityData loadModelInfo() {
|
||||
return this.entityData;
|
||||
public Vector getVelocity() {
|
||||
return velocity;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
package io.github.fisher2911.hmccosmetics.listener;
|
||||
|
||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
||||
import io.github.fisher2911.hmccosmetics.user.Equipment;
|
||||
import io.github.fisher2911.hmccosmetics.user.User;
|
||||
import io.github.fisher2911.hmccosmetics.user.UserManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
public class ClickListener implements Listener {
|
||||
|
||||
@@ -56,15 +60,18 @@ public class ClickListener implements Listener {
|
||||
this.plugin = plugin;
|
||||
this.userManager = this.plugin.getUserManager();
|
||||
}
|
||||
/*
|
||||
|
||||
// @EventHandler
|
||||
// public void onArmorSlotClick(final InventoryClickEvent event) {
|
||||
// final int slot = event.getSlot();
|
||||
// if (!(event.getWhoClicked() instanceof final Player player)) return;
|
||||
// if (slot >= 36 && slot <= 40) {
|
||||
// this.fixInventory(player);
|
||||
// }
|
||||
// }
|
||||
@EventHandler
|
||||
public void onArmorSlotClick(final InventoryClickEvent event) {
|
||||
final int slot = event.getSlot();
|
||||
if (!(event.getWhoClicked() instanceof Player)) return;
|
||||
if (slot >= 36 && slot <= 40) {
|
||||
this.fixInventory(((Player) event.getWhoClicked()).getPlayer());
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
//
|
||||
// @EventHandler
|
||||
// public void onBlockClick(final PlayerInteractEvent event) {
|
||||
@@ -102,22 +109,25 @@ public class ClickListener implements Listener {
|
||||
// this.userManager.get(player.getUniqueId()).ifPresent(this::doRunnable);
|
||||
// }
|
||||
//
|
||||
// private void fixInventory(final Player player) {
|
||||
// final Optional<User> optionalUser = this.userManager.get(player.getUniqueId());
|
||||
//
|
||||
// if (optionalUser.isEmpty()) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// this.doRunnable(optionalUser.get());
|
||||
// }
|
||||
//
|
||||
// private void doRunnable(final User user) {
|
||||
// Bukkit.getScheduler().runTaskLaterAsynchronously(
|
||||
// this.plugin, () -> this.userManager.updateCosmetics(user),
|
||||
// 1);
|
||||
// }
|
||||
//
|
||||
/*
|
||||
private void fixInventory(final Player player) {
|
||||
final Optional<User> optionalUser = this.userManager.get(player.getUniqueId());
|
||||
|
||||
if (optionalUser.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.doRunnable(optionalUser.get());
|
||||
}
|
||||
|
||||
private void doRunnable(final User user) {
|
||||
Equipment equip = this.userManager.getItemList(user, user.getEquipment(), Collections.emptySet());
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(
|
||||
this.plugin, () -> this.userManager.sendUpdatePacket(user, equip),
|
||||
1);
|
||||
}
|
||||
*/
|
||||
|
||||
// private void checkFix(final Player player, final int clickedSlot, final ItemStack itemStack) {
|
||||
// final EquipmentSlot slot = this.getArmorSlot(itemStack.getType());
|
||||
// if (slot == null) return;
|
||||
@@ -138,5 +148,4 @@ public class ClickListener implements Listener {
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
package io.github.fisher2911.hmccosmetics.listener;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.event.PacketListenerAbstract;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.event.PacketSendEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientClickWindow;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerWindowItems;
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
||||
import io.github.fisher2911.hmccosmetics.config.CosmeticSettings;
|
||||
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
||||
import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor;
|
||||
import io.github.fisher2911.hmccosmetics.packet.PacketManager;
|
||||
import io.github.fisher2911.hmccosmetics.packet.wrappers.WrapperPlayClientWindowClick;
|
||||
import io.github.fisher2911.hmccosmetics.packet.wrappers.WrapperPlayServerWindowItems;
|
||||
import io.github.fisher2911.hmccosmetics.task.DelayedTask;
|
||||
import io.github.fisher2911.hmccosmetics.task.TaskManager;
|
||||
import io.github.fisher2911.hmccosmetics.user.Equipment;
|
||||
import io.github.fisher2911.hmccosmetics.user.User;
|
||||
import io.github.fisher2911.hmccosmetics.user.UserManager;
|
||||
import io.github.fisher2911.hmccosmetics.util.Utils;
|
||||
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@@ -36,13 +35,8 @@ import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class CosmeticFixListener implements Listener {
|
||||
|
||||
@@ -122,6 +116,7 @@ public class CosmeticFixListener implements Listener {
|
||||
if (type == null) return;
|
||||
|
||||
this.taskManager.submit(() -> {
|
||||
|
||||
final EntityEquipment equipment = player.getEquipment();
|
||||
final ItemStack current;
|
||||
if (equipment == null) {
|
||||
@@ -140,117 +135,139 @@ public class CosmeticFixListener implements Listener {
|
||||
}
|
||||
|
||||
private void registerInventoryClickListener() {
|
||||
PacketEvents.getAPI().getEventManager().registerListener(
|
||||
new PacketListenerAbstract() {
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() != PacketType.Play.Client.CLICK_WINDOW) return;
|
||||
final WrapperPlayClientClickWindow packet = new WrapperPlayClientClickWindow(event);
|
||||
if (packet.getWindowId() != 0) return;
|
||||
if (!(event.getPlayer() instanceof final Player player)) return;
|
||||
int slotClicked = packet.getSlot();
|
||||
taskManager.submit(() -> {
|
||||
final Optional<User> optionalUser = userManager.get(player.getUniqueId());
|
||||
if (optionalUser.isEmpty()) return;
|
||||
final User user = optionalUser.get();
|
||||
EquipmentSlot slot = getPacketArmorSlot(slotClicked);
|
||||
if (slot == null) {
|
||||
return;
|
||||
}
|
||||
final EntityEquipment entityEquipment = player.getEquipment();
|
||||
if (entityEquipment == null) return;
|
||||
final ItemStack current = Utils.replaceIfNull(entityEquipment.getItem(slot), new ItemStack(Material.AIR));
|
||||
final ArmorItem.Type type = ArmorItem.Type.fromEquipmentSlot(slot);
|
||||
if (type == null) return;
|
||||
updateOnClick(
|
||||
player,
|
||||
slot,
|
||||
user,
|
||||
type,
|
||||
current
|
||||
);
|
||||
});
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmetics.getPlugin(HMCCosmetics.class), ListenerPriority.NORMAL, PacketType.Play.Client.WINDOW_CLICK) {
|
||||
@Override
|
||||
public void onPacketReceiving(PacketEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
int invTypeClicked = event.getPacket().getIntegers().read(0);
|
||||
int slotClicked = event.getPacket().getIntegers().read(2);
|
||||
|
||||
// Must be a player inventory.
|
||||
if (invTypeClicked != 0) return;
|
||||
// -999 is when a player clicks outside their inventory. https://wiki.vg/Inventory#Player_Inventory
|
||||
if (slotClicked == -999) return;
|
||||
if (!(event.getPlayer() instanceof Player)) return;
|
||||
taskManager.submit(() -> {
|
||||
final Optional<User> optionalUser = userManager.get(player.getUniqueId());
|
||||
if (optionalUser.isEmpty()) return;
|
||||
final User user = optionalUser.get();
|
||||
EquipmentSlot slot = getPacketArmorSlot(slotClicked);
|
||||
if (slot == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
);
|
||||
final EntityEquipment entityEquipment = player.getEquipment();
|
||||
if (entityEquipment == null) return;
|
||||
final ItemStack current = Utils.replaceIfNull(entityEquipment.getItem(slot), new ItemStack(Material.AIR));
|
||||
final ArmorItem.Type type = ArmorItem.Type.fromEquipmentSlot(slot);
|
||||
if (type == null) return;
|
||||
updateOnClick(
|
||||
player,
|
||||
slot,
|
||||
user,
|
||||
type,
|
||||
current
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateOnClick(final Player player, final EquipmentSlot slot, final User user, final ArmorItem.Type type, final ItemStack current) {
|
||||
//plugin.getLogger().log(Level.INFO, "updateOnClick (171)");
|
||||
|
||||
final Location location = player.getLocation();
|
||||
final Equipment equipment = Equipment.fromEntityEquipment(player.getEquipment());
|
||||
final Equipment equipment = new Equipment();
|
||||
final ItemStack cosmetic = userManager.getCosmeticItem(
|
||||
user.getPlayerArmor().getItem(type),
|
||||
current,
|
||||
ArmorItem.Status.APPLIED,
|
||||
slot
|
||||
);
|
||||
//plugin.getLogger().log(Level.INFO, "Set cosmetic in " + slot + " to " + cosmetic);
|
||||
if (cosmetic != null && cosmetic.getType() != Material.AIR) equipment.setItem(slot, cosmetic);
|
||||
//plugin.getLogger().log(Level.INFO, "Set cosmetic in " + slot + " to " + cosmetic + "(done)");
|
||||
|
||||
final List<com.github.retrooper.packetevents.protocol.player.Equipment> items =
|
||||
userManager.getItemList(user, equipment, Collections.emptySet());
|
||||
items.removeIf(e -> {
|
||||
final com.github.retrooper.packetevents.protocol.player.EquipmentSlot s = e.getSlot();
|
||||
final ArmorItem.Type t = ArmorItem.Type.fromPacketSlot(s);
|
||||
if (t == null) return false;
|
||||
/*
|
||||
final Equipment items = userManager.getItemList(user, equipment, Collections.emptySet());
|
||||
for (EquipmentSlot e : items.keys()) {
|
||||
//final EquipmentSlot s = e.getSlot();
|
||||
final ArmorItem.Type t = ArmorItem.Type.fromWrapper(e);
|
||||
ItemStack air = new ItemStack(Material.AIR);
|
||||
if (t == null) {
|
||||
//plugin.getLogger().log(Level.INFO, "T is null");
|
||||
equipment.setItem(e, air);
|
||||
return;
|
||||
}
|
||||
final ArmorItem armorItem = user.getPlayerArmor().getItem(t);
|
||||
final ItemStack i = SpigotConversionUtil.toBukkitItemStack(e.getItem());
|
||||
return armorItem.isEmpty() && i.equals(equipment.getItem(t.getSlot()));
|
||||
});
|
||||
final ItemStack i = equipment.getItem(e);
|
||||
if (i == null) {
|
||||
//plugin.getLogger().log(Level.INFO, "I is null");
|
||||
equipment.setItem(e, air);
|
||||
return;
|
||||
}
|
||||
Boolean remove = armorItem.isEmpty() && i.equals(equipment.getItem(t.getSlot()));
|
||||
if (remove) {
|
||||
//plugin.getLogger().log(Level.INFO, "Boolean is true");
|
||||
equipment.setItem(e, air);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
*/
|
||||
for (final Player other : Bukkit.getOnlinePlayers()) {
|
||||
if (!settings.isInViewDistance(location, other.getLocation())) continue;
|
||||
userManager.sendUpdatePacket(
|
||||
user,
|
||||
items
|
||||
equipment
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void registerMenuChangeListener() {
|
||||
PacketEvents.getAPI().getEventManager().registerListener(
|
||||
new PacketListenerAbstract() {
|
||||
@Override
|
||||
public void onPacketSend(PacketSendEvent event) {
|
||||
if (event.getPacketType() != PacketType.Play.Server.WINDOW_ITEMS) return;
|
||||
final WrapperPlayServerWindowItems packet = new WrapperPlayServerWindowItems(event);
|
||||
if (!(event.getPlayer() instanceof final Player player)) return;
|
||||
final int windowId = packet.getWindowId();
|
||||
final List<com.github.retrooper.packetevents.protocol.item.ItemStack> itemStacks = packet.getItems();
|
||||
taskManager.submit(() -> {
|
||||
final Optional<User> optionalUser = userManager.get(player.getUniqueId());
|
||||
if (optionalUser.isEmpty()) return;
|
||||
final User user = optionalUser.get();
|
||||
if (windowId != 0) return;
|
||||
final int size = itemStacks.size();
|
||||
final PlayerArmor playerArmor = user.getPlayerArmor();
|
||||
final List<com.github.retrooper.packetevents.protocol.player.Equipment> equipmentList = new ArrayList<>();
|
||||
for (final ArmorItem armorItem : playerArmor.getArmorItems()) {
|
||||
final ArmorItem.Type type = armorItem.getType();
|
||||
final EquipmentSlot slot = type.getSlot();
|
||||
if (slot == null) continue;
|
||||
final int packetSlot = getPacketArmorSlot(slot);
|
||||
if (packetSlot == -1) continue;
|
||||
if (packetSlot >= size) continue;
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmetics.getPlugin(HMCCosmetics.class), ListenerPriority.NORMAL, PacketType.Play.Server.WINDOW_ITEMS) {
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if (event.getPlayer() == null) return;
|
||||
WrapperPlayServerWindowItems wrapper = new WrapperPlayServerWindowItems(event.getPacket());
|
||||
if (!(event.getPlayer() instanceof Player)) return;
|
||||
final int windowId = wrapper.getWindowId();
|
||||
|
||||
final ItemStack current = SpigotConversionUtil.toBukkitItemStack(itemStacks.get(packetSlot));
|
||||
final com.github.retrooper.packetevents.protocol.item.ItemStack setTo =
|
||||
SpigotConversionUtil.fromBukkitItemStack(userManager.getCosmeticItem(
|
||||
armorItem,
|
||||
current,
|
||||
ArmorItem.Status.APPLIED,
|
||||
slot
|
||||
));
|
||||
if (SpigotConversionUtil.fromBukkitItemStack(current).equals(setTo)) continue;
|
||||
equipmentList.add(PacketManager.getEquipment(setTo, slot));
|
||||
}
|
||||
userManager.sendUpdatePacket(
|
||||
user,
|
||||
equipmentList
|
||||
);
|
||||
});
|
||||
// packet.setItems(itemStacks);
|
||||
List<ItemStack> items = wrapper.getSlotData();
|
||||
taskManager.submit(() -> {
|
||||
final Optional<User> optionalUser = userManager.get(player.getUniqueId());
|
||||
if (optionalUser.isEmpty()) return;
|
||||
final User user = optionalUser.get();
|
||||
if (windowId != 0) return;
|
||||
final int size = items.size();
|
||||
final PlayerArmor playerArmor = user.getPlayerArmor();
|
||||
final Equipment equip = userManager.getItemList(user);
|
||||
for (final ArmorItem armorItem : playerArmor.getArmorItems()) {
|
||||
final ArmorItem.Type type = armorItem.getType();
|
||||
final EquipmentSlot slot = type.getSlot();
|
||||
if (slot == null) continue;
|
||||
final int packetSlot = getPacketArmorSlot(slot);
|
||||
if (packetSlot == -1) continue;
|
||||
if (packetSlot >= size) continue;
|
||||
|
||||
final ItemStack current = (items.get(packetSlot));
|
||||
final ItemStack setTo =
|
||||
(userManager.getCosmeticItem(
|
||||
armorItem,
|
||||
current,
|
||||
ArmorItem.Status.APPLIED,
|
||||
slot
|
||||
));
|
||||
if ((current).equals(setTo)) continue;
|
||||
equip.setItem(slot, setTo);
|
||||
}
|
||||
}
|
||||
);
|
||||
userManager.sendUpdatePacket(
|
||||
user,
|
||||
equip
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private int getPacketArmorSlot(final EquipmentSlot slot) {
|
||||
@@ -349,10 +366,11 @@ public class CosmeticFixListener implements Listener {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
private void fixCosmetics(final Player player) {
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(this.plugin,
|
||||
() -> this.userManager.updateCosmetics(player.getUniqueId()), 2);
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.github.fisher2911.hmccosmetics.listener;
|
||||
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
||||
import io.github.fisher2911.hmccosmetics.config.WardrobeSettings;
|
||||
import io.github.fisher2911.hmccosmetics.database.Database;
|
||||
@@ -13,6 +14,7 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -36,16 +38,18 @@ public class JoinListener implements Listener {
|
||||
user -> new TaskChain(this.plugin).chain(
|
||||
() -> this.userManager.add(user)
|
||||
).chain(() -> {
|
||||
// this.userManager.resendCosmetics(player);
|
||||
// this.userManager.updateCosmetics(user);
|
||||
final WardrobeSettings settings = this.plugin.getSettings().getWardrobeSettings();
|
||||
if (settings.isAlwaysDisplay() && settings.getWardrobeLocation() != null) {
|
||||
final Wardrobe wardrobe = user.getWardrobe();
|
||||
wardrobe.setCurrentLocation(settings.getWardrobeLocation());
|
||||
wardrobe.spawnFakePlayer(player);
|
||||
}
|
||||
}, true).execute()
|
||||
);
|
||||
// and finally, resend the cosmetics
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(HMCCosmetics.getPlugin(HMCCosmetics.class),
|
||||
() -> {
|
||||
this.userManager.updateCosmetics(user);
|
||||
}, 20);
|
||||
}, true).execute());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package io.github.fisher2911.hmccosmetics.listener;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.event.PacketListenerAbstract;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
||||
import io.github.fisher2911.hmccosmetics.user.UserManager;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -20,21 +21,21 @@ public class WardrobeListener implements Listener {
|
||||
public WardrobeListener(final HMCCosmetics plugin) {
|
||||
this.plugin = plugin;
|
||||
this.userManager = this.plugin.getUserManager();
|
||||
PacketEvents.getAPI().getEventManager().registerListener(
|
||||
new PacketListenerAbstract() {
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() != PacketType.Play.Client.ANIMATION) return;
|
||||
if (!(event.getPlayer() instanceof final Player player)) return;
|
||||
WardrobeListener.this.userManager.get(player.getUniqueId()).ifPresent(user -> {
|
||||
if (!user.getWardrobe().isActive()) return;
|
||||
Bukkit.getScheduler().runTask(plugin, () -> {
|
||||
WardrobeListener.this.plugin.getCosmeticsMenu().openDefault(player);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmetics.getPlugin(HMCCosmetics.class), ListenerPriority.NORMAL, PacketType.Play.Client.ARM_ANIMATION) {
|
||||
@Override
|
||||
public void onPacketReceiving(PacketEvent event) {
|
||||
if (!(event.getPlayer() instanceof Player)) return;
|
||||
Player player = event.getPlayer();
|
||||
WardrobeListener.this.userManager.get(player.getUniqueId()).ifPresent(user -> {
|
||||
if (!user.getWardrobe().isActive()) return;
|
||||
Bukkit.getScheduler().runTask(plugin, () -> {
|
||||
WardrobeListener.this.plugin.getCosmeticsMenu().openDefault(player);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
||||
@@ -1,128 +1,85 @@
|
||||
package io.github.fisher2911.hmccosmetics.packet;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
||||
import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose;
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
||||
import com.github.retrooper.packetevents.protocol.player.Equipment;
|
||||
import com.github.retrooper.packetevents.protocol.player.EquipmentSlot;
|
||||
import com.github.retrooper.packetevents.protocol.player.GameMode;
|
||||
import com.github.retrooper.packetevents.protocol.player.TextureProperty;
|
||||
import com.github.retrooper.packetevents.protocol.player.UserProfile;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerAttachEntity;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDestroyEntities;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityEquipment;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityHeadLook;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityMetadata;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityRelativeMove;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityRotation;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityTeleport;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityVelocity;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfo;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetPassengers;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnEntity;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnLivingEntity;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnPlayer;
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
||||
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import io.github.fisher2911.hmccosmetics.packet.versions.PacketBase;
|
||||
import io.github.fisher2911.hmccosmetics.packet.versions.PacketManager_1_19_2;
|
||||
import io.github.fisher2911.hmccosmetics.user.Equipment;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PacketManager {
|
||||
//
|
||||
// private static final PacketHelper PACKET_HELPER;
|
||||
//
|
||||
// static {
|
||||
// final String version = Bukkit.getVersion();
|
||||
// if (version.contains("1.16")) {
|
||||
// PACKET_HELPER = new PacketHelper_1_16_R3();
|
||||
// } else if (version.contains("1.17")) {
|
||||
// PACKET_HELPER = new PacketHelper_1_17_R1();
|
||||
// } else if (version.contains("1.18")) {
|
||||
// PACKET_HELPER = new PacketHelper_1_18_R1();
|
||||
// } else {
|
||||
// PACKET_HELPER = null;
|
||||
// }
|
||||
// }
|
||||
private static BiMap<List<String>, PacketBase> packetHelper = HashBiMap.create();
|
||||
|
||||
public static void sendArmorStandMetaContainer(final int armorStandId, final Collection<? extends Player> sendTo) {
|
||||
sendArmorStandMetaContainer(armorStandId, sendTo.toArray(new Player[0]));
|
||||
public static final PacketBase WildUpdate = new PacketManager_1_19_2();
|
||||
|
||||
private static PacketBase packetVersion;
|
||||
|
||||
public static void setupPackets() {
|
||||
for (PacketBase packet : packetHelper.values()) {
|
||||
for (String version : packet.getVersion()) {
|
||||
if (Bukkit.getVersion().contains(version)) {
|
||||
packetVersion = packet;
|
||||
HMCCosmetics.getPlugin(HMCCosmetics.class).getLogger().info("Found protocol support for your version. Choosing: " + packet.getVersion());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (packetVersion == null) {
|
||||
HMCCosmetics.getPlugin(HMCCosmetics.class).getLogger().severe("Unable to find proper support for your version. Defaulting packets to use 1.19.2 information. You can safely ignore this if you do not encounter any problems.");
|
||||
packetVersion = WildUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
public static void addPacketBase(PacketBase packet) {
|
||||
if (packetHelper.containsKey(packet.getVersion())) {
|
||||
HMCCosmetics.getPlugin(HMCCosmetics.class).getLogger().severe("A protocol version was duplicated! This has overriden the old packet support for that version. You can ignore if this is intentional.");
|
||||
}
|
||||
packetHelper.put(packet.getVersion(), packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends meta data for armor stands.
|
||||
* @param armorStandId
|
||||
* @param sendTo
|
||||
*/
|
||||
public static void sendArmorStandMetaContainer(final int armorStandId, final Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
sendPacketAsync(p, new WrapperPlayServerEntityMetadata(
|
||||
armorStandId,
|
||||
List.of(
|
||||
new EntityData(0, EntityDataTypes.BYTE, (byte) 0x20),
|
||||
new EntityData(15, EntityDataTypes.BYTE, (byte) 0x10)
|
||||
)
|
||||
));
|
||||
}
|
||||
packetVersion.sendArmorStandMetaContainer(armorStandId, sendTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends cloud meta data about an entity to a player (No idea what this means?)
|
||||
* @param entityId
|
||||
* @param sendTo
|
||||
*/
|
||||
public static void sendCloudMetaData(int entityId, Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
sendPacketAsync(p, new WrapperPlayServerEntityMetadata(
|
||||
entityId,
|
||||
List.of(
|
||||
new EntityData(0, EntityDataTypes.BYTE, (byte) 0),
|
||||
new EntityData(2, EntityDataTypes.OPTIONAL_COMPONENT, Optional.empty()),
|
||||
new EntityData(6, EntityDataTypes.ENTITY_POSE, EntityPose.STANDING),
|
||||
new EntityData(4, EntityDataTypes.BOOLEAN, false),
|
||||
new EntityData(8, EntityDataTypes.FLOAT, 0.0f),
|
||||
new EntityData(9, EntityDataTypes.INT, 0),
|
||||
new EntityData(11, EntityDataTypes.PARTICLE, 21),
|
||||
new EntityData(10, EntityDataTypes.BOOLEAN, false),
|
||||
new EntityData(1, EntityDataTypes.INT, 300),
|
||||
new EntityData(3, EntityDataTypes.BOOLEAN, false),
|
||||
new EntityData(7, EntityDataTypes.INT, 0),
|
||||
new EntityData(5, EntityDataTypes.BOOLEAN, false)
|
||||
)
|
||||
));
|
||||
}
|
||||
packetVersion.sendCloudMetaData(entityId, sendTo);
|
||||
}
|
||||
|
||||
public static void sendVelocityPacket(final int entityId, Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
sendPacketAsync(p, new WrapperPlayServerEntityVelocity(
|
||||
entityId,
|
||||
new Vector3d(0.5, 0.5, 0.5)
|
||||
));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Sends a movement packet relative to a position.
|
||||
* @param entityId
|
||||
* @param sendTo
|
||||
*/
|
||||
|
||||
public static void sendRelativeMovePacket(final int entityId, Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
sendPacketAsync(p, new WrapperPlayServerEntityRelativeMove(
|
||||
entityId,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
false
|
||||
));
|
||||
}
|
||||
packetVersion.sendRelativeMovePacket(entityId, sendTo);
|
||||
}
|
||||
|
||||
public static void sendHeadLookPacket(final int entityId, Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
sendPacketAsync(p, new WrapperPlayServerEntityHeadLook(
|
||||
entityId,
|
||||
0
|
||||
));
|
||||
}
|
||||
public static void sendHeadLookPacket(int entityId, float yaw, Player... sendTo) {
|
||||
packetVersion.sendHeadLookPacket(entityId, yaw, sendTo);
|
||||
}
|
||||
|
||||
public static void sendEntitySpawnPacket(
|
||||
@@ -130,7 +87,7 @@ public class PacketManager {
|
||||
final int entityId,
|
||||
final EntityType entityType,
|
||||
final Collection<? extends Player> sendTo) {
|
||||
sendEntitySpawnPacket(location, entityId, entityType, sendTo.toArray(new Player[0]));
|
||||
packetVersion.sendEntitySpawnPacket(location, entityId, entityType, sendTo);
|
||||
}
|
||||
|
||||
public static void sendEntitySpawnPacket(
|
||||
@@ -138,7 +95,7 @@ public class PacketManager {
|
||||
final int entityId,
|
||||
final EntityType entityType,
|
||||
final Player... sendTo) {
|
||||
sendEntitySpawnPacket(location, entityId, entityType, UUID.randomUUID(), sendTo);
|
||||
packetVersion.sendEntitySpawnPacket(location, entityId, entityType, sendTo);
|
||||
}
|
||||
|
||||
public static void sendEntitySpawnPacket(
|
||||
@@ -147,30 +104,25 @@ public class PacketManager {
|
||||
final EntityType entityType,
|
||||
final UUID uuid,
|
||||
final Collection<? extends Player> sendTo) {
|
||||
sendEntitySpawnPacket(location, entityId, entityType, uuid, sendTo.toArray(new Player[0]));
|
||||
packetVersion.sendEntitySpawnPacket(location, entityId, entityType, uuid, sendTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* "Spawns" an entity for players. This entity is fake and is mearly client side.
|
||||
* @param location Location to spawn the entity.
|
||||
* @param entityId The entityID that is being spawned.
|
||||
* @param entityType The entity type that is being spawned.
|
||||
* @param uuid The UUID of the entity being spawned.
|
||||
* @param sendTo Whom to send the packet to.
|
||||
*/
|
||||
public static void sendEntitySpawnPacket(
|
||||
final Location location,
|
||||
final int entityId,
|
||||
final EntityType entityType,
|
||||
final UUID uuid,
|
||||
final Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
sendPacketAsync(p, new WrapperPlayServerSpawnLivingEntity(
|
||||
entityId,
|
||||
uuid,
|
||||
entityType,
|
||||
new Vector3d(location.getX(), location.getY(), location.getZ()),
|
||||
location.getYaw(),
|
||||
location.getPitch(),
|
||||
0f,
|
||||
Vector3d.zero(),
|
||||
Collections.emptyList()
|
||||
));
|
||||
}
|
||||
packetVersion.sendEntitySpawnPacket(location, entityId, entityType, uuid, sendTo);
|
||||
}
|
||||
|
||||
public static void sendEntityNotLivingSpawnPacket(
|
||||
final Location location,
|
||||
final int entityId,
|
||||
@@ -178,32 +130,20 @@ public class PacketManager {
|
||||
final UUID uuid,
|
||||
int data,
|
||||
final Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
sendPacketAsync(p, new WrapperPlayServerSpawnEntity(
|
||||
entityId,
|
||||
Optional.of(uuid),
|
||||
entityType,
|
||||
new Vector3d(location.getX(), location.getY(), location.getZ()),
|
||||
0,
|
||||
0,
|
||||
0f,
|
||||
data,
|
||||
Optional.of(Vector3d.zero())
|
||||
));
|
||||
}
|
||||
packetVersion.sendEntityNotLivingSpawnPacket(location, entityId, entityType, uuid, data, sendTo);
|
||||
}
|
||||
|
||||
public static void sendInvisibilityPacket(final int entityId, final Collection<? extends Player> sendTo) {
|
||||
sendInvisibilityPacket(entityId, sendTo.toArray(new Player[0]));
|
||||
packetVersion.sendInvisibilityPacket(entityId, sendTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will make a entity invisible
|
||||
* @param entityId Which entity will this affect?
|
||||
* @param sendTo Whom to send the packet to
|
||||
*/
|
||||
public static void sendInvisibilityPacket(final int entityId, final Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
sendPacketAsync(p, new WrapperPlayServerEntityMetadata(
|
||||
entityId,
|
||||
List.of(new EntityData(0, EntityDataTypes.BYTE, (byte) 0x20))
|
||||
));
|
||||
}
|
||||
packetVersion.sendInvisibilityPacket(entityId, sendTo);
|
||||
}
|
||||
|
||||
public static void sendTeleportPacket(
|
||||
@@ -212,24 +152,23 @@ public class PacketManager {
|
||||
boolean onGround,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendTeleportPacket(entityId, location, onGround, sendTo.toArray(new Player[0]));
|
||||
packetVersion.sendTeleportPacket(entityId, location, onGround, sendTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used when a player is sent 8+ blocks.
|
||||
* @param entityId Entity this affects
|
||||
* @param location Location a player is being teleported to
|
||||
* @param onGround If the packet is on the ground
|
||||
* @param sendTo Whom to send the packet to
|
||||
*/
|
||||
public static void sendTeleportPacket(
|
||||
final int entityId,
|
||||
final Location location,
|
||||
boolean onGround,
|
||||
final Player... sendTo
|
||||
) {
|
||||
for (final Player p : sendTo) {
|
||||
sendPacketAsync(p, new WrapperPlayServerEntityTeleport(
|
||||
entityId,
|
||||
new Vector3d(location.getX(), location.getY(), location.getZ()),
|
||||
location.getYaw(),
|
||||
location.getPitch(),
|
||||
onGround
|
||||
));
|
||||
}
|
||||
packetVersion.sendTeleportPacket(entityId, location, onGround, sendTo);
|
||||
}
|
||||
|
||||
public static void sendMovePacket(
|
||||
@@ -239,9 +178,17 @@ public class PacketManager {
|
||||
final boolean onGround,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendMovePacket(entityId, from, to, onGround, sendTo.toArray(new Player[0]));
|
||||
packetVersion.sendMovePacket(entityId, from, to, onGround, sendTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a movement packet from one location to another
|
||||
* @param entityId Entity this will affect
|
||||
* @param from Previous location
|
||||
* @param to New location
|
||||
* @param onGround If the movement is on the ground
|
||||
* @param sendTo Whom to send the packet to
|
||||
*/
|
||||
public static void sendMovePacket(
|
||||
final int entityId,
|
||||
final Location from,
|
||||
@@ -249,15 +196,7 @@ public class PacketManager {
|
||||
final boolean onGround,
|
||||
final Player... sendTo
|
||||
) {
|
||||
for (final Player p : sendTo) {
|
||||
sendPacketAsync(p, new WrapperPlayServerEntityRelativeMove(
|
||||
entityId,
|
||||
to.getX() - from.getX(),
|
||||
to.getY() - from.getY(),
|
||||
to.getZ() - from.getZ(),
|
||||
onGround
|
||||
));
|
||||
}
|
||||
packetVersion.sendMovePacket(entityId, from, to, onGround, sendTo);
|
||||
}
|
||||
|
||||
public static void sendLeashPacket(
|
||||
@@ -265,67 +204,50 @@ public class PacketManager {
|
||||
final int entityId,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendLeashPacket(balloonId, entityId, sendTo.toArray(new Player[0]));
|
||||
packetVersion.sendLeashPacket(balloonId, entityId, sendTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a leash packet, useful for balloons!
|
||||
* @param leashedEntity Entity being leashed (ex. a horse)
|
||||
* @param entityId Entity this is affecting (ex. a player)
|
||||
* @param sendTo Whom to send the packet to
|
||||
*/
|
||||
public static void sendLeashPacket(
|
||||
final int balloonId,
|
||||
final int leashedEntity,
|
||||
final int entityId,
|
||||
final Player... sendTo
|
||||
) {
|
||||
for (final Player p : sendTo) {
|
||||
sendPacketAsync(p, new WrapperPlayServerAttachEntity(
|
||||
balloonId,
|
||||
entityId,
|
||||
true
|
||||
));
|
||||
}
|
||||
packetVersion.sendLeashPacket(leashedEntity, entityId, sendTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Useful for updating packet equipment on a player
|
||||
* @param equipment The equipment that is being equiped for the player. THIS IS NOT REAL ARMOR, mearly packets. If a player attempts to remove their cosmetics, it will disappear.
|
||||
* @param entityID Entity this will affect
|
||||
* @param sendTo Whom to send the packet to
|
||||
*/
|
||||
public static void sendEquipmentPacket(
|
||||
final List<Equipment> equipmentList,
|
||||
final int entityId,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendEquipmentPacket(equipmentList, entityId, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
public static void sendEquipmentPacket(
|
||||
final List<Equipment> equipmentList,
|
||||
final int entityId,
|
||||
final Player... sendTo
|
||||
) {
|
||||
for (final Player p : sendTo) {
|
||||
sendPacketAsync(p, new WrapperPlayServerEntityEquipment(
|
||||
entityId,
|
||||
equipmentList
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendRotationPacket(
|
||||
final int entityId,
|
||||
final Location location,
|
||||
final boolean onGround,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendRotationPacket(entityId, location, onGround, sendTo.toArray(new Player[0]));
|
||||
final Equipment equipment,
|
||||
final int entityID,
|
||||
final Player... sendTo) {
|
||||
packetVersion.sendEquipmentPacket(equipment, entityID, sendTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a rotation packet for an entity
|
||||
* @param entityId EntityID that rotates their body
|
||||
* @param location Location/Vector that will be looked at
|
||||
* @param onGround Whether it is on the ground or not.
|
||||
* @param sendTo Whom to send the packet to
|
||||
*/
|
||||
public static void sendRotationPacket(
|
||||
final int entityId,
|
||||
final Location location,
|
||||
final boolean onGround,
|
||||
final Player... sendTo
|
||||
) {
|
||||
for (final Player p : sendTo) {
|
||||
sendPacketAsync(p, new WrapperPlayServerEntityRotation(
|
||||
entityId,
|
||||
location.getYaw(),
|
||||
location.getPitch(),
|
||||
onGround
|
||||
));
|
||||
}
|
||||
packetVersion.sendRotationPacket(entityId, location, onGround, sendTo);
|
||||
}
|
||||
|
||||
public static void sendLookPacket(
|
||||
@@ -333,129 +255,104 @@ public class PacketManager {
|
||||
final Location location,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendLookPacket(entityId, location, sendTo.toArray(new Player[0]));
|
||||
packetVersion.sendLookPacket(entityId, location, sendTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a look packet at a location
|
||||
* @param entityId EntityID this packet affects
|
||||
* @param location Location/Vector that an entity looks at.
|
||||
* @param sendTo Whom to send the packet to
|
||||
*/
|
||||
public static void sendLookPacket(
|
||||
final int entityId,
|
||||
final Location location,
|
||||
final Player... sendTo
|
||||
) {
|
||||
for (final Player p : sendTo) {
|
||||
sendPacketAsync(p, new WrapperPlayServerEntityHeadLook(
|
||||
entityId,
|
||||
location.getYaw()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendRidingPacket(
|
||||
final int mountId,
|
||||
final int passengerId,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendRidingPacket(mountId, passengerId, sendTo.toArray(new Player[0]));
|
||||
packetVersion.sendLookPacket(entityId, location, sendTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mostly to deal with backpacks, this deals with entities riding other entities.
|
||||
* @param mountId The entity that is the "mount", ex. a player
|
||||
* @param passengerId The entity that is riding the mount, ex. a armorstand for a backpack
|
||||
* @param sendTo Whom to send the packet to
|
||||
*/
|
||||
public static void sendRidingPacket(
|
||||
final int mountId,
|
||||
final int passengerId,
|
||||
final Player... sendTo
|
||||
) {
|
||||
for (final Player p : sendTo) {
|
||||
sendPacketAsync(p, new WrapperPlayServerSetPassengers(
|
||||
mountId,
|
||||
new int[]{passengerId}
|
||||
));
|
||||
}
|
||||
packetVersion.sendRidingPacket(mountId, passengerId, sendTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys an entity from a player
|
||||
* @param entityId The entity to delete for a player
|
||||
* @param sendTo The players the packet should be sent to
|
||||
*/
|
||||
public static void sendEntityDestroyPacket(final int entityId, final Collection<? extends Player> sendTo) {
|
||||
sendEntityDestroyPacket(entityId, sendTo.toArray(new Player[0]));
|
||||
packetVersion.sendEntityDestroyPacket(entityId, sendTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys an entity from a player
|
||||
* @param entityId The entity to delete for a player
|
||||
* @param sendTo The players the packet should be sent to
|
||||
*/
|
||||
public static void sendEntityDestroyPacket(final int entityId, final Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
sendPacketAsync(p, new WrapperPlayServerDestroyEntities(entityId));
|
||||
}
|
||||
packetVersion.sendEntityDestroyPacket(entityId, sendTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a camera packet
|
||||
* @param entityId The Entity ID that camera will go towards
|
||||
* @param sendTo The players that will be sent this packet
|
||||
*/
|
||||
public static void sendCameraPacket(final int entityId, final Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
sendPacketAsync(p, new WrapperPlayServerCamera(entityId));
|
||||
}
|
||||
packetVersion.sendCameraPacket(entityId, sendTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a camera packet
|
||||
* @param entity The Entity that camera will go towards
|
||||
* @param sendTo The players that will be sent this packet
|
||||
*/
|
||||
public static void sendCameraPacket(final Entity entity, final Player... sendTo) {
|
||||
packetVersion.sendCameraPacket(entity, sendTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a camera packet
|
||||
* @param entityId The Entity ID that camera will go towards
|
||||
* @param sendTo The players that will be sent this packet
|
||||
*/
|
||||
public static void sendCameraPacket(final int entityId, final Collection<? extends Player> sendTo) {
|
||||
sendCameraPacket(entityId, sendTo.toArray(new Player[0]));
|
||||
packetVersion.sendCameraPacket(entityId, sendTo);
|
||||
}
|
||||
|
||||
// public static void sendSoundPacket(
|
||||
// final Player player,
|
||||
// final Location location,
|
||||
// final MinecraftKey name,
|
||||
// final float volume,
|
||||
// final float pitch,
|
||||
// final EnumWrappers.SoundCategory soundCategory,
|
||||
// final Player...sendTo
|
||||
// ) {
|
||||
// final var packet = new WrapperPlayServerSoundEffect(
|
||||
//
|
||||
// );
|
||||
// final var manager = ProtocolLibrary.getProtocolManager();
|
||||
// final var packet = manager.createPacket(PacketType.Play.Server.CUSTOM_SOUND_EFFECT);
|
||||
//
|
||||
// packet.getMinecraftKeys()
|
||||
// .write(
|
||||
// 0,
|
||||
// name
|
||||
// );
|
||||
//
|
||||
// packet.getSoundCategories()
|
||||
// .write(0, EnumWrappers.SoundCategory.valueOf(soundCategory.name()));
|
||||
//
|
||||
// packet.getIntegers()
|
||||
// .write(0, location.getBlockX() * 8)
|
||||
// .write(
|
||||
// 1, location.getBlockY() * 8
|
||||
// )
|
||||
// .write(2, location.getBlockZ() * 8);
|
||||
//
|
||||
// packet.getFloat()
|
||||
// .write(0, volume)
|
||||
// .write(1, pitch);
|
||||
//
|
||||
// return packet;
|
||||
// }
|
||||
|
||||
public static void sendFakePlayerSpawnPacket(
|
||||
final Location location,
|
||||
final UUID uuid,
|
||||
final int entityId,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendFakePlayerSpawnPacket(location, uuid, entityId, sendTo.toArray(new Player[0]));
|
||||
packetVersion.sendFakePlayerSpawnPacket(location, uuid, entityId, sendTo);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param location Location of the fake player.
|
||||
* @param uuid UUID of the fake player. Should be random.
|
||||
* @param entityId The entityID that the entity will take on.
|
||||
* @param sendTo Who should it send the packet to?
|
||||
*/
|
||||
public static void sendFakePlayerSpawnPacket(
|
||||
final Location location,
|
||||
final UUID uuid,
|
||||
final int entityId,
|
||||
final Player... sendTo
|
||||
) {
|
||||
for (final Player p : sendTo) {
|
||||
sendPacketAsync(p, new WrapperPlayServerSpawnPlayer(
|
||||
entityId,
|
||||
uuid,
|
||||
new com.github.retrooper.packetevents.protocol.world.Location(
|
||||
location.getX(),
|
||||
location.getY(),
|
||||
location.getZ(),
|
||||
location.getYaw(),
|
||||
location.getPitch()
|
||||
)
|
||||
));
|
||||
}
|
||||
packetVersion.sendFakePlayerSpawnPacket(location, uuid, entityId, sendTo);
|
||||
}
|
||||
|
||||
public static void sendFakePlayerInfoPacket(
|
||||
@@ -463,54 +360,40 @@ public class PacketManager {
|
||||
final UUID uuid,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendFakePlayerInfoPacket(skinnedPlayer, uuid, sendTo.toArray(new Player[0]));
|
||||
packetVersion.sendFakePlayerInfoPacket(skinnedPlayer, uuid, sendTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fake player entity.
|
||||
* @param skinnedPlayer The original player it bases itself off of.
|
||||
* @param uuid UUID of the fake entity.
|
||||
* @param sendTo Whom to send the packet to
|
||||
*/
|
||||
public static void sendFakePlayerInfoPacket(
|
||||
final Player skinnedPlayer,
|
||||
final UUID uuid,
|
||||
final Player... sendTo
|
||||
) {
|
||||
final List<TextureProperty> textures = PacketEvents.getAPI().getPlayerManager().getUser(skinnedPlayer).getProfile().getTextureProperties();
|
||||
final WrapperPlayServerPlayerInfo.PlayerData data = new WrapperPlayServerPlayerInfo.PlayerData(
|
||||
Component.text(""),
|
||||
new UserProfile(
|
||||
uuid,
|
||||
"",
|
||||
textures
|
||||
),
|
||||
GameMode.CREATIVE,
|
||||
0
|
||||
);
|
||||
for (final Player p : sendTo) {
|
||||
sendPacketAsync(p, new WrapperPlayServerPlayerInfo(
|
||||
WrapperPlayServerPlayerInfo.Action.ADD_PLAYER,
|
||||
data
|
||||
));
|
||||
}
|
||||
packetVersion.sendFakePlayerInfoPacket(skinnedPlayer, uuid, sendTo);
|
||||
}
|
||||
|
||||
public static void sendPlayerOverlayPacket(
|
||||
final int playerId,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendPlayerOverlayPacket(playerId, sendTo.toArray(new Player[0]));
|
||||
packetVersion.sendPlayerOverlayPacket(playerId, sendTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the overlay packet for entities.
|
||||
* @param playerId The entity the packet is about
|
||||
* @param sendTo Whom is sent the packet.
|
||||
*/
|
||||
public static void sendPlayerOverlayPacket(
|
||||
final int playerId,
|
||||
final Player... sendTo
|
||||
) {
|
||||
final byte mask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x40;
|
||||
for (final Player p : sendTo) {
|
||||
sendPacketAsync(p, new WrapperPlayServerEntityMetadata(
|
||||
playerId,
|
||||
List.of(
|
||||
new EntityData(17, EntityDataTypes.BYTE, mask),
|
||||
new EntityData(15, EntityDataTypes.BYTE, (byte) 0x10)
|
||||
)
|
||||
));
|
||||
}
|
||||
packetVersion.sendPlayerOverlayPacket(playerId, sendTo);
|
||||
}
|
||||
|
||||
public static void sendRemovePlayerPacket(
|
||||
@@ -518,69 +401,60 @@ public class PacketManager {
|
||||
final UUID uuid,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendRemovePlayerPacket(player, uuid, sendTo.toArray(new Player[0]));
|
||||
packetVersion.sendRemovePlayerPacket(player, uuid, sendTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a fake player from being seen by players.
|
||||
* @param player Which gameprofile to wrap for removing the player.
|
||||
* @param uuid What is the fake player UUID
|
||||
* @param sendTo Whom to send the packet to
|
||||
*/
|
||||
public static void sendRemovePlayerPacket(
|
||||
final Player player,
|
||||
final UUID uuid,
|
||||
final Player... sendTo
|
||||
) {
|
||||
for (final Player p : sendTo) {
|
||||
sendPacketAsync(p, new WrapperPlayServerPlayerInfo(
|
||||
WrapperPlayServerPlayerInfo.Action.REMOVE_PLAYER,
|
||||
new WrapperPlayServerPlayerInfo.PlayerData(
|
||||
Component.empty(),
|
||||
new UserProfile(
|
||||
uuid,
|
||||
player.getDisplayName()
|
||||
),
|
||||
com.github.retrooper.packetevents.protocol.player.GameMode.SURVIVAL,
|
||||
0
|
||||
)
|
||||
));
|
||||
}
|
||||
packetVersion.sendRemovePlayerPacket(player, uuid, sendTo);
|
||||
}
|
||||
|
||||
public static void sendPacketAsync(final Player player, final PacketWrapper<?> packet) {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(HMCCosmetics.getPlugin(HMCCosmetics.class), () ->
|
||||
PacketEvents.getAPI().getPlayerManager().sendPacket(player, packet)
|
||||
);
|
||||
/**
|
||||
* Sends a gamemode change packet to a player.
|
||||
* @param player Player to change their gamemode.
|
||||
* @param gamemode Bukkit gamemode to change it to
|
||||
*/
|
||||
public static void sendGameModeChange(
|
||||
final Player player,
|
||||
final GameMode gamemode
|
||||
) {
|
||||
packetVersion.sendGameModeChange(player, gamemode);
|
||||
}
|
||||
|
||||
public static void sendPacketAsyncSilently(final Player player, final PacketWrapper<?> packet) {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(HMCCosmetics.getPlugin(HMCCosmetics.class), () ->
|
||||
PacketEvents.getAPI().getPlayerManager().sendPacketSilently(player, packet)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public static com.github.retrooper.packetevents.protocol.player.Equipment getEquipment(
|
||||
final ItemStack itemStack,
|
||||
final org.bukkit.inventory.EquipmentSlot slot
|
||||
/**
|
||||
* Sends a gamemode change packet to a player.
|
||||
* @param player Player to change their gamemode.
|
||||
* @param gamemode Gamemode value to change it to
|
||||
*/
|
||||
public static void sendGameModeChange(
|
||||
final Player player,
|
||||
final int gamemode
|
||||
) {
|
||||
return getEquipment(SpigotConversionUtil.fromBukkitItemStack(itemStack), slot);
|
||||
packetVersion.sendGameModeChange(player, gamemode);
|
||||
}
|
||||
|
||||
public static com.github.retrooper.packetevents.protocol.player.Equipment getEquipment(
|
||||
final com.github.retrooper.packetevents.protocol.item.ItemStack itemStack,
|
||||
final org.bukkit.inventory.EquipmentSlot slot
|
||||
) {
|
||||
return new com.github.retrooper.packetevents.protocol.player.Equipment(
|
||||
PacketManager.fromBukkitSlot(slot),
|
||||
itemStack
|
||||
);
|
||||
public static void sendNewTeam(
|
||||
final Player skinnedPlayer,
|
||||
final Player... sendTo) {
|
||||
packetVersion.sendNewTeam(skinnedPlayer, sendTo);
|
||||
}
|
||||
|
||||
public static EquipmentSlot fromBukkitSlot(final org.bukkit.inventory.EquipmentSlot slot) {
|
||||
return switch (slot) {
|
||||
case HEAD -> EquipmentSlot.HELMET;
|
||||
case CHEST -> EquipmentSlot.CHEST_PLATE;
|
||||
case LEGS -> EquipmentSlot.LEGGINGS;
|
||||
case FEET -> EquipmentSlot.BOOTS;
|
||||
case HAND -> EquipmentSlot.MAIN_HAND;
|
||||
case OFF_HAND -> EquipmentSlot.OFF_HAND;
|
||||
};
|
||||
/**
|
||||
* This sends a packet to a player asyncronously, preventing clogging on the main thread.
|
||||
* @param player Which player to send the packet to
|
||||
* @param packet What packet to send to the player
|
||||
*/
|
||||
public static void sendPacketAsync(final Player player, final PacketContainer packet) {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(HMCCosmetics.getPlugin(HMCCosmetics.class),
|
||||
() -> ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
package io.github.fisher2911.hmccosmetics.packet;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
|
||||
public class WrapperPlayServerCamera extends PacketWrapper<WrapperPlayServerCamera> {
|
||||
|
||||
private int entityID;
|
||||
|
||||
public WrapperPlayServerCamera(final int entityID) {
|
||||
super(PacketType.Play.Server.CAMERA);
|
||||
this.entityID = entityID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read() {
|
||||
this.entityID = this.readVarInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copy(WrapperPlayServerCamera wrapper) {
|
||||
this.entityID = wrapper.entityID;
|
||||
}
|
||||
|
||||
public void write() {
|
||||
this.writeVarInt(this.entityID);
|
||||
}
|
||||
|
||||
public int getEntityId() {
|
||||
return this.entityID;
|
||||
}
|
||||
|
||||
public void setEntityIds(int entityID) {
|
||||
this.entityID = entityID;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,514 @@
|
||||
package io.github.fisher2911.hmccosmetics.packet.versions;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.wrappers.*;
|
||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
||||
import io.github.fisher2911.hmccosmetics.packet.PacketManager;
|
||||
import io.github.fisher2911.hmccosmetics.packet.wrappers.WrapperPlayServerNamedEntitySpawn;
|
||||
import io.github.fisher2911.hmccosmetics.packet.wrappers.WrapperPlayServerPlayerInfo;
|
||||
import io.github.fisher2911.hmccosmetics.packet.wrappers.WrapperPlayServerRelEntityMove;
|
||||
import io.github.fisher2911.hmccosmetics.packet.wrappers.WrapperPlayServerRelEntityMoveLook;
|
||||
import io.github.fisher2911.hmccosmetics.user.Equipment;
|
||||
import io.github.fisher2911.hmccosmetics.util.PlayerUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PacketBase {
|
||||
|
||||
// This is a PacketBase made to be in parity with the latest version. Other classes can override certain methods.
|
||||
|
||||
List<String> version;
|
||||
|
||||
protected PacketBase(@NotNull final List<String> version) {
|
||||
this.version = version;
|
||||
|
||||
PacketManager.addPacketBase(this);
|
||||
}
|
||||
|
||||
public List<String> getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void sendArmorStandMetaContainer(final int armorStandId, final Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
packet.getModifier().writeDefaults();
|
||||
packet.getIntegers().write(0, armorStandId);
|
||||
WrappedDataWatcher metadata = new WrappedDataWatcher();
|
||||
//final WrappedDataWatcher.Serializer serializer = WrappedDataWatcher.Registry.get(Byte.class);
|
||||
if (metadata == null) return;
|
||||
// 0x10 & 0x20
|
||||
metadata.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x20);
|
||||
metadata.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x10);
|
||||
packet.getWatchableCollectionModifier().write(0, metadata.getWatchableObjects());
|
||||
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void sendCloudMetaData(int entityId, Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
packet.getModifier().writeDefaults();
|
||||
packet.getIntegers().write(0, entityId);
|
||||
WrappedDataWatcher wrapper = new WrappedDataWatcher();
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x20);
|
||||
//wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(2, WrappedDataWatcher.Registry.get(Optional.class)), Optional.empty());
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(6, WrappedDataWatcher.Registry.get(EnumWrappers.EntityPose.class)), EnumWrappers.EntityPose.STANDING);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(4, WrappedDataWatcher.Registry.get(Boolean.class)), false);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(8, WrappedDataWatcher.Registry.get(Float.class)), 0.0f);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(9, WrappedDataWatcher.Registry.get(int.class)), 0);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(11, WrappedDataWatcher.Registry.get(EnumWrappers.Particle.class)), 21);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(10, WrappedDataWatcher.Registry.get(Boolean.class)), false);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(3, WrappedDataWatcher.Registry.get(Boolean.class)), false);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(4, WrappedDataWatcher.Registry.get(Boolean.class)), false);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(5, WrappedDataWatcher.Registry.get(Boolean.class)), false);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(1, WrappedDataWatcher.Registry.get(int.class)), 300);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(7, WrappedDataWatcher.Registry.get(int.class)), 0);
|
||||
packet.getWatchableCollectionModifier().write(0, wrapper.getWatchableObjects());
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void sendRelativeMovePacket(final int entityId, Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.REL_ENTITY_MOVE);
|
||||
WrapperPlayServerRelEntityMove wrapper = new WrapperPlayServerRelEntityMove(packet);
|
||||
wrapper.setDx(0.0);
|
||||
wrapper.setDy(0.0);
|
||||
wrapper.setDz(0.0);
|
||||
wrapper.setOnGround(false);
|
||||
|
||||
sendPacketAsync(p, wrapper.getHandle());
|
||||
}
|
||||
}
|
||||
public void sendHeadLookPacket(int entityId, float yaw, Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.REL_ENTITY_MOVE_LOOK);
|
||||
WrapperPlayServerRelEntityMoveLook wrapper = new WrapperPlayServerRelEntityMoveLook(packet);
|
||||
wrapper.setYaw(yaw);
|
||||
wrapper.setEntityID(entityId);
|
||||
sendPacketAsync(p, wrapper.getHandle());
|
||||
}
|
||||
}
|
||||
public void sendEntitySpawnPacket(
|
||||
final Location location,
|
||||
final int entityId,
|
||||
final EntityType entityType,
|
||||
final Collection<? extends Player> sendTo) {
|
||||
sendEntitySpawnPacket(location, entityId, entityType, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
public void sendEntitySpawnPacket(
|
||||
final Location location,
|
||||
final int entityId,
|
||||
final EntityType entityType,
|
||||
final Player... sendTo) {
|
||||
sendEntitySpawnPacket(location, entityId, entityType, UUID.randomUUID(), sendTo);
|
||||
}
|
||||
public void sendEntitySpawnPacket(
|
||||
final Location location,
|
||||
final int entityId,
|
||||
final EntityType entityType,
|
||||
final UUID uuid,
|
||||
final Collection<? extends Player> sendTo) {
|
||||
sendEntitySpawnPacket(location, entityId, entityType, uuid, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
public void sendEntitySpawnPacket(
|
||||
final Location location,
|
||||
final int entityId,
|
||||
final EntityType entityType,
|
||||
final UUID uuid,
|
||||
final Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY);
|
||||
packet.getModifier().writeDefaults();
|
||||
packet.getUUIDs().write(0, uuid);
|
||||
packet.getIntegers().write(0, entityId);
|
||||
packet.getEntityTypeModifier().write(0, entityType);
|
||||
packet.getDoubles().
|
||||
write(0, location.getX()).
|
||||
write(1, location.getY()).
|
||||
write(2, location.getZ());
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
@Deprecated
|
||||
public void sendEntityNotLivingSpawnPacket(
|
||||
final Location location,
|
||||
final int entityId,
|
||||
final EntityType entityType,
|
||||
final UUID uuid,
|
||||
int data,
|
||||
final Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
|
||||
}
|
||||
}
|
||||
public void sendInvisibilityPacket(final int entityId, final Collection<? extends Player> sendTo) {
|
||||
sendInvisibilityPacket(entityId, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
public void sendInvisibilityPacket(final int entityId, final Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
packet.getModifier().writeDefaults();
|
||||
packet.getIntegers().write(0, entityId);
|
||||
WrappedDataWatcher wrapper = new WrappedDataWatcher();
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x20);
|
||||
packet.getWatchableCollectionModifier().write(0, wrapper.getWatchableObjects());
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
public void sendTeleportPacket(
|
||||
final int entityId,
|
||||
final Location location,
|
||||
boolean onGround,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendTeleportPacket(entityId, location, onGround, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
|
||||
public void sendTeleportPacket(
|
||||
final int entityId,
|
||||
final Location location,
|
||||
boolean onGround,
|
||||
final Player... sendTo
|
||||
) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT);
|
||||
packet.getIntegers().write(0, entityId);
|
||||
packet.getDoubles().write(0, location.getX());
|
||||
packet.getDoubles().write(1, location.getY());
|
||||
packet.getDoubles().write(2, location.getZ());
|
||||
packet.getBytes().write(0, (byte) (location.getYaw() * 256.0F / 360.0F));
|
||||
packet.getBytes().write(1, (byte) (location.getPitch() * 256.0F / 360.0F));
|
||||
packet.getBooleans().write(0, onGround);
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
public void sendMovePacket(
|
||||
final int entityId,
|
||||
final Location from,
|
||||
final Location to,
|
||||
final boolean onGround,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendMovePacket(entityId, from, to, onGround, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
public void sendMovePacket(
|
||||
final int entityId,
|
||||
final Location from,
|
||||
final Location to,
|
||||
final boolean onGround,
|
||||
final Player... sendTo
|
||||
) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.REL_ENTITY_MOVE);
|
||||
WrapperPlayServerRelEntityMove wrapper = new WrapperPlayServerRelEntityMove(packet);
|
||||
wrapper.setEntityID(entityId);
|
||||
wrapper.setDx(to.getX() - from.getX());
|
||||
wrapper.setDy(to.getY() - from.getY());
|
||||
wrapper.setDz(to.getZ() - from.getZ());
|
||||
wrapper.setOnGround(onGround);
|
||||
sendPacketAsync(p, wrapper.getHandle());
|
||||
}
|
||||
}
|
||||
public void sendLeashPacket(
|
||||
final int balloonId,
|
||||
final int entityId,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendLeashPacket(balloonId, entityId, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
public void sendLeashPacket(
|
||||
final int leashedEntity,
|
||||
final int entityId,
|
||||
final Player... sendTo
|
||||
) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ATTACH_ENTITY);
|
||||
packet.getIntegers().write(0, leashedEntity);
|
||||
packet.getIntegers().write(1, entityId);
|
||||
// Leash?
|
||||
//packet.getBooleans().write(0, true);
|
||||
/*
|
||||
sendPacketAsync(p, new WrapperPlayServerAttachEntity(
|
||||
balloonId,
|
||||
entityId,
|
||||
true
|
||||
));
|
||||
*/
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void sendEquipmentPacket(
|
||||
final Equipment equipment,
|
||||
final int entityID,
|
||||
final Player... sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_EQUIPMENT);
|
||||
packet.getIntegers().write(0, entityID);
|
||||
List<Pair<EnumWrappers.ItemSlot, ItemStack>> list = new ArrayList<>();
|
||||
for (EquipmentSlot slot : equipment.keys()) {
|
||||
if (PlayerUtils.itemBukkitSlot(slot) != null) list.add(new Pair<>(PlayerUtils.itemBukkitSlot(slot), equipment.getItem(slot)));
|
||||
}
|
||||
if (list == null) return;
|
||||
packet.getSlotStackPairLists().write(0, list);
|
||||
for (Player p : sendTo) {
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendRotationPacket(
|
||||
final int entityId,
|
||||
final Location location,
|
||||
final boolean onGround,
|
||||
final Player... sendTo
|
||||
) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_LOOK);
|
||||
packet.getIntegers().write(0, entityId);
|
||||
float ROTATION_FACTOR = 256.0F / 360.0F;
|
||||
packet.getBytes().write(0, (byte) (location.getYaw() * ROTATION_FACTOR));
|
||||
packet.getBytes().write(1, (byte) (location.getPitch() * ROTATION_FACTOR));
|
||||
|
||||
//Bukkit.getLogger().info("DEBUG: Yaw: " + (location.getYaw() * ROTATION_FACTOR) + " | Original Yaw: " + location.getYaw());
|
||||
packet.getBooleans().write(0, onGround);
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
public void sendLookPacket(
|
||||
final int entityId,
|
||||
final Location location,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendLookPacket(entityId, location, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
public void sendLookPacket(
|
||||
final int entityId,
|
||||
final Location location,
|
||||
final Player... sendTo
|
||||
) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_HEAD_ROTATION);
|
||||
packet.getIntegers().write(0, entityId);
|
||||
packet.getBytes().write(0, (byte) (location.getYaw() * 256.0F / 360.0F));
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendRidingPacket(
|
||||
final int mountId,
|
||||
final int passengerId,
|
||||
final Player... sendTo
|
||||
) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.MOUNT);
|
||||
packet.getIntegers().write(0, mountId);
|
||||
packet.getIntegerArrays().write(0, new int[]{passengerId});
|
||||
for (final Player p : sendTo) {
|
||||
//p.sendMessage("MountID: " + mountId + " / Raw Passenger: " + passengerId + " | Next Entity: " + Database.getNextEntityId());
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendEntityDestroyPacket(final int entityId, final Collection<? extends Player> sendTo) {
|
||||
sendEntityDestroyPacket(entityId, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
public void sendEntityDestroyPacket(final int entityId, final Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY);
|
||||
packet.getModifier().write(0, new IntArrayList(new int[]{entityId}));
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendCameraPacket(final int entityId, final Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.CAMERA);
|
||||
packet.getIntegers().write(0, entityId);
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendCameraPacket(final Entity entity, final Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.CAMERA);
|
||||
packet.getEntityModifier(p.getWorld()).write(0, entity);
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void sendCameraPacket(final int entityId, final Collection<? extends Player> sendTo) {
|
||||
sendCameraPacket(entityId, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
public void sendFakePlayerSpawnPacket(
|
||||
final Location location,
|
||||
final UUID uuid,
|
||||
final int entityId,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendFakePlayerSpawnPacket(location, uuid, entityId, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
public void sendFakePlayerSpawnPacket(
|
||||
final Location location,
|
||||
final UUID uuid,
|
||||
final int entityId,
|
||||
final Player... sendTo
|
||||
) {
|
||||
for (final Player p : sendTo) {
|
||||
WrapperPlayServerNamedEntitySpawn wrapper = new WrapperPlayServerNamedEntitySpawn();
|
||||
wrapper.setEntityID(entityId);
|
||||
wrapper.setPlayerUUID(uuid);
|
||||
wrapper.setPosition(location.toVector());
|
||||
wrapper.setPitch(location.getPitch());
|
||||
wrapper.setYaw(location.getYaw());
|
||||
sendPacketAsync(p, wrapper.getHandle());
|
||||
}
|
||||
}
|
||||
public void sendFakePlayerInfoPacket(
|
||||
final Player skinnedPlayer,
|
||||
final UUID uuid,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendFakePlayerInfoPacket(skinnedPlayer, uuid, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
public void sendFakePlayerInfoPacket(
|
||||
final Player skinnedPlayer,
|
||||
final UUID uuid,
|
||||
final Player... sendTo
|
||||
) {
|
||||
WrapperPlayServerPlayerInfo info = new WrapperPlayServerPlayerInfo();
|
||||
info.setAction(EnumWrappers.PlayerInfoAction.ADD_PLAYER);
|
||||
|
||||
String name = "Mannequin-" + skinnedPlayer.getEntityId();
|
||||
while (name.length() > 16) {
|
||||
name = name.substring(16);
|
||||
}
|
||||
|
||||
WrappedGameProfile wrappedGameProfile = new WrappedGameProfile(uuid, name);
|
||||
wrappedGameProfile.getProperties().put("textures", PlayerUtils.getSkin(skinnedPlayer));
|
||||
info.setData(List.of(new PlayerInfoData(wrappedGameProfile, 0, EnumWrappers.NativeGameMode.CREATIVE, WrappedChatComponent.fromText(name))));
|
||||
for (final Player p : sendTo) {
|
||||
sendPacketAsync(p, info.getHandle());
|
||||
}
|
||||
}
|
||||
public void sendPlayerOverlayPacket(
|
||||
final int playerId,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendPlayerOverlayPacket(playerId, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
public void sendPlayerOverlayPacket(
|
||||
final int playerId,
|
||||
final Player... sendTo
|
||||
) {
|
||||
final byte mask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x40;
|
||||
for (final Player p : sendTo) {
|
||||
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
packet.getModifier().writeDefaults();
|
||||
packet.getIntegers().write(0, playerId);
|
||||
WrappedDataWatcher wrapper = new WrappedDataWatcher();
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(17, WrappedDataWatcher.Registry.get(Byte.class)), mask);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x10);
|
||||
packet.getWatchableCollectionModifier().write(0, wrapper.getWatchableObjects());
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
public void sendRemovePlayerPacket(
|
||||
final Player player,
|
||||
final UUID uuid,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendRemovePlayerPacket(player, uuid, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
public void sendRemovePlayerPacket(
|
||||
final Player player,
|
||||
final UUID uuid,
|
||||
final Player... sendTo
|
||||
) {
|
||||
for (final Player p : sendTo) {
|
||||
WrapperPlayServerPlayerInfo info = new WrapperPlayServerPlayerInfo();
|
||||
info.setAction(EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
|
||||
|
||||
String name = "Mannequin-" + player.getEntityId();
|
||||
while (name.length() > 16) {
|
||||
name = name.substring(16);
|
||||
}
|
||||
|
||||
info.setData(List.of(new PlayerInfoData(new WrappedGameProfile(uuid, player.getName()), 0, EnumWrappers.NativeGameMode.CREATIVE, WrappedChatComponent.fromText(name))));
|
||||
sendPacketAsync(p, info.getHandle());
|
||||
}
|
||||
}
|
||||
public void sendGameModeChange(
|
||||
final Player player,
|
||||
final GameMode gamemode
|
||||
) {
|
||||
sendGameModeChange(player, PlayerUtils.convertGamemode(gamemode));
|
||||
}
|
||||
public void sendGameModeChange(
|
||||
final Player player,
|
||||
final int gamemode
|
||||
) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.GAME_STATE_CHANGE);
|
||||
packet.getGameStateIDs().write(0, 3);
|
||||
// Tells what event this is. This is a change gamemode event.
|
||||
packet.getFloat().write(0, (float) gamemode);
|
||||
sendPacketAsync(player, packet);
|
||||
}
|
||||
|
||||
public void sendNewTeam(
|
||||
final Player skinnedPlayer,
|
||||
final Player... sendTo)
|
||||
{
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.SCOREBOARD_TEAM);
|
||||
packet.getStrings().write(0, "npcteam");
|
||||
packet.getBytes().write(0, (byte) 0);
|
||||
packet.getStrings().write(1, " "); // Team Displayname?
|
||||
packet.getStrings().write(2, "always");
|
||||
|
||||
String name = "Mannequin-" + skinnedPlayer.getEntityId();
|
||||
while (name.length() > 16) {
|
||||
name = name.substring(16);
|
||||
}
|
||||
|
||||
String[] nameList = new String[]{name};
|
||||
packet.getStringArrays().write(0, nameList);
|
||||
for (Player player : sendTo) {
|
||||
sendPacketAsync(player, packet);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendPacketAsync(final Player player, final PacketContainer packet) {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(HMCCosmetics.getPlugin(HMCCosmetics.class),
|
||||
() -> ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,654 @@
|
||||
package io.github.fisher2911.hmccosmetics.packet.versions;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.wrappers.*;
|
||||
import io.github.fisher2911.hmccosmetics.packet.wrappers.*;
|
||||
import io.github.fisher2911.hmccosmetics.user.Equipment;
|
||||
import io.github.fisher2911.hmccosmetics.util.PlayerUtils;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PacketManager_1_19_2 extends PacketBase {
|
||||
|
||||
|
||||
public PacketManager_1_19_2() {
|
||||
super(List.of("1.19", "1.19.1", "1.19.2"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends meta data for armor stands.
|
||||
* @param armorStandId
|
||||
* @param sendTo
|
||||
*/
|
||||
@Override
|
||||
public void sendArmorStandMetaContainer(final int armorStandId, final Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
packet.getModifier().writeDefaults();
|
||||
packet.getIntegers().write(0, armorStandId);
|
||||
WrappedDataWatcher metadata = new WrappedDataWatcher();
|
||||
if (metadata == null) return;
|
||||
// 0x10 & 0x20
|
||||
metadata.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x20);
|
||||
metadata.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x10);
|
||||
packet.getWatchableCollectionModifier().write(0, metadata.getWatchableObjects());
|
||||
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends cloud meta data about an entity to a player (No idea what this means?)
|
||||
* @param entityId
|
||||
* @param sendTo
|
||||
*/
|
||||
@Override
|
||||
public void sendCloudMetaData(int entityId, Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
packet.getModifier().writeDefaults();
|
||||
packet.getIntegers().write(0, entityId);
|
||||
WrappedDataWatcher wrapper = new WrappedDataWatcher();
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x20);
|
||||
//wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(2, WrappedDataWatcher.Registry.get(Optional.class)), Optional.empty());
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(6, WrappedDataWatcher.Registry.get(EnumWrappers.EntityPose.class)), EnumWrappers.EntityPose.STANDING);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(4, WrappedDataWatcher.Registry.get(Boolean.class)), false);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(8, WrappedDataWatcher.Registry.get(Float.class)), 0.0f);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(9, WrappedDataWatcher.Registry.get(int.class)), 0);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(11, WrappedDataWatcher.Registry.get(EnumWrappers.Particle.class)), 21);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(10, WrappedDataWatcher.Registry.get(Boolean.class)), false);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(3, WrappedDataWatcher.Registry.get(Boolean.class)), false);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(4, WrappedDataWatcher.Registry.get(Boolean.class)), false);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(5, WrappedDataWatcher.Registry.get(Boolean.class)), false);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(1, WrappedDataWatcher.Registry.get(int.class)), 300);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(7, WrappedDataWatcher.Registry.get(int.class)), 0);
|
||||
packet.getWatchableCollectionModifier().write(0, wrapper.getWatchableObjects());
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a movement packet relative to a position.
|
||||
* @param entityId
|
||||
* @param sendTo
|
||||
*/
|
||||
@Override
|
||||
public void sendRelativeMovePacket(final int entityId, Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.REL_ENTITY_MOVE);
|
||||
WrapperPlayServerRelEntityMove wrapper = new WrapperPlayServerRelEntityMove(packet);
|
||||
wrapper.setDx(0.0);
|
||||
wrapper.setDy(0.0);
|
||||
wrapper.setDz(0.0);
|
||||
wrapper.setOnGround(false);
|
||||
|
||||
sendPacketAsync(p, wrapper.getHandle());
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void sendHeadLookPacket(int entityId, float yaw, Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.REL_ENTITY_MOVE_LOOK);
|
||||
WrapperPlayServerRelEntityMoveLook wrapper = new WrapperPlayServerRelEntityMoveLook(packet);
|
||||
wrapper.setYaw(yaw);
|
||||
wrapper.setEntityID(entityId);
|
||||
sendPacketAsync(p, wrapper.getHandle());
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void sendEntitySpawnPacket(
|
||||
final Location location,
|
||||
final int entityId,
|
||||
final EntityType entityType,
|
||||
final Collection<? extends Player> sendTo) {
|
||||
sendEntitySpawnPacket(location, entityId, entityType, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
@Override
|
||||
public void sendEntitySpawnPacket(
|
||||
final Location location,
|
||||
final int entityId,
|
||||
final EntityType entityType,
|
||||
final Player... sendTo) {
|
||||
sendEntitySpawnPacket(location, entityId, entityType, UUID.randomUUID(), sendTo);
|
||||
}
|
||||
@Override
|
||||
public void sendEntitySpawnPacket(
|
||||
final Location location,
|
||||
final int entityId,
|
||||
final EntityType entityType,
|
||||
final UUID uuid,
|
||||
final Collection<? extends Player> sendTo) {
|
||||
sendEntitySpawnPacket(location, entityId, entityType, uuid, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
* "Spawns" an entity for players. This entity is fake and is mearly client side.
|
||||
* @param location Location to spawn the entity.
|
||||
* @param entityId The entityID that is being spawned.
|
||||
* @param entityType The entity type that is being spawned.
|
||||
* @param uuid The UUID of the entity being spawned.
|
||||
* @param sendTo Whom to send the packet to.
|
||||
*/
|
||||
@Override
|
||||
public void sendEntitySpawnPacket(
|
||||
final Location location,
|
||||
final int entityId,
|
||||
final EntityType entityType,
|
||||
final UUID uuid,
|
||||
final Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY);
|
||||
packet.getModifier().writeDefaults();
|
||||
packet.getUUIDs().write(0, uuid);
|
||||
packet.getIntegers().write(0, entityId);
|
||||
packet.getEntityTypeModifier().write(0, entityType);
|
||||
packet.getDoubles().
|
||||
write(0, location.getX()).
|
||||
write(1, location.getY()).
|
||||
write(2, location.getZ());
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
@Deprecated @Override
|
||||
public void sendEntityNotLivingSpawnPacket(
|
||||
final Location location,
|
||||
final int entityId,
|
||||
final EntityType entityType,
|
||||
final UUID uuid,
|
||||
int data,
|
||||
final Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void sendInvisibilityPacket(final int entityId, final Collection<? extends Player> sendTo) {
|
||||
sendInvisibilityPacket(entityId, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Will make a entity invisible
|
||||
* @param entityId Which entity will this affect?
|
||||
* @param sendTo Whom to send the packet to
|
||||
*/
|
||||
@Override
|
||||
public void sendInvisibilityPacket(final int entityId, final Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
packet.getModifier().writeDefaults();
|
||||
packet.getIntegers().write(0, entityId);
|
||||
WrappedDataWatcher wrapper = new WrappedDataWatcher();
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x20);
|
||||
packet.getWatchableCollectionModifier().write(0, wrapper.getWatchableObjects());
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void sendTeleportPacket(
|
||||
final int entityId,
|
||||
final Location location,
|
||||
boolean onGround,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendTeleportPacket(entityId, location, onGround, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Used when a player is sent 8+ blocks.
|
||||
* @param entityId Entity this affects
|
||||
* @param location Location a player is being teleported to
|
||||
* @param onGround If the packet is on the ground
|
||||
* @param sendTo Whom to send the packet to
|
||||
*/
|
||||
@Override
|
||||
public void sendTeleportPacket(
|
||||
final int entityId,
|
||||
final Location location,
|
||||
boolean onGround,
|
||||
final Player... sendTo
|
||||
) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT);
|
||||
packet.getIntegers().write(0, entityId);
|
||||
packet.getDoubles().write(0, location.getX());
|
||||
packet.getDoubles().write(1, location.getY());
|
||||
packet.getDoubles().write(2, location.getZ());
|
||||
packet.getBytes().write(0, (byte) (location.getYaw() * 256.0F / 360.0F));
|
||||
packet.getBytes().write(1, (byte) (location.getPitch() * 256.0F / 360.0F));
|
||||
packet.getBooleans().write(0, onGround);
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void sendMovePacket(
|
||||
final int entityId,
|
||||
final Location from,
|
||||
final Location to,
|
||||
final boolean onGround,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendMovePacket(entityId, from, to, onGround, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a movement packet from one location to another
|
||||
* @param entityId Entity this will affect
|
||||
* @param from Previous location
|
||||
* @param to New location
|
||||
* @param onGround If the movement is on the ground
|
||||
* @param sendTo Whom to send the packet to
|
||||
*/
|
||||
@Override
|
||||
public void sendMovePacket(
|
||||
final int entityId,
|
||||
final Location from,
|
||||
final Location to,
|
||||
final boolean onGround,
|
||||
final Player... sendTo
|
||||
) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.REL_ENTITY_MOVE);
|
||||
WrapperPlayServerRelEntityMove wrapper = new WrapperPlayServerRelEntityMove(packet);
|
||||
wrapper.setEntityID(entityId);
|
||||
wrapper.setDx(to.getX() - from.getX());
|
||||
wrapper.setDy(to.getY() - from.getY());
|
||||
wrapper.setDz(to.getZ() - from.getZ());
|
||||
wrapper.setOnGround(onGround);
|
||||
sendPacketAsync(p, wrapper.getHandle());
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void sendLeashPacket(
|
||||
final int balloonId,
|
||||
final int entityId,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendLeashPacket(balloonId, entityId, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a leash packet, useful for balloons!
|
||||
* @param leashedEntity Entity being leashed (ex. a horse)
|
||||
* @param entityId Entity this is affecting (ex. a player)
|
||||
* @param sendTo Whom to send the packet to
|
||||
*/
|
||||
@Override
|
||||
public void sendLeashPacket(
|
||||
final int leashedEntity,
|
||||
final int entityId,
|
||||
final Player... sendTo
|
||||
) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ATTACH_ENTITY);
|
||||
packet.getIntegers().write(0, leashedEntity);
|
||||
packet.getIntegers().write(1, entityId);
|
||||
// Leash?
|
||||
//packet.getBooleans().write(0, true);
|
||||
/*
|
||||
sendPacketAsync(p, new WrapperPlayServerAttachEntity(
|
||||
balloonId,
|
||||
entityId,
|
||||
true
|
||||
));
|
||||
*/
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Useful for updating packet equipment on a player
|
||||
* @param equipment The equipment that is being equiped for the player. THIS IS NOT REAL ARMOR, mearly packets. If a player attempts to remove their cosmetics, it will disappear.
|
||||
* @param entityID Entity this will affect
|
||||
* @param sendTo Whom to send the packet to
|
||||
*/
|
||||
@Override
|
||||
public void sendEquipmentPacket(
|
||||
final Equipment equipment,
|
||||
final int entityID,
|
||||
final Player... sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_EQUIPMENT);
|
||||
packet.getIntegers().write(0, entityID);
|
||||
List<Pair<EnumWrappers.ItemSlot, ItemStack>> list = new ArrayList<>();
|
||||
for (EquipmentSlot slot : equipment.keys()) {
|
||||
if (PlayerUtils.itemBukkitSlot(slot) != null) list.add(new Pair<>(PlayerUtils.itemBukkitSlot(slot), equipment.getItem(slot)));
|
||||
}
|
||||
if (list.isEmpty() || list == null) return;
|
||||
packet.getSlotStackPairLists().write(0, list);
|
||||
for (Player p : sendTo) {
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a rotation packet for an entity
|
||||
* @param entityId EntityID that rotates their body
|
||||
* @param location Location/Vector that will be looked at
|
||||
* @param onGround Whether it is on the ground or not.
|
||||
* @param sendTo Whom to send the packet to
|
||||
*/
|
||||
@Override
|
||||
public void sendRotationPacket(
|
||||
final int entityId,
|
||||
final Location location,
|
||||
final boolean onGround,
|
||||
final Player... sendTo
|
||||
) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_LOOK);
|
||||
packet.getIntegers().write(0, entityId);
|
||||
float ROTATION_FACTOR = 256.0F / 360.0F;
|
||||
packet.getBytes().write(0, (byte) (location.getYaw() * ROTATION_FACTOR));
|
||||
packet.getBytes().write(1, (byte) (location.getPitch() * ROTATION_FACTOR));
|
||||
|
||||
//Bukkit.getLogger().info("DEBUG: Yaw: " + (location.getYaw() * ROTATION_FACTOR) + " | Original Yaw: " + location.getYaw());
|
||||
packet.getBooleans().write(0, onGround);
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void sendLookPacket(
|
||||
final int entityId,
|
||||
final Location location,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendLookPacket(entityId, location, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a look packet at a location
|
||||
* @param entityId EntityID this packet affects
|
||||
* @param location Location/Vector that an entity looks at.
|
||||
* @param sendTo Whom to send the packet to
|
||||
*/
|
||||
@Override
|
||||
public void sendLookPacket(
|
||||
final int entityId,
|
||||
final Location location,
|
||||
final Player... sendTo
|
||||
) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_HEAD_ROTATION);
|
||||
packet.getIntegers().write(0, entityId);
|
||||
packet.getBytes().write(0, (byte) (location.getYaw() * 256.0F / 360.0F));
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mostly to deal with backpacks, this deals with entities riding other entities.
|
||||
* @param mountId The entity that is the "mount", ex. a player
|
||||
* @param passengerId The entity that is riding the mount, ex. a armorstand for a backpack
|
||||
* @param sendTo Whom to send the packet to
|
||||
*/
|
||||
@Override
|
||||
public void sendRidingPacket(
|
||||
final int mountId,
|
||||
final int passengerId,
|
||||
final Player... sendTo
|
||||
) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.MOUNT);
|
||||
packet.getIntegers().write(0, mountId);
|
||||
packet.getIntegerArrays().write(0, new int[]{passengerId});
|
||||
for (final Player p : sendTo) {
|
||||
//p.sendMessage("MountID: " + mountId + " / Raw Passenger: " + passengerId + " | Next Entity: " + Database.getNextEntityId());
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Destroys an entity from a player
|
||||
* @param entityId The entity to delete for a player
|
||||
* @param sendTo The players the packet should be sent to
|
||||
*/
|
||||
@Override
|
||||
public void sendEntityDestroyPacket(final int entityId, final Collection<? extends Player> sendTo) {
|
||||
sendEntityDestroyPacket(entityId, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys an entity from a player
|
||||
* @param entityId The entity to delete for a player
|
||||
* @param sendTo The players the packet should be sent to
|
||||
*/
|
||||
@Override
|
||||
public void sendEntityDestroyPacket(final int entityId, final Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY);
|
||||
packet.getModifier().write(0, new IntArrayList(new int[]{entityId}));
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a camera packet
|
||||
* @param entityId The Entity ID that camera will go towards
|
||||
* @param sendTo The players that will be sent this packet
|
||||
*/
|
||||
@Override
|
||||
public void sendCameraPacket(final int entityId, final Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.CAMERA);
|
||||
packet.getIntegers().write(0, entityId);
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a camera packet
|
||||
* @param entity The Entity that camera will go towards
|
||||
* @param sendTo The players that will be sent this packet
|
||||
*/
|
||||
@Override
|
||||
public void sendCameraPacket(final Entity entity, final Player... sendTo) {
|
||||
for (final Player p : sendTo) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.CAMERA);
|
||||
packet.getEntityModifier(p.getWorld()).write(0, entity);
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a camera packet
|
||||
* @param entityId The Entity ID that camera will go towards
|
||||
* @param sendTo The players that will be sent this packet
|
||||
*/
|
||||
@Override
|
||||
public void sendCameraPacket(final int entityId, final Collection<? extends Player> sendTo) {
|
||||
sendCameraPacket(entityId, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
@Override
|
||||
public void sendFakePlayerSpawnPacket(
|
||||
final Location location,
|
||||
final UUID uuid,
|
||||
final int entityId,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendFakePlayerSpawnPacket(location, uuid, entityId, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param location Location of the fake player.
|
||||
* @param uuid UUID of the fake player. Should be random.
|
||||
* @param entityId The entityID that the entity will take on.
|
||||
* @param sendTo Who should it send the packet to?
|
||||
*/
|
||||
@Override
|
||||
public void sendFakePlayerSpawnPacket(
|
||||
final Location location,
|
||||
final UUID uuid,
|
||||
final int entityId,
|
||||
final Player... sendTo
|
||||
) {
|
||||
for (final Player p : sendTo) {
|
||||
WrapperPlayServerNamedEntitySpawn wrapper = new WrapperPlayServerNamedEntitySpawn();
|
||||
wrapper.setEntityID(entityId);
|
||||
wrapper.setPlayerUUID(uuid);
|
||||
wrapper.setPosition(location.toVector());
|
||||
wrapper.setPitch(location.getPitch());
|
||||
wrapper.setYaw(location.getYaw());
|
||||
sendPacketAsync(p, wrapper.getHandle());
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void sendFakePlayerInfoPacket(
|
||||
final Player skinnedPlayer,
|
||||
final UUID uuid,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendFakePlayerInfoPacket(skinnedPlayer, uuid, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fake player entity.
|
||||
* @param skinnedPlayer The original player it bases itself off of.
|
||||
* @param uuid UUID of the fake entity.
|
||||
* @param sendTo Whom to send the packet to
|
||||
*/
|
||||
@Override
|
||||
public void sendFakePlayerInfoPacket(
|
||||
final Player skinnedPlayer,
|
||||
final UUID uuid,
|
||||
final Player... sendTo
|
||||
) {
|
||||
WrapperPlayServerPlayerInfo info = new WrapperPlayServerPlayerInfo();
|
||||
info.setAction(EnumWrappers.PlayerInfoAction.ADD_PLAYER);
|
||||
|
||||
String name = "Mannequin-" + skinnedPlayer.getEntityId();
|
||||
while (name.length() > 16) {
|
||||
name = name.substring(16);
|
||||
}
|
||||
|
||||
WrappedGameProfile wrappedGameProfile = new WrappedGameProfile(uuid, name);
|
||||
wrappedGameProfile.getProperties().put("textures", PlayerUtils.getSkin(skinnedPlayer));
|
||||
info.setData(List.of(new PlayerInfoData(wrappedGameProfile, 0, EnumWrappers.NativeGameMode.CREATIVE, WrappedChatComponent.fromText(name))));
|
||||
for (final Player p : sendTo) {
|
||||
sendPacketAsync(p, info.getHandle());
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void sendPlayerOverlayPacket(
|
||||
final int playerId,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendPlayerOverlayPacket(playerId, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the overlay packet for entities.
|
||||
* @param playerId The entity the packet is about
|
||||
* @param sendTo Whom is sent the packet.
|
||||
*/
|
||||
@Override
|
||||
public void sendPlayerOverlayPacket(
|
||||
final int playerId,
|
||||
final Player... sendTo
|
||||
) {
|
||||
/*
|
||||
0x01 = Is on fire
|
||||
0x02 = Is courching
|
||||
0x04 = Unusued
|
||||
0x08 = Sprinting
|
||||
0x10 = Is swimming
|
||||
0x20 = Invisibile
|
||||
0x40 = Is Glowing
|
||||
0x80 = Is flying with an elytra
|
||||
https://wiki.vg/Entity_metadata#Entity
|
||||
*/
|
||||
final byte mask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x40;
|
||||
for (final Player p : sendTo) {
|
||||
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
packet.getModifier().writeDefaults();
|
||||
packet.getIntegers().write(0, playerId);
|
||||
WrappedDataWatcher wrapper = new WrappedDataWatcher();
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(17, WrappedDataWatcher.Registry.get(Byte.class)), mask);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x10);
|
||||
packet.getWatchableCollectionModifier().write(0, wrapper.getWatchableObjects());
|
||||
sendPacketAsync(p, packet);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void sendRemovePlayerPacket(
|
||||
final Player player,
|
||||
final UUID uuid,
|
||||
final Collection<? extends Player> sendTo
|
||||
) {
|
||||
sendRemovePlayerPacket(player, uuid, sendTo.toArray(new Player[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a fake player from being seen by players.
|
||||
* @param player Which gameprofile to wrap for removing the player.
|
||||
* @param uuid What is the fake player UUID
|
||||
* @param sendTo Whom to send the packet to
|
||||
*/
|
||||
@Override
|
||||
public void sendRemovePlayerPacket(
|
||||
final Player player,
|
||||
final UUID uuid,
|
||||
final Player... sendTo
|
||||
) {
|
||||
for (final Player p : sendTo) {
|
||||
WrapperPlayServerPlayerInfo info = new WrapperPlayServerPlayerInfo();
|
||||
info.setAction(EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
|
||||
|
||||
String name = "Mannequin-" + player.getEntityId();
|
||||
while (name.length() > 16) {
|
||||
name = name.substring(16);
|
||||
}
|
||||
|
||||
info.setData(List.of(new PlayerInfoData(new WrappedGameProfile(uuid, player.getName()), 0, EnumWrappers.NativeGameMode.CREATIVE, WrappedChatComponent.fromText(name))));
|
||||
sendPacketAsync(p, info.getHandle());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a gamemode change packet to a player.
|
||||
* @param player Player to change their gamemode.
|
||||
* @param gamemode Bukkit gamemode to change it to
|
||||
*/
|
||||
@Override
|
||||
public void sendGameModeChange(
|
||||
final Player player,
|
||||
final GameMode gamemode
|
||||
) {
|
||||
sendGameModeChange(player, PlayerUtils.convertGamemode(gamemode));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a gamemode change packet to a player.
|
||||
* @param player Player to change their gamemode.
|
||||
* @param gamemode Gamemode value to change it to
|
||||
*/
|
||||
@Override
|
||||
public void sendGameModeChange(
|
||||
final Player player,
|
||||
final int gamemode
|
||||
) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.GAME_STATE_CHANGE);
|
||||
packet.getGameStateIDs().write(0, 3);
|
||||
// Tells what event this is. This is a change gamemode event.
|
||||
packet.getFloat().write(0, (float) gamemode);
|
||||
sendPacketAsync(player, packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendNewTeam(
|
||||
final Player skinnedPlayer,
|
||||
final Player... sendTo)
|
||||
{
|
||||
// This needs to be worked on. If you know how to do it, PR: https://wiki.vg/Protocol#Update_Teams
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package io.github.fisher2911.hmccosmetics.packet.wrappers;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.google.common.base.Objects;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
// Courtesy of Packet Wrapper
|
||||
public class AbstractPacket {
|
||||
|
||||
// The packet we will be modifying
|
||||
protected PacketContainer handle;
|
||||
|
||||
/**
|
||||
* Constructs a new strongly typed wrapper for the given packet.
|
||||
*
|
||||
* @param handle - handle to the raw packet data.
|
||||
* @param type - the packet type.
|
||||
*/
|
||||
protected AbstractPacket(PacketContainer handle, PacketType type) {
|
||||
// Make sure we're given a valid packet
|
||||
if (handle == null)
|
||||
throw new IllegalArgumentException("Packet handle cannot be NULL.");
|
||||
if (!Objects.equal(handle.getType(), type))
|
||||
throw new IllegalArgumentException(handle.getHandle()
|
||||
+ " is not a packet of type " + type);
|
||||
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a handle to the raw packet data.
|
||||
*
|
||||
* @return Raw packet data.
|
||||
*/
|
||||
public PacketContainer getHandle() {
|
||||
return handle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the current packet to the given receiver.
|
||||
*
|
||||
* @param receiver - the receiver.
|
||||
* @throws RuntimeException If the packet cannot be sent.
|
||||
*/
|
||||
public void sendPacket(Player receiver) {
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(receiver,
|
||||
getHandle());
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the current packet to all online players.
|
||||
*/
|
||||
public void broadcastPacket() {
|
||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getHandle());
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate receiving the current packet from the given sender.
|
||||
*
|
||||
* @param sender - the sender.
|
||||
* @throws RuntimeException If the packet cannot be received.
|
||||
* @deprecated Misspelled. recieve to receive
|
||||
* @see #receivePacket(Player)
|
||||
*/
|
||||
@Deprecated
|
||||
public void recievePacket(Player sender) {
|
||||
try {
|
||||
ProtocolLibrary.getProtocolManager().receiveClientPacket(sender,
|
||||
getHandle());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot recieve packet.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate receiving the current packet from the given sender.
|
||||
*
|
||||
* @param sender - the sender.
|
||||
* @throws RuntimeException if the packet cannot be received.
|
||||
*/
|
||||
public void receivePacket(Player sender) {
|
||||
try {
|
||||
ProtocolLibrary.getProtocolManager().receiveClientPacket(sender,
|
||||
getHandle());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot receive packet.", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package io.github.fisher2911.hmccosmetics.packet.wrappers;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
|
||||
public class WrapperPlayClientWindowClick extends AbstractPacket {
|
||||
public static final PacketType TYPE = PacketType.Play.Client.WINDOW_CLICK;
|
||||
|
||||
public WrapperPlayClientWindowClick() {
|
||||
super(new PacketContainer(TYPE), TYPE);
|
||||
handle.getModifier().writeDefaults();
|
||||
}
|
||||
|
||||
public WrapperPlayClientWindowClick(PacketContainer packet) {
|
||||
super(packet, TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve Window ID.
|
||||
* <p>
|
||||
* Notes: the id of the window which was clicked. 0 for player inventory.
|
||||
*
|
||||
* @return The current Window ID
|
||||
*/
|
||||
public int getWindowId() {
|
||||
return handle.getIntegers().read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Window ID.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setWindowId(int value) {
|
||||
handle.getIntegers().write(0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve Slot.
|
||||
* <p>
|
||||
* Notes: the clicked slot. See below.
|
||||
*
|
||||
* @return The current Slot
|
||||
*/
|
||||
public int getSlot() {
|
||||
return handle.getIntegers().read(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Slot.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setSlot(int value) {
|
||||
handle.getIntegers().write(1, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve Button.
|
||||
* <p>
|
||||
* Notes: the button used in the click. See below.
|
||||
*
|
||||
* @return The current Button
|
||||
*/
|
||||
public int getButton() {
|
||||
return handle.getIntegers().read(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Button.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setButton(int value) {
|
||||
handle.getIntegers().write(2, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve Action number.
|
||||
* <p>
|
||||
* Notes: a unique number for the action, used for transaction handling (See
|
||||
* the Transaction packet).
|
||||
*
|
||||
* @return The current Action number
|
||||
*/
|
||||
public short getActionNumber() {
|
||||
return handle.getShorts().read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Action number.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setActionNumber(short value) {
|
||||
handle.getShorts().write(0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve Clicked item.
|
||||
*
|
||||
* @return The current Clicked item
|
||||
*/
|
||||
public ItemStack getClickedItem() {
|
||||
return handle.getItemModifier().read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Clicked item.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setClickedItem(ItemStack value) {
|
||||
handle.getItemModifier().write(0, value);
|
||||
}
|
||||
|
||||
public InventoryClickType getShift() {
|
||||
return handle.getEnumModifier(InventoryClickType.class, 5).read(0);
|
||||
}
|
||||
|
||||
public void setShift(InventoryClickType value) {
|
||||
handle.getEnumModifier(InventoryClickType.class, 5).write(0, value);
|
||||
}
|
||||
|
||||
public enum InventoryClickType {
|
||||
PICKUP, QUICK_MOVE, SWAP, CLONE, THROW, QUICK_CRAFT, PICKUP_ALL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package io.github.fisher2911.hmccosmetics.packet.wrappers;
|
||||
|
||||
import io.github.fisher2911.hmccosmetics.user.Equipment;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.ItemSlot;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class WrapperPlayServerEntityEquipment extends AbstractPacket {
|
||||
public static final PacketType TYPE =
|
||||
PacketType.Play.Server.ENTITY_EQUIPMENT;
|
||||
private List<Equipment> equipment;
|
||||
|
||||
public WrapperPlayServerEntityEquipment() {
|
||||
super(new PacketContainer(TYPE), TYPE);
|
||||
handle.getModifier().writeDefaults();
|
||||
}
|
||||
|
||||
public WrapperPlayServerEntityEquipment(PacketContainer packet) {
|
||||
super(packet, TYPE);
|
||||
}
|
||||
|
||||
public void read() {
|
||||
|
||||
}
|
||||
|
||||
public WrapperPlayServerEntityEquipment(PacketContainer packet, int entityId, List<Equipment> equipment) {
|
||||
super(packet, TYPE);
|
||||
setEntityID(entityId);
|
||||
this.equipment = equipment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve Entity ID.
|
||||
* <p>
|
||||
* Notes: entity's ID
|
||||
*
|
||||
* @return The current Entity ID
|
||||
*/
|
||||
public int getEntityID() {
|
||||
return handle.getIntegers().read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Entity ID.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setEntityID(int value) {
|
||||
handle.getIntegers().write(0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the entity of the painting that will be spawned.
|
||||
*
|
||||
* @param world - the current world of the entity.
|
||||
* @return The spawned entity.
|
||||
*/
|
||||
public Entity getEntity(World world) {
|
||||
return handle.getEntityModifier(world).read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the entity of the painting that will be spawned.
|
||||
*
|
||||
* @param event - the packet event.
|
||||
* @return The spawned entity.
|
||||
*/
|
||||
public Entity getEntity(PacketEvent event) {
|
||||
return getEntity(event.getPlayer().getWorld());
|
||||
}
|
||||
|
||||
public ItemSlot getSlot() {
|
||||
return handle.getItemSlots().read(0);
|
||||
}
|
||||
|
||||
public void setSlot(ItemSlot value) {
|
||||
if (handle.getItemSlots().getValues().size() > 0) {
|
||||
handle.getItemSlots().write(0, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve Item.
|
||||
* <p>
|
||||
* Notes: item in slot format
|
||||
*
|
||||
* @return The current Item
|
||||
*/
|
||||
public ItemStack getItem() {
|
||||
return handle.getItemModifier().read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Item.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setItem(ItemStack value) {
|
||||
if (handle.getItemModifier().getValues().size() > 0) {
|
||||
handle.getItemModifier().write(0, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package io.github.fisher2911.hmccosmetics.packet.wrappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
|
||||
|
||||
public class WrapperPlayServerEntityMetadata extends AbstractPacket {
|
||||
public static final PacketType TYPE =
|
||||
PacketType.Play.Server.ENTITY_METADATA;
|
||||
|
||||
public WrapperPlayServerEntityMetadata() {
|
||||
super(new PacketContainer(TYPE), TYPE);
|
||||
handle.getModifier().writeDefaults();
|
||||
}
|
||||
|
||||
public WrapperPlayServerEntityMetadata(PacketContainer packet) {
|
||||
super(packet, TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve Entity ID.
|
||||
* <p>
|
||||
* Notes: entity's ID
|
||||
*
|
||||
* @return The current Entity ID
|
||||
*/
|
||||
public int getEntityID() {
|
||||
return handle.getIntegers().read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Entity ID.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setEntityID(int value) {
|
||||
handle.getIntegers().write(0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the entity of the painting that will be spawned.
|
||||
*
|
||||
* @param world - the current world of the entity.
|
||||
* @return The spawned entity.
|
||||
*/
|
||||
public Entity getEntity(World world) {
|
||||
return handle.getEntityModifier(world).read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the entity of the painting that will be spawned.
|
||||
*
|
||||
* @param event - the packet event.
|
||||
* @return The spawned entity.
|
||||
*/
|
||||
public Entity getEntity(PacketEvent event) {
|
||||
return getEntity(event.getPlayer().getWorld());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve Metadata.
|
||||
*
|
||||
* @return The current Metadata
|
||||
*/
|
||||
public List<WrappedWatchableObject> getMetadata() {
|
||||
return handle.getWatchableCollectionModifier().read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Metadata.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setMetadata(List<WrappedWatchableObject> value) {
|
||||
handle.getWatchableCollectionModifier().write(0, value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
package io.github.fisher2911.hmccosmetics.packet.wrappers;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
|
||||
public class WrapperPlayServerNamedEntitySpawn extends AbstractPacket {
|
||||
public static final PacketType TYPE =
|
||||
PacketType.Play.Server.NAMED_ENTITY_SPAWN;
|
||||
|
||||
public WrapperPlayServerNamedEntitySpawn() {
|
||||
super(new PacketContainer(TYPE), TYPE);
|
||||
handle.getModifier().writeDefaults();
|
||||
}
|
||||
|
||||
public WrapperPlayServerNamedEntitySpawn(PacketContainer packet) {
|
||||
super(packet, TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve Entity ID.
|
||||
* <p>
|
||||
* Notes: entity's ID
|
||||
*
|
||||
* @return The current Entity ID
|
||||
*/
|
||||
public int getEntityID() {
|
||||
return handle.getIntegers().read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Entity ID.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setEntityID(int value) {
|
||||
handle.getIntegers().write(0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the entity of the painting that will be spawned.
|
||||
*
|
||||
* @param world - the current world of the entity.
|
||||
* @return The spawned entity.
|
||||
*/
|
||||
public Entity getEntity(World world) {
|
||||
return handle.getEntityModifier(world).read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the entity of the painting that will be spawned.
|
||||
*
|
||||
* @param event - the packet event.
|
||||
* @return The spawned entity.
|
||||
*/
|
||||
public Entity getEntity(PacketEvent event) {
|
||||
return getEntity(event.getPlayer().getWorld());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve Player UUID.
|
||||
* <p>
|
||||
* Notes: player's UUID
|
||||
*
|
||||
* @return The current Player UUID
|
||||
*/
|
||||
public UUID getPlayerUUID() {
|
||||
return handle.getUUIDs().read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Player UUID.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setPlayerUUID(UUID value) {
|
||||
handle.getUUIDs().write(0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the position of the spawned entity as a vector.
|
||||
*
|
||||
* @return The position as a vector.
|
||||
*/
|
||||
public Vector getPosition() {
|
||||
return new Vector(getX(), getY(), getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the position of the spawned entity using a vector.
|
||||
*
|
||||
* @param position - the new position.
|
||||
*/
|
||||
public void setPosition(Vector position) {
|
||||
setX(position.getX());
|
||||
setY(position.getY());
|
||||
setZ(position.getZ());
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return handle.getDoubles().read(0);
|
||||
}
|
||||
|
||||
public void setX(double value) {
|
||||
handle.getDoubles().write(0, value);
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return handle.getDoubles().read(1);
|
||||
}
|
||||
|
||||
public void setY(double value) {
|
||||
handle.getDoubles().write(1, value);
|
||||
}
|
||||
|
||||
public double getZ() {
|
||||
return handle.getDoubles().read(2);
|
||||
}
|
||||
|
||||
public void setZ(double value) {
|
||||
handle.getDoubles().write(2, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the yaw of the spawned entity.
|
||||
*
|
||||
* @return The current Yaw
|
||||
*/
|
||||
public float getYaw() {
|
||||
return (handle.getBytes().read(0) * 360.F) / 256.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the yaw of the spawned entity.
|
||||
*
|
||||
* @param value - new yaw.
|
||||
*/
|
||||
public void setYaw(float value) {
|
||||
handle.getBytes().write(0, (byte) (value * 256.0F / 360.0F));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the pitch of the spawned entity.
|
||||
*
|
||||
* @return The current pitch
|
||||
*/
|
||||
public float getPitch() {
|
||||
return (handle.getBytes().read(1) * 360.F) / 256.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the pitch of the spawned entity.
|
||||
*
|
||||
* @param value - new pitch.
|
||||
*/
|
||||
public void setPitch(float value) {
|
||||
handle.getBytes().write(1, (byte) (value * 256.0F / 360.0F));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package io.github.fisher2911.hmccosmetics.packet.wrappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction;
|
||||
import com.comphenix.protocol.wrappers.PlayerInfoData;
|
||||
|
||||
public class WrapperPlayServerPlayerInfo extends AbstractPacket {
|
||||
public static final PacketType TYPE = PacketType.Play.Server.PLAYER_INFO;
|
||||
|
||||
public WrapperPlayServerPlayerInfo() {
|
||||
super(new PacketContainer(TYPE), TYPE);
|
||||
handle.getModifier().writeDefaults();
|
||||
}
|
||||
|
||||
public WrapperPlayServerPlayerInfo(PacketContainer packet) {
|
||||
super(packet, TYPE);
|
||||
}
|
||||
|
||||
public PlayerInfoAction getAction() {
|
||||
return handle.getPlayerInfoAction().read(0);
|
||||
}
|
||||
|
||||
public void setAction(PlayerInfoAction value) {
|
||||
handle.getPlayerInfoAction().write(0, value);
|
||||
}
|
||||
|
||||
public List<PlayerInfoData> getData() {
|
||||
return handle.getPlayerInfoDataLists().read(0);
|
||||
}
|
||||
|
||||
public void setData(List<PlayerInfoData> value) {
|
||||
handle.getPlayerInfoDataLists().write(0, value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
package io.github.fisher2911.hmccosmetics.packet.wrappers;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
|
||||
public class WrapperPlayServerRelEntityMove extends AbstractPacket {
|
||||
public static final PacketType TYPE =
|
||||
PacketType.Play.Server.REL_ENTITY_MOVE;
|
||||
|
||||
public WrapperPlayServerRelEntityMove() {
|
||||
super(new PacketContainer(TYPE), TYPE);
|
||||
handle.getModifier().writeDefaults();
|
||||
}
|
||||
|
||||
public WrapperPlayServerRelEntityMove(PacketContainer packet) {
|
||||
super(packet, TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve Entity ID.
|
||||
* <p>
|
||||
* Notes: entity's ID
|
||||
*
|
||||
* @return The current Entity ID
|
||||
*/
|
||||
public int getEntityID() {
|
||||
return handle.getIntegers().read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Entity ID.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setEntityID(int value) {
|
||||
handle.getIntegers().write(0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the entity of the painting that will be spawned.
|
||||
*
|
||||
* @param world - the current world of the entity.
|
||||
* @return The spawned entity.
|
||||
*/
|
||||
public Entity getEntity(World world) {
|
||||
return handle.getEntityModifier(world).read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the entity of the painting that will be spawned.
|
||||
*
|
||||
* @param event - the packet event.
|
||||
* @return The spawned entity.
|
||||
*/
|
||||
public Entity getEntity(PacketEvent event) {
|
||||
return getEntity(event.getPlayer().getWorld());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve DX.
|
||||
*
|
||||
* @return The current DX
|
||||
*/
|
||||
public double getDx() {
|
||||
return handle.getShorts().read(0) / 4096D;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set DX.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setDx(double value) {
|
||||
handle.getShorts().write(0, (short) (value * 4096));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve DY.
|
||||
*
|
||||
* @return The current DY
|
||||
*/
|
||||
public double getDy() {
|
||||
return handle.getShorts().read(1) / 4096D;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set DY.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setDy(double value) {
|
||||
handle.getShorts().write(1, (short) (value * 4096));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve DZ.
|
||||
*
|
||||
* @return The current DZ
|
||||
*/
|
||||
public double getDz() {
|
||||
return handle.getShorts().read(2) / 4096D;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set DZ.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setDz(double value) {
|
||||
handle.getShorts().write(2, (short) (value * 4096));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the yaw of the current entity.
|
||||
*
|
||||
* @return The current Yaw
|
||||
*/
|
||||
public float getYaw() {
|
||||
return (handle.getBytes().read(0) * 360.F) / 256.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the yaw of the current entity.
|
||||
*
|
||||
* @param value - new yaw.
|
||||
*/
|
||||
public void setYaw(float value) {
|
||||
handle.getBytes().write(0, (byte) (value * 256.0F / 360.0F));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the pitch of the current entity.
|
||||
*
|
||||
* @return The current pitch
|
||||
*/
|
||||
public float getPitch() {
|
||||
return (handle.getBytes().read(1) * 360.F) / 256.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the pitch of the current entity.
|
||||
*
|
||||
* @param value - new pitch.
|
||||
*/
|
||||
public void setPitch(float value) {
|
||||
handle.getBytes().write(1, (byte) (value * 256.0F / 360.0F));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve On Ground.
|
||||
*
|
||||
* @return The current On Ground
|
||||
*/
|
||||
public boolean getOnGround() {
|
||||
return handle.getBooleans().read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set On Ground.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setOnGround(boolean value) {
|
||||
handle.getBooleans().write(0, value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
package io.github.fisher2911.hmccosmetics.packet.wrappers;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
|
||||
public class WrapperPlayServerRelEntityMoveLook extends AbstractPacket {
|
||||
public static final PacketType TYPE =
|
||||
PacketType.Play.Server.REL_ENTITY_MOVE_LOOK;
|
||||
|
||||
public WrapperPlayServerRelEntityMoveLook() {
|
||||
super(new PacketContainer(TYPE), TYPE);
|
||||
handle.getModifier().writeDefaults();
|
||||
}
|
||||
|
||||
public WrapperPlayServerRelEntityMoveLook(PacketContainer packet) {
|
||||
super(packet, TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve Entity ID.
|
||||
* <p>
|
||||
* Notes: entity's ID
|
||||
*
|
||||
* @return The current Entity ID
|
||||
*/
|
||||
public int getEntityID() {
|
||||
return handle.getIntegers().read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Entity ID.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setEntityID(int value) {
|
||||
handle.getIntegers().write(0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the entity of the painting that will be spawned.
|
||||
*
|
||||
* @param world - the current world of the entity.
|
||||
* @return The spawned entity.
|
||||
*/
|
||||
public Entity getEntity(World world) {
|
||||
return handle.getEntityModifier(world).read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the entity of the painting that will be spawned.
|
||||
*
|
||||
* @param event - the packet event.
|
||||
* @return The spawned entity.
|
||||
*/
|
||||
public Entity getEntity(PacketEvent event) {
|
||||
return getEntity(event.getPlayer().getWorld());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve DX.
|
||||
*
|
||||
* @return The current DX
|
||||
*/
|
||||
public double getDx() {
|
||||
return handle.getShorts().read(0) / 4096D;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set DX.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setDx(double value) {
|
||||
handle.getShorts().write(0, (short) (value * 4096));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve DY.
|
||||
*
|
||||
* @return The current DY
|
||||
*/
|
||||
public double getDy() {
|
||||
return handle.getShorts().read(1) / 4096D;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set DY.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setDy(double value) {
|
||||
handle.getShorts().write(1, (short) (value * 4096));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve DZ.
|
||||
*
|
||||
* @return The current DZ
|
||||
*/
|
||||
public double getDz() {
|
||||
return handle.getShorts().read(2) / 4096D;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set DZ.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setDz(double value) {
|
||||
handle.getShorts().write(2, (short) (value * 4096));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the yaw of the current entity.
|
||||
*
|
||||
* @return The current Yaw
|
||||
*/
|
||||
public float getYaw() {
|
||||
return (handle.getBytes().read(0) * 360.F) / 256.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the yaw of the current entity.
|
||||
*
|
||||
* @param value - new yaw.
|
||||
*/
|
||||
public void setYaw(float value) {
|
||||
handle.getBytes().write(0, (byte) (value * 256.0F / 360.0F));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the pitch of the current entity.
|
||||
*
|
||||
* @return The current pitch
|
||||
*/
|
||||
public float getPitch() {
|
||||
return (handle.getBytes().read(1) * 360.F) / 256.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the pitch of the current entity.
|
||||
*
|
||||
* @param value - new pitch.
|
||||
*/
|
||||
public void setPitch(float value) {
|
||||
handle.getBytes().write(1, (byte) (value * 256.0F / 360.0F));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve On Ground.
|
||||
*
|
||||
* @return The current On Ground
|
||||
*/
|
||||
public boolean getOnGround() {
|
||||
return handle.getBooleans().read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set On Ground.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setOnGround(boolean value) {
|
||||
handle.getBooleans().write(0, value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,314 @@
|
||||
package io.github.fisher2911.hmccosmetics.packet.wrappers;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.injector.PacketConstructor;
|
||||
|
||||
public class WrapperPlayServerSpawnEntity extends AbstractPacket {
|
||||
public static final PacketType TYPE = PacketType.Play.Server.SPAWN_ENTITY;
|
||||
|
||||
private static PacketConstructor entityConstructor;
|
||||
|
||||
public WrapperPlayServerSpawnEntity() {
|
||||
super(new PacketContainer(TYPE), TYPE);
|
||||
handle.getModifier().writeDefaults();
|
||||
}
|
||||
|
||||
public WrapperPlayServerSpawnEntity(PacketContainer packet) {
|
||||
super(packet, TYPE);
|
||||
}
|
||||
|
||||
public WrapperPlayServerSpawnEntity(Entity entity, int type, int objectData) {
|
||||
super(fromEntity(entity, type, objectData), TYPE);
|
||||
}
|
||||
|
||||
// Useful constructor
|
||||
private static PacketContainer fromEntity(Entity entity, int type,
|
||||
int objectData) {
|
||||
if (entityConstructor == null)
|
||||
entityConstructor =
|
||||
ProtocolLibrary.getProtocolManager()
|
||||
.createPacketConstructor(TYPE, entity, type,
|
||||
objectData);
|
||||
return entityConstructor.createPacket(entity, type, objectData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve entity ID of the Object.
|
||||
*
|
||||
* @return The current EID
|
||||
*/
|
||||
public int getEntityID() {
|
||||
return handle.getIntegers().read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the entity that will be spawned.
|
||||
*
|
||||
* @param world - the current world of the entity.
|
||||
* @return The spawned entity.
|
||||
*/
|
||||
public Entity getEntity(World world) {
|
||||
return handle.getEntityModifier(world).read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the entity that will be spawned.
|
||||
*
|
||||
* @param event - the packet event.
|
||||
* @return The spawned entity.
|
||||
*/
|
||||
public Entity getEntity(PacketEvent event) {
|
||||
return getEntity(event.getPlayer().getWorld());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set entity ID of the Object.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setEntityID(int value) {
|
||||
handle.getIntegers().write(0, value);
|
||||
}
|
||||
|
||||
public UUID getUniqueId() {
|
||||
return handle.getUUIDs().read(0);
|
||||
}
|
||||
|
||||
public void setUniqueId(UUID value) {
|
||||
handle.getUUIDs().write(0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the x position of the object.
|
||||
* <p>
|
||||
* Note that the coordinate is rounded off to the nearest 1/32 of a meter.
|
||||
*
|
||||
* @return The current X
|
||||
*/
|
||||
public double getX() {
|
||||
return handle.getDoubles().read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the x position of the object.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setX(double value) {
|
||||
handle.getDoubles().write(0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the y position of the object.
|
||||
* <p>
|
||||
* Note that the coordinate is rounded off to the nearest 1/32 of a meter.
|
||||
*
|
||||
* @return The current y
|
||||
*/
|
||||
public double getY() {
|
||||
return handle.getDoubles().read(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the y position of the object.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setY(double value) {
|
||||
handle.getDoubles().write(1, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the z position of the object.
|
||||
* <p>
|
||||
* Note that the coordinate is rounded off to the nearest 1/32 of a meter.
|
||||
*
|
||||
* @return The current z
|
||||
*/
|
||||
public double getZ() {
|
||||
return handle.getDoubles().read(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the z position of the object.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setZ(double value) {
|
||||
handle.getDoubles().write(2, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the optional speed x.
|
||||
* <p>
|
||||
* This is ignored if {@link #getObjectData()} is zero.
|
||||
*
|
||||
* @return The optional speed x.
|
||||
*/
|
||||
public double getOptionalSpeedX() {
|
||||
return handle.getIntegers().read(1) / 8000.0D;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the optional speed x.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setOptionalSpeedX(double value) {
|
||||
handle.getIntegers().write(1, (int) (value * 8000.0D));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the optional speed y.
|
||||
* <p>
|
||||
* This is ignored if {@link #getObjectData()} is zero.
|
||||
*
|
||||
* @return The optional speed y.
|
||||
*/
|
||||
public double getOptionalSpeedY() {
|
||||
return handle.getIntegers().read(2) / 8000.0D;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the optional speed y.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setOptionalSpeedY(double value) {
|
||||
handle.getIntegers().write(2, (int) (value * 8000.0D));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the optional speed z.
|
||||
* <p>
|
||||
* This is ignored if {@link #getObjectData()} is zero.
|
||||
*
|
||||
* @return The optional speed z.
|
||||
*/
|
||||
public double getOptionalSpeedZ() {
|
||||
return handle.getIntegers().read(3) / 8000.0D;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the optional speed z.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setOptionalSpeedZ(double value) {
|
||||
handle.getIntegers().write(3, (int) (value * 8000.0D));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the pitch.
|
||||
*
|
||||
* @return The current pitch.
|
||||
*/
|
||||
public float getPitch() {
|
||||
return (handle.getIntegers().read(4) * 360.F) / 256.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the pitch.
|
||||
*
|
||||
* @param value - new pitch.
|
||||
*/
|
||||
public void setPitch(float value) {
|
||||
handle.getIntegers().write(4, (int) (value * 256.0F / 360.0F));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the yaw.
|
||||
*
|
||||
* @return The current Yaw
|
||||
*/
|
||||
public float getYaw() {
|
||||
return (handle.getIntegers().read(5) * 360.F) / 256.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the yaw of the object spawned.
|
||||
*
|
||||
* @param value - new yaw.
|
||||
*/
|
||||
public void setYaw(float value) {
|
||||
handle.getIntegers().write(5, (int) (value * 256.0F / 360.0F));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the type of object.
|
||||
*
|
||||
* @return The current Type
|
||||
*/
|
||||
public EntityType getType() {
|
||||
return handle.getEntityTypeModifier().read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type of object.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setType(EntityType value) {
|
||||
handle.getEntityTypeModifier().write(0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve object data.
|
||||
* <p>
|
||||
* The content depends on the object type:
|
||||
* <table border="1" cellpadding="4">
|
||||
* <tr>
|
||||
* <th>Object Type:</th>
|
||||
* <th>Name:</th>
|
||||
* <th>Description</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>ITEM_FRAME</td>
|
||||
* <td>Orientation</td>
|
||||
* <td>0-3: South, West, North, East</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>FALLING_BLOCK</td>
|
||||
* <td>Block Type</td>
|
||||
* <td>BlockID | (Metadata << 0xC)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>Projectiles</td>
|
||||
* <td>Entity ID</td>
|
||||
* <td>The entity ID of the thrower</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>Splash Potions</td>
|
||||
* <td>Data Value</td>
|
||||
* <td>Potion data value.</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* @return The current object Data
|
||||
*/
|
||||
public int getObjectData() {
|
||||
return handle.getIntegers().read(6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set object Data.
|
||||
* <p>
|
||||
* The content depends on the object type. See {@link #getObjectData()} for
|
||||
* more information.
|
||||
*
|
||||
* @param value - new object data.
|
||||
*/
|
||||
public void setObjectData(int value) {
|
||||
handle.getIntegers().write(6, value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package io.github.fisher2911.hmccosmetics.packet.wrappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
|
||||
public class WrapperPlayServerWindowItems extends AbstractPacket {
|
||||
public static final PacketType TYPE = PacketType.Play.Server.WINDOW_ITEMS;
|
||||
|
||||
public WrapperPlayServerWindowItems() {
|
||||
super(new PacketContainer(TYPE), TYPE);
|
||||
handle.getModifier().writeDefaults();
|
||||
}
|
||||
|
||||
public WrapperPlayServerWindowItems(PacketContainer packet) {
|
||||
super(packet, TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve Window ID.
|
||||
* <p>
|
||||
* Notes: the id of window which items are being sent for. 0 for player
|
||||
* inventory.
|
||||
*
|
||||
* @return The current Window ID
|
||||
*/
|
||||
public int getWindowId() {
|
||||
return handle.getIntegers().read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Window ID.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setWindowId(int value) {
|
||||
handle.getIntegers().write(0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve Slot data.
|
||||
*
|
||||
* @return The current Slot data
|
||||
*/
|
||||
public List<ItemStack> getSlotData() {
|
||||
return handle.getItemListModifier().read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Slot data.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setSlotData(List<ItemStack> value) {
|
||||
handle.getItemListModifier().write(0, value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,35 +1,32 @@
|
||||
package io.github.fisher2911.hmccosmetics.user;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
|
||||
import com.github.retrooper.packetevents.protocol.player.EquipmentSlot;
|
||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
||||
import io.github.fisher2911.hmccosmetics.config.Settings;
|
||||
import io.github.fisher2911.hmccosmetics.database.Database;
|
||||
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
||||
import io.github.fisher2911.hmccosmetics.packet.PacketManager;
|
||||
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||
import io.github.retrooper.packetevents.util.SpigotReflectionUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class Backpack {
|
||||
|
||||
private final HMCCosmetics plugin;
|
||||
private final int armorStandID;
|
||||
private final int particleCount = HMCCosmetics.getPlugin(HMCCosmetics.class).getSettings().getCosmeticSettings().getParticleCount();
|
||||
private final List<Integer> particleIDS = new ArrayList<>();
|
||||
|
||||
public Backpack(HMCCosmetics plugin, int armorStandID) {
|
||||
this.plugin = plugin;
|
||||
this.armorStandID = armorStandID;
|
||||
for (int i = 0; i < particleCount; i++) {
|
||||
particleIDS.add(SpigotReflectionUtil.generateEntityId());
|
||||
}
|
||||
}
|
||||
|
||||
public void spawn(BaseUser<?> owner, Player other, Location location, Settings settings) {
|
||||
@@ -38,6 +35,7 @@ public class Backpack {
|
||||
this.spawnForOther(owner, other, location);
|
||||
return;
|
||||
}
|
||||
this.updateIds(owner);
|
||||
this.spawnForSelf(other, location);
|
||||
}
|
||||
|
||||
@@ -49,7 +47,7 @@ public class Backpack {
|
||||
if (currentSize == particleCount) return;
|
||||
if (currentSize < particleCount) {
|
||||
for (int i = currentSize; i < particleCount; i++) {
|
||||
this.particleIDS.add(SpigotReflectionUtil.generateEntityId());
|
||||
this.particleIDS.add(Database.getNextEntityId());
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -57,9 +55,11 @@ public class Backpack {
|
||||
}
|
||||
|
||||
private void spawnForOther(BaseUser<?> owner, Player other, Location location) {
|
||||
PacketManager.sendEntitySpawnPacket(location, this.armorStandID, EntityTypes.ARMOR_STAND, other);
|
||||
PacketManager.sendEntitySpawnPacket(location, this.armorStandID, EntityType.ARMOR_STAND, other);
|
||||
PacketManager.sendArmorStandMetaContainer(this.armorStandID, other);
|
||||
PacketManager.sendRidingPacket(owner.getEntityId(), this.armorStandID, other);
|
||||
//plugin.getLogger().info("Sent spawnForOther. Mount: " + owner.getEntityId() + " | Armorstand: " + this.armorStandID);
|
||||
//PacketManager.sendRidingPacket(owner.getEntityId(), new int[]{this.armorStandID}, other);
|
||||
}
|
||||
|
||||
private void spawnForSelf(Player other, Location location) {
|
||||
@@ -67,13 +67,13 @@ public class Backpack {
|
||||
PacketManager.sendEntityNotLivingSpawnPacket(
|
||||
location,
|
||||
id,
|
||||
EntityTypes.AREA_EFFECT_CLOUD,
|
||||
EntityType.AREA_EFFECT_CLOUD,
|
||||
UUID.randomUUID(),
|
||||
0,
|
||||
other
|
||||
);
|
||||
}
|
||||
PacketManager.sendEntitySpawnPacket(location, this.armorStandID, EntityTypes.ARMOR_STAND, other);
|
||||
PacketManager.sendEntitySpawnPacket(location, this.armorStandID, EntityType.ARMOR_STAND, other);
|
||||
}
|
||||
|
||||
public void despawn(Player player) {
|
||||
@@ -96,37 +96,28 @@ public class Backpack {
|
||||
final boolean isSelf = owner.getId().equals(other.getUniqueId());
|
||||
final boolean firstPersonMode = settings.getCosmeticSettings().isFirstPersonBackpackMode();
|
||||
final ArmorItem.Type type = isSelf && firstPersonMode ? ArmorItem.Type.SELF_BACKPACK : ArmorItem.Type.BACKPACK;
|
||||
final List<com.github.retrooper.packetevents.protocol.player.Equipment> equipment = new ArrayList<>();
|
||||
final int lookDownPitch = settings.getCosmeticSettings().getLookDownPitch();
|
||||
final boolean hidden = !owner.shouldShow(other);
|
||||
ItemStack itemStack = owner.getPlayerArmor().getItem(type).getItemStack(ArmorItem.Status.APPLIED);
|
||||
Equipment equip = new Equipment();
|
||||
final boolean isLookingDown =
|
||||
!firstPersonMode &&
|
||||
isSelf &&
|
||||
lookDownPitch != -1 &&
|
||||
owner.isFacingDown(location, lookDownPitch);
|
||||
if (hidden || isLookingDown) {
|
||||
equipment.add(new com.github.retrooper.packetevents.protocol.player.Equipment(
|
||||
EquipmentSlot.HELMET,
|
||||
new com.github.retrooper.packetevents.protocol.item.ItemStack.Builder().
|
||||
type(ItemTypes.AIR).
|
||||
build()
|
||||
));
|
||||
PacketManager.sendEquipmentPacket(equipment, this.armorStandID, other);
|
||||
equip.setItem(EquipmentSlot.HEAD, new ItemStack(Material.AIR));
|
||||
PacketManager.sendEquipmentPacket(equip, this.armorStandID, other);
|
||||
return;
|
||||
}
|
||||
final com.github.retrooper.packetevents.protocol.item.ItemStack itemStack =
|
||||
SpigotConversionUtil.fromBukkitItemStack(owner.getPlayerArmor().getItem(type).getItemStack(ArmorItem.Status.APPLIED));
|
||||
equipment.add(new com.github.retrooper.packetevents.protocol.player.Equipment(
|
||||
EquipmentSlot.HELMET,
|
||||
itemStack
|
||||
));
|
||||
|
||||
PacketManager.sendEquipmentPacket(equipment, this.armorStandID, other);
|
||||
equip.setItem(EquipmentSlot.HEAD, itemStack);
|
||||
PacketManager.sendEquipmentPacket(equip, this.armorStandID, other);
|
||||
PacketManager.sendArmorStandMetaContainer(this.armorStandID, other);
|
||||
PacketManager.sendRotationPacket(this.armorStandID, location, false, other);
|
||||
PacketManager.sendLookPacket(this.armorStandID, location, other);
|
||||
if (!isSelf) {
|
||||
if (!isSelf || !firstPersonMode || this.particleIDS.size() == 0) {
|
||||
PacketManager.sendRidingPacket(owner.getEntityId(), this.armorStandID, other);
|
||||
//plugin.getLogger().info("Sent updateBackpack. Mount: " + owner.getEntityId() + " | Armorstand: " + this.armorStandID);
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < this.particleIDS.size(); i++) {
|
||||
@@ -139,6 +130,6 @@ public class Backpack {
|
||||
}
|
||||
}
|
||||
PacketManager.sendRidingPacket(particleIDS.get(particleIDS.size() - 1), this.armorStandID, other);
|
||||
//plugin.getLogger().info("Sent updateBackpack Other. Mount: " + owner.getEntityId() + " | Armorstand: " + this.armorStandID);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package io.github.fisher2911.hmccosmetics.user;
|
||||
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
import io.github.fisher2911.hmccosmetics.config.CosmeticSettings;
|
||||
import io.github.fisher2911.hmccosmetics.config.Settings;
|
||||
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
||||
import io.github.fisher2911.hmccosmetics.gui.BalloonItem;
|
||||
import io.github.fisher2911.hmccosmetics.hook.CitizensHook;
|
||||
import io.github.fisher2911.hmccosmetics.hook.HookManager;
|
||||
import io.github.fisher2911.hmccosmetics.hook.ModelEngineHook;
|
||||
import io.github.fisher2911.hmccosmetics.hook.entity.BalloonEntity;
|
||||
@@ -47,7 +47,7 @@ public abstract class BaseUser<T> {
|
||||
if (!HookManager.getInstance().isEnabled(ModelEngineHook.class)) {
|
||||
this.balloon = null;
|
||||
} else {
|
||||
this.balloon = new BalloonEntity(UUID.randomUUID(), -1, EntityType.PUFFERFISH);
|
||||
this.balloon = new BalloonEntity(entityIds.balloon(), getLocation());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ public abstract class BaseUser<T> {
|
||||
this.balloon.addPlayerToModel(other, id);
|
||||
}
|
||||
final int balloonId = this.getBalloonId();
|
||||
PacketManager.sendEntitySpawnPacket(actual, balloonId, EntityTypes.PUFFERFISH, other);
|
||||
PacketManager.sendEntitySpawnPacket(actual, balloonId, EntityType.PUFFERFISH, other);
|
||||
PacketManager.sendInvisibilityPacket(balloonId, other);
|
||||
PacketManager.sendLeashPacket(balloonId, this.getEntityId(), other);
|
||||
this.updateBalloon(other, location, settings);
|
||||
|
||||
@@ -1,17 +1,25 @@
|
||||
package io.github.fisher2911.hmccosmetics.user;
|
||||
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import io.github.fisher2911.hmccosmetics.packet.PacketManager;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.EntityEquipment;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class Equipment {
|
||||
|
||||
private static final EquipmentSlot[] VALUES = EquipmentSlot.values();
|
||||
private final Map<EquipmentSlot, ItemStack> equipment = new EnumMap<>(EquipmentSlot.class);
|
||||
private final HashMap<EquipmentSlot, ItemStack> equipment = new HashMap<>();
|
||||
|
||||
public Equipment() {
|
||||
}
|
||||
@@ -25,6 +33,24 @@ public class Equipment {
|
||||
return equipment;
|
||||
}
|
||||
|
||||
public static Equipment fromEntityEquipment(@Nullable final Player player) {
|
||||
if (player == null) return new Equipment();
|
||||
final Equipment equipment = new Equipment();
|
||||
for (final EquipmentSlot slot : VALUES) {
|
||||
equipment.setItem(slot, player.getInventory().getItem(slot));
|
||||
}
|
||||
return equipment;
|
||||
}
|
||||
|
||||
public static Equipment fromEntityEquipment(@Nullable final User user) {
|
||||
if (user == null) return new Equipment();
|
||||
final Equipment equipment = new Equipment();
|
||||
for (final EquipmentSlot slot : VALUES) {
|
||||
equipment.setItem(slot, user.getPlayer().getInventory().getItem(slot));
|
||||
}
|
||||
return equipment;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ItemStack getItem(final EquipmentSlot slot) {
|
||||
return this.equipment.get(slot);
|
||||
@@ -34,4 +60,19 @@ public class Equipment {
|
||||
this.equipment.put(slot, itemStack);
|
||||
}
|
||||
|
||||
public EquipmentSlot[] values() {
|
||||
return VALUES;
|
||||
}
|
||||
|
||||
public Set<EquipmentSlot> keys() {
|
||||
return equipment.keySet();
|
||||
}
|
||||
|
||||
public void removeSlot(EquipmentSlot slot) {
|
||||
equipment.remove(slot);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
equipment.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,10 @@ public class User extends BaseUser<UUID> {
|
||||
}
|
||||
|
||||
public @Nullable Player getPlayer() {
|
||||
// Forwhatever reason, this was sometimes null. Just a fallback in case
|
||||
if (this.playerReference == null) {
|
||||
return Bukkit.getPlayer(this.getId());
|
||||
}
|
||||
Player player = this.playerReference.get();
|
||||
if (player == null) {
|
||||
player = Bukkit.getPlayer(this.getId());
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.github.fisher2911.hmccosmetics.user;
|
||||
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
||||
import io.github.fisher2911.hmccosmetics.api.CosmeticItem;
|
||||
import io.github.fisher2911.hmccosmetics.api.event.CosmeticChangeEvent;
|
||||
@@ -13,6 +14,7 @@ import io.github.fisher2911.hmccosmetics.message.Placeholder;
|
||||
import io.github.fisher2911.hmccosmetics.message.Translation;
|
||||
import io.github.fisher2911.hmccosmetics.packet.PacketManager;
|
||||
import io.github.fisher2911.hmccosmetics.task.InfiniteTask;
|
||||
import io.github.fisher2911.hmccosmetics.util.PlayerUtils;
|
||||
import io.github.fisher2911.hmccosmetics.util.Utils;
|
||||
import io.github.fisher2911.hmccosmetics.util.builder.ItemBuilder;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -105,18 +107,14 @@ public class UserManager {
|
||||
this.sendUpdatePacket(
|
||||
user,
|
||||
other,
|
||||
this.getItemList(
|
||||
user,
|
||||
user.getEquipment(),
|
||||
Collections.emptySet()
|
||||
)
|
||||
getItemList(user)
|
||||
);
|
||||
}
|
||||
|
||||
public void updateCosmetics(final BaseUser<?> user) {
|
||||
this.sendUpdatePacket(
|
||||
user,
|
||||
this.getItemList(user, user.getEquipment(), Collections.emptySet())
|
||||
getItemList(user)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -148,18 +146,24 @@ public class UserManager {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
public List<com.github.retrooper.packetevents.protocol.player.Equipment> getItemList(
|
||||
public Equipment getItemList(
|
||||
final BaseUser<?> user
|
||||
) {
|
||||
return getItemList(user, user.getEquipment(), Collections.emptySet());
|
||||
}
|
||||
|
||||
public Equipment getItemList(
|
||||
final BaseUser<?> user,
|
||||
final Equipment equipment,
|
||||
final Set<ArmorItem.Type> ignored
|
||||
) {
|
||||
final PlayerArmor armor = user.getPlayerArmor();
|
||||
final List<com.github.retrooper.packetevents.protocol.player.Equipment> items = new ArrayList<>();
|
||||
for (final ArmorItem.Type type : ArmorItem.Type.values()) {
|
||||
final EquipmentSlot slot = type.getSlot();
|
||||
if (slot == null) continue;
|
||||
if (ignored.contains(type)) {
|
||||
items.add(PacketManager.getEquipment(equipment.getItem(slot), slot));
|
||||
Equipment item = PlayerUtils.getEquipment(equipment.getItem(slot), slot);
|
||||
equipment.setItem(slot, item.getItem(slot));
|
||||
continue;
|
||||
}
|
||||
final ItemStack wearing = Utils.replaceIfNull(equipment.getItem(slot), new ItemStack(Material.AIR));
|
||||
@@ -169,17 +173,9 @@ public class UserManager {
|
||||
ArmorItem.Status.APPLIED,
|
||||
slot
|
||||
);
|
||||
items.add(PacketManager.getEquipment(itemStack, slot));
|
||||
equipment.setItem(slot, itemStack);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
public List<com.github.retrooper.packetevents.protocol.player.Equipment> getEmptyItemList() {
|
||||
final List<com.github.retrooper.packetevents.protocol.player.Equipment> items = new ArrayList<>();
|
||||
for (final EquipmentSlot slot : EquipmentSlot.values()) {
|
||||
items.add(PacketManager.getEquipment(new ItemStack(Material.AIR), slot));
|
||||
}
|
||||
return items;
|
||||
return equipment;
|
||||
}
|
||||
|
||||
public void setItem(final BaseUser<?> user, final ArmorItem armorItem, final boolean sendPacket) {
|
||||
@@ -262,7 +258,8 @@ public class UserManager {
|
||||
|
||||
public void removeAll() {
|
||||
for (final var user : this.userMap.values()) {
|
||||
user.despawnAttached();
|
||||
// server is shutting down anyways when this is called
|
||||
//user.despawnAttached();
|
||||
}
|
||||
|
||||
this.userMap.clear();
|
||||
@@ -286,39 +283,42 @@ public class UserManager {
|
||||
final ArmorItem.Type type) {
|
||||
final EquipmentSlot slot = type.getSlot();
|
||||
final ItemStack itemStack = this.getCosmeticItem(armorItem, wearing, ArmorItem.Status.APPLIED, slot);
|
||||
final List<com.github.retrooper.packetevents.protocol.player.Equipment> itemList = new ArrayList<>();
|
||||
itemList.add(PacketManager.getEquipment(itemStack, slot));
|
||||
this.sendUpdatePacket(user, itemList);
|
||||
//final List<Equipment> itemList = new ArrayList<>();
|
||||
//itemList.add(PacketManager.getEquipment(itemStack, slot));
|
||||
Equipment equip = new Equipment();
|
||||
equip.setItem(slot, itemStack);
|
||||
this.sendUpdatePacket(user, equip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a packet to a player "updating" their equipment.
|
||||
* @param user The user having their equipment being updated.
|
||||
* @param equipment The equipment that is being set on the player.
|
||||
*/
|
||||
public void sendUpdatePacket(
|
||||
final BaseUser<?> user,
|
||||
List<com.github.retrooper.packetevents.protocol.player.Equipment> items
|
||||
Equipment equipment
|
||||
) {
|
||||
// final Player player = user.getPlayer();
|
||||
// if (player == null) return;
|
||||
final Location location = user.getLocation();
|
||||
if (location == null) return;
|
||||
final int entityId = user.getEntityId();
|
||||
if (items.isEmpty()) return;
|
||||
if (equipment == null) return;
|
||||
for (final User otherUser : this.userMap.values()) {
|
||||
final Player other = otherUser.getPlayer();
|
||||
if (other == null) continue;
|
||||
if (!user.shouldShow(other)) continue;
|
||||
if (!this.settings.getCosmeticSettings().isInViewDistance(location, other.getLocation())) continue;
|
||||
user.updateBackpack(other, this.settings);
|
||||
PacketManager.sendEquipmentPacket(
|
||||
items,
|
||||
entityId,
|
||||
other
|
||||
);
|
||||
PacketManager.sendEquipmentPacket(equipment, entityId, other);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendUpdatePacket(
|
||||
final BaseUser<?> user,
|
||||
final Player other,
|
||||
List<com.github.retrooper.packetevents.protocol.player.Equipment> items
|
||||
Equipment equipment
|
||||
) {
|
||||
// final Player player = user.getPlayer();
|
||||
// if (player == null) return;
|
||||
@@ -328,10 +328,6 @@ public class UserManager {
|
||||
if (other == null) return;
|
||||
if (!user.shouldShow(other)) return;
|
||||
if (!this.settings.getCosmeticSettings().isInViewDistance(location, other.getLocation())) return;
|
||||
PacketManager.sendEquipmentPacket(
|
||||
items,
|
||||
entityId,
|
||||
other
|
||||
);
|
||||
PacketManager.sendEquipmentPacket(equipment, entityId, other);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.github.fisher2911.hmccosmetics.user;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
import com.comphenix.protocol.wrappers.Vector3F;
|
||||
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
|
||||
import io.github.fisher2911.hmccosmetics.config.WardrobeSettings;
|
||||
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
|
||||
@@ -10,8 +10,13 @@ import io.github.fisher2911.hmccosmetics.task.SupplierTask;
|
||||
import io.github.fisher2911.hmccosmetics.task.Task;
|
||||
import io.github.fisher2911.hmccosmetics.task.TaskChain;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -28,6 +33,8 @@ public class Wardrobe extends User {
|
||||
private boolean active;
|
||||
private boolean spawned;
|
||||
private Location currentLocation;
|
||||
private Location enterLocation;
|
||||
private GameMode originalGamemode;
|
||||
|
||||
public Wardrobe(
|
||||
final HMCCosmetics plugin,
|
||||
@@ -42,11 +49,27 @@ public class Wardrobe extends User {
|
||||
this.ownerUUID = ownerUUID;
|
||||
this.active = active;
|
||||
this.wardrobe = this;
|
||||
this.originalGamemode = GameMode.SURVIVAL;
|
||||
}
|
||||
|
||||
public void spawnFakePlayer(final Player viewer) {
|
||||
final UserManager userManager = this.plugin.getUserManager();
|
||||
final WardrobeSettings settings = this.plugin.getSettings().getWardrobeSettings();
|
||||
this.originalGamemode = viewer.getGameMode();
|
||||
this.enterLocation = viewer.getLocation();
|
||||
Bukkit.getScheduler().runTaskAsynchronously(this.plugin, () -> {
|
||||
PacketManager.sendEntitySpawnPacket(
|
||||
settings.getViewerLocation(),
|
||||
this.entityIds.wardrobeViewer(),
|
||||
EntityType.ARMOR_STAND,
|
||||
viewer
|
||||
);
|
||||
PacketManager.sendFakePlayerInfoPacket(viewer, this.getId(), viewer);
|
||||
PacketManager.sendInvisibilityPacket(
|
||||
this.entityIds.wardrobeViewer(),
|
||||
viewer
|
||||
);
|
||||
});
|
||||
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(
|
||||
this.plugin,
|
||||
@@ -54,20 +77,15 @@ public class Wardrobe extends User {
|
||||
if (settings.inDistanceOfStatic(viewer.getLocation())) {
|
||||
this.currentLocation = settings.getWardrobeLocation();
|
||||
userManager.get(viewer.getUniqueId()).ifPresent(user -> {
|
||||
userManager.sendUpdatePacket(user, userManager.getEmptyItemList());
|
||||
userManager.sendUpdatePacket(user, userManager.getItemList(user));
|
||||
user.despawnAttached();
|
||||
user.despawnBalloon();
|
||||
});
|
||||
PacketManager.sendEntitySpawnPacket(
|
||||
settings.getViewerLocation(),
|
||||
this.entityIds.wardrobeViewer(),
|
||||
EntityTypes.ARMOR_STAND,
|
||||
viewer
|
||||
);
|
||||
PacketManager.sendCameraPacket(
|
||||
this.entityIds.wardrobeViewer(),
|
||||
viewer
|
||||
);
|
||||
// This makes the player viewing the wardrobe invisible
|
||||
PacketManager.sendInvisibilityPacket(
|
||||
this.entityIds.wardrobeViewer(),
|
||||
viewer
|
||||
@@ -77,10 +95,15 @@ public class Wardrobe extends User {
|
||||
settings.getViewerLocation(),
|
||||
viewer
|
||||
);
|
||||
// This make the person viewing the wardrobe invisible
|
||||
PacketManager.sendInvisibilityPacket(
|
||||
viewer.getEntityId(),
|
||||
viewer
|
||||
);
|
||||
PacketManager.sendGameModeChange(
|
||||
viewer,
|
||||
GameMode.SPECTATOR
|
||||
);
|
||||
this.hidePlayer();
|
||||
this.setActive(true);
|
||||
} else if (this.currentLocation == null) {
|
||||
@@ -91,8 +114,8 @@ public class Wardrobe extends User {
|
||||
return;
|
||||
}
|
||||
final int entityId = this.getEntityId();
|
||||
PacketManager.sendFakePlayerInfoPacket(viewer, this.getId(), viewer);
|
||||
PacketManager.sendFakePlayerSpawnPacket(this.currentLocation, this.getId(), entityId, viewer);
|
||||
PacketManager.sendNewTeam(viewer, viewer);
|
||||
PacketManager.sendLookPacket(entityId, this.currentLocation, viewer);
|
||||
PacketManager.sendRotationPacket(entityId, this.currentLocation, true, viewer);
|
||||
PacketManager.sendPlayerOverlayPacket(entityId, viewer);
|
||||
@@ -110,9 +133,8 @@ public class Wardrobe extends User {
|
||||
);
|
||||
}
|
||||
});
|
||||
// PacketManager.sendEntitySpawnPacket(this.currentLocation, this.getEntityId(), EntityTypes.ZOMBIE, viewer);
|
||||
this.spawned = true;
|
||||
this.startSpinTask(viewer);
|
||||
this.updateTask(viewer);
|
||||
},
|
||||
settings.getSpawnDelay()
|
||||
);
|
||||
@@ -137,6 +159,9 @@ public class Wardrobe extends User {
|
||||
viewer
|
||||
);
|
||||
this.showPlayer(this.plugin.getUserManager());
|
||||
PacketManager.sendGameModeChange(
|
||||
viewer, originalGamemode
|
||||
);
|
||||
final Collection<ArmorItem> armorItems = new ArrayList<>(this.getPlayerArmor().getArmorItems());
|
||||
if (settings.isApplyCosmeticsOnClose()) {
|
||||
final Optional<User> optionalUser = userManager.get(this.ownerUUID);
|
||||
@@ -167,32 +192,51 @@ public class Wardrobe extends User {
|
||||
},
|
||||
true
|
||||
).chain(
|
||||
() -> viewer.teleport(settings.getLeaveLocation())
|
||||
() -> {
|
||||
if (settings.isReturnLastLocation()) {
|
||||
viewer.teleport(enterLocation);
|
||||
} else {
|
||||
viewer.teleport(settings.getLeaveLocation());
|
||||
}
|
||||
}
|
||||
).chain(() -> {
|
||||
this.despawnAttached();
|
||||
this.despawnBalloon();
|
||||
}, true).
|
||||
execute();
|
||||
}, true)
|
||||
.execute();
|
||||
},
|
||||
settings.getDespawnDelay()
|
||||
);
|
||||
}
|
||||
|
||||
private void startSpinTask(final Player player) {
|
||||
/**
|
||||
* Used as an updater to send packets and other information to the player while they are in the wardrobe
|
||||
* @param player
|
||||
*/
|
||||
private void updateTask(final Player player) {
|
||||
final AtomicInteger data = new AtomicInteger();
|
||||
final int rotationSpeed = this.plugin.getSettings().getWardrobeSettings().getRotationSpeed();
|
||||
final boolean equipPumpkin = this.plugin.getSettings().getWardrobeSettings().isEquipPumpkin();
|
||||
final int entityId = this.getEntityId();
|
||||
final Task task = new SupplierTask(
|
||||
() -> {
|
||||
if (this.currentLocation == null) return;
|
||||
final Location location = this.currentLocation.clone();
|
||||
final int yaw = data.get();
|
||||
|
||||
location.setYaw(yaw);
|
||||
PacketManager.sendLookPacket(entityId, location, player);
|
||||
this.updateOutsideCosmetics(player, location, this.plugin.getSettings());
|
||||
location.setYaw(this.getNextYaw(yaw - 30, rotationSpeed));
|
||||
PacketManager.sendRotationPacket(entityId, location, true, player);
|
||||
data.set(this.getNextYaw(yaw, rotationSpeed));
|
||||
|
||||
// Need to put the pumpkin here because it will be overriden otherwise ~ LoJoSho
|
||||
if (equipPumpkin) {
|
||||
Equipment equipment = new Equipment();
|
||||
equipment.setItem(EquipmentSlot.HEAD, new ItemStack(Material.CARVED_PUMPKIN));
|
||||
PacketManager.sendEquipmentPacket(equipment, player.getEntityId(), player);
|
||||
}
|
||||
},
|
||||
() -> !this.spawned || this.currentLocation == null
|
||||
);
|
||||
@@ -200,8 +244,12 @@ public class Wardrobe extends User {
|
||||
}
|
||||
|
||||
private int getNextYaw(final int current, final int rotationSpeed) {
|
||||
if (current + rotationSpeed > 179) return -179;
|
||||
return current + rotationSpeed;
|
||||
int nextYaw = current + rotationSpeed;
|
||||
if (nextYaw > 179) {
|
||||
nextYaw = (current + rotationSpeed) - 358;
|
||||
return nextYaw;
|
||||
}
|
||||
return nextYaw;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package io.github.fisher2911.hmccosmetics.util;
|
||||
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
||||
import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
||||
import com.comphenix.protocol.wrappers.WrappedSignedProperty;
|
||||
import io.github.fisher2911.hmccosmetics.user.Equipment;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class PlayerUtils {
|
||||
|
||||
public static WrappedSignedProperty getSkin(Player player) {
|
||||
WrappedSignedProperty skinData = WrappedGameProfile.fromPlayer(player).getProperties()
|
||||
.get("textures").stream().findAny().orElse(null);
|
||||
|
||||
if (skinData == null)
|
||||
throw new RuntimeException("Missing skin data");
|
||||
|
||||
return new WrappedSignedProperty("textures", skinData.getValue(), skinData.getSignature());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the equipment of a slot
|
||||
* @param itemStack the ItemStack of a slot
|
||||
* @param slot the slot to look at
|
||||
* @return returns the equipment at a slot
|
||||
*/
|
||||
// It works now, need to redo this sytem sometime in the future...
|
||||
public static Equipment getEquipment(
|
||||
final ItemStack itemStack,
|
||||
final org.bukkit.inventory.EquipmentSlot slot
|
||||
) {
|
||||
Equipment equip = new Equipment();
|
||||
equip.setItem(slot, itemStack);
|
||||
return equip;
|
||||
}
|
||||
/*
|
||||
public static EquipmentSlot fromBukkitSlot(final org.bukkit.inventory.EquipmentSlot slot) {
|
||||
return switch (slot) {
|
||||
case HEAD -> EquipmentSlot.HELMET;
|
||||
case CHEST -> EquipmentSlot.CHEST_PLATE;
|
||||
case LEGS -> EquipmentSlot.LEGGINGS;
|
||||
case FEET -> EquipmentSlot.BOOTS;
|
||||
case HAND -> EquipmentSlot.MAIN_HAND;
|
||||
case OFF_HAND -> EquipmentSlot.OFF_HAND;
|
||||
};
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Converts from the Bukkit item slots to ProtocolLib item slots. Will produce a null if an improper bukkit item slot is sent through
|
||||
* @param slot The BUKKIT item slot to convert.
|
||||
* @return The ProtocolLib item slot that is returned
|
||||
*/
|
||||
public static EnumWrappers.ItemSlot itemBukkitSlot(final EquipmentSlot slot) {
|
||||
return switch (slot) {
|
||||
case HEAD -> EnumWrappers.ItemSlot.HEAD;
|
||||
case CHEST -> EnumWrappers.ItemSlot.CHEST;
|
||||
case LEGS -> EnumWrappers.ItemSlot.LEGS;
|
||||
case FEET -> EnumWrappers.ItemSlot.FEET;
|
||||
case HAND -> EnumWrappers.ItemSlot.MAINHAND;
|
||||
case OFF_HAND -> EnumWrappers.ItemSlot.OFFHAND;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a bukkit gamemode into an integer for use in packets
|
||||
* @param gamemode Bukkit gamemode to convert.
|
||||
* @return int of the gamemode
|
||||
*/
|
||||
public static int convertGamemode(final GameMode gamemode) {
|
||||
return switch (gamemode) {
|
||||
case SURVIVAL -> 0;
|
||||
case CREATIVE -> 1;
|
||||
case ADVENTURE -> 2;
|
||||
case SPECTATOR -> 3;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,10 @@ cosmetic-settings:
|
||||
require-empty-chest-plate: false
|
||||
require-empty-pants: false
|
||||
require-empty-boots: false
|
||||
# Disable if you don't want to use the first person backpack system
|
||||
# See the wiki for more information
|
||||
# This option has been temporarily disabled in the beta releases.
|
||||
first-person-backpack-mode: false
|
||||
|
||||
# The pitch the player must look down for the backpack to be removed
|
||||
# Set to -1 for no removal
|
||||
@@ -38,6 +42,10 @@ wardrobe:
|
||||
despawn-delay: 40
|
||||
# if cosmetics that the user have permissions for should be applied on close of wardrobe
|
||||
apply-cosmetics-on-close: true
|
||||
# Applies a pumpkin for an overlay of the player while in the wardrobe.
|
||||
equip-pumpkin: false
|
||||
# Rather than having a set exit location, this will send the player back to where they entered the wardrobe.
|
||||
return-last-location: false
|
||||
open-sound:
|
||||
sound: # Play a sound
|
||||
name: "minecraft:block.chain.break"
|
||||
|
||||
28
common/src/main/resources/items.yml
Normal file
28
common/src/main/resources/items.yml
Normal file
@@ -0,0 +1,28 @@
|
||||
1:
|
||||
material: PAPER
|
||||
name: "<blue>Backpack"
|
||||
lore:
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore:
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
model-data: 8
|
||||
type: SELF_BACKPACK
|
||||
permission: ""
|
||||
id: backpack_self
|
||||
2:
|
||||
material: PAPER
|
||||
name: "<blue>Future Wings"
|
||||
lore:
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore:
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
model-data: 10
|
||||
type: SELF_BACKPACK
|
||||
permission: ""
|
||||
id: future_wings_self
|
||||
@@ -11,7 +11,7 @@ items:
|
||||
locked-lore: # Lore displayed when the player does not have the correct permission.
|
||||
- "<red>You do not own this item!"
|
||||
applied-lore: # Lore displayed when the player has the cosmetic in their inventory.
|
||||
- "<gray>My awesome <rainbow>Colorful Hat</rainbow>!"
|
||||
- "<gray>My awesome <rainbow>Colorful Hat</rainbow>!"
|
||||
amount: 1
|
||||
model-data: 2 # CustomModelData Number
|
||||
type: HAT
|
||||
@@ -36,10 +36,32 @@ items:
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
model-data: 4
|
||||
action:
|
||||
equip:
|
||||
any:
|
||||
set-cosmetics: backpack_self
|
||||
type: BACKPACK
|
||||
permission: ""
|
||||
id: backpack
|
||||
3:
|
||||
material: PAPER
|
||||
name: "<#d24c9f>Future Wings"
|
||||
lore:
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore:
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
model-data: 9
|
||||
action:
|
||||
equip:
|
||||
any:
|
||||
set-cosmetics: future_wings_self
|
||||
type: BACKPACK
|
||||
permission: ""
|
||||
id: future_wings
|
||||
4:
|
||||
material: PAPER
|
||||
name: "<blue>Lantern Cosmetic"
|
||||
lore:
|
||||
@@ -53,7 +75,7 @@ items:
|
||||
type: OFF_HAND
|
||||
permission: ""
|
||||
id: lantern_cosmetic
|
||||
4:
|
||||
5:
|
||||
material: PAPER
|
||||
name: "<blue>Baseball Hat"
|
||||
lore:
|
||||
@@ -67,7 +89,49 @@ items:
|
||||
type: HAT
|
||||
permission: ""
|
||||
id: baseball_hat
|
||||
5:
|
||||
6:
|
||||
material: PAPER
|
||||
name: "<green>Frog Hat"
|
||||
lore:
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore:
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
model-data: 11
|
||||
type: HAT
|
||||
permission: ""
|
||||
id: frog_hat
|
||||
7:
|
||||
material: PAPER
|
||||
name: "<#d24c9f>Jetpack"
|
||||
lore:
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore:
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
model-data: 12
|
||||
type: BACKPACK
|
||||
permission: ""
|
||||
id: jetpack
|
||||
10:
|
||||
material: PAPER
|
||||
name: "<#d24c9f>Hammer"
|
||||
lore:
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore:
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
model-data: 13
|
||||
type: OFF_HAND
|
||||
permission: ""
|
||||
id: hammer
|
||||
11:
|
||||
material: DIAMOND_CHESTPLATE
|
||||
name: "<blue>Cosmetic Chestplate"
|
||||
lore:
|
||||
@@ -80,7 +144,7 @@ items:
|
||||
type: CHEST_PLATE
|
||||
permission: ""
|
||||
id: chestplate
|
||||
6:
|
||||
12:
|
||||
material: DIAMOND_LEGGINGS
|
||||
name: "<blue>Cosmetic Leggings"
|
||||
lore:
|
||||
@@ -93,7 +157,7 @@ items:
|
||||
type: PANTS
|
||||
permission: ""
|
||||
id: pants
|
||||
7:
|
||||
13:
|
||||
material: DIAMOND_BOOTS
|
||||
name: "<blue>Cosmetic Boots"
|
||||
lore:
|
||||
@@ -106,7 +170,7 @@ items:
|
||||
type: BOOTS
|
||||
permission: ""
|
||||
id: boots
|
||||
10:
|
||||
14:
|
||||
material: PAPER
|
||||
name: "<blue>Balloon"
|
||||
lore:
|
||||
|
||||
@@ -1,193 +0,0 @@
|
||||
title: "<white>" # GUI Title
|
||||
rows: 5 # Rows in the GUI
|
||||
items:
|
||||
1: # GUI Slot number
|
||||
material: LEATHER_HORSE_ARMOR # Also supports Oraxen items! Format: "oraxen:item_name"
|
||||
name: "<rainbow>Colorful Hat</rainbow>"
|
||||
lore: # Lore displayed when the player owns the item
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore: # Lore displayed when the player does not have the correct permission.
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
model-data: 2 # CustomModelData Number
|
||||
type: HAT
|
||||
dyeable: true # Enables dyeable item feature
|
||||
color: # Sets default color for item. Uses RGB format.
|
||||
red: 5
|
||||
green: 230
|
||||
blue: 100
|
||||
action: # See how the action system works on the wiki
|
||||
any:
|
||||
open-menu: dye-menu
|
||||
permission: "cosmetics.colorful_hat" # Can be anything you want.
|
||||
id: colorful_hat # Internal identifier. Can be anything you want.
|
||||
2:
|
||||
material: PAPER
|
||||
name: "<blue>Backpack"
|
||||
lore:
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore:
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
model-data: 4
|
||||
type: BACKPACK
|
||||
permission: ""
|
||||
id: backpack
|
||||
action:
|
||||
# when the action should be run
|
||||
# equip = when a cosmetic is equipped
|
||||
# remove = when a cosmetic is removed
|
||||
# any all = default, does not need to be specified
|
||||
equip:
|
||||
# click type
|
||||
any:
|
||||
send-message: "on equip"
|
||||
remove:
|
||||
any:
|
||||
send-message: "on-remove"
|
||||
any:
|
||||
# send a message
|
||||
send-message: "Test first message"
|
||||
# send a command, format is <sender:command>
|
||||
# senders can be player or console
|
||||
send-command: "player:give %player% diamond"
|
||||
# list of messages
|
||||
send-messages:
|
||||
- "Message 1"
|
||||
- "Message 2"
|
||||
# list of commands
|
||||
send-commands:
|
||||
- "player:help"
|
||||
- "console:give %player% gold_ingot"
|
||||
# set items in the specified slots in the inventory
|
||||
# works with all actions
|
||||
# sets items in the next inventory if open-menu is specified
|
||||
set-items:
|
||||
12:
|
||||
material: PAPER
|
||||
name: "<red>Backpack"
|
||||
lore:
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore:
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
model-data: 4
|
||||
type: BACKPACK
|
||||
permission: ""
|
||||
id: backpack
|
||||
action:
|
||||
any:
|
||||
send-message: "It worked?"
|
||||
set-items:
|
||||
12:
|
||||
material: PAPER
|
||||
name: "<rainbow>Backpack"
|
||||
lore:
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore:
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
model-data: 4
|
||||
type: BACKPACK
|
||||
permission: ""
|
||||
id: backpack
|
||||
|
||||
3:
|
||||
material: PAPER
|
||||
name: "<blue>Lantern Cosmetic"
|
||||
lore:
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore:
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
model-data: 5
|
||||
type: OFF_HAND
|
||||
permission: ""
|
||||
id: lantern_cosmetic
|
||||
4:
|
||||
material: PAPER
|
||||
name: "<blue>Baseball Hat"
|
||||
lore:
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore:
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
model-data: 6
|
||||
type: HAT
|
||||
permission: ""
|
||||
id: baseball_hat
|
||||
5:
|
||||
material: DIAMOND_CHESTPLATE
|
||||
name: "<blue>Cosmetic Chestplate"
|
||||
lore:
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore:
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
type: CHEST_PLATE
|
||||
permission: ""
|
||||
id: chestplate
|
||||
6:
|
||||
material: DIAMOND_LEGGINGS
|
||||
name: "<blue>Cosmetic Leggings"
|
||||
lore:
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore:
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
type: PANTS
|
||||
permission: ""
|
||||
id: pants
|
||||
7:
|
||||
material: DIAMOND_BOOTS
|
||||
name: "<blue>Cosmetic Boots"
|
||||
lore:
|
||||
- ""
|
||||
- "<gray>Enabled: <#6D9DC5>%enabled%"
|
||||
- "<gray>Allowed: <#6D9DC5>%allowed%"
|
||||
locked-lore:
|
||||
- "<red>You do not own this item!"
|
||||
amount: 1
|
||||
type: BOOTS
|
||||
permission: ""
|
||||
id: boots
|
||||
37:
|
||||
material: PAPER
|
||||
name: "<#40B7D6>Previous Page"
|
||||
amount: 1
|
||||
model-data: 1
|
||||
action:
|
||||
any:
|
||||
open-menu: menu-2
|
||||
40:
|
||||
material: PAPER
|
||||
name: "<rainbow>Customization Menu</rainbow>"
|
||||
amount: 1
|
||||
model-data: 3
|
||||
action:
|
||||
any:
|
||||
open-menu: dye-menu
|
||||
43:
|
||||
material: PAPER
|
||||
name: "<#40B7D6>Next Page"
|
||||
amount: 1
|
||||
model-data: 2
|
||||
action:
|
||||
any:
|
||||
open-menu: menu-2
|
||||
2
gradle.properties
Normal file
2
gradle.properties
Normal file
@@ -0,0 +1,2 @@
|
||||
copyJar=false
|
||||
hibiscusmc_plugin_path=""
|
||||
Reference in New Issue
Block a user