mirror of
https://github.com/ViaVersion/ViaVersion.git
synced 2024-11-25 03:25:11 +01:00
Add ViaManager and abstraction / Add todo list
This commit is contained in:
parent
e7ab232b28
commit
05930ad791
14
TODOLIST
Normal file
14
TODOLIST
Normal file
@ -0,0 +1,14 @@
|
||||
Migrate EntityUtil to be cool
|
||||
Fix 1.9to1.8
|
||||
Fix 1.9.3to1.9.1/2
|
||||
Fix 1.9.1/2to1.9.3/4
|
||||
Fix snapshot to 1.10
|
||||
Fix BaseProtocol
|
||||
Fix BossBar to use Generics
|
||||
Register Listeners Properly
|
||||
Fix commands
|
||||
Handle injector errors
|
||||
Add new info to dump for platform
|
||||
Migrate Bukkit types to our own :D
|
||||
|
||||
Important: Create builder for ViaManager which allows supplying on the command exectutor, injector, platform :D
|
@ -1,71 +1,55 @@
|
||||
package us.myles.ViaVersion;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import us.myles.ViaVersion.api.Pair;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.ViaAPI;
|
||||
import us.myles.ViaVersion.api.ViaVersion;
|
||||
import us.myles.ViaVersion.api.ViaVersionAPI;
|
||||
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.platform.ViaPlatform;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
||||
import us.myles.ViaVersion.boss.ViaBossBar;
|
||||
import us.myles.ViaVersion.bukkit.BukkitCommandHandler;
|
||||
import us.myles.ViaVersion.bukkit.BukkitViaAPI;
|
||||
import us.myles.ViaVersion.bukkit.BukkitViaInjector;
|
||||
import us.myles.ViaVersion.classgenerator.ClassGenerator;
|
||||
import us.myles.ViaVersion.handlers.ViaVersionInitializer;
|
||||
import us.myles.ViaVersion.listeners.UpdateListener;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.update.UpdateUtil;
|
||||
import us.myles.ViaVersion.util.ConcurrentList;
|
||||
import us.myles.ViaVersion.util.ListWrapper;
|
||||
import us.myles.ViaVersion.util.ProtocolSupportUtil;
|
||||
import us.myles.ViaVersion.util.ReflectionUtil;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI, ViaPlatform {
|
||||
public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform {
|
||||
|
||||
private final Map<UUID, UserConnection> portedPlayers = new ConcurrentHashMap<>();
|
||||
private List<ChannelFuture> injectedFutures = new ArrayList<>();
|
||||
private List<Pair<Field, Object>> injectedLists = new ArrayList<>();
|
||||
private BukkitCommandHandler commandHandler;
|
||||
private boolean debug = false;
|
||||
private boolean compatSpigotBuild = false;
|
||||
private boolean spigot = true;
|
||||
private boolean lateBind = false;
|
||||
private boolean protocolSupport = false;
|
||||
@Getter
|
||||
private ViaConfig conf;
|
||||
@Getter
|
||||
private ViaAPI<Player> api = new BukkitViaAPI(this);
|
||||
|
||||
public ViaVersionPlugin() {
|
||||
// Config magic
|
||||
conf = new ViaConfig(this);
|
||||
// Init platform
|
||||
Via.init(this);
|
||||
// For compatibility
|
||||
ViaVersion.setInstance(this);
|
||||
|
||||
// Check if we're using protocol support too
|
||||
protocolSupport = Bukkit.getPluginManager().getPlugin("ProtocolSupport") != null;
|
||||
|
||||
if (protocolSupport) {
|
||||
getLogger().info("Hooking into ProtocolSupport, to prevent issues!");
|
||||
try {
|
||||
patchLists();
|
||||
BukkitViaInjector.patchLists();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -74,27 +58,6 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI, ViaPl
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
// Config magic
|
||||
conf = new ViaConfig(this);
|
||||
// Init platform
|
||||
Via.init(this);
|
||||
// For compatibility
|
||||
ViaVersion.setInstance(this);
|
||||
|
||||
// Handle reloads
|
||||
if (System.getProperty("ViaVersion") != null) {
|
||||
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(ChatColor.translateAlternateColorCodes('&', getConf().getReloadDisconnectMsg()));
|
||||
}
|
||||
|
||||
} else {
|
||||
getLogger().severe("ViaVersion is already loaded, this should work fine. If you get any console errors, try rebooting.");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Spigot detector
|
||||
try {
|
||||
Class.forName("org.spigotmc.SpigotConfig");
|
||||
@ -111,35 +74,19 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI, ViaPl
|
||||
|
||||
// Generate classes needed (only works if it's compat or ps)
|
||||
ClassGenerator.generate();
|
||||
lateBind = !isBinded();
|
||||
lateBind = !BukkitViaInjector.isBinded();
|
||||
|
||||
getLogger().info("ViaVersion " + getDescription().getVersion() + (compatSpigotBuild ? "compat" : "") + " is now loaded" + (lateBind ? ", waiting for boot. (late-bind)" : ", injecting!"));
|
||||
if (!lateBind)
|
||||
injectPacketHandler();
|
||||
if (!lateBind) {
|
||||
Via.getManager().init();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
if (lateBind)
|
||||
injectPacketHandler();
|
||||
if (conf.isCheckForUpdates())
|
||||
UpdateUtil.sendUpdateMessage();
|
||||
// Gather version :)
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
gatherProtocolVersion();
|
||||
// Check if there are any pipes to this version
|
||||
if (ProtocolRegistry.SERVER_PROTOCOL != -1) {
|
||||
getLogger().info("ViaVersion detected server version: " + ProtocolVersion.getProtocol(ProtocolRegistry.SERVER_PROTOCOL));
|
||||
if (!ProtocolRegistry.isWorkingPipe()) {
|
||||
getLogger().warning("ViaVersion does not have any compatible versions for this server version, please read our resource page carefully.");
|
||||
}
|
||||
}
|
||||
ProtocolRegistry.refreshVersions();
|
||||
}
|
||||
});
|
||||
|
||||
if (lateBind) {
|
||||
Via.getManager().init();
|
||||
}
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(new UpdateListener(), this);
|
||||
|
||||
@ -157,325 +104,18 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI, ViaPl
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
getLogger().info("ViaVersion is disabling, if this is a reload and you experience issues consider rebooting.");
|
||||
uninject();
|
||||
// TODO: Call ViaManager.destroy()
|
||||
}
|
||||
|
||||
public void gatherProtocolVersion() {
|
||||
try {
|
||||
Class<?> serverClazz = ReflectionUtil.nms("MinecraftServer");
|
||||
Object server = ReflectionUtil.invokeStatic(serverClazz, "getServer");
|
||||
Class<?> pingClazz = ReflectionUtil.nms("ServerPing");
|
||||
Object ping = null;
|
||||
// Search for ping method
|
||||
for (Field f : serverClazz.getDeclaredFields()) {
|
||||
if (f.getType() != null) {
|
||||
if (f.getType().getSimpleName().equals("ServerPing")) {
|
||||
f.setAccessible(true);
|
||||
ping = f.get(server);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ping != null) {
|
||||
Object serverData = null;
|
||||
for (Field f : pingClazz.getDeclaredFields()) {
|
||||
if (f.getType() != null) {
|
||||
if (f.getType().getSimpleName().endsWith("ServerData")) {
|
||||
f.setAccessible(true);
|
||||
serverData = f.get(ping);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (serverData != null) {
|
||||
int protocolVersion = -1;
|
||||
for (Field f : serverData.getClass().getDeclaredFields()) {
|
||||
if (f.getType() != null) {
|
||||
if (f.getType() == int.class) {
|
||||
f.setAccessible(true);
|
||||
protocolVersion = (int) f.get(serverData);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (protocolVersion != -1) {
|
||||
ProtocolRegistry.SERVER_PROTOCOL = protocolVersion;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// We couldn't work it out... We'll just use ping and hope for the best...
|
||||
}
|
||||
}
|
||||
|
||||
public Object getServerConnection() throws Exception {
|
||||
Class<?> serverClazz = ReflectionUtil.nms("MinecraftServer");
|
||||
Object server = ReflectionUtil.invokeStatic(serverClazz, "getServer");
|
||||
Object connection = null;
|
||||
for (Method m : serverClazz.getDeclaredMethods()) {
|
||||
if (m.getReturnType() != null) {
|
||||
if (m.getReturnType().getSimpleName().equals("ServerConnection")) {
|
||||
if (m.getParameterTypes().length == 0) {
|
||||
connection = m.invoke(server);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
|
||||
public void injectPacketHandler() {
|
||||
try {
|
||||
Object connection = getServerConnection();
|
||||
if (connection == null) {
|
||||
getLogger().warning("We failed to find the core component 'ServerConnection', please file an issue on our GitHub.");
|
||||
return;
|
||||
}
|
||||
for (Field field : connection.getClass().getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
final Object value = field.get(connection);
|
||||
if (value instanceof List) {
|
||||
// Inject the list
|
||||
List wrapper = new ListWrapper((List) value) {
|
||||
@Override
|
||||
public synchronized void handleAdd(Object o) {
|
||||
synchronized (this) {
|
||||
if (o instanceof ChannelFuture) {
|
||||
inject((ChannelFuture) o);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
injectedLists.add(new Pair<>(field, connection));
|
||||
field.set(connection, wrapper);
|
||||
// Iterate through current list
|
||||
synchronized (wrapper) {
|
||||
for (Object o : (List) value) {
|
||||
if (o instanceof ChannelFuture) {
|
||||
inject((ChannelFuture) o);
|
||||
} else {
|
||||
break; // not the right list.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
System.setProperty("ViaVersion", getDescription().getVersion());
|
||||
} catch (Exception e) {
|
||||
getLogger().severe("Unable to inject ViaVersion, please post these details on our GitHub and ensure you're using a compatible server version.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void patchLists() throws Exception {
|
||||
Object connection = getServerConnection();
|
||||
if (connection == null) {
|
||||
getLogger().warning("We failed to find the core component 'ServerConnection', please file an issue on our GitHub.");
|
||||
return;
|
||||
}
|
||||
for (Field field : connection.getClass().getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
final Object value = field.get(connection);
|
||||
if (value instanceof List) {
|
||||
if (!(value instanceof ConcurrentList)) {
|
||||
ConcurrentList list = new ConcurrentList();
|
||||
list.addAll((List) value);
|
||||
field.set(connection, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean isBinded() {
|
||||
try {
|
||||
Object connection = getServerConnection();
|
||||
if (connection == null) {
|
||||
return false;
|
||||
}
|
||||
for (Field field : connection.getClass().getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
final Object value = field.get(connection);
|
||||
if (value instanceof List) {
|
||||
// Inject the list
|
||||
synchronized (value) {
|
||||
for (Object o : (List) value) {
|
||||
if (o instanceof ChannelFuture) {
|
||||
return true;
|
||||
} else {
|
||||
break; // not the right list.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void inject(ChannelFuture future) {
|
||||
try {
|
||||
ChannelHandler bootstrapAcceptor = future.channel().pipeline().first();
|
||||
try {
|
||||
ChannelInitializer<SocketChannel> oldInit = ReflectionUtil.get(bootstrapAcceptor, "childHandler", ChannelInitializer.class);
|
||||
ChannelInitializer newInit = new ViaVersionInitializer(oldInit);
|
||||
|
||||
ReflectionUtil.set(bootstrapAcceptor, "childHandler", newInit);
|
||||
injectedFutures.add(future);
|
||||
} catch (NoSuchFieldException e) {
|
||||
// let's find who to blame!
|
||||
ClassLoader cl = bootstrapAcceptor.getClass().getClassLoader();
|
||||
if (cl.getClass().getName().equals("org.bukkit.plugin.java.PluginClassLoader")) {
|
||||
PluginDescriptionFile yaml = ReflectionUtil.get(cl, "description", PluginDescriptionFile.class);
|
||||
throw new Exception("Unable to inject, due to " + bootstrapAcceptor.getClass().getName() + ", try without the plugin " + yaml.getName() + "?");
|
||||
} else {
|
||||
throw new Exception("Unable to find core component 'childHandler', please check your plugins. issue: " + bootstrapAcceptor.getClass().getName());
|
||||
}
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
getLogger().severe("We failed to inject ViaVersion, have you got late-bind enabled with something else?");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
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 handler, reload won't work with connections, please reboot!");
|
||||
}
|
||||
}
|
||||
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 won't work with connections, please reboot!");
|
||||
}
|
||||
}
|
||||
|
||||
injectedLists.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPorted(Player player) {
|
||||
return isPorted(player.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPlayerVersion(@NonNull Player player) {
|
||||
if (!isPorted(player))
|
||||
return getExternalVersion(player);
|
||||
return portedPlayers.get(player.getUniqueId()).get(ProtocolInfo.class).getProtocolVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPlayerVersion(@NonNull UUID uuid) {
|
||||
if (!isPorted(uuid))
|
||||
return getExternalVersion(Bukkit.getPlayer(uuid));
|
||||
return portedPlayers.get(uuid).get(ProtocolInfo.class).getProtocolVersion();
|
||||
}
|
||||
|
||||
private int getExternalVersion(Player player) {
|
||||
if (!isProtocolSupport()) {
|
||||
return ProtocolRegistry.SERVER_PROTOCOL;
|
||||
} else {
|
||||
return ProtocolSupportUtil.getProtocolVersion(player);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPorted(UUID playerUUID) {
|
||||
return portedPlayers.containsKey(playerUUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return getDescription().getVersion();
|
||||
}
|
||||
|
||||
public UserConnection getConnection(UUID playerUUID) {
|
||||
return portedPlayers.get(playerUUID);
|
||||
}
|
||||
|
||||
public UserConnection getConnection(Player player) {
|
||||
return portedPlayers.get(player.getUniqueId());
|
||||
}
|
||||
|
||||
public void sendRawPacket(Player player, ByteBuf packet) throws IllegalArgumentException {
|
||||
sendRawPacket(player.getUniqueId(), packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendRawPacket(UUID uuid, ByteBuf packet) throws IllegalArgumentException {
|
||||
if (!isPorted(uuid)) throw new IllegalArgumentException("This player is not controlled by ViaVersion!");
|
||||
UserConnection ci = portedPlayers.get(uuid);
|
||||
ci.sendRawPacket(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossBar createBossBar(String title, BossColor color, BossStyle style) {
|
||||
return new ViaBossBar(title, 1F, color, style);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossBar createBossBar(String title, float health, BossColor color, BossStyle style) {
|
||||
return new ViaBossBar(title, health, color, style);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDebug() {
|
||||
return this.debug;
|
||||
}
|
||||
|
||||
public void setDebug(boolean value) {
|
||||
this.debug = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViaVersionCommand getCommandHandler() {
|
||||
return commandHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompatSpigotBuild() {
|
||||
return compatSpigotBuild;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SortedSet<Integer> getSupportedVersions() {
|
||||
SortedSet<Integer> outputSet = new TreeSet<>(ProtocolRegistry.getSupportedVersions());
|
||||
outputSet.removeAll(getConf().getBlockedProtocols());
|
||||
|
||||
return outputSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpigot() {
|
||||
return this.spigot;
|
||||
}
|
||||
|
||||
public void addPortedClient(UserConnection info) {
|
||||
portedPlayers.put(info.get(ProtocolInfo.class).getUuid(), info);
|
||||
}
|
||||
|
||||
public void removePortedClient(UUID clientID) {
|
||||
portedPlayers.remove(clientID);
|
||||
}
|
||||
|
||||
public void run(final Runnable runnable, boolean wait) {
|
||||
try {
|
||||
Future f = Bukkit.getScheduler().callSyncMethod(Bukkit.getPluginManager().getPlugin("ViaVersion"), new Callable<Boolean>() {
|
||||
@ -499,10 +139,6 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI, ViaPl
|
||||
return protocolSupport;
|
||||
}
|
||||
|
||||
public Map<UUID, UserConnection> getPortedPlayers() {
|
||||
return portedPlayers;
|
||||
}
|
||||
|
||||
public boolean handlePPS(UserConnection info) {
|
||||
// Max PPS Checker
|
||||
if (conf.getMaxPPS() > 0) {
|
||||
@ -576,4 +212,17 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI, ViaPl
|
||||
public boolean isPluginEnabled() {
|
||||
return Bukkit.getPluginManager().getPlugin("ViaVersion").isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReload() {
|
||||
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(ChatColor.translateAlternateColorCodes('&', getConf().getReloadDisconnectMsg()));
|
||||
}
|
||||
|
||||
} else {
|
||||
getLogger().severe("ViaVersion is already loaded, this should work fine. If you get any console errors, try rebooting.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,13 +7,12 @@ 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.protocol.ProtocolRegistry;
|
||||
import us.myles.ViaVersion.boss.ViaBossBar;
|
||||
|
||||
import java.util.SortedSet;
|
||||
import java.util.UUID;
|
||||
|
||||
@Deprecated
|
||||
public interface ViaVersionAPI {
|
||||
public interface ViaVersionAPI extends ViaAPI<Player> {
|
||||
/**
|
||||
* Is the player connection modified by ViaVersion?
|
||||
*
|
||||
|
@ -8,6 +8,7 @@ import us.myles.ViaVersion.api.boss.BossStyle;
|
||||
|
||||
@Getter
|
||||
public class ViaBossBar extends CommonBoss {
|
||||
// TODO: Fix to use generics
|
||||
|
||||
public ViaBossBar(String title, float health, BossColor color, BossStyle style) {
|
||||
super(title, health, color, style);
|
||||
|
@ -0,0 +1,127 @@
|
||||
package us.myles.ViaVersion.bukkit;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import us.myles.ViaVersion.ViaVersionPlugin;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.ViaAPI;
|
||||
import us.myles.ViaVersion.api.ViaVersionAPI;
|
||||
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.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.util.ProtocolSupportUtil;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class BukkitViaAPI implements ViaAPI<Player>, ViaVersionAPI {
|
||||
public ViaVersionPlugin plugin;
|
||||
|
||||
@Override
|
||||
public int getPlayerVersion(@NonNull Player player) {
|
||||
if (!isPorted(player))
|
||||
return getExternalVersion(player);
|
||||
return getPortedPlayers().get(player.getUniqueId()).get(ProtocolInfo.class).getProtocolVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPlayerVersion(@NonNull UUID uuid) {
|
||||
if (!isPorted(uuid))
|
||||
return getExternalVersion(Bukkit.getPlayer(uuid));
|
||||
return getPortedPlayers().get(uuid).get(ProtocolInfo.class).getProtocolVersion();
|
||||
}
|
||||
|
||||
private int getExternalVersion(Player player) {
|
||||
if (!isProtocolSupport()) {
|
||||
return ProtocolRegistry.SERVER_PROTOCOL;
|
||||
} else {
|
||||
return ProtocolSupportUtil.getProtocolVersion(player);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPorted(Player player) {
|
||||
return isPorted(player.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPorted(UUID playerUUID) {
|
||||
return getPortedPlayers().containsKey(playerUUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return plugin.getDescription().getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendRawPacket(UUID uuid, ByteBuf packet) throws IllegalArgumentException {
|
||||
if (!isPorted(uuid)) throw new IllegalArgumentException("This player is not controlled by ViaVersion!");
|
||||
UserConnection ci = getPortedPlayers().get(uuid);
|
||||
ci.sendRawPacket(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendRawPacket(Player player, ByteBuf packet) throws IllegalArgumentException {
|
||||
sendRawPacket(player.getUniqueId(), packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossBar createBossBar(String title, BossColor color, BossStyle style) {
|
||||
return new ViaBossBar(title, 1F, color, style);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossBar createBossBar(String title, float health, BossColor color, BossStyle style) {
|
||||
return new ViaBossBar(title, health, color, style);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDebug() {
|
||||
return Via.getManager().isDebug();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViaVersionCommand getCommandHandler() {
|
||||
return Via.getManager().getCommandHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SortedSet<Integer> getSupportedVersions() {
|
||||
SortedSet<Integer> outputSet = new TreeSet<>(ProtocolRegistry.getSupportedVersions());
|
||||
outputSet.removeAll(Via.getPlatform().getConf().getBlockedProtocols());
|
||||
|
||||
return outputSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompatSpigotBuild() {
|
||||
return plugin.isCompatSpigotBuild();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSpigot() {
|
||||
return plugin.isSpigot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProtocolSupport() {
|
||||
return plugin.isProtocolSupport();
|
||||
}
|
||||
|
||||
public Map<UUID, UserConnection> getPortedPlayers() {
|
||||
return Via.getManager().getPortedPlayers();
|
||||
}
|
||||
}
|
@ -0,0 +1,233 @@
|
||||
package us.myles.ViaVersion.bukkit;
|
||||
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import us.myles.ViaVersion.api.Pair;
|
||||
import us.myles.ViaVersion.api.platform.ViaInjector;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
|
||||
import us.myles.ViaVersion.handlers.ViaVersionInitializer;
|
||||
import us.myles.ViaVersion.util.ConcurrentList;
|
||||
import us.myles.ViaVersion.util.ListWrapper;
|
||||
import us.myles.ViaVersion.util.ReflectionUtil;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BukkitViaInjector implements ViaInjector {
|
||||
private List<ChannelFuture> injectedFutures = new ArrayList<>();
|
||||
private List<Pair<Field, Object>> injectedLists = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void inject() {
|
||||
try {
|
||||
Object connection = getServerConnection();
|
||||
if (connection == null) {
|
||||
getLogger().warning("We failed to find the core component 'ServerConnection', please file an issue on our GitHub.");
|
||||
return;
|
||||
}
|
||||
for (Field field : connection.getClass().getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
final Object value = field.get(connection);
|
||||
if (value instanceof List) {
|
||||
// Inject the list
|
||||
List wrapper = new ListWrapper((List) value) {
|
||||
@Override
|
||||
public synchronized void handleAdd(Object o) {
|
||||
synchronized (this) {
|
||||
if (o instanceof ChannelFuture) {
|
||||
injectChannelFuture((ChannelFuture) o);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
injectedLists.add(new Pair<>(field, connection));
|
||||
field.set(connection, wrapper);
|
||||
// Iterate through current list
|
||||
synchronized (wrapper) {
|
||||
for (Object o : (List) value) {
|
||||
if (o instanceof ChannelFuture) {
|
||||
injectChannelFuture((ChannelFuture) o);
|
||||
} else {
|
||||
break; // not the right list.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
getLogger().severe("Unable to inject ViaVersion, please post these details on our GitHub and ensure you're using a compatible server version.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void injectChannelFuture(ChannelFuture future) {
|
||||
try {
|
||||
ChannelHandler bootstrapAcceptor = future.channel().pipeline().first();
|
||||
try {
|
||||
ChannelInitializer<SocketChannel> oldInit = ReflectionUtil.get(bootstrapAcceptor, "childHandler", ChannelInitializer.class);
|
||||
ChannelInitializer newInit = new ViaVersionInitializer(oldInit);
|
||||
|
||||
ReflectionUtil.set(bootstrapAcceptor, "childHandler", newInit);
|
||||
injectedFutures.add(future);
|
||||
} catch (NoSuchFieldException e) {
|
||||
// let's find who to blame!
|
||||
ClassLoader cl = bootstrapAcceptor.getClass().getClassLoader();
|
||||
if (cl.getClass().getName().equals("org.bukkit.plugin.java.PluginClassLoader")) {
|
||||
PluginDescriptionFile yaml = ReflectionUtil.get(cl, "description", PluginDescriptionFile.class);
|
||||
throw new Exception("Unable to inject, due to " + bootstrapAcceptor.getClass().getName() + ", try without the plugin " + yaml.getName() + "?");
|
||||
} else {
|
||||
throw new Exception("Unable to find core component 'childHandler', please check your plugins. issue: " + bootstrapAcceptor.getClass().getName());
|
||||
}
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
getLogger().severe("We failed to inject ViaVersion, have you got late-bind enabled with something else?");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public 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 handler, reload won't work with connections, please reboot!");
|
||||
}
|
||||
}
|
||||
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 won't work with connections, please reboot!");
|
||||
}
|
||||
}
|
||||
|
||||
injectedLists.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getServerProtocolVersion() {
|
||||
try {
|
||||
Class<?> serverClazz = ReflectionUtil.nms("MinecraftServer");
|
||||
Object server = ReflectionUtil.invokeStatic(serverClazz, "getServer");
|
||||
Class<?> pingClazz = ReflectionUtil.nms("ServerPing");
|
||||
Object ping = null;
|
||||
// Search for ping method
|
||||
for (Field f : serverClazz.getDeclaredFields()) {
|
||||
if (f.getType() != null) {
|
||||
if (f.getType().getSimpleName().equals("ServerPing")) {
|
||||
f.setAccessible(true);
|
||||
ping = f.get(server);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ping != null) {
|
||||
Object serverData = null;
|
||||
for (Field f : pingClazz.getDeclaredFields()) {
|
||||
if (f.getType() != null) {
|
||||
if (f.getType().getSimpleName().endsWith("ServerData")) {
|
||||
f.setAccessible(true);
|
||||
serverData = f.get(ping);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (serverData != null) {
|
||||
int protocolVersion = -1;
|
||||
for (Field f : serverData.getClass().getDeclaredFields()) {
|
||||
if (f.getType() != null) {
|
||||
if (f.getType() == int.class) {
|
||||
f.setAccessible(true);
|
||||
protocolVersion = (int) f.get(serverData);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (protocolVersion != -1) {
|
||||
return protocolVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// We couldn't work it out... We'll just use ping and hope for the best...
|
||||
}
|
||||
}
|
||||
|
||||
public static Object getServerConnection() throws Exception {
|
||||
Class<?> serverClazz = ReflectionUtil.nms("MinecraftServer");
|
||||
Object server = ReflectionUtil.invokeStatic(serverClazz, "getServer");
|
||||
Object connection = null;
|
||||
for (Method m : serverClazz.getDeclaredMethods()) {
|
||||
if (m.getReturnType() != null) {
|
||||
if (m.getReturnType().getSimpleName().equals("ServerConnection")) {
|
||||
if (m.getParameterTypes().length == 0) {
|
||||
connection = m.invoke(server);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
|
||||
public static void patchLists() throws Exception {
|
||||
Object connection = getServerConnection();
|
||||
if (connection == null) {
|
||||
getLogger().warning("We failed to find the core component 'ServerConnection', please file an issue on our GitHub.");
|
||||
return;
|
||||
}
|
||||
for (Field field : connection.getClass().getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
final Object value = field.get(connection);
|
||||
if (value instanceof List) {
|
||||
if (!(value instanceof ConcurrentList)) {
|
||||
ConcurrentList list = new ConcurrentList();
|
||||
list.addAll((List) value);
|
||||
field.set(connection, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isBinded() {
|
||||
try {
|
||||
Object connection = getServerConnection();
|
||||
if (connection == null) {
|
||||
return false;
|
||||
}
|
||||
for (Field field : connection.getClass().getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
final Object value = field.get(connection);
|
||||
if (value instanceof List) {
|
||||
// Inject the list
|
||||
synchronized (value) {
|
||||
for (Object o : (List) value) {
|
||||
if (o instanceof ChannelFuture) {
|
||||
return true;
|
||||
} else {
|
||||
break; // not the right list.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -20,7 +20,6 @@ public class ViaDecodeHandler extends ByteToMessageDecoder {
|
||||
|
||||
private final ByteToMessageDecoder minecraftDecoder;
|
||||
private final UserConnection info;
|
||||
public static int PASSTHROUGH_ID = 1000;
|
||||
|
||||
public ViaDecodeHandler(UserConnection info, ByteToMessageDecoder minecraftDecoder) {
|
||||
this.info = info;
|
||||
|
@ -15,5 +15,4 @@ public class UpdateListener implements Listener {
|
||||
UpdateUtil.sendUpdateMessage(e.getPlayer().getUniqueId());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners;
|
||||
package us.myles.ViaVersion.listeners.protocol1_9to1_8;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.HumanEntity;
|
@ -1,4 +1,4 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners;
|
||||
package us.myles.ViaVersion.listeners.protocol1_9to1_8;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.EventHandler;
|
@ -1,4 +1,4 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners;
|
||||
package us.myles.ViaVersion.listeners.protocol1_9to1_8;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufOutputStream;
|
@ -1,4 +1,4 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners;
|
||||
package us.myles.ViaVersion.listeners.protocol1_9to1_8;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
@ -1,4 +1,4 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners;
|
||||
package us.myles.ViaVersion.listeners.protocol1_9to1_8;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
@ -1,4 +1,4 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners;
|
||||
package us.myles.ViaVersion.listeners.protocol1_9to1_8;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
@ -7,6 +7,7 @@
|
||||
<groupId>us.myles</groupId>
|
||||
<version>1.0.0-ALPHA-16w38a</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>viaversion-common</artifactId>
|
||||
|
84
common/src/main/java/us/myles/ViaVersion/ViaManager.java
Normal file
84
common/src/main/java/us/myles/ViaVersion/ViaManager.java
Normal file
@ -0,0 +1,84 @@
|
||||
package us.myles.ViaVersion;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import us.myles.ViaVersion.api.command.ViaVersionCommand;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.platform.ViaInjector;
|
||||
import us.myles.ViaVersion.api.platform.ViaPlatform;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.update.UpdateUtil;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Getter
|
||||
public class ViaManager {
|
||||
private ViaPlatform platform;
|
||||
private final Map<UUID, UserConnection> portedPlayers = new ConcurrentHashMap<>();
|
||||
@Setter
|
||||
private boolean debug = false;
|
||||
// Internals
|
||||
private ViaInjector injector;
|
||||
private ViaVersionCommand commandHandler;
|
||||
|
||||
public ViaManager(ViaPlatform platform) {
|
||||
this.platform = platform;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
if (System.getProperty("ViaVersion") != null) {
|
||||
// Reload?
|
||||
platform.onReload();
|
||||
}
|
||||
// Check for updates
|
||||
if (platform.getConf().isCheckForUpdates())
|
||||
UpdateUtil.sendUpdateMessage();
|
||||
// Inject
|
||||
// TODO: Get errors
|
||||
injector.inject();
|
||||
// Mark as injected
|
||||
System.setProperty("ViaVersion", getPlatform().getPluginVersion());
|
||||
// If successful
|
||||
// TODO: This method might run in onLoad, ensure sync tasks can still run if plugin not enabled.
|
||||
platform.runSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ProtocolRegistry.SERVER_PROTOCOL = injector.getServerProtocolVersion();
|
||||
|
||||
// Check if there are any pipes to this version
|
||||
if (ProtocolRegistry.SERVER_PROTOCOL != -1) {
|
||||
getPlatform().getLogger().info("ViaVersion detected server version: " + ProtocolVersion.getProtocol(ProtocolRegistry.SERVER_PROTOCOL));
|
||||
if (!ProtocolRegistry.isWorkingPipe()) {
|
||||
getPlatform().getLogger().warning("ViaVersion does not have any compatible versions for this server version, please read our resource page carefully.");
|
||||
}
|
||||
}
|
||||
ProtocolRegistry.refreshVersions();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
// Uninject
|
||||
getPlatform().getLogger().info("ViaVersion is disabling, if this is a reload and you experience issues consider rebooting.");
|
||||
injector.uninject();
|
||||
}
|
||||
|
||||
public void addPortedClient(UserConnection info) {
|
||||
portedPlayers.put(info.get(ProtocolInfo.class).getUuid(), info);
|
||||
}
|
||||
|
||||
public void removePortedClient(UUID clientID) {
|
||||
portedPlayers.remove(clientID);
|
||||
}
|
||||
|
||||
public UserConnection getConnection(UUID playerUUID) {
|
||||
return portedPlayers.get(playerUUID);
|
||||
}
|
||||
|
||||
}
|
@ -12,7 +12,6 @@ import us.myles.ViaVersion.api.remapper.ValueCreator;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.api.type.TypeConverter;
|
||||
import us.myles.ViaVersion.exception.InformativeException;
|
||||
import us.myles.ViaVersion.handlers.ViaDecodeHandler;
|
||||
import us.myles.ViaVersion.packets.Direction;
|
||||
import us.myles.ViaVersion.packets.State;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
@ -25,6 +24,8 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class PacketWrapper {
|
||||
public static int PASSTHROUGH_ID = 1000;
|
||||
|
||||
private final ByteBuf inputBuffer;
|
||||
private final UserConnection userConnection;
|
||||
private boolean send = true;
|
||||
@ -461,7 +462,7 @@ public class PacketWrapper {
|
||||
public void sendToServer() throws Exception {
|
||||
if (!isCancelled()) {
|
||||
ByteBuf output = inputBuffer == null ? Unpooled.buffer() : inputBuffer.alloc().buffer();
|
||||
Type.VAR_INT.write(output, ViaDecodeHandler.PASSTHROUGH_ID); // Pass through
|
||||
Type.VAR_INT.write(output, PacketWrapper.PASSTHROUGH_ID); // Pass through
|
||||
|
||||
writeToBuffer(output);
|
||||
|
||||
|
@ -2,14 +2,23 @@ package us.myles.ViaVersion.api;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import us.myles.ViaVersion.ViaManager;
|
||||
import us.myles.ViaVersion.api.platform.ViaPlatform;
|
||||
|
||||
public class Via {
|
||||
@Getter
|
||||
private static ViaPlatform platform;
|
||||
@Getter
|
||||
private static ViaManager manager;
|
||||
|
||||
public static void init(ViaPlatform platform) {
|
||||
Validate.isTrue(platform == null, "Platform is already set");
|
||||
Via.platform = platform;
|
||||
Via.manager = new ViaManager(platform);
|
||||
}
|
||||
|
||||
public static ViaAPI getAPI() {
|
||||
Validate.isTrue(platform != null, "ViaVersion has not loaded the Platform");
|
||||
return Via.platform.getApi();
|
||||
}
|
||||
}
|
||||
|
100
common/src/main/java/us/myles/ViaVersion/api/ViaAPI.java
Normal file
100
common/src/main/java/us/myles/ViaVersion/api/ViaAPI.java
Normal file
@ -0,0 +1,100 @@
|
||||
package us.myles.ViaVersion.api;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
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.protocol.ProtocolRegistry;
|
||||
|
||||
import java.util.SortedSet;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Represents the ViaAPI
|
||||
*
|
||||
* @param <T> The player type for the specific platform, for bukkit it's {@code ViaAPI<Player>}
|
||||
*/
|
||||
public interface ViaAPI<T> {
|
||||
/**
|
||||
* Get protocol number from a player
|
||||
* Will also retrieve version from ProtocolSupport if it's being used.
|
||||
*
|
||||
* @param player Platform player object, eg. Bukkit this is Player
|
||||
* @return Protocol ID, For example (47=1.8-1.8.8, 107=1.9, 108=1.9.1)
|
||||
*/
|
||||
int getPlayerVersion(T player);
|
||||
|
||||
/**
|
||||
* Get protocol number from a player
|
||||
*
|
||||
* @param uuid UUID of a player
|
||||
* @return Protocol ID, For example (47=1.8-1.8.8, 107=1.9, 108=1.9.1)
|
||||
*/
|
||||
int getPlayerVersion(UUID uuid);
|
||||
|
||||
/**
|
||||
* Is player using 1.9?
|
||||
*
|
||||
* @param playerUUID UUID of a player
|
||||
* @return True if the client is on 1.9
|
||||
* @deprecated As of 0.9.9, because all players are ported use {@link #getPlayerVersion(UUID)}
|
||||
*/
|
||||
@Deprecated
|
||||
boolean isPorted(UUID playerUUID);
|
||||
|
||||
/**
|
||||
* Get the version of the plugin
|
||||
*
|
||||
* @return Plugin version
|
||||
*/
|
||||
String getVersion();
|
||||
|
||||
/**
|
||||
* Send a raw packet to the player (Use new IDs)
|
||||
*
|
||||
* @param player Platform player object, eg. Bukkit this is Player
|
||||
* @param packet The packet, you need a VarInt ID then the packet contents.
|
||||
* @throws IllegalArgumentException If not on 1.9 throws IllegalArg
|
||||
*/
|
||||
void sendRawPacket(T player, ByteBuf packet) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Send a raw packet to the player (Use new IDs)
|
||||
*
|
||||
* @param uuid The uuid from the player to send packet
|
||||
* @param packet The packet, you need a VarInt ID then the packet contents.
|
||||
* @throws IllegalArgumentException If not on 1.9 throws IllegalArg
|
||||
*/
|
||||
void sendRawPacket(UUID uuid, ByteBuf packet) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Create a new bossbar instance
|
||||
*
|
||||
* @param title The title
|
||||
* @param color The color
|
||||
* @param style The style
|
||||
* @return BossBar instance
|
||||
*/
|
||||
BossBar createBossBar(String title, BossColor color, BossStyle style);
|
||||
|
||||
/**
|
||||
* Create a new bossbar instance
|
||||
*
|
||||
* @param title The title
|
||||
* @param health Number between 0 and 1
|
||||
* @param color The color
|
||||
* @param style The style
|
||||
* @return BossBar instance
|
||||
*/
|
||||
BossBar createBossBar(String title, float health, BossColor color, BossStyle style);
|
||||
|
||||
/**
|
||||
* Get the supported protocol versions
|
||||
* This method removes any blocked protocol versions.
|
||||
*
|
||||
* @return a list of protocol versions
|
||||
* @see ProtocolRegistry#getSupportedVersions() for full list.
|
||||
*/
|
||||
SortedSet<Integer> getSupportedVersions();
|
||||
}
|
@ -7,7 +7,6 @@ import io.netty.channel.socket.SocketChannel;
|
||||
import lombok.Data;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.ViaVersion;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
|
||||
import java.util.Map;
|
||||
|
@ -0,0 +1,9 @@
|
||||
package us.myles.ViaVersion.api.platform;
|
||||
|
||||
public interface ViaInjector {
|
||||
public void inject();
|
||||
|
||||
public void uninject();
|
||||
|
||||
public int getServerProtocolVersion();
|
||||
}
|
@ -1,9 +1,17 @@
|
||||
package us.myles.ViaVersion.api.platform;
|
||||
|
||||
import us.myles.ViaVersion.api.ViaAPI;
|
||||
import us.myles.ViaVersion.api.ViaVersionConfig;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public interface ViaPlatform {
|
||||
/**
|
||||
* ViaPlatform represents a platform ViaVersion runs on
|
||||
*
|
||||
* @param <T> - The player type for the platform, used for API related methods
|
||||
*/
|
||||
public interface ViaPlatform<T> {
|
||||
public Logger getLogger();
|
||||
|
||||
public String getPlatformName();
|
||||
@ -19,4 +27,10 @@ public interface ViaPlatform {
|
||||
public boolean kickPlayer(UUID uuid, String message);
|
||||
|
||||
public boolean isPluginEnabled();
|
||||
|
||||
public ViaAPI<T> getApi();
|
||||
|
||||
public ViaVersionConfig getConf();
|
||||
|
||||
public void onReload();
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package us.myles.ViaVersion.api.protocol;
|
||||
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.ViaVersion;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.platform.ViaPlatform;
|
||||
import us.myles.ViaVersion.packets.Direction;
|
||||
@ -74,7 +74,7 @@ public class ProtocolPipeline extends Protocol {
|
||||
|
||||
super.transform(direction, state, packetWrapper);
|
||||
|
||||
if (ViaVersion.getInstance().isDebug()) {
|
||||
if (Via.getManager().isDebug()) {
|
||||
// Debug packet
|
||||
String packet = "UNKNOWN";
|
||||
|
||||
@ -109,7 +109,7 @@ public class ProtocolPipeline extends Protocol {
|
||||
}
|
||||
}
|
||||
String name = packet + "[" + userConnection.get(ProtocolInfo.class).getProtocolVersion() + "]";
|
||||
ViaPlatform platform = ViaVersion.getPlatform();
|
||||
ViaPlatform platform = Via.getPlatform();
|
||||
|
||||
String actualUsername = packetWrapper.user().get(ProtocolInfo.class).getUsername();
|
||||
String username = actualUsername != null ? actualUsername + " " : "";
|
||||
|
@ -3,7 +3,7 @@ package us.myles.ViaVersion.api.protocol;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import us.myles.ViaVersion.api.Pair;
|
||||
import us.myles.ViaVersion.api.ViaVersion;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.protocols.base.BaseProtocol;
|
||||
import us.myles.ViaVersion.protocols.protocol1_10to1_9_3.Protocol1_10To1_9_3_4;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.Protocol1_9_1_2TO1_9_3_4;
|
||||
@ -61,7 +61,7 @@ public class ProtocolRegistry {
|
||||
registryMap.get(version).put(output, protocol);
|
||||
}
|
||||
|
||||
if (ViaVersion.getPlatform().isPluginEnabled()) {
|
||||
if (Via.getPlatform().isPluginEnabled()) {
|
||||
protocol.registerListeners();
|
||||
refreshVersions();
|
||||
} else {
|
||||
|
@ -15,8 +15,8 @@ import us.myles.ViaVersion.api.remapper.ValueTransformer;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.api.type.types.version.Metadata1_8Type;
|
||||
import us.myles.ViaVersion.api.type.types.version.MetadataList1_8Type;
|
||||
import us.myles.ViaVersion.listeners.protocol1_9to1_8.*;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
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.*;
|
||||
|
||||
|
@ -3,7 +3,7 @@ package us.myles.ViaVersion.protocols.protocol1_9to1_8.storage;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.ViaVersion;
|
||||
import us.myles.ViaVersion.api.data.StoredObject;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
@ -24,6 +24,7 @@ public class ClientChunks extends StoredObject {
|
||||
|
||||
static {
|
||||
try {
|
||||
// TODO: Abstract this ?
|
||||
mapChunkBulkRef = new ReflectionUtil.ClassReflection(ReflectionUtil.nms("PacketPlayOutMapChunkBulk"));
|
||||
mapChunkRef = new ReflectionUtil.ClassReflection(ReflectionUtil.nms("PacketPlayOutMapChunk"));
|
||||
if (ViaVersion.getInstance().isSpigot()) {
|
||||
@ -31,7 +32,7 @@ public class ClientChunks extends StoredObject {
|
||||
worldRef = ReflectionUtil.nms("World");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Failed to initialise chunks reflection", e);
|
||||
Via.getPlatform().getLogger().log(Level.WARNING, "Failed to initialise chunks reflection", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,7 +84,7 @@ public class ClientChunks extends StoredObject {
|
||||
list.add(chunkPacket);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Failed to transform chunks bulk", e);
|
||||
Via.getPlatform().getLogger().log(Level.WARNING, "Failed to transform chunks bulk", e);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package us.myles.ViaVersion.protocols.protocol1_9to1_8.types;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import org.bukkit.Bukkit;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.ViaVersion;
|
||||
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
|
||||
import us.myles.ViaVersion.api.type.PartialType;
|
||||
@ -134,7 +134,7 @@ public class ChunkType extends PartialType<Chunk, ClientChunks> {
|
||||
|
||||
// Check remaining bytes
|
||||
if (bytesLeft > 0) {
|
||||
Bukkit.getLogger().log(Level.WARNING, bytesLeft + " Bytes left after reading chunks! (" + groundUp + ")");
|
||||
Via.getPlatform().getLogger().log(Level.WARNING, bytesLeft + " Bytes left after reading chunks! (" + groundUp + ")");
|
||||
}
|
||||
|
||||
// Return chunks
|
||||
|
@ -1,6 +1,5 @@
|
||||
package us.myles.ViaVersion.protocols.protocolsnapshotto1_10;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.spacehq.opennbt.tag.builtin.CompoundTag;
|
||||
import org.spacehq.opennbt.tag.builtin.StringTag;
|
||||
import us.myles.ViaVersion.api.minecraft.item.Item;
|
||||
@ -31,7 +30,7 @@ public class ItemRewriter {
|
||||
}
|
||||
|
||||
private static boolean hasEntityTag(Item item) {
|
||||
if (item != null && item.getId() == Material.MONSTER_EGG.getId()) {
|
||||
if (item != null && item.getId() == 383) { // Monster Egg
|
||||
CompoundTag tag = item.getTag();
|
||||
if (tag != null && tag.contains("EntityTag") && tag.get("EntityTag") instanceof CompoundTag) {
|
||||
if (((CompoundTag) tag.get("EntityTag")).get("id") instanceof StringTag) {
|
||||
|
@ -5,7 +5,7 @@ import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import us.myles.ViaVersion.api.ViaVersion;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
@ -24,16 +24,16 @@ public class UpdateUtil {
|
||||
private final static Gson gson = new GsonBuilder().create();
|
||||
|
||||
public static void sendUpdateMessage(final UUID uuid) {
|
||||
ViaVersion.getPlatform().runAsync(new Runnable() {
|
||||
Via.getPlatform().runAsync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final String message = getUpdateMessage(false);
|
||||
if (message != null) {
|
||||
ViaVersion.getPlatform().runSync(
|
||||
Via.getPlatform().runSync(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ViaVersion.getPlatform().sendMessage(uuid, PREFIX + message);
|
||||
Via.getPlatform().sendMessage(uuid, PREFIX + message);
|
||||
}
|
||||
}
|
||||
);
|
||||
@ -43,16 +43,16 @@ public class UpdateUtil {
|
||||
}
|
||||
|
||||
public static void sendUpdateMessage() {
|
||||
ViaVersion.getPlatform().runAsync(new Runnable() {
|
||||
Via.getPlatform().runAsync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final String message = getUpdateMessage(true);
|
||||
if (message != null) {
|
||||
ViaVersion.getPlatform().runSync(
|
||||
Via.getPlatform().runSync(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ViaVersion.getPlatform().getLogger().warning(message);
|
||||
Via.getPlatform().getLogger().warning(message);
|
||||
}
|
||||
}
|
||||
);
|
||||
@ -62,7 +62,7 @@ public class UpdateUtil {
|
||||
}
|
||||
|
||||
private static String getUpdateMessage(boolean console) {
|
||||
if (ViaVersion.getInstance().getVersion().equals("${project.version}")) {
|
||||
if (Via.getPlatform().getPluginVersion().equals("${project.version}")) {
|
||||
return "You are using a debug/custom version, consider updating.";
|
||||
}
|
||||
String newestString = getNewestVersion();
|
||||
@ -75,7 +75,7 @@ public class UpdateUtil {
|
||||
}
|
||||
Version current;
|
||||
try {
|
||||
current = new Version(ViaVersion.getInstance().getVersion());
|
||||
current = new Version(Via.getPlatform().getPluginVersion());
|
||||
} catch (IllegalArgumentException e) {
|
||||
return "You are using a custom version, consider updating.";
|
||||
}
|
||||
@ -97,7 +97,7 @@ public class UpdateUtil {
|
||||
URL url = new URL(URL + PLUGIN + LATEST_VERSION + "?" + System.currentTimeMillis());
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setUseCaches(true);
|
||||
connection.addRequestProperty("User-Agent", "ViaVersion " + ViaVersion.getInstance().getVersion());
|
||||
connection.addRequestProperty("User-Agent", "ViaVersion " + Via.getPlatform().getPluginVersion());
|
||||
connection.setDoOutput(true);
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
String input;
|
||||
|
@ -6,7 +6,6 @@ import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
public abstract class ListWrapper implements List {
|
||||
public final Object lock = new Object();
|
||||
private final List list;
|
||||
|
||||
public ListWrapper(List inputList) {
|
||||
|
Loading…
Reference in New Issue
Block a user