feat: wrappers

This commit is contained in:
ineanto 2023-04-25 23:25:14 +02:00
parent 94634f7bba
commit cee168e225
6 changed files with 228 additions and 22 deletions

View file

@ -1,7 +1,9 @@
package net.artelnatif.nicko; package net.artelnatif.nicko;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager; import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.*;
import net.artelnatif.nicko.command.NickoCommand; import net.artelnatif.nicko.command.NickoCommand;
import net.artelnatif.nicko.config.Configuration; import net.artelnatif.nicko.config.Configuration;
import net.artelnatif.nicko.config.ConfigurationManager; import net.artelnatif.nicko.config.ConfigurationManager;
@ -27,6 +29,7 @@ import xyz.xenondevs.invui.item.impl.SimpleItem;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Field;
public class NickoBukkit extends JavaPlugin { public class NickoBukkit extends JavaPlugin {
private static NickoBukkit plugin; private static NickoBukkit plugin;
@ -104,6 +107,27 @@ public class NickoBukkit extends JavaPlugin {
getServer().getPluginManager().registerEvents(new PlayerJoinListener(), this); getServer().getPluginManager().registerEvents(new PlayerJoinListener(), this);
getServer().getPluginManager().registerEvents(new PlayerQuitListener(), this); getServer().getPluginManager().registerEvents(new PlayerQuitListener(), this);
protocolManager.addPacketListener(new PacketAdapter(
this,
ListenerPriority.NORMAL,
PacketType.Play.Server.PLAYER_INFO) {
@Override
public void onPacketReceiving(PacketEvent event) {
}
@Override
public void onPacketSending(PacketEvent event) {
final PacketContainer packet = event.getPacket();
packet.getStructures().getFields().forEach(fieldAccessor -> {
final Field field = fieldAccessor.getField();
getLogger().info("field=[" +
"name=" + field.getName() + "," +
"type=" + field.getType().getSimpleName() +
"]");
});
}
});
getLogger().info("Nicko (Bukkit) has been enabled."); getLogger().info("Nicko (Bukkit) has been enabled.");
} }
} }

View file

