Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-07-11 09:48:03 +02:00
Add Sponge Support
Dieser Commit ist enthalten in:
Ursprung
a1fbca11f0
Commit
b371c14a27
3
TODOLIST
3
TODOLIST
|
@ -1 +1,2 @@
|
||||||
Handle injector errors
|
PORT STUFF TO GUAVA :D (so we dont need to include commons)
|
||||||
|
Test on SpongeForge, only tested SpongeVanilla
|
|
@ -16,12 +16,25 @@
|
||||||
<bukkitVersion>1.8.8-R0.1-SNAPSHOT</bukkitVersion>
|
<bukkitVersion>1.8.8-R0.1-SNAPSHOT</bukkitVersion>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<targetPath>.</targetPath>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
<directory>src/main/resources/</directory>
|
||||||
|
<includes>
|
||||||
|
<include>*</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</build>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- Common Module -->
|
<!-- Common Module -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>us.myles</groupId>
|
<groupId>us.myles</groupId>
|
||||||
<artifactId>viaversion-common</artifactId>
|
<artifactId>viaversion-common</artifactId>
|
||||||
<version>${parent.version}</version>
|
<version>${project.parent.version}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ public class BukkitViaBulkChunkTranslator extends BulkChunkTranslatorProvider {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
// TODO: Abstract this ?
|
|
||||||
mapChunkBulkRef = new ReflectionUtil.ClassReflection(ReflectionUtil.nms("PacketPlayOutMapChunkBulk"));
|
mapChunkBulkRef = new ReflectionUtil.ClassReflection(ReflectionUtil.nms("PacketPlayOutMapChunkBulk"));
|
||||||
mapChunkRef = new ReflectionUtil.ClassReflection(ReflectionUtil.nms("PacketPlayOutMapChunk"));
|
mapChunkRef = new ReflectionUtil.ClassReflection(ReflectionUtil.nms("PacketPlayOutMapChunk"));
|
||||||
if (((ViaVersionPlugin) Via.getPlatform()).isSpigot()) {
|
if (((ViaVersionPlugin) Via.getPlatform()).isSpigot()) {
|
||||||
|
@ -74,7 +73,7 @@ public class BukkitViaBulkChunkTranslator extends BulkChunkTranslatorProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabled() {
|
public boolean isFiltered(Class<?> packetClass) {
|
||||||
return true;
|
return packetClass.getName().endsWith("PacketPlayOutMapChunkBulk");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ package us.myles.ViaVersion.listeners;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
import us.myles.ViaVersion.api.ViaVersion;
|
import us.myles.ViaVersion.api.Via;
|
||||||
import us.myles.ViaVersion.update.UpdateUtil;
|
import us.myles.ViaVersion.update.UpdateUtil;
|
||||||
|
|
||||||
public class UpdateListener implements Listener {
|
public class UpdateListener implements Listener {
|
||||||
|
@ -11,7 +11,7 @@ public class UpdateListener implements Listener {
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onJoin(PlayerJoinEvent e) {
|
public void onJoin(PlayerJoinEvent e) {
|
||||||
if (e.getPlayer().hasPermission("viaversion.update")
|
if (e.getPlayer().hasPermission("viaversion.update")
|
||||||
&& ViaVersion.getConfig().isCheckForUpdates()) {
|
&& Via.getConfig().isCheckForUpdates()) {
|
||||||
UpdateUtil.sendUpdateMessage(e.getPlayer().getUniqueId());
|
UpdateUtil.sendUpdateMessage(e.getPlayer().getUniqueId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ name: ViaVersion
|
||||||
main: us.myles.ViaVersion.ViaVersionPlugin
|
main: us.myles.ViaVersion.ViaVersionPlugin
|
||||||
authors: [_MylesC, Matsv]
|
authors: [_MylesC, Matsv]
|
||||||
version: ${project.version}
|
version: ${project.version}
|
||||||
|
description: Allow newer Minecraft versions to connect to an older server version.
|
||||||
load: postworld
|
load: postworld
|
||||||
loadbefore: [ProtocolLib, ProxyPipe, SpigotLib, SkinRestorer]
|
loadbefore: [ProtocolLib, ProxyPipe, SpigotLib, SkinRestorer]
|
||||||
softdepend: [ProtocolSupport, PacketListenerApi]
|
softdepend: [ProtocolSupport, PacketListenerApi]
|
||||||
|
|
|
@ -11,6 +11,19 @@
|
||||||
|
|
||||||
<artifactId>viaversion-bungee</artifactId>
|
<artifactId>viaversion-bungee</artifactId>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<targetPath>.</targetPath>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
<directory>src/main/resources/</directory>
|
||||||
|
<includes>
|
||||||
|
<include>*</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</build>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- BungeeCord -->
|
<!-- BungeeCord -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -91,9 +91,8 @@ public class Protocol1_9TO1_8 extends Protocol {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFiltered(Class packetClass) {
|
public boolean isFiltered(Class packetClass) {
|
||||||
if (!Via.getManager().getProviders().get(BulkChunkTranslatorProvider.class).isEnabled())
|
return Via.getManager().getProviders().get(BulkChunkTranslatorProvider.class).isFiltered(packetClass);
|
||||||
return false;
|
|
||||||
return packetClass.getName().endsWith("PacketPlayOutMapChunkBulk");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -11,7 +11,7 @@ public class BulkChunkTranslatorProvider implements Provider {
|
||||||
return Arrays.asList(packet);
|
return Arrays.asList(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEnabled() {
|
public boolean isFiltered(Class<?> packet) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
17
jar/pom.xml
17
jar/pom.xml
|
@ -18,7 +18,7 @@
|
||||||
<resource>
|
<resource>
|
||||||
<targetPath>.</targetPath>
|
<targetPath>.</targetPath>
|
||||||
<filtering>false</filtering>
|
<filtering>false</filtering>
|
||||||
<directory>.</directory>
|
<directory>../</directory>
|
||||||
<includes>
|
<includes>
|
||||||
<include>LICENSE</include>
|
<include>LICENSE</include>
|
||||||
</includes>
|
</includes>
|
||||||
|
@ -57,6 +57,10 @@
|
||||||
<pattern>org.javassist</pattern>
|
<pattern>org.javassist</pattern>
|
||||||
<shadedPattern>us.myles.viaversion.libs.javassist</shadedPattern>
|
<shadedPattern>us.myles.viaversion.libs.javassist</shadedPattern>
|
||||||
</relocation>
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>org.apache</pattern>
|
||||||
|
<shadedPattern>us.myles.viaversion.libs.apache</shadedPattern>
|
||||||
|
</relocation>
|
||||||
</relocations>
|
</relocations>
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
|
@ -75,17 +79,22 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>us.myles</groupId>
|
<groupId>us.myles</groupId>
|
||||||
<artifactId>viaversion-common</artifactId>
|
<artifactId>viaversion-common</artifactId>
|
||||||
<version>${parent.version}</version>
|
<version>${project.parent.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>us.myles</groupId>
|
<groupId>us.myles</groupId>
|
||||||
<artifactId>viaversion-bukkit</artifactId>
|
<artifactId>viaversion-bukkit</artifactId>
|
||||||
<version>${parent.version}</version>
|
<version>${project.parent.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>us.myles</groupId>
|
<groupId>us.myles</groupId>
|
||||||
<artifactId>viaversion-bungee</artifactId>
|
<artifactId>viaversion-bungee</artifactId>
|
||||||
<version>${parent.version}</version>
|
<version>${project.parent.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>us.myles</groupId>
|
||||||
|
<artifactId>viaversion-sponge</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
3
pom.xml
3
pom.xml
|
@ -19,6 +19,7 @@
|
||||||
<module>common</module>
|
<module>common</module>
|
||||||
<module>bukkit</module>
|
<module>bukkit</module>
|
||||||
<module>bungee</module>
|
<module>bungee</module>
|
||||||
|
<module>sponge</module>
|
||||||
<module>jar</module>
|
<module>jar</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
|
@ -104,7 +105,7 @@
|
||||||
<groupId>commons-lang</groupId>
|
<groupId>commons-lang</groupId>
|
||||||
<artifactId>commons-lang</artifactId>
|
<artifactId>commons-lang</artifactId>
|
||||||
<version>2.6</version>
|
<version>2.6</version>
|
||||||
<scope>provided</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- ChatColour API -->
|
<!-- ChatColour API -->
|
||||||
|
|
72
sponge/pom.xml
Normale Datei
72
sponge/pom.xml
Normale Datei
|
@ -0,0 +1,72 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>viaversion-parent</artifactId>
|
||||||
|
<groupId>us.myles</groupId>
|
||||||
|
<version>1.0.0-ALPHA-modules</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>viaversion-sponge</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>sponge</id>
|
||||||
|
<url>http://repo.spongepowered.org/maven</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<targetPath>.</targetPath>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
<directory>src/main/resources/</directory>
|
||||||
|
<includes>
|
||||||
|
<include>*</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>templating-maven-plugin</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>filter-src</id>
|
||||||
|
<goals>
|
||||||
|
<goal>filter-sources</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- Common Module -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>us.myles</groupId>
|
||||||
|
<artifactId>viaversion-common</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Sponge API -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spongepowered</groupId>
|
||||||
|
<artifactId>spongeapi</artifactId>
|
||||||
|
<version>4.1.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,5 @@
|
||||||
|
package us.myles.ViaVersion.sponge;
|
||||||
|
|
||||||
|
public class VersionInfo {
|
||||||
|
public static final String VERSION = "${project.version}";
|
||||||
|
}
|
163
sponge/src/main/java/us/myles/ViaVersion/SpongePlugin.java
Normale Datei
163
sponge/src/main/java/us/myles/ViaVersion/SpongePlugin.java
Normale Datei
|
@ -0,0 +1,163 @@
|
||||||
|
package us.myles.ViaVersion;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import org.spongepowered.api.Game;
|
||||||
|
import org.spongepowered.api.entity.living.player.Player;
|
||||||
|
import org.spongepowered.api.event.Listener;
|
||||||
|
import org.spongepowered.api.event.game.state.GameStartedServerEvent;
|
||||||
|
import org.spongepowered.api.plugin.Plugin;
|
||||||
|
import org.spongepowered.api.plugin.PluginContainer;
|
||||||
|
import org.spongepowered.api.scheduler.SpongeExecutorService;
|
||||||
|
import org.spongepowered.api.text.serializer.TextSerializers;
|
||||||
|
import us.myles.ViaVersion.api.Via;
|
||||||
|
import us.myles.ViaVersion.api.ViaAPI;
|
||||||
|
import us.myles.ViaVersion.api.ViaVersionConfig;
|
||||||
|
import us.myles.ViaVersion.api.command.ViaCommandSender;
|
||||||
|
import us.myles.ViaVersion.api.configuration.ConfigurationProvider;
|
||||||
|
import us.myles.ViaVersion.api.platform.ViaPlatform;
|
||||||
|
import us.myles.ViaVersion.sponge.*;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
@Plugin(id = "viaversion",
|
||||||
|
name = "ViaVersion",
|
||||||
|
version = VersionInfo.VERSION,
|
||||||
|
authors = {"_MylesC", "Matsv"},
|
||||||
|
description = "Allow newer Minecraft versions to connect to an older server version."
|
||||||
|
)
|
||||||
|
public class SpongePlugin implements ViaPlatform {
|
||||||
|
@Inject
|
||||||
|
private Game game;
|
||||||
|
@Inject
|
||||||
|
private PluginContainer container;
|
||||||
|
|
||||||
|
private SpongeExecutorService asyncExecutor;
|
||||||
|
private SpongeExecutorService syncExecutor;
|
||||||
|
private SpongeConfigAPI conf = new SpongeConfigAPI(this);
|
||||||
|
private SpongeViaAPI api = new SpongeViaAPI();
|
||||||
|
private Logger logger;
|
||||||
|
|
||||||
|
@Listener
|
||||||
|
public void onServerStart(GameStartedServerEvent event) {
|
||||||
|
// Setup Logger
|
||||||
|
logger = new LoggerWrapper(container.getLogger());
|
||||||
|
// Setup Plugin
|
||||||
|
syncExecutor = game.getScheduler().createSyncExecutor(this);
|
||||||
|
asyncExecutor = game.getScheduler().createAsyncExecutor(this);
|
||||||
|
SpongeCommandHandler commandHandler = new SpongeCommandHandler();
|
||||||
|
game.getCommandManager().register(this, commandHandler, Arrays.asList("viaversion", "viaver"));
|
||||||
|
// Init platform
|
||||||
|
Via.init(ViaManager.builder()
|
||||||
|
.platform(this)
|
||||||
|
.commandHandler(commandHandler)
|
||||||
|
.injector(new SpongeViaInjector())
|
||||||
|
.loader(new SpongeViaLoader(this))
|
||||||
|
.build());
|
||||||
|
|
||||||
|
// Inject!
|
||||||
|
Via.getManager().init();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Logger getLogger() {
|
||||||
|
return logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPlatformName() {
|
||||||
|
return "Sponge";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPluginVersion() {
|
||||||
|
return container.getVersion().orElse("Unknown Version");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int runAsync(Runnable runnable) {
|
||||||
|
asyncExecutor.execute(runnable);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int runSync(Runnable runnable) {
|
||||||
|
syncExecutor.execute(runnable);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int runRepeatingSync(Runnable runnable, Long ticks) {
|
||||||
|
Long time = ticks * 50L;
|
||||||
|
syncExecutor.scheduleAtFixedRate(runnable, time, time, TimeUnit.MILLISECONDS);
|
||||||
|
// use id?
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancelTask(int taskId) {
|
||||||
|
// oh.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ViaCommandSender[] getOnlinePlayers() {
|
||||||
|
ViaCommandSender[] array = new ViaCommandSender[game.getServer().getOnlinePlayers().size()];
|
||||||
|
int i = 0;
|
||||||
|
for (Player player : game.getServer().getOnlinePlayers()) {
|
||||||
|
array[i++] = new SpongeCommandSender(player);
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPluginEnabled() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ViaAPI getApi() {
|
||||||
|
return api;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ViaVersionConfig getConf() {
|
||||||
|
return conf;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigurationProvider getConfigurationProvider() {
|
||||||
|
return conf;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReload() {
|
||||||
|
// TODO: Warning?
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonObject getDump() {
|
||||||
|
return new JsonObject();
|
||||||
|
}
|
||||||
|
}
|
125
sponge/src/main/java/us/myles/ViaVersion/sponge/LoggerWrapper.java
Normale Datei
125
sponge/src/main/java/us/myles/ViaVersion/sponge/LoggerWrapper.java
Normale Datei
|
@ -0,0 +1,125 @@
|
||||||
|
package us.myles.ViaVersion.sponge;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.LogRecord;
|
||||||
|
|
||||||
|
public class LoggerWrapper extends java.util.logging.Logger {
|
||||||
|
private final Logger base;
|
||||||
|
|
||||||
|
public LoggerWrapper(Logger logger) {
|
||||||
|
super("logger", null);
|
||||||
|
this.base = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void log(LogRecord record) {
|
||||||
|
log(record.getLevel(), record.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void log(Level level, String msg) {
|
||||||
|
if (level == Level.FINEST) {
|
||||||
|
base.trace(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (level == Level.FINE) {
|
||||||
|
base.debug(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (level == Level.WARNING) {
|
||||||
|
base.warn(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (level == Level.SEVERE) {
|
||||||
|
base.error(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (level == Level.INFO) {
|
||||||
|
base.info(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
base.trace(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void log(Level level, String msg, Object param1) {
|
||||||
|
if (level == Level.FINEST) {
|
||||||
|
base.trace(msg, param1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (level == Level.FINE) {
|
||||||
|
base.debug(msg, param1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (level == Level.WARNING) {
|
||||||
|
base.warn(msg, param1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (level == Level.SEVERE) {
|
||||||
|
base.error(msg, param1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (level == Level.INFO) {
|
||||||
|
base.info(msg, param1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
base.trace(msg, param1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void log(Level level, String msg, Object[] params) {
|
||||||
|
if (level == Level.FINEST) {
|
||||||
|
base.trace(msg, params);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (level == Level.FINE) {
|
||||||
|
base.debug(msg, params);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (level == Level.WARNING) {
|
||||||
|
base.warn(msg, params);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (level == Level.SEVERE) {
|
||||||
|
base.error(msg, params);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (level == Level.INFO) {
|
||||||
|
base.info(msg, params);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
base.trace(msg, params);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void log(Level level, String msg, Throwable params) {
|
||||||
|
if (level == Level.FINEST) {
|
||||||
|
base.trace(msg, params);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (level == Level.FINE) {
|
||||||
|
base.debug(msg, params);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (level == Level.WARNING) {
|
||||||
|
base.warn(msg, params);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (level == Level.SEVERE) {
|
||||||
|
base.error(msg, params);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (level == Level.INFO) {
|
||||||
|
base.info(msg, params);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
base.trace(msg, params);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
35
sponge/src/main/java/us/myles/ViaVersion/sponge/SpongeBossBar.java
Normale Datei
35
sponge/src/main/java/us/myles/ViaVersion/sponge/SpongeBossBar.java
Normale Datei
|
@ -0,0 +1,35 @@
|
||||||
|
package us.myles.ViaVersion.sponge;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.spongepowered.api.entity.living.player.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.boss.CommonBoss;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class SpongeBossBar extends CommonBoss<Player> {
|
||||||
|
|
||||||
|
public SpongeBossBar(String title, float health, BossColor color, BossStyle style) {
|
||||||
|
super(title, health, color, style);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BossBar addPlayer(Player player) {
|
||||||
|
addPlayer(player.getUniqueId());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BossBar addPlayers(Player... players) {
|
||||||
|
for (Player p : players)
|
||||||
|
addPlayer(p);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BossBar removePlayer(Player player) {
|
||||||
|
removePlayer(player.getUniqueId());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package us.myles.ViaVersion.sponge;
|
||||||
|
|
||||||
|
import org.spongepowered.api.command.CommandCallable;
|
||||||
|
import org.spongepowered.api.command.CommandException;
|
||||||
|
import org.spongepowered.api.command.CommandResult;
|
||||||
|
import org.spongepowered.api.command.CommandSource;
|
||||||
|
import org.spongepowered.api.text.Text;
|
||||||
|
import us.myles.ViaVersion.commands.ViaCommandHandler;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class SpongeCommandHandler extends ViaCommandHandler implements CommandCallable {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommandResult process(CommandSource source, String arguments) throws CommandException {
|
||||||
|
String[] args = arguments.length() > 0 ? arguments.split(" ") : new String[0];
|
||||||
|
onCommand(new SpongeCommandSender(source), args);
|
||||||
|
return CommandResult.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getSuggestions(CommandSource source, String arguments) throws CommandException {
|
||||||
|
String[] args = arguments.length() > 0 ? arguments.split(" ") : new String[0];
|
||||||
|
return onTabComplete(new SpongeCommandSender(source), args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean testPermission(CommandSource source) {
|
||||||
|
return source.hasPermission("viaversion.admin");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<? extends Text> getShortDescription(CommandSource source) {
|
||||||
|
return Optional.of(Text.of("Shows ViaVersion Version and more."));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<? extends Text> getHelp(CommandSource source) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Text getUsage(CommandSource source) {
|
||||||
|
return Text.of("Usage /viaversion");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package us.myles.ViaVersion.sponge;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import org.spongepowered.api.command.CommandSource;
|
||||||
|
import org.spongepowered.api.entity.living.player.Player;
|
||||||
|
import org.spongepowered.api.text.serializer.TextSerializer;
|
||||||
|
import org.spongepowered.api.text.serializer.TextSerializers;
|
||||||
|
import us.myles.ViaVersion.api.command.ViaCommandSender;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class SpongeCommandSender implements ViaCommandSender {
|
||||||
|
private CommandSource source;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(String permission) {
|
||||||
|
return source.hasPermission(permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMessage(String msg) {
|
||||||
|
source.sendMessage(TextSerializers.LEGACY_FORMATTING_CODE.deserialize(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UUID getUUID() {
|
||||||
|
if (source instanceof Player) {
|
||||||
|
return ((Player) source).getUniqueId();
|
||||||
|
} else {
|
||||||
|
return UUID.fromString(getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return source.getName();
|
||||||
|
}
|
||||||
|
}
|
183
sponge/src/main/java/us/myles/ViaVersion/sponge/SpongeConfigAPI.java
Normale Datei
183
sponge/src/main/java/us/myles/ViaVersion/sponge/SpongeConfigAPI.java
Normale Datei
|
@ -0,0 +1,183 @@
|
||||||
|
package us.myles.ViaVersion.sponge;
|
||||||
|
|
||||||
|
import us.myles.ViaVersion.SpongePlugin;
|
||||||
|
import us.myles.ViaVersion.api.ViaVersionConfig;
|
||||||
|
import us.myles.ViaVersion.api.configuration.ConfigurationProvider;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class SpongeConfigAPI implements ViaVersionConfig, ConfigurationProvider{
|
||||||
|
private final SpongePlugin spongePlugin;
|
||||||
|
|
||||||
|
public SpongeConfigAPI(SpongePlugin spongePlugin) {
|
||||||
|
this.spongePlugin = spongePlugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCheckForUpdates() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPreventCollision() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNewEffectIndicator() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isShowNewDeathMessages() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSuppressMetadataErrors() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isShieldBlocking() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isHologramPatch() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBossbarPatch() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBossbarAntiflicker() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUnknownEntitiesSuppressed() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getHologramYOffset() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAutoTeam() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBlockBreakPatch() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxPPS() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMaxPPSKickMessage() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTrackingPeriod() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getWarningPPS() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxWarnings() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMaxWarningsKickMessage() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAntiXRay() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSendSupportedVersions() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStimulatePlayerTick() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isItemCache() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNMSPlayerTicking() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReplacePistons() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPistonReplacementId() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isForceJsonTransform() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Integer> getBlockedProtocols() {
|
||||||
|
return Arrays.asList(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getBlockedDisconnectMsg() {
|
||||||
|
return "Boop";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getReloadDisconnectMsg() {
|
||||||
|
return "Beep";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(String path, Object value) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveConfig() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getValues() {
|
||||||
|
return new HashMap<>();
|
||||||
|
}
|
||||||
|
}
|
81
sponge/src/main/java/us/myles/ViaVersion/sponge/SpongeViaAPI.java
Normale Datei
81
sponge/src/main/java/us/myles/ViaVersion/sponge/SpongeViaAPI.java
Normale Datei
|
@ -0,0 +1,81 @@
|
||||||
|
package us.myles.ViaVersion.sponge;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import org.spongepowered.api.entity.living.player.Player;
|
||||||
|
import us.myles.ViaVersion.SpongePlugin;
|
||||||
|
import us.myles.ViaVersion.api.Via;
|
||||||
|
import us.myles.ViaVersion.api.ViaAPI;
|
||||||
|
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.data.UserConnection;
|
||||||
|
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
|
||||||
|
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class SpongeViaAPI implements ViaAPI<Player> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPlayerVersion(@NonNull Player player) {
|
||||||
|
if (!isPorted(player.getUniqueId()))
|
||||||
|
return ProtocolRegistry.SERVER_PROTOCOL;
|
||||||
|
return getPortedPlayers().get(player.getUniqueId()).get(ProtocolInfo.class).getProtocolVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPlayerVersion(@NonNull UUID uuid) {
|
||||||
|
if (!isPorted(uuid))
|
||||||
|
return ProtocolRegistry.SERVER_PROTOCOL;
|
||||||
|
return getPortedPlayers().get(uuid).get(ProtocolInfo.class).getProtocolVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPorted(UUID playerUUID) {
|
||||||
|
return getPortedPlayers().containsKey(playerUUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getVersion() {
|
||||||
|
return Via.getPlatform().getPluginVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 SpongeBossBar(title, 1F, color, style);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BossBar createBossBar(String title, float health, BossColor color, BossStyle style) {
|
||||||
|
return new SpongeBossBar(title, health, color, style);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SortedSet<Integer> getSupportedVersions() {
|
||||||
|
SortedSet<Integer> outputSet = new TreeSet<>(ProtocolRegistry.getSupportedVersions());
|
||||||
|
outputSet.removeAll(Via.getPlatform().getConf().getBlockedProtocols());
|
||||||
|
|
||||||
|
return outputSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<UUID, UserConnection> getPortedPlayers() {
|
||||||
|
return Via.getManager().getPortedPlayers();
|
||||||
|
}
|
||||||
|
}
|
197
sponge/src/main/java/us/myles/ViaVersion/sponge/SpongeViaInjector.java
Normale Datei
197
sponge/src/main/java/us/myles/ViaVersion/sponge/SpongeViaInjector.java
Normale Datei
|
@ -0,0 +1,197 @@
|
||||||
|
package us.myles.ViaVersion.sponge;
|
||||||
|
|
||||||
|
import io.netty.channel.ChannelFuture;
|
||||||
|
import io.netty.channel.ChannelHandler;
|
||||||
|
import io.netty.channel.ChannelInitializer;
|
||||||
|
import io.netty.channel.socket.SocketChannel;
|
||||||
|
import us.myles.ViaVersion.api.Pair;
|
||||||
|
import us.myles.ViaVersion.api.Via;
|
||||||
|
import us.myles.ViaVersion.api.platform.ViaInjector;
|
||||||
|
import us.myles.ViaVersion.sponge.handlers.ViaVersionInitializer;
|
||||||
|
import us.myles.ViaVersion.sponge.util.ReflectionUtil;
|
||||||
|
import us.myles.ViaVersion.util.ListWrapper;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SpongeViaInjector implements ViaInjector {
|
||||||
|
private List<ChannelFuture> injectedFutures = new ArrayList<>();
|
||||||
|
private List<Pair<Field, Object>> injectedLists = new ArrayList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void inject() throws Exception {
|
||||||
|
try {
|
||||||
|
Object connection = getServerConnection();
|
||||||
|
if (connection == null) {
|
||||||
|
throw new Exception("We failed to find the core component 'ServerConnection', please file an issue on our GitHub.");
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
try {
|
||||||
|
injectChannelFuture((ChannelFuture) o);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
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) {
|
||||||
|
Via.getPlatform().getLogger().severe("Unable to inject ViaVersion, please post these details on our GitHub and ensure you're using a compatible server version.");
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void injectChannelFuture(ChannelFuture future) throws Exception {
|
||||||
|
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) {
|
||||||
|
throw new Exception("Unable to find core component 'childHandler', please check your plugins. issue: " + bootstrapAcceptor.getClass().getName());
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Via.getPlatform().getLogger().severe("We failed to inject ViaVersion, have you got late-bind enabled with something else?");
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void uninject() {
|
||||||
|
// TODO: Uninject from players currently online
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object getServer() throws Exception {
|
||||||
|
Class<?> serverClazz = Class.forName("net.minecraft.server.MinecraftServer");
|
||||||
|
for (Method m : serverClazz.getDeclaredMethods()) {
|
||||||
|
if (m.getParameterCount() == 0) {
|
||||||
|
if ((m.getModifiers() & Modifier.STATIC) == Modifier.STATIC) {
|
||||||
|
if (m.getReturnType().equals(serverClazz)) {
|
||||||
|
return m.invoke(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Exception("Could not find MinecraftServer static field!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getServerProtocolVersion() throws Exception {
|
||||||
|
try {
|
||||||
|
Class<?> serverClazz = Class.forName("net.minecraft.server.MinecraftServer");
|
||||||
|
Object server = getServer();
|
||||||
|
Class<?> pingClazz = Class.forName("net.minecraft.network.ServerStatusResponse");
|
||||||
|
Object ping = null;
|
||||||
|
// Search for ping method
|
||||||
|
for (Field f : serverClazz.getDeclaredFields()) {
|
||||||
|
if (f.getType() != null) {
|
||||||
|
if (f.getType().getSimpleName().equals("ServerStatusResponse")) {
|
||||||
|
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("MinecraftProtocolVersionIdentifier")) {
|
||||||
|
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) {
|
||||||
|
throw new Exception("Failed to get server", e);
|
||||||
|
}
|
||||||
|
throw new Exception("Failed to get server");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object getServerConnection() throws Exception {
|
||||||
|
Class<?> serverClazz = Class.forName("net.minecraft.server.MinecraftServer");
|
||||||
|
Object server = getServer();
|
||||||
|
Object connection = null;
|
||||||
|
for (Method m : serverClazz.getDeclaredMethods()) {
|
||||||
|
if (m.getReturnType() != null) {
|
||||||
|
if (m.getReturnType().getSimpleName().equals("NetworkSystem")) {
|
||||||
|
if (m.getParameterTypes().length == 0) {
|
||||||
|
connection = m.invoke(server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
72
sponge/src/main/java/us/myles/ViaVersion/sponge/SpongeViaLoader.java
Normale Datei
72
sponge/src/main/java/us/myles/ViaVersion/sponge/SpongeViaLoader.java
Normale Datei
|
@ -0,0 +1,72 @@
|
||||||
|
package us.myles.ViaVersion.sponge;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import org.spongepowered.api.Sponge;
|
||||||
|
import us.myles.ViaVersion.SpongePlugin;
|
||||||
|
import us.myles.ViaVersion.api.Via;
|
||||||
|
import us.myles.ViaVersion.api.platform.ViaPlatformLoader;
|
||||||
|
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider;
|
||||||
|
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
|
||||||
|
import us.myles.ViaVersion.sponge.listeners.ClientLeaveListener;
|
||||||
|
import us.myles.ViaVersion.sponge.listeners.UpdateListener;
|
||||||
|
import us.myles.ViaVersion.sponge.providers.SpongeViaBulkChunkTranslator;
|
||||||
|
import us.myles.ViaVersion.sponge.providers.SpongeViaMovementTransmitter;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class SpongeViaLoader implements ViaPlatformLoader {
|
||||||
|
private SpongePlugin plugin;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load() {
|
||||||
|
// Update Listener
|
||||||
|
Sponge.getEventManager().registerListeners(plugin, new UpdateListener());
|
||||||
|
//
|
||||||
|
/* Base Protocol */
|
||||||
|
Sponge.getEventManager().registerListeners(plugin, new ClientLeaveListener());
|
||||||
|
// /* 1.9 client to 1.8 server */
|
||||||
|
//
|
||||||
|
// new ArmorListener(plugin).register();
|
||||||
|
// new CommandBlockListener(plugin).register();
|
||||||
|
// new DeathListener(plugin).register();
|
||||||
|
// new BlockListener(plugin).register();
|
||||||
|
//
|
||||||
|
// if (Bukkit.getVersion().toLowerCase().contains("paper") || Bukkit.getVersion().toLowerCase().contains("taco")) {
|
||||||
|
// plugin.getLogger().info("Enabling PaperSpigot/TacoSpigot patch: Fixes block placement.");
|
||||||
|
// new PaperPatch(plugin).register();
|
||||||
|
// }
|
||||||
|
// if (plugin.getConf().isItemCache()) {
|
||||||
|
// new HandItemCache().runTaskTimerAsynchronously(plugin, 2L, 2L); // Updates player's items :)
|
||||||
|
// HandItemCache.CACHE = true;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /* Providers */
|
||||||
|
Via.getManager().getProviders().use(BulkChunkTranslatorProvider.class, new SpongeViaBulkChunkTranslator());
|
||||||
|
Via.getManager().getProviders().use(MovementTransmitterProvider.class, new SpongeViaMovementTransmitter());
|
||||||
|
// Via.getManager().getProviders().use(HandItemProvider.class, new HandItemProvider() {
|
||||||
|
// @Override
|
||||||
|
// public Item getHandItem(final UserConnection info) {
|
||||||
|
// if (HandItemCache.CACHE) {
|
||||||
|
// return HandItemCache.getHandItem(info.get(ProtocolInfo.class).getUuid());
|
||||||
|
// } else {
|
||||||
|
// try {
|
||||||
|
// return Bukkit.getScheduler().callSyncMethod(Bukkit.getPluginManager().getPlugin("ViaVersion"), new Callable<Item>() {
|
||||||
|
// @Override
|
||||||
|
// public Item call() throws Exception {
|
||||||
|
// UUID playerUUID = info.get(ProtocolInfo.class).getUuid();
|
||||||
|
// if (Bukkit.getPlayer(playerUUID) != null) {
|
||||||
|
// return HandItemCache.convert(Bukkit.getPlayer(playerUUID).getItemInHand());
|
||||||
|
// }
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// }).get(10, TimeUnit.SECONDS);
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// System.out.println("Error fetching hand item: " + e.getClass().getName());
|
||||||
|
// if (Via.getManager().isDebug())
|
||||||
|
// e.printStackTrace();
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
package us.myles.ViaVersion.sponge.handlers;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||||
|
import us.myles.ViaVersion.api.PacketWrapper;
|
||||||
|
import us.myles.ViaVersion.api.data.UserConnection;
|
||||||
|
import us.myles.ViaVersion.api.type.Type;
|
||||||
|
import us.myles.ViaVersion.exception.CancelException;
|
||||||
|
import us.myles.ViaVersion.packets.Direction;
|
||||||
|
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||||
|
import us.myles.ViaVersion.util.PipelineUtil;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ViaDecodeHandler extends ByteToMessageDecoder {
|
||||||
|
|
||||||
|
private final ByteToMessageDecoder minecraftDecoder;
|
||||||
|
private final UserConnection info;
|
||||||
|
|
||||||
|
public ViaDecodeHandler(UserConnection info, ByteToMessageDecoder minecraftDecoder) {
|
||||||
|
this.info = info;
|
||||||
|
this.minecraftDecoder = minecraftDecoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void decode(ChannelHandlerContext ctx, ByteBuf bytebuf, List<Object> list) throws Exception {
|
||||||
|
// use transformers
|
||||||
|
if (bytebuf.readableBytes() > 0) {
|
||||||
|
// Ignore if pending disconnect
|
||||||
|
if (info.isPendingDisconnect()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Increment received
|
||||||
|
boolean second = info.incrementReceived();
|
||||||
|
// Check PPS
|
||||||
|
// TODO implement pps
|
||||||
|
// if (second) {
|
||||||
|
// if (((ViaVersionPlugin) Via.getPlatform()).handlePPS(info))
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (info.isActive()) {
|
||||||
|
// Handle ID
|
||||||
|
int id = Type.VAR_INT.read(bytebuf);
|
||||||
|
// Transform
|
||||||
|
ByteBuf newPacket = ctx.alloc().buffer();
|
||||||
|
try {
|
||||||
|
if (id == PacketWrapper.PASSTHROUGH_ID) {
|
||||||
|
newPacket.writeBytes(bytebuf);
|
||||||
|
} else {
|
||||||
|
PacketWrapper wrapper = new PacketWrapper(id, bytebuf, info);
|
||||||
|
ProtocolInfo protInfo = info.get(ProtocolInfo.class);
|
||||||
|
protInfo.getPipeline().transform(Direction.INCOMING, protInfo.getState(), wrapper);
|
||||||
|
wrapper.writeToBuffer(newPacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
bytebuf.clear();
|
||||||
|
bytebuf = newPacket;
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Clear Buffer
|
||||||
|
bytebuf.clear();
|
||||||
|
// Release Packet, be free!
|
||||||
|
newPacket.release();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// call minecraft decoder
|
||||||
|
try {
|
||||||
|
list.addAll(PipelineUtil.callDecode(this.minecraftDecoder, ctx, bytebuf));
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
if (e.getCause() instanceof Exception) {
|
||||||
|
throw (Exception) e.getCause();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (info.isActive()) {
|
||||||
|
bytebuf.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||||
|
if (PipelineUtil.containsCause(cause, CancelException.class)) return;
|
||||||
|
super.exceptionCaught(ctx, cause);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
package us.myles.ViaVersion.sponge.handlers;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.handler.codec.MessageToByteEncoder;
|
||||||
|
import us.myles.ViaVersion.api.PacketWrapper;
|
||||||
|
import us.myles.ViaVersion.api.Via;
|
||||||
|
import us.myles.ViaVersion.api.data.UserConnection;
|
||||||
|
import us.myles.ViaVersion.api.type.Type;
|
||||||
|
import us.myles.ViaVersion.exception.CancelException;
|
||||||
|
import us.myles.ViaVersion.packets.Direction;
|
||||||
|
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||||
|
import us.myles.ViaVersion.util.PipelineUtil;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
||||||
|
public class ViaEncodeHandler extends MessageToByteEncoder {
|
||||||
|
private final UserConnection info;
|
||||||
|
private final MessageToByteEncoder minecraftEncoder;
|
||||||
|
|
||||||
|
public ViaEncodeHandler(UserConnection info, MessageToByteEncoder minecraftEncoder) {
|
||||||
|
this.info = info;
|
||||||
|
this.minecraftEncoder = minecraftEncoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void encode(final ChannelHandlerContext ctx, Object o, final ByteBuf bytebuf) throws Exception {
|
||||||
|
// handle the packet type
|
||||||
|
if (!(o instanceof ByteBuf)) {
|
||||||
|
// call minecraft encoder
|
||||||
|
try {
|
||||||
|
PipelineUtil.callEncode(this.minecraftEncoder, ctx, o, bytebuf);
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
if (e.getCause() instanceof Exception) {
|
||||||
|
throw (Exception) e.getCause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bytebuf.readableBytes() == 0) {
|
||||||
|
throw new CancelException();
|
||||||
|
}
|
||||||
|
// Increment sent
|
||||||
|
info.incrementSent();
|
||||||
|
if (info.isActive()) {
|
||||||
|
// Handle ID
|
||||||
|
int id = Type.VAR_INT.read(bytebuf);
|
||||||
|
// Transform
|
||||||
|
ByteBuf oldPacket = bytebuf.copy();
|
||||||
|
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);
|
||||||
|
} catch (Exception e) {
|
||||||
|
bytebuf.clear();
|
||||||
|
throw e;
|
||||||
|
} finally {
|
||||||
|
oldPacket.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||||
|
if (PipelineUtil.containsCause(cause, CancelException.class)) return;
|
||||||
|
super.exceptionCaught(ctx, cause);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package us.myles.ViaVersion.sponge.handlers;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.handler.codec.MessageToMessageEncoder;
|
||||||
|
import us.myles.ViaVersion.api.data.UserConnection;
|
||||||
|
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ViaPacketHandler extends MessageToMessageEncoder {
|
||||||
|
private final UserConnection info;
|
||||||
|
|
||||||
|
public ViaPacketHandler(UserConnection info) {
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void encode(ChannelHandlerContext ctx, Object o, List list) throws Exception {
|
||||||
|
// Split chunks bulk packet up in to single chunks packets before it reached the encoder.
|
||||||
|
// This will prevent issues with several plugins and other protocol handlers due to the chunks being sent twice.
|
||||||
|
// It also sends the chunks in the right order possible resolving some issues with added chunks/block/entity data.
|
||||||
|
if (!(o instanceof ByteBuf)) {
|
||||||
|
info.setLastPacket(o);
|
||||||
|
/* This transformer is more for fixing issues which we find hard at packet level :) */
|
||||||
|
if (info.isActive()) {
|
||||||
|
if (info.get(ProtocolInfo.class).getPipeline().filter(o, list)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list.add(o);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package us.myles.ViaVersion.sponge.handlers;
|
||||||
|
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import io.netty.channel.ChannelInitializer;
|
||||||
|
import io.netty.channel.socket.SocketChannel;
|
||||||
|
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||||
|
import io.netty.handler.codec.MessageToByteEncoder;
|
||||||
|
import us.myles.ViaVersion.api.data.UserConnection;
|
||||||
|
import us.myles.ViaVersion.api.protocol.ProtocolPipeline;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
public class ViaVersionInitializer extends ChannelInitializer<SocketChannel> {
|
||||||
|
|
||||||
|
private final ChannelInitializer<SocketChannel> original;
|
||||||
|
private Method method;
|
||||||
|
|
||||||
|
public ViaVersionInitializer(ChannelInitializer<SocketChannel> oldInit) {
|
||||||
|
this.original = oldInit;
|
||||||
|
try {
|
||||||
|
this.method = ChannelInitializer.class.getDeclaredMethod("initChannel", Channel.class);
|
||||||
|
this.method.setAccessible(true);
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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.original, socketChannel);
|
||||||
|
// Add our transformers
|
||||||
|
MessageToByteEncoder encoder = new ViaEncodeHandler(info, (MessageToByteEncoder) socketChannel.pipeline().get("encoder"));
|
||||||
|
ByteToMessageDecoder decoder = new ViaDecodeHandler(info, (ByteToMessageDecoder) socketChannel.pipeline().get("decoder"));
|
||||||
|
ViaPacketHandler chunkHandler = new ViaPacketHandler(info);
|
||||||
|
|
||||||
|
socketChannel.pipeline().replace("encoder", "encoder", encoder);
|
||||||
|
socketChannel.pipeline().replace("decoder", "decoder", decoder);
|
||||||
|
socketChannel.pipeline().addAfter("packet_handler", "viaversion_packet_handler", chunkHandler);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package us.myles.ViaVersion.sponge.listeners;
|
||||||
|
|
||||||
|
import org.spongepowered.api.event.Listener;
|
||||||
|
import org.spongepowered.api.event.network.ClientConnectionEvent;
|
||||||
|
import us.myles.ViaVersion.api.Via;
|
||||||
|
|
||||||
|
public class ClientLeaveListener {
|
||||||
|
@Listener
|
||||||
|
public void onDisconnect(ClientConnectionEvent.Disconnect disconnect) {
|
||||||
|
Via.getManager().removePortedClient(disconnect.getTargetEntity().getUniqueId());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package us.myles.ViaVersion.sponge.listeners;
|
||||||
|
|
||||||
|
import org.spongepowered.api.event.Listener;
|
||||||
|
import org.spongepowered.api.event.network.ClientConnectionEvent;
|
||||||
|
import us.myles.ViaVersion.api.Via;
|
||||||
|
import us.myles.ViaVersion.update.UpdateUtil;
|
||||||
|
|
||||||
|
public class UpdateListener {
|
||||||
|
@Listener
|
||||||
|
public void onJoin(ClientConnectionEvent.Join join) {
|
||||||
|
if (join.getTargetEntity().hasPermission("viaversion.update")
|
||||||
|
&& Via.getConfig().isCheckForUpdates()) {
|
||||||
|
UpdateUtil.sendUpdateMessage(join.getTargetEntity().getUniqueId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package us.myles.ViaVersion.sponge.providers;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import us.myles.ViaVersion.api.Via;
|
||||||
|
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider;
|
||||||
|
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks;
|
||||||
|
import us.myles.ViaVersion.sponge.util.ReflectionUtil;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
public class SpongeViaBulkChunkTranslator extends BulkChunkTranslatorProvider {
|
||||||
|
// Reflection
|
||||||
|
private static ReflectionUtil.ClassReflection mapChunkBulkRef;
|
||||||
|
private static ReflectionUtil.ClassReflection mapChunkRef;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
mapChunkBulkRef = new ReflectionUtil.ClassReflection(Class.forName("net.minecraft.network.play.server.S26PacketMapChunkBulk"));
|
||||||
|
mapChunkRef = new ReflectionUtil.ClassReflection(Class.forName("net.minecraft.network.play.server.S21PacketChunkData"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
Via.getPlatform().getLogger().log(Level.WARNING, "Failed to initialise chunks reflection", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Object> transformMapChunkBulk(Object packet, ClientChunks clientChunks) {
|
||||||
|
List<Object> list = Lists.newArrayList();
|
||||||
|
try {
|
||||||
|
int[] xcoords = mapChunkBulkRef.getFieldValue("field_149266_a", packet, int[].class);
|
||||||
|
int[] zcoords = mapChunkBulkRef.getFieldValue("field_149264_b", packet, int[].class);
|
||||||
|
Object[] chunkMaps = mapChunkBulkRef.getFieldValue("field_179755_c", packet, Object[].class);
|
||||||
|
for (int i = 0; i < chunkMaps.length; i++) {
|
||||||
|
int x = xcoords[i];
|
||||||
|
int z = zcoords[i];
|
||||||
|
Object chunkMap = chunkMaps[i];
|
||||||
|
Object chunkPacket = mapChunkRef.newInstance();
|
||||||
|
mapChunkRef.setFieldValue("field_149284_a", chunkPacket, x);
|
||||||
|
mapChunkRef.setFieldValue("field_149282_b", chunkPacket, z);
|
||||||
|
mapChunkRef.setFieldValue("field_179758_c", chunkPacket, chunkMap);
|
||||||
|
mapChunkRef.setFieldValue("field_149279_g", chunkPacket, true); // Chunk bulk chunks are always ground-up
|
||||||
|
clientChunks.getBulkChunks().add(ClientChunks.toLong(x, z)); // Store for later
|
||||||
|
list.add(chunkPacket);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Via.getPlatform().getLogger().log(Level.WARNING, "Failed to transform chunks bulk", e);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFiltered(Class<?> packetClass) {
|
||||||
|
return packetClass.getName().endsWith("S26PacketMapChunkBulk");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package us.myles.ViaVersion.sponge.providers;
|
||||||
|
|
||||||
|
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
public class SpongeViaMovementTransmitter extends MovementTransmitterProvider {
|
||||||
|
// Used for packet mode
|
||||||
|
private Object idlePacket;
|
||||||
|
private Object idlePacket2;
|
||||||
|
|
||||||
|
public SpongeViaMovementTransmitter() {
|
||||||
|
Class<?> idlePacketClass;
|
||||||
|
try {
|
||||||
|
idlePacketClass = Class.forName("net.minecraft.network.play.client.C03PacketPlayer");
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
throw new RuntimeException("Couldn't find idle packet, help!", e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
idlePacket = idlePacketClass.newInstance();
|
||||||
|
idlePacket2 = idlePacketClass.newInstance();
|
||||||
|
|
||||||
|
Field flying = idlePacketClass.getDeclaredField("field_149474_g");
|
||||||
|
flying.setAccessible(true);
|
||||||
|
|
||||||
|
flying.set(idlePacket2, true);
|
||||||
|
} catch (NoSuchFieldException | InstantiationException | IllegalArgumentException | IllegalAccessException e) {
|
||||||
|
throw new RuntimeException("Couldn't make player idle packet, help!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getFlyingPacket() {
|
||||||
|
return idlePacket2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getGroundPacket() {
|
||||||
|
return idlePacket;
|
||||||
|
}
|
||||||
|
}
|
130
sponge/src/main/java/us/myles/ViaVersion/sponge/util/ReflectionUtil.java
Normale Datei
130
sponge/src/main/java/us/myles/ViaVersion/sponge/util/ReflectionUtil.java
Normale Datei
|
@ -0,0 +1,130 @@
|
||||||
|
package us.myles.ViaVersion.sponge.util;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ReflectionUtil {
|
||||||
|
|
||||||
|
public static Object invokeStatic(Class<?> clazz, String method) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||||
|
Method m = clazz.getDeclaredMethod(method);
|
||||||
|
return m.invoke(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object invoke(Object o, String method) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||||
|
Method m = o.getClass().getDeclaredMethod(method);
|
||||||
|
return m.invoke(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T getStatic(Class<?> clazz, String f, Class<T> t) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
Field field = clazz.getDeclaredField(f);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return (T) field.get(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T getSuper(Object o, String f, Class<T> t) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
Field field = o.getClass().getSuperclass().getDeclaredField(f);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return (T) field.get(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T get(Object instance, Class<?> clazz, String f, Class<T> t) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
Field field = clazz.getDeclaredField(f);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return (T) field.get(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T get(Object o, String f, Class<T> t) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
Field field = o.getClass().getDeclaredField(f);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return (T) field.get(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T getPublic(Object o, String f, Class<T> t) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
Field field = o.getClass().getField(f);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return (T) field.get(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void set(Object o, String f, Object value) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
Field field = o.getClass().getDeclaredField(f);
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(o, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class ClassReflection {
|
||||||
|
private final Class<?> handle;
|
||||||
|
private final Map<String, Field> fields = Maps.newConcurrentMap();
|
||||||
|
private final Map<String, Method> methods = Maps.newConcurrentMap();
|
||||||
|
|
||||||
|
public ClassReflection(Class<?> handle) {
|
||||||
|
this(handle, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassReflection(Class<?> handle, boolean recursive) {
|
||||||
|
this.handle = handle;
|
||||||
|
scanFields(handle, recursive);
|
||||||
|
scanMethods(handle, recursive);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scanFields(Class<?> host, boolean recursive) {
|
||||||
|
if (host.getSuperclass() != null && recursive) {
|
||||||
|
scanFields(host.getSuperclass(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Field field : host.getDeclaredFields()) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
fields.put(field.getName(), field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scanMethods(Class<?> host, boolean recursive) {
|
||||||
|
if (host.getSuperclass() != null && recursive) {
|
||||||
|
scanMethods(host.getSuperclass(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Method method : host.getDeclaredMethods()) {
|
||||||
|
method.setAccessible(true);
|
||||||
|
methods.put(method.getName(), method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object newInstance() throws IllegalAccessException, InstantiationException {
|
||||||
|
return handle.newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Field getField(String name) {
|
||||||
|
return fields.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFieldValue(String fieldName, Object instance, Object value) throws IllegalAccessException {
|
||||||
|
getField(fieldName).set(instance, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T getFieldValue(String fieldName, Object instance, Class<T> type) throws IllegalAccessException {
|
||||||
|
return type.cast(getField(fieldName).get(instance));
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T invokeMethod(Class<T> type, String methodName, Object instance, Object... args) throws InvocationTargetException, IllegalAccessException {
|
||||||
|
return type.cast(getMethod(methodName).invoke(instance, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Method getMethod(String name) {
|
||||||
|
return methods.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<Field> getFields() {
|
||||||
|
return Collections.unmodifiableCollection(fields.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<Method> getMethods() {
|
||||||
|
return Collections.unmodifiableCollection(methods.values());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren