3
0
Mirror von https://github.com/ViaVersion/ViaVersion.git synchronisiert 2024-12-26 00:00:28 +01:00

Merge pull request #7 from MylesIsCool/master

Update from master
Dieser Commit ist enthalten in:
HugoDaBosss 2016-03-04 14:43:10 +01:00
Commit 0dd530a593
15 geänderte Dateien mit 687 neuen und 146 gelöschten Zeilen

Datei anzeigen

@ -1,17 +1,9 @@
# ViaVersion 0.4.6 # ViaVersion 0.4.9
**Allows the connection of 1.8 clients to 1.9** **Allows the connection of 1.9 clients to 1.8**
This plugin modifies netty to allow connection of 1.9 clients to 1.8, This plugin modifies netty to allow connection of 1.9 clients to 1.8,
**Don't use late bind* ###**Don't use late bind*
**As of this point it doesn't have everything, I need to fix:**
Attempt to make boats nicer when they don't work
Remap spawn eggs
If you have a bug with entities, please report the full stack trace
This took hours of work, so if you enjoy this consider looking into contacting me and supporting my projects. This took hours of work, so if you enjoy this consider looking into contacting me and supporting my projects.
@ -24,16 +16,27 @@ Sources:
**MCProtocolLib** (used for chunk reading & some of writing.) **MCProtocolLib** (used for chunk reading & some of writing.)
**OpenNBT** (used for slot rewriting)
Contributors: Contributors:
-------- --------
**Myself** (harhar) **Myself** (harhar)
**Matsv/StamBoom** **Matsv/StamBoom**
**HugoDaBosss** **HugoDaBosss**
**SanderGielisse** **SanderGielisse**
**Paulomart** **Paulomart**
**gigosaurus** **gigosaurus**
**fillefilip8**
**Chat: ** https://gitter.im/MylesIsCool/ViaVersion **Chat: ** https://gitter.im/MylesIsCool/ViaVersion
We use it to collaborate and solve errors, sign in with github. We use it to collaborate and solve errors, sign in with github.

37
pom.xml
Datei anzeigen

@ -1,14 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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"> 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> <modelVersion>4.0.0</modelVersion>
<groupId>us.myles</groupId> <groupId>us.myles</groupId>
<artifactId>ViaVersion</artifactId> <artifactId>ViaVersion</artifactId>
<version>1.0-SNAPSHOT</version> <version>0.4.9</version>
<build> <build>
<finalName>ViaVersion-${version}</finalName>
<plugins> <plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.4</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
@ -18,8 +34,19 @@
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build> </build>
<dependencies> <dependencies>
<dependency>
<groupId>org.spacehq</groupId>
<artifactId>opennbt</artifactId>
<version>1.0</version>
</dependency>
<dependency> <dependency>
<groupId>org.bukkit</groupId> <groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId> <artifactId>bukkit</artifactId>
@ -50,5 +77,9 @@
<id>spigot-repo</id> <id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url> <url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository> </repository>
<repository>
<id>spacehq-repo</id>
<url>https://repo.spacehq.org/content/repositories/releases/</url>
</repository>
</repositories> </repositories>
</project> </project>

Datei anzeigen

@ -12,12 +12,13 @@ import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import us.myles.ViaVersion.api.ViaVersion; import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.api.ViaVersionAPI; import us.myles.ViaVersion.api.ViaVersionAPI;
import us.myles.ViaVersion.commands.ViaVersionCommand;
import us.myles.ViaVersion.handlers.ViaVersionInitializer; import us.myles.ViaVersion.handlers.ViaVersionInitializer;
import us.myles.ViaVersion.util.ReflectionUtil; import us.myles.ViaVersion.util.ReflectionUtil;
import java.lang.reflect.Field;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -33,12 +34,12 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
@Override @Override
public void onEnable() { public void onEnable() {
ViaVersion.setInstance(this); ViaVersion.setInstance(this);
if(System.getProperty("ViaVersion") != null){ if (System.getProperty("ViaVersion") != null) {
getLogger().severe("ViaVersion is already loaded, we don't support reloads. Please reboot if you wish to update."); getLogger().severe("ViaVersion is already loaded, we don't support reloads. Please reboot if you wish to update.");
return; return;
} }
getLogger().info("ViaVersion enabled, injecting. (Allows 1.8 to be accessed via 1.9)"); getLogger().info("ViaVersion " + getDescription().getVersion() + " is now enabled, injecting. (Allows 1.8 to be accessed via 1.9)");
try { try {
injectPacketHandler(); injectPacketHandler();
System.setProperty("ViaVersion", getDescription().getVersion()); System.setProperty("ViaVersion", getDescription().getVersion());
@ -52,24 +53,36 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
setPorted(e.getPlayer().getUniqueId(), false); setPorted(e.getPlayer().getUniqueId(), false);
} }
}, this); }, this);
getCommand("viaversion").setExecutor(new ViaVersionCommand());
} }
public void injectPacketHandler() throws Exception { public void injectPacketHandler() throws Exception {
Class<?> serverClazz = ReflectionUtil.nms("MinecraftServer"); Class<?> serverClazz = ReflectionUtil.nms("MinecraftServer");
Object server = ReflectionUtil.invokeStatic(serverClazz, "getServer"); Object server = ReflectionUtil.invokeStatic(serverClazz, "getServer");
Object connection = serverClazz.getDeclaredMethod("getServerConnection").invoke(server); Object connection = serverClazz.getDeclaredMethod("getServerConnection").invoke(server);
// loop through all fields checking if list
List<ChannelFuture> futures = ReflectionUtil.get(connection, "g", List.class); boolean injected = false;
if (futures.size() == 0) { for (Field field : connection.getClass().getDeclaredFields()) {
throw new Exception("Could not find server to inject (Please ensure late-bind in your spigot.yml is false)"); field.setAccessible(true);
} Object value = field.get(connection);
if (value instanceof List) {
for (ChannelFuture future : futures) { for (Object o : (List) value) {
if (o instanceof ChannelFuture) {
ChannelFuture future = (ChannelFuture) o;
ChannelPipeline pipeline = future.channel().pipeline(); ChannelPipeline pipeline = future.channel().pipeline();
ChannelHandler bootstrapAcceptor = pipeline.first(); ChannelHandler bootstrapAcceptor = pipeline.first();
ChannelInitializer<SocketChannel> oldInit = ReflectionUtil.get(bootstrapAcceptor, "childHandler", ChannelInitializer.class); ChannelInitializer<SocketChannel> oldInit = ReflectionUtil.get(bootstrapAcceptor, "childHandler", ChannelInitializer.class);
ChannelInitializer newInit = new ViaVersionInitializer(oldInit); ChannelInitializer newInit = new ViaVersionInitializer(oldInit);
ReflectionUtil.set(bootstrapAcceptor, "childHandler", newInit); ReflectionUtil.set(bootstrapAcceptor, "childHandler", newInit);
injected = true;
} else {
break; // not the right list.
}
}
}
}
if (!injected) {
throw new Exception("Could not find server to inject (Please ensure late-bind in your spigot.yml is false)");
} }
} }
@ -78,6 +91,11 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
return portedPlayers.contains(player.getUniqueId()); return portedPlayers.contains(player.getUniqueId());
} }
@Override
public String getVersion() {
return getDescription().getVersion();
}
public void setPorted(UUID id, boolean value) { public void setPorted(UUID id, boolean value) {
if (value) { if (value) {
portedPlayers.add(id); portedPlayers.add(id);

Datei anzeigen

@ -3,6 +3,11 @@ package us.myles.ViaVersion.api;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public interface ViaVersionAPI { public interface ViaVersionAPI {
/**
* Is player using 1.9?
* @param player
* @return
*/
boolean isPorted(Player player); boolean isPorted(Player player);
String getVersion();
} }

Datei anzeigen

@ -0,0 +1,48 @@
package us.myles.ViaVersion.commands;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import us.myles.ViaVersion.api.ViaVersion;
import java.util.ArrayList;
import java.util.List;
/**
* Created by fillefilip8 on 2016-03-03.
*/
public class ViaVersionCommand implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (sender.hasPermission("viaversion.admin")) {
if (args.length == 0) {
sender.sendMessage(color("&aViaVersion &c" + ViaVersion.getInstance().getVersion()));
sender.sendMessage(color("&6Commands:"));
sender.sendMessage(color("&2/viaversion list &7- &6Shows lists of all 1.9 clients and 1.8 clients."));
} else if (args.length == 1) {
if (args[0].equalsIgnoreCase("list")) {
List<String> portedPlayers = new ArrayList<String>();
List<String> normalPlayers = new ArrayList<String>();
for (Player p : Bukkit.getOnlinePlayers()) {
if (ViaVersion.getInstance().isPorted(p)) {
portedPlayers.add(p.getName());
} else {
normalPlayers.add(p.getName());
}
}
sender.sendMessage(color("&8[&61.9&8]: &b" + portedPlayers.toString()));
sender.sendMessage(color("&8[&61.8&8]: &b" + normalPlayers.toString()));
}
}
}
return false;
}
public String color(String string){
return string.replace("&", "§");
}
}

Datei anzeigen

@ -31,6 +31,7 @@ public class ViaDecodeHandler extends ByteToMessageDecoder {
ByteBuf newPacket = ctx.alloc().buffer(); ByteBuf newPacket = ctx.alloc().buffer();
try { try {
incomingTransformer.transform(id, bytebuf, newPacket); incomingTransformer.transform(id, bytebuf, newPacket);
bytebuf.readBytes(bytebuf.readableBytes());
bytebuf = newPacket; bytebuf = newPacket;
} catch (CancelException e) { } catch (CancelException e) {
bytebuf.readBytes(bytebuf.readableBytes()); bytebuf.readBytes(bytebuf.readableBytes());
@ -44,13 +45,7 @@ public class ViaDecodeHandler extends ByteToMessageDecoder {
@Override @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
if (!(cause.getCause().getCause() instanceof CancelException)) { if (PacketUtil.containsCause(cause, CancelException.class)) return;
if (!(cause.getCause() instanceof CancelException)) {
if (!(cause instanceof CancelException)) {
super.exceptionCaught(ctx, cause); super.exceptionCaught(ctx, cause);
} }
}
}
}
} }

Datei anzeigen

@ -72,12 +72,7 @@ public class ViaEncodeHandler extends MessageToByteEncoder {
@Override @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
if (!(cause.getCause().getCause() instanceof CancelException)) { if (PacketUtil.containsCause(cause, CancelException.class)) return;
if (!(cause.getCause() instanceof CancelException)) {
if (!(cause instanceof CancelException)) {
super.exceptionCaught(ctx, cause); super.exceptionCaught(ctx, cause);
} }
}
}
}
} }

Datei anzeigen

