Compare commits

..
59 Commits
Author SHA1 Message Date
Myles 6b8b0e1771 Bump version to 0.7.6-SNAPSHOT 2016-04-13 19:42:53 +01:00
Myles e6671513f2 Improve an issue to do with block breaking ghosting back, note this is not a fully fix, but improves the issue quite a bit. 2016-04-13 16:54:18 +01:00
Myles 4c7b50d6fb Fix chunk sending order, Fixes #338, #292 (I believe.) 2016-04-13 15:05:50 +01:00
Mats 1c9229a2fc Don't unload the chunks twice (#350) 2016-04-13 12:25:41 +01:00
Mats d11c18c024 Remove MCProtocolLib (#349) 2016-04-12 12:40:12 +01:00
Mats dc4b5b4d35 Possibility to show the new 1.9 death messages (#348) 2016-04-12 12:01:37 +01:00
Mats 517299d673 Show skeletons' bow like 1.8, not down as 1.9 without target (#347) 2016-04-12 11:18:58 +01:00
Mats a8baa7af50 Transform Combat packet (#346) 2016-04-12 11:18:51 +01:00
Myles a1f847c905 Patch respawn packet to reset bulk / loaded cache. 2016-04-11 20:17:48 +01:00
Mats f3ea43b1eb Reformat / optimize imports (#344) 2016-04-10 18:43:08 +01:00
Mats 551b5d0654 Rewrite effect ids (#342)
* Rewrite effect ids

* Remove test line

* Remove Lombok unused thingy

* No need to check.
2016-04-10 14:29:25 +01:00
Mats 9f39662df6 Check if custom name is visible and if custom name is not empty. Fix …
* Check if custom name is visible and if custom name is not empty. Fix #327

* Fix typo
2016-04-06 13:50:09 +01:00
Myles 7ea2156f37 Bump version 2016-04-05 14:31:40 +01:00
Mats 5032e7d07e Only apply the 'Hologram patch' to small entities since it only happens to them.
Only apply the 'Hologram patch' to small entities (Doesn't fix issue but hey)
2016-04-04 15:55:48 +01:00
Myles c7c6ee9fbc Delay registration of protocols until the plugin has loaded to prevent it being done at the wrong time, #323 #316 Fixed 2016-04-03 23:30:10 +01:00
Mats 4431ca63c2 Fix viaversion list command 2016-04-03 11:26:27 +01:00
Myles 1fa7211cf0 Construct List properly, Fix #314 2016-04-03 01:51:38 +01:00
Myles de576795dc Blame @Matsv 2016-04-02 22:59:40 +01:00
Myles f6286bcc25 Bump version 2016-04-02 22:13:30 +01:00
Myles 8276b212e9 Merge pull request #313 from Matsv/master
Stop allowing everyone to change the instance
2016-04-02 21:32:46 +01:00
Matsv aabd9247a6 Stop allowing everyone to change the instance 2016-04-02 21:45:24 +02:00
Myles 997c2ad6a1 Fix Potions: ThrownPotion is now correct, and the particles are too.
Fixes #223
Also changes a tiny bit of javadoc :)
2016-04-02 14:46:30 +01:00
Myles 233a2ba5df Merge pull request #312 from Matsv/dev
Fix custom NBT for potions / spawneggs
2016-04-02 14:09:00 +01:00
Matsv ed0d5a7cfb Fix NBT for potions 2016-04-02 15:06:10 +02:00
Matsv 87f083460c Fix custom named spawneggs 2016-04-02 15:02:41 +02:00
Myles 2d6dedefb8 Add some packet plugins to loadbefore to ensure it works better with them. 2016-04-02 13:50:21 +01:00
Myles 8adbf36a3a Merge pull request #311 from Matsv/dev
Make command sender messages cleaner
2016-04-02 13:30:10 +01:00
Matsv 8c706b665c Don't format if no args are given 2016-04-02 11:58:15 +02:00
Matsv 2e3677a592 Make command sender messages cleaner 2016-04-02 11:51:17 +02:00
Myles 3602c5087b Don't send a meta data packet when list is empty. #288 2016-04-01 18:13:23 +01:00
Myles 5c84b3d8cc Merge pull request #309 from HugoDaBosss/master
Implement subcommand to reload the config
2016-04-01 16:41:03 +01:00
Hugo Kerstens 7defe7129f Implement subcommand to reload the config 2016-04-01 17:31:44 +02:00
Myles 995dc135b8 Merge pull request #308 from Matsv/boss
Cleanup BossBar class & add new bossbar api method, addPlayers()
2016-04-01 15:07:04 +01:00
Matsv 3f64fb7d5f Cleanup BossBar class & add new bossbar api method, addPlayers() 2016-04-01 16:03:56 +02:00
Myles ac8f7a00ae Merge pull request #305 from HugoDaBosss/master
Implement new protocol version registry
2016-03-31 22:45:39 +01:00
Myles 6893f34289 Support reloading to some extent, if you use protocol lib it will kick all your players... (So you probably should just get a PluginManager...)
One day i'll fully patch to work... (If I don't kick the players it ends up that ProtocolLib implodes and nobody can connect.)
2016-03-31 22:45:15 +01:00
Hugo Kerstens 0a69d62cbe Fixed typo (blame Mats) 2016-03-31 23:26:13 +02:00
Myles 5e0096aa2c Merge pull request #307 from Matsv/master
Woops use the same instance
2016-03-31 21:49:42 +01:00
Matsv 7326205495 Woops use the same instance 2016-03-31 22:48:20 +02:00
Myles a8212db7f2 Merge pull request #306 from Matsv/tabcomplete
Tabcomplete
2016-03-31 19:55:11 +01:00
Matsv 2905d77206 Reformatting moved color to the top ;( 2016-03-31 20:53:03 +02:00
Matsv cb8ec2ce20 Add tab-complete possibility and help subcommand 2016-03-31 20:50:22 +02:00
Hugo Kerstens 09f484f956 Implement new protocol version registry 2016-03-31 19:50:04 +02:00
Myles c48922eb3e Merge pull request #304 from Matsv/cmd
Implement new command API
2016-03-31 17:56:08 +01:00
Matsv b701a0ef67 Change debug mode subcmd description 2016-03-31 18:55:05 +02:00
Matsv eb50f4e907 Merge branch 'master' of https://github.com/Matsv/ViaVersion into cmd 2016-03-31 17:53:12 +02:00
Matsv 6480ea34fc Changed javadoc 2016-03-31 17:52:06 +02:00
Matsv 511941462f Add javadoc 2016-03-31 17:51:30 +02:00
Matsv 34cc783cac Fix missing description, add javadocs, make sure subcommand is valid, check permission 2016-03-31 17:48:15 +02:00
Matsv ecc79b4f49 Command API to keep it clean and make it possible for developers to add their own viaversion subcommands if they want to. 2016-03-31 17:22:42 +02:00
Myles 76f10c463f Merge pull request #301 from Matsv/master
Handle discontinued player item in hand, fixes #299
2016-03-31 15:49:24 +01:00
Matsv 41d5144b57 Handle discontinued player item in hand, fixes #299 2016-03-31 16:28:56 +02:00
Myles de196f2e4f Merge pull request #300 from HugoDaBosss/master
Small optimization in join packet
2016-03-31 14:10:52 +01:00
Hugo Kerstens 0acc2f95fb Remove unneeded code 2016-03-31 15:08:19 +02:00
Myles d16eb9b27e Version bump 2016-03-30 17:46:00 +01:00
Myles 8760b53a0a Fix Disconnect Issue (It's not really harmful but still) 2016-03-30 17:45:24 +01:00
Myles a40182186f Fix debug issue with 1.9.2 2016-03-30 17:34:13 +01:00
Myles ef2b173749 Merge pull request #295 from Matsv/master
Rename 1_9_1 PRE to just 1_9_1
2016-03-30 17:33:15 +01:00
Matsv 75c9284cda Rename 1_9_1 PRE to just 1_9_1 2016-03-30 18:23:52 +02:00
47 changed files with 1032 additions and 197 deletions

No files matched your search

+1 -3
View File
@@ -1,4 +1,4 @@
# ViaVersion 0.7.1
# ViaVersion 0.7.5
[![Build Status](https://travis-ci.org/MylesIsCool/ViaVersion.svg?branch=master)](https://travis-ci.org/MylesIsCool/ViaVersion)
[![Gitter](https://badges.gitter.im/MylesIsCool/ViaVersion.svg)](https://gitter.im/MylesIsCool/ViaVersion)
@@ -20,8 +20,6 @@ Sources:
**wiki.vg** (Protocol info, though I did have to find a lot myself)
**MCProtocolLib** (used for chunk reading & some of writing.)
**OpenNBT** (used for slot rewriting)
+1 -1
View File
@@ -6,7 +6,7 @@
<groupId>us.myles</groupId>
<artifactId>viaversion</artifactId>
<version>0.7.1-SNAPSHOT</version>
<version>0.7.6-SNAPSHOT</version>
<packaging>jar</packaging>
<name>ViaVersion</name>
@@ -1,6 +1,5 @@
package us.myles.ViaVersion;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import org.bukkit.scheduler.BukkitRunnable;
import us.myles.ViaVersion.api.data.UserConnection;
@@ -34,9 +33,13 @@ public class ViaIdleThread extends BukkitRunnable {
long nextIdleUpdate = info.get(MovementTracker.class).getNextIdlePacket();
if (nextIdleUpdate <= System.currentTimeMillis()) {
ChannelHandlerContext context = PipelineUtil.getContextBefore("decoder", info.getChannel().pipeline());
context.fireChannelRead(idlePacket);
if (info.getChannel().isOpen()) {
if (context != null) {
context.fireChannelRead(idlePacket);
info.get(MovementTracker.class).incrementIdlePacket();
info.get(MovementTracker.class).incrementIdlePacket();
}
}
}
}
}
@@ -9,16 +9,18 @@ import lombok.NonNull;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import us.myles.ViaVersion.api.Pair;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.api.ViaVersionAPI;
import us.myles.ViaVersion.api.ViaVersionConfig;
import us.myles.ViaVersion.api.boss.BossBar;
import us.myles.ViaVersion.api.boss.BossColor;
import us.myles.ViaVersion.api.boss.BossStyle;
import us.myles.ViaVersion.api.command.ViaVersionCommand;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
import us.myles.ViaVersion.boss.ViaBossBar;
import us.myles.ViaVersion.commands.ViaVersionCommand;
import us.myles.ViaVersion.commands.ViaCommandHandler;
import us.myles.ViaVersion.handlers.ViaVersionInitializer;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import us.myles.ViaVersion.update.UpdateListener;
@@ -30,6 +32,7 @@ import us.myles.ViaVersion.util.ReflectionUtil;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -41,18 +44,36 @@ import java.util.concurrent.TimeUnit;
public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI, ViaVersionConfig {
private final Map<UUID, UserConnection> portedPlayers = new ConcurrentHashMap<>();
private List<ChannelFuture> injectedFutures = new ArrayList<>();
private List<Pair<Field, Object>> injectedLists = new ArrayList<>();
private ViaCommandHandler commandHandler;
private boolean debug = false;
@Override
public void onEnable() {
public void onLoad() {
ViaVersion.setInstance(this);
generateConfig();
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("Some features may not work.");
return;
if (Bukkit.getPluginManager().getPlugin("ProtocolLib") != null) {
getLogger().severe("ViaVersion is already loaded, we're going to kick all the players... because otherwise we'll crash because of ProtocolLib.");
for (Player player : Bukkit.getOnlinePlayers()) {
player.kickPlayer("Server reload, please rejoin!");
}
} else {
getLogger().severe("ViaVersion is already loaded, this should work fine... Otherwise reboot the server!!!");
}
}
getLogger().info("ViaVersion " + getDescription().getVersion() + " is now loaded, injecting.");
injectPacketHandler();
}
@Override
public void onEnable() {
if (isCheckForUpdates())
UpdateUtil.sendUpdateMessage(this);
// Gather version :)
Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
@Override
@@ -68,16 +89,20 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI, ViaVe
}
});
getLogger().info("ViaVersion " + getDescription().getVersion() + " is now enabled, injecting.");
injectPacketHandler();
if (isCheckForUpdates())
UpdateUtil.sendUpdateMessage(this);
Bukkit.getPluginManager().registerEvents(new UpdateListener(this), this);
getCommand("viaversion").setExecutor(new ViaVersionCommand(this));
getCommand("viaversion").setExecutor(commandHandler = new ViaCommandHandler());
getCommand("viaversion").setTabCompleter(commandHandler);
// Register Protocol Listeners
ProtocolRegistry.registerListeners();
}
@Override
public void onDisable() {
getLogger().info("ViaVersion is disabling, if this is a reload it may not work.");
uninject();
}
public void gatherProtocolVersion() {
@@ -182,6 +207,7 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI, ViaVe
}
}
};
injectedLists.add(new Pair<>(field, connection));
field.set(connection, wrapper);
// Iterate through current list
synchronized (wrapper) {
@@ -210,6 +236,7 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI, ViaVe
ChannelInitializer newInit = new ViaVersionInitializer(oldInit);
ReflectionUtil.set(bootstrapAcceptor, "childHandler", newInit);
injectedFutures.add(future);
} catch (NoSuchFieldException e) {
// field not found
throw new Exception("Unable to find childHandler, blame " + bootstrapAcceptor.getClass().getName());
@@ -220,6 +247,35 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI, ViaVe
}
}
private void uninject() {
// TODO: Uninject from players currently online to prevent protocol lib issues.
for (ChannelFuture future : injectedFutures) {
ChannelHandler bootstrapAcceptor = future.channel().pipeline().first();
try {
ChannelInitializer<SocketChannel> oldInit = ReflectionUtil.get(bootstrapAcceptor, "childHandler", ChannelInitializer.class);
if (oldInit instanceof ViaVersionInitializer) {
ReflectionUtil.set(bootstrapAcceptor, "childHandler", ((ViaVersionInitializer) oldInit).getOriginal());
}
} catch (Exception e) {
System.out.println("Failed to remove injection... reload won't work with connections sorry");
}
}
injectedFutures.clear();
for (Pair<Field, Object> pair : injectedLists) {
try {
Object o = pair.getKey().get(pair.getValue());
if (o instanceof ListWrapper) {
pair.getKey().set(pair.getValue(), ((ListWrapper) o).getOriginalList());
}
} catch (IllegalAccessException e) {
System.out.println("Failed to remove injection... reload might not work with connections sorry");
}
}
injectedLists.clear();
}
@Override
public boolean isPorted(Player player) {
return isPorted(player.getUniqueId());
@@ -287,6 +343,11 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI, ViaVe
this.debug = value;
}
@Override
public ViaVersionCommand getCommandHandler() {
return commandHandler;
}
public boolean isCheckForUpdates() {
return getConfig().getBoolean("checkforupdates", true);
}
@@ -299,6 +360,11 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI, ViaVe
return getConfig().getBoolean("use-new-effect-indicator", true);
}
@Override
public boolean isShowNewDeathMessages() {
return getConfig().getBoolean("use-new-deathmessages", false);
}
public boolean isSuppressMetadataErrors() {
return getConfig().getBoolean("suppress-metadata-errors", false);
}
@@ -327,6 +393,10 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI, ViaVe
return getConfig().getDouble("hologram-y", -1D);
}
public boolean isBlockBreakPatch() {
return getConfig().getBoolean("block-break-patch", true);
}
public boolean isAutoTeam() {
// Collision has to be enabled first
return isPreventCollision() && getConfig().getBoolean("auto-team", true);
@@ -198,6 +198,7 @@ public class PacketWrapper {
/**
* Send this packet to the associated user.
* Be careful not to send packets twice.
* (Sends it after current)
*
* @throws Exception if it fails to write
*/
@@ -1,6 +1,7 @@
package us.myles.ViaVersion.api;
import lombok.Getter;
import org.apache.commons.lang.Validate;
import us.myles.ViaVersion.ViaVersionPlugin;
public class ViaVersion {
@@ -11,6 +12,7 @@ public class ViaVersion {
private static ViaVersionConfig config;
public static void setInstance(ViaVersionPlugin plugin) {
Validate.isTrue(instance == null, "Instance is already set");
ViaVersion.instance = plugin;
ViaVersion.config = plugin;
}
@@ -5,6 +5,7 @@ import org.bukkit.entity.Player;
import us.myles.ViaVersion.api.boss.BossBar;
import us.myles.ViaVersion.api.boss.BossColor;
import us.myles.ViaVersion.api.boss.BossStyle;
import us.myles.ViaVersion.api.command.ViaVersionCommand;
import java.util.UUID;
@@ -93,4 +94,11 @@ public interface ViaVersionAPI {
* @return true if debug is enabled
*/
boolean isDebug();
/**
* Get ViaVersions command handler
*
* @return command handler
*/
ViaVersionCommand getCommandHandler();
}
@@ -30,6 +30,13 @@ public interface ViaVersionConfig {
*/
boolean isNewEffectIndicator();
/**
* Get if 1.9 clients are shown the new death message on the death screen
*
* @return true if enabled
*/
boolean isShowNewDeathMessages();
/**
* Get if metadata errors will be suppressed
*
@@ -86,4 +93,11 @@ public interface ViaVersionConfig {
* @return true if automatic teaming is enabled
*/
boolean isAutoTeam();
/**
* Get if our block break patch is enabled to prevent weird ghost glitches.
*
* @return true if it is enabled.
*/
boolean isBlockBreakPatch();
}
@@ -69,6 +69,14 @@ public interface BossBar {
*/
BossBar addPlayer(Player player);
/**
* add multiple players
*
* @param players list of players
* @return the bossbar instance
*/
BossBar addPlayers(Player... players);
/**
* Remove the bossbar from a player
*
@@ -0,0 +1,77 @@
package us.myles.ViaVersion.api.command;
import org.bukkit.command.CommandSender;
import us.myles.ViaVersion.commands.ViaCommandHandler;
import java.util.Collections;
import java.util.List;
public abstract class ViaSubCommand {
/**
* Subcommand name
*
* @return your input
*/
public abstract String name();
/**
* subcommand description, this'll show in /viaversion list
*
* @return your input
*/
public abstract String description();
/**
* Usage example:
* "playerversion [name]"
*
* @return your input
*/
public String usage() {
return name();
}
/**
* Permission, null for everyone
*
* @return
*/
public String permission() {
return "viaversion.admin";
}
/**
* Gets triggered on execution
*
* @param sender Command sender
* @param args Arguments
* @return command executed succesfully if false, show usage
*/
public abstract boolean execute(CommandSender sender, String[] args);
/**
* Yay, possibility to implement tab-completion
*
* @param sender Command sender
* @param args args
* @return tab complete possibilities
*/
public List<String> onTabComplete(CommandSender sender, String[] args) {
return Collections.emptyList();
}
public String color(String s) {
return ViaCommandHandler.color(s);
}
/**
* Send message formatted / colored
*
* @param sender command sender
* @param message string message
* @param args optional objects
*/
public void sendMessage(CommandSender sender, String message, Object... args) {
ViaCommandHandler.sendMessage(sender, message, args);
}
}
@@ -0,0 +1,27 @@
package us.myles.ViaVersion.api.command;
public interface ViaVersionCommand {
/**
* Register your own subcommand inside ViaVersion
*
* @param command Your own SubCommand instance to handle it.
* @throws Exception throws an exception when the subcommand already exists or if it's not valid, example: spacee
*/
void registerSubCommand(ViaSubCommand command) throws Exception;
/**
* Check if a subcommand is registered.
*
* @param name Subcommand name
* @return true if it exists
*/
boolean hasSubCommand(String name);
/**
* Get subcommand instance by name
*
* @param name subcommand name
* @return ViaSubCommand instance
*/
ViaSubCommand getSubCommand(String name);
}
@@ -1,12 +1,14 @@
package us.myles.ViaVersion.api.minecraft;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
@AllArgsConstructor
@Getter
@ToString
@EqualsAndHashCode
public class Position {
private Long x;
private Long y;
@@ -2,11 +2,11 @@ package us.myles.ViaVersion.api.protocol;
import lombok.AllArgsConstructor;
import lombok.Getter;
import us.myles.ViaVersion.exception.CancelException;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.Pair;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.exception.CancelException;
import us.myles.ViaVersion.packets.Direction;
import us.myles.ViaVersion.packets.State;
@@ -20,7 +20,6 @@ public abstract class Protocol {
public Protocol() {
registerPackets();
registerListeners();
}
/**
@@ -82,11 +82,11 @@ public class ProtocolPipeline extends Protocol {
String packet = "UNKNOWN";
// For 1.8/1.9 server version, eventually we'll probably get an API for this...
if (ProtocolRegistry.SERVER_PROTOCOL >= ProtocolVersion.V1_8 &&
ProtocolRegistry.SERVER_PROTOCOL <= ProtocolVersion.V1_9_1_PRE2) {
if (ProtocolRegistry.SERVER_PROTOCOL >= ProtocolVersion.v1_8.getId() &&
ProtocolRegistry.SERVER_PROTOCOL <= ProtocolVersion.v1_9_2.getId()) {
PacketType type;
if (ProtocolRegistry.SERVER_PROTOCOL == ProtocolVersion.V1_8) {
if (ProtocolRegistry.SERVER_PROTOCOL == ProtocolVersion.v1_8.getId()) {
if (direction == Direction.INCOMING) {
type = PacketType.findNewPacket(state, direction, originalID);
} else {
@@ -1,5 +1,6 @@
package us.myles.ViaVersion.api.protocol;
import org.bukkit.Bukkit;
import us.myles.ViaVersion.api.Pair;
import us.myles.ViaVersion.protocols.protocol1_9_1to1_9.Protocol1_9_1TO1_9;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
@@ -11,11 +12,12 @@ public class ProtocolRegistry {
// Input Version -> Output Version & Protocol (Allows fast lookup)
private static Map<Integer, Map<Integer, Protocol>> registryMap = new HashMap<>();
private static Map<Pair<Integer, Integer>, List<Pair<Integer, Protocol>>> pathCache = new HashMap<>();
private static List<Protocol> registerList = new ArrayList<>();
static {
// Register built in protocols
registerProtocol(new Protocol1_9TO1_8(), Collections.singletonList(ProtocolVersion.V1_9), ProtocolVersion.V1_8);
registerProtocol(new Protocol1_9_1TO1_9(), Arrays.asList(ProtocolVersion.V1_9_1_PRE2, ProtocolVersion.V1_9_2), ProtocolVersion.V1_9);
registerProtocol(new Protocol1_9TO1_8(), Collections.singletonList(ProtocolVersion.v1_9.getId()), ProtocolVersion.v1_8.getId());
registerProtocol(new Protocol1_9_1TO1_9(), Arrays.asList(ProtocolVersion.v1_9_1.getId(), ProtocolVersion.v1_9_2.getId()), ProtocolVersion.v1_9.getId());
}
/**
@@ -37,6 +39,12 @@ public class ProtocolRegistry {
registryMap.get(version).put(output, protocol);
}
if (Bukkit.getPluginManager().getPlugin("ViaVersion").isEnabled()) {
protocol.registerListeners();
} else {
registerList.add(protocol);
}
}
/**
@@ -51,6 +59,16 @@ public class ProtocolRegistry {
return false; // No destination for protocol
}
/**
* Called when the server is enabled, to register any non registered listeners.
*/
public static void registerListeners() {
for (Protocol protocol : registerList) {
protocol.registerListeners();
}
registerList.clear();
}
/**
* Calculate a path to get from an input protocol to the servers protocol.
*
@@ -1,13 +1,46 @@
package us.myles.ViaVersion.api.protocol;
import lombok.Data;
import lombok.NonNull;
import java.util.*;
@Data
public class ProtocolVersion {
/* Defined protocol constants */
public static final int V1_7_1 = 4;
public static final int V1_7_6 = 5;
private static final Map<Integer, ProtocolVersion> versions = new HashMap<>();
public static final int V1_8 = 47;
public static final ProtocolVersion v1_7_1;
public static final ProtocolVersion v1_7_6;
public static final ProtocolVersion v1_8;
public static final ProtocolVersion v1_9;
public static final ProtocolVersion v1_9_1;
public static final ProtocolVersion v1_9_2;
public static final int V1_9 = 107;
public static final int V1_9_1_PRE2 = 108; // used for 1.9.1
public static final int V1_9_2 = 109;
private final int id;
private final String name;
static {
register(v1_7_1 = new ProtocolVersion(4, "1.7-1.7.5"));
register(v1_7_6 = new ProtocolVersion(5, "1.7.6-1.7.10"));
register(v1_8 = new ProtocolVersion(47, "1.8.x"));
register(v1_9 = new ProtocolVersion(107, "1.9"));
register(v1_9_1 = new ProtocolVersion(108, "1.9.1"));
register(v1_9_2 = new ProtocolVersion(109, "1.9.2"));
}
public static void register(@NonNull ProtocolVersion protocol) {
versions.put(protocol.getId(), protocol);
}
public static boolean isRegistered(int id) {
return versions.containsKey(id);
}
public static ProtocolVersion getProtocol(int id) {
return versions.get(id);
}
public static List<ProtocolVersion> getProtocols() {
return Collections.unmodifiableList(new ArrayList<ProtocolVersion>(versions.values()));
}
}
@@ -3,6 +3,7 @@ package us.myles.ViaVersion.boss;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.Getter;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.Validate;
import org.bukkit.entity.Player;
@@ -42,8 +43,7 @@ public class ViaBossBar implements BossBar {
}
@Override
public BossBar setTitle(String title) {
Validate.notNull(title, "Title cannot be null");
public BossBar setTitle(@NonNull String title) {
this.title = title;
sendPacket(UpdateAction.UPDATE_TITLE);
return this;
@@ -63,24 +63,22 @@ public class ViaBossBar implements BossBar {
}
@Override
public BossBar setColor(BossColor color) {
Validate.notNull(color, "Color cannot be null");
public BossBar setColor(@NonNull BossColor color) {
this.color = color;
sendPacket(UpdateAction.UPDATE_STYLE);
return this;
}
@Override
public BossBar setStyle(BossStyle style) {
Validate.notNull(style, "Style cannot be null");
public BossBar setStyle(@NonNull BossStyle style) {
this.style = style;
sendPacket(UpdateAction.UPDATE_STYLE);
return this;
}
@Override
public BossBar addPlayer(Player player) {
if (player != null && !players.contains(player.getUniqueId())) {
public BossBar addPlayer(@NonNull Player player) {
if (!players.contains(player.getUniqueId())) {
players.add(player.getUniqueId());
if (visible)
sendPacket(player.getUniqueId(), getPacket(UpdateAction.ADD));
@@ -89,8 +87,8 @@ public class ViaBossBar implements BossBar {
}
@Override
public BossBar removePlayer(Player player) {
if (player != null && players.contains(player.getUniqueId())) {
public BossBar removePlayer(@NonNull Player player) {
if (players.contains(player.getUniqueId())) {
players.remove(player.getUniqueId());
sendPacket(player.getUniqueId(), getPacket(UpdateAction.REMOVE));
}
@@ -98,7 +96,14 @@ public class ViaBossBar implements BossBar {
}
@Override
public BossBar addFlag(BossFlag flag) {
public BossBar addPlayers(@NonNull Player... players) {
for (Player p : players)
addPlayer(p);
return this;
}
@Override
public BossBar addFlag(@NonNull BossFlag flag) {
if (!hasFlag(flag))
flags.add(flag);
sendPacket(UpdateAction.UPDATE_FLAGS);
@@ -106,7 +111,7 @@ public class ViaBossBar implements BossBar {
}
@Override
public BossBar removeFlag(BossFlag flag) {
public BossBar removeFlag(@NonNull BossFlag flag) {
if (hasFlag(flag))
flags.remove(flag);
sendPacket(UpdateAction.UPDATE_FLAGS);
@@ -114,7 +119,7 @@ public class ViaBossBar implements BossBar {
}
@Override
public boolean hasFlag(BossFlag flag) {
public boolean hasFlag(@NonNull BossFlag flag) {
return flags.contains(flag);
}
@@ -154,7 +159,7 @@ public class ViaBossBar implements BossBar {
}
private void sendPacket(UUID uuid, ByteBuf buf) {
if (!ViaVersion.getInstance().isPorted(uuid) || !(ViaVersion.getInstance().getPlayerVersion(uuid) >= ProtocolVersion.V1_9)) {
if (!ViaVersion.getInstance().isPorted(uuid) || !(ViaVersion.getInstance().getPlayerVersion(uuid) >= ProtocolVersion.v1_9.getId())) {
players.remove(uuid);
return;
}
@@ -0,0 +1,152 @@
package us.myles.ViaVersion.commands;
import lombok.NonNull;
import org.apache.commons.lang.Validate;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.api.command.ViaSubCommand;
import us.myles.ViaVersion.api.command.ViaVersionCommand;
import us.myles.ViaVersion.commands.defaultsubs.*;
import java.util.*;
public class ViaCommandHandler implements ViaVersionCommand, CommandExecutor, TabCompleter {
private Map<String, ViaSubCommand> commandMap;
public ViaCommandHandler() {
commandMap = new HashMap<>();
try {
registerDefaults();
} catch (Exception e) {
//ignore never throws exception because it doesn't exists
}
}
@Override
public void registerSubCommand(@NonNull ViaSubCommand command) throws Exception {
Validate.isTrue(command.name().matches("^[a-z0-9_-]{3,15}$"), command.name() + " is not a valid subcommand name");
if (hasSubCommand(command.name()))
throw new Exception("ViaSubCommand " + command.name() + " does already exists!"); //Maybe another exception later.
commandMap.put(command.name().toLowerCase(), command);
}
@Override
public boolean hasSubCommand(String name) {
return commandMap.containsKey(name.toLowerCase());
}
@Override
public ViaSubCommand getSubCommand(String name) {
return commandMap.get(name.toLowerCase());
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String arg, String[] args) {
if (args.length == 0) {
showHelp(sender);
return false;
}
if (!hasSubCommand(args[0])) {
sender.sendMessage(color("&cThis command is not found"));
showHelp(sender);
return false;
}
ViaSubCommand handler = getSubCommand(args[0]);
if (!hasPermission(sender, handler.permission())) {
sender.sendMessage(color("&cYou are not allowed to use this command!"));
return false;
}
String[] subArgs = Arrays.copyOfRange(args, 1, args.length);
boolean result = handler.execute(sender, subArgs);
if (!result)
sender.sendMessage("Usage: /viaversion " + handler.usage());
return result;
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String arg, String[] args) {
Set<ViaSubCommand> allowed = calculateAllowedCommands(sender);
List<String> output = new ArrayList<>();
//SubCommands tabcomplete
if (args.length == 1) {
if (!args[0].equals("")) {
for (ViaSubCommand sub : allowed)
if (sub.name().toLowerCase().startsWith(args[0].toLowerCase()))
output.add(sub.name());
} else {
for (ViaSubCommand sub : allowed)
output.add(sub.name());
}
}
//Let the SubCommand handle it
else if (args.length >= 2) {
if (getSubCommand(args[0]) != null) {
ViaSubCommand sub = getSubCommand(args[0]);
if (!allowed.contains(sub))
return output;
String[] subArgs = Arrays.copyOfRange(args, 1, args.length);
List<String> tab = sub.onTabComplete(sender, subArgs);
Collections.sort(tab);
return tab;
}
}
return output;
}
public void showHelp(CommandSender sender) {
Set<ViaSubCommand> allowed = calculateAllowedCommands(sender);
if (allowed.size() == 0) {
sender.sendMessage(color("&cYou are not allowed to use this command!"));
return;
}
sender.sendMessage(color("&aViaVersion &c" + ViaVersion.getInstance().getVersion()));
sender.sendMessage(color("&6Commands:"));
for (ViaSubCommand cmd : allowed)
sender.sendMessage(color(String.format("&2/viaversion %s &7- &6%s", cmd.usage(), cmd.description())));
allowed.clear();
}
private Set<ViaSubCommand> calculateAllowedCommands(CommandSender sender) {
Set<ViaSubCommand> cmds = new HashSet<>();
for (ViaSubCommand sub : commandMap.values())
if (hasPermission(sender, sub.permission()))
cmds.add(sub);
return cmds;
}
private boolean hasPermission(CommandSender sender, String permission) {
return permission == null || sender.hasPermission(permission);
}
private void registerDefaults() throws Exception {
registerSubCommand(new ListSubCmd());
registerSubCommand(new DebugSubCmd());
registerSubCommand(new DisplayLeaksSubCmd());
registerSubCommand(new DontBugMeSubCmd());
registerSubCommand(new AutoTeamSubCmd());
registerSubCommand(new HelpSubCmd());
registerSubCommand(new ReloadSubCmd());
}
public static String color(String string) {
try {
string = ChatColor.translateAlternateColorCodes('&', string); //Dont replace all & with $ like we did before.
} catch (Exception ignored) {
}
return string;
}
public static void sendMessage(@NonNull CommandSender sender, String message, Object... args) {
sender.sendMessage(color(args == null ? message : String.format(message, args)));
}
}
@@ -1,82 +0,0 @@
package us.myles.ViaVersion.commands;
import io.netty.util.ResourceLeakDetector;
import lombok.RequiredArgsConstructor;
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.ViaVersionPlugin;
import us.myles.ViaVersion.api.ViaVersion;
import java.util.ArrayList;
import java.util.List;
@RequiredArgsConstructor
public class ViaVersionCommand implements CommandExecutor {
private final ViaVersionPlugin plugin;
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (sender.hasPermission("viaversion.admin")) {
if (args.length == 0) {
sendHelp(sender);
} else if (args.length == 1) {
if (args[0].equalsIgnoreCase("list")) {
List<String> portedPlayers = new ArrayList<>();
List<String> normalPlayers = new ArrayList<>();
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()));
} else if (args[0].equalsIgnoreCase("debug")) {
plugin.setDebug(!plugin.isDebug());
sender.sendMessage(color("&6Debug mode is now " + (plugin.isDebug() ? "&aenabled" : "&cdisabled")));
} else if (args[0].equalsIgnoreCase("displayleaks")) {
if (ResourceLeakDetector.getLevel() != ResourceLeakDetector.Level.ADVANCED) {
ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.ADVANCED);
} else {
ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.DISABLED);
}
sender.sendMessage(color("&6Leak detector is now " + (ResourceLeakDetector.getLevel() == ResourceLeakDetector.Level.ADVANCED ? "&aenabled" : "&cdisabled")));
} else if (args[0].equalsIgnoreCase("dontbugme")) {
boolean newValue = !plugin.isCheckForUpdates();
plugin.getConfig().set("checkforupdates", newValue);
plugin.saveConfig();
sender.sendMessage(color("&6We will " + (newValue ? "&anotify you about updates." : "&cnot tell you about updates.")));
} else if (args[0].equalsIgnoreCase("autoteam")) {
boolean newValue = !plugin.isAutoTeam();
plugin.getConfig().set("auto-team", newValue);
plugin.saveConfig();
sender.sendMessage(color("&6We will " + (newValue ? "&aautomatically team players" : "&cno longer auto team players")));
sender.sendMessage(color("&6All players will need to re-login for the change to take place."));
} else {
sendHelp(sender);
}
}
}
return false;
}
public void sendHelp(CommandSender sender) {
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."));
sender.sendMessage(color("&2/viaversion debug &7- &6Toggle debug mode"));
sender.sendMessage(color("&2/viaversion autoteam &7- &6Toggle automatically teaming to prevent colliding."));
sender.sendMessage(color("&2/viaversion dontbugme &7- &6Toggle checking for updates."));
}
public String color(String string) {
return string.replace("&", "§");
}
}
@@ -0,0 +1,31 @@
package us.myles.ViaVersion.commands.defaultsubs;
import org.bukkit.command.CommandSender;
import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.api.command.ViaSubCommand;
public class AutoTeamSubCmd extends ViaSubCommand {
@Override
public String name() {
return "autoteam";
}
@Override
public String description() {
return "Toggle automatically teaming to prevent colliding.";
}
@Override
public boolean execute(CommandSender sender, String[] args) {
ViaVersionPlugin plugin = (ViaVersionPlugin) ViaVersion.getInstance();
boolean newValue = !plugin.isAutoTeam();
plugin.getConfig().set("auto-team", newValue);
plugin.saveConfig();
sendMessage(sender, "&6We will %s", (newValue ? "&aautomatically team players" : "&cno longer auto team players"));
sendMessage(sender, "&6All players will need to re-login for the change to take place.");
return true;
}
}
@@ -0,0 +1,27 @@
package us.myles.ViaVersion.commands.defaultsubs;
import org.bukkit.command.CommandSender;
import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.api.command.ViaSubCommand;
public class DebugSubCmd extends ViaSubCommand {
@Override
public String name() {
return "debug";
}
@Override
public String description() {
return "Toggle debug mode";
}
@Override
public boolean execute(CommandSender sender, String[] args) {
ViaVersionPlugin plugin = (ViaVersionPlugin) ViaVersion.getInstance();
plugin.setDebug(!plugin.isDebug());
sendMessage(sender, "&6Debug mode is now %s", (plugin.isDebug() ? "&aenabled" : "&cdisabled"));
return true;
}
}
@@ -0,0 +1,28 @@
package us.myles.ViaVersion.commands.defaultsubs;
import io.netty.util.ResourceLeakDetector;
import org.bukkit.command.CommandSender;
import us.myles.ViaVersion.api.command.ViaSubCommand;
public class DisplayLeaksSubCmd extends ViaSubCommand {
@Override
public String name() {
return "displayleaks";
}
@Override
public String description() {
return "Try to hunt memory leaks!";
}
@Override
public boolean execute(CommandSender sender, String[] args) {
if (ResourceLeakDetector.getLevel() != ResourceLeakDetector.Level.ADVANCED)
ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.ADVANCED);
else
ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.DISABLED);
sendMessage(sender, "&6Leak detector is now %s", (ResourceLeakDetector.getLevel() == ResourceLeakDetector.Level.ADVANCED ? "&aenabled" : "&cdisabled"));
return true;
}
}
@@ -0,0 +1,30 @@
package us.myles.ViaVersion.commands.defaultsubs;
import org.bukkit.command.CommandSender;
import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.api.command.ViaSubCommand;
public class DontBugMeSubCmd extends ViaSubCommand {
@Override
public String name() {
return "dontbugme";
}
@Override
public String description() {
return "Toggle checking for updates";
}
@Override
public boolean execute(CommandSender sender, String[] args) {
ViaVersionPlugin plugin = (ViaVersionPlugin) ViaVersion.getInstance();
boolean newValue = !plugin.isCheckForUpdates();
plugin.getConfig().set("checkforupdates", newValue);
plugin.saveConfig();
sendMessage(sender, "&6We will %snotify you about updates.", (newValue ? "&a" : "&cnot "));
return true;
}
}
@@ -0,0 +1,27 @@
package us.myles.ViaVersion.commands.defaultsubs;
import org.bukkit.command.CommandSender;
import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.api.command.ViaSubCommand;
import us.myles.ViaVersion.commands.ViaCommandHandler;
public class HelpSubCmd extends ViaSubCommand {
@Override
public String name() {
return "help";
}
@Override
public String description() {
return "You are looking at it right now!";
}
@Override
public boolean execute(CommandSender sender, String[] args) {
ViaVersionPlugin plugin = (ViaVersionPlugin) ViaVersion.getInstance();
((ViaCommandHandler) plugin.getCommandHandler()).showHelp(sender);
return true;
}
}
@@ -0,0 +1,45 @@
package us.myles.ViaVersion.commands.defaultsubs;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.api.command.ViaSubCommand;
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
import java.util.*;
public class ListSubCmd extends ViaSubCommand {
@Override
public String name() {
return "list";
}
@Override
public String description() {
return "Shows lists of the versions from logged in players";
}
@Override
public String usage() {
return "list";
}
@Override
public boolean execute(CommandSender sender, String[] args) {
Map<Integer, Set<String>> playerVersions = new HashMap<>();
for (Player p : Bukkit.getOnlinePlayers()) {
int playerVersion = ViaVersion.getInstance().getPlayerVersion(p);
if (!playerVersions.containsKey(playerVersion))
playerVersions.put(playerVersion, new HashSet<String>());
playerVersions.get(playerVersion).add(p.getName());
}
Map<Integer, Set<String>> sorted = new TreeMap<>(playerVersions);
for (Map.Entry<Integer, Set<String>> entry : sorted.entrySet())
sendMessage(sender, "&8[&6%s&8]: &b%s", ProtocolVersion.getProtocol(entry.getKey()).getName(), entry.getValue());
sorted.clear();
return true;
}
}
@@ -0,0 +1,27 @@
package us.myles.ViaVersion.commands.defaultsubs;
import org.bukkit.command.CommandSender;
import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.api.command.ViaSubCommand;
public class ReloadSubCmd extends ViaSubCommand {
@Override
public String name() {
return "reload";
}
@Override
public String description() {
return "Reload the config from the disk";
}
@Override
public boolean execute(CommandSender sender, String[] args) {
ViaVersionPlugin plugin = (ViaVersionPlugin) ViaVersion.getInstance();
plugin.generateConfig();
sendMessage(sender, "&6Configuration successfully reloaded! Some features may need a restart.");
return true;
}
}
@@ -21,9 +21,9 @@ public class InformativeException extends Exception {
}
private String getSource(Class<?> sourceClazz) {
if(sourceClazz.isAnonymousClass()){
if (sourceClazz.isAnonymousClass()) {
return sourceClazz.getName() + " (Anonymous)";
}else{
} else {
return sourceClazz.getName();
}
}
@@ -56,6 +56,7 @@ public class ViaDecodeHandler extends ByteToMessageDecoder {
throw e;
}
}
// call minecraft decoder
try {
list.addAll(PipelineUtil.callDecode(this.minecraftDecoder, ctx, bytebuf));
@@ -49,10 +49,10 @@ public class ViaEncodeHandler extends MessageToByteEncoder {
bytebuf.clear();
try {
PacketWrapper wrapper = new PacketWrapper(id, oldPacket, info);
ProtocolInfo protInfo = info.get(ProtocolInfo.class);
protInfo.getPipeline().transform(Direction.OUTGOING, protInfo.getState(), wrapper);
wrapper.writeToBuffer(bytebuf);
PacketWrapper wrapper = new PacketWrapper(id, oldPacket, info);
ProtocolInfo protInfo = info.get(ProtocolInfo.class);
protInfo.getPipeline().transform(Direction.OUTGOING, protInfo.getState(), wrapper);
wrapper.writeToBuffer(bytebuf);
} catch (Exception e) {
bytebuf.clear();
throw e;
@@ -12,11 +12,11 @@ import java.lang.reflect.Method;
public class ViaVersionInitializer extends ChannelInitializer<SocketChannel> {
private final ChannelInitializer<SocketChannel> oldInit;
private final ChannelInitializer<SocketChannel> original;
private Method method;
public ViaVersionInitializer(ChannelInitializer<SocketChannel> oldInit) {
this.oldInit = oldInit;
this.original = oldInit;
try {
this.method = ChannelInitializer.class.getDeclaredMethod("initChannel", Channel.class);
this.method.setAccessible(true);
@@ -25,13 +25,17 @@ public class ViaVersionInitializer extends ChannelInitializer<SocketChannel> {
}
}
public ChannelInitializer<SocketChannel> getOriginal() {
return original;
}
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
UserConnection info = new UserConnection(socketChannel);
// init protocol
new ProtocolPipeline(info);
// Add originals
this.method.invoke(this.oldInit, socketChannel);
this.method.invoke(this.original, socketChannel);
// Add our transformers
ViaEncodeHandler encoder = new ViaEncodeHandler(info, (MessageToByteEncoder) socketChannel.pipeline().get("encoder"));
ViaDecodeHandler decoder = new ViaDecodeHandler(info, (ByteToMessageDecoder) socketChannel.pipeline().get("decoder"));
@@ -18,6 +18,8 @@ public class ItemRewriter {
private static final Map<String, Integer> POTION_NAME_TO_ID = new HashMap<>();
private static final Map<Integer, String> POTION_ID_TO_NAME = new HashMap<>();
private static final Map<Integer, Integer> POTION_INDEX = new HashMap<>();
static {
/* Entities */
registerEntity(1, "Item");
@@ -84,6 +86,7 @@ public class ItemRewriter {
registerEntity(200, "EnderCrystal");
/* Potions */
registerPotion(-1, "empty");
registerPotion(0, "water");
registerPotion(64, "mundane");
registerPotion(32, "thick");
@@ -147,8 +150,9 @@ public class ItemRewriter {
if (ENTTIY_NAME_TO_ID.containsKey(id.getValue()))
data = ENTTIY_NAME_TO_ID.get(id.getValue());
}
tag.remove("EntityTag");
}
item.setTag(null);
item.setTag(tag);
item.setData((short) data);
}
if (item.getId() == Material.POTION.getId()) {
@@ -160,10 +164,12 @@ public class ItemRewriter {
if (POTION_NAME_TO_ID.containsKey(potionName)) {
data = POTION_NAME_TO_ID.get(potionName);
}
tag.remove("Potion");
}
item.setTag(null);
item.setTag(tag);
item.setData((short) data);
}
//Splash potion
if (item.getId() == 438) {
CompoundTag tag = item.getTag();
int data = 0;
@@ -174,8 +180,9 @@ public class ItemRewriter {
if (POTION_NAME_TO_ID.containsKey(potionName)) {
data = POTION_NAME_TO_ID.get(potionName) + 8192;
}
tag.remove("Potion");
}
item.setTag(null);
item.setTag(tag);
item.setData((short) data);
}
}
@@ -238,12 +245,20 @@ public class ItemRewriter {
}
}
public static int getNewEffectID(int oldID) {
if (oldID >= 16384) {
oldID -= 8192;
}
return POTION_INDEX.containsKey(oldID) ? POTION_INDEX.get(oldID) : 0;
}
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_INDEX.put(id, POTION_ID_TO_NAME.size());
POTION_ID_TO_NAME.put(id, name);
POTION_NAME_TO_ID.put(name, id);
}
@@ -15,10 +15,7 @@ import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.ValueTransformer;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners.ArmorListener;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners.BlockListener;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners.CommandBlockListener;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners.PaperPatch;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners.*;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.packets.*;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker;
@@ -99,8 +96,9 @@ public class Protocol1_9TO1_8 extends Protocol {
ViaVersionPlugin plugin = (ViaVersionPlugin) Bukkit.getPluginManager().getPlugin("ViaVersion");
Bukkit.getPluginManager().registerEvents(new ArmorListener(plugin), plugin);
Bukkit.getPluginManager().registerEvents(new CommandBlockListener(plugin), plugin);
Bukkit.getPluginManager().registerEvents(new DeathListener(plugin), plugin);
Bukkit.getPluginManager().registerEvents(new BlockListener(plugin), plugin);
if(Bukkit.getVersion().toLowerCase().contains("paper")){
if (Bukkit.getVersion().toLowerCase().contains("paper")) {
plugin.getLogger().info("Enabling PaperSpigot patch: Fixes block placement.");
Bukkit.getPluginManager().registerEvents(new PaperPatch(), plugin);
}
@@ -20,7 +20,7 @@ public class BlockListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void placeBlock(BlockPlaceEvent e) {
if(plugin.isPorted(e.getPlayer())) {
if (plugin.isPorted(e.getPlayer())) {
UserConnection c = plugin.getConnection(e.getPlayer());
if (!c.get(ProtocolInfo.class).getPipeline().contains(Protocol1_9TO1_8.class)) return;
Block b = e.getBlockPlaced();
@@ -0,0 +1,65 @@
package us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners;
import lombok.RequiredArgsConstructor;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.PlayerDeathEvent;
import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
@RequiredArgsConstructor
public class DeathListener implements Listener {
private final ViaVersionPlugin plugin;
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void onDeath(PlayerDeathEvent e) {
Player p = e.getEntity();
if (plugin.isShowNewDeathMessages() && checkGamerule(p.getWorld()) && e.getDeathMessage() != null && checkPipeline(p)) {
sendPacket(p, e.getDeathMessage());
}
}
public boolean checkPipeline(Player p) {
UserConnection userConnection = plugin.getConnection(p);
return userConnection != null && userConnection.get(ProtocolInfo.class).getPipeline().contains(Protocol1_9TO1_8.class);
}
private UserConnection getUserConnection(Player p) {
return plugin.getConnection(p);
}
public boolean checkGamerule(World w) {
try {
return Boolean.parseBoolean(w.getGameRuleValue("showDeathMessage"));
} catch (Exception e) {
return false;
}
}
private void sendPacket(final Player p, final String msg) {
Bukkit.getScheduler().runTask(plugin, new Runnable() {
@Override
public void run() {
PacketWrapper wrapper = new PacketWrapper(0x2C, null, getUserConnection(p));
try {
wrapper.write(Type.VAR_INT, 2);
wrapper.write(Type.VAR_INT, p.getEntityId());
wrapper.write(Type.INT, p.getEntityId());
Protocol1_9TO1_8.FIX_JSON.write(wrapper, msg);
wrapper.send();
} catch (Exception e) {
e.printStackTrace();
wrapper.clearInputBuffer();
}
}
});
}
}
@@ -32,18 +32,18 @@ public class PaperPatch implements Listener {
} else {
if (e.getPlayer().getLocation().getBlock().getRelative(BlockFace.UP).equals(e.getBlock())) {
e.setCancelled(true);
}else{
} else {
// Within radius of block
if(Math.abs(diff.getX()) <= 0.8 && Math.abs(diff.getZ()) <= 0.8D){
if (Math.abs(diff.getX()) <= 0.8 && Math.abs(diff.getZ()) <= 0.8D) {
// Are they on the edge / shifting ish
if(diff.getY() <= 0.1D && diff.getY() >= -0.1D){
if (diff.getY() <= 0.1D && diff.getY() >= -0.1D) {
e.setCancelled(true);
return;
}
BlockFace relative = e.getBlockAgainst().getFace(e.getBlock());
// Are they towering up, (handles some latency)
if(relative == BlockFace.UP){
if(diff.getY() < 1D && diff.getY() >= 0D){
if (relative == BlockFace.UP) {
if (diff.getY() < 1D && diff.getY() >= 0D) {
e.setCancelled(true);
}
}
@@ -3,7 +3,6 @@ package us.myles.ViaVersion.protocols.protocol1_9to1_8.metadata;
import org.bukkit.entity.EntityType;
import org.bukkit.util.EulerAngle;
import org.bukkit.util.Vector;
import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
@@ -201,6 +201,16 @@ public class EntityPackets {
tracker.handleMetadata(entityID, metadataList);
}
});
// Cancel packet if list empty
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
List<Metadata> metadataList = wrapper.get(Protocol1_9TO1_8.METADATA_LIST, 0);
if (metadataList.size() == 0)
wrapper.cancel();
}
});
}
});
@@ -242,6 +252,24 @@ public class EntityPackets {
}
});
// Combat Event Packet
protocol.registerOutgoing(State.PLAY, 0x42, 0x2C, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); //Event id
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
if (wrapper.get(Type.VAR_INT, 0) == 2) { // entity dead
wrapper.passthrough(Type.VAR_INT); //Player id
wrapper.passthrough(Type.INT); //Entity id
Protocol1_9TO1_8.FIX_JSON.write(wrapper, wrapper.read(Type.STRING));
}
}
});
}
});
/* Packets which do not have any field remapping or handlers */
@@ -251,7 +279,6 @@ public class EntityPackets {
protocol.registerOutgoing(State.PLAY, 0x16, 0x27); // Entity Look Packet
protocol.registerOutgoing(State.PLAY, 0x14, 0x28); // Entity Packet
protocol.registerOutgoing(State.PLAY, 0x42, 0x2C); // Combat Event Packet
protocol.registerOutgoing(State.PLAY, 0x0A, 0x2F); // Use Bed Packet
protocol.registerOutgoing(State.PLAY, 0x1E, 0x31); // Remove Entity Effect Packet
@@ -150,6 +150,7 @@ public class PlayerPackets {
int entityID = wrapper.get(Type.INT, 0);
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
tracker.getClientEntityTypes().put(entityID, EntityType.PLAYER);
tracker.setEntityID(entityID);
}
});
map(Type.UNSIGNED_BYTE); // 1 - Player Gamemode
@@ -158,15 +159,6 @@ public class PlayerPackets {
map(Type.UNSIGNED_BYTE); // 4 - Max Players (Tab)
map(Type.STRING); // 5 - Level Type
map(Type.BOOLEAN); // 6 - Reduced Debug info
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int myID = wrapper.get(Type.INT, 0);
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
tracker.setEntityID(myID);
}
});
}
});
@@ -261,6 +253,22 @@ public class PlayerPackets {
}
});
// Respawn Packet
protocol.registerOutgoing(State.PLAY, 0x07, 0x33, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
// Client unloads chunks on respawn, take note
ClientChunks cc = wrapper.user().get(ClientChunks.class);
cc.getBulkChunks().clear();
cc.getLoadedChunks().clear();
}
});
}
});
/* Removed packets */
// Map Bulk
@@ -298,7 +306,6 @@ public class PlayerPackets {
protocol.registerOutgoing(State.PLAY, 0x39, 0x2B); // Player Abilities Packet
protocol.registerOutgoing(State.PLAY, 0x00, 0x1F); // Keep Alive Packet
protocol.registerOutgoing(State.PLAY, 0x48, 0x32); // Resource Pack Send Packet
protocol.registerOutgoing(State.PLAY, 0x07, 0x33); // Respawn Packet
protocol.registerOutgoing(State.PLAY, 0x43, 0x36); // Camera Packet
protocol.registerOutgoing(State.PLAY, 0x2B, 0x1E); // Change Game State Packet
@@ -1,7 +1,9 @@
package us.myles.ViaVersion.protocols.protocol1_9to1_8.packets;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketHandler;
@@ -10,11 +12,14 @@ import us.myles.ViaVersion.api.remapper.ValueCreator;
import us.myles.ViaVersion.api.remapper.ValueTransformer;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.ItemRewriter;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.metadata.MetadataRewriter;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.metadata.NewType;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker;
import us.myles.ViaVersion.util.EntityUtil;
import java.util.ArrayList;
import java.util.List;
public class SpawnPackets {
@@ -80,6 +85,34 @@ public class SpawnPackets {
wrapper.write(Type.SHORT, vZ);
}
});
// Handle potions
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
final int entityID = wrapper.get(Type.VAR_INT, 0);
final int data = wrapper.get(Type.INT, 0); // Data
int typeID = wrapper.get(Type.BYTE, 0);
if (EntityUtil.getTypeFromID(typeID, true) == EntityType.SPLASH_POTION) {
// Convert this to meta data, woo!
PacketWrapper metaPacket = wrapper.create(0x39, new ValueCreator() {
@Override
public void write(PacketWrapper wrapper) throws Exception {
wrapper.write(Type.VAR_INT, entityID);
List<Metadata> meta = new ArrayList<>();
Item item = new Item((short) Material.POTION.getId(), (byte) 1, (short) data, null);
ItemRewriter.toClient(item); // Rewrite so that it gets the right nbt
Metadata potion = new Metadata(5, NewType.Slot.getTypeID(), Type.ITEM, item);
meta.add(potion);
wrapper.write(Protocol1_9TO1_8.METADATA_LIST, meta);
}
});
metaPacket.send();
}
}
});
}
});
@@ -253,7 +286,24 @@ public class SpawnPackets {
map(Type.BYTE); // 5 - Yaw
map(Type.BYTE); // 6 - Pitch
map(Type.SHORT, Type.NOTHING); // Current Item is discontinued
handler(new PacketHandler() { //Handle discontinued player hand item
@Override
public void handle(PacketWrapper wrapper) throws Exception {
short item = wrapper.read(Type.SHORT);
// System.out.println(item);
if (item != 0) {
PacketWrapper packet = new PacketWrapper(0x3C, null, wrapper.user());
packet.write(Type.VAR_INT, wrapper.get(Type.VAR_INT, 0));
packet.write(Type.VAR_INT, 1);
packet.write(Type.ITEM, new Item(item, (byte) 1, (short) 0, null));
try {
packet.send();
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
map(Protocol1_9TO1_8.METADATA_LIST);
@@ -6,7 +6,6 @@ import org.spacehq.opennbt.tag.builtin.StringTag;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.api.minecraft.Position;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketHandler;
@@ -15,7 +14,9 @@ import us.myles.ViaVersion.api.remapper.ValueCreator;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.ArmorType;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.ItemRewriter;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.sounds.Effect;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.sounds.SoundEffect;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker;
@@ -40,21 +41,31 @@ public class WorldPackets {
@Override
public void registerMap() {
map(Type.INT); // 0 - Effect ID
// Everything else get's written through
map(Type.POSITION); // 1 - Position
map(Type.INT); // 2 - Data
map(Type.BOOLEAN); // 3 - Disable relative volume
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int id = wrapper.get(Type.INT, 0);
if (id >= 1000 && id < 2000 && id != 1005) { // Sound Effect
wrapper.cancel();
}
if (id == 1005) { // Fix jukebox
id = 1010;
}
id = Effect.getNewId(id);
wrapper.set(Type.INT, 0, id);
}
});
// Rewrite potion effect as it changed to use a dynamic registry
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int id = wrapper.get(Type.INT, 0);
if (id == 2002) {
int data = wrapper.get(Type.INT, 1);
int newData = ItemRewriter.getNewEffectID(data);
wrapper.set(Type.INT, 1, newData);
}
}
});
}
});
@@ -103,14 +114,9 @@ public class WorldPackets {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
ClientChunks clientChunks = wrapper.user().get(ClientChunks.class);
Chunk chunk = wrapper.passthrough(new ChunkType(clientChunks));
if (chunk.isUnloadPacket()) {
PacketWrapper unload = wrapper.create(0x1D);
unload.write(Type.INT, chunk.getX());
unload.write(Type.INT, chunk.getZ());
unload.send();
wrapper.cancel();
}
wrapper.passthrough(new ChunkType(clientChunks));
// eat any other data (Usually happens with unload packets)
wrapper.read(Type.REMAINING_BYTES);
}
});
}
@@ -167,11 +173,34 @@ public class WorldPackets {
});
}
});
// Block Change Packet
protocol.registerOutgoing(State.PLAY, 0x23, 0x0B, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.POSITION);
map(Type.VAR_INT);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Position pos = wrapper.user().get(EntityTracker.class).getCurrentlyDigging();
if (pos != null) {
if (wrapper.get(Type.POSITION, 0).equals(pos)) {
// cancel this one
if (wrapper.get(Type.VAR_INT, 0) != 0) {
wrapper.cancel();
wrapper.user().get(EntityTracker.class).setCurrentlyDigging(null);
}
}
}
}
});
}
});
/* Packets which do not have any field remapping or handlers */
protocol.registerOutgoing(State.PLAY, 0x25, 0x08); // Block Break Animation Packet
protocol.registerOutgoing(State.PLAY, 0x24, 0x0A); // Block Action Packet
protocol.registerOutgoing(State.PLAY, 0x23, 0x0B); // Block Change Packet
protocol.registerOutgoing(State.PLAY, 0x22, 0x10); // Multi Block Change Packet
protocol.registerOutgoing(State.PLAY, 0x27, 0x1C); // Explosion Packet
protocol.registerOutgoing(State.PLAY, 0x2A, 0x22); // Particle Packet
@@ -221,6 +250,26 @@ public class WorldPackets {
}
}
});
// Digging patch (prevents it glitching)
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
if(!ViaVersion.getConfig().isBlockBreakPatch()) return;
EntityTracker entityTracker = wrapper.user().get(EntityTracker.class);
final Position block = wrapper.get(Type.POSITION, 0);
int status = wrapper.get(Type.UNSIGNED_BYTE, 0);
if (status == 0) {
entityTracker.setCurrentlyDigging(null);
}
if (status == 1) {
entityTracker.setCurrentlyDigging(null);
}
if (status == 2) {
entityTracker.setCurrentlyDigging(block);
}
}
});
}
});
@@ -0,0 +1,44 @@
package us.myles.ViaVersion.protocols.protocol1_9to1_8.sounds;
import java.util.HashMap;
public class Effect {
private static HashMap<Integer, Integer> effects;
static {
effects = new HashMap<>();
addRewrite(1005, 1010); //Play music disc
addRewrite(1003, 1005); //Iron door open
addRewrite(1006, 1011); //Iron door close
addRewrite(1004, 1009); //Fizz / Fire extinguished
addRewrite(1007, 1015); //Ghast charge / warns
addRewrite(1008, 1016); //Ghast shoot
addRewrite(1009, 1016); //Ghast shoot (Lower volume according to wiki.vg)
addRewrite(1010, 1019); //Zombie attacks wood door
addRewrite(1011, 1020); //Zombie attacks metal door
addRewrite(1012, 1021); //Zombie breaks wood door
addRewrite(1014, 1024); //Wither shoot
addRewrite(1015, 1025); //Bat takeoff / aka herobrine
addRewrite(1016, 1026); //Zombie inject
addRewrite(1017, 1027); //Zombie villager converted
addRewrite(1020, 1029); //Anvil break
addRewrite(1021, 1030); //Anvil use
addRewrite(1022, 1031); //Anvil land
}
public static int getNewId(int id) {
if (!contains(id))
return id;
return effects.get(id);
}
public static boolean contains(int oldId) {
return effects.containsKey(oldId);
}
private static void addRewrite(int oldId, int newId) {
effects.put(oldId, newId);
}
}
@@ -260,9 +260,10 @@ public enum SoundEffect {
private final boolean breaksound;
private static HashMap<String, SoundEffect> effects;
static {
effects = new HashMap<String, SoundEffect>();
for(SoundEffect e : SoundEffect.values()) {
effects = new HashMap<>();
for (SoundEffect e : SoundEffect.values()) {
effects.put(e.getName(), e);
}
}
@@ -283,7 +284,7 @@ public enum SoundEffect {
public static SoundEffect getByName(String name) {
name = name.toLowerCase();
if(effects.containsKey(name))
if (effects.containsKey(name))
return effects.get(name);
return null;
}
@@ -22,6 +22,7 @@ import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.metadata.NewType;
import java.util.*;
import java.util.concurrent.TimeUnit;
@@ -43,6 +44,8 @@ public class EntityTracker extends StoredObject {
private Long lastPlaceBlock = -1L;
@Setter
private int entityID;
@Setter
private Position currentlyDigging = null;
private boolean teamExists = false;
public EntityTracker(UserConnection user) {
@@ -89,21 +92,21 @@ public class EntityTracker extends StoredObject {
}
public boolean interactedBlockRecently(int x, int y, int z) {
if(blockInteractions.size() == 0)
if (blockInteractions.size() == 0)
return false;
Iterator<Position> it = blockInteractions.asMap().keySet().iterator();
while(it.hasNext()) {
while (it.hasNext()) {
Position p = it.next();
if(p.getX() == x)
if(p.getY() == y)
if(p.getZ() == z)
if (p.getX() == x)
if (p.getY() == y)
if (p.getZ() == z)
return true;
}
return false;
}
public void addBlockInteraction(Position p) {
blockInteractions.put(p,Material.AIR);
blockInteractions.put(p, Material.AIR);
}
public void handleMetadata(int entityID, List<Metadata> metadataList) {
@@ -126,6 +129,12 @@ public class EntityTracker extends StoredObject {
}
}
if (type == EntityType.SKELETON) {
if ((getMetaByIndex(metadataList, 12)) == null) {
metadataList.add(new Metadata(12, NewType.Boolean.getTypeID(), Type.BOOLEAN, true));
}
}
if (type == EntityType.PLAYER) {
if (metadata.getId() == 0) {
// Byte
@@ -143,9 +152,12 @@ public class EntityTracker extends StoredObject {
}
}
if (type == EntityType.ARMOR_STAND && ((ViaVersionPlugin) ViaVersion.getInstance()).isHologramPatch()) {
if (metadata.getId() == 0) {
if (metadata.getId() == 0 && getMetaByIndex(metadataList, 10) != null) {
Metadata meta = getMetaByIndex(metadataList, 10); //Only happens if the armorstand is small
byte data = (byte) metadata.getValue();
if ((data & 0x20) == 0x20) {
// Check invisible | Check small | Check if custom name is empty | Check if custom name visible is true
if ((data & 0x20) == 0x20 && ((byte) meta.getValue() & 0x01) == 0x01
&& ((String) getMetaByIndex(metadataList, 2).getValue()).length() != 0 && (boolean) getMetaByIndex(metadataList, 3).getValue()) {
if (!knownHolograms.contains(entityID)) {
knownHolograms.add(entityID);
try {
@@ -200,6 +212,13 @@ public class EntityTracker extends StoredObject {
}
}
public Metadata getMetaByIndex(List<Metadata> list, int index) {
for (Metadata meta : list)
if (index == meta.getId())
return meta;
return null;
}
public void sendTeamPacket(boolean b) {
PacketWrapper wrapper = new PacketWrapper(0x41, null, getUser());
wrapper.write(Type.STRING, "viaversion"); // Use viaversion as name
@@ -14,6 +14,10 @@ public abstract class ListWrapper implements List {
public abstract void handleAdd(Object o);
public List getOriginalList() {
return list;
}
@Override
public synchronized int size() {
return this.list.size();
@@ -1,7 +1,6 @@
package us.myles.ViaVersion.util;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.ByteToMessageDecoder;
+5 -1
View File
@@ -22,6 +22,10 @@ bossbar-patch: true
bossbar-anti-flicker: false
# This will show the new effect indicator in the top-right corner for 1.9 players.
use-new-effect-indicator: true
# Show the new death messages for 1.9 on the death screen
use-new-deathmessages: false
# This will suppress the following error: 'Unable to get entity for ID: xxxx'
# This error message means one of you plugins is sending bad packets!
suppress-entityid-errors: false
suppress-entityid-errors: false
# Our patch for block breaking issue, if you have issues with block updates then disable this.
block-break-patch: true
+1 -2
View File
@@ -3,9 +3,8 @@ main: us.myles.ViaVersion.ViaVersionPlugin
author: _MylesC
version: ${project.version}
load: startup
loadbefore: [ProtocolLib, ProxyPipe]
loadbefore: [ProtocolLib, ProxyPipe, SpigotLib, PacketListenerApi]
commands:
viaversion:
description: Shows ViaVersion Version and more.
permission: viaversion.admin
aliases: [viaver]