Platform and Sponge changes

This commit is contained in:
creeper123123321 2018-06-14 15:21:49 -03:00
parent 05617a95b7
commit f12a210665
No known key found for this signature in database
GPG Key ID: 0AC57D54786721D1
9 changed files with 211 additions and 84 deletions

View File

@ -1,10 +1,11 @@
package us.myles.ViaVersion.bukkit.platform;
import lombok.AllArgsConstructor;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.scheduler.BukkitTask;
import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
@ -21,43 +22,60 @@ import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BulkChunkTransla
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.HandItemProvider;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
@AllArgsConstructor
public class BukkitViaLoader implements ViaPlatformLoader {
private ViaVersionPlugin plugin;
private Set<Listener> listeners = new HashSet<>();
private Set<BukkitTask> tasks = new HashSet<>();
public BukkitViaLoader(ViaVersionPlugin plugin) {
this.plugin = plugin;
}
public void registerListener(Listener listener) {
Bukkit.getPluginManager().registerEvents(storeListener(listener), plugin);
}
public <T extends Listener> T storeListener(T listener) {
listeners.add(listener);
return listener;
}
@Override
public void load() {
// Update Listener
Bukkit.getPluginManager().registerEvents(new UpdateListener(), plugin);
registerListener(new UpdateListener());
/* Base Protocol */
final ViaVersionPlugin plugin = (ViaVersionPlugin) Bukkit.getPluginManager().getPlugin("ViaVersion");
Bukkit.getPluginManager().registerEvents(new Listener() {
registerListener(new Listener() {
@EventHandler
public void onPlayerQuit(PlayerQuitEvent e) {
Via.getManager().removePortedClient(e.getPlayer().getUniqueId());
}
}, plugin);
});
/* 1.9 client to 1.8 server */
new ArmorListener(plugin).register();
new DeathListener(plugin).register();
new BlockListener(plugin).register();
storeListener(new ArmorListener(plugin)).register();
storeListener(new DeathListener(plugin)).register();
storeListener(new BlockListener(plugin)).register();
if (Bukkit.getVersion().toLowerCase().contains("paper")
|| Bukkit.getVersion().toLowerCase().contains("taco")
|| Bukkit.getVersion().toLowerCase().contains("torch")) {
plugin.getLogger().info("Enabling PaperSpigot/TacoSpigot/Torch patch: Fixes block placement.");
new PaperPatch(plugin).register();
storeListener(new PaperPatch(plugin)).register();
}
if (plugin.getConf().isItemCache()) {
new HandItemCache().runTaskTimerAsynchronously(plugin, 2L, 2L); // Updates player's items :)
tasks.add(new HandItemCache().runTaskTimerAsynchronously(plugin, 2L, 2L)); // Updates player's items :)
HandItemCache.CACHE = true;
}
@ -95,4 +113,17 @@ public class BukkitViaLoader implements ViaPlatformLoader {
});
}
@Override
public void unload() {
// todo restore providers
for (Listener listener : listeners) {
HandlerList.unregisterAll(listener);
}
listeners.clear();
for (BukkitTask task : tasks) {
task.cancel();
}
tasks.clear();
}
}

View File

@ -1,7 +1,8 @@
package us.myles.ViaVersion.bungee.platform;
import lombok.AllArgsConstructor;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.api.scheduler.ScheduledTask;
import us.myles.ViaVersion.BungeePlugin;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.platform.ViaPlatformLoader;
@ -19,20 +20,33 @@ import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BossBarProvider;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.EntityIdProvider;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@AllArgsConstructor
public class BungeeViaLoader implements ViaPlatformLoader {
private BungeePlugin plugin;
private Set<Listener> listeners = new HashSet<>();
private Set<ScheduledTask> tasks = new HashSet<>();
public BungeeViaLoader(BungeePlugin plugin) {
this.plugin = plugin;
}
private void registerListener(Listener listener) {
listeners.add(listener);
ProxyServer.getInstance().getPluginManager().registerListener(plugin, listener);
}
@Override
public void load() {
// Listeners
ProxyServer.getInstance().getPluginManager().registerListener(plugin, plugin);
ProxyServer.getInstance().getPluginManager().registerListener(plugin, new UpdateListener());
ProxyServer.getInstance().getPluginManager().registerListener(plugin, new BungeeServerHandler());
ProxyServer.getInstance().getPluginManager().registerListener(plugin, new MainHandPatch());
ProxyServer.getInstance().getPluginManager().registerListener(plugin, new ElytraPatch());
registerListener(plugin);
registerListener(new UpdateListener());
registerListener(new BungeeServerHandler());
registerListener(new MainHandPatch());
registerListener(new ElytraPatch());
// Providers
Via.getManager().getProviders().use(MovementTransmitterProvider.class, new BungeeMovementTransmitter());
@ -41,7 +55,24 @@ public class BungeeViaLoader implements ViaPlatformLoader {
Via.getManager().getProviders().use(BossBarProvider.class, new BungeeBossBarProvider());
if (plugin.getConf().getBungeePingInterval() > 0) {
plugin.getProxy().getScheduler().schedule(plugin, new ProtocolDetectorService(plugin), 0, plugin.getConf().getBungeePingInterval(), TimeUnit.SECONDS);
tasks.add(plugin.getProxy().getScheduler().schedule(
plugin,
new ProtocolDetectorService(plugin),
0, plugin.getConf().getBungeePingInterval(),
TimeUnit.SECONDS
));
}
}
@Override
public void unload() {
for (Listener listener : listeners) {
ProxyServer.getInstance().getPluginManager().unregisterListener(listener);
}
listeners.clear();
for (ScheduledTask task : tasks) {
task.cancel();
}
tasks.clear();
}
}

View File

@ -102,6 +102,9 @@ public class ViaManager {
getPlatform().getLogger().severe("ViaVersion failed to uninject:");
e.printStackTrace();
}
// Unload
loader.unload();
}
public void addPortedClient(UserConnection info) {

View File

@ -5,4 +5,6 @@ public interface ViaPlatformLoader {
* Initialise the loading for a platform, eg. registering listeners / providers / events etc.
*/
void load();
void unload();
}

View File

@ -2,14 +2,19 @@ package us.myles.ViaVersion;
import com.google.gson.JsonObject;
import com.google.inject.Inject;
import lombok.Getter;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.chat.ComponentSerializer;
import org.spongepowered.api.Game;
import org.spongepowered.api.config.DefaultConfig;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.game.state.GameAboutToStartServerEvent;
import org.spongepowered.api.event.game.state.GameInitializationEvent;
import org.spongepowered.api.event.game.state.GameStoppingServerEvent;
import org.spongepowered.api.plugin.Plugin;
import org.spongepowered.api.plugin.PluginContainer;
import org.spongepowered.api.scheduler.SpongeExecutorService;
import org.spongepowered.api.scheduler.Task;
import org.spongepowered.api.text.serializer.TextSerializers;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.ViaAPI;
@ -37,8 +42,7 @@ import java.util.logging.Logger;
name = "ViaVersion",
version = VersionInfo.VERSION,
authors = {"_MylesC", "Matsv"},
description = "Allow newer Minecraft versions to connect to an older server version.",
dependencies = {}
description = "Allow newer Minecraft versions to connect to an older server version."
)
public class SpongePlugin implements ViaPlatform {
@Inject
@ -52,22 +56,20 @@ public class SpongePlugin implements ViaPlatform {
private File defaultConfig;
private SpongeViaAPI api = new SpongeViaAPI();
private SpongeExecutorService asyncExecutor;
private SpongeExecutorService syncExecutor;
private SpongeConfigAPI conf;
@Getter
private Logger logger;
@Listener
public void onServerStart(GameAboutToStartServerEvent event) {
public void onGameStart(GameInitializationEvent event) {
// Setup Logger
logger = new LoggerWrapper(container.getLogger());
// Setup Plugin
conf = new SpongeConfigAPI(container, defaultConfig.getParentFile());
syncExecutor = game.getScheduler().createSyncExecutor(this);
asyncExecutor = game.getScheduler().createAsyncExecutor(this);
SpongeCommandHandler commandHandler = new SpongeCommandHandler();
game.getCommandManager().register(this, commandHandler, Arrays.asList("viaversion", "viaver", "vvsponge"));
getLogger().info("ViaVersion " + getPluginVersion() + " is now loaded, injecting!");
game.getCommandManager().register(this, commandHandler, "viaversion", "viaver", "vvsponge");
getLogger().info("ViaVersion " + getPluginVersion() + " is now loaded!");
// Init platform
Via.init(ViaManager.builder()
.platform(this)
@ -75,14 +77,18 @@ public class SpongePlugin implements ViaPlatform {
.injector(new SpongeViaInjector())
.loader(new SpongeViaLoader(this))
.build());
}
@Listener
public void onServerStart(GameAboutToStartServerEvent event) {
// Inject!
logger.info("ViaVersion is injecting!");
Via.getManager().init();
}
@Override
public Logger getLogger() {
return logger;
@Listener
public void onServerStop(GameStoppingServerEvent event) {
Via.getManager().destroy();
}
@Override
@ -102,26 +108,41 @@ public class SpongePlugin implements ViaPlatform {
@Override
public TaskId runAsync(Runnable runnable) {
asyncExecutor.execute(runnable);
return new SpongeTaskId(null);
return new SpongeTaskId(
Task.builder()
.execute(runnable)
.async()
.submit(this)
);
}
@Override
public TaskId runSync(Runnable runnable) {
syncExecutor.execute(runnable);
return new SpongeTaskId(null);
return new SpongeTaskId(
Task.builder()
.execute(runnable)
.submit(this)
);
}
@Override
public TaskId runSync(Runnable runnable, Long ticks) {
Long delay = ticks * 50L;
return new SpongeTaskId(syncExecutor.schedule(runnable, delay, TimeUnit.MILLISECONDS).getTask());
return new SpongeTaskId(
Task.builder()
.execute(runnable)
.delayTicks(ticks)
.submit(this)
);
}
@Override
public TaskId runRepeatingSync(Runnable runnable, Long ticks) {
Long time = ticks * 50L;
return new SpongeTaskId(syncExecutor.scheduleAtFixedRate(runnable, time, time, TimeUnit.MILLISECONDS).getTask());
return new SpongeTaskId(
Task.builder()
.execute(runnable)
.intervalTicks(ticks)
.submit(this)
);
}
@Override
@ -145,21 +166,24 @@ public class SpongePlugin implements ViaPlatform {
@Override
public void sendMessage(UUID uuid, String message) {
for (Player player : game.getServer().getOnlinePlayers()) {
if (player.getUniqueId().equals(uuid))
player.sendMessage(TextSerializers.LEGACY_FORMATTING_CODE.deserialize(message));
}
game.getServer().getPlayer(uuid)
.ifPresent(player ->
player.sendMessage(
TextSerializers.JSON.deserialize(
ComponentSerializer.toString(
TextComponent.fromLegacyText(message) // Hacky way to fix links
)
)
)
);
}
@Override
public boolean kickPlayer(UUID uuid, String message) {
for (Player player : game.getServer().getOnlinePlayers()) {
if (player.getUniqueId().equals(uuid)) {
player.kick(TextSerializers.LEGACY_FORMATTING_CODE.deserialize(message));
return true;
}
}
return false;
return game.getServer().getPlayer(uuid).map(player -> {
player.kick(TextSerializers.LEGACY_FORMATTING_CODE.deserialize(message));
return true;
}).orElse(false);
}
@Override

View File

@ -1,9 +1,11 @@
package us.myles.ViaVersion.sponge.commands;
import lombok.AllArgsConstructor;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.chat.ComponentSerializer;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.text.serializer.TextSerializers;
import org.spongepowered.api.util.Identifiable;
import us.myles.ViaVersion.api.command.ViaCommandSender;
import java.util.UUID;
@ -19,16 +21,23 @@ public class SpongeCommandSender implements ViaCommandSender {
@Override
public void sendMessage(String msg) {
source.sendMessage(TextSerializers.LEGACY_FORMATTING_CODE.deserialize(msg));
source.sendMessage(
TextSerializers.JSON.deserialize(
ComponentSerializer.toString(
TextComponent.fromLegacyText(msg) // Hacky way to fix links
)
)
);
}
@Override
public UUID getUUID() {
if (source instanceof Player) {
return ((Player) source).getUniqueId();
if (source instanceof Identifiable) {
return ((Identifiable) source).getUniqueId();
} else {
return UUID.fromString(getName());
}
}
@Override

View File

@ -5,18 +5,20 @@ import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.MessageToByteEncoder;
import lombok.Getter;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.protocol.ProtocolPipeline;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
import java.lang.reflect.Method;
public class SpongeChannelInitializer extends ChannelInitializer<SocketChannel> {
public class SpongeChannelInitializer extends ChannelInitializer<Channel> {
private final ChannelInitializer<SocketChannel> original;
@Getter
private final ChannelInitializer<Channel> original;
private Method method;
public SpongeChannelInitializer(ChannelInitializer<SocketChannel> oldInit) {
public SpongeChannelInitializer(ChannelInitializer<Channel> oldInit) {
this.original = oldInit;
try {
this.method = ChannelInitializer.class.getDeclaredMethod("initChannel", Channel.class);
@ -26,29 +28,27 @@ public class SpongeChannelInitializer extends ChannelInitializer<SocketChannel>
}
}
public ChannelInitializer<SocketChannel> getOriginal() {
return original;
}
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
protected void initChannel(Channel channel) throws Exception {
// Ensure ViaVersion is loaded
if (ProtocolRegistry.SERVER_PROTOCOL != -1) {
UserConnection info = new UserConnection(socketChannel);
if (ProtocolRegistry.SERVER_PROTOCOL != -1
&& channel instanceof SocketChannel) { // channel can be LocalChannel on internal server
UserConnection info = new UserConnection((SocketChannel) channel);
// init protocol
new ProtocolPipeline(info);
// Add originals
this.method.invoke(this.original, socketChannel);
this.method.invoke(this.original, channel);
// Add our transformers
MessageToByteEncoder encoder = new SpongeEncodeHandler(info, (MessageToByteEncoder) socketChannel.pipeline().get("encoder"));
ByteToMessageDecoder decoder = new SpongeDecodeHandler(info, (ByteToMessageDecoder) socketChannel.pipeline().get("decoder"));
MessageToByteEncoder encoder = new SpongeEncodeHandler(info, (MessageToByteEncoder) channel.pipeline().get("encoder"));
ByteToMessageDecoder decoder = new SpongeDecodeHandler(info, (ByteToMessageDecoder) channel.pipeline().get("decoder"));
SpongePacketHandler chunkHandler = new SpongePacketHandler(info);
socketChannel.pipeline().replace("encoder", "encoder", encoder);
socketChannel.pipeline().replace("decoder", "decoder", decoder);
socketChannel.pipeline().addAfter("packet_handler", "viaversion_packet_handler", chunkHandler);
channel.pipeline().replace("encoder", "encoder", encoder);
channel.pipeline().replace("decoder", "decoder", decoder);
channel.pipeline().addAfter("packet_handler", "viaversion_packet_handler", chunkHandler);
} else {
this.method.invoke(this.original, socketChannel);
this.method.invoke(this.original, channel);
}
}
}

View File

@ -1,9 +1,9 @@
package us.myles.ViaVersion.sponge.platform;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import org.spongepowered.api.MinecraftVersion;
import org.spongepowered.api.Sponge;
import us.myles.ViaVersion.api.Pair;
@ -86,7 +86,7 @@ public class SpongeViaInjector implements ViaInjector {
bootstrapAcceptor = future.channel().pipeline().first();
}
try {
ChannelInitializer<SocketChannel> oldInit = ReflectionUtil.get(bootstrapAcceptor, "childHandler", ChannelInitializer.class);
ChannelInitializer<Channel> oldInit = ReflectionUtil.get(bootstrapAcceptor, "childHandler", ChannelInitializer.class);
ChannelInitializer newInit = new SpongeChannelInitializer(oldInit);
ReflectionUtil.set(bootstrapAcceptor, "childHandler", newInit);
@ -111,7 +111,7 @@ public class SpongeViaInjector implements ViaInjector {
for (String name : names) {
ChannelHandler handler = future.channel().pipeline().get(name);
try {
ChannelInitializer<SocketChannel> oldInit = ReflectionUtil.get(handler, "childHandler", ChannelInitializer.class);
ChannelInitializer<Channel> oldInit = ReflectionUtil.get(handler, "childHandler", ChannelInitializer.class);
if (oldInit instanceof SpongeChannelInitializer) {
bootstrapAcceptor = handler;
}
@ -125,7 +125,7 @@ public class SpongeViaInjector implements ViaInjector {
}
try {
ChannelInitializer<SocketChannel> oldInit = ReflectionUtil.get(bootstrapAcceptor, "childHandler", ChannelInitializer.class);
ChannelInitializer<Channel> oldInit = ReflectionUtil.get(bootstrapAcceptor, "childHandler", ChannelInitializer.class);
if (oldInit instanceof SpongeChannelInitializer) {
ReflectionUtil.set(bootstrapAcceptor, "childHandler", ((SpongeChannelInitializer) oldInit).getOriginal());
}

View File

@ -1,11 +1,11 @@
package us.myles.ViaVersion.sponge.platform;
import lombok.AllArgsConstructor;
import org.spongepowered.api.Sponge;
import us.myles.ViaVersion.SpongePlugin;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.platform.TaskId;
import us.myles.ViaVersion.api.platform.ViaPlatformLoader;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider;
@ -21,28 +21,47 @@ import us.myles.ViaVersion.sponge.listeners.protocol1_9to1_8.sponge5.Sponge5Armo
import us.myles.ViaVersion.sponge.providers.SpongeViaBulkChunkTranslator;
import us.myles.ViaVersion.sponge.providers.SpongeViaMovementTransmitter;
@AllArgsConstructor
import java.util.HashSet;
import java.util.Set;
public class SpongeViaLoader implements ViaPlatformLoader {
private SpongePlugin plugin;
private Set<Object> listeners = new HashSet<>();
private Set<TaskId> tasks = new HashSet<>();
public SpongeViaLoader(SpongePlugin plugin) {
this.plugin = plugin;
}
private void registerListener(Object listener) {
Sponge.getEventManager().registerListeners(plugin, storeListener(listener));
}
private <T> T storeListener(T listener) {
listeners.add(listener);
return listener;
}
@Override
public void load() {
// Update Listener
Sponge.getEventManager().registerListeners(plugin, new UpdateListener());
registerListener(new UpdateListener());
/* Base Protocol */
Sponge.getEventManager().registerListeners(plugin, new ClientLeaveListener());
registerListener(new ClientLeaveListener());
/* 1.9 client to 1.8 server */
try {
Class.forName("org.spongepowered.api.event.entity.DisplaceEntityEvent");
new Sponge4ArmorListener().register();
storeListener(new Sponge4ArmorListener()).register();
} catch (ClassNotFoundException e) {
new Sponge5ArmorListener(plugin).register();
storeListener(new Sponge5ArmorListener(plugin)).register();
}
new DeathListener(plugin).register();
new BlockListener(plugin).register();
storeListener(new DeathListener(plugin)).register();
storeListener(new BlockListener(plugin)).register();
if (plugin.getConf().isItemCache()) {
Via.getPlatform().runRepeatingSync(new HandItemCache(), 2L); // Updates players items :)
tasks.add(Via.getPlatform().runRepeatingSync(new HandItemCache(), 2L)); // Updates players items :)
HandItemCache.CACHE = true;
}
@ -60,4 +79,12 @@ public class SpongeViaLoader implements ViaPlatformLoader {
}
});
}
}
public void unload() {
// todo restore providers
listeners.forEach(Sponge.getEventManager()::unregisterListeners);
listeners.clear();
tasks.forEach(Via.getPlatform()::cancelTask);
tasks.clear();
}
}