@ -27,10 +27,10 @@ public enum MetaIndex {
STAND_LL_POS(ArmorStand.class, 15, Type.Rotation, NewType.Vector3F), STAND_LL_POS(ArmorStand.class, 15, Type.Rotation, NewType.Vector3F),
STAND_RL_POS(ArmorStand.class, 16, Type.Rotation, NewType.Vector3F), STAND_RL_POS(ArmorStand.class, 16, Type.Rotation, NewType.Vector3F),
// human, discountined? // human, discountined?
PLAYER_SKIN_FLAGS(HumanEntity.class, 10, Type.Byte, NewType.Discontinued), // unsigned on 1.8 PLAYER_SKIN_FLAGS(HumanEntity.class, 10, Type.Byte, 12, NewType.Byte), // unsigned on 1.8
PLAYER_HUMAN_BYTE(HumanEntity.class, 16, Type.Byte, NewType.Discontinued), // unused on 1.8 PLAYER_HUMAN_BYTE(HumanEntity.class, 16, Type.Byte, NewType.Discontinued), // unused on 1.8
PLAYER_ADDITIONAL_HEARTS(HumanEntity.class, 17, Type.Float, NewType.Discontinued), PLAYER_ADDITIONAL_HEARTS(HumanEntity.class, 17, Type.Float, 10, NewType.Float),
PLAYER_SCORE(HumanEntity.class, 18, Type.Int, NewType.Discontinued), PLAYER_SCORE(HumanEntity.class, 18, Type.Int, 11, NewType.VarInt),
// horse // horse
HORSE_INFO(Horse.class, 16, Type.Int, 12, NewType.Byte), HORSE_INFO(Horse.class, 16, Type.Int, 12, NewType.Byte),
HORSE_TYPE(Horse.class, 19, Type.Byte, 13, NewType.VarInt), HORSE_TYPE(Horse.class, 19, Type.Byte, 13, NewType.VarInt),

Datei anzeigen

@ -11,6 +11,8 @@ import org.bukkit.util.Vector;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion.slot.ItemSlotRewriter;
import us.myles.ViaVersion.slot.ItemSlotRewriter.ItemStack;
import us.myles.ViaVersion.util.PacketUtil; import us.myles.ViaVersion.util.PacketUtil;
public class MetadataRewriter { public class MetadataRewriter {
@ -92,7 +94,9 @@ public class MetadataRewriter {
output.writeBoolean(((Byte) value).byteValue() != 0); output.writeBoolean(((Byte) value).byteValue() != 0);
break; break;
case Slot: case Slot:
PacketUtil.writeItem(value, output); ItemStack item = (ItemStack) value;
ItemSlotRewriter.fixIdsFrom1_8To1_9(item);
ItemSlotRewriter.writeItemStack(item, output);
break; break;
case Position: case Position:
Vector vector = (Vector) value; Vector vector = (Vector) value;
@ -148,8 +152,13 @@ public class MetadataRewriter {
case String: case String:
entries.add(new Entry(index, PacketUtil.readString(buf))); entries.add(new Entry(index, PacketUtil.readString(buf)));
break; break;
case Slot: case Slot: {
entries.add(new Entry(index, PacketUtil.readItem(buf))); try {
entries.add(new Entry(index, ItemSlotRewriter.readItemStack(buf)));
} catch (Exception e) {
e.printStackTrace();
}
}
break; break;
case Position: { case Position: {
int x = buf.readInt(); int x = buf.readInt();

Datei anzeigen

@ -0,0 +1,297 @@
package us.myles.ViaVersion.slot;
import io.netty.buffer.ByteBuf;
import org.bukkit.Material;
import org.spacehq.opennbt.tag.builtin.CompoundTag;
import org.spacehq.opennbt.tag.builtin.StringTag;
import us.myles.ViaVersion.CancelException;
import us.myles.ViaVersion.util.PacketUtil;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class ItemSlotRewriter {
public static void rewrite1_9To1_8(ByteBuf input, ByteBuf output) throws CancelException {
try {
ItemStack item = readItemStack(input);
fixIdsFrom1_9To1_8(item);
writeItemStack(item, output);
} catch (Exception e) {
System.out.println("Error while rewriting an item slot.");
e.printStackTrace();
throw new CancelException();
}
}
public static void rewrite1_8To1_9(ByteBuf input, ByteBuf output) throws CancelException {
try {
ItemStack item = readItemStack(input);
fixIdsFrom1_8To1_9(item);
writeItemStack(item, output);
} catch (Exception e) {
System.out.println("Error while rewriting an item slot.");
e.printStackTrace();
throw new CancelException();
}
}
public static void fixIdsFrom1_9To1_8(ItemStack item) {
if (item != null) {
if (item.id == Material.MONSTER_EGG.getId() && item.data == 0) {
CompoundTag tag = item.tag;
int data = 0;
if (tag != null && tag.get("EntityTag") instanceof CompoundTag) {
CompoundTag entityTag = tag.get("EntityTag");
if (entityTag.get("id") instanceof StringTag) {
StringTag id = entityTag.get("id");
if (ENTTIY_NAME_TO_ID.containsKey(id.getValue()))
data = ENTTIY_NAME_TO_ID.get(id.getValue());
}
}
item.tag = null;
item.data = (short) data;
}
if (item.id == Material.POTION.getId()) {
CompoundTag tag = item.tag;
int data = 0;
if (tag != null && tag.get("Potion") instanceof StringTag) {
StringTag potion = tag.get("Potion");
String potionName = potion.getValue().replace("minecraft:", "");
if (POTION_NAME_TO_ID.containsKey(potionName)) {
data = POTION_NAME_TO_ID.get(potionName);
}
}
item.tag = null;
item.data = (short) data;
}
if (item.id == 438) {
CompoundTag tag = item.tag;
int data = 0;
item.id = (short) Material.POTION.getId();
if (tag != null && tag.get("Potion") instanceof StringTag) {
StringTag potion = tag.get("Potion");
String potionName = potion.getValue().replace("minecraft:", "");
if (POTION_NAME_TO_ID.containsKey(potionName)) {
data = POTION_NAME_TO_ID.get(potionName) + 8192;
}
}
item.tag = null;
item.data = (short) data;
}
}
}
public static void fixIdsFrom1_8To1_9(ItemStack item) {
if (item != null) {
if (item.id == Material.MONSTER_EGG.getId() && item.data != 0) {
CompoundTag tag = item.tag;
if (tag == null) {
tag = new CompoundTag("tag");
}
CompoundTag entityTag = new CompoundTag("EntityTag");
if (ENTTIY_ID_TO_NAME.containsKey(Integer.valueOf(item.data))) {
StringTag id = new StringTag("id", ENTTIY_ID_TO_NAME.get(Integer.valueOf(item.data)));
entityTag.put(id);
tag.put(entityTag);
}
item.tag = tag;
item.data = 0;
}
if (item.id == Material.POTION.getId()) {
CompoundTag tag = item.tag;
if (tag == null) {
tag = new CompoundTag("tag");
}
if(item.data >= 16384){
item.id = 438; // splash id
item.data = (short) (item.data - 8192);
}
if (POTION_ID_TO_NAME.containsKey(Integer.valueOf(item.data))) {
String name = POTION_ID_TO_NAME.get(Integer.valueOf(item.data));
StringTag potion = new StringTag("Potion", "minecraft:" + name);
tag.put(potion);
}
item.tag = tag;
item.data = 0;
}
}
}
public static ItemStack readItemStack(ByteBuf input) throws IOException {
short id = input.readShort();
if (id < 0) {
return null;
} else {
ItemStack item = new ItemStack();
item.id = id;
item.amount = input.readByte();
item.data = input.readShort();
item.tag = PacketUtil.readNBT(input);
return item;
}
}
public static void writeItemStack(ItemStack item, ByteBuf output) throws IOException {
if (item == null) {
output.writeShort(-1);
} else {
output.writeShort(item.id);
output.writeByte(item.amount);
output.writeShort(item.data);
PacketUtil.writeNBT(output, item.tag);
}
}
public static class ItemStack {
public short id;
public byte amount;
public short data;
public CompoundTag tag;
public static ItemStack fromBukkit(org.bukkit.inventory.ItemStack stack) {
ItemStack item = new ItemStack();
item.id = (short) stack.getTypeId();
item.amount = (byte) stack.getAmount();
item.data = stack.getData().getData();
// TODO: nbt
return item;
}
}
private static Map<String, Integer> ENTTIY_NAME_TO_ID = new HashMap<>();
private static Map<Integer, String> ENTTIY_ID_TO_NAME = new HashMap<>();
private static Map<String, Integer> POTION_NAME_TO_ID = new HashMap<>();
private static Map<Integer, String> POTION_ID_TO_NAME = new HashMap<>();
static {
/* Entities */
registerEntity(1, "Item");
registerEntity(2, "XPOrb");
registerEntity(7, "ThrownEgg");
registerEntity(8, "LeashKnot");
registerEntity(9, "Painting");
registerEntity(10, "Arrow");
registerEntity(11, "Snowball");
registerEntity(12, "Fireball");
registerEntity(13, "SmallFireball");
registerEntity(14, "ThrownEnderpearl");
registerEntity(15, "EyeOfEnderSignal");
registerEntity(16, "ThrownPotion");
registerEntity(17, "ThrownExpBottle");
registerEntity(18, "ItemFrame");
registerEntity(19, "WitherSkull");
registerEntity(20, "PrimedTnt");
registerEntity(21, "FallingSand");
registerEntity(22, "FireworksRocketEntity");
registerEntity(30, "ArmorStand");
registerEntity(40, "MinecartCommandBlock");
registerEntity(41, "Boat");
registerEntity(42, "MinecartRideable");
registerEntity(43, "MinecartChest");
registerEntity(44, "MinecartFurnace");
registerEntity(45, "MinecartTNT");
registerEntity(46, "MinecartHopper");
registerEntity(47, "MinecartSpawner");
registerEntity(48, "Mob");
registerEntity(49, "Monster");
registerEntity(50, "Creeper");
registerEntity(51, "Skeleton");
registerEntity(52, "Spider");
registerEntity(53, "Giant");
registerEntity(54, "Zombie");
registerEntity(55, "Slime");
registerEntity(56, "Ghast");
registerEntity(57, "PigZombie");
registerEntity(58, "Enderman");
registerEntity(59, "CaveSpider");
registerEntity(60, "Silverfish");
registerEntity(61, "Blaze");
registerEntity(62, "LavaSlime");
registerEntity(63, "EnderDragon");
registerEntity(64, "WitherBoss");
registerEntity(65, "Bat");
registerEntity(66, "Witch");
registerEntity(67, "Endermite");
registerEntity(68, "Guardian");
registerEntity(90, "Pig");
registerEntity(91, "Sheep");
registerEntity(92, "Cow");
registerEntity(93, "Chicken");
registerEntity(94, "Squid");
registerEntity(95, "Wolf");
registerEntity(96, "MushroomCow");
registerEntity(97, "SnowMan");
registerEntity(98, "Ozelot");
registerEntity(99, "VillagerGolem");
registerEntity(100, "EntityHorse");
registerEntity(101, "Rabbit");
registerEntity(120, "Villager");
registerEntity(200, "EnderCrystal");
/* Potions */
registerPotion(0, "water");
registerPotion(64, "mundane");
registerPotion(32, "thick");
registerPotion(16, "awkward");
registerPotion(8198, "night_vision");
registerPotion(8262, "long_night_vision");
registerPotion(8206, "invisibility");
registerPotion(8270, "long_invisibility");
registerPotion(8203, "leaping");
registerPotion(8267, "long_leaping");
registerPotion(8235, "strong_leaping");
registerPotion(8195, "fire_resistance");
registerPotion(8259, "long_fire_resistance");
registerPotion(8194, "swiftness");
registerPotion(8258, "long_swiftness");
registerPotion(8226, "strong_swiftness");
registerPotion(8202, "slowness");
registerPotion(8266, "long_slowness");
registerPotion(8205, "water_breathing");
registerPotion(8269, "long_water_breathing");
registerPotion(8197, "healing");
registerPotion(8229, "strong_healing");
registerPotion(8204, "harming");
registerPotion(8236, "strong_harming");
registerPotion(8196, "poison");
registerPotion(8260, "long_poison");
registerPotion(8228, "strong_poison");
registerPotion(8193, "regeneration");
registerPotion(8257, "long_regeneration");
registerPotion(8225, "strong_regeneration");
registerPotion(8201, "strength");
registerPotion(8265, "long_strength");
registerPotion(8233, "strong_strength");
registerPotion(8200, "weakness");
registerPotion(8264, "long_weakness");
}
private static void registerEntity(Integer id, String name) {
ENTTIY_ID_TO_NAME.put(id, name);
ENTTIY_NAME_TO_ID.put(name, id);
}
private static void registerPotion(Integer id, String name) {
POTION_ID_TO_NAME.put(id, name);
POTION_NAME_TO_ID.put(name, id);
}
}

Datei anzeigen

@ -1,17 +1,26 @@
package us.myles.ViaVersion.transformers; package us.myles.ViaVersion.transformers;
import com.avaje.ebeaninternal.server.cluster.Packet;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.spacehq.opennbt.tag.builtin.ListTag;
import org.spacehq.opennbt.tag.builtin.StringTag;
import org.spacehq.opennbt.tag.builtin.Tag;
import us.myles.ViaVersion.CancelException; import us.myles.ViaVersion.CancelException;
import us.myles.ViaVersion.ConnectionInfo; import us.myles.ViaVersion.ConnectionInfo;
import us.myles.ViaVersion.ViaVersionPlugin; import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.slot.ItemSlotRewriter;
import us.myles.ViaVersion.packets.PacketType; import us.myles.ViaVersion.packets.PacketType;
import us.myles.ViaVersion.packets.State; import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.util.PacketUtil; import us.myles.ViaVersion.util.PacketUtil;
import us.myles.ViaVersion.util.ReflectionUtil; import us.myles.ViaVersion.util.ReflectionUtil;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.nio.charset.Charset;
public class IncomingTransformer { public class IncomingTransformer {
private final ConnectionInfo info; private final ConnectionInfo info;
@ -82,7 +91,7 @@ public class IncomingTransformer {
return; return;
} }
if (packet == PacketType.PLAY_PLAYER_DIGGING) { if (packet == PacketType.PLAY_PLAYER_DIGGING) {
byte status = input.readByte(); int status = input.readByte() & 0xFF; // unsign
if (status == 6) { // item swap if (status == 6) { // item swap
throw new CancelException(); throw new CancelException();
} }
@ -102,7 +111,9 @@ public class IncomingTransformer {
if (slot == 45 && windowID == 0) { if (slot == 45 && windowID == 0) {
try { try {
Class<?> setSlot = ReflectionUtil.nms("PacketPlayOutSetSlot"); Class<?> setSlot = ReflectionUtil.nms("PacketPlayOutSetSlot");
Object setSlotPacket = setSlot.getConstructors()[1].newInstance(windowID, slot, null); Constructor setSlotConstruct = setSlot.getDeclaredConstructor(int.class, int.class, ReflectionUtil.nms("ItemStack"));
// properly construct
Object setSlotPacket = setSlotConstruct.newInstance(windowID, slot, null);
info.getChannel().pipeline().writeAndFlush(setSlotPacket); // slot is empty info.getChannel().pipeline().writeAndFlush(setSlotPacket); // slot is empty
slot = -999; // we're evil, they'll throw item on the ground slot = -999; // we're evil, they'll throw item on the ground
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
@ -113,6 +124,8 @@ public class IncomingTransformer {
e.printStackTrace(); e.printStackTrace();
} catch (InvocationTargetException e) { } catch (InvocationTargetException e) {
e.printStackTrace(); e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} }
} }
@ -121,7 +134,7 @@ public class IncomingTransformer {
output.writeByte(button); output.writeByte(button);
output.writeShort(action); output.writeShort(action);
output.writeByte(mode); output.writeByte(mode);
output.writeBytes(input); ItemSlotRewriter.rewrite1_9To1_8(input, output);
return; return;
} }
if (packet == PacketType.PLAY_CLIENT_SETTINGS) { if (packet == PacketType.PLAY_CLIENT_SETTINGS) {
@ -166,6 +179,26 @@ public class IncomingTransformer {
} }
return; return;
} }
if(packet == PacketType.PLAY_PLUGIN_MESSAGE_REQUEST) {
String name = PacketUtil.readString(input);
PacketUtil.writeString(name, output);
byte[] b = new byte[input.readableBytes()];
input.readBytes(b);
// patch books
if(name.equals("MC|BSign")){
ByteBuf in = Unpooled.wrappedBuffer(b);
try {
ItemSlotRewriter.ItemStack stack = ItemSlotRewriter.readItemStack(in);
stack.id = (short) Material.WRITTEN_BOOK.getId();
// write
ItemSlotRewriter.writeItemStack(stack, output);
} catch (IOException e) {
e.printStackTrace();
}
return;
}
output.writeBytes(b);
}
if (packet == PacketType.PLAY_PLAYER_BLOCK_PLACEMENT) { if (packet == PacketType.PLAY_PLAYER_BLOCK_PLACEMENT) {
Long position = input.readLong(); Long position = input.readLong();
output.writeLong(position); output.writeLong(position);
@ -174,22 +207,14 @@ public class IncomingTransformer {
int hand = PacketUtil.readVarInt(input); int hand = PacketUtil.readVarInt(input);
ItemStack inHand = ViaVersionPlugin.getHandItem(info); ItemStack inHand = ViaVersionPlugin.getHandItem(info);
Object item = null;
try { try {
Method m = ReflectionUtil.obc("inventory.CraftItemStack").getDeclaredMethod("asNMSCopy", ItemStack.class); ItemSlotRewriter.ItemStack item = ItemSlotRewriter.ItemStack.fromBukkit(inHand);
item = m.invoke(null, inHand); ItemSlotRewriter.fixIdsFrom1_9To1_8(item);
} catch (NoSuchMethodException e) { ItemSlotRewriter.writeItemStack(item, output);
e.printStackTrace(); } catch (Exception e) {
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace(); e.printStackTrace();
} }
PacketUtil.writeItem(item, output);
short curX = input.readUnsignedByte(); short curX = input.readUnsignedByte();
output.writeByte(curX); output.writeByte(curX);
short curY = input.readUnsignedByte(); short curY = input.readUnsignedByte();
@ -206,26 +231,25 @@ public class IncomingTransformer {
output.writeByte(255); output.writeByte(255);
// write item in hand // write item in hand
ItemStack inHand = ViaVersionPlugin.getHandItem(info); ItemStack inHand = ViaVersionPlugin.getHandItem(info);
Object item = null;
try { try {
Method m = ReflectionUtil.obc("inventory.CraftItemStack").getDeclaredMethod("asNMSCopy", ItemStack.class); ItemSlotRewriter.ItemStack item = ItemSlotRewriter.ItemStack.fromBukkit(inHand);
item = m.invoke(null, inHand); ItemSlotRewriter.fixIdsFrom1_9To1_8(item);
} catch (NoSuchMethodException e) { ItemSlotRewriter.writeItemStack(item, output);
e.printStackTrace(); } catch (Exception e) {
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace(); e.printStackTrace();
} }
PacketUtil.writeItem(item, output);
output.writeByte(-1); output.writeByte(-1);
output.writeByte(-1); output.writeByte(-1);
output.writeByte(-1); output.writeByte(-1);
return; return;
} }
if (packet == PacketType.PLAY_CREATIVE_INVENTORY_ACTION) {
short slot = input.readShort();
output.writeShort(slot);
ItemSlotRewriter.rewrite1_9To1_8(input, output);
}
output.writeBytes(input); output.writeBytes(input);
} }
} }

Datei anzeigen

@ -1,15 +1,17 @@
package us.myles.ViaVersion.transformers; package us.myles.ViaVersion.transformers;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.bukkit.Material;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.spacehq.mc.protocol.data.game.chunk.Column; import org.spacehq.mc.protocol.data.game.chunk.Column;
import org.spacehq.mc.protocol.util.NetUtil; import org.spacehq.mc.protocol.util.NetUtil;
import org.spacehq.opennbt.tag.builtin.ListTag;
import org.spacehq.opennbt.tag.builtin.StringTag;
import org.spacehq.opennbt.tag.builtin.Tag;
import us.myles.ViaVersion.CancelException; import us.myles.ViaVersion.CancelException;
import us.myles.ViaVersion.ConnectionInfo; import us.myles.ViaVersion.ConnectionInfo;
import us.myles.ViaVersion.ViaVersionPlugin; import us.myles.ViaVersion.ViaVersionPlugin;
@ -17,6 +19,7 @@ import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.metadata.MetadataRewriter; import us.myles.ViaVersion.metadata.MetadataRewriter;
import us.myles.ViaVersion.packets.PacketType; import us.myles.ViaVersion.packets.PacketType;
import us.myles.ViaVersion.packets.State; import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.slot.ItemSlotRewriter;
import us.myles.ViaVersion.sounds.SoundEffect; import us.myles.ViaVersion.sounds.SoundEffect;
import us.myles.ViaVersion.util.EntityUtil; import us.myles.ViaVersion.util.EntityUtil;
import us.myles.ViaVersion.util.PacketUtil; import us.myles.ViaVersion.util.PacketUtil;
@ -28,7 +31,6 @@ import java.util.*;
import static us.myles.ViaVersion.util.PacketUtil.*; import static us.myles.ViaVersion.util.PacketUtil.*;
public class OutgoingTransformer { public class OutgoingTransformer {
private static Gson gson = new Gson();
private final ConnectionInfo info; private final ConnectionInfo info;
private final ViaVersionPlugin plugin = (ViaVersionPlugin) ViaVersion.getInstance(); private final ViaVersionPlugin plugin = (ViaVersionPlugin) ViaVersion.getInstance();
private boolean cancel = false; private boolean cancel = false;
@ -50,7 +52,7 @@ public class OutgoingTransformer {
if (packet == null) { if (packet == null) {
throw new RuntimeException("Outgoing Packet not found? " + packetID + " State: " + info.getState() + " Version: " + info.getProtocol()); throw new RuntimeException("Outgoing Packet not found? " + packetID + " State: " + info.getState() + " Version: " + info.getProtocol());
} }
// if (packet != PacketType.PLAY_CHUNK_DATA && packet != PacketType.PLAY_KEEP_ALIVE && packet != PacketType.PLAY_TIME_UPDATE && (!packet.name().toLowerCase().contains("move") && !packet.name().contains("look"))) // if (packet != PacketType.PLAY_CHUNK_DATA && packet != PacketType.PLAY_KEEP_ALIVE && packet != PacketType.PLAY_TIME_UPDATE && (!packet.name().toLowerCase().contains("move") && !packet.name().toLowerCase().contains("look")))
// System.out.println("Packet Type: " + packet + " Original ID: " + packetID + " State:" + info.getState()); // System.out.println("Packet Type: " + packet + " Original ID: " + packetID + " State:" + info.getState());
if (packet.getPacketID() != -1) { if (packet.getPacketID() != -1) {
packetID = packet.getNewPacketID(); packetID = packet.getNewPacketID();
@ -60,14 +62,13 @@ public class OutgoingTransformer {
PacketUtil.writeVarInt(packetID, output); PacketUtil.writeVarInt(packetID, output);
if (packet == PacketType.PLAY_NAMED_SOUND_EFFECT) { if (packet == PacketType.PLAY_NAMED_SOUND_EFFECT) {
String name = PacketUtil.readString(input); String name = PacketUtil.readString(input);
SoundEffect effect = SoundEffect.getByName(name); SoundEffect effect = SoundEffect.getByName(name);
int catid = 0; int catid = 0;
String newname = name; String newname = name;
if (effect != null) { if (effect != null) {
if(effect.isBreakPlaceSound()) { if (effect.isBreakPlaceSound()) {
input.readBytes(input.readableBytes()); throw new CancelException();
output.clear();
return;
} }
catid = effect.getCategory().getId(); catid = effect.getCategory().getId();
newname = effect.getNewName(); newname = effect.getNewName();
@ -87,12 +88,12 @@ public class OutgoingTransformer {
if (!vehicleMap.containsKey(passenger)) if (!vehicleMap.containsKey(passenger))
throw new CancelException(); throw new CancelException();
vehicle = vehicleMap.remove(passenger); vehicle = vehicleMap.remove(passenger);
writeVarInt(vehicle,output); writeVarInt(vehicle, output);
writeVarIntArray(Collections.<Integer>emptyList(), output); writeVarIntArray(Collections.<Integer>emptyList(), output);
} else{ } else {
writeVarInt(vehicle, output); writeVarInt(vehicle, output);
writeVarIntArray(Collections.singletonList(passenger), output); writeVarIntArray(Collections.singletonList(passenger), output);
vehicleMap.put(passenger,vehicle); vehicleMap.put(passenger, vehicle);
} }
return; return;
} }
@ -100,6 +101,17 @@ public class OutgoingTransformer {
output.writeInt(vehicle); output.writeInt(vehicle);
return; return;
} }
if (packet == PacketType.PLAY_PLUGIN_MESSAGE) {
String name = PacketUtil.readString(input);
PacketUtil.writeString(name, output);
byte[] b = new byte[input.readableBytes()];
input.readBytes(b);
// patch books
if(name.equals("MC|BOpen")){
PacketUtil.writeVarInt(0, output);
}
output.writeBytes(b);
}
if (packet == PacketType.PLAY_DISCONNECT) { if (packet == PacketType.PLAY_DISCONNECT) {
String reason = readString(input); String reason = readString(input);
writeString(fixJson(reason), output); writeString(fixJson(reason), output);
@ -115,6 +127,55 @@ public class OutgoingTransformer {
output.writeBytes(input); output.writeBytes(input);
return; return;
} }
if (packet == PacketType.PLAY_PLAYER_LIST_ITEM) {
int action = readVarInt(input);
writeVarInt(action, output);
int players = readVarInt(input);
writeVarInt(players, output);
// loop through players
for (int i = 0; i < players; i++) {
UUID uuid = readUUID(input);
writeUUID(uuid, output);
if (action == 0) { // add player
writeString(readString(input), output); // name
int properties = readVarInt(input);
writeVarInt(properties, output);
// loop through properties
for (int j = 0; j < properties; j++) {
writeString(readString(input), output); // name
writeString(readString(input), output); // value
boolean isSigned = input.readBoolean();
output.writeBoolean(isSigned);
if (isSigned) {
writeString(readString(input), output); // signature
}
}
writeVarInt(readVarInt(input), output); // gamemode
writeVarInt(readVarInt(input), output); // ping
boolean hasDisplayName = input.readBoolean();
output.writeBoolean(hasDisplayName);
if (hasDisplayName) {
writeString(fixJson(readString(input)), output); // display name
}
} else if ((action == 1) || (action == 2)) { // update gamemode || update latency
writeVarInt(readVarInt(input), output);
} else if (action == 3) { // update display name
boolean hasDisplayName = input.readBoolean();
output.writeBoolean(hasDisplayName);
if (hasDisplayName) {
writeString(fixJson(readString(input)), output); // display name
}
} else if (action == 4) { // remove player
// no fields
}
}
return;
}
if (packet == PacketType.PLAY_PLAYER_LIST_HEADER_FOOTER) { if (packet == PacketType.PLAY_PLAYER_LIST_HEADER_FOOTER) {
String header = readString(input); String header = readString(input);
String footer = readString(input); String footer = readString(input);
@ -192,9 +253,14 @@ public class OutgoingTransformer {
if (packet == PacketType.STATUS_RESPONSE) { if (packet == PacketType.STATUS_RESPONSE) {
String original = PacketUtil.readString(input); String original = PacketUtil.readString(input);
JsonObject object = gson.fromJson(original, JsonObject.class); try {
object.get("version").getAsJsonObject().addProperty("protocol", info.getProtocol()); JSONObject json = (JSONObject) new JSONParser().parse(original);
PacketUtil.writeString(gson.toJson(object), output); JSONObject version = (JSONObject) json.get("version");
version.put("protocol", info.getProtocol());
PacketUtil.writeString(json.toJSONString(), output);
} catch (ParseException e) {
e.printStackTrace();
}
return; return;
} }
if (packet == PacketType.LOGIN_SUCCESS) { if (packet == PacketType.LOGIN_SUCCESS) {
@ -221,7 +287,9 @@ public class OutgoingTransformer {
slot += 1; // add 1 so it's now 2-5 slot += 1; // add 1 so it's now 2-5
} }
PacketUtil.writeVarInt(slot, output); PacketUtil.writeVarInt(slot, output);
output.writeBytes(input);
ItemSlotRewriter.rewrite1_8To1_9(input, output);
return;
} }
if (packet == PacketType.PLAY_ENTITY_METADATA) { if (packet == PacketType.PLAY_ENTITY_METADATA) {
int id = PacketUtil.readVarInt(input); int id = PacketUtil.readVarInt(input);
@ -338,6 +406,28 @@ public class OutgoingTransformer {
output.writeBytes(input); output.writeBytes(input);
return; return;
} }
if (packet == PacketType.PLAY_SET_SLOT) {
int windowId = input.readUnsignedByte();
output.writeByte(windowId);
short slot = input.readShort();
output.writeShort(slot);
ItemSlotRewriter.rewrite1_8To1_9(input, output);
return;
}
if (packet == PacketType.PLAY_WINDOW_ITEMS) {
int windowId = input.readUnsignedByte();
output.writeByte(windowId);
short count = input.readShort();
output.writeShort(count);
for (int i = 0; i < count; i++) {
ItemSlotRewriter.rewrite1_8To1_9(input, output);
}
return;
}
if (packet == PacketType.PLAY_SPAWN_MOB) { if (packet == PacketType.PLAY_SPAWN_MOB) {
int id = PacketUtil.readVarInt(input); int id = PacketUtil.readVarInt(input);
PacketUtil.writeVarInt(id, output); PacketUtil.writeVarInt(id, output);
@ -428,6 +518,20 @@ public class OutgoingTransformer {
output.writeBytes(input); output.writeBytes(input);
return; return;
} }
if (packet == PacketType.PLAY_ENTITY_EFFECT) {
int id = PacketUtil.readVarInt(input);
PacketUtil.writeVarInt(id, output);
byte effectID = input.readByte();
output.writeByte(effectID);
byte amplifier = input.readByte();
output.writeByte(amplifier);
int duration = PacketUtil.readVarInt(input);
PacketUtil.writeVarInt(duration, output);
// we need to write as a byte instead of boolean
boolean hideParticles = input.readBoolean();
output.writeByte(hideParticles ? 1 : 0);
return;
}
if (packet == PacketType.PLAY_TEAM) { if (packet == PacketType.PLAY_TEAM) {
String teamName = PacketUtil.readString(input); String teamName = PacketUtil.readString(input);
PacketUtil.writeString(teamName, output); PacketUtil.writeString(teamName, output);
@ -460,7 +564,7 @@ public class OutgoingTransformer {
int bitMask = input.readUnsignedShort(); int bitMask = input.readUnsignedShort();
if (bitMask == 0) { if (bitMask == 0 && groundUp) {
output.clear(); output.clear();
PacketUtil.writeVarInt(PacketType.PLAY_UNLOAD_CHUNK.getNewPacketID(), output); PacketUtil.writeVarInt(PacketType.PLAY_UNLOAD_CHUNK.getNewPacketID(), output);
output.writeInt(chunkX); output.writeInt(chunkX);
@ -497,7 +601,7 @@ public class OutgoingTransformer {
output.writeBytes(input); output.writeBytes(input);
} }
private String fixJson(String line) { public static String fixJson(String line) {
if (line == null || line.equalsIgnoreCase("null")) { if (line == null || line.equalsIgnoreCase("null")) {
line = "{\"text\":\"\"}"; line = "{\"text\":\"\"}";
} else { } else {
@ -508,9 +612,8 @@ public class OutgoingTransformer {
} }
try { try {
new JSONParser().parse(line); new JSONParser().parse(line);
} } catch (Exception e) {
catch (org.json.simple.parser.ParseException e) { System.out.println("Invalid JSON String: \"" + line + "\" Please report this issue to the ViaVersion Github: " + e.getMessage());
System.out.println("Invalid JSON String: \"" + line + "\" Please report this issue to the ViaVersion Github!");
return "{\"text\":\"\"}"; return "{\"text\":\"\"}";
} }
return line; return line;

Datei anzeigen

@ -3,6 +3,8 @@ package us.myles.ViaVersion.util;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufOutputStream;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.MessageToByteEncoder; import io.netty.handler.codec.MessageToByteEncoder;
@ -11,6 +13,9 @@ import us.myles.ViaVersion.chunks.PacketChunk;
import us.myles.ViaVersion.chunks.PacketChunkData; import us.myles.ViaVersion.chunks.PacketChunkData;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@ -21,6 +26,9 @@ import java.util.BitSet;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import org.spacehq.opennbt.NBTIO;
import org.spacehq.opennbt.tag.builtin.CompoundTag;
public class PacketUtil { public class PacketUtil {
private static Method DECODE_METHOD; private static Method DECODE_METHOD;
private static Method ENCODE_METHOD; private static Method ENCODE_METHOD;
@ -42,6 +50,25 @@ public class PacketUtil {
} }
} }
public static CompoundTag readNBT(ByteBuf input) throws IOException {
int readerIndex = input.readerIndex();
byte b = input.readByte();
if (b == 0) {
return null;
} else {
input.readerIndex(readerIndex);
return (CompoundTag) NBTIO.readTag(new DataInputStream(new ByteBufInputStream(input)));
}
}
public static void writeNBT(ByteBuf output, CompoundTag tag) throws IOException {
if (tag == null) {
output.writeByte(0);
} else {
NBTIO.writeTag(new DataOutputStream(new ByteBufOutputStream(output)), tag);
}
}
public static List<Object> callDecode(ByteToMessageDecoder decoder, ChannelHandlerContext ctx, Object input) { public static List<Object> callDecode(ByteToMessageDecoder decoder, ChannelHandlerContext ctx, Object input) {
List<Object> output = new ArrayList<Object>(); List<Object> output = new ArrayList<Object>();
try { try {
@ -354,45 +381,6 @@ public class PacketUtil {
return output; return output;
} }
public static void writeItem(Object value, ByteBuf output) {
try {
Class<?> serializer = ReflectionUtil.nms("PacketDataSerializer");
Object init = serializer.getDeclaredConstructor(ByteBuf.class).newInstance(output);
Method toCall = init.getClass().getDeclaredMethod("a", ReflectionUtil.nms("ItemStack"));
toCall.invoke(init, value);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
public static Object readItem(ByteBuf output) {
try {
Class<?> serializer = ReflectionUtil.nms("PacketDataSerializer");
Object init = serializer.getDeclaredConstructor(ByteBuf.class).newInstance(output);
Method toCall = init.getClass().getDeclaredMethod("i");
return toCall.invoke(init);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
public static long[] readBlockPosition(ByteBuf buf) { public static long[] readBlockPosition(ByteBuf buf) {
long val = buf.readLong(); long val = buf.readLong();
long x = (val >> 38); // signed long x = (val >> 38); // signed
@ -414,4 +402,12 @@ public class PacketUtil {
return data; return data;
} }
public static boolean containsCause(Throwable t, Class<? extends Throwable> c) {
while (t != null) {
t = t.getCause();
if (c.isAssignableFrom(t.getClass())) return true;
}
return false;
}
} }

Datei anzeigen

@ -27,6 +27,18 @@ public class ReflectionUtil {
return m.invoke(o); return m.invoke(o);
} }
public static <T> T getStatic(Class<?> clazz, String f, Class<T> t) throws NoSuchFieldException, IllegalAccessException {
Field field = clazz.getDeclaredField(f);
field.setAccessible(true);
return (T) field.get(null);
}
public static <T> T get(Object instance, Class<?> clazz, String f, Class<T> t) throws NoSuchFieldException, IllegalAccessException {
Field field = clazz.getDeclaredField(f);
field.setAccessible(true);
return (T) field.get(instance);
}
public static <T> T get(Object o, String f, Class<T> t) throws NoSuchFieldException, IllegalAccessException { public static <T> T get(Object o, String f, Class<T> t) throws NoSuchFieldException, IllegalAccessException {
Field field = o.getClass().getDeclaredField(f); Field field = o.getClass().getDeclaredField(f);
field.setAccessible(true); field.setAccessible(true);

Datei anzeigen

@ -1,6 +1,11 @@
name: ViaVersion name: ViaVersion
main: us.myles.ViaVersion.ViaVersionPlugin main: us.myles.ViaVersion.ViaVersionPlugin
author: _MylesC author: _MylesC
version: 0.4.6 version: ${version}
load: startup load: startup
loadbefore: [ProtocolLib, ProxyPipe] loadbefore: [ProtocolLib, ProxyPipe]
commands:
viaversion:
description: Shows ViaVersion Version and more.
permission: viaversion.admin
aliases: [viaver]