@ -1,20 +1,23 @@
package net.artelnatif.nicko.disguise; package net.artelnatif.nicko.disguise;
import com.comphenix.protocol.wrappers.WrappedGameProfile; import com.comphenix.protocol.wrappers.*;
import com.comphenix.protocol.wrappers.WrappedSignedProperty; import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multimap;
import net.artelnatif.nicko.NickoBukkit; import net.artelnatif.nicko.NickoBukkit;
import net.artelnatif.nicko.i18n.I18NDict; import net.artelnatif.nicko.i18n.I18NDict;
import net.artelnatif.nicko.mojang.MojangAPI; import net.artelnatif.nicko.mojang.MojangAPI;
import net.artelnatif.nicko.mojang.MojangSkin; import net.artelnatif.nicko.mojang.MojangSkin;
import net.artelnatif.nicko.storage.PlayerDataStore; import net.artelnatif.nicko.storage.PlayerDataStore;
import net.artelnatif.nicko.storage.name.PlayerNameStore; import net.artelnatif.nicko.storage.name.PlayerNameStore;
import net.artelnatif.nicko.wrapper.WrapperPlayServerRespawn;
import net.artelnatif.nicko.wrapper.WrapperPlayerServerPlayerInfo;
import net.artelnatif.nicko.wrapper.WrapperPlayerServerPlayerInfoRemove;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent;
import java.io.IOException; import java.io.IOException;
import java.util.Collection; import java.util.EnumSet;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
@ -95,9 +98,9 @@ public class AppearanceManager {
public ActionResult<Void> updatePlayer(boolean skinChange) { public ActionResult<Void> updatePlayer(boolean skinChange) {
final String displayName = profile.getName() == null ? player.getName() : profile.getName(); final String displayName = profile.getName() == null ? player.getName() : profile.getName();
Bukkit.broadcastMessage("Building UserProfile");
final WrappedGameProfile gameProfile = new WrappedGameProfile(player.getUniqueId(), displayName);
Bukkit.broadcastMessage("Building UserProfile");
final WrappedGameProfile gameProfile = WrappedGameProfile.fromPlayer(player).withName(displayName);
final ActionResult<Void> result = updateGameProfileSkin(gameProfile, skinChange); final ActionResult<Void> result = updateGameProfileSkin(gameProfile, skinChange);
if (!result.isError()) { if (!result.isError()) {
updateTabList(gameProfile, displayName); updateTabList(gameProfile, displayName);
@ -118,9 +121,9 @@ public class AppearanceManager {
skin = mojang.getSkin(uuid.get()); skin = mojang.getSkin(uuid.get());
if (skin.isPresent()) { if (skin.isPresent()) {
final MojangSkin skinResult = skin.get(); final MojangSkin skinResult = skin.get();
final Collection<WrappedSignedProperty> properties = gameProfile.getProperties().values(); final Multimap<String, WrappedSignedProperty> properties = gameProfile.getProperties();
properties.clear(); properties.get("textures").clear();
properties.add(new WrappedSignedProperty("textures", skinResult.getValue(), skinResult.getSignature())); properties.put("textures", new WrappedSignedProperty("textures", skinResult.getValue(), skinResult.getSignature()));
Bukkit.broadcastMessage("Modified properties"); Bukkit.broadcastMessage("Modified properties");
} }
} }
@ -137,14 +140,32 @@ public class AppearanceManager {
private void respawnPlayer() { private void respawnPlayer() {
Bukkit.broadcastMessage("Respawning player"); Bukkit.broadcastMessage("Respawning player");
final World world = player.getWorld(); final World world = player.getWorld();
// TODO (Ineanto, 4/23/23): Respawn Packet final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn();
player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); respawn.setGameMode(player.getGameMode());
respawn.setDifficulty(world.getDifficulty());
respawn.setDimension(world);
respawn.setSeed(world.getSeed());
respawn.sendPacket(player);
} }
private void updateTabList(WrappedGameProfile gameProfile, String displayName) { private void updateTabList(WrappedGameProfile gameProfile, String displayName) {
// TODO (Ineanto, 4/23/23): Update player info packet
// TODO (Ineanto, 4/23/23): Remove player info packet
Bukkit.broadcastMessage("Updating tablist"); Bukkit.broadcastMessage("Updating tablist");
// TODO (Ineanto, 4/23/23): Send packets final WrapperPlayerServerPlayerInfoRemove remove = new WrapperPlayerServerPlayerInfoRemove();
remove.setUUIDs(ImmutableList.of(player.getUniqueId()));
final WrapperPlayerServerPlayerInfo update = new WrapperPlayerServerPlayerInfo();
update.setActions(EnumSet.of(EnumWrappers.PlayerInfoAction.ADD_PLAYER,
EnumWrappers.PlayerInfoAction.UPDATE_LISTED,
EnumWrappers.PlayerInfoAction.UPDATE_DISPLAY_NAME,
EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE,
EnumWrappers.PlayerInfoAction.UPDATE_LATENCY));
update.setData(ImmutableList.of(new PlayerInfoData(
gameProfile,
player.getPing(),
EnumWrappers.NativeGameMode.fromBukkit(player.getGameMode()),
WrappedChatComponent.fromText(displayName)
)));
remove.sendPacket(player);
update.sendPacket(player);
} }
} }

View file

@ -2,12 +2,17 @@ package net.artelnatif.nicko.wrapper;
import com.comphenix.protocol.PacketType; import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.utility.MinecraftVersion;
import com.comphenix.protocol.wrappers.BukkitConverters;
import com.comphenix.protocol.wrappers.EnumWrappers;
import org.bukkit.Difficulty;
import org.bukkit.GameMode;
import org.bukkit.World; import org.bukkit.World;
import java.util.Optional;
/** /**
* 1.19.4 compliant version of the WrapperPlayServerRespawn. * Up-to-date version of the Wrapper class
* for the PacketPlayServerRespawn.
* *
* @author ineanto, based on work from dmulloy2 and Kristian S. Strangeland * @author ineanto, based on work from dmulloy2 and Kristian S. Strangeland
*/ */
@ -19,19 +24,92 @@ public class WrapperPlayServerRespawn extends AbstractPacket {
handle.getModifier().writeDefaults(); handle.getModifier().writeDefaults();
} }
public Optional<World> getDimension() { //.............
return handle.getDimensionTypes().optionRead(0); // Dimension Field (1.8 - Present)
// The dimension field has changed types,
// numerous times. Version 1.8 through 1.15 need an integer,
// 1.15 through 1.18 need a (NBT Tag) Identifier and
// 1.19.2 and beyond require a Holder of a DimensionManager Identifier (???).
// (Wiki.vg still refers this as an Identifier)
//
// n.b.: this field is a nightmare please mojang stop refactoring
// your code to change things that were working perfectly fine before
//.............
public World getDimension() {
if (MinecraftVersion.WILD_UPDATE.atOrAbove()) {
// 1.19 and above
return handle.getHolders(
MinecraftReflection.getDimensionManager(),
BukkitConverters.getDimensionConverter()
).read(0);
}
return handle.getDimensionTypes().read(0);
} }
public void setDimension(World value) { public void setDimension(World value) {
if (MinecraftVersion.WILD_UPDATE.atOrAbove()) {
// 1.19 and above
handle.getWorldKeys().withParamType(
MinecraftReflection.getResourceKey(),
BukkitConverters.getWorldKeyConverter()
).write(0, value);
return;
}
// 1.18 and below
handle.getDimensionTypes().write(0, value); handle.getDimensionTypes().write(0, value);
} }
public Optional<Long> getSeed() { //.............
return handle.getLongs().optionRead(0); // GameMode Field
//.............
public void getGameMode() {
// Present since 1.8, we're good!
handle.getGameModes().read(0);
}
public void setGameMode(GameMode value) {
// Present since 1.8, we're good!
handle.getGameModes().write(0, EnumWrappers.NativeGameMode.fromBukkit(value));
}
//.............
// Seed Field
// Added in 1.15.
//.............
public long getSeed() {
if (MinecraftVersion.BEE_UPDATE.atOrAbove()) {
return handle.getLongs().read(0);
}
return -1;
} }
public void setSeed(long value) { public void setSeed(long value) {
handle.getLongs().write(0, value); if (MinecraftVersion.BEE_UPDATE.atOrAbove()) {
handle.getLongs().write(0, value);
}
}
//.............
// Difficulty Field
// Removed in 1.14.
//.............
public Difficulty getDifficulty() {
if (MinecraftVersion.VILLAGE_UPDATE.atOrAbove()) {
return null;
}
final EnumWrappers.Difficulty difficulty = handle.getDifficulties().read(0);
return difficulty == null ? null : Difficulty.valueOf(difficulty.name());
}
public void setDifficulty(Difficulty difficulty) {
if (difficulty != null && !MinecraftVersion.VILLAGE_UPDATE.atOrAbove()) {
handle.getDifficulties().write(0, EnumWrappers.Difficulty.valueOf(difficulty.name()));
}
} }
} }

View file

@ -0,0 +1,46 @@
package net.artelnatif.nicko.wrapper;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.wrappers.EnumWrappers;
import com.comphenix.protocol.wrappers.PlayerInfoData;
import java.util.List;
import java.util.Set;
/**
* Up-to-date version of the Wrapper class
* for the PlayerServerPlayerInfo.
*
* @author ineanto, based on work from dmulloy2 and Kristian S. Strangeland
*/
public class WrapperPlayerServerPlayerInfo extends AbstractPacket {
public static final PacketType TYPE = PacketType.Play.Server.PLAYER_INFO;
public WrapperPlayerServerPlayerInfo() {
super(new PacketContainer(TYPE), TYPE);
handle.getModifier().writeDefaults();
}
public WrapperPlayerServerPlayerInfo(PacketContainer packet) {
super(packet, TYPE);
}
public Set<EnumWrappers.PlayerInfoAction> getActions() {
return handle.getPlayerInfoActions().read(0);
}
public void setActions(Set<EnumWrappers.PlayerInfoAction> value) {
handle.getPlayerInfoActions().write(0, value);
}
public List<PlayerInfoData> getData() {
return handle.getPlayerInfoDataLists().read(0);
}
public void setData(List<PlayerInfoData> value) {
//handle.getSets(PlayerInfoData.getConverter()).write(0, value);
handle.getPlayerInfoDataLists().write(1, value);
}
}

View file

@ -0,0 +1,35 @@
package net.artelnatif.nicko.wrapper;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.PacketContainer;
import java.util.List;
import java.util.UUID;
/**
* Up-to-date version of the Wrapper class
* for the PlayerServerPlayerInfoRemove.
*
* @author ineanto, based on work from dmulloy2 and Kristian S. Strangeland
*/
public class WrapperPlayerServerPlayerInfoRemove extends AbstractPacket {
public static final PacketType TYPE = PacketType.Play.Server.PLAYER_INFO_REMOVE;
public WrapperPlayerServerPlayerInfoRemove() {
super(new PacketContainer(TYPE), TYPE);
handle.getModifier().writeDefaults();
}
public WrapperPlayerServerPlayerInfoRemove(PacketContainer packet) {
super(packet, TYPE);
}
public List<UUID> getUUIDs() {
return handle.getUUIDLists().read(0);
}
public void setUUIDs(List<UUID> value) {
handle.getUUIDLists().write(0, value);
}
}

View file

@ -4,6 +4,8 @@ version: 1.0-SNAPSHOT
author: Ineanto author: Ineanto
api-version: 1.13 api-version: 1.13
softdepend: [ PlaceholderAPI ] softdepend: [ PlaceholderAPI ]
depend:
- ProtocolLib
load: POSTWORLD load: POSTWORLD
commands: commands:
nicko: nicko: