feat: protocollib, java 8
This commit is contained in:
parent
fd732fc886
commit
7f3ecddc51
16 changed files with 387 additions and 79 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -46,5 +46,4 @@ v1_19_R1/target
|
||||||
target
|
target
|
||||||
|
|
||||||
# Maven Dependency Reduced Pom
|
# Maven Dependency Reduced Pom
|
||||||
dist/dependency-reduced-pom.xml
|
dependency-reduced-pom.xml
|
||||||
core/dependency-reduced-pom.xml
|
|
|
@ -87,13 +87,17 @@
|
||||||
<id>placeholderapi</id>
|
<id>placeholderapi</id>
|
||||||
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
|
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
|
||||||
</repository>
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>dmulloy2-repo</id>
|
||||||
|
<url>https://repo.dmulloy2.net/repository/public/</url>
|
||||||
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.retrooper.packetevents</groupId>
|
<groupId>com.comphenix.protocol</groupId>
|
||||||
<artifactId>spigot</artifactId>
|
<artifactId>ProtocolLib</artifactId>
|
||||||
<version>2.0.0-SNAPSHOT</version>
|
<version>5.0.0-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>me.clip</groupId>
|
<groupId>me.clip</groupId>
|
||||||
|
@ -157,8 +161,8 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.target>17</maven.compiler.target>
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
<maven.compiler.source>17</maven.compiler.source>
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
</properties>
|
</properties>
|
||||||
</project>
|
</project>
|
||||||
|
|
20
pom.xml
20
pom.xml
|
@ -10,8 +10,8 @@
|
||||||
<name>Nicko</name>
|
<name>Nicko</name>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>17</maven.compiler.source>
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
<maven.compiler.target>17</maven.compiler.target>
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
@ -32,15 +32,19 @@
|
||||||
<id>placeholderapi</id>
|
<id>placeholderapi</id>
|
||||||
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
|
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
|
||||||
</repository>
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>dmulloy2-repo</id>
|
||||||
|
<url>https://repo.dmulloy2.net/repository/public/</url>
|
||||||
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.retrooper.packetevents</groupId>
|
<groupId>com.comphenix.protocol</groupId>
|
||||||
<artifactId>spigot</artifactId>
|
<artifactId>ProtocolLib</artifactId>
|
||||||
<version>2.0.0-SNAPSHOT</version>
|
<version>5.0.0-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
</dependency>
|
||||||
</dependency>
|
<!-- And so on -->
|
||||||
<!-- PlaceHolder API -->
|
<!-- PlaceHolder API -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>me.clip</groupId>
|
<groupId>me.clip</groupId>
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package net.artelnatif.nicko;
|
package net.artelnatif.nicko;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.ProtocolLibrary;
|
||||||
|
import com.comphenix.protocol.ProtocolManager;
|
||||||
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;
|
||||||
|
@ -37,6 +39,7 @@ public class NickoBukkit extends JavaPlugin {
|
||||||
private Configuration configuration;
|
private Configuration configuration;
|
||||||
private LocaleFileManager localeFileManager;
|
private LocaleFileManager localeFileManager;
|
||||||
private PlayerNameStore nameStore;
|
private PlayerNameStore nameStore;
|
||||||
|
private ProtocolManager protocolManager;
|
||||||
|
|
||||||
public NickoBukkit() { this.unitTesting = false; }
|
public NickoBukkit() { this.unitTesting = false; }
|
||||||
|
|
||||||
|
@ -76,6 +79,7 @@ public class NickoBukkit extends JavaPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!unitTesting) {
|
if (!unitTesting) {
|
||||||
|
protocolManager = ProtocolLibrary.getProtocolManager();
|
||||||
localeFileManager = new LocaleFileManager();
|
localeFileManager = new LocaleFileManager();
|
||||||
if (configuration.isCustomLocale()) {
|
if (configuration.isCustomLocale()) {
|
||||||
if (localeFileManager.dumpFromLocale(Locale.ENGLISH)) {
|
if (localeFileManager.dumpFromLocale(Locale.ENGLISH)) {
|
||||||
|
@ -150,4 +154,6 @@ public class NickoBukkit extends JavaPlugin {
|
||||||
public LocaleFileManager getLocaleFileManager() {
|
public LocaleFileManager getLocaleFileManager() {
|
||||||
return localeFileManager;
|
return localeFileManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ProtocolManager getProtocolManager() { return protocolManager; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package net.artelnatif.nicko.anvil;
|
package net.artelnatif.nicko.anvil;
|
||||||
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
import net.artelnatif.nicko.NickoBukkit;
|
||||||
import net.artelnatif.nicko.appearance.AppearanceManager;
|
import net.artelnatif.nicko.disguise.AppearanceManager;
|
||||||
import net.artelnatif.nicko.disguise.ActionResult;
|
import net.artelnatif.nicko.disguise.ActionResult;
|
||||||
import net.artelnatif.nicko.i18n.I18N;
|
import net.artelnatif.nicko.i18n.I18N;
|
||||||
import net.artelnatif.nicko.i18n.I18NDict;
|
import net.artelnatif.nicko.i18n.I18NDict;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package net.artelnatif.nicko.command.sub;
|
package net.artelnatif.nicko.command.sub;
|
||||||
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
import net.artelnatif.nicko.NickoBukkit;
|
||||||
import net.artelnatif.nicko.appearance.AppearanceManager;
|
import net.artelnatif.nicko.disguise.AppearanceManager;
|
||||||
import net.artelnatif.nicko.i18n.I18N;
|
import net.artelnatif.nicko.i18n.I18N;
|
||||||
import net.artelnatif.nicko.i18n.I18NDict;
|
import net.artelnatif.nicko.i18n.I18NDict;
|
||||||
import net.artelnatif.nicko.mojang.MojangUtils;
|
import net.artelnatif.nicko.mojang.MojangUtils;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package net.artelnatif.nicko.command.sub;
|
package net.artelnatif.nicko.command.sub;
|
||||||
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
import net.artelnatif.nicko.NickoBukkit;
|
||||||
import net.artelnatif.nicko.appearance.AppearanceManager;
|
import net.artelnatif.nicko.disguise.AppearanceManager;
|
||||||
import net.artelnatif.nicko.mojang.MojangUtils;
|
import net.artelnatif.nicko.mojang.MojangUtils;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
|
|
|
@ -1,29 +1,20 @@
|
||||||
package net.artelnatif.nicko.appearance;
|
package net.artelnatif.nicko.disguise;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.PacketEvents;
|
import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
||||||
import com.github.retrooper.packetevents.protocol.player.TextureProperty;
|
import com.comphenix.protocol.wrappers.WrappedSignedProperty;
|
||||||
import com.github.retrooper.packetevents.protocol.player.UserProfile;
|
|
||||||
import com.github.retrooper.packetevents.protocol.world.Difficulty;
|
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoRemove;
|
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoUpdate;
|
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerRespawn;
|
|
||||||
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
import net.artelnatif.nicko.NickoBukkit;
|
||||||
import net.artelnatif.nicko.disguise.ActionResult;
|
|
||||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
|
||||||
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.kyori.adventure.text.Component;
|
|
||||||
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.EnumSet;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
|
||||||
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;
|
||||||
|
@ -105,16 +96,17 @@ 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");
|
Bukkit.broadcastMessage("Building UserProfile");
|
||||||
final UserProfile userProfile = new UserProfile(player.getUniqueId(), displayName);
|
final WrappedGameProfile gameProfile = new WrappedGameProfile(player.getUniqueId(), displayName);
|
||||||
|
|
||||||
final ActionResult<Void> result = updateGameProfileSkin(userProfile, skinChange);
|
final ActionResult<Void> result = updateGameProfileSkin(gameProfile, skinChange);
|
||||||
if (!result.isError()) {
|
if (!result.isError()) {
|
||||||
updateTabList(userProfile, displayName);
|
updateTabList(gameProfile, displayName);
|
||||||
|
respawnPlayer();
|
||||||
}
|
}
|
||||||
return new ActionResult<>();
|
return new ActionResult<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ActionResult<Void> updateGameProfileSkin(UserProfile userProfile, boolean skinChange) {
|
private ActionResult<Void> updateGameProfileSkin(WrappedGameProfile gameProfile, boolean skinChange) {
|
||||||
final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName());
|
final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName());
|
||||||
|
|
||||||
if (skinChange || changeOnlyName) {
|
if (skinChange || changeOnlyName) {
|
||||||
|
@ -126,14 +118,12 @@ 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 List<TextureProperty> properties = userProfile.getTextureProperties();
|
final Collection<WrappedSignedProperty> properties = gameProfile.getProperties().values();
|
||||||
properties.clear();
|
properties.clear();
|
||||||
properties.add(new TextureProperty("textures", skinResult.getValue(), skinResult.getSignature()));
|
properties.add(new WrappedSignedProperty("textures", skinResult.getValue(), skinResult.getSignature()));
|
||||||
Bukkit.broadcastMessage("Modified properties");
|
Bukkit.broadcastMessage("Modified properties");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Bukkit.broadcastMessage("Respawning player");
|
|
||||||
respawnPlayer();
|
|
||||||
return new ActionResult<>();
|
return new ActionResult<>();
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
return new ActionResult<>(I18NDict.Error.SKIN_FAIL_CACHE);
|
return new ActionResult<>(I18NDict.Error.SKIN_FAIL_CACHE);
|
||||||
|
@ -145,43 +135,16 @@ public class AppearanceManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void respawnPlayer() {
|
private void respawnPlayer() {
|
||||||
|
Bukkit.broadcastMessage("Respawning player");
|
||||||
final World world = player.getWorld();
|
final World world = player.getWorld();
|
||||||
final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn(
|
// TODO (Ineanto, 4/23/23): Respawn Packet
|
||||||
SpigotConversionUtil.fromBukkitWorld(world),
|
player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN);
|
||||||
world.getName(),
|
|
||||||
Difficulty.getById(world.getDifficulty().ordinal()),
|
|
||||||
world.getSeed(),
|
|
||||||
SpigotConversionUtil.fromBukkitGameMode(player.getGameMode()),
|
|
||||||
null,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
null,
|
|
||||||
null
|
|
||||||
);
|
|
||||||
PacketEvents.getAPI().getPlayerManager().sendPacket(player, respawn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateTabList(UserProfile userProfile, String displayName) {
|
private void updateTabList(WrappedGameProfile gameProfile, String displayName) {
|
||||||
final WrapperPlayServerPlayerInfoUpdate infoAdd = new WrapperPlayServerPlayerInfoUpdate(EnumSet.of(
|
// TODO (Ineanto, 4/23/23): Update player info packet
|
||||||
WrapperPlayServerPlayerInfoUpdate.Action.ADD_PLAYER,
|
// TODO (Ineanto, 4/23/23): Remove player info packet
|
||||||
WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_GAME_MODE,
|
|
||||||
WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_DISPLAY_NAME,
|
|
||||||
WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_LISTED,
|
|
||||||
WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_LATENCY
|
|
||||||
), new WrapperPlayServerPlayerInfoUpdate.PlayerInfo(
|
|
||||||
userProfile,
|
|
||||||
true,
|
|
||||||
0,
|
|
||||||
SpigotConversionUtil.fromBukkitGameMode(player.getGameMode()),
|
|
||||||
Component.text(displayName),
|
|
||||||
null
|
|
||||||
));
|
|
||||||
|
|
||||||
final WrapperPlayServerPlayerInfoRemove infoRemove = new WrapperPlayServerPlayerInfoRemove(player.getUniqueId());
|
|
||||||
Bukkit.broadcastMessage("Updating tablist");
|
Bukkit.broadcastMessage("Updating tablist");
|
||||||
PacketEvents.getAPI().getPlayerManager().sendPacket(player, infoRemove);
|
// TODO (Ineanto, 4/23/23): Send packets
|
||||||
PacketEvents.getAPI().getPlayerManager().sendPacket(player, infoAdd);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package net.artelnatif.nicko.event;
|
package net.artelnatif.nicko.event;
|
||||||
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
import net.artelnatif.nicko.NickoBukkit;
|
||||||
import net.artelnatif.nicko.appearance.AppearanceManager;
|
import net.artelnatif.nicko.disguise.AppearanceManager;
|
||||||
import net.artelnatif.nicko.disguise.ActionResult;
|
import net.artelnatif.nicko.disguise.ActionResult;
|
||||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
import net.artelnatif.nicko.disguise.NickoProfile;
|
||||||
import net.artelnatif.nicko.i18n.I18N;
|
import net.artelnatif.nicko.i18n.I18N;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package net.artelnatif.nicko.gui.items.main;
|
package net.artelnatif.nicko.gui.items.main;
|
||||||
|
|
||||||
import net.artelnatif.nicko.appearance.AppearanceManager;
|
import net.artelnatif.nicko.disguise.AppearanceManager;
|
||||||
import net.artelnatif.nicko.i18n.I18N;
|
import net.artelnatif.nicko.i18n.I18N;
|
||||||
import net.artelnatif.nicko.i18n.I18NDict;
|
import net.artelnatif.nicko.i18n.I18NDict;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
|
|
@ -25,7 +25,7 @@ public class MojangAPI {
|
||||||
|
|
||||||
private final Logger logger = Logger.getLogger("MojangAPI");
|
private final Logger logger = Logger.getLogger("MojangAPI");
|
||||||
|
|
||||||
private final CacheLoader<String, Optional<MojangSkin>> loader = new CacheLoader<>() {
|
private final CacheLoader<String, Optional<MojangSkin>> loader = new CacheLoader<String, Optional<MojangSkin>>() {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public Optional<MojangSkin> load(@Nonnull String uuid) throws Exception {
|
public Optional<MojangSkin> load(@Nonnull String uuid) throws Exception {
|
||||||
return getSkinFromMojang(uuid);
|
return getSkinFromMojang(uuid);
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
/**
|
||||||
|
* PacketWrapper - ProtocolLib wrappers for Minecraft packets
|
||||||
|
* Copyright (C) dmulloy2 <http://dmulloy2.net>
|
||||||
|
* Copyright (C) Kristian S. Strangeland
|
||||||
|
* <p>
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
* <p>
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
* <p>
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package net.artelnatif.nicko.wrapper;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
public abstract class AbstractPacket {
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
public void receivePacket(Player sender) {
|
||||||
|
try {
|
||||||
|
ProtocolLibrary.getProtocolManager().receiveClientPacket(sender,
|
||||||
|
getHandle());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Cannot receive packet.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package net.artelnatif.nicko.wrapper;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
|
import org.bukkit.World;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1.19.4 compliant version of the WrapperPlayServerRespawn.
|
||||||
|
*
|
||||||
|
* @author ineanto, based on work from dmulloy2 and Kristian S. Strangeland
|
||||||
|
*/
|
||||||
|
public class WrapperPlayServerRespawn extends AbstractPacket {
|
||||||
|
public static final PacketType TYPE = PacketType.Play.Server.RESPAWN;
|
||||||
|
|
||||||
|
public WrapperPlayServerRespawn() {
|
||||||
|
super(new PacketContainer(TYPE), TYPE);
|
||||||
|
handle.getModifier().writeDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<World> getDimension() {
|
||||||
|
return handle.getDimensionTypes().optionRead(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDimension(World value) {
|
||||||
|
handle.getDimensionTypes().write(0, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Long> getSeed() {
|
||||||
|
return handle.getLongs().optionRead(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSeed(long value) {
|
||||||
|
handle.getLongs().write(0, value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,6 @@ author: Ineanto
|
||||||
api-version: 1.13
|
api-version: 1.13
|
||||||
softdepend: [ PlaceholderAPI ]
|
softdepend: [ PlaceholderAPI ]
|
||||||
load: POSTWORLD
|
load: POSTWORLD
|
||||||
depend: [ packetevents ]
|
|
||||||
commands:
|
commands:
|
||||||
nicko:
|
nicko:
|
||||||
description: "Opens Nicko's GUI."
|
description: "Opens Nicko's GUI."
|
||||||
|
|
68
v1_19_R3/pom.xml
Normal file
68
v1_19_R3/pom.xml
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>net.artelnatif</groupId>
|
||||||
|
<artifactId>nicko-parent</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>v1_19_R3</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>net.md-5</groupId>
|
||||||
|
<artifactId>specialsource-maven-plugin</artifactId>
|
||||||
|
<version>1.2.4</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>remap</goal>
|
||||||
|
</goals>
|
||||||
|
<id>remap-obf</id>
|
||||||
|
<configuration>
|
||||||
|
<srgIn>org.spigotmc:minecraft-server:1.19.4-R0.1-SNAPSHOT:txt:maps-mojang</srgIn>
|
||||||
|
<reverse>true</reverse>
|
||||||
|
<remappedDependencies>org.spigotmc:spigot:1.19.4-R0.1-SNAPSHOT:jar:remapped-mojang</remappedDependencies>
|
||||||
|
<remappedArtifactAttached>true</remappedArtifactAttached>
|
||||||
|
<remappedClassifierName>remapped-obf</remappedClassifierName>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>remap</goal>
|
||||||
|
</goals>
|
||||||
|
<id>remap-spigot</id>
|
||||||
|
<configuration>
|
||||||
|
<inputFile>${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar</inputFile>
|
||||||
|
<srgIn>org.spigotmc:minecraft-server:1.19.4-R0.1-SNAPSHOT:csrg:maps-spigot</srgIn>
|
||||||
|
<remappedDependencies>org.spigotmc:spigot:1.19.4-R0.1-SNAPSHOT:jar:remapped-obf</remappedDependencies>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spigotmc</groupId>
|
||||||
|
<artifactId>spigot</artifactId>
|
||||||
|
<version>1.19.4-R0.1-SNAPSHOT</version>
|
||||||
|
<classifier>remapped-mojang</classifier>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.artelnatif</groupId>
|
||||||
|
<artifactId>core</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
140
v1_19_R3/src/main/java/net/artelnatif/nicko/impl/v1_19_R3.java
Normal file
140
v1_19_R3/src/main/java/net/artelnatif/nicko/impl/v1_19_R3.java
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
package net.artelnatif.nicko.impl;
|
||||||
|
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
|
import com.mojang.authlib.properties.Property;
|
||||||
|
import com.mojang.authlib.properties.PropertyMap;
|
||||||
|
import net.artelnatif.nicko.NickoBukkit;
|
||||||
|
import net.artelnatif.nicko.disguise.ActionResult;
|
||||||
|
import net.artelnatif.nicko.disguise.NickoProfile;
|
||||||
|
import net.artelnatif.nicko.mojang.MojangSkin;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.network.chat.RemoteChatSession;
|
||||||
|
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.resources.ResourceKey;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.entity.player.ProfilePublicKey;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class v1_19_R3 implements Internals {
|
||||||
|
final Logger logger = Bukkit.getLogger();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateSelf(Player player) {
|
||||||
|
final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
|
||||||
|
final ServerLevel level = serverPlayer.getLevel();
|
||||||
|
final ResourceKey<Level> levelResourceKey = serverPlayer.getLevel().dimension();
|
||||||
|
final ClientboundRespawnPacket respawn = new ClientboundRespawnPacket(serverPlayer.level.dimensionTypeId(),
|
||||||
|
levelResourceKey, level.getWorld().getSeed(),
|
||||||
|
serverPlayer.gameMode.getGameModeForPlayer(), serverPlayer.gameMode.getPreviousGameModeForPlayer(),
|
||||||
|
level.isDebug(),
|
||||||
|
level.isFlat(),
|
||||||
|
(byte) 0x00,
|
||||||
|
Optional.empty());
|
||||||
|
|
||||||
|
final boolean wasFlying = player.isFlying();
|
||||||
|
serverPlayer.connection.send(respawn);
|
||||||
|
player.setFlying(wasFlying);
|
||||||
|
player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN);
|
||||||
|
player.updateInventory();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateOthers(Player player) {
|
||||||
|
final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
|
||||||
|
|
||||||
|
final ClientboundRemoveEntitiesPacket remove = new ClientboundRemoveEntitiesPacket(serverPlayer.getBukkitEntity().getEntityId());
|
||||||
|
final ClientboundAddEntityPacket add = new ClientboundAddEntityPacket(serverPlayer);
|
||||||
|
|
||||||
|
final SynchedEntityData entityData = serverPlayer.getEntityData();
|
||||||
|
final EntityDataAccessor<Byte> skinPartAccessor = new EntityDataAccessor<>(17, EntityDataSerializers.BYTE);
|
||||||
|
entityData.set(skinPartAccessor, (byte) 0x7f);
|
||||||
|
final ClientboundSetEntityDataPacket entityMetadata = new ClientboundSetEntityDataPacket(serverPlayer.getBukkitEntity().getEntityId(), entityData.getNonDefaultValues());
|
||||||
|
|
||||||
|
Bukkit.getOnlinePlayers().forEach(online -> {
|
||||||
|
final ServerPlayer onlineServerPlayer = ((CraftPlayer) online).getHandle();
|
||||||
|
if (onlineServerPlayer.getBukkitEntity().getUniqueId() != player.getUniqueId()) {
|
||||||
|
onlineServerPlayer.connection.send(remove);
|
||||||
|
onlineServerPlayer.connection.send(add);
|
||||||
|
}
|
||||||
|
onlineServerPlayer.connection.send(entityMetadata);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionResult<Void> updateProfile(Player player, NickoProfile profile, boolean skinChange, boolean reset) {
|
||||||
|
final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName());
|
||||||
|
final String profileName = profile.getName() == null ? player.getName() : profile.getName();
|
||||||
|
|
||||||
|
final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
|
||||||
|
final GameProfile gameProfile = new GameProfile(player.getUniqueId(), profileName);
|
||||||
|
|
||||||
|
if (skinChange || changeOnlyName) {
|
||||||
|
final ActionResult<MojangSkin> skinFetch = fetchSkinTextures(profile, reset);
|
||||||
|
if (!skinFetch.isError()) {
|
||||||
|
final MojangSkin skin = skinFetch.getResult();
|
||||||
|
final PropertyMap properties = gameProfile.getProperties();
|
||||||
|
properties.removeAll("textures");
|
||||||
|
properties.put("textures", new Property("textures", skin.getValue(), skin.getSignature()));
|
||||||
|
updateSelf(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final ClientboundPlayerInfoUpdatePacket init = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(Collections.singletonList(serverPlayer));
|
||||||
|
final ClientboundPlayerInfoRemovePacket remove = new ClientboundPlayerInfoRemovePacket(Collections.singletonList(player.getUniqueId()));
|
||||||
|
|
||||||
|
RemoteChatSession chatSession;
|
||||||
|
if (serverPlayer.getChatSession() == null) {
|
||||||
|
NickoBukkit.getInstance().getLogger().warning("Chat Session of " + serverPlayer.displayName + " is null!");
|
||||||
|
NickoBukkit.getInstance().getLogger().warning("If your server is in offline mode/under BungeeCord you can safely ignore this message.");
|
||||||
|
chatSession = null;
|
||||||
|
} else {
|
||||||
|
final UUID uuid = serverPlayer.getChatSession().sessionId();
|
||||||
|
final ProfilePublicKey ppk = serverPlayer.getChatSession().profilePublicKey();
|
||||||
|
chatSession = new RemoteChatSession(uuid, ppk);
|
||||||
|
}
|
||||||
|
|
||||||
|
spoofPlayerInfoPacket(init, Collections.singletonList(new ClientboundPlayerInfoUpdatePacket.Entry(
|
||||||
|
player.getUniqueId(),
|
||||||
|
gameProfile,
|
||||||
|
true,
|
||||||
|
serverPlayer.latency,
|
||||||
|
serverPlayer.gameMode.getGameModeForPlayer(),
|
||||||
|
Component.literal(profileName),
|
||||||
|
chatSession == null ? null : chatSession.asData()
|
||||||
|
)));
|
||||||
|
|
||||||
|
|
||||||
|
Bukkit.getOnlinePlayers().forEach(online -> {
|
||||||
|
final ServerPlayer onlinePlayer = ((CraftPlayer) online).getHandle();
|
||||||
|
onlinePlayer.connection.send(remove);
|
||||||
|
onlinePlayer.connection.send(init);
|
||||||
|
});
|
||||||
|
// TODO: 3/17/23 Update signature to avoid duplicate for loop
|
||||||
|
updateOthers(player);
|
||||||
|
return new ActionResult<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void spoofPlayerInfoPacket(Object object, Object newValue) {
|
||||||
|
try {
|
||||||
|
final Field field = object.getClass().getDeclaredField("b");
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(object, newValue);
|
||||||
|
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
NickoBukkit.getInstance().getLogger().warning("Unable to spoof packet, that's bad! (" + e.getMessage() + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue