feat: internal packet sender is now functional

This commit is contained in:
ineanto 2024-11-14 20:11:13 +01:00
parent 9b64ec18ba
commit 3440f1fad1
Signed by: ineanto
GPG key ID: E511F9CAA2F9CE84
4 changed files with 55 additions and 19 deletions

View file

@ -66,7 +66,7 @@ public class Nicko extends JavaPlugin {
if (!MinecraftVersion.TRAILS_AND_TAILS.atOrAbove()) {
getLogger().severe("This version (" + MinecraftVersion.getCurrentVersion().getVersion() + ") is not supported by Nicko!");
getLogger().severe("As of version 1.0.7, Nicko only supports the latest two majors Minecraft versions. (Currently 1.20.X-1.21.X)");
getLogger().severe("As of version 1.2.0, Nicko only supports the latest Minecraft versions. (Currently 1.21.3)");
dataStore.getStorage().setError(true);
Bukkit.getPluginManager().disablePlugin(this);
}

View file

@ -12,13 +12,11 @@ import xyz.xenondevs.invui.item.builder.AbstractItemBuilder;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.*;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PlayerLanguage {
private final MessageFormat formatter = new MessageFormat("");
private final Logger logger = Logger.getLogger("I18N");
private final Nicko instance = Nicko.getInstance();
private final Pattern replacementPattern = Pattern.compile("(?ms)\\{\\d+}");
private final YamlConfig yamlConfig;

View file

@ -4,18 +4,19 @@ import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import com.mojang.authlib.properties.PropertyMap;
import it.unimi.dsi.fastutil.ints.IntList;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.contents.PlainTextContents;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket;
import net.minecraft.network.protocol.game.ClientboundRespawnPacket;
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket;
import net.minecraft.network.protocol.game.*;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.phys.Vec3;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.entity.Player;
import xyz.ineanto.nicko.Nicko;
import xyz.ineanto.nicko.appearance.ActionResult;
@ -25,8 +26,10 @@ import xyz.ineanto.nicko.mojang.MojangSkin;
import xyz.ineanto.nicko.profile.NickoProfile;
import java.io.IOException;
import java.util.EnumSet;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.concurrent.ExecutionException;
/**
@ -47,10 +50,20 @@ public class InternalPacketSender implements PacketSender {
public void sendEntityRespawn() {
if (!profile.hasData()) return;
final Entity entityPlayer = (Entity) player;
final ClientboundRemoveEntitiesPacket destroy = new ClientboundRemoveEntitiesPacket(IntList.of(player.getEntityId()));
final ClientboundAddEntityPacket add = new ClientboundAddEntityPacket(entityPlayer, 0, entityPlayer.getOnPos());
final ClientboundAddEntityPacket add = new ClientboundAddEntityPacket(
new Random().nextInt(9999),
player.getUniqueId(),
player.getX(),
player.getY(),
player.getZ(),
player.getPitch(),
player.getYaw(),
EntityType.PLAYER,
0,
Vec3.ZERO,
player.getBodyYaw()
);
Bukkit.getOnlinePlayers().stream().filter(receiver -> receiver.getUniqueId() != player.getUniqueId()).forEach(receiver -> {
sendPacket(destroy, player);
@ -60,7 +73,7 @@ public class InternalPacketSender implements PacketSender {
@Override
public ActionResult sendGameProfileUpdate(String name, boolean skinChange, boolean reset) {
final GameProfile gameProfile = ((ServerPlayer) player).gameProfile;
final GameProfile gameProfile = ((CraftPlayer) player).getProfile();
// TODO (Ineanto, 31/10/2024): Could this be refactored to get rid of the boolean?
if (skinChange) {
@ -75,6 +88,7 @@ public class InternalPacketSender implements PacketSender {
final PropertyMap properties = gameProfile.getProperties();
properties.get("textures").clear();
properties.put("textures", new Property("textures", skinResult.value(), skinResult.signature()));
((CraftPlayer) player).getHandle().gameProfile = gameProfile;
} else {
return ActionResult.error(LanguageKey.Error.MOJANG_SKIN);
}
@ -107,19 +121,46 @@ public class InternalPacketSender implements PacketSender {
@Override
public void sendPlayerRespawn() {
final ServerPlayer serverPlayer = (ServerPlayer) player;
final ServerLevel world = (ServerLevel) player.getWorld();
final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
final ServerLevel level = serverPlayer.serverLevel();
final ClientboundRespawnPacket respawn = new ClientboundRespawnPacket(serverPlayer.createCommonSpawnInfo(world), (byte) 0x03);
final ClientboundRespawnPacket respawn = new ClientboundRespawnPacket(serverPlayer.createCommonSpawnInfo(level), (byte) 0x03);
sendPacket(respawn, player);
}
@Override
public void sendTabListUpdate(String displayName) {
final ServerPlayer serverPlayer = (((CraftPlayer) player)).getHandle();
final EnumSet<ClientboundPlayerInfoUpdatePacket.Action> actions = EnumSet.of(
ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER,
ClientboundPlayerInfoUpdatePacket.Action.INITIALIZE_CHAT,
ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED,
ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME,
ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE,
ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LATENCY);
final List<ClientboundPlayerInfoUpdatePacket.Entry> entries = List.of(new ClientboundPlayerInfoUpdatePacket.Entry(
player.getUniqueId(),
serverPlayer.gameProfile,
true,
player.getPing(),
serverPlayer.gameMode.getGameModeForPlayer(),
MutableComponent.create(new PlainTextContents.LiteralContents(displayName)),
1,
null
));
final ClientboundPlayerInfoUpdatePacket update = new ClientboundPlayerInfoUpdatePacket(actions, entries);
final ClientboundPlayerInfoRemovePacket remove = new ClientboundPlayerInfoRemovePacket(List.of(player.getUniqueId()));
Bukkit.getOnlinePlayers().forEach(onlinePlayer -> {
sendPacket(remove, onlinePlayer);
sendPacket(update, onlinePlayer);
});
}
private void sendPacket(Packet<?> packet, Player player) {
((ServerPlayer) player).connection.send(packet);
(((CraftPlayer) player).getHandle()).connection.send(packet);
}
}

View file

@ -4,7 +4,6 @@ import org.bukkit.entity.Player;
import xyz.ineanto.nicko.Nicko;
import xyz.ineanto.nicko.language.Language;
import xyz.ineanto.nicko.storage.PlayerDataStore;
import xyz.ineanto.nicko.storage.name.PlayerNameStore;
import java.util.Optional;
import java.util.UUID;
@ -15,8 +14,6 @@ public class NickoProfile implements Cloneable {
private static final Nicko instance = Nicko.getInstance();
private static final PlayerDataStore dataStore = instance.getDataStore();
private final PlayerNameStore nameStore = instance.getNameStore();
private String name;
private String skin;
private Language language;