A lot of fucking things
This commit is contained in:
parent
57973a9bec
commit
b498c50b2d
@ -58,6 +58,12 @@ public abstract class JavaPlugin extends PluginBase {
|
|||||||
private File configFile = null;
|
private File configFile = null;
|
||||||
private PluginLogger logger = null;
|
private PluginLogger logger = null;
|
||||||
|
|
||||||
|
public JavaPlugin(String fakeName) {
|
||||||
|
JavaPluginLoader loader = JavaPluginLoader.loader;
|
||||||
|
isEnabled = true;
|
||||||
|
init(loader, loader.server, new PluginDescriptionFile(fakeName, "1.0", "null"), null, null, classLoader);
|
||||||
|
}
|
||||||
|
|
||||||
public JavaPlugin() {
|
public JavaPlugin() {
|
||||||
final ClassLoader classLoader = this.getClass().getClassLoader();
|
final ClassLoader classLoader = this.getClass().getClassLoader();
|
||||||
if (!(classLoader instanceof PluginClassLoader)) {
|
if (!(classLoader instanceof PluginClassLoader)) {
|
||||||
|
@ -49,7 +49,7 @@ public final class JavaPluginLoader implements PluginLoader {
|
|||||||
private final Pattern[] fileFilters = new Pattern[] { Pattern.compile("\\.jar$"), };
|
private final Pattern[] fileFilters = new Pattern[] { Pattern.compile("\\.jar$"), };
|
||||||
private final Map<String, Class<?>> classes = new java.util.concurrent.ConcurrentHashMap<>(); // Spigot
|
private final Map<String, Class<?>> classes = new java.util.concurrent.ConcurrentHashMap<>(); // Spigot
|
||||||
private final Map<String, PluginClassLoader> loaders = new LinkedHashMap<>();
|
private final Map<String, PluginClassLoader> loaders = new LinkedHashMap<>();
|
||||||
|
public static JavaPluginLoader loader;
|
||||||
/**
|
/**
|
||||||
* This class was not meant to be constructed explicitly
|
* This class was not meant to be constructed explicitly
|
||||||
*
|
*
|
||||||
@ -59,6 +59,7 @@ public final class JavaPluginLoader implements PluginLoader {
|
|||||||
public JavaPluginLoader(Server instance) {
|
public JavaPluginLoader(Server instance) {
|
||||||
Validate.notNull(instance, "Server cannot be null");
|
Validate.notNull(instance, "Server cannot be null");
|
||||||
server = instance;
|
server = instance;
|
||||||
|
loader = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Plugin loadPlugin(final File file) throws InvalidPluginException {
|
public Plugin loadPlugin(final File file) throws InvalidPluginException {
|
||||||
|
@ -9,6 +9,7 @@ plugins {
|
|||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
mavenLocal()
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
maven(url = "https://libraries.minecraft.net")
|
maven(url = "https://libraries.minecraft.net")
|
||||||
maven(url = "https://oss.sonatype.org/content/groups/public")
|
maven(url = "https://oss.sonatype.org/content/groups/public")
|
||||||
@ -57,6 +58,17 @@ dependencies {
|
|||||||
|
|
||||||
compileOnly("org.projectlombok:lombok:1.18.24")
|
compileOnly("org.projectlombok:lombok:1.18.24")
|
||||||
annotationProcessor("org.projectlombok:lombok:1.18.24")
|
annotationProcessor("org.projectlombok:lombok:1.18.24")
|
||||||
|
|
||||||
|
|
||||||
|
implementation("net.kyori:adventure-text-serializer-gson-legacy-impl:4.9.3")
|
||||||
|
implementation("net.kyori:adventure-api:4.9.3")
|
||||||
|
implementation("net.kyori:adventure-text-serializer-legacy:4.7.0")
|
||||||
|
implementation("com.viaversion:opennbt:2.0-SNAPSHOT")
|
||||||
|
implementation("space.vectrix.flare:flare-fastutil:1.0.0")
|
||||||
|
implementation("javassist:javassist:3.11.0.GA")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun TaskContainer.registerRunTask(
|
fun TaskContainer.registerRunTask(
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.api.ViaRewindConfig;
|
||||||
|
import com.elevatemc.spigot.viarewind.api.ViaRewindPlatform;
|
||||||
|
|
||||||
|
public class ViaRewind {
|
||||||
|
private static ViaRewindPlatform platform;
|
||||||
|
private static ViaRewindConfig config;
|
||||||
|
|
||||||
|
public static void init(ViaRewindPlatform platform, ViaRewindConfig config) {
|
||||||
|
ViaRewind.platform = platform;
|
||||||
|
ViaRewind.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ViaRewindPlatform getPlatform() {
|
||||||
|
return ViaRewind.platform;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ViaRewindConfig getConfig() {
|
||||||
|
return ViaRewind.config;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.api.ViaRewindConfigImpl;
|
||||||
|
import com.elevatemc.spigot.viarewind.api.ViaRewindPlatform;
|
||||||
|
import com.elevatemc.spigot.viaversion.bukkit.ViaVersionPlugin;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class ViaRewindPlugin implements ViaRewindPlatform {
|
||||||
|
|
||||||
|
public void onEnable() {
|
||||||
|
ViaRewindConfigImpl conf = new ViaRewindConfigImpl(new File("config", "viarewind.yml"));
|
||||||
|
conf.reloadConfig();
|
||||||
|
this.init(conf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Logger getLogger() {
|
||||||
|
return ViaVersionPlugin.getPlugin().getLogger();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.api;
|
||||||
|
|
||||||
|
public interface ViaRewindConfig {
|
||||||
|
|
||||||
|
public enum CooldownIndicator {
|
||||||
|
TITLE, ACTION_BAR, BOSS_BAR, DISABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
CooldownIndicator getCooldownIndicator();
|
||||||
|
|
||||||
|
boolean isReplaceAdventureMode();
|
||||||
|
|
||||||
|
boolean isReplaceParticles();
|
||||||
|
|
||||||
|
int getMaxBookPages();
|
||||||
|
|
||||||
|
int getMaxBookPageSize();
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.api;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viaversion.util.Config;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ViaRewindConfigImpl extends Config implements ViaRewindConfig {
|
||||||
|
public ViaRewindConfigImpl(File configFile) {
|
||||||
|
super(configFile);
|
||||||
|
reloadConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CooldownIndicator getCooldownIndicator() {
|
||||||
|
return CooldownIndicator.valueOf(getString("cooldown-indicator", "TITLE").toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReplaceAdventureMode() {
|
||||||
|
return getBoolean("replace-adventure", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReplaceParticles() {
|
||||||
|
return getBoolean("replace-particles", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxBookPages() {
|
||||||
|
return getInt("max-book-pages", 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxBookPageSize() {
|
||||||
|
return getInt("max-book-page-length", 5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URL getDefaultConfigURL() {
|
||||||
|
return getClass().getClassLoader().getResource("viaversion/viarewind.yml");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleConfig(Map<String, Object> map) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getUnsupportedOptions() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.api;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.ViaRewind;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_0_5to1_7_6_10.Protocol1_7_0_5to1_7_6_10;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10TO1_8;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6to1_7_2.Protocol1_7_6to1_7_2;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.Protocol1_8TO1_9;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.Via;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.version.ProtocolVersion;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public interface ViaRewindPlatform {
|
||||||
|
default void init(ViaRewindConfig config) {
|
||||||
|
ViaRewind.init(this, config);
|
||||||
|
|
||||||
|
String version = ViaRewind.class.getPackage().getImplementationVersion();
|
||||||
|
Via.getManager().getSubPlatforms().add(version != null ? version : "UNKNOWN");
|
||||||
|
|
||||||
|
Via.getManager().getProtocolManager().registerProtocol(new Protocol1_8TO1_9(), ProtocolVersion.v1_8, ProtocolVersion.v1_9);
|
||||||
|
Via.getManager().getProtocolManager().registerProtocol(new Protocol1_7_6_10TO1_8(), ProtocolVersion.v1_7_6, ProtocolVersion.v1_8);
|
||||||
|
Via.getManager().getProtocolManager().registerProtocol(new Protocol1_7_0_5to1_7_6_10(), ProtocolVersion.v1_7_1, ProtocolVersion.v1_7_6);
|
||||||
|
|
||||||
|
Via.getManager().getProtocolManager().registerProtocol(new Protocol1_7_6to1_7_2(), ProtocolVersion.v1_7_6, ProtocolVersion.v1_7_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger getLogger();
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.netty;
|
||||||
|
|
||||||
|
import io.netty.channel.ChannelHandler;
|
||||||
|
import io.netty.channel.ChannelHandlerAdapter;
|
||||||
|
|
||||||
|
@ChannelHandler.Sharable
|
||||||
|
public class EmptyChannelHandler extends ChannelHandlerAdapter {
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.netty;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.handler.codec.MessageToByteEncoder;
|
||||||
|
|
||||||
|
public class ForwardMessageToByteEncoder extends MessageToByteEncoder<ByteBuf> {
|
||||||
|
@Override
|
||||||
|
protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) throws Exception {
|
||||||
|
out.writeBytes(msg);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,102 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_0_5to1_7_6_10;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.ClientboundPackets1_7;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.ServerboundPackets1_7;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.AbstractProtocol;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.State;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.remapper.PacketRemapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.remapper.ValueTransformer;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class Protocol1_7_0_5to1_7_6_10 extends AbstractProtocol<ClientboundPackets1_7, ClientboundPackets1_7, ServerboundPackets1_7, ServerboundPackets1_7> {
|
||||||
|
public static final ValueTransformer<String, String> REMOVE_DASHES = new ValueTransformer<String, String>(Type.STRING) {
|
||||||
|
@Override
|
||||||
|
public String transform(PacketWrapper packetWrapper, String s) {
|
||||||
|
return s.replace("-", "");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public Protocol1_7_0_5to1_7_6_10() {
|
||||||
|
super(ClientboundPackets1_7.class, ClientboundPackets1_7.class, ServerboundPackets1_7.class, ServerboundPackets1_7.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void registerPackets() {
|
||||||
|
//Login Success
|
||||||
|
this.registerClientbound(State.LOGIN, 0x02, 0x02, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.STRING, REMOVE_DASHES);
|
||||||
|
map(Type.STRING);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Spawn Player
|
||||||
|
this.registerClientbound(ClientboundPackets1_7.SPAWN_PLAYER, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.STRING, REMOVE_DASHES);
|
||||||
|
map(Type.STRING);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int size = packetWrapper.read(Type.VAR_INT);
|
||||||
|
for (int i = 0; i < size * 3; i++) packetWrapper.read(Type.STRING);
|
||||||
|
});
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.SHORT);
|
||||||
|
map(Types1_7_6_10.METADATA_LIST);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Teams
|
||||||
|
this.registerClientbound(ClientboundPackets1_7.TEAMS, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.STRING);
|
||||||
|
map(Type.BYTE);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
byte mode = packetWrapper.get(Type.BYTE, 0);
|
||||||
|
if (mode == 0 || mode == 2) {
|
||||||
|
packetWrapper.passthrough(Type.STRING);
|
||||||
|
packetWrapper.passthrough(Type.STRING);
|
||||||
|
packetWrapper.passthrough(Type.STRING);
|
||||||
|
packetWrapper.passthrough(Type.BYTE);
|
||||||
|
}
|
||||||
|
if (mode == 0 || mode == 3 || mode == 4) {
|
||||||
|
List<String> entryList = new ArrayList<>();
|
||||||
|
int size = packetWrapper.read(Type.SHORT);
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
entryList.add(packetWrapper.read(Type.STRING));
|
||||||
|
}
|
||||||
|
|
||||||
|
entryList = entryList.stream()
|
||||||
|
.map(it -> it.length() > 16 ? it.substring(0, 16) : it)
|
||||||
|
.distinct()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
packetWrapper.write(Type.SHORT, (short) entryList.size());
|
||||||
|
for (String entry : entryList) {
|
||||||
|
packetWrapper.write(Type.STRING, entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(UserConnection userConnection) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.ClientboundPacketType;
|
||||||
|
|
||||||
|
public enum ClientboundPackets1_7 implements ClientboundPacketType {
|
||||||
|
KEEP_ALIVE, // 0x00
|
||||||
|
JOIN_GAME, // 0x01
|
||||||
|
CHAT_MESSAGE, // 0x02
|
||||||
|
TIME_UPDATE, // 0x03
|
||||||
|
ENTITY_EQUIPMENT, // 0x04
|
||||||
|
SPAWN_POSITION, // 0x05
|
||||||
|
UPDATE_HEALTH, // 0x06
|
||||||
|
RESPAWN, // 0x07
|
||||||
|
PLAYER_POSITION, // 0x08
|
||||||
|
HELD_ITEM_CHANGE, // 0x09
|
||||||
|
USE_BED, // 0x0A
|
||||||
|
ENTITY_ANIMATION, // 0x0B
|
||||||
|
SPAWN_PLAYER, // 0x0C
|
||||||
|
COLLECT_ITEM, // 0x0D
|
||||||
|
SPAWN_ENTITY, // 0x0E
|
||||||
|
SPAWN_MOB, // 0x0F
|
||||||
|
SPAWN_PAINTING, // 0x10
|
||||||
|
SPAWN_EXPERIENCE_ORB, // 0x11
|
||||||
|
ENTITY_VELOCITY, // 0x12
|
||||||
|
DESTROY_ENTITIES, // 0x13
|
||||||
|
ENTITY_MOVEMENT, // 0x14
|
||||||
|
ENTITY_POSITION, // 0x15
|
||||||
|
ENTITY_ROTATION, // 0x16
|
||||||
|
ENTITY_POSITION_AND_ROTATION, // 0x17
|
||||||
|
ENTITY_TELEPORT, // 0x18
|
||||||
|
ENTITY_HEAD_LOOK, // 0x19
|
||||||
|
ENTITY_STATUS, // 0x1A
|
||||||
|
ATTACH_ENTITY, // 0x1B
|
||||||
|
ENTITY_METADATA, // 0x1C
|
||||||
|
ENTITY_EFFECT, // 0x1D
|
||||||
|
REMOVE_ENTITY_EFFECT, // 0x1E
|
||||||
|
SET_EXPERIENCE, // 0x1F
|
||||||
|
ENTITY_PROPERTIES, // 0x20
|
||||||
|
CHUNK_DATA, // 0x21
|
||||||
|
MULTI_BLOCK_CHANGE, // 0x22
|
||||||
|
BLOCK_CHANGE, // 0x23
|
||||||
|
BLOCK_ACTION, // 0x24
|
||||||
|
BLOCK_BREAK_ANIMATION, // 0x25
|
||||||
|
MAP_BULK_CHUNK, // 0x26
|
||||||
|
EXPLOSION, // 0x27
|
||||||
|
EFFECT, // 0x28
|
||||||
|
NAMED_SOUND, // 0x29
|
||||||
|
SPAWN_PARTICLE, // 0x2A
|
||||||
|
GAME_EVENT, // 0x2B
|
||||||
|
SPAWN_GLOBAL_ENTITY, // 0x2C
|
||||||
|
OPEN_WINDOW, // 0x2D
|
||||||
|
CLOSE_WINDOW, // 0x2E
|
||||||
|
SET_SLOT, // 0x2F
|
||||||
|
WINDOW_ITEMS, // 0x30
|
||||||
|
WINDOW_PROPERTY, // 0x31
|
||||||
|
WINDOW_CONFIRMATION, // 0x32
|
||||||
|
UPDATE_SIGN, // 0x33
|
||||||
|
MAP_DATA, // 0x34
|
||||||
|
BLOCK_ENTITY_DATA, // 0x35
|
||||||
|
OPEN_SIGN_EDITOR, // 0x36
|
||||||
|
STATISTICS, // 0x37
|
||||||
|
PLAYER_INFO, // 0x38
|
||||||
|
PLAYER_ABILITIES, // 0x39
|
||||||
|
TAB_COMPLETE, // 0x3A
|
||||||
|
SCOREBOARD_OBJECTIVE, // 0x3B
|
||||||
|
UPDATE_SCORE, // 0x3C
|
||||||
|
DISPLAY_SCOREBOARD, // 0x3D
|
||||||
|
TEAMS, // 0x3E
|
||||||
|
PLUGIN_MESSAGE, // 0x3F
|
||||||
|
DISCONNECT; // 0x40
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return ordinal();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,111 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.packets.*;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.provider.CompressionHandlerProvider;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.storage.*;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.Ticker;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.Via;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.platform.providers.ViaProviders;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.AbstractProtocol;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.Direction;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.State;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.remapper.PacketRemapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_8.ServerboundPackets1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
|
||||||
|
|
||||||
|
public class Protocol1_7_6_10TO1_8 extends AbstractProtocol<ClientboundPackets1_8, ClientboundPackets1_7,
|
||||||
|
ServerboundPackets1_8, ServerboundPackets1_7> {
|
||||||
|
|
||||||
|
public Protocol1_7_6_10TO1_8() {
|
||||||
|
super(ClientboundPackets1_8.class, ClientboundPackets1_7.class, ServerboundPackets1_8.class, ServerboundPackets1_7.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void registerPackets() {
|
||||||
|
EntityPackets.register(this);
|
||||||
|
InventoryPackets.register(this);
|
||||||
|
PlayerPackets.register(this);
|
||||||
|
ScoreboardPackets.register(this);
|
||||||
|
SpawnPackets.register(this);
|
||||||
|
WorldPackets.register(this);
|
||||||
|
|
||||||
|
this.registerClientbound(ClientboundPackets1_8.KEEP_ALIVE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT, Type.INT);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.cancelClientbound(ClientboundPackets1_8.SET_COMPRESSION); // unused
|
||||||
|
|
||||||
|
this.registerServerbound(ServerboundPackets1_7.KEEP_ALIVE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.INT, Type.VAR_INT);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Encryption Request
|
||||||
|
this.registerClientbound(State.LOGIN, 0x01, 0x01, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.STRING); //Server ID
|
||||||
|
map(Type.BYTE_ARRAY_PRIMITIVE, Type.SHORT_BYTE_ARRAY); // Public key
|
||||||
|
map(Type.BYTE_ARRAY_PRIMITIVE, Type.SHORT_BYTE_ARRAY); // Verification token
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Set Compression
|
||||||
|
this.registerClientbound(State.LOGIN, 0x03, 0x03, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
Via.getManager().getProviders().get(CompressionHandlerProvider.class)
|
||||||
|
.handleSetCompression(packetWrapper.user(), packetWrapper.read(Type.VAR_INT));
|
||||||
|
packetWrapper.cancel();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Encryption Response
|
||||||
|
this.registerServerbound(State.LOGIN, 0x01, 0x01, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.SHORT_BYTE_ARRAY, Type.BYTE_ARRAY_PRIMITIVE); // Shared secret
|
||||||
|
map(Type.SHORT_BYTE_ARRAY, Type.BYTE_ARRAY_PRIMITIVE); // Verification token
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void transform(Direction direction, State state, PacketWrapper packetWrapper) throws Exception {
|
||||||
|
Via.getManager().getProviders().get(CompressionHandlerProvider.class)
|
||||||
|
.handleTransform(packetWrapper.user());
|
||||||
|
|
||||||
|
super.transform(direction, state, packetWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(UserConnection userConnection) {
|
||||||
|
Ticker.init();
|
||||||
|
|
||||||
|
userConnection.put(new Windows(userConnection));
|
||||||
|
userConnection.put(new EntityTracker(userConnection));
|
||||||
|
userConnection.put(new PlayerPosition(userConnection));
|
||||||
|
userConnection.put(new GameProfileStorage(userConnection));
|
||||||
|
userConnection.put(new Scoreboard(userConnection));
|
||||||
|
userConnection.put(new CompressionSendStorage(userConnection));
|
||||||
|
userConnection.put(new WorldBorder(userConnection));
|
||||||
|
userConnection.put(new PlayerAbilities(userConnection));
|
||||||
|
userConnection.put(new ClientWorld(userConnection));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void register(ViaProviders providers) {
|
||||||
|
providers.register(CompressionHandlerProvider.class, new CompressionHandlerProvider());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.ServerboundPacketType;
|
||||||
|
|
||||||
|
public enum ServerboundPackets1_7 implements ServerboundPacketType {
|
||||||
|
KEEP_ALIVE, // 0x00
|
||||||
|
CHAT_MESSAGE, // 0x01
|
||||||
|
INTERACT_ENTITY, // 0x02
|
||||||
|
PLAYER_MOVEMENT, // 0x03
|
||||||
|
PLAYER_POSITION, // 0x04
|
||||||
|
PLAYER_ROTATION, // 0x05
|
||||||
|
PLAYER_POSITION_AND_ROTATION, // 0x06
|
||||||
|
PLAYER_DIGGING, // 0x07
|
||||||
|
PLAYER_BLOCK_PLACEMENT, // 0x08
|
||||||
|
HELD_ITEM_CHANGE, // 0x09
|
||||||
|
ANIMATION, // 0x0A
|
||||||
|
ENTITY_ACTION, // 0x0B
|
||||||
|
STEER_VEHICLE, // 0x0C
|
||||||
|
CLOSE_WINDOW, // 0x0D
|
||||||
|
CLICK_WINDOW, // 0x0E
|
||||||
|
WINDOW_CONFIRMATION, // 0x0F
|
||||||
|
CREATIVE_INVENTORY_ACTION, // 0x10
|
||||||
|
CLICK_WINDOW_BUTTON, // 0x11
|
||||||
|
UPDATE_SIGN, // 0x12
|
||||||
|
PLAYER_ABILITIES, // 0x13
|
||||||
|
TAB_COMPLETE, // 0x14
|
||||||
|
CLIENT_SETTINGS, // 0x15
|
||||||
|
CLIENT_STATUS, // 0x16
|
||||||
|
PLUGIN_MESSAGE; // 0x17
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return ordinal();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,139 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.chunks;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.items.ReplacementRegistry1_7_6_10to1_8;
|
||||||
|
import com.elevatemc.spigot.viarewind.replacement.Replacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.storage.BlockState;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.types.CustomByteType;
|
||||||
|
|
||||||
|
import java.util.zip.Deflater;
|
||||||
|
|
||||||
|
public class ChunkPacketTransformer {
|
||||||
|
|
||||||
|
private static byte[] transformChunkData(byte[] data, int primaryBitMask, boolean skyLight, boolean groundUp) {
|
||||||
|
int dataSize = 0;
|
||||||
|
|
||||||
|
ByteBuf buf = Unpooled.buffer();
|
||||||
|
ByteBuf blockDataBuf = Unpooled.buffer();
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
if ((primaryBitMask & 1 << i) == 0) continue;
|
||||||
|
byte tmp = 0;
|
||||||
|
for (int j = 0; j < 4096; j++) {
|
||||||
|
short blockData = (short) ((data[(dataSize + 1)] & 0xFF) << 8 | data[dataSize] & 0xFF);
|
||||||
|
dataSize += 2;
|
||||||
|
|
||||||
|
int id = BlockState.extractId(blockData);
|
||||||
|
int meta = BlockState.extractData(blockData);
|
||||||
|
|
||||||
|
Replacement replace = ReplacementRegistry1_7_6_10to1_8.getReplacement(id, meta);
|
||||||
|
|
||||||
|
if (replace != null) {
|
||||||
|
id = replace.getId();
|
||||||
|
meta = replace.replaceData(meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.writeByte(id);
|
||||||
|
|
||||||
|
if (j % 2 == 0) {
|
||||||
|
tmp = (byte) (meta & 0xF);
|
||||||
|
} else {
|
||||||
|
blockDataBuf.writeByte(tmp | (meta & 15) << 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.writeBytes(blockDataBuf);
|
||||||
|
blockDataBuf.release();
|
||||||
|
|
||||||
|
int columnCount = Integer.bitCount(primaryBitMask);
|
||||||
|
|
||||||
|
//Block light
|
||||||
|
buf.writeBytes(data, dataSize, 2048 * columnCount);
|
||||||
|
dataSize += 2048 * columnCount;
|
||||||
|
|
||||||
|
//Sky light
|
||||||
|
if (skyLight) {
|
||||||
|
buf.writeBytes(data, dataSize, 2048 * columnCount);
|
||||||
|
dataSize += 2048 * columnCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (groundUp && dataSize + 256 <= data.length) {
|
||||||
|
buf.writeBytes(data, dataSize, 256);
|
||||||
|
dataSize += 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = new byte[buf.readableBytes()];
|
||||||
|
buf.readBytes(data);
|
||||||
|
buf.release();
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int calcSize(int i, boolean flag, boolean flag1) {
|
||||||
|
int j = i * 2 * 16 * 16 * 16;
|
||||||
|
int k = i * 16 * 16 * 16 / 2;
|
||||||
|
int l = flag ? i * 16 * 16 * 16 / 2 : 0;
|
||||||
|
int i1 = flag1 ? 256 : 0;
|
||||||
|
|
||||||
|
return j + k + l + i1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void transformChunkBulk(PacketWrapper packetWrapper) throws Exception {
|
||||||
|
boolean skyLightSent = packetWrapper.read(Type.BOOLEAN);
|
||||||
|
int columnCount = packetWrapper.read(Type.VAR_INT);
|
||||||
|
int[] chunkX = new int[columnCount];
|
||||||
|
int[] chunkZ = new int[columnCount];
|
||||||
|
int[] primaryBitMask = new int[columnCount];
|
||||||
|
byte[][] data = new byte[columnCount][];
|
||||||
|
|
||||||
|
for (int i = 0; i < columnCount; i++) {
|
||||||
|
chunkX[i] = packetWrapper.read(Type.INT);
|
||||||
|
chunkZ[i] = packetWrapper.read(Type.INT);
|
||||||
|
primaryBitMask[i] = packetWrapper.read(Type.UNSIGNED_SHORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
int totalSize = 0;
|
||||||
|
for (int i = 0; i < columnCount; i++) {
|
||||||
|
int size = calcSize(Integer.bitCount(primaryBitMask[i]), skyLightSent, true);
|
||||||
|
CustomByteType customByteType = new CustomByteType(size);
|
||||||
|
data[i] = transformChunkData(packetWrapper.read(customByteType), primaryBitMask[i], skyLightSent, true);
|
||||||
|
totalSize += data[i].length;
|
||||||
|
}
|
||||||
|
|
||||||
|
packetWrapper.write(Type.SHORT, (short) columnCount);
|
||||||
|
|
||||||
|
byte[] buildBuffer = new byte[totalSize];
|
||||||
|
|
||||||
|
int bufferLocation = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < columnCount; ++i) {
|
||||||
|
System.arraycopy(data[i], 0, buildBuffer, bufferLocation, data[i].length);
|
||||||
|
bufferLocation += data[i].length;
|
||||||
|
}
|
||||||
|
|
||||||
|
Deflater deflater = new Deflater(4);
|
||||||
|
deflater.reset();
|
||||||
|
deflater.setInput(buildBuffer);
|
||||||
|
deflater.finish();
|
||||||
|
byte[] buffer = new byte[buildBuffer.length + 100];
|
||||||
|
int compressedSize = deflater.deflate(buffer);
|
||||||
|
byte[] finalBuffer = new byte[compressedSize];
|
||||||
|
System.arraycopy(buffer, 0, finalBuffer, 0, compressedSize);
|
||||||
|
|
||||||
|
packetWrapper.write(Type.INT, compressedSize);
|
||||||
|
packetWrapper.write(Type.BOOLEAN, skyLightSent);
|
||||||
|
|
||||||
|
CustomByteType customByteType = new CustomByteType(compressedSize);
|
||||||
|
packetWrapper.write(customByteType, finalBuffer);
|
||||||
|
|
||||||
|
for (int i = 0; i < columnCount; i++) {
|
||||||
|
packetWrapper.write(Type.INT, chunkX[i]);
|
||||||
|
packetWrapper.write(Type.INT, chunkZ[i]);
|
||||||
|
packetWrapper.write(Type.SHORT, (short) primaryBitMask[i]);
|
||||||
|
packetWrapper.write(Type.SHORT, (short) 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.chunks;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.chunks.NibbleArray;
|
||||||
|
|
||||||
|
public class ExtendedBlockStorage {
|
||||||
|
private int yBase;
|
||||||
|
private byte[] blockLSBArray;
|
||||||
|
private NibbleArray blockMSBArray;
|
||||||
|
private NibbleArray blockMetadataArray;
|
||||||
|
private NibbleArray blocklightArray;
|
||||||
|
private NibbleArray skylightArray;
|
||||||
|
|
||||||
|
public ExtendedBlockStorage(int paramInt, boolean paramBoolean) {
|
||||||
|
this.yBase = paramInt;
|
||||||
|
this.blockLSBArray = new byte[4096];
|
||||||
|
this.blockMetadataArray = new NibbleArray(this.blockLSBArray.length);
|
||||||
|
this.blocklightArray = new NibbleArray(this.blockLSBArray.length);
|
||||||
|
if (paramBoolean) {
|
||||||
|
this.skylightArray = new NibbleArray(this.blockLSBArray.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getExtBlockMetadata(int paramInt1, int paramInt2, int paramInt3) {
|
||||||
|
return this.blockMetadataArray.get(paramInt1, paramInt2, paramInt3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExtBlockMetadata(int paramInt1, int paramInt2, int paramInt3, int paramInt4) {
|
||||||
|
this.blockMetadataArray.set(paramInt1, paramInt2, paramInt3, paramInt4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getYLocation() {
|
||||||
|
return this.yBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExtSkylightValue(int paramInt1, int paramInt2, int paramInt3, int paramInt4) {
|
||||||
|
this.skylightArray.set(paramInt1, paramInt2, paramInt3, paramInt4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getExtSkylightValue(int paramInt1, int paramInt2, int paramInt3) {
|
||||||
|
return this.skylightArray.get(paramInt1, paramInt2, paramInt3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExtBlocklightValue(int paramInt1, int paramInt2, int paramInt3, int paramInt4) {
|
||||||
|
this.blocklightArray.set(paramInt1, paramInt2, paramInt3, paramInt4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getExtBlocklightValue(int paramInt1, int paramInt2, int paramInt3) {
|
||||||
|
return this.blocklightArray.get(paramInt1, paramInt2, paramInt3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getBlockLSBArray() {
|
||||||
|
return this.blockLSBArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return this.blockMSBArray==null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearMSBArray() {
|
||||||
|
this.blockMSBArray = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NibbleArray getBlockMSBArray() {
|
||||||
|
return this.blockMSBArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NibbleArray getMetadataArray() {
|
||||||
|
return this.blockMetadataArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NibbleArray getBlocklightArray() {
|
||||||
|
return this.blocklightArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NibbleArray getSkylightArray() {
|
||||||
|
return this.skylightArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBlockLSBArray(byte[] paramArrayOfByte) {
|
||||||
|
this.blockLSBArray = paramArrayOfByte;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBlockMSBArray(NibbleArray paramNibbleArray) {
|
||||||
|
this.blockMSBArray = paramNibbleArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBlockMetadataArray(NibbleArray paramNibbleArray) {
|
||||||
|
this.blockMetadataArray = paramNibbleArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBlocklightArray(NibbleArray paramNibbleArray) {
|
||||||
|
this.blocklightArray = paramNibbleArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSkylightArray(NibbleArray paramNibbleArray) {
|
||||||
|
this.skylightArray = paramNibbleArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NibbleArray createBlockMSBArray() {
|
||||||
|
this.blockMSBArray = new NibbleArray(this.blockLSBArray.length);
|
||||||
|
return this.blockMSBArray;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,315 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.entityreplacements;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.ClientboundPackets1_7;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10TO1_8;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.metadata.MetadataRewriter;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types.MetaType1_7_6_10;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
|
||||||
|
import com.elevatemc.spigot.viarewind.replacement.EntityReplacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.PacketUtil;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.math.AABB;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.math.Vector3d;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.entities.Entity1_10Types;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.Metadata;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.types.MetaType1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ArmorStandReplacement implements EntityReplacement {
|
||||||
|
private int entityId;
|
||||||
|
private List<Metadata> datawatcher = new ArrayList<>();
|
||||||
|
private int[] entityIds = null;
|
||||||
|
private double locX, locY, locZ;
|
||||||
|
private State currentState = null;
|
||||||
|
private boolean invisible = false;
|
||||||
|
private boolean nameTagVisible = false;
|
||||||
|
private String name = null;
|
||||||
|
private UserConnection user;
|
||||||
|
private float yaw, pitch;
|
||||||
|
private float headYaw;
|
||||||
|
private boolean small = false;
|
||||||
|
private boolean marker = false;
|
||||||
|
|
||||||
|
public int getEntityId() {
|
||||||
|
return this.entityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum State {
|
||||||
|
HOLOGRAM, ZOMBIE
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArmorStandReplacement(int entityId, UserConnection user) {
|
||||||
|
this.entityId = entityId;
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocation(double x, double y, double z) {
|
||||||
|
if (x != this.locX || y != this.locY || z != this.locZ) {
|
||||||
|
this.locX = x;
|
||||||
|
this.locY = y;
|
||||||
|
this.locZ = z;
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void relMove(double x, double y, double z) {
|
||||||
|
if (x == 0.0 && y == 0.0 && z == 0.0) return;
|
||||||
|
this.locX += x;
|
||||||
|
this.locY += y;
|
||||||
|
this.locZ += z;
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYawPitch(float yaw, float pitch) {
|
||||||
|
if (this.yaw != yaw && this.pitch != pitch || this.headYaw != yaw) {
|
||||||
|
this.yaw = yaw;
|
||||||
|
this.headYaw = yaw;
|
||||||
|
this.pitch = pitch;
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeadYaw(float yaw) {
|
||||||
|
if (this.headYaw != yaw) {
|
||||||
|
this.headYaw = yaw;
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateMetadata(List<Metadata> metadataList) {
|
||||||
|
for (Metadata metadata : metadataList) {
|
||||||
|
datawatcher.removeIf(m -> m.id() == metadata.id());
|
||||||
|
datawatcher.add(metadata);
|
||||||
|
}
|
||||||
|
updateState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateState() {
|
||||||
|
byte flags = 0;
|
||||||
|
byte armorStandFlags = 0;
|
||||||
|
for (Metadata metadata : datawatcher) {
|
||||||
|
if (metadata.id() == 0 && metadata.metaType() == MetaType1_8.Byte) {
|
||||||
|
flags = ((Number) metadata.getValue()).byteValue();
|
||||||
|
} else if (metadata.id() == 2 && metadata.metaType() == MetaType1_8.String) {
|
||||||
|
name = metadata.getValue().toString();
|
||||||
|
if (name != null && name.equals("")) name = null;
|
||||||
|
} else if (metadata.id() == 10 && metadata.metaType() == MetaType1_8.Byte) {
|
||||||
|
armorStandFlags = ((Number) metadata.getValue()).byteValue();
|
||||||
|
} else if (metadata.id() == 3 && metadata.metaType() == MetaType1_8.Byte) {
|
||||||
|
nameTagVisible = ((Number) metadata.getValue()).byteValue() != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
invisible = (flags & 0x20) != 0;
|
||||||
|
small = (armorStandFlags & 0x01) != 0;
|
||||||
|
marker = (armorStandFlags & 0x10) != 0;
|
||||||
|
|
||||||
|
State prevState = currentState;
|
||||||
|
if (invisible && name != null) {
|
||||||
|
currentState = State.HOLOGRAM;
|
||||||
|
} else {
|
||||||
|
currentState = State.ZOMBIE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentState != prevState) {
|
||||||
|
despawn();
|
||||||
|
spawn();
|
||||||
|
} else {
|
||||||
|
updateMetadata();
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateLocation() {
|
||||||
|
if (entityIds == null) return;
|
||||||
|
|
||||||
|
if (currentState == State.ZOMBIE) {
|
||||||
|
updateZombieLocation();
|
||||||
|
} else if (currentState == State.HOLOGRAM) {
|
||||||
|
updateHologramLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateZombieLocation() {
|
||||||
|
PacketWrapper teleport = PacketWrapper.create(ClientboundPackets1_7.ENTITY_TELEPORT, null, user);
|
||||||
|
teleport.write(Type.INT, entityId);
|
||||||
|
teleport.write(Type.INT, (int) (locX * 32.0));
|
||||||
|
teleport.write(Type.INT, (int) (locY * 32.0));
|
||||||
|
teleport.write(Type.INT, (int) (locZ * 32.0));
|
||||||
|
teleport.write(Type.BYTE, (byte) ((yaw / 360f) * 256));
|
||||||
|
teleport.write(Type.BYTE, (byte) ((pitch / 360f) * 256));
|
||||||
|
|
||||||
|
PacketWrapper head = PacketWrapper.create(ClientboundPackets1_7.ENTITY_HEAD_LOOK, null, user);
|
||||||
|
head.write(Type.INT, entityId);
|
||||||
|
head.write(Type.BYTE, (byte) ((headYaw / 360f) * 256));
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(teleport, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
PacketUtil.sendPacket(head, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateHologramLocation() {
|
||||||
|
PacketWrapper detach = PacketWrapper.create(ClientboundPackets1_7.ATTACH_ENTITY, null, user);
|
||||||
|
detach.write(Type.INT, entityIds[1]);
|
||||||
|
detach.write(Type.INT, -1);
|
||||||
|
detach.write(Type.BOOLEAN, false);
|
||||||
|
|
||||||
|
PacketWrapper teleportSkull = PacketWrapper.create(ClientboundPackets1_7.ENTITY_TELEPORT, null, user);
|
||||||
|
teleportSkull.write(Type.INT, entityIds[0]);
|
||||||
|
teleportSkull.write(Type.INT, (int) (locX * 32.0));
|
||||||
|
teleportSkull.write(Type.INT, (int) ((locY + (marker ? 54.85 : small ? 56 : 57)) * 32.0)); //Don't ask me where this offset is coming from
|
||||||
|
teleportSkull.write(Type.INT, (int) (locZ * 32.0));
|
||||||
|
teleportSkull.write(Type.BYTE, (byte) 0);
|
||||||
|
teleportSkull.write(Type.BYTE, (byte) 0);
|
||||||
|
|
||||||
|
PacketWrapper teleportHorse = PacketWrapper.create(ClientboundPackets1_7.ENTITY_TELEPORT, null, user);
|
||||||
|
teleportHorse.write(Type.INT, entityIds[1]);
|
||||||
|
teleportHorse.write(Type.INT, (int) (locX * 32.0));
|
||||||
|
teleportHorse.write(Type.INT, (int) ((locY + 56.75) * 32.0));
|
||||||
|
teleportHorse.write(Type.INT, (int) (locZ * 32.0));
|
||||||
|
teleportHorse.write(Type.BYTE, (byte) 0);
|
||||||
|
teleportHorse.write(Type.BYTE, (byte) 0);
|
||||||
|
|
||||||
|
PacketWrapper attach = PacketWrapper.create(ClientboundPackets1_7.ATTACH_ENTITY, null, user);
|
||||||
|
attach.write(Type.INT, entityIds[1]);
|
||||||
|
attach.write(Type.INT, entityIds[0]);
|
||||||
|
attach.write(Type.BOOLEAN, false);
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(detach, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
PacketUtil.sendPacket(teleportSkull, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
PacketUtil.sendPacket(teleportHorse, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
PacketUtil.sendPacket(attach, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateMetadata() {
|
||||||
|
if (entityIds == null) return;
|
||||||
|
|
||||||
|
PacketWrapper metadataPacket = PacketWrapper.create(ClientboundPackets1_7.ENTITY_METADATA, null, user);
|
||||||
|
|
||||||
|
if (currentState == State.ZOMBIE) {
|
||||||
|
writeZombieMeta(metadataPacket);
|
||||||
|
} else if (currentState == State.HOLOGRAM) {
|
||||||
|
writeHologramMeta(metadataPacket);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(metadataPacket, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeZombieMeta(PacketWrapper metadataPacket) {
|
||||||
|
metadataPacket.write(Type.INT, entityIds[0]);
|
||||||
|
|
||||||
|
List<Metadata> metadataList = new ArrayList<>();
|
||||||
|
for (Metadata metadata : datawatcher) {
|
||||||
|
if (metadata.id() < 0 || metadata.id() > 9) continue;
|
||||||
|
metadataList.add(new Metadata(metadata.id(), metadata.metaType(), metadata.getValue()));
|
||||||
|
}
|
||||||
|
if (small) metadataList.add(new Metadata(12, MetaType1_8.Byte, (byte) 1));
|
||||||
|
MetadataRewriter.transform(Entity1_10Types.EntityType.ZOMBIE, metadataList);
|
||||||
|
|
||||||
|
metadataPacket.write(Types1_7_6_10.METADATA_LIST, metadataList);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeHologramMeta(PacketWrapper metadataPacket) {
|
||||||
|
metadataPacket.write(Type.INT, entityIds[1]);
|
||||||
|
|
||||||
|
List<Metadata> metadataList = new ArrayList<>();
|
||||||
|
metadataList.add(new Metadata(12, MetaType1_7_6_10.Int, -1700000));
|
||||||
|
metadataList.add(new Metadata(10, MetaType1_7_6_10.String, name));
|
||||||
|
metadataList.add(new Metadata(11, MetaType1_7_6_10.Byte, (byte) 1));
|
||||||
|
|
||||||
|
metadataPacket.write(Types1_7_6_10.METADATA_LIST, metadataList);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void spawn() {
|
||||||
|
if (entityIds != null) despawn();
|
||||||
|
|
||||||
|
if (currentState == State.ZOMBIE) {
|
||||||
|
spawnZombie();
|
||||||
|
} else if (currentState == State.HOLOGRAM) {
|
||||||
|
spawnHologram();
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMetadata();
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void spawnZombie() {
|
||||||
|
PacketWrapper spawn = PacketWrapper.create(ClientboundPackets1_7.SPAWN_MOB, null, user);
|
||||||
|
spawn.write(Type.VAR_INT, entityId);
|
||||||
|
spawn.write(Type.UNSIGNED_BYTE, (short) 54);
|
||||||
|
spawn.write(Type.INT, (int) (locX * 32.0));
|
||||||
|
spawn.write(Type.INT, (int) (locY * 32.0));
|
||||||
|
spawn.write(Type.INT, (int) (locZ * 32.0));
|
||||||
|
spawn.write(Type.BYTE, (byte) 0);
|
||||||
|
spawn.write(Type.BYTE, (byte) 0);
|
||||||
|
spawn.write(Type.BYTE, (byte) 0);
|
||||||
|
spawn.write(Type.SHORT, (short) 0);
|
||||||
|
spawn.write(Type.SHORT, (short) 0);
|
||||||
|
spawn.write(Type.SHORT, (short) 0);
|
||||||
|
spawn.write(Types1_7_6_10.METADATA_LIST, new ArrayList<>());
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(spawn, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
|
||||||
|
entityIds = new int[] {entityId};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void spawnHologram() {
|
||||||
|
int[] entityIds = new int[] {entityId, additionalEntityId()};
|
||||||
|
|
||||||
|
PacketWrapper spawnSkull = PacketWrapper.create(ClientboundPackets1_7.SPAWN_ENTITY, null, user);
|
||||||
|
spawnSkull.write(Type.VAR_INT, entityIds[0]);
|
||||||
|
spawnSkull.write(Type.BYTE, (byte) 66);
|
||||||
|
spawnSkull.write(Type.INT, (int) (locX * 32.0));
|
||||||
|
spawnSkull.write(Type.INT, (int) (locY * 32.0));
|
||||||
|
spawnSkull.write(Type.INT, (int) (locZ * 32.0));
|
||||||
|
spawnSkull.write(Type.BYTE, (byte) 0);
|
||||||
|
spawnSkull.write(Type.BYTE, (byte) 0);
|
||||||
|
spawnSkull.write(Type.INT, 0);
|
||||||
|
|
||||||
|
PacketWrapper spawnHorse = PacketWrapper.create(ClientboundPackets1_7.SPAWN_MOB, null, user);
|
||||||
|
spawnHorse.write(Type.VAR_INT, entityIds[1]);
|
||||||
|
spawnHorse.write(Type.UNSIGNED_BYTE, (short) 100);
|
||||||
|
spawnHorse.write(Type.INT, (int) (locX * 32.0));
|
||||||
|
spawnHorse.write(Type.INT, (int) (locY * 32.0));
|
||||||
|
spawnHorse.write(Type.INT, (int) (locZ * 32.0));
|
||||||
|
spawnHorse.write(Type.BYTE, (byte) 0);
|
||||||
|
spawnHorse.write(Type.BYTE, (byte) 0);
|
||||||
|
spawnHorse.write(Type.BYTE, (byte) 0);
|
||||||
|
spawnHorse.write(Type.SHORT, (short) 0);
|
||||||
|
spawnHorse.write(Type.SHORT, (short) 0);
|
||||||
|
spawnHorse.write(Type.SHORT, (short) 0);
|
||||||
|
spawnHorse.write(Types1_7_6_10.METADATA_LIST, new ArrayList<>());
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(spawnSkull, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
PacketUtil.sendPacket(spawnHorse, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
|
||||||
|
this.entityIds = entityIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int additionalEntityId() {
|
||||||
|
return Integer.MAX_VALUE - 16000 - entityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AABB getBoundingBox() {
|
||||||
|
double w = this.small ? 0.25 : 0.5;
|
||||||
|
double h = this.small ? 0.9875 : 1.975;
|
||||||
|
Vector3d min = new Vector3d(this.locX - w / 2, this.locY, this.locZ - w / 2);
|
||||||
|
Vector3d max = new Vector3d(this.locX + w / 2, this.locY + h, this.locZ + w / 2);
|
||||||
|
return new AABB(min, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void despawn() {
|
||||||
|
if (entityIds == null) return;
|
||||||
|
PacketWrapper despawn = PacketWrapper.create(ClientboundPackets1_7.DESTROY_ENTITIES, null, user);
|
||||||
|
despawn.write(Type.BYTE, (byte) entityIds.length);
|
||||||
|
for (int id : entityIds) {
|
||||||
|
despawn.write(Type.INT, id);
|
||||||
|
}
|
||||||
|
entityIds = null;
|
||||||
|
PacketUtil.sendPacket(despawn, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,131 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.entityreplacements;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10TO1_8;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.metadata.MetadataRewriter;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
|
||||||
|
import com.elevatemc.spigot.viarewind.replacement.EntityReplacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.PacketUtil;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.entities.Entity1_10Types;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.Metadata;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class EndermiteReplacement implements EntityReplacement {
|
||||||
|
private int entityId;
|
||||||
|
private List<Metadata> datawatcher = new ArrayList<>();
|
||||||
|
private double locX, locY, locZ;
|
||||||
|
private float yaw, pitch;
|
||||||
|
private float headYaw;
|
||||||
|
private UserConnection user;
|
||||||
|
|
||||||
|
public EndermiteReplacement(int entityId, UserConnection user) {
|
||||||
|
this.entityId = entityId;
|
||||||
|
this.user = user;
|
||||||
|
spawn();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocation(double x, double y, double z) {
|
||||||
|
this.locX = x;
|
||||||
|
this.locY = y;
|
||||||
|
this.locZ = z;
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void relMove(double x, double y, double z) {
|
||||||
|
this.locX += x;
|
||||||
|
this.locY += y;
|
||||||
|
this.locZ += z;
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYawPitch(float yaw, float pitch) {
|
||||||
|
if (this.yaw!=yaw || this.pitch!=pitch) {
|
||||||
|
this.yaw = yaw;
|
||||||
|
this.pitch = pitch;
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeadYaw(float yaw) {
|
||||||
|
if (this.headYaw!=yaw) {
|
||||||
|
this.headYaw = yaw;
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateMetadata(List<Metadata> metadataList) {
|
||||||
|
for (Metadata metadata : metadataList) {
|
||||||
|
datawatcher.removeIf(m -> m.id()==metadata.id());
|
||||||
|
datawatcher.add(metadata);
|
||||||
|
}
|
||||||
|
updateMetadata();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateLocation() {
|
||||||
|
PacketWrapper teleport = PacketWrapper.create(0x18, null, user);
|
||||||
|
teleport.write(Type.INT, entityId);
|
||||||
|
teleport.write(Type.INT, (int) (locX * 32.0));
|
||||||
|
teleport.write(Type.INT, (int) (locY * 32.0));
|
||||||
|
teleport.write(Type.INT, (int) (locZ * 32.0));
|
||||||
|
teleport.write(Type.BYTE, (byte)((yaw / 360f) * 256));
|
||||||
|
teleport.write(Type.BYTE, (byte)((pitch / 360f) * 256));
|
||||||
|
|
||||||
|
PacketWrapper head = PacketWrapper.create(0x19, null, user);
|
||||||
|
head.write(Type.INT, entityId);
|
||||||
|
head.write(Type.BYTE, (byte)((headYaw / 360f) * 256));
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(teleport, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
PacketUtil.sendPacket(head, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateMetadata() {
|
||||||
|
PacketWrapper metadataPacket = PacketWrapper.create(0x1C, null, user);
|
||||||
|
metadataPacket.write(Type.INT, entityId);
|
||||||
|
|
||||||
|
List<Metadata> metadataList = new ArrayList<>();
|
||||||
|
for (Metadata metadata : datawatcher) {
|
||||||
|
metadataList.add(new Metadata(metadata.id(), metadata.metaType(), metadata.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
MetadataRewriter.transform(Entity1_10Types.EntityType.SQUID, metadataList);
|
||||||
|
|
||||||
|
metadataPacket.write(Types1_7_6_10.METADATA_LIST, metadataList);
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(metadataPacket, Protocol1_7_6_10TO1_8.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void spawn() {
|
||||||
|
PacketWrapper spawn = PacketWrapper.create(0x0F, null, user);
|
||||||
|
spawn.write(Type.VAR_INT, entityId);
|
||||||
|
spawn.write(Type.UNSIGNED_BYTE, (short) 60);
|
||||||
|
spawn.write(Type.INT, 0);
|
||||||
|
spawn.write(Type.INT, 0);
|
||||||
|
spawn.write(Type.INT, 0);
|
||||||
|
spawn.write(Type.BYTE, (byte) 0);
|
||||||
|
spawn.write(Type.BYTE, (byte) 0);
|
||||||
|
spawn.write(Type.BYTE, (byte) 0);
|
||||||
|
spawn.write(Type.SHORT, (short) 0);
|
||||||
|
spawn.write(Type.SHORT, (short) 0);
|
||||||
|
spawn.write(Type.SHORT, (short) 0);
|
||||||
|
spawn.write(Types1_7_6_10.METADATA_LIST, new ArrayList<>());
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(spawn, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void despawn() {
|
||||||
|
PacketWrapper despawn = PacketWrapper.create(0x13, null, user);
|
||||||
|
despawn.write(Types1_7_6_10.INT_ARRAY, new int[] {entityId});
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(despawn, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEntityId() {
|
||||||
|
return this.entityId;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,132 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.entityreplacements;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10TO1_8;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.metadata.MetadataRewriter;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
|
||||||
|
import com.elevatemc.spigot.viarewind.replacement.EntityReplacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.PacketUtil;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.entities.Entity1_10Types;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.Metadata;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class GuardianReplacement implements EntityReplacement {
|
||||||
|
private int entityId;
|
||||||
|
private List<Metadata> datawatcher = new ArrayList<>();
|
||||||
|
private double locX, locY, locZ;
|
||||||
|
private float yaw, pitch;
|
||||||
|
private float headYaw;
|
||||||
|
private UserConnection user;
|
||||||
|
|
||||||
|
public GuardianReplacement(int entityId, UserConnection user) {
|
||||||
|
this.entityId = entityId;
|
||||||
|
this.user = user;
|
||||||
|
spawn();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocation(double x, double y, double z) {
|
||||||
|
this.locX = x;
|
||||||
|
this.locY = y;
|
||||||
|
this.locZ = z;
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void relMove(double x, double y, double z) {
|
||||||
|
this.locX += x;
|
||||||
|
this.locY += y;
|
||||||
|
this.locZ += z;
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYawPitch(float yaw, float pitch) {
|
||||||
|
if (this.yaw!=yaw || this.pitch!=pitch) {
|
||||||
|
this.yaw = yaw;
|
||||||
|
this.pitch = pitch;
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeadYaw(float yaw) {
|
||||||
|
if (this.headYaw!=yaw) {
|
||||||
|
this.headYaw = yaw;
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateMetadata(List<Metadata> metadataList) {
|
||||||
|
for (Metadata metadata : metadataList) {
|
||||||
|
datawatcher.removeIf(m -> m.id()==metadata.id());
|
||||||
|
datawatcher.add(metadata);
|
||||||
|
}
|
||||||
|
updateMetadata();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateLocation() {
|
||||||
|
PacketWrapper teleport = PacketWrapper.create(0x18, null, user);
|
||||||
|
teleport.write(Type.INT, entityId);
|
||||||
|
teleport.write(Type.INT, (int) (locX * 32.0));
|
||||||
|
teleport.write(Type.INT, (int) (locY * 32.0));
|
||||||
|
teleport.write(Type.INT, (int) (locZ * 32.0));
|
||||||
|
teleport.write(Type.BYTE, (byte)((yaw / 360f) * 256));
|
||||||
|
teleport.write(Type.BYTE, (byte)((pitch / 360f) * 256));
|
||||||
|
|
||||||
|
PacketWrapper head = PacketWrapper.create(0x19, null, user);
|
||||||
|
head.write(Type.INT, entityId);
|
||||||
|
head.write(Type.BYTE, (byte)((headYaw / 360f) * 256));
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(teleport, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
PacketUtil.sendPacket(head, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateMetadata() {
|
||||||
|
PacketWrapper metadataPacket = PacketWrapper.create(0x1C, null, user);
|
||||||
|
metadataPacket.write(Type.INT, entityId);
|
||||||
|
|
||||||
|
List<Metadata> metadataList = new ArrayList<>();
|
||||||
|
for (Metadata metadata : datawatcher) {
|
||||||
|
if (metadata.id()==16 || metadata.id()==17) continue;
|
||||||
|
metadataList.add(new Metadata(metadata.id(), metadata.metaType(), metadata.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
MetadataRewriter.transform(Entity1_10Types.EntityType.SQUID, metadataList);
|
||||||
|
|
||||||
|
metadataPacket.write(Types1_7_6_10.METADATA_LIST, metadataList);
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(metadataPacket, Protocol1_7_6_10TO1_8.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void spawn() {
|
||||||
|
PacketWrapper spawn = PacketWrapper.create(0x0F, null, user);
|
||||||
|
spawn.write(Type.VAR_INT, entityId);
|
||||||
|
spawn.write(Type.UNSIGNED_BYTE, (short) 94);
|
||||||
|
spawn.write(Type.INT, 0);
|
||||||
|
spawn.write(Type.INT, 0);
|
||||||
|
spawn.write(Type.INT, 0);
|
||||||
|
spawn.write(Type.BYTE, (byte) 0);
|
||||||
|
spawn.write(Type.BYTE, (byte) 0);
|
||||||
|
spawn.write(Type.BYTE, (byte) 0);
|
||||||
|
spawn.write(Type.SHORT, (short) 0);
|
||||||
|
spawn.write(Type.SHORT, (short) 0);
|
||||||
|
spawn.write(Type.SHORT, (short) 0);
|
||||||
|
spawn.write(Types1_7_6_10.METADATA_LIST, new ArrayList<>());
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(spawn, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void despawn() {
|
||||||
|
PacketWrapper despawn = PacketWrapper.create(0x13, null, user);
|
||||||
|
despawn.write(Types1_7_6_10.INT_ARRAY, new int[] {entityId});
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(despawn, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEntityId() {
|
||||||
|
return this.entityId;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,132 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.entityreplacements;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.ClientboundPackets1_7;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10TO1_8;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.metadata.MetadataRewriter;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
|
||||||
|
import com.elevatemc.spigot.viarewind.replacement.EntityReplacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.PacketUtil;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.entities.Entity1_10Types;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.Metadata;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class RabbitReplacement implements EntityReplacement {
|
||||||
|
private int entityId;
|
||||||
|
private List<Metadata> datawatcher = new ArrayList<>();
|
||||||
|
private double locX, locY, locZ;
|
||||||
|
private float yaw, pitch;
|
||||||
|
private float headYaw;
|
||||||
|
private UserConnection user;
|
||||||
|
|
||||||
|
public RabbitReplacement(int entityId, UserConnection user) {
|
||||||
|
this.entityId = entityId;
|
||||||
|
this.user = user;
|
||||||
|
spawn();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocation(double x, double y, double z) {
|
||||||
|
this.locX = x;
|
||||||
|
this.locY = y;
|
||||||
|
this.locZ = z;
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void relMove(double x, double y, double z) {
|
||||||
|
this.locX += x;
|
||||||
|
this.locY += y;
|
||||||
|
this.locZ += z;
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYawPitch(float yaw, float pitch) {
|
||||||
|
if (this.yaw != yaw || this.pitch != pitch) {
|
||||||
|
this.yaw = yaw;
|
||||||
|
this.pitch = pitch;
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeadYaw(float yaw) {
|
||||||
|
if (this.headYaw != yaw) {
|
||||||
|
this.headYaw = yaw;
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateMetadata(List<Metadata> metadataList) {
|
||||||
|
for (Metadata metadata : metadataList) {
|
||||||
|
datawatcher.removeIf(m -> m.id() == metadata.id());
|
||||||
|
datawatcher.add(metadata);
|
||||||
|
}
|
||||||
|
updateMetadata();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateLocation() {
|
||||||
|
PacketWrapper teleport = PacketWrapper.create(ClientboundPackets1_7.ENTITY_TELEPORT, null, user);
|
||||||
|
teleport.write(Type.INT, entityId);
|
||||||
|
teleport.write(Type.INT, (int) (locX * 32.0));
|
||||||
|
teleport.write(Type.INT, (int) (locY * 32.0));
|
||||||
|
teleport.write(Type.INT, (int) (locZ * 32.0));
|
||||||
|
teleport.write(Type.BYTE, (byte) ((yaw / 360f) * 256));
|
||||||
|
teleport.write(Type.BYTE, (byte) ((pitch / 360f) * 256));
|
||||||
|
|
||||||
|
PacketWrapper head = PacketWrapper.create(ClientboundPackets1_7.ENTITY_HEAD_LOOK, null, user);
|
||||||
|
head.write(Type.INT, entityId);
|
||||||
|
head.write(Type.BYTE, (byte) ((headYaw / 360f) * 256));
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(teleport, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
PacketUtil.sendPacket(head, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateMetadata() {
|
||||||
|
PacketWrapper metadataPacket = PacketWrapper.create(ClientboundPackets1_7.ENTITY_METADATA, null, user);
|
||||||
|
metadataPacket.write(Type.INT, entityId);
|
||||||
|
|
||||||
|
List<Metadata> metadataList = new ArrayList<>();
|
||||||
|
for (Metadata metadata : datawatcher) {
|
||||||
|
metadataList.add(new Metadata(metadata.id(), metadata.metaType(), metadata.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
MetadataRewriter.transform(Entity1_10Types.EntityType.CHICKEN, metadataList);
|
||||||
|
|
||||||
|
metadataPacket.write(Types1_7_6_10.METADATA_LIST, metadataList);
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(metadataPacket, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void spawn() {
|
||||||
|
PacketWrapper spawn = PacketWrapper.create(ClientboundPackets1_7.SPAWN_MOB, null, user);
|
||||||
|
spawn.write(Type.VAR_INT, entityId);
|
||||||
|
spawn.write(Type.UNSIGNED_BYTE, (short) 93); // chicken
|
||||||
|
spawn.write(Type.INT, 0);
|
||||||
|
spawn.write(Type.INT, 0);
|
||||||
|
spawn.write(Type.INT, 0);
|
||||||
|
spawn.write(Type.BYTE, (byte) 0);
|
||||||
|
spawn.write(Type.BYTE, (byte) 0);
|
||||||
|
spawn.write(Type.BYTE, (byte) 0);
|
||||||
|
spawn.write(Type.SHORT, (short) 0);
|
||||||
|
spawn.write(Type.SHORT, (short) 0);
|
||||||
|
spawn.write(Type.SHORT, (short) 0);
|
||||||
|
spawn.write(Types1_7_6_10.METADATA_LIST, new ArrayList<>());
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(spawn, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void despawn() {
|
||||||
|
PacketWrapper despawn = PacketWrapper.create(ClientboundPackets1_7.DESTROY_ENTITIES, null, user);
|
||||||
|
despawn.write(Types1_7_6_10.INT_ARRAY, new int[]{entityId});
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(despawn, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEntityId() {
|
||||||
|
return this.entityId;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,118 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.items;
|
||||||
|
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.*;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.ChatUtil;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.Enchantments;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.item.Item;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ItemRewriter {
|
||||||
|
|
||||||
|
public static Item toClient(Item item) {
|
||||||
|
if (item==null) return null;
|
||||||
|
|
||||||
|
CompoundTag tag = item.tag();
|
||||||
|
if (tag==null) item.setTag(tag = new CompoundTag());
|
||||||
|
|
||||||
|
CompoundTag viaVersionTag = new CompoundTag();
|
||||||
|
tag.put("ViaRewind1_7_6_10to1_8", viaVersionTag);
|
||||||
|
|
||||||
|
viaVersionTag.put("id", new ShortTag((short) item.identifier()));
|
||||||
|
viaVersionTag.put("data", new ShortTag(item.data()));
|
||||||
|
|
||||||
|
CompoundTag display = tag.get("display");
|
||||||
|
if (display!=null && display.contains("Name")) {
|
||||||
|
viaVersionTag.put("displayName", new StringTag((String) display.get("Name").getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (display!=null && display.contains("Lore")) {
|
||||||
|
viaVersionTag.put("lore", new ListTag(((ListTag)display.get("Lore")).getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tag.contains("ench") || tag.contains("StoredEnchantments")) {
|
||||||
|
ListTag enchTag = tag.contains("ench") ? tag.get("ench") : tag.get("StoredEnchantments");
|
||||||
|
List<Tag> lore = new ArrayList<>();
|
||||||
|
for (Tag ench : new ArrayList<>(enchTag.getValue())) {
|
||||||
|
short id = ((NumberTag) ((CompoundTag)ench).get("id")).asShort();
|
||||||
|
short lvl = ((NumberTag) ((CompoundTag)ench).get("lvl")).asShort();
|
||||||
|
String s;
|
||||||
|
if (id==8) {
|
||||||
|
s = "§r§7Depth Strider ";
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
enchTag.remove(ench);
|
||||||
|
s += Enchantments.ENCHANTMENTS.getOrDefault(lvl, "enchantment.level." + lvl);
|
||||||
|
lore.add(new StringTag(s));
|
||||||
|
}
|
||||||
|
if (!lore.isEmpty()) {
|
||||||
|
if (display==null) {
|
||||||
|
tag.put("display", display = new CompoundTag());
|
||||||
|
viaVersionTag.put("noDisplay", new ByteTag());
|
||||||
|
}
|
||||||
|
ListTag loreTag = display.get("Lore");
|
||||||
|
if (loreTag==null) display.put("Lore", loreTag = new ListTag(StringTag.class));
|
||||||
|
lore.addAll(loreTag.getValue());
|
||||||
|
loreTag.setValue(lore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.identifier()==387 && tag.contains("pages")) {
|
||||||
|
ListTag pages = tag.get("pages");
|
||||||
|
ListTag oldPages = new ListTag(StringTag.class);
|
||||||
|
viaVersionTag.put("pages", oldPages);
|
||||||
|
|
||||||
|
for (int i = 0; i<pages.size(); i++) {
|
||||||
|
StringTag page = pages.get(i);
|
||||||
|
String value = page.getValue();
|
||||||
|
oldPages.add(new StringTag(value));
|
||||||
|
value = ChatUtil.jsonToLegacy(value);
|
||||||
|
page.setValue(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReplacementRegistry1_7_6_10to1_8.replace(item);
|
||||||
|
|
||||||
|
if (viaVersionTag.size()==2 && (short)viaVersionTag.get("id").getValue()==item.identifier() && (short)viaVersionTag.get("data").getValue()==item.data()) {
|
||||||
|
item.tag().remove("ViaRewind1_7_6_10to1_8");
|
||||||
|
if (item.tag().isEmpty()) item.setTag(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Item toServer(Item item) {
|
||||||
|
if (item==null) return null;
|
||||||
|
|
||||||
|
CompoundTag tag = item.tag();
|
||||||
|
|
||||||
|
if (tag==null || !item.tag().contains("ViaRewind1_7_6_10to1_8")) return item;
|
||||||
|
|
||||||
|
CompoundTag viaVersionTag = tag.remove("ViaRewind1_7_6_10to1_8");
|
||||||
|
|
||||||
|
item.setIdentifier((short) viaVersionTag.get("id").getValue());
|
||||||
|
item.setData((Short) viaVersionTag.get("data").getValue());
|
||||||
|
|
||||||
|
if (viaVersionTag.contains("noDisplay")) tag.remove("display");
|
||||||
|
|
||||||
|
if (viaVersionTag.contains("displayName")) {
|
||||||
|
CompoundTag display = tag.get("display");
|
||||||
|
if (display==null) tag.put("display", display = new CompoundTag());
|
||||||
|
StringTag name = display.get("Name");
|
||||||
|
if (name==null) display.put("Name", new StringTag((String) viaVersionTag.get("displayName").getValue()));
|
||||||
|
else name.setValue((String) viaVersionTag.get("displayName").getValue());
|
||||||
|
} else if (tag.contains("display")) {
|
||||||
|
((CompoundTag)tag.get("display")).remove("Name");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.identifier()==387) {
|
||||||
|
ListTag oldPages = viaVersionTag.get("pages");
|
||||||
|
tag.remove("pages");
|
||||||
|
tag.put("pages", oldPages);
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,105 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.items;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.replacement.Replacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.replacement.ReplacementRegistry;
|
||||||
|
import com.elevatemc.spigot.viarewind.storage.BlockState;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.item.Item;
|
||||||
|
|
||||||
|
public class ReplacementRegistry1_7_6_10to1_8 {
|
||||||
|
private static final ReplacementRegistry registry = new ReplacementRegistry();
|
||||||
|
|
||||||
|
static {
|
||||||
|
registry.registerBlock(176, new Replacement(63));
|
||||||
|
registry.registerBlock(177, new Replacement(68));
|
||||||
|
registry.registerBlock(193, new Replacement(64));
|
||||||
|
registry.registerBlock(194, new Replacement(64));
|
||||||
|
registry.registerBlock(195, new Replacement(64));
|
||||||
|
registry.registerBlock(196, new Replacement(64));
|
||||||
|
registry.registerBlock(197, new Replacement(64));
|
||||||
|
registry.registerBlock(77, 5, new Replacement(69, 6));
|
||||||
|
registry.registerBlock(77, 13, new Replacement(69, 14));
|
||||||
|
registry.registerBlock(77, 0, new Replacement(69, 0));
|
||||||
|
registry.registerBlock(77, 8, new Replacement(69, 8));
|
||||||
|
registry.registerBlock(143, 5, new Replacement(69, 6));
|
||||||
|
registry.registerBlock(143, 13, new Replacement(69, 14));
|
||||||
|
registry.registerBlock(143, 0, new Replacement(69, 0));
|
||||||
|
registry.registerBlock(143, 8, new Replacement(69, 8));
|
||||||
|
registry.registerBlock(178, new Replacement(151));
|
||||||
|
registry.registerBlock(182, 0, new Replacement(44, 1));
|
||||||
|
registry.registerBlock(182, 8, new Replacement(44, 9));
|
||||||
|
|
||||||
|
registry.registerItem(425, new Replacement(323, "Banner"));
|
||||||
|
registry.registerItem(409, new Replacement(406, "Prismarine Shard"));
|
||||||
|
registry.registerItem(410, new Replacement(406, "Prismarine Crystal"));
|
||||||
|
registry.registerItem(416, new Replacement(280, "Armor Stand"));
|
||||||
|
registry.registerItem(423, new Replacement(363, "Raw Mutton"));
|
||||||
|
registry.registerItem(424, new Replacement(364, "Cooked Mutton"));
|
||||||
|
registry.registerItem(411, new Replacement(365, "Raw Rabbit"));
|
||||||
|
registry.registerItem(412, new Replacement(366, "Cooked Rabbit"));
|
||||||
|
registry.registerItem(413, new Replacement(282, "Rabbit Stew"));
|
||||||
|
registry.registerItem(414, new Replacement(375, "Rabbit's Foot"));
|
||||||
|
registry.registerItem(415, new Replacement(334, "Rabbit Hide"));
|
||||||
|
registry.registerItem(373, 8203, new Replacement(373, 0, "Potion of Leaping"));
|
||||||
|
registry.registerItem(373, 8235, new Replacement(373, 0, "Potion of Leaping"));
|
||||||
|
registry.registerItem(373, 8267, new Replacement(373, 0, "Potion of Leaping"));
|
||||||
|
registry.registerItem(373, 16395, new Replacement(373, 0, "Splash Potion of Leaping"));
|
||||||
|
registry.registerItem(373, 16427, new Replacement(373, 0, "Splash Potion of Leaping"));
|
||||||
|
registry.registerItem(373, 16459, new Replacement(373, 0, "Splash Potion of Leaping"));
|
||||||
|
registry.registerItem(383, 30, new Replacement(383, "Spawn ArmorStand"));
|
||||||
|
registry.registerItem(383, 67, new Replacement(383, "Spawn Endermite"));
|
||||||
|
registry.registerItem(383, 68, new Replacement(383, "Spawn Guardian"));
|
||||||
|
registry.registerItem(383, 101, new Replacement(383, "Spawn Rabbit"));
|
||||||
|
registry.registerItem(19, 1, new Replacement(19, 0, "Wet Sponge"));
|
||||||
|
registry.registerItem(182, new Replacement(44, 1, "Red Sandstone Slab"));
|
||||||
|
|
||||||
|
registry.registerItemBlock(166, new Replacement(20, "Barrier"));
|
||||||
|
registry.registerItemBlock(167, new Replacement(96, "Iron Trapdoor"));
|
||||||
|
registry.registerItemBlock(1, 1, new Replacement(1, 0, "Granite"));
|
||||||
|
registry.registerItemBlock(1, 2, new Replacement(1, 0, "Polished Granite"));
|
||||||
|
registry.registerItemBlock(1, 3, new Replacement(1, 0, "Diorite"));
|
||||||
|
registry.registerItemBlock(1, 4, new Replacement(1, 0, "Polished Diorite"));
|
||||||
|
registry.registerItemBlock(1, 5, new Replacement(1, 0, "Andesite"));
|
||||||
|
registry.registerItemBlock(1, 6, new Replacement(1, 0, "Polished Andesite"));
|
||||||
|
registry.registerItemBlock(168, 0, new Replacement(1, 0, "Prismarine"));
|
||||||
|
registry.registerItemBlock(168, 1, new Replacement(98, 0, "Prismarine Bricks"));
|
||||||
|
registry.registerItemBlock(168, 2, new Replacement(98, 1, "Dark Prismarine"));
|
||||||
|
registry.registerItemBlock(169, new Replacement(89, "Sea Lantern"));
|
||||||
|
registry.registerItemBlock(165, new Replacement(95, 5, "Slime Block"));
|
||||||
|
registry.registerItemBlock(179, 0, new Replacement(24, "Red Sandstone"));
|
||||||
|
registry.registerItemBlock(179, 1, new Replacement(24, "Chiseled Red Sandstone"));
|
||||||
|
registry.registerItemBlock(179, 2, new Replacement(24, "Smooth Sandstone"));
|
||||||
|
registry.registerItemBlock(181, new Replacement(43, 1, "Double Red Sandstone Slab"));
|
||||||
|
registry.registerItemBlock(180, new Replacement(128, "Red Sandstone Stairs"));
|
||||||
|
registry.registerItemBlock(188, new Replacement(85, "Spruce Fence"));
|
||||||
|
registry.registerItemBlock(189, new Replacement(85, "Birch Fence"));
|
||||||
|
registry.registerItemBlock(190, new Replacement(85, "Jungle Fence"));
|
||||||
|
registry.registerItemBlock(191, new Replacement(85, "Dark Oak Fence"));
|
||||||
|
registry.registerItemBlock(192, new Replacement(85, "Acacia Fence"));
|
||||||
|
registry.registerItemBlock(183, new Replacement(107, "Spruce Fence Gate"));
|
||||||
|
registry.registerItemBlock(184, new Replacement(107, "Birch Fence Gate"));
|
||||||
|
registry.registerItemBlock(185, new Replacement(107, "Jungle Fence Gate"));
|
||||||
|
registry.registerItemBlock(186, new Replacement(107, "Dark Oak Fence Gate"));
|
||||||
|
registry.registerItemBlock(187, new Replacement(107, "Acacia Fence Gate"));
|
||||||
|
registry.registerItemBlock(427, new Replacement(324, "Spruce Door"));
|
||||||
|
registry.registerItemBlock(428, new Replacement(324, "Birch Door"));
|
||||||
|
registry.registerItemBlock(429, new Replacement(324, "Jungle Door"));
|
||||||
|
registry.registerItemBlock(430, new Replacement(324, "Dark Oak Door"));
|
||||||
|
registry.registerItemBlock(431, new Replacement(324, "Acacia Door"));
|
||||||
|
registry.registerItemBlock(157, new Replacement(28, "Activator Rail"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Item replace(Item item) {
|
||||||
|
return registry.replace(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int replace(int raw) {
|
||||||
|
int data = BlockState.extractData(raw);
|
||||||
|
Replacement replace = registry.replace(BlockState.extractId(raw), data);
|
||||||
|
return replace != null ? BlockState.stateToRaw(replace.getId(), replace.replaceData(data)) : raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Replacement getReplacement(int id, int data) {
|
||||||
|
return registry.replace(id, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.metadata;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_7_6_10.metadata.MetaIndex1_8to1_7_6_10;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.entities.Entity1_10Types;
|
||||||
|
import com.elevatemc.spigot.viaversion.util.Pair;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class MetaIndex1_7_6_10to1_8 {
|
||||||
|
|
||||||
|
private static final HashMap<Pair<Entity1_10Types.EntityType, Integer>, MetaIndex1_8to1_7_6_10> metadataRewrites = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
for (MetaIndex1_8to1_7_6_10 index : MetaIndex1_8to1_7_6_10.values())
|
||||||
|
metadataRewrites.put(new Pair<>(index.getClazz(), index.getNewIndex()), index);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Optional<MetaIndex1_8to1_7_6_10> getIndex(Entity1_10Types.EntityType type, int index) {
|
||||||
|
Pair pair = new Pair<>(type, index);
|
||||||
|
if (metadataRewrites.containsKey(pair)) {
|
||||||
|
return Optional.of(metadataRewrites.get(pair));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MetaIndex1_8to1_7_6_10 searchIndex(Entity1_10Types.EntityType type, int index) {
|
||||||
|
Entity1_10Types.EntityType currentType = type;
|
||||||
|
do {
|
||||||
|
Optional<MetaIndex1_8to1_7_6_10> optMeta = getIndex(currentType, index);
|
||||||
|
|
||||||
|
if (optMeta.isPresent()) {
|
||||||
|
return optMeta.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
currentType = currentType.getParent();
|
||||||
|
} while (currentType != null);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,93 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.metadata;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.ViaRewind;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.items.ItemRewriter;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types.MetaType1_7_6_10;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_7_6_10.metadata.MetaIndex1_8to1_7_6_10;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.entities.Entity1_10Types;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.entities.Entity1_10Types.EntityType;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.item.Item;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.Metadata;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.types.MetaType1_8;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MetadataRewriter {
|
||||||
|
|
||||||
|
public static void transform(Entity1_10Types.EntityType type, List<Metadata> list) {
|
||||||
|
for (Metadata entry : new ArrayList<>(list)) {
|
||||||
|
MetaIndex1_8to1_7_6_10 metaIndex = MetaIndex1_7_6_10to1_8.searchIndex(type, entry.id());
|
||||||
|
try {
|
||||||
|
if (metaIndex == null) throw new Exception("Could not find valid metadata");
|
||||||
|
if (metaIndex.getOldType() == MetaType1_7_6_10.NonExistent) {
|
||||||
|
list.remove(entry);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Object value = entry.getValue();
|
||||||
|
if (!metaIndex.getNewType().type().getOutputClass().isAssignableFrom(value.getClass())) {
|
||||||
|
list.remove(entry);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
entry.setMetaTypeUnsafe(metaIndex.getOldType());
|
||||||
|
entry.setId(metaIndex.getIndex());
|
||||||
|
switch (metaIndex.getOldType()) {
|
||||||
|
case Int:
|
||||||
|
if (metaIndex.getNewType() == MetaType1_8.Byte) {
|
||||||
|
entry.setValue(((Byte) value).intValue());
|
||||||
|
if (metaIndex==MetaIndex1_8to1_7_6_10.ENTITY_AGEABLE_AGE) {
|
||||||
|
if ((Integer) entry.getValue() < 0) {
|
||||||
|
entry.setValue(-25000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (metaIndex.getNewType() == MetaType1_8.Short) {
|
||||||
|
entry.setValue(((Short) value).intValue());
|
||||||
|
}
|
||||||
|
if (metaIndex.getNewType() == MetaType1_8.Int) {
|
||||||
|
entry.setValue(value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Byte:
|
||||||
|
if (metaIndex.getNewType() == MetaType1_8.Int) {
|
||||||
|
entry.setValue(((Integer) value).byteValue());
|
||||||
|
}
|
||||||
|
if (metaIndex.getNewType() == MetaType1_8.Byte) {
|
||||||
|
if (metaIndex==MetaIndex1_8to1_7_6_10.ITEM_FRAME_ROTATION) {
|
||||||
|
value = (Byte)((Integer)((Byte)value / 2)).byteValue();
|
||||||
|
}
|
||||||
|
entry.setValue(value);
|
||||||
|
}
|
||||||
|
if (metaIndex==MetaIndex1_8to1_7_6_10.HUMAN_SKIN_FLAGS) {
|
||||||
|
byte flags = (byte) value;
|
||||||
|
boolean cape = (flags & 0x01) != 0;
|
||||||
|
flags = (byte) (cape ? 0x00 : 0x02);
|
||||||
|
entry.setValue(flags);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Slot:
|
||||||
|
entry.setValue(ItemRewriter.toClient((Item) value));
|
||||||
|
break;
|
||||||
|
case Float:
|
||||||
|
entry.setValue(value);
|
||||||
|
break;
|
||||||
|
case Short:
|
||||||
|
entry.setValue(value);
|
||||||
|
break;
|
||||||
|
case String:
|
||||||
|
entry.setValue(value);
|
||||||
|
break;
|
||||||
|
case Position:
|
||||||
|
entry.setValue(value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ViaRewind.getPlatform().getLogger().warning("[Out] Unhandled MetaDataType: " + metaIndex.getNewType());
|
||||||
|
list.remove(entry);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
list.remove(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,343 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.packets;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10TO1_8;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.items.ItemRewriter;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.metadata.MetadataRewriter;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.storage.EntityTracker;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.storage.GameProfileStorage;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
|
||||||
|
import com.elevatemc.spigot.viarewind.replacement.EntityReplacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.PacketUtil;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.Position;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.entities.Entity1_10Types;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.item.Item;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.Metadata;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.remapper.PacketRemapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.types.version.Types1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class EntityPackets {
|
||||||
|
|
||||||
|
public static void register(Protocol1_7_6_10TO1_8 protocol) {
|
||||||
|
|
||||||
|
/* OUTGOING */
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_EQUIPMENT, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT, Type.INT); //Entity Id
|
||||||
|
map(Type.SHORT); //Slot
|
||||||
|
map(Type.ITEM, Types1_7_6_10.COMPRESSED_NBT_ITEM); //Item
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
Item item = packetWrapper.get(Types1_7_6_10.COMPRESSED_NBT_ITEM, 0);
|
||||||
|
ItemRewriter.toClient(item);
|
||||||
|
packetWrapper.set(Types1_7_6_10.COMPRESSED_NBT_ITEM, 0, item);
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
if (packetWrapper.get(Type.SHORT, 0) > 4) packetWrapper.cancel();
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
if (packetWrapper.isCancelled()) return;
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
UUID uuid = tracker.getPlayerUUID(packetWrapper.get(Type.INT, 0));
|
||||||
|
if (uuid == null) return;
|
||||||
|
Item[] equipment = tracker.getPlayerEquipment(uuid);
|
||||||
|
if (equipment == null) tracker.setPlayerEquipment(uuid, equipment = new Item[5]);
|
||||||
|
equipment[packetWrapper.get(Type.SHORT, 0)] = packetWrapper.get(Types1_7_6_10.COMPRESSED_NBT_ITEM, 0);
|
||||||
|
GameProfileStorage storage = packetWrapper.user().get(GameProfileStorage.class);
|
||||||
|
GameProfileStorage.GameProfile profile = storage.get(uuid);
|
||||||
|
if (profile != null && profile.gamemode == 3) packetWrapper.cancel();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.USE_BED, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT, Type.INT); //Entity Id
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
Position position = packetWrapper.read(Type.POSITION);
|
||||||
|
packetWrapper.write(Type.INT, position.getX());
|
||||||
|
packetWrapper.write(Type.UNSIGNED_BYTE, (short) position.getY());
|
||||||
|
packetWrapper.write(Type.INT, position.getZ());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.COLLECT_ITEM, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT, Type.INT); //Collected Entity ID
|
||||||
|
map(Type.VAR_INT, Type.INT); //Collector Entity ID
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_VELOCITY, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT, Type.INT); //Entity Id
|
||||||
|
map(Type.SHORT); //velX
|
||||||
|
map(Type.SHORT); //velY
|
||||||
|
map(Type.SHORT); //velZ
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.DESTROY_ENTITIES, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int[] entityIds = packetWrapper.read(Type.VAR_INT_ARRAY_PRIMITIVE);
|
||||||
|
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
for (int entityId : entityIds) tracker.removeEntity(entityId);
|
||||||
|
|
||||||
|
while (entityIds.length > 127) {
|
||||||
|
int[] entityIds2 = new int[127];
|
||||||
|
System.arraycopy(entityIds, 0, entityIds2, 0, 127);
|
||||||
|
int[] temp = new int[entityIds.length - 127];
|
||||||
|
System.arraycopy(entityIds, 127, temp, 0, temp.length);
|
||||||
|
entityIds = temp;
|
||||||
|
|
||||||
|
PacketWrapper destroy = PacketWrapper.create(0x13, null, packetWrapper.user());
|
||||||
|
destroy.write(Types1_7_6_10.INT_ARRAY, entityIds2);
|
||||||
|
PacketUtil.sendPacket(destroy, Protocol1_7_6_10TO1_8.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
packetWrapper.write(Types1_7_6_10.INT_ARRAY, entityIds);
|
||||||
|
}); //Entity Id Array
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_MOVEMENT, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT, Type.INT); //Entity Id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_POSITION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT, Type.INT); //Entity Id
|
||||||
|
map(Type.BYTE); //x
|
||||||
|
map(Type.BYTE); //y
|
||||||
|
map(Type.BYTE); //z
|
||||||
|
map(Type.BOOLEAN, Type.NOTHING);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.INT, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
|
||||||
|
if (replacement != null) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
int x = packetWrapper.get(Type.BYTE, 0);
|
||||||
|
int y = packetWrapper.get(Type.BYTE, 1);
|
||||||
|
int z = packetWrapper.get(Type.BYTE, 2);
|
||||||
|
replacement.relMove(x / 32.0, y / 32.0, z / 32.0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_ROTATION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT, Type.INT); //Entity Id
|
||||||
|
map(Type.BYTE); //yaw
|
||||||
|
map(Type.BYTE); //pitch
|
||||||
|
map(Type.BOOLEAN, Type.NOTHING);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.INT, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
|
||||||
|
if (replacement != null) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
int yaw = packetWrapper.get(Type.BYTE, 0);
|
||||||
|
int pitch = packetWrapper.get(Type.BYTE, 1);
|
||||||
|
replacement.setYawPitch(yaw * 360f / 256, pitch * 360f / 256);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_POSITION_AND_ROTATION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT, Type.INT); //Entity Id
|
||||||
|
map(Type.BYTE); //x
|
||||||
|
map(Type.BYTE); //y
|
||||||
|
map(Type.BYTE); //z
|
||||||
|
map(Type.BYTE); //yaw
|
||||||
|
map(Type.BYTE); //pitch
|
||||||
|
map(Type.BOOLEAN,Type.NOTHING);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.INT, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
|
||||||
|
if (replacement != null) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
int x = packetWrapper.get(Type.BYTE, 0);
|
||||||
|
int y = packetWrapper.get(Type.BYTE, 1);
|
||||||
|
int z = packetWrapper.get(Type.BYTE, 2);
|
||||||
|
int yaw = packetWrapper.get(Type.BYTE, 3);
|
||||||
|
int pitch = packetWrapper.get(Type.BYTE, 4);
|
||||||
|
replacement.relMove(x / 32.0, y / 32.0, z / 32.0);
|
||||||
|
replacement.setYawPitch(yaw * 360f / 256, pitch * 360f / 256);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_TELEPORT, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT, Type.INT); //Entity Id
|
||||||
|
map(Type.INT); //x
|
||||||
|
map(Type.INT); //y
|
||||||
|
map(Type.INT); //z
|
||||||
|
map(Type.BYTE); //yaw
|
||||||
|
map(Type.BYTE); //pitch
|
||||||
|
map(Type.BOOLEAN, Type.NOTHING);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.INT, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
Entity1_10Types.EntityType type = tracker.getClientEntityTypes().get(entityId);
|
||||||
|
if (type == Entity1_10Types.EntityType.MINECART_ABSTRACT) {
|
||||||
|
int y = packetWrapper.get(Type.INT, 2);
|
||||||
|
y += 12;
|
||||||
|
packetWrapper.set(Type.INT, 2, y);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.INT, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
|
||||||
|
if (replacement != null) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
int x = packetWrapper.get(Type.INT, 1);
|
||||||
|
int y = packetWrapper.get(Type.INT, 2);
|
||||||
|
int z = packetWrapper.get(Type.INT, 3);
|
||||||
|
int yaw = packetWrapper.get(Type.BYTE, 0);
|
||||||
|
int pitch = packetWrapper.get(Type.BYTE, 1);
|
||||||
|
replacement.setLocation(x / 32.0, y / 32.0, z / 32.0);
|
||||||
|
replacement.setYawPitch(yaw * 360f / 256, pitch * 360f / 256);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_HEAD_LOOK, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT, Type.INT); //Entity Id
|
||||||
|
map(Type.BYTE); //Head yaw
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.INT, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
|
||||||
|
if (replacement != null) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
int yaw = packetWrapper.get(Type.BYTE, 0);
|
||||||
|
replacement.setHeadYaw(yaw * 360f / 256);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.ATTACH_ENTITY, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.BOOLEAN);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
boolean leash = packetWrapper.get(Type.BOOLEAN, 0);
|
||||||
|
if (leash) return;
|
||||||
|
int passenger = packetWrapper.get(Type.INT, 0);
|
||||||
|
int vehicle = packetWrapper.get(Type.INT, 1);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
tracker.setPassenger(vehicle, passenger);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_METADATA, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT, Type.INT); //Entity Id
|
||||||
|
map(Types1_8.METADATA_LIST, Types1_7_6_10.METADATA_LIST); //Metadata
|
||||||
|
handler(wrapper -> {
|
||||||
|
List<Metadata> metadataList = wrapper.get(Types1_7_6_10.METADATA_LIST, 0);
|
||||||
|
int entityId = wrapper.get(Type.INT, 0);
|
||||||
|
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
|
||||||
|
if (tracker.getClientEntityTypes().containsKey(entityId)) {
|
||||||
|
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
|
||||||
|
if (replacement != null) {
|
||||||
|
wrapper.cancel();
|
||||||
|
replacement.updateMetadata(metadataList);
|
||||||
|
} else {
|
||||||
|
MetadataRewriter.transform(tracker.getClientEntityTypes().get(entityId), metadataList);
|
||||||
|
if (metadataList.isEmpty()) wrapper.cancel();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tracker.addMetadataToBuffer(entityId, metadataList);
|
||||||
|
wrapper.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_EFFECT, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT, Type.INT); //Entity Id
|
||||||
|
map(Type.BYTE); //Effect Id
|
||||||
|
map(Type.BYTE); //Amplifier
|
||||||
|
map(Type.VAR_INT, Type.SHORT); //Duration
|
||||||
|
map(Type.BYTE, Type.NOTHING); //Hide Particles
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.REMOVE_ENTITY_EFFECT, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT, Type.INT); //Entity Id
|
||||||
|
map(Type.BYTE); //Effect Id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_PROPERTIES, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT, Type.INT); //Entity Id
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.INT, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
if (tracker.getEntityReplacement(entityId) != null) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int amount = packetWrapper.passthrough(Type.INT);
|
||||||
|
for (int i = 0; i < amount; i++) {
|
||||||
|
packetWrapper.passthrough(Type.STRING);
|
||||||
|
packetWrapper.passthrough(Type.DOUBLE);
|
||||||
|
int modifierlength = packetWrapper.read(Type.VAR_INT);
|
||||||
|
packetWrapper.write(Type.SHORT, (short) modifierlength);
|
||||||
|
for (int j = 0; j < modifierlength; j++) {
|
||||||
|
packetWrapper.passthrough(Type.UUID);
|
||||||
|
packetWrapper.passthrough(Type.DOUBLE);
|
||||||
|
packetWrapper.passthrough(Type.BYTE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.cancelClientbound(ClientboundPackets1_8.UPDATE_ENTITY_NBT);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,270 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.packets;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10TO1_8;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.ServerboundPackets1_7;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.items.ItemRewriter;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.storage.EntityTracker;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.storage.GameProfileStorage;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.storage.Windows;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.ChatUtil;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.item.Item;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.remapper.PacketRemapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class InventoryPackets {
|
||||||
|
|
||||||
|
public static void register(Protocol1_7_6_10TO1_8 protocol) {
|
||||||
|
|
||||||
|
/* OUTGOING */
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.OPEN_WINDOW, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
short windowId = packetWrapper.passthrough(Type.UNSIGNED_BYTE);
|
||||||
|
String windowType = packetWrapper.read(Type.STRING);
|
||||||
|
short windowtypeId = (short) Windows.getInventoryType(windowType);
|
||||||
|
packetWrapper.user().get(Windows.class).types.put(windowId, windowtypeId);
|
||||||
|
packetWrapper.write(Type.UNSIGNED_BYTE, windowtypeId);
|
||||||
|
|
||||||
|
JsonElement titleComponent = packetWrapper.read(Type.COMPONENT); //Title
|
||||||
|
String title = ChatUtil.jsonToLegacy(titleComponent);
|
||||||
|
title = ChatUtil.removeUnusedColor(title, '8');
|
||||||
|
if (title.length() > 32) {
|
||||||
|
title = title.substring(0, 32);
|
||||||
|
}
|
||||||
|
packetWrapper.write(Type.STRING, title); //Window title
|
||||||
|
|
||||||
|
packetWrapper.passthrough(Type.UNSIGNED_BYTE);
|
||||||
|
packetWrapper.write(Type.BOOLEAN, true);
|
||||||
|
if (windowtypeId == 11) packetWrapper.passthrough(Type.INT); //Entity Id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.CLOSE_WINDOW, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
short windowsId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
|
||||||
|
packetWrapper.user().get(Windows.class).remove(windowsId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.SET_SLOT, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
short windowId = packetWrapper.read(Type.UNSIGNED_BYTE); //Window Id
|
||||||
|
short windowType = packetWrapper.user().get(Windows.class).get(windowId);
|
||||||
|
packetWrapper.write(Type.UNSIGNED_BYTE, (short) windowId);
|
||||||
|
short slot = packetWrapper.read(Type.SHORT);
|
||||||
|
if (windowType == 4) {
|
||||||
|
if (slot == 1) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
return;
|
||||||
|
} else if (slot >= 2) {
|
||||||
|
slot -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
packetWrapper.write(Type.SHORT, slot); //Slot
|
||||||
|
});
|
||||||
|
map(Type.ITEM, Types1_7_6_10.COMPRESSED_NBT_ITEM); //Item
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
Item item = packetWrapper.get(Types1_7_6_10.COMPRESSED_NBT_ITEM, 0);
|
||||||
|
ItemRewriter.toClient(item);
|
||||||
|
packetWrapper.set(Types1_7_6_10.COMPRESSED_NBT_ITEM, 0, item);
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
short windowId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
|
||||||
|
if (windowId != 0) return;
|
||||||
|
short slot = packetWrapper.get(Type.SHORT, 0);
|
||||||
|
if (slot < 5 || slot > 8) return;
|
||||||
|
Item item = packetWrapper.get(Types1_7_6_10.COMPRESSED_NBT_ITEM, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
UUID uuid = packetWrapper.user().getProtocolInfo().getUuid();
|
||||||
|
Item[] equipment = tracker.getPlayerEquipment(uuid);
|
||||||
|
if (equipment == null) {
|
||||||
|
tracker.setPlayerEquipment(uuid, equipment = new Item[5]);
|
||||||
|
}
|
||||||
|
equipment[9 - slot] = item;
|
||||||
|
if (tracker.getGamemode() == 3) packetWrapper.cancel();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.WINDOW_ITEMS, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
short windowId = packetWrapper.read(Type.UNSIGNED_BYTE); //Window Id
|
||||||
|
short windowType = packetWrapper.user().get(Windows.class).get(windowId);
|
||||||
|
packetWrapper.write(Type.UNSIGNED_BYTE, windowId);
|
||||||
|
Item[] items = packetWrapper.read(Type.ITEM_ARRAY);
|
||||||
|
if (windowType == 4) {
|
||||||
|
Item[] old = items;
|
||||||
|
items = new Item[old.length - 1];
|
||||||
|
items[0] = old[0];
|
||||||
|
System.arraycopy(old, 2, items, 1, old.length - 3);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < items.length; i++) items[i] = ItemRewriter.toClient(items[i]);
|
||||||
|
packetWrapper.write(Types1_7_6_10.COMPRESSED_NBT_ITEM_ARRAY, items); //Items
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
short windowId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
|
||||||
|
if (windowId != 0) return;
|
||||||
|
Item[] items = packetWrapper.get(Types1_7_6_10.COMPRESSED_NBT_ITEM_ARRAY, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
UUID uuid = packetWrapper.user().getProtocolInfo().getUuid();
|
||||||
|
Item[] equipment = tracker.getPlayerEquipment(uuid);
|
||||||
|
if (equipment == null) {
|
||||||
|
tracker.setPlayerEquipment(uuid, equipment = new Item[5]);
|
||||||
|
}
|
||||||
|
for (int i = 5; i < 9; i++) {
|
||||||
|
equipment[9 - i] = items[i];
|
||||||
|
if (tracker.getGamemode() == 3) items[i] = null;
|
||||||
|
}
|
||||||
|
if (tracker.getGamemode() == 3) {
|
||||||
|
GameProfileStorage.GameProfile profile = packetWrapper.user().get(GameProfileStorage.class).get(uuid);
|
||||||
|
if (profile != null) items[5] = profile.getSkull();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.WINDOW_PROPERTY, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
map(Type.SHORT);
|
||||||
|
map(Type.SHORT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
short windowId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
|
||||||
|
Windows windows = packetWrapper.user().get(Windows.class);
|
||||||
|
short windowType = windows.get(windowId);
|
||||||
|
|
||||||
|
short property = packetWrapper.get(Type.SHORT, 0);
|
||||||
|
short value = packetWrapper.get(Type.SHORT, 1);
|
||||||
|
|
||||||
|
if (windowType == -1) return;
|
||||||
|
if (windowType == 2) { //Furnace
|
||||||
|
Windows.Furnace furnace = windows.furnace.computeIfAbsent(windowId, x -> new Windows.Furnace());
|
||||||
|
if (property == 0 || property == 1) {
|
||||||
|
if (property == 0) {
|
||||||
|
furnace.setFuelLeft(value);
|
||||||
|
} else {
|
||||||
|
furnace.setMaxFuel(value);
|
||||||
|
}
|
||||||
|
if (furnace.getMaxFuel() == 0) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
value = (short) (200 * furnace.getFuelLeft() / furnace.getMaxFuel());
|
||||||
|
packetWrapper.set(Type.SHORT, 0, (short) 1);
|
||||||
|
packetWrapper.set(Type.SHORT, 1, value);
|
||||||
|
} else if (property == 2 || property == 3) {
|
||||||
|
if (property == 2) {
|
||||||
|
furnace.setProgress(value);
|
||||||
|
} else {
|
||||||
|
furnace.setMaxProgress(value);
|
||||||
|
}
|
||||||
|
if (furnace.getMaxProgress() == 0) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
value = (short) (200 * furnace.getProgress() / furnace.getMaxProgress());
|
||||||
|
packetWrapper.set(Type.SHORT, 0, (short) 0);
|
||||||
|
packetWrapper.set(Type.SHORT, 1, value);
|
||||||
|
}
|
||||||
|
} else if (windowType == 4) { //Enchanting Table
|
||||||
|
if (property > 2) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (windowType == 8) {
|
||||||
|
windows.levelCost = value;
|
||||||
|
windows.anvilId = windowId;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* INCOMING */
|
||||||
|
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_7.CLOSE_WINDOW, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
short windowsId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
|
||||||
|
packetWrapper.user().get(Windows.class).remove(windowsId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_7.CLICK_WINDOW, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
short windowId = packetWrapper.read(Type.BYTE); //Window Id
|
||||||
|
packetWrapper.write(Type.UNSIGNED_BYTE, windowId);
|
||||||
|
short windowType = packetWrapper.user().get(Windows.class).get(windowId);
|
||||||
|
short slot = packetWrapper.read(Type.SHORT);
|
||||||
|
if (windowType == 4) {
|
||||||
|
if (slot > 0) {
|
||||||
|
slot += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
packetWrapper.write(Type.SHORT, slot);
|
||||||
|
});
|
||||||
|
map(Type.BYTE); //Button
|
||||||
|
map(Type.SHORT); //Action Number
|
||||||
|
map(Type.BYTE); //Mode
|
||||||
|
map(Types1_7_6_10.COMPRESSED_NBT_ITEM, Type.ITEM);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
Item item = packetWrapper.get(Type.ITEM, 0);
|
||||||
|
ItemRewriter.toServer(item);
|
||||||
|
packetWrapper.set(Type.ITEM, 0, item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
Completely useless, transaction packet have been always 1:1, until 1.17 removed them
|
||||||
|
This code will break anticheat support.
|
||||||
|
*/
|
||||||
|
/*protocol.registerServerbound(ServerboundPackets1_7.WINDOW_CONFIRMATION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.SHORT);
|
||||||
|
map(Type.BOOLEAN);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int action = packetWrapper.get(Type.SHORT, 0);
|
||||||
|
if (action == -89) packetWrapper.cancel();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
|
||||||
|
//Creative Inventory Action
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_7.CREATIVE_INVENTORY_ACTION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.SHORT); //Slot
|
||||||
|
map(Types1_7_6_10.COMPRESSED_NBT_ITEM, Type.ITEM); //Item
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
Item item = packetWrapper.get(Type.ITEM, 0);
|
||||||
|
ItemRewriter.toServer(item);
|
||||||
|
packetWrapper.set(Type.ITEM, 0, item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,923 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.packets;
|
||||||
|
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import com.elevatemc.spigot.viarewind.ViaRewind;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.ClientboundPackets1_7;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10TO1_8;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.ServerboundPackets1_7;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.entityreplacements.ArmorStandReplacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.items.ItemRewriter;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.provider.TitleRenderProvider;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.storage.*;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
|
||||||
|
import com.elevatemc.spigot.viarewind.replacement.EntityReplacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.ChatUtil;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.PacketUtil;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.Utils;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.math.AABB;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.math.Ray3d;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.math.RayTracing;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.math.Vector3d;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.Via;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.Position;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.entities.Entity1_10Types;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.item.Item;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.remapper.PacketRemapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class PlayerPackets {
|
||||||
|
|
||||||
|
public static void register(Protocol1_7_6_10TO1_8 protocol) {
|
||||||
|
|
||||||
|
/* OUTGOING */
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.JOIN_GAME, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.INT); //Entiy Id
|
||||||
|
map(Type.UNSIGNED_BYTE); //Gamemode
|
||||||
|
map(Type.BYTE); //Dimension
|
||||||
|
map(Type.UNSIGNED_BYTE); //Difficulty
|
||||||
|
map(Type.UNSIGNED_BYTE); //Max players
|
||||||
|
map(Type.STRING); //Level Type
|
||||||
|
map(Type.BOOLEAN, Type.NOTHING);//Reduced Debug Info
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
if (!ViaRewind.getConfig().isReplaceAdventureMode()) return;
|
||||||
|
if (packetWrapper.get(Type.UNSIGNED_BYTE, 0) == 2) {
|
||||||
|
packetWrapper.set(Type.UNSIGNED_BYTE, 0, (short) 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
tracker.setGamemode(packetWrapper.get(Type.UNSIGNED_BYTE, 0));
|
||||||
|
tracker.setPlayerId(packetWrapper.get(Type.INT, 0));
|
||||||
|
tracker.getClientEntityTypes().put(tracker.getPlayerId(), Entity1_10Types.EntityType.ENTITY_HUMAN);
|
||||||
|
tracker.setDimension(packetWrapper.get(Type.BYTE, 0));
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
ClientWorld world = packetWrapper.user().get(ClientWorld.class);
|
||||||
|
world.setEnvironment(packetWrapper.get(Type.BYTE, 0));
|
||||||
|
});
|
||||||
|
handler(wrapper -> {
|
||||||
|
// Reset on Velocity server change
|
||||||
|
wrapper.user().put(new Scoreboard(wrapper.user()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.CHAT_MESSAGE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.COMPONENT); //Chat Message
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int position = packetWrapper.read(Type.BYTE);
|
||||||
|
if (position == 2) packetWrapper.cancel();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_POSITION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
Position position = packetWrapper.read(Type.POSITION);
|
||||||
|
packetWrapper.write(Type.INT, position.getX());
|
||||||
|
packetWrapper.write(Type.INT, (int) position.getY());
|
||||||
|
packetWrapper.write(Type.INT, position.getZ());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.UPDATE_HEALTH, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.FLOAT); //Health
|
||||||
|
map(Type.VAR_INT, Type.SHORT); //Food
|
||||||
|
map(Type.FLOAT); //Food Saturation
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.RESPAWN, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
map(Type.STRING);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
if (!ViaRewind.getConfig().isReplaceAdventureMode()) return;
|
||||||
|
if (packetWrapper.get(Type.UNSIGNED_BYTE, 1) == 2) {
|
||||||
|
packetWrapper.set(Type.UNSIGNED_BYTE, 1, (short) 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
tracker.setGamemode(packetWrapper.get(Type.UNSIGNED_BYTE, 1));
|
||||||
|
if (tracker.getDimension() != packetWrapper.get(Type.INT, 0)) {
|
||||||
|
tracker.setDimension(packetWrapper.get(Type.INT, 0));
|
||||||
|
tracker.clearEntities();
|
||||||
|
tracker.getClientEntityTypes().put(tracker.getPlayerId(), Entity1_10Types.EntityType.ENTITY_HUMAN);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
ClientWorld world = packetWrapper.user().get(ClientWorld.class);
|
||||||
|
world.setEnvironment(packetWrapper.get(Type.INT, 0));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.PLAYER_POSITION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.DOUBLE); //x
|
||||||
|
map(Type.DOUBLE); //y
|
||||||
|
map(Type.DOUBLE); //z
|
||||||
|
map(Type.FLOAT); //yaw
|
||||||
|
map(Type.FLOAT); //pitch
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
PlayerPosition playerPosition = packetWrapper.user().get(PlayerPosition.class);
|
||||||
|
playerPosition.setPositionPacketReceived(true);
|
||||||
|
|
||||||
|
int flags = packetWrapper.read(Type.BYTE);
|
||||||
|
if ((flags & 0x01) == 0x01) {
|
||||||
|
double x = packetWrapper.get(Type.DOUBLE, 0);
|
||||||
|
x += playerPosition.getPosX();
|
||||||
|
packetWrapper.set(Type.DOUBLE, 0, x);
|
||||||
|
}
|
||||||
|
double y = packetWrapper.get(Type.DOUBLE, 1);
|
||||||
|
if ((flags & 0x02) == 0x02) {
|
||||||
|
y += playerPosition.getPosY();
|
||||||
|
}
|
||||||
|
playerPosition.setReceivedPosY(y);
|
||||||
|
y += (double) 1.62F;
|
||||||
|
packetWrapper.set(Type.DOUBLE, 1, y);
|
||||||
|
if ((flags & 0x04) == 0x04) {
|
||||||
|
double z = packetWrapper.get(Type.DOUBLE, 2);
|
||||||
|
z += playerPosition.getPosZ();
|
||||||
|
packetWrapper.set(Type.DOUBLE, 2, z);
|
||||||
|
}
|
||||||
|
if ((flags & 0x08) == 0x08) {
|
||||||
|
float yaw = packetWrapper.get(Type.FLOAT, 0);
|
||||||
|
yaw += playerPosition.getYaw();
|
||||||
|
packetWrapper.set(Type.FLOAT, 0, yaw);
|
||||||
|
}
|
||||||
|
if ((flags & 0x10) == 0x10) {
|
||||||
|
float pitch = packetWrapper.get(Type.FLOAT, 1);
|
||||||
|
pitch += playerPosition.getPitch();
|
||||||
|
packetWrapper.set(Type.FLOAT, 1, pitch);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
PlayerPosition playerPosition = packetWrapper.user().get(PlayerPosition.class);
|
||||||
|
packetWrapper.write(Type.BOOLEAN, playerPosition.isOnGround());
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
if (tracker.getSpectating() != tracker.getPlayerId()) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.SET_EXPERIENCE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.FLOAT); //Experience bar
|
||||||
|
map(Type.VAR_INT, Type.SHORT); //Level
|
||||||
|
map(Type.VAR_INT, Type.SHORT); //Total Experience
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.GAME_EVENT, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int mode = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
|
||||||
|
if (mode != 3) return;
|
||||||
|
int gamemode = packetWrapper.get(Type.FLOAT, 0).intValue();
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
if (gamemode == 3 || tracker.getGamemode() == 3) {
|
||||||
|
UUID uuid = packetWrapper.user().getProtocolInfo().getUuid();
|
||||||
|
Item[] equipment;
|
||||||
|
if (gamemode == 3) {
|
||||||
|
GameProfileStorage.GameProfile profile = packetWrapper.user().get(GameProfileStorage.class).get(uuid);
|
||||||
|
equipment = new Item[5];
|
||||||
|
equipment[4] = profile.getSkull();
|
||||||
|
} else {
|
||||||
|
equipment = tracker.getPlayerEquipment(uuid);
|
||||||
|
if (equipment == null) equipment = new Item[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i < 5; i++) {
|
||||||
|
PacketWrapper setSlot = PacketWrapper.create(0x2F, null, packetWrapper.user());
|
||||||
|
setSlot.write(Type.BYTE, (byte) 0);
|
||||||
|
setSlot.write(Type.SHORT, (short) (9 - i));
|
||||||
|
setSlot.write(Types1_7_6_10.COMPRESSED_NBT_ITEM, equipment[i]);
|
||||||
|
PacketUtil.sendPacket(setSlot, Protocol1_7_6_10TO1_8.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int mode = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
|
||||||
|
if (mode == 3) {
|
||||||
|
int gamemode = packetWrapper.get(Type.FLOAT, 0).intValue();
|
||||||
|
if (gamemode == 2 && ViaRewind.getConfig().isReplaceAdventureMode()) {
|
||||||
|
gamemode = 0;
|
||||||
|
packetWrapper.set(Type.FLOAT, 0, 0.0f);
|
||||||
|
}
|
||||||
|
packetWrapper.user().get(EntityTracker.class).setGamemode(gamemode);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.OPEN_SIGN_EDITOR, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
Position position = packetWrapper.read(Type.POSITION);
|
||||||
|
packetWrapper.write(Type.INT, position.getX());
|
||||||
|
packetWrapper.write(Type.INT, position.getY());
|
||||||
|
packetWrapper.write(Type.INT, position.getZ());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.PLAYER_INFO, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
int action = packetWrapper.read(Type.VAR_INT);
|
||||||
|
int count = packetWrapper.read(Type.VAR_INT);
|
||||||
|
GameProfileStorage gameProfileStorage = packetWrapper.user().get(GameProfileStorage.class);
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
UUID uuid = packetWrapper.read(Type.UUID);
|
||||||
|
if (action == 0) {
|
||||||
|
String name = packetWrapper.read(Type.STRING);
|
||||||
|
|
||||||
|
GameProfileStorage.GameProfile gameProfile = gameProfileStorage.get(uuid);
|
||||||
|
if (gameProfile == null) gameProfile = gameProfileStorage.put(uuid, name);
|
||||||
|
|
||||||
|
int propertyCount = packetWrapper.read(Type.VAR_INT);
|
||||||
|
while (propertyCount-- > 0) {
|
||||||
|
gameProfile.properties.add(new GameProfileStorage.Property(packetWrapper.read(Type.STRING), packetWrapper.read(Type.STRING), packetWrapper.read(Type.BOOLEAN) ? packetWrapper.read(Type.STRING) : null));
|
||||||
|
}
|
||||||
|
int gamemode = packetWrapper.read(Type.VAR_INT);
|
||||||
|
int ping = packetWrapper.read(Type.VAR_INT);
|
||||||
|
gameProfile.ping = ping;
|
||||||
|
gameProfile.gamemode = gamemode;
|
||||||
|
if (packetWrapper.read(Type.BOOLEAN)) {
|
||||||
|
gameProfile.setDisplayName(ChatUtil.jsonToLegacy(packetWrapper.read(Type.COMPONENT)));
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketWrapper packet = PacketWrapper.create(0x38, null, packetWrapper.user());
|
||||||
|
packet.write(Type.STRING, gameProfile.name);
|
||||||
|
packet.write(Type.BOOLEAN, true);
|
||||||
|
packet.write(Type.SHORT, (short) ping);
|
||||||
|
PacketUtil.sendPacket(packet, Protocol1_7_6_10TO1_8.class);
|
||||||
|
} else if (action == 1) {
|
||||||
|
int gamemode = packetWrapper.read(Type.VAR_INT);
|
||||||
|
|
||||||
|
GameProfileStorage.GameProfile gameProfile = gameProfileStorage.get(uuid);
|
||||||
|
if (gameProfile == null || gameProfile.gamemode == gamemode) continue;
|
||||||
|
|
||||||
|
if (gamemode == 3 || gameProfile.gamemode == 3) {
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
int entityId = tracker.getPlayerEntityId(uuid);
|
||||||
|
if (entityId != -1) {
|
||||||
|
Item[] equipment;
|
||||||
|
if (gamemode == 3) {
|
||||||
|
equipment = new Item[5];
|
||||||
|
equipment[4] = gameProfile.getSkull();
|
||||||
|
} else {
|
||||||
|
equipment = tracker.getPlayerEquipment(uuid);
|
||||||
|
if (equipment == null) equipment = new Item[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (short slot = 0; slot < 5; slot++) {
|
||||||
|
PacketWrapper equipmentPacket = PacketWrapper.create(0x04, null, packetWrapper.user());
|
||||||
|
equipmentPacket.write(Type.INT, entityId);
|
||||||
|
equipmentPacket.write(Type.SHORT, slot);
|
||||||
|
equipmentPacket.write(Types1_7_6_10.COMPRESSED_NBT_ITEM, equipment[slot]);
|
||||||
|
PacketUtil.sendPacket(equipmentPacket, Protocol1_7_6_10TO1_8.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gameProfile.gamemode = gamemode;
|
||||||
|
} else if (action == 2) {
|
||||||
|
int ping = packetWrapper.read(Type.VAR_INT);
|
||||||
|
|
||||||
|
GameProfileStorage.GameProfile gameProfile = gameProfileStorage.get(uuid);
|
||||||
|
if (gameProfile == null) continue;
|
||||||
|
|
||||||
|
gameProfile.ping = ping;
|
||||||
|
|
||||||
|
PacketWrapper packet = PacketWrapper.create(0x38, null, packetWrapper.user());
|
||||||
|
packet.write(Type.STRING, gameProfile.name);
|
||||||
|
packet.write(Type.BOOLEAN, true);
|
||||||
|
packet.write(Type.SHORT, (short) ping);
|
||||||
|
PacketUtil.sendPacket(packet, Protocol1_7_6_10TO1_8.class);
|
||||||
|
} else if (action == 3) {
|
||||||
|
String displayName = packetWrapper.read(Type.BOOLEAN) ? ChatUtil.jsonToLegacy(packetWrapper.read(Type.COMPONENT)) : null;
|
||||||
|
|
||||||
|
GameProfileStorage.GameProfile gameProfile = gameProfileStorage.get(uuid);
|
||||||
|
if (gameProfile == null || gameProfile.displayName == null && displayName == null) continue;
|
||||||
|
|
||||||
|
if (gameProfile.displayName == null && displayName != null || gameProfile.displayName != null && displayName == null || !gameProfile.displayName.equals(displayName)) {
|
||||||
|
gameProfile.setDisplayName(displayName);
|
||||||
|
}
|
||||||
|
} else if (action == 4) {
|
||||||
|
GameProfileStorage.GameProfile gameProfile = gameProfileStorage.remove(uuid);
|
||||||
|
if (gameProfile == null) continue;
|
||||||
|
|
||||||
|
PacketWrapper packet = PacketWrapper.create(0x38, null, packetWrapper.user());
|
||||||
|
//packet.write(Type.STRING, gameProfile.getDisplayName());
|
||||||
|
packet.write(Type.STRING, gameProfile.name);
|
||||||
|
packet.write(Type.BOOLEAN, false);
|
||||||
|
packet.write(Type.SHORT, (short) gameProfile.ping);
|
||||||
|
PacketUtil.sendPacket(packet, Protocol1_7_6_10TO1_8.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.PLAYER_ABILITIES, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
byte flags = packetWrapper.get(Type.BYTE, 0);
|
||||||
|
float flySpeed = packetWrapper.get(Type.FLOAT, 0);
|
||||||
|
float walkSpeed = packetWrapper.get(Type.FLOAT, 1);
|
||||||
|
PlayerAbilities abilities = packetWrapper.user().get(PlayerAbilities.class);
|
||||||
|
abilities.setInvincible((flags & 8) == 8);
|
||||||
|
abilities.setAllowFly((flags & 4) == 4);
|
||||||
|
abilities.setFlying((flags & 2) == 2);
|
||||||
|
abilities.setCreative((flags & 1) == 1);
|
||||||
|
abilities.setFlySpeed(flySpeed);
|
||||||
|
abilities.setWalkSpeed(walkSpeed);
|
||||||
|
if (abilities.isSprinting() && abilities.isFlying()) {
|
||||||
|
packetWrapper.set(Type.FLOAT, 0, abilities.getFlySpeed() * 2.0f);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.PLUGIN_MESSAGE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.STRING);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
String channel = packetWrapper.get(Type.STRING, 0);
|
||||||
|
if (channel.equalsIgnoreCase("MC|TrList")) {
|
||||||
|
packetWrapper.passthrough(Type.INT); //Window Id
|
||||||
|
|
||||||
|
int size;
|
||||||
|
if (packetWrapper.isReadable(Type.BYTE, 0)) {
|
||||||
|
size = packetWrapper.passthrough(Type.BYTE);
|
||||||
|
} else {
|
||||||
|
size = packetWrapper.passthrough(Type.UNSIGNED_BYTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
Item item = ItemRewriter.toClient(packetWrapper.read(Type.ITEM));
|
||||||
|
packetWrapper.write(Types1_7_6_10.COMPRESSED_NBT_ITEM, item); //Buy Item 1
|
||||||
|
|
||||||
|
item = ItemRewriter.toClient(packetWrapper.read(Type.ITEM));
|
||||||
|
packetWrapper.write(Types1_7_6_10.COMPRESSED_NBT_ITEM, item); //Buy Item 3
|
||||||
|
|
||||||
|
boolean has3Items = packetWrapper.passthrough(Type.BOOLEAN);
|
||||||
|
if (has3Items) {
|
||||||
|
item = ItemRewriter.toClient(packetWrapper.read(Type.ITEM));
|
||||||
|
packetWrapper.write(Types1_7_6_10.COMPRESSED_NBT_ITEM, item); //Buy Item 2
|
||||||
|
}
|
||||||
|
|
||||||
|
packetWrapper.passthrough(Type.BOOLEAN); //Unavailable
|
||||||
|
packetWrapper.read(Type.INT); //Uses
|
||||||
|
packetWrapper.read(Type.INT); //Max Uses
|
||||||
|
}
|
||||||
|
} else if (channel.equalsIgnoreCase("MC|Brand")) {
|
||||||
|
packetWrapper.write(Type.REMAINING_BYTES, packetWrapper.read(Type.STRING).getBytes(StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
|
||||||
|
packetWrapper.cancel();
|
||||||
|
packetWrapper.setId(-1);
|
||||||
|
ByteBuf newPacketBuf = Unpooled.buffer();
|
||||||
|
packetWrapper.writeToBuffer(newPacketBuf);
|
||||||
|
PacketWrapper newWrapper = PacketWrapper.create(0x3F, newPacketBuf, packetWrapper.user());
|
||||||
|
newWrapper.passthrough(Type.STRING);
|
||||||
|
if (newPacketBuf.readableBytes() <= Short.MAX_VALUE) {
|
||||||
|
newWrapper.write(Type.SHORT, (short) newPacketBuf.readableBytes());
|
||||||
|
newWrapper.send(Protocol1_7_6_10TO1_8.class);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Camera
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.CAMERA, null, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
|
||||||
|
int entityId = packetWrapper.read(Type.VAR_INT);
|
||||||
|
int spectating = tracker.getSpectating();
|
||||||
|
|
||||||
|
if (spectating != entityId) {
|
||||||
|
tracker.setSpectating(entityId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Title
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.TITLE, null, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
TitleRenderProvider titleRenderProvider = Via.getManager().getProviders().get(TitleRenderProvider.class);
|
||||||
|
if (titleRenderProvider == null) return;
|
||||||
|
int action = packetWrapper.read(Type.VAR_INT);
|
||||||
|
UUID uuid = Utils.getUUID(packetWrapper.user());
|
||||||
|
switch (action) {
|
||||||
|
case 0:
|
||||||
|
titleRenderProvider.setTitle(uuid, packetWrapper.read(Type.STRING));
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
titleRenderProvider.setSubTitle(uuid, packetWrapper.read(Type.STRING));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
titleRenderProvider.setTimings(uuid, packetWrapper.read(Type.INT), packetWrapper.read(Type.INT), packetWrapper.read(Type.INT));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
titleRenderProvider.clear(uuid);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
titleRenderProvider.reset(uuid);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Player List Header And Footer
|
||||||
|
protocol.cancelClientbound(ClientboundPackets1_8.TAB_LIST);
|
||||||
|
|
||||||
|
//Resource Pack Send
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.RESOURCE_PACK, ClientboundPackets1_7.PLUGIN_MESSAGE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
create(Type.STRING, "MC|RPack");
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
ByteBuf buf = ByteBufAllocator.DEFAULT.buffer();
|
||||||
|
try {
|
||||||
|
// Url
|
||||||
|
Type.STRING.write(buf, packetWrapper.read(Type.STRING));
|
||||||
|
|
||||||
|
packetWrapper.write(Type.SHORT_BYTE_ARRAY, Type.REMAINING_BYTES.read(buf));
|
||||||
|
} finally {
|
||||||
|
buf.release();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
map(Type.STRING, Type.NOTHING); // Hash
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* INCOMING */
|
||||||
|
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_7.CHAT_MESSAGE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.STRING);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
String msg = packetWrapper.get(Type.STRING, 0);
|
||||||
|
int gamemode = packetWrapper.user().get(EntityTracker.class).getGamemode();
|
||||||
|
if (gamemode == 3 && msg.toLowerCase().startsWith("/stp ")) {
|
||||||
|
String username = msg.split(" ")[1];
|
||||||
|
GameProfileStorage storage = packetWrapper.user().get(GameProfileStorage.class);
|
||||||
|
GameProfileStorage.GameProfile profile = storage.get(username, true);
|
||||||
|
if (profile != null && profile.uuid != null) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
|
||||||
|
PacketWrapper teleportPacket = PacketWrapper.create(0x18, null, packetWrapper.user());
|
||||||
|
teleportPacket.write(Type.UUID, profile.uuid);
|
||||||
|
|
||||||
|
PacketUtil.sendToServer(teleportPacket, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_7.INTERACT_ENTITY, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.INT, Type.VAR_INT);
|
||||||
|
map(Type.BYTE, Type.VAR_INT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int mode = packetWrapper.get(Type.VAR_INT, 1);
|
||||||
|
if (mode != 0) return;
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
|
||||||
|
if (!(replacement instanceof ArmorStandReplacement)) return;
|
||||||
|
ArmorStandReplacement armorStand = (ArmorStandReplacement) replacement;
|
||||||
|
AABB boundingBox = armorStand.getBoundingBox();
|
||||||
|
PlayerPosition playerPosition = packetWrapper.user().get(PlayerPosition.class);
|
||||||
|
Vector3d pos = new Vector3d(playerPosition.getPosX(), playerPosition.getPosY() + 1.8, playerPosition.getPosZ());
|
||||||
|
double yaw = Math.toRadians(playerPosition.getYaw());
|
||||||
|
double pitch = Math.toRadians(playerPosition.getPitch());
|
||||||
|
Vector3d dir = new Vector3d(-Math.cos(pitch) * Math.sin(yaw), -Math.sin(pitch), Math.cos(pitch) * Math.cos(yaw));
|
||||||
|
Ray3d ray = new Ray3d(pos, dir);
|
||||||
|
Vector3d intersection = RayTracing.trace(ray, boundingBox, 5.0);
|
||||||
|
if (intersection == null) return;
|
||||||
|
intersection.substract(boundingBox.getMin());
|
||||||
|
mode = 2;
|
||||||
|
packetWrapper.set(Type.VAR_INT, 1, mode);
|
||||||
|
packetWrapper.write(Type.FLOAT, (float) intersection.getX());
|
||||||
|
packetWrapper.write(Type.FLOAT, (float) intersection.getY());
|
||||||
|
packetWrapper.write(Type.FLOAT, (float) intersection.getZ());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_7.PLAYER_MOVEMENT, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.BOOLEAN);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
PlayerPosition playerPosition = packetWrapper.user().get(PlayerPosition.class);
|
||||||
|
playerPosition.setOnGround(packetWrapper.get(Type.BOOLEAN, 0));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_7.PLAYER_POSITION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.DOUBLE); //X
|
||||||
|
map(Type.DOUBLE); //Y
|
||||||
|
map(Type.DOUBLE, Type.NOTHING);
|
||||||
|
map(Type.DOUBLE); //Z
|
||||||
|
map(Type.BOOLEAN); //OnGround
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
double x = packetWrapper.get(Type.DOUBLE, 0);
|
||||||
|
double feetY = packetWrapper.get(Type.DOUBLE, 1);
|
||||||
|
double z = packetWrapper.get(Type.DOUBLE, 2);
|
||||||
|
|
||||||
|
PlayerPosition playerPosition = packetWrapper.user().get(PlayerPosition.class);
|
||||||
|
/*
|
||||||
|
Completely useless, this isn't vanilla behaviour so it would trigger anticheats.
|
||||||
|
*/
|
||||||
|
/*if (playerPosition.isPositionPacketReceived()) {
|
||||||
|
playerPosition.setPositionPacketReceived(false);
|
||||||
|
feetY -= 0.01;
|
||||||
|
packetWrapper.set(Type.DOUBLE, 1, feetY);
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
|
playerPosition.setOnGround(packetWrapper.get(Type.BOOLEAN, 0));
|
||||||
|
playerPosition.setPos(x, feetY, z);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_7.PLAYER_ROTATION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.BOOLEAN);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
PlayerPosition playerPosition = packetWrapper.user().get(PlayerPosition.class);
|
||||||
|
playerPosition.setYaw(packetWrapper.get(Type.FLOAT, 0));
|
||||||
|
playerPosition.setPitch(packetWrapper.get(Type.FLOAT, 1));
|
||||||
|
playerPosition.setOnGround(packetWrapper.get(Type.BOOLEAN, 0));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_7.PLAYER_POSITION_AND_ROTATION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.DOUBLE); //X
|
||||||
|
map(Type.DOUBLE); //Y
|
||||||
|
map(Type.DOUBLE, Type.NOTHING);
|
||||||
|
map(Type.DOUBLE); //Z
|
||||||
|
map(Type.FLOAT); //Yaw
|
||||||
|
map(Type.FLOAT); //Pitch
|
||||||
|
map(Type.BOOLEAN); //OnGround
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
double x = packetWrapper.get(Type.DOUBLE, 0);
|
||||||
|
double feetY = packetWrapper.get(Type.DOUBLE, 1);
|
||||||
|
double z = packetWrapper.get(Type.DOUBLE, 2);
|
||||||
|
|
||||||
|
float yaw = packetWrapper.get(Type.FLOAT, 0);
|
||||||
|
float pitch = packetWrapper.get(Type.FLOAT, 1);
|
||||||
|
|
||||||
|
PlayerPosition playerPosition = packetWrapper.user().get(PlayerPosition.class);
|
||||||
|
/*
|
||||||
|
We can't track teleports like this, this packet could've just been a POSLOOK
|
||||||
|
sent before client accepted teleport, also there could be multiple teleports
|
||||||
|
and the #getReceivedPosY(), would be wrong y-coord
|
||||||
|
|
||||||
|
Because of this inaccuracy it could teleport players to a wrong place
|
||||||
|
and trigger anticheats
|
||||||
|
|
||||||
|
I've tested this change and there is no noticable glitchiness in client view.
|
||||||
|
*/
|
||||||
|
/*if (playerPosition.isPositionPacketReceived()) {
|
||||||
|
playerPosition.setPositionPacketReceived(false);
|
||||||
|
feetY = playerPosition.getReceivedPosY();
|
||||||
|
packetWrapper.set(Type.DOUBLE, 1, feetY);
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
playerPosition.setOnGround(packetWrapper.get(Type.BOOLEAN, 0));
|
||||||
|
playerPosition.setPos(x, feetY, z);
|
||||||
|
playerPosition.setYaw(yaw);
|
||||||
|
playerPosition.setPitch(pitch);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_7.PLAYER_DIGGING, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT); //Status
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int x = packetWrapper.read(Type.INT);
|
||||||
|
short y = packetWrapper.read(Type.UNSIGNED_BYTE);
|
||||||
|
int z = packetWrapper.read(Type.INT);
|
||||||
|
packetWrapper.write(Type.POSITION, new Position(x, y, z));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_7.PLAYER_BLOCK_PLACEMENT, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int x = packetWrapper.read(Type.INT);
|
||||||
|
short y = packetWrapper.read(Type.UNSIGNED_BYTE);
|
||||||
|
int z = packetWrapper.read(Type.INT);
|
||||||
|
packetWrapper.write(Type.POSITION, new Position(x, y, z));
|
||||||
|
|
||||||
|
packetWrapper.passthrough(Type.BYTE); //Direction
|
||||||
|
Item item = packetWrapper.read(Types1_7_6_10.COMPRESSED_NBT_ITEM);
|
||||||
|
item = ItemRewriter.toServer(item);
|
||||||
|
packetWrapper.write(Type.ITEM, item);
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
packetWrapper.passthrough(Type.BYTE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_7.ANIMATION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.read(Type.INT);
|
||||||
|
int animation = packetWrapper.read(Type.BYTE); //Animation
|
||||||
|
if (animation == 1) return;
|
||||||
|
packetWrapper.cancel();
|
||||||
|
//1.7 vanilla client is not sending this packet with animation!=1
|
||||||
|
switch (animation) {
|
||||||
|
case 104:
|
||||||
|
animation = 0;
|
||||||
|
break;
|
||||||
|
case 105:
|
||||||
|
animation = 1;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
animation = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PacketWrapper entityAction = PacketWrapper.create(0x0B, null, packetWrapper.user());
|
||||||
|
entityAction.write(Type.VAR_INT, entityId);
|
||||||
|
entityAction.write(Type.VAR_INT, animation);
|
||||||
|
entityAction.write(Type.VAR_INT, 0);
|
||||||
|
PacketUtil.sendPacket(entityAction, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_7.ENTITY_ACTION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.INT, Type.VAR_INT); //Entity Id
|
||||||
|
handler(packetWrapper -> packetWrapper.write(Type.VAR_INT, packetWrapper.read(Type.BYTE) - 1)); //Action Id
|
||||||
|
map(Type.INT, Type.VAR_INT); //Action Paramter
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int action = packetWrapper.get(Type.VAR_INT, 1);
|
||||||
|
if (action == 3 || action == 4) {
|
||||||
|
PlayerAbilities abilities = packetWrapper.user().get(PlayerAbilities.class);
|
||||||
|
abilities.setSprinting(action == 3);
|
||||||
|
PacketWrapper abilitiesPacket = PacketWrapper.create(0x39, null, packetWrapper.user());
|
||||||
|
abilitiesPacket.write(Type.BYTE, abilities.getFlags());
|
||||||
|
abilitiesPacket.write(Type.FLOAT, abilities.isSprinting() ? abilities.getFlySpeed() * 2.0f : abilities.getFlySpeed());
|
||||||
|
abilitiesPacket.write(Type.FLOAT, abilities.getWalkSpeed());
|
||||||
|
PacketUtil.sendPacket(abilitiesPacket, Protocol1_7_6_10TO1_8.class);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_7.STEER_VEHICLE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.FLOAT); //Sideways
|
||||||
|
map(Type.FLOAT); //Forwards
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
boolean jump = packetWrapper.read(Type.BOOLEAN);
|
||||||
|
boolean unmount = packetWrapper.read(Type.BOOLEAN);
|
||||||
|
short flags = 0;
|
||||||
|
if (jump) flags += 0x01;
|
||||||
|
if (unmount) flags += 0x02;
|
||||||
|
packetWrapper.write(Type.UNSIGNED_BYTE, flags);
|
||||||
|
|
||||||
|
if (unmount) {
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
if (tracker.getSpectating() != tracker.getPlayerId()) {
|
||||||
|
PacketWrapper sneakPacket = PacketWrapper.create(0x0B, null, packetWrapper.user());
|
||||||
|
sneakPacket.write(Type.VAR_INT, tracker.getPlayerId());
|
||||||
|
sneakPacket.write(Type.VAR_INT, 0); //Start sneaking
|
||||||
|
sneakPacket.write(Type.VAR_INT, 0); //Action Parameter
|
||||||
|
|
||||||
|
PacketWrapper unsneakPacket = PacketWrapper.create(0x0B, null, packetWrapper.user());
|
||||||
|
unsneakPacket.write(Type.VAR_INT, tracker.getPlayerId());
|
||||||
|
unsneakPacket.write(Type.VAR_INT, 1); //Stop sneaking
|
||||||
|
unsneakPacket.write(Type.VAR_INT, 0); //Action Parameter
|
||||||
|
|
||||||
|
PacketUtil.sendToServer(sneakPacket, Protocol1_7_6_10TO1_8.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_7.UPDATE_SIGN, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int x = packetWrapper.read(Type.INT);
|
||||||
|
short y = packetWrapper.read(Type.SHORT);
|
||||||
|
int z = packetWrapper.read(Type.INT);
|
||||||
|
packetWrapper.write(Type.POSITION, new Position(x, y, z));
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
String line = packetWrapper.read(Type.STRING);
|
||||||
|
line = ChatUtil.legacyToJson(line);
|
||||||
|
packetWrapper.write(Type.COMPONENT, new JsonParser().parse(line));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_7.PLAYER_ABILITIES, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
PlayerAbilities abilities = packetWrapper.user().get(PlayerAbilities.class);
|
||||||
|
if (abilities.isAllowFly()) {
|
||||||
|
byte flags = packetWrapper.get(Type.BYTE, 0);
|
||||||
|
abilities.setFlying((flags & 2) == 2);
|
||||||
|
}
|
||||||
|
packetWrapper.set(Type.FLOAT, 0, abilities.getFlySpeed());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_7.TAB_COMPLETE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.STRING);
|
||||||
|
create(Type.OPTIONAL_POSITION, null);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
String msg = packetWrapper.get(Type.STRING, 0);
|
||||||
|
if (msg.toLowerCase().startsWith("/stp ")) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
String[] args = msg.split(" ");
|
||||||
|
if (args.length <= 2) {
|
||||||
|
String prefix = args.length == 1 ? "" : args[1];
|
||||||
|
GameProfileStorage storage = packetWrapper.user().get(GameProfileStorage.class);
|
||||||
|
List<GameProfileStorage.GameProfile> profiles = storage.getAllWithPrefix(prefix, true);
|
||||||
|
|
||||||
|
PacketWrapper tabComplete = PacketWrapper.create(0x3A, null, packetWrapper.user());
|
||||||
|
tabComplete.write(Type.VAR_INT, profiles.size());
|
||||||
|
for (GameProfileStorage.GameProfile profile : profiles) {
|
||||||
|
tabComplete.write(Type.STRING, profile.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(tabComplete, Protocol1_7_6_10TO1_8.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Client Settings
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_7.CLIENT_SETTINGS, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.STRING);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.BOOLEAN);
|
||||||
|
map(Type.BYTE, Type.NOTHING);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
boolean cape = packetWrapper.read(Type.BOOLEAN);
|
||||||
|
packetWrapper.write(Type.UNSIGNED_BYTE, (short) (cape ? 127 : 126));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_7.PLUGIN_MESSAGE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.STRING);
|
||||||
|
map(Type.SHORT, Type.NOTHING); // Length
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
String channel = packetWrapper.get(Type.STRING, 0);
|
||||||
|
|
||||||
|
switch (channel) {
|
||||||
|
case "MC|TrSel": {
|
||||||
|
packetWrapper.passthrough(Type.INT);
|
||||||
|
packetWrapper.read(Type.REMAINING_BYTES); // unused data ???
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "MC|ItemName": {
|
||||||
|
byte[] data = packetWrapper.read(Type.REMAINING_BYTES);
|
||||||
|
String name = new String(data, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
packetWrapper.write(Type.STRING, name);
|
||||||
|
|
||||||
|
Windows windows = packetWrapper.user().get(Windows.class);
|
||||||
|
PacketWrapper updateCost = PacketWrapper.create(0x31, null, packetWrapper.user());
|
||||||
|
updateCost.write(Type.UNSIGNED_BYTE, windows.anvilId);
|
||||||
|
updateCost.write(Type.SHORT, (short) 0);
|
||||||
|
updateCost.write(Type.SHORT, windows.levelCost);
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(updateCost, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "MC|BEdit":
|
||||||
|
case "MC|BSign": {
|
||||||
|
Item book = packetWrapper.read(Types1_7_6_10.COMPRESSED_NBT_ITEM);
|
||||||
|
CompoundTag tag = book.tag();
|
||||||
|
if (tag != null && tag.contains("pages")) {
|
||||||
|
ListTag pages = tag.get("pages");
|
||||||
|
for (int i = 0; i < pages.size(); i++) {
|
||||||
|
StringTag page = pages.get(i);
|
||||||
|
String value = page.getValue();
|
||||||
|
value = ChatUtil.legacyToJson(value);
|
||||||
|
page.setValue(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
packetWrapper.write(Type.ITEM, book);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "MC|Brand": {
|
||||||
|
packetWrapper.write(Type.STRING, new String(packetWrapper.read(Type.REMAINING_BYTES), StandardCharsets.UTF_8));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,244 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.packets;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10TO1_8;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.storage.Scoreboard;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.PacketUtil;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.remapper.PacketRemapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.util.ChatColorUtil;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class ScoreboardPackets {
|
||||||
|
|
||||||
|
public static void register(Protocol1_7_6_10TO1_8 protocol) {
|
||||||
|
|
||||||
|
/* OUTGOING */
|
||||||
|
|
||||||
|
//Scoreboard Objective
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.SCOREBOARD_OBJECTIVE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
String name = packetWrapper.passthrough(Type.STRING);
|
||||||
|
if (name.length() > 16) {
|
||||||
|
packetWrapper.set(Type.STRING, 0, name = name.substring(0, 16));
|
||||||
|
}
|
||||||
|
byte mode = packetWrapper.read(Type.BYTE);
|
||||||
|
|
||||||
|
Scoreboard scoreboard = packetWrapper.user().get(Scoreboard.class);
|
||||||
|
if (mode == 0) {
|
||||||
|
if (scoreboard.objectiveExists(name)) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
scoreboard.addObjective(name);
|
||||||
|
} else if (mode == 1) {
|
||||||
|
if (!scoreboard.objectiveExists(name)) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (scoreboard.getColorIndependentSidebar() != null) {
|
||||||
|
String username = packetWrapper.user().getProtocolInfo().getUsername();
|
||||||
|
Optional<Byte> color = scoreboard.getPlayerTeamColor(username);
|
||||||
|
if (color.isPresent()) {
|
||||||
|
String sidebar = scoreboard.getColorDependentSidebar().get(color.get());
|
||||||
|
if (name.equals(sidebar)) {
|
||||||
|
PacketWrapper sidebarPacket = PacketWrapper.create(0x3D, null, packetWrapper.user());
|
||||||
|
sidebarPacket.write(Type.BYTE, (byte) 1);
|
||||||
|
sidebarPacket.write(Type.STRING, scoreboard.getColorIndependentSidebar());
|
||||||
|
PacketUtil.sendPacket(sidebarPacket, Protocol1_7_6_10TO1_8.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scoreboard.removeObjective(name);
|
||||||
|
} else if (mode == 2) {
|
||||||
|
if (!scoreboard.objectiveExists(name)) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == 0 || mode == 2) {
|
||||||
|
String displayName = packetWrapper.passthrough(Type.STRING);
|
||||||
|
if (displayName.length() > 32) {
|
||||||
|
packetWrapper.set(Type.STRING, 1, displayName.substring(0, 32));
|
||||||
|
}
|
||||||
|
packetWrapper.read(Type.STRING);
|
||||||
|
} else {
|
||||||
|
packetWrapper.write(Type.STRING, "");
|
||||||
|
}
|
||||||
|
packetWrapper.write(Type.BYTE, mode);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Update Score
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.UPDATE_SCORE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.STRING); // Name
|
||||||
|
map(Type.VAR_INT, Type.BYTE); // Mode
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
Scoreboard scoreboard = packetWrapper.user().get(Scoreboard.class);
|
||||||
|
String name = packetWrapper.get(Type.STRING, 0);
|
||||||
|
byte mode = packetWrapper.get(Type.BYTE, 0);
|
||||||
|
|
||||||
|
if (mode == 1) {
|
||||||
|
name = scoreboard.removeTeamForScore(name);
|
||||||
|
} else {
|
||||||
|
name = scoreboard.sendTeamForScore(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name.length() > 16) {
|
||||||
|
name = ChatColorUtil.stripColor(name);
|
||||||
|
if (name.length() > 16) {
|
||||||
|
name = name.substring(0, 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
packetWrapper.set(Type.STRING, 0, name);
|
||||||
|
|
||||||
|
String objective = packetWrapper.read(Type.STRING);
|
||||||
|
if (objective.length() > 16) {
|
||||||
|
objective = objective.substring(0, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode != 1) {
|
||||||
|
int score = packetWrapper.read(Type.VAR_INT);
|
||||||
|
packetWrapper.write(Type.STRING, objective);
|
||||||
|
packetWrapper.write(Type.INT, score);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.DISPLAY_SCOREBOARD, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.BYTE); // Position
|
||||||
|
map(Type.STRING); // Score name
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
byte position = packetWrapper.get(Type.BYTE, 0);
|
||||||
|
String name = packetWrapper.get(Type.STRING, 0);
|
||||||
|
Scoreboard scoreboard = packetWrapper.user().get(Scoreboard.class);
|
||||||
|
if (position > 2) { // team specific sidebar
|
||||||
|
byte receiverTeamColor = (byte) (position - 3);
|
||||||
|
scoreboard.getColorDependentSidebar().put(receiverTeamColor, name);
|
||||||
|
|
||||||
|
String username = packetWrapper.user().getProtocolInfo().getUsername();
|
||||||
|
Optional<Byte> color = scoreboard.getPlayerTeamColor(username);
|
||||||
|
if (color.isPresent() && color.get() == receiverTeamColor) {
|
||||||
|
position = 1;
|
||||||
|
} else {
|
||||||
|
position = -1;
|
||||||
|
}
|
||||||
|
} else if (position == 1) { // team independent sidebar
|
||||||
|
scoreboard.setColorIndependentSidebar(name);
|
||||||
|
String username = packetWrapper.user().getProtocolInfo().getUsername();
|
||||||
|
Optional<Byte> color = scoreboard.getPlayerTeamColor(username);
|
||||||
|
if (color.isPresent() && scoreboard.getColorDependentSidebar().containsKey(color.get())) {
|
||||||
|
position = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (position == -1) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
packetWrapper.set(Type.BYTE, 0, position);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.TEAMS, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.STRING);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
String team = packetWrapper.get(Type.STRING, 0);
|
||||||
|
if (team == null) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
byte mode = packetWrapper.passthrough(Type.BYTE);
|
||||||
|
|
||||||
|
Scoreboard scoreboard = packetWrapper.user().get(Scoreboard.class);
|
||||||
|
|
||||||
|
if (mode != 0 && !scoreboard.teamExists(team)) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
return;
|
||||||
|
} else if (mode == 0 && scoreboard.teamExists(team)) {
|
||||||
|
scoreboard.removeTeam(team);
|
||||||
|
|
||||||
|
PacketWrapper remove = PacketWrapper.create(0x3E, null, packetWrapper.user());
|
||||||
|
remove.write(Type.STRING, team);
|
||||||
|
remove.write(Type.BYTE, (byte) 1);
|
||||||
|
PacketUtil.sendPacket(remove, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == 0) {
|
||||||
|
scoreboard.addTeam(team);
|
||||||
|
} else if (mode == 1) {
|
||||||
|
scoreboard.removeTeam(team);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == 0 || mode == 2) {
|
||||||
|
packetWrapper.passthrough(Type.STRING); // Display name
|
||||||
|
packetWrapper.passthrough(Type.STRING); // prefix
|
||||||
|
packetWrapper.passthrough(Type.STRING); // suffix
|
||||||
|
packetWrapper.passthrough(Type.BYTE); // friendly fire
|
||||||
|
packetWrapper.read(Type.STRING); // name tag visibility
|
||||||
|
byte color = packetWrapper.read(Type.BYTE);
|
||||||
|
if (mode == 2 && scoreboard.getTeamColor(team).get() != color) {
|
||||||
|
String username = packetWrapper.user().getProtocolInfo().getUsername();
|
||||||
|
String sidebar = scoreboard.getColorDependentSidebar().get(color);
|
||||||
|
PacketWrapper sidebarPacket = packetWrapper.create(0x3D);
|
||||||
|
sidebarPacket.write(Type.BYTE, (byte) 1);
|
||||||
|
sidebarPacket.write(Type.STRING, sidebar == null ? "" : sidebar);
|
||||||
|
PacketUtil.sendPacket(sidebarPacket, Protocol1_7_6_10TO1_8.class);
|
||||||
|
}
|
||||||
|
scoreboard.setTeamColor(team, color);
|
||||||
|
}
|
||||||
|
if (mode == 0 || mode == 3 || mode == 4) {
|
||||||
|
byte color = scoreboard.getTeamColor(team).get();
|
||||||
|
String[] entries = packetWrapper.read(Type.STRING_ARRAY);
|
||||||
|
List<String> entryList = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < entries.length; i++) {
|
||||||
|
String entry = entries[i];
|
||||||
|
String username = packetWrapper.user().getProtocolInfo().getUsername();
|
||||||
|
|
||||||
|
if (mode == 4) {
|
||||||
|
if (!scoreboard.isPlayerInTeam(entry, team)) continue;
|
||||||
|
scoreboard.removePlayerFromTeam(entry, team);
|
||||||
|
if (entry.equals(username)) {
|
||||||
|
PacketWrapper sidebarPacket = packetWrapper.create(0x3D);
|
||||||
|
sidebarPacket.write(Type.BYTE, (byte) 1);
|
||||||
|
sidebarPacket.write(Type.STRING, scoreboard.getColorIndependentSidebar() == null ? "" : scoreboard.getColorIndependentSidebar());
|
||||||
|
PacketUtil.sendPacket(sidebarPacket, Protocol1_7_6_10TO1_8.class);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
scoreboard.addPlayerToTeam(entry, team);
|
||||||
|
if (entry.equals(username) && scoreboard.getColorDependentSidebar().containsKey(color)) {
|
||||||
|
PacketWrapper displayObjective = packetWrapper.create(0x3D);
|
||||||
|
displayObjective.write(Type.BYTE, (byte) 1);
|
||||||
|
displayObjective.write(Type.STRING, scoreboard.getColorDependentSidebar().get(color));
|
||||||
|
PacketUtil.sendPacket(displayObjective, Protocol1_7_6_10TO1_8.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
entryList.add(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
packetWrapper.write(Type.SHORT, (short) entryList.size());
|
||||||
|
for (String entry : entryList) {
|
||||||
|
packetWrapper.write(Type.STRING, entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,310 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.packets;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10TO1_8;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.entityreplacements.ArmorStandReplacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.entityreplacements.EndermiteReplacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.entityreplacements.GuardianReplacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.entityreplacements.RabbitReplacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.items.ReplacementRegistry1_7_6_10to1_8;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.metadata.MetadataRewriter;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.storage.EntityTracker;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.storage.GameProfileStorage;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
|
||||||
|
import com.elevatemc.spigot.viarewind.replacement.EntityReplacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.replacement.Replacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.PacketUtil;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.Position;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.entities.Entity1_10Types;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.Metadata;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.remapper.PacketRemapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.types.version.Types1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class SpawnPackets {
|
||||||
|
|
||||||
|
public static void register(Protocol1_7_6_10TO1_8 protocol) {
|
||||||
|
|
||||||
|
/* OUTGOING */
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_PLAYER, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
UUID uuid = packetWrapper.read(Type.UUID);
|
||||||
|
packetWrapper.write(Type.STRING, uuid.toString());
|
||||||
|
|
||||||
|
GameProfileStorage gameProfileStorage = packetWrapper.user().get(GameProfileStorage.class);
|
||||||
|
|
||||||
|
GameProfileStorage.GameProfile gameProfile = gameProfileStorage.get(uuid);
|
||||||
|
if (gameProfile == null) {
|
||||||
|
packetWrapper.write(Type.STRING, "");
|
||||||
|
packetWrapper.write(Type.VAR_INT, 0);
|
||||||
|
} else {
|
||||||
|
packetWrapper.write(Type.STRING, gameProfile.name.length() > 16 ? gameProfile.name.substring(0, 16) : gameProfile.name);
|
||||||
|
packetWrapper.write(Type.VAR_INT, gameProfile.properties.size());
|
||||||
|
for (GameProfileStorage.Property property : gameProfile.properties) {
|
||||||
|
packetWrapper.write(Type.STRING, property.name);
|
||||||
|
packetWrapper.write(Type.STRING, property.value);
|
||||||
|
packetWrapper.write(Type.STRING, property.signature == null ? "" : property.signature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gameProfile != null && gameProfile.gamemode == 3) {
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
|
||||||
|
PacketWrapper equipmentPacket = PacketWrapper.create(0x04, null, packetWrapper.user());
|
||||||
|
equipmentPacket.write(Type.INT, entityId);
|
||||||
|
equipmentPacket.write(Type.SHORT, (short) 4);
|
||||||
|
equipmentPacket.write(Types1_7_6_10.COMPRESSED_NBT_ITEM, gameProfile.getSkull());
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(equipmentPacket, Protocol1_7_6_10TO1_8.class);
|
||||||
|
|
||||||
|
for (short i = 0; i < 4; i++) {
|
||||||
|
equipmentPacket = PacketWrapper.create(0x04, null, packetWrapper.user());
|
||||||
|
equipmentPacket.write(Type.INT, entityId);
|
||||||
|
equipmentPacket.write(Type.SHORT, i);
|
||||||
|
equipmentPacket.write(Types1_7_6_10.COMPRESSED_NBT_ITEM, null);
|
||||||
|
PacketUtil.sendPacket(equipmentPacket, Protocol1_7_6_10TO1_8.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
tracker.addPlayer(packetWrapper.get(Type.VAR_INT, 0), uuid);
|
||||||
|
});
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.SHORT);
|
||||||
|
map(Types1_8.METADATA_LIST, Types1_7_6_10.METADATA_LIST);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
List<Metadata> metadata = packetWrapper.get(Types1_7_6_10.METADATA_LIST, 0); //Metadata
|
||||||
|
MetadataRewriter.transform(Entity1_10Types.EntityType.PLAYER, metadata);
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
tracker.getClientEntityTypes().put(entityId, Entity1_10Types.EntityType.PLAYER);
|
||||||
|
tracker.sendMetadataBuffer(entityId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_ENTITY, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.INT);
|
||||||
|
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
byte typeId = packetWrapper.get(Type.BYTE, 0);
|
||||||
|
int x = packetWrapper.get(Type.INT, 0);
|
||||||
|
int y = packetWrapper.get(Type.INT, 1);
|
||||||
|
int z = packetWrapper.get(Type.INT, 2);
|
||||||
|
byte pitch = packetWrapper.get(Type.BYTE, 1);
|
||||||
|
byte yaw = packetWrapper.get(Type.BYTE, 2);
|
||||||
|
|
||||||
|
if (typeId == 71) {
|
||||||
|
switch (yaw) {
|
||||||
|
case -128:
|
||||||
|
z += 32;
|
||||||
|
yaw = 0;
|
||||||
|
break;
|
||||||
|
case -64:
|
||||||
|
x -= 32;
|
||||||
|
yaw = -64;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
z -= 32;
|
||||||
|
yaw = -128;
|
||||||
|
break;
|
||||||
|
case 64:
|
||||||
|
x += 32;
|
||||||
|
yaw = 64;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (typeId == 78) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
ArmorStandReplacement armorStand = new ArmorStandReplacement(entityId, packetWrapper.user());
|
||||||
|
armorStand.setLocation(x / 32.0, y / 32.0, z / 32.0);
|
||||||
|
armorStand.setYawPitch(yaw * 360f / 256, pitch * 360f / 256);
|
||||||
|
armorStand.setHeadYaw(yaw * 360f / 256);
|
||||||
|
tracker.addEntityReplacement(armorStand);
|
||||||
|
} else if (typeId == 10) {
|
||||||
|
y += 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
packetWrapper.set(Type.BYTE, 0, typeId);
|
||||||
|
packetWrapper.set(Type.INT, 0, x);
|
||||||
|
packetWrapper.set(Type.INT, 1, y);
|
||||||
|
packetWrapper.set(Type.INT, 2, z);
|
||||||
|
packetWrapper.set(Type.BYTE, 1, pitch);
|
||||||
|
packetWrapper.set(Type.BYTE, 2, yaw);
|
||||||
|
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
Entity1_10Types.EntityType type = Entity1_10Types.getTypeFromId(typeId, true);
|
||||||
|
tracker.getClientEntityTypes().put(entityId, type);
|
||||||
|
tracker.sendMetadataBuffer(entityId);
|
||||||
|
|
||||||
|
int data = packetWrapper.get(Type.INT, 3);
|
||||||
|
|
||||||
|
if (type != null && type.isOrHasParent(Entity1_10Types.EntityType.FALLING_BLOCK)) {
|
||||||
|
int blockId = data & 0xFFF;
|
||||||
|
int blockData = data >> 12 & 0xF;
|
||||||
|
Replacement replace = ReplacementRegistry1_7_6_10to1_8.getReplacement(blockId, blockData);
|
||||||
|
if (replace != null) {
|
||||||
|
blockId = replace.getId();
|
||||||
|
blockData = replace.replaceData(blockData);
|
||||||
|
}
|
||||||
|
packetWrapper.set(Type.INT, 3, data = (blockId | blockData << 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data > 0) {
|
||||||
|
packetWrapper.passthrough(Type.SHORT);
|
||||||
|
packetWrapper.passthrough(Type.SHORT);
|
||||||
|
packetWrapper.passthrough(Type.SHORT);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_MOB, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.SHORT);
|
||||||
|
map(Type.SHORT);
|
||||||
|
map(Type.SHORT);
|
||||||
|
map(Types1_8.METADATA_LIST, Types1_7_6_10.METADATA_LIST);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
int typeId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
|
||||||
|
int x = packetWrapper.get(Type.INT, 0);
|
||||||
|
int y = packetWrapper.get(Type.INT, 1);
|
||||||
|
int z = packetWrapper.get(Type.INT, 2);
|
||||||
|
byte pitch = packetWrapper.get(Type.BYTE, 1);
|
||||||
|
byte yaw = packetWrapper.get(Type.BYTE, 0);
|
||||||
|
byte headYaw = packetWrapper.get(Type.BYTE, 2);
|
||||||
|
|
||||||
|
if (typeId == 30 || typeId == 68 || typeId == 67 || typeId == 101) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
EntityReplacement replacement = null;
|
||||||
|
if (typeId == 30) {
|
||||||
|
replacement = new ArmorStandReplacement(entityId, packetWrapper.user());
|
||||||
|
} else if (typeId == 68) {
|
||||||
|
replacement = new GuardianReplacement(entityId, packetWrapper.user());
|
||||||
|
} else if (typeId == 67) {
|
||||||
|
replacement = new EndermiteReplacement(entityId, packetWrapper.user());
|
||||||
|
} else if (typeId == 101){
|
||||||
|
replacement = new RabbitReplacement(entityId, packetWrapper.user());
|
||||||
|
}
|
||||||
|
replacement.setLocation(x / 32.0, y / 32.0, z / 32.0);
|
||||||
|
replacement.setYawPitch(yaw * 360f / 256, pitch * 360f / 256);
|
||||||
|
replacement.setHeadYaw(headYaw * 360f / 256);
|
||||||
|
tracker.addEntityReplacement(replacement);
|
||||||
|
} else if (typeId == 255 || typeId == -1) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
int typeId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
tracker.getClientEntityTypes().put(entityId, Entity1_10Types.getTypeFromId(typeId, false));
|
||||||
|
tracker.sendMetadataBuffer(entityId);
|
||||||
|
});
|
||||||
|
handler(wrapper -> {
|
||||||
|
List<Metadata> metadataList = wrapper.get(Types1_7_6_10.METADATA_LIST, 0);
|
||||||
|
int entityId = wrapper.get(Type.VAR_INT, 0);
|
||||||
|
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
|
||||||
|
if (tracker.getEntityReplacement(entityId) != null) {
|
||||||
|
tracker.getEntityReplacement(entityId).updateMetadata(metadataList);
|
||||||
|
} else if (tracker.getClientEntityTypes().containsKey(entityId)) {
|
||||||
|
MetadataRewriter.transform(tracker.getClientEntityTypes().get(entityId), metadataList);
|
||||||
|
} else {
|
||||||
|
wrapper.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_PAINTING, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT); //Entity Id
|
||||||
|
map(Type.STRING); //Title
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
Position position = packetWrapper.read(Type.POSITION);
|
||||||
|
packetWrapper.write(Type.INT, position.getX());
|
||||||
|
packetWrapper.write(Type.INT, position.getY());
|
||||||
|
packetWrapper.write(Type.INT, position.getZ());
|
||||||
|
});
|
||||||
|
map(Type.UNSIGNED_BYTE, Type.INT); //Rotation
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
tracker.getClientEntityTypes().put(entityId, Entity1_10Types.EntityType.PAINTING);
|
||||||
|
tracker.sendMetadataBuffer(entityId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_EXPERIENCE_ORB, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.SHORT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
tracker.getClientEntityTypes().put(entityId, Entity1_10Types.EntityType.EXPERIENCE_ORB);
|
||||||
|
tracker.sendMetadataBuffer(entityId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_GLOBAL_ENTITY, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.INT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
tracker.getClientEntityTypes().put(entityId, Entity1_10Types.EntityType.LIGHTNING);
|
||||||
|
tracker.sendMetadataBuffer(entityId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,334 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.packets;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10TO1_8;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.chunks.ChunkPacketTransformer;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.items.ReplacementRegistry1_7_6_10to1_8;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.storage.WorldBorder;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types.Chunk1_7_10Type;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types.Particle;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
|
||||||
|
import com.elevatemc.spigot.viarewind.replacement.Replacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.types.VarLongType;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.ChatUtil;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.PacketUtil;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.BlockChangeRecord;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.Position;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.chunks.Chunk;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.chunks.ChunkSection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.remapper.PacketRemapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.types.CustomByteType;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9to1_8.types.Chunk1_8Type;
|
||||||
|
import com.elevatemc.spigot.viaversion.util.ChatColorUtil;
|
||||||
|
|
||||||
|
public class WorldPackets {
|
||||||
|
|
||||||
|
public static void register(Protocol1_7_6_10TO1_8 protocol) {
|
||||||
|
|
||||||
|
/* OUTGOING */
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.CHUNK_DATA, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
ClientWorld world = packetWrapper.user().get(ClientWorld.class);
|
||||||
|
Chunk chunk = packetWrapper.read(new Chunk1_8Type(world));
|
||||||
|
packetWrapper.write(new Chunk1_7_10Type(world), chunk);
|
||||||
|
for (ChunkSection section : chunk.getSections()) {
|
||||||
|
if (section == null) continue;
|
||||||
|
for (int i = 0; i < section.getPaletteSize(); i++) {
|
||||||
|
int block = section.getPaletteEntry(i);
|
||||||
|
int replacedBlock = ReplacementRegistry1_7_6_10to1_8.replace(block);
|
||||||
|
section.setPaletteEntry(i, replacedBlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.MULTI_BLOCK_CHANGE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.INT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
final BlockChangeRecord[] records = packetWrapper.read(Type.BLOCK_CHANGE_RECORD_ARRAY);
|
||||||
|
packetWrapper.write(Type.SHORT, (short) records.length);
|
||||||
|
packetWrapper.write(Type.INT, records.length * 4);
|
||||||
|
for (BlockChangeRecord record : records) {
|
||||||
|
short data = (short) (record.getSectionX() << 12 | record.getSectionZ() << 8 | record.getY());
|
||||||
|
packetWrapper.write(Type.SHORT, data);
|
||||||
|
int replacedBlock = ReplacementRegistry1_7_6_10to1_8.replace(record.getBlockId());
|
||||||
|
packetWrapper.write(Type.SHORT, (short) replacedBlock);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.BLOCK_CHANGE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
Position position = packetWrapper.read(Type.POSITION);
|
||||||
|
packetWrapper.write(Type.INT, position.getX());
|
||||||
|
packetWrapper.write(Type.UNSIGNED_BYTE, (short) position.getY());
|
||||||
|
packetWrapper.write(Type.INT, position.getZ());
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int data = packetWrapper.read(Type.VAR_INT);
|
||||||
|
|
||||||
|
int blockId = data >> 4;
|
||||||
|
int meta = data & 0xF;
|
||||||
|
|
||||||
|
Replacement replace = ReplacementRegistry1_7_6_10to1_8.getReplacement(blockId, meta);
|
||||||
|
|
||||||
|
if (replace != null) {
|
||||||
|
blockId = replace.getId();
|
||||||
|
meta = replace.replaceData(meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
packetWrapper.write(Type.VAR_INT, blockId);
|
||||||
|
packetWrapper.write(Type.UNSIGNED_BYTE, (short) meta);
|
||||||
|
}); //Block Data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.BLOCK_ACTION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
Position position = packetWrapper.read(Type.POSITION);
|
||||||
|
packetWrapper.write(Type.INT, position.getX());
|
||||||
|
packetWrapper.write(Type.SHORT, (short) position.getY());
|
||||||
|
packetWrapper.write(Type.INT, position.getZ());
|
||||||
|
});
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.BLOCK_BREAK_ANIMATION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT); //Entity Id
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
Position position = packetWrapper.read(Type.POSITION);
|
||||||
|
packetWrapper.write(Type.INT, position.getX());
|
||||||
|
packetWrapper.write(Type.INT, position.getY());
|
||||||
|
packetWrapper.write(Type.INT, position.getZ());
|
||||||
|
});
|
||||||
|
map(Type.BYTE); //Progress
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.MAP_BULK_CHUNK, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(ChunkPacketTransformer::transformChunkBulk);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Effect
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.EFFECT, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.INT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
Position position = packetWrapper.read(Type.POSITION);
|
||||||
|
packetWrapper.write(Type.INT, position.getX());
|
||||||
|
packetWrapper.write(Type.BYTE, (byte) position.getY());
|
||||||
|
packetWrapper.write(Type.INT, position.getZ());
|
||||||
|
});
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.BOOLEAN);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_PARTICLE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int particleId = packetWrapper.read(Type.INT);
|
||||||
|
Particle particle = Particle.find(particleId);
|
||||||
|
if (particle == null) particle = Particle.CRIT;
|
||||||
|
packetWrapper.write(Type.STRING, particle.name);
|
||||||
|
|
||||||
|
packetWrapper.read(Type.BOOLEAN);
|
||||||
|
});
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.INT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
String name = packetWrapper.get(Type.STRING, 0);
|
||||||
|
Particle particle = Particle.find(name);
|
||||||
|
|
||||||
|
if (particle == Particle.ICON_CRACK || particle == Particle.BLOCK_CRACK || particle == Particle.BLOCK_DUST) {
|
||||||
|
int id = packetWrapper.read(Type.VAR_INT);
|
||||||
|
int data = particle == Particle.ICON_CRACK ? packetWrapper.read(Type.VAR_INT) : 0;
|
||||||
|
if (id >= 256 && id <= 422 || id >= 2256 && id <= 2267) { //item
|
||||||
|
particle = Particle.ICON_CRACK;
|
||||||
|
} else if (id >= 0 && id <= 164 || id >= 170 && id <= 175) {
|
||||||
|
if (particle == Particle.ICON_CRACK) particle = Particle.BLOCK_CRACK;
|
||||||
|
} else {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
name = particle.name + "_" + id + "_" + data;
|
||||||
|
}
|
||||||
|
|
||||||
|
packetWrapper.set(Type.STRING, 0, name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.UPDATE_SIGN, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
Position position = packetWrapper.read(Type.POSITION);
|
||||||
|
packetWrapper.write(Type.INT, position.getX());
|
||||||
|
packetWrapper.write(Type.SHORT, (short) position.getY());
|
||||||
|
packetWrapper.write(Type.INT, position.getZ());
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
String line = packetWrapper.read(Type.STRING);
|
||||||
|
line = ChatUtil.jsonToLegacy(line);
|
||||||
|
line = ChatUtil.removeUnusedColor(line, '0');
|
||||||
|
if (line.length() > 15) {
|
||||||
|
line = ChatColorUtil.stripColor(line);
|
||||||
|
if (line.length() > 15) line = line.substring(0, 15);
|
||||||
|
}
|
||||||
|
packetWrapper.write(Type.STRING, line);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.MAP_DATA, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
int id = packetWrapper.read(Type.VAR_INT);
|
||||||
|
byte scale = packetWrapper.read(Type.BYTE);
|
||||||
|
|
||||||
|
int count = packetWrapper.read(Type.VAR_INT);
|
||||||
|
byte[] icons = new byte[count * 4];
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
int j = packetWrapper.read(Type.BYTE);
|
||||||
|
icons[i * 4] = (byte) (j >> 4 & 0xF);
|
||||||
|
icons[i * 4 + 1] = packetWrapper.read(Type.BYTE);
|
||||||
|
icons[i * 4 + 2] = packetWrapper.read(Type.BYTE);
|
||||||
|
icons[i * 4 + 3] = (byte) (j & 0xF);
|
||||||
|
}
|
||||||
|
short columns = packetWrapper.read(Type.UNSIGNED_BYTE);
|
||||||
|
if (columns > 0) {
|
||||||
|
short rows = packetWrapper.read(Type.UNSIGNED_BYTE);
|
||||||
|
short x = packetWrapper.read(Type.UNSIGNED_BYTE);
|
||||||
|
short z = packetWrapper.read(Type.UNSIGNED_BYTE);
|
||||||
|
byte[] data = packetWrapper.read(Type.BYTE_ARRAY_PRIMITIVE);
|
||||||
|
|
||||||
|
for (int column = 0; column < columns; column++) {
|
||||||
|
byte[] columnData = new byte[rows + 3];
|
||||||
|
columnData[0] = 0;
|
||||||
|
columnData[1] = (byte) (x + column);
|
||||||
|
columnData[2] = (byte) z;
|
||||||
|
|
||||||
|
for (int i = 0; i < rows; i++) {
|
||||||
|
columnData[i + 3] = data[column + i * columns];
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketWrapper columnUpdate = PacketWrapper.create(0x34, null, packetWrapper.user());
|
||||||
|
columnUpdate.write(Type.VAR_INT, id);
|
||||||
|
columnUpdate.write(Type.SHORT, (short) columnData.length);
|
||||||
|
columnUpdate.write(new CustomByteType(columnData.length), columnData);
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(columnUpdate, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count > 0) {
|
||||||
|
byte[] iconData = new byte[count * 3 + 1];
|
||||||
|
iconData[0] = 1;
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
iconData[i * 3 + 1] = (byte) (icons[i * 4] << 4 | icons[i * 4 + 3] & 0xF);
|
||||||
|
iconData[i * 3 + 2] = icons[i * 4 + 1];
|
||||||
|
iconData[i * 3 + 3] = icons[i * 4 + 2];
|
||||||
|
}
|
||||||
|
PacketWrapper iconUpdate = PacketWrapper.create(0x34, null, packetWrapper.user());
|
||||||
|
iconUpdate.write(Type.VAR_INT, id);
|
||||||
|
iconUpdate.write(Type.SHORT, (short) iconData.length);
|
||||||
|
CustomByteType customByteType = new CustomByteType(iconData.length);
|
||||||
|
iconUpdate.write(customByteType, iconData);
|
||||||
|
PacketUtil.sendPacket(iconUpdate, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketWrapper scaleUpdate = PacketWrapper.create(0x34, null, packetWrapper.user());
|
||||||
|
scaleUpdate.write(Type.VAR_INT, id);
|
||||||
|
scaleUpdate.write(Type.SHORT, (short) 2);
|
||||||
|
scaleUpdate.write(new CustomByteType(2), new byte[]{2, scale});
|
||||||
|
PacketUtil.sendPacket(scaleUpdate, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.BLOCK_ENTITY_DATA, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
Position position = packetWrapper.read(Type.POSITION);
|
||||||
|
packetWrapper.write(Type.INT, position.getX());
|
||||||
|
packetWrapper.write(Type.SHORT, (short) position.getY());
|
||||||
|
packetWrapper.write(Type.INT, position.getZ());
|
||||||
|
});
|
||||||
|
map(Type.UNSIGNED_BYTE); //Action
|
||||||
|
map(Type.NBT, Types1_7_6_10.COMPRESSED_NBT);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
protocol.cancelClientbound(ClientboundPackets1_8.SERVER_DIFFICULTY);
|
||||||
|
protocol.cancelClientbound(ClientboundPackets1_8.COMBAT_EVENT);
|
||||||
|
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_8.WORLD_BORDER, null, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int action = packetWrapper.read(Type.VAR_INT);
|
||||||
|
WorldBorder worldBorder = packetWrapper.user().get(WorldBorder.class);
|
||||||
|
if (action == 0) {
|
||||||
|
worldBorder.setSize(packetWrapper.read(Type.DOUBLE));
|
||||||
|
} else if (action == 1) {
|
||||||
|
worldBorder.lerpSize(packetWrapper.read(Type.DOUBLE), packetWrapper.read(Type.DOUBLE), packetWrapper.read(VarLongType.VAR_LONG));
|
||||||
|
} else if (action == 2) {
|
||||||
|
worldBorder.setCenter(packetWrapper.read(Type.DOUBLE), packetWrapper.read(Type.DOUBLE));
|
||||||
|
} else if (action == 3) {
|
||||||
|
worldBorder.init(
|
||||||
|
packetWrapper.read(Type.DOUBLE), packetWrapper.read(Type.DOUBLE),
|
||||||
|
packetWrapper.read(Type.DOUBLE), packetWrapper.read(Type.DOUBLE),
|
||||||
|
packetWrapper.read(VarLongType.VAR_LONG),
|
||||||
|
packetWrapper.read(Type.VAR_INT),
|
||||||
|
packetWrapper.read(Type.VAR_INT), packetWrapper.read(Type.VAR_INT)
|
||||||
|
);
|
||||||
|
} else if (action == 4) {
|
||||||
|
worldBorder.setWarningTime(packetWrapper.read(Type.VAR_INT));
|
||||||
|
} else if (action == 5) {
|
||||||
|
worldBorder.setWarningBlocks(packetWrapper.read(Type.VAR_INT));
|
||||||
|
}
|
||||||
|
|
||||||
|
packetWrapper.cancel();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,158 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.provider;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
|
import io.netty.channel.ChannelHandler;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.channel.ChannelPipeline;
|
||||||
|
import io.netty.handler.codec.DecoderException;
|
||||||
|
import io.netty.handler.codec.MessageToByteEncoder;
|
||||||
|
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||||
|
import com.elevatemc.spigot.viarewind.netty.EmptyChannelHandler;
|
||||||
|
import com.elevatemc.spigot.viarewind.netty.ForwardMessageToByteEncoder;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.storage.CompressionSendStorage;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.Via;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.platform.providers.Provider;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.zip.Deflater;
|
||||||
|
import java.util.zip.Inflater;
|
||||||
|
|
||||||
|
public class CompressionHandlerProvider implements Provider {
|
||||||
|
public void handleSetCompression(UserConnection user, int threshold) {
|
||||||
|
ChannelPipeline pipeline = user.getChannel().pipeline();
|
||||||
|
if (user.isClientSide()) {
|
||||||
|
pipeline.addBefore(Via.getManager().getInjector().getEncoderName(), "compress", getEncoder(threshold));
|
||||||
|
pipeline.addBefore(Via.getManager().getInjector().getDecoderName(), "decompress", getDecoder(threshold));
|
||||||
|
} else {
|
||||||
|
CompressionSendStorage storage = user.get(CompressionSendStorage.class);
|
||||||
|
storage.setRemoveCompression(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleTransform(UserConnection user) {
|
||||||
|
CompressionSendStorage storage = user.get(CompressionSendStorage.class);
|
||||||
|
if (storage.isRemoveCompression()) {
|
||||||
|
ChannelPipeline pipeline = user.getChannel().pipeline();
|
||||||
|
|
||||||
|
String compressor = null;
|
||||||
|
String decompressor = null;
|
||||||
|
if (pipeline.get("compress") != null) {
|
||||||
|
compressor = "compress";
|
||||||
|
decompressor = "decompress";
|
||||||
|
} else if (pipeline.get("compression-encoder") != null) { // Velocity
|
||||||
|
compressor = "compression-encoder";
|
||||||
|
decompressor = "compression-decoder";
|
||||||
|
}
|
||||||
|
if (compressor != null) { // We can neutralize the effect of compressor to the client
|
||||||
|
pipeline.replace(decompressor, decompressor, new EmptyChannelHandler());
|
||||||
|
pipeline.replace(compressor, compressor, new ForwardMessageToByteEncoder());
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Couldn't remove compression for 1.7!");
|
||||||
|
}
|
||||||
|
|
||||||
|
storage.setRemoveCompression(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ChannelHandler getEncoder(int threshold) {
|
||||||
|
return new Compressor(threshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ChannelHandler getDecoder(int threshold) {
|
||||||
|
return new Decompressor(threshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Decompressor extends MessageToMessageDecoder<ByteBuf> {
|
||||||
|
// https://github.com/Gerrygames/ClientViaVersion/blob/master/src/main/java/de/gerrygames/the5zig/clientviaversion/netty/CompressionEncoder.java
|
||||||
|
private final Inflater inflater;
|
||||||
|
private final int threshold;
|
||||||
|
|
||||||
|
public Decompressor(int var1) {
|
||||||
|
this.threshold = var1;
|
||||||
|
this.inflater = new Inflater();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
||||||
|
if (!in.isReadable()) return;
|
||||||
|
|
||||||
|
int outLength = Type.VAR_INT.readPrimitive(in);
|
||||||
|
if (outLength == 0) {
|
||||||
|
out.add(in.readBytes(in.readableBytes()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outLength < this.threshold) {
|
||||||
|
throw new DecoderException("Badly compressed packet - size of " + outLength + " is below server threshold of " + this.threshold);
|
||||||
|
} else if (outLength > 2097152) {
|
||||||
|
throw new DecoderException("Badly compressed packet - size of " + outLength + " is larger than protocol maximum of " + 2097152);
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteBuf temp = in;
|
||||||
|
if (!in.hasArray()) {
|
||||||
|
temp = ByteBufAllocator.DEFAULT.heapBuffer().writeBytes(in);
|
||||||
|
} else {
|
||||||
|
in.retain();
|
||||||
|
}
|
||||||
|
ByteBuf output = ByteBufAllocator.DEFAULT.heapBuffer(outLength, outLength);
|
||||||
|
try {
|
||||||
|
this.inflater.setInput(temp.array(), temp.arrayOffset() + temp.readerIndex(), temp.readableBytes());
|
||||||
|
output.writerIndex(output.writerIndex() + this.inflater.inflate(
|
||||||
|
output.array(), output.arrayOffset(), outLength));
|
||||||
|
out.add(output.retain());
|
||||||
|
} finally {
|
||||||
|
output.release();
|
||||||
|
temp.release();
|
||||||
|
this.inflater.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Compressor extends MessageToByteEncoder<ByteBuf> {
|
||||||
|
// https://github.com/Gerrygames/ClientViaVersion/blob/master/src/main/java/de/gerrygames/the5zig/clientviaversion/netty/CompressionEncoder.java
|
||||||
|
private final Deflater deflater;
|
||||||
|
private final int threshold;
|
||||||
|
|
||||||
|
public Compressor(int var1) {
|
||||||
|
this.threshold = var1;
|
||||||
|
this.deflater = new Deflater();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void encode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception {
|
||||||
|
int frameLength = in.readableBytes();
|
||||||
|
if (frameLength < this.threshold) {
|
||||||
|
out.writeByte(0); // varint
|
||||||
|
out.writeBytes(in);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type.VAR_INT.writePrimitive(out, frameLength);
|
||||||
|
|
||||||
|
ByteBuf temp = in;
|
||||||
|
if (!in.hasArray()) {
|
||||||
|
temp = ByteBufAllocator.DEFAULT.heapBuffer().writeBytes(in);
|
||||||
|
} else {
|
||||||
|
in.retain();
|
||||||
|
}
|
||||||
|
ByteBuf output = ByteBufAllocator.DEFAULT.heapBuffer();
|
||||||
|
try {
|
||||||
|
this.deflater.setInput(temp.array(), temp.arrayOffset() + temp.readerIndex(), temp.readableBytes());
|
||||||
|
deflater.finish();
|
||||||
|
|
||||||
|
while (!deflater.finished()) {
|
||||||
|
output.ensureWritable(4096);
|
||||||
|
output.writerIndex(output.writerIndex() + this.deflater.deflate(output.array(),
|
||||||
|
output.arrayOffset() + output.writerIndex(), output.writableBytes()));
|
||||||
|
}
|
||||||
|
out.writeBytes(output);
|
||||||
|
} finally {
|
||||||
|
output.release();
|
||||||
|
temp.release();
|
||||||
|
this.deflater.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.provider;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viaversion.api.platform.providers.Provider;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
public abstract class TitleRenderProvider implements Provider {
|
||||||
|
protected Map<UUID, Integer> fadeIn = new HashMap<>();
|
||||||
|
protected Map<UUID, Integer> stay = new HashMap<>();
|
||||||
|
protected Map<UUID, Integer> fadeOut = new HashMap<>();
|
||||||
|
protected Map<UUID, String> titles = new HashMap<>();
|
||||||
|
protected Map<UUID, String> subTitles = new HashMap<>();
|
||||||
|
protected Map<UUID, AtomicInteger> times = new HashMap<>();
|
||||||
|
|
||||||
|
public void setTimings(UUID uuid, int fadeIn, int stay, int fadeOut) {
|
||||||
|
setFadeIn(uuid, fadeIn);
|
||||||
|
setStay(uuid, stay);
|
||||||
|
setFadeOut(uuid, fadeOut);
|
||||||
|
|
||||||
|
AtomicInteger time = getTime(uuid);
|
||||||
|
if (time.get()>0) time.set(getFadeIn(uuid) + getStay(uuid) + getFadeOut(uuid));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset(UUID uuid) {
|
||||||
|
this.titles.remove(uuid);
|
||||||
|
this.subTitles.remove(uuid);
|
||||||
|
getTime(uuid).set(0);
|
||||||
|
fadeIn.remove(uuid);
|
||||||
|
stay.remove(uuid);
|
||||||
|
fadeOut.remove(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(UUID uuid, String title) {
|
||||||
|
this.titles.put(uuid, title);
|
||||||
|
getTime(uuid).set(getFadeIn(uuid) + getStay(uuid) + getFadeOut(uuid));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubTitle(UUID uuid, String subTitle) {
|
||||||
|
this.subTitles.put(uuid, subTitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear(UUID uuid) {
|
||||||
|
this.titles.remove(uuid);
|
||||||
|
this.subTitles.remove(uuid);
|
||||||
|
getTime(uuid).set(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AtomicInteger getTime(UUID uuid) {
|
||||||
|
return times.computeIfAbsent(uuid, key -> new AtomicInteger(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFadeIn(UUID uuid) {
|
||||||
|
return fadeIn.getOrDefault(uuid, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStay(UUID uuid) {
|
||||||
|
return stay.getOrDefault(uuid, 70);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFadeOut(UUID uuid) {
|
||||||
|
return fadeOut.getOrDefault(uuid, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFadeIn(UUID uuid, int fadeIn) {
|
||||||
|
if (fadeIn>=0) this.fadeIn.put(uuid, fadeIn);
|
||||||
|
else this.fadeIn.remove(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStay(UUID uuid, int stay) {
|
||||||
|
if (stay>=0) this.stay.put(uuid, stay);
|
||||||
|
else this.stay.remove(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFadeOut(UUID uuid, int fadeOut) {
|
||||||
|
if (fadeOut>=0) this.fadeOut.put(uuid, fadeOut);
|
||||||
|
else this.fadeOut.remove(uuid);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.storage;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.StoredObject;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
|
||||||
|
public class CompressionSendStorage extends StoredObject {
|
||||||
|
private boolean removeCompression = false;
|
||||||
|
|
||||||
|
public CompressionSendStorage(UserConnection user) {
|
||||||
|
super(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRemoveCompression() {
|
||||||
|
return removeCompression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemoveCompression(boolean removeCompression) {
|
||||||
|
this.removeCompression = removeCompression;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,233 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.storage;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10TO1_8;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.metadata.MetadataRewriter;
|
||||||
|
import com.elevatemc.spigot.viarewind.replacement.EntityReplacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.PacketUtil;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.StoredObject;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.data.entity.ClientEntityIdChangeListener;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.entities.Entity1_10Types;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.item.Item;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.Metadata;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.types.version.Types1_8;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public class EntityTracker extends StoredObject implements ClientEntityIdChangeListener {
|
||||||
|
private final Map<Integer, Entity1_10Types.EntityType> clientEntityTypes = new ConcurrentHashMap();
|
||||||
|
private final Map<Integer, List<Metadata>> metadataBuffer = new ConcurrentHashMap();
|
||||||
|
private final Map<Integer, Integer> vehicles = new ConcurrentHashMap<>();
|
||||||
|
private final Map<Integer, EntityReplacement> entityReplacements = new ConcurrentHashMap<>();
|
||||||
|
private final Map<Integer, UUID> playersByEntityId = new HashMap<>();
|
||||||
|
private final Map<UUID, Integer> playersByUniqueId = new HashMap<>();
|
||||||
|
private final Map<UUID, Item[]> playerEquipment = new HashMap<>();
|
||||||
|
private int gamemode = 0;
|
||||||
|
private int playerId = -1;
|
||||||
|
private int spectating = -1;
|
||||||
|
private int dimension = 0;
|
||||||
|
|
||||||
|
public EntityTracker(UserConnection user) {
|
||||||
|
super(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeEntity(int entityId) {
|
||||||
|
clientEntityTypes.remove(entityId);
|
||||||
|
if (entityReplacements.containsKey(entityId)) {
|
||||||
|
entityReplacements.remove(entityId).despawn();
|
||||||
|
}
|
||||||
|
if (playersByEntityId.containsKey(entityId)) {
|
||||||
|
playersByUniqueId.remove(playersByEntityId.remove(entityId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPlayer(Integer entityId, UUID uuid) {
|
||||||
|
playersByUniqueId.put(uuid, entityId);
|
||||||
|
playersByEntityId.put(entityId, uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getPlayerUUID(int entityId) {
|
||||||
|
return playersByEntityId.get(entityId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPlayerEntityId(UUID uuid) {
|
||||||
|
return playersByUniqueId.getOrDefault(uuid, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item[] getPlayerEquipment(UUID uuid) {
|
||||||
|
return playerEquipment.get(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlayerEquipment(UUID uuid, Item[] equipment) {
|
||||||
|
playerEquipment.put(uuid, equipment);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<Integer, Entity1_10Types.EntityType> getClientEntityTypes() {
|
||||||
|
return this.clientEntityTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMetadataToBuffer(int entityID, List<Metadata> metadataList) {
|
||||||
|
if (this.metadataBuffer.containsKey(entityID)) {
|
||||||
|
this.metadataBuffer.get(entityID).addAll(metadataList);
|
||||||
|
} else if (!metadataList.isEmpty()) {
|
||||||
|
this.metadataBuffer.put(entityID, metadataList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addEntityReplacement(EntityReplacement entityReplacement) {
|
||||||
|
entityReplacements.put(entityReplacement.getEntityId(), entityReplacement);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityReplacement getEntityReplacement(int entityId) {
|
||||||
|
return entityReplacements.get(entityId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Metadata> getBufferedMetadata(int entityId) {
|
||||||
|
return metadataBuffer.get(entityId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendMetadataBuffer(int entityId) {
|
||||||
|
if (!this.metadataBuffer.containsKey(entityId)) return;
|
||||||
|
if (entityReplacements.containsKey(entityId)) {
|
||||||
|
entityReplacements.get(entityId).updateMetadata(this.metadataBuffer.remove(entityId));
|
||||||
|
} else {
|
||||||
|
Entity1_10Types.EntityType type = this.getClientEntityTypes().get(entityId);
|
||||||
|
PacketWrapper wrapper = PacketWrapper.create(0x1C, null, this.getUser());
|
||||||
|
wrapper.write(Type.VAR_INT, entityId);
|
||||||
|
wrapper.write(Types1_8.METADATA_LIST, this.metadataBuffer.get(entityId));
|
||||||
|
MetadataRewriter.transform(type, this.metadataBuffer.get(entityId));
|
||||||
|
if (!this.metadataBuffer.get(entityId).isEmpty()) {
|
||||||
|
PacketUtil.sendPacket(wrapper, Protocol1_7_6_10TO1_8.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.metadataBuffer.remove(entityId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVehicle(int passengerId) {
|
||||||
|
for (Map.Entry<Integer, Integer> vehicle : vehicles.entrySet()) {
|
||||||
|
if (vehicle.getValue()==passengerId) return vehicle.getValue();
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPassenger(int vehicleId) {
|
||||||
|
return vehicles.getOrDefault(vehicleId, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassenger(int vehicleId, int passengerId) {
|
||||||
|
if (vehicleId==this.spectating && this.spectating!=this.playerId) {
|
||||||
|
try {
|
||||||
|
PacketWrapper sneakPacket = PacketWrapper.create(0x0B, null, getUser());
|
||||||
|
sneakPacket.write(Type.VAR_INT, playerId);
|
||||||
|
sneakPacket.write(Type.VAR_INT, 0); //Start sneaking
|
||||||
|
sneakPacket.write(Type.VAR_INT, 0); //Action Parameter
|
||||||
|
|
||||||
|
PacketWrapper unsneakPacket = PacketWrapper.create(0x0B, null, getUser());
|
||||||
|
unsneakPacket.write(Type.VAR_INT, playerId);
|
||||||
|
unsneakPacket.write(Type.VAR_INT, 1); //Stop sneaking
|
||||||
|
unsneakPacket.write(Type.VAR_INT, 0); //Action Parameter
|
||||||
|
|
||||||
|
PacketUtil.sendToServer(sneakPacket, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
|
||||||
|
setSpectating(playerId);
|
||||||
|
} catch (Exception ex) {ex.printStackTrace();}
|
||||||
|
}
|
||||||
|
if (vehicleId==-1) {
|
||||||
|
int oldVehicleId = getVehicle(passengerId);
|
||||||
|
vehicles.remove(oldVehicleId);
|
||||||
|
} else if (passengerId==-1) {
|
||||||
|
vehicles.remove(vehicleId);
|
||||||
|
} else {
|
||||||
|
vehicles.put(vehicleId, passengerId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSpectating() {
|
||||||
|
return spectating;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setSpectating(int spectating) {
|
||||||
|
if (spectating!=this.playerId && getPassenger(spectating)!=-1) {
|
||||||
|
|
||||||
|
PacketWrapper sneakPacket = PacketWrapper.create(0x0B, null, getUser());
|
||||||
|
sneakPacket.write(Type.VAR_INT, playerId);
|
||||||
|
sneakPacket.write(Type.VAR_INT, 0); //Start sneaking
|
||||||
|
sneakPacket.write(Type.VAR_INT, 0); //Action Parameter
|
||||||
|
|
||||||
|
PacketWrapper unsneakPacket = PacketWrapper.create(0x0B, null, getUser());
|
||||||
|
unsneakPacket.write(Type.VAR_INT, playerId);
|
||||||
|
unsneakPacket.write(Type.VAR_INT, 1); //Stop sneaking
|
||||||
|
unsneakPacket.write(Type.VAR_INT, 0); //Action Parameter
|
||||||
|
|
||||||
|
PacketUtil.sendToServer(sneakPacket, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
|
||||||
|
setSpectating(this.playerId);
|
||||||
|
return false; //Entity has Passenger
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.spectating!=spectating && this.spectating!=this.playerId) {
|
||||||
|
PacketWrapper unmount = PacketWrapper.create(0x1B, null, this.getUser());
|
||||||
|
unmount.write(Type.INT, this.playerId);
|
||||||
|
unmount.write(Type.INT, -1);
|
||||||
|
unmount.write(Type.BOOLEAN, false);
|
||||||
|
PacketUtil.sendPacket(unmount, Protocol1_7_6_10TO1_8.class);
|
||||||
|
}
|
||||||
|
this.spectating = spectating;
|
||||||
|
if (spectating!=this.playerId) {
|
||||||
|
PacketWrapper mount = PacketWrapper.create(0x1B, null, this.getUser());
|
||||||
|
mount.write(Type.INT, this.playerId);
|
||||||
|
mount.write(Type.INT, this.spectating);
|
||||||
|
mount.write(Type.BOOLEAN, false);
|
||||||
|
PacketUtil.sendPacket(mount, Protocol1_7_6_10TO1_8.class);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getGamemode() {
|
||||||
|
return gamemode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGamemode(int gamemode) {
|
||||||
|
this.gamemode = gamemode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPlayerId() {
|
||||||
|
return playerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlayerId(int playerId) {
|
||||||
|
this.playerId = this.spectating = playerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearEntities() {
|
||||||
|
clientEntityTypes.clear();
|
||||||
|
entityReplacements.clear();
|
||||||
|
vehicles.clear();
|
||||||
|
metadataBuffer.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDimension() {
|
||||||
|
return dimension;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDimension(int dimension) {
|
||||||
|
this.dimension = dimension;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setClientEntityId(int playerEntityId) {
|
||||||
|
if (this.spectating == this.playerId) {
|
||||||
|
this.spectating = playerEntityId;
|
||||||
|
}
|
||||||
|
clientEntityTypes.remove(this.playerId);
|
||||||
|
this.playerId = playerEntityId;
|
||||||
|
clientEntityTypes.put(this.playerId, Entity1_10Types.EntityType.ENTITY_HUMAN);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,136 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.storage;
|
||||||
|
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.ChatUtil;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.StoredObject;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.item.DataItem;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.item.Item;
|
||||||
|
import com.elevatemc.spigot.viaversion.util.ChatColorUtil;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class GameProfileStorage extends StoredObject {
|
||||||
|
private Map<UUID, GameProfile> properties = new HashMap<>();
|
||||||
|
|
||||||
|
public GameProfileStorage(UserConnection user) {
|
||||||
|
super(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameProfile put(UUID uuid, String name) {
|
||||||
|
GameProfile gameProfile = new GameProfile(uuid, name);
|
||||||
|
properties.put(uuid, gameProfile);
|
||||||
|
return gameProfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putProperty(UUID uuid, Property property) {
|
||||||
|
properties.computeIfAbsent(uuid, profile -> new GameProfile(uuid, null)).properties.add(property);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putProperty(UUID uuid, String name, String value, String signature) {
|
||||||
|
putProperty(uuid, new Property(name, value, signature));
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameProfile get(UUID uuid) {
|
||||||
|
return properties.get(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameProfile get(String name, boolean ignoreCase) {
|
||||||
|
if (ignoreCase) name = name.toLowerCase();
|
||||||
|
|
||||||
|
for (GameProfile profile : properties.values()) {
|
||||||
|
if (profile.name == null) continue;
|
||||||
|
|
||||||
|
String n = ignoreCase ? profile.name.toLowerCase() : profile.name;
|
||||||
|
|
||||||
|
if (n.equals(name)) {
|
||||||
|
return profile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<GameProfile> getAllWithPrefix(String prefix, boolean ignoreCase) {
|
||||||
|
if (ignoreCase) prefix = prefix.toLowerCase();
|
||||||
|
|
||||||
|
ArrayList<GameProfile> profiles = new ArrayList<>();
|
||||||
|
|
||||||
|
for (GameProfile profile : properties.values()) {
|
||||||
|
if (profile.name == null) continue;
|
||||||
|
|
||||||
|
String n = ignoreCase ? profile.name.toLowerCase() : profile.name;
|
||||||
|
|
||||||
|
if (n.startsWith(prefix)) profiles.add(profile);
|
||||||
|
}
|
||||||
|
|
||||||
|
return profiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameProfile remove(UUID uuid) {
|
||||||
|
return properties.remove(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class GameProfile {
|
||||||
|
public String name;
|
||||||
|
public String displayName;
|
||||||
|
public int ping;
|
||||||
|
public UUID uuid;
|
||||||
|
public List<Property> properties = new ArrayList<>();
|
||||||
|
public int gamemode = 0;
|
||||||
|
|
||||||
|
public GameProfile(UUID uuid, String name) {
|
||||||
|
this.name = name;
|
||||||
|
this.uuid = uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item getSkull() {
|
||||||
|
CompoundTag tag = new CompoundTag();
|
||||||
|
CompoundTag ownerTag = new CompoundTag();
|
||||||
|
tag.put("SkullOwner", ownerTag);
|
||||||
|
ownerTag.put("Id", new StringTag(uuid.toString()));
|
||||||
|
CompoundTag properties = new CompoundTag();
|
||||||
|
ownerTag.put("Properties", properties);
|
||||||
|
ListTag textures = new ListTag(CompoundTag.class);
|
||||||
|
properties.put("textures", textures);
|
||||||
|
for (Property property : this.properties) {
|
||||||
|
if (property.name.equals("textures")) {
|
||||||
|
CompoundTag textureTag = new CompoundTag();
|
||||||
|
textureTag.put("Value", new StringTag(property.value));
|
||||||
|
if (property.signature != null) {
|
||||||
|
textureTag.put("Signature", new StringTag(property.signature));
|
||||||
|
}
|
||||||
|
textures.add(textureTag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new DataItem(397, (byte) 1, (short) 3, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDisplayName() {
|
||||||
|
String displayName = this.displayName == null ? name : this.displayName;
|
||||||
|
if (displayName.length() > 16) displayName = ChatUtil.removeUnusedColor(displayName, 'f');
|
||||||
|
if (displayName.length() > 16) displayName = ChatColorUtil.stripColor(displayName);
|
||||||
|
if (displayName.length() > 16) displayName = displayName.substring(0, 16);
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisplayName(String displayName) {
|
||||||
|
this.displayName = displayName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Property {
|
||||||
|
public String name;
|
||||||
|
public String value;
|
||||||
|
public String signature;
|
||||||
|
|
||||||
|
public Property(String name, String value, String signature) {
|
||||||
|
this.name = name;
|
||||||
|
this.value = value;
|
||||||
|
this.signature = signature;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,115 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.storage;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.StoredObject;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
|
||||||
|
public class PlayerAbilities extends StoredObject {
|
||||||
|
private boolean sprinting, allowFly, flying, invincible, creative;
|
||||||
|
private float flySpeed, walkSpeed;
|
||||||
|
|
||||||
|
public PlayerAbilities(UserConnection user) {
|
||||||
|
super(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getFlags() {
|
||||||
|
byte flags = 0;
|
||||||
|
if (invincible) flags |= 8;
|
||||||
|
if (allowFly) flags |= 4;
|
||||||
|
if (flying) flags |= 2;
|
||||||
|
if (creative) flags |= 1;
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSprinting() {
|
||||||
|
return this.sprinting;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAllowFly() {
|
||||||
|
return this.allowFly;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFlying() {
|
||||||
|
return this.flying;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInvincible() {
|
||||||
|
return this.invincible;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCreative() {
|
||||||
|
return this.creative;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getFlySpeed() {
|
||||||
|
return this.flySpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getWalkSpeed() {
|
||||||
|
return this.walkSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSprinting(boolean sprinting) {
|
||||||
|
this.sprinting = sprinting;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllowFly(boolean allowFly) {
|
||||||
|
this.allowFly = allowFly;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFlying(boolean flying) {
|
||||||
|
this.flying = flying;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInvincible(boolean invincible) {
|
||||||
|
this.invincible = invincible;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreative(boolean creative) {
|
||||||
|
this.creative = creative;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFlySpeed(float flySpeed) {
|
||||||
|
this.flySpeed = flySpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWalkSpeed(float walkSpeed) {
|
||||||
|
this.walkSpeed = walkSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(final Object o) {
|
||||||
|
if (o == this) return true;
|
||||||
|
if (!(o instanceof PlayerAbilities))
|
||||||
|
return false;
|
||||||
|
final PlayerAbilities other = (PlayerAbilities) o;
|
||||||
|
if (!other.canEqual((Object) this)) return false;
|
||||||
|
if (this.isSprinting() != other.isSprinting()) return false;
|
||||||
|
if (this.isAllowFly() != other.isAllowFly()) return false;
|
||||||
|
if (this.isFlying() != other.isFlying()) return false;
|
||||||
|
if (this.isInvincible() != other.isInvincible()) return false;
|
||||||
|
if (this.isCreative() != other.isCreative()) return false;
|
||||||
|
if (Float.compare(this.getFlySpeed(), other.getFlySpeed()) != 0) return false;
|
||||||
|
if (Float.compare(this.getWalkSpeed(), other.getWalkSpeed()) != 0) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean canEqual(final Object other) {
|
||||||
|
return other instanceof PlayerAbilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
final int PRIME = 59;
|
||||||
|
int result = 1;
|
||||||
|
result = result * PRIME + (this.isSprinting() ? 79 : 97);
|
||||||
|
result = result * PRIME + (this.isAllowFly() ? 79 : 97);
|
||||||
|
result = result * PRIME + (this.isFlying() ? 79 : 97);
|
||||||
|
result = result * PRIME + (this.isInvincible() ? 79 : 97);
|
||||||
|
result = result * PRIME + (this.isCreative() ? 79 : 97);
|
||||||
|
result = result * PRIME + Float.floatToIntBits(this.getFlySpeed());
|
||||||
|
result = result * PRIME + Float.floatToIntBits(this.getWalkSpeed());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "PlayerAbilities(sprinting=" + this.isSprinting() + ", allowFly=" + this.isAllowFly() + ", flying=" + this.isFlying() + ", invincible=" + this.isInvincible() + ", creative=" + this.isCreative() + ", flySpeed=" + this.getFlySpeed() + ", walkSpeed=" + this.getWalkSpeed() + ")";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.storage;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.StoredObject;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
|
||||||
|
public class PlayerPosition extends StoredObject {
|
||||||
|
private double posX, posY, posZ;
|
||||||
|
private float yaw, pitch;
|
||||||
|
private boolean onGround;
|
||||||
|
private boolean positionPacketReceived;
|
||||||
|
private double receivedPosY;
|
||||||
|
|
||||||
|
public PlayerPosition(UserConnection user) {
|
||||||
|
super(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPos(double x, double y, double z) {
|
||||||
|
posX = x;
|
||||||
|
posY = y;
|
||||||
|
posZ = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPositionPacketReceived() {
|
||||||
|
return positionPacketReceived;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPositionPacketReceived(boolean positionPacketReceived) {
|
||||||
|
this.positionPacketReceived = positionPacketReceived;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getReceivedPosY() {
|
||||||
|
return receivedPosY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReceivedPosY(double receivedPosY) {
|
||||||
|
this.receivedPosY = receivedPosY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getPosX() {
|
||||||
|
return posX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPosX(double posX) {
|
||||||
|
this.posX = posX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getPosY() {
|
||||||
|
return posY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPosY(double posY) {
|
||||||
|
this.posY = posY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getPosZ() {
|
||||||
|
return posZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPosZ(double posZ) {
|
||||||
|
this.posZ = posZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getYaw() {
|
||||||
|
return yaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYaw(float yaw) {
|
||||||
|
this.yaw = yaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getPitch() {
|
||||||
|
return pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPitch(float pitch) {
|
||||||
|
this.pitch = pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOnGround() {
|
||||||
|
return onGround;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnGround(boolean onGround) {
|
||||||
|
this.onGround = onGround;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,168 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.storage;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10TO1_8;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.PacketUtil;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.StoredObject;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class Scoreboard extends StoredObject {
|
||||||
|
private HashMap<String, List<String>> teams = new HashMap<>();
|
||||||
|
private HashSet<String> objectives = new HashSet<>();
|
||||||
|
private HashMap<String, ScoreTeam> scoreTeams = new HashMap<>();
|
||||||
|
private HashMap<String, Byte> teamColors = new HashMap<>();
|
||||||
|
private HashSet<String> scoreTeamNames = new HashSet<>();
|
||||||
|
private String colorIndependentSidebar;
|
||||||
|
private HashMap<Byte, String> colorDependentSidebar = new HashMap<>();
|
||||||
|
|
||||||
|
public Scoreboard(UserConnection user) {
|
||||||
|
super(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPlayerToTeam(String player, String team) {
|
||||||
|
teams.computeIfAbsent(team, key -> new ArrayList<>()).add(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTeamColor(String team, Byte color) {
|
||||||
|
teamColors.put(team, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Byte> getTeamColor(String team) {
|
||||||
|
return Optional.ofNullable(teamColors.get(team));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTeam(String team) {
|
||||||
|
teams.computeIfAbsent(team, key -> new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeTeam(String team) {
|
||||||
|
teams.remove(team);
|
||||||
|
scoreTeams.remove(team);
|
||||||
|
teamColors.remove(team);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean teamExists(String team) {
|
||||||
|
return teams.containsKey(team);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removePlayerFromTeam(String player, String team) {
|
||||||
|
List<String> teamPlayers = teams.get(team);
|
||||||
|
if (teamPlayers!=null) teamPlayers.remove(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPlayerInTeam(String player, String team) {
|
||||||
|
List<String> teamPlayers = teams.get(team);
|
||||||
|
return teamPlayers != null && teamPlayers.contains(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPlayerInTeam(String player) {
|
||||||
|
for (List<String> teamPlayers : teams.values()) {
|
||||||
|
if (teamPlayers.contains(player)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Byte> getPlayerTeamColor(String player) {
|
||||||
|
Optional<String> team = getTeam(player);
|
||||||
|
return team.isPresent() ? getTeamColor(team.get()) : Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<String> getTeam(String player) {
|
||||||
|
for (Map.Entry<String, List<String>> entry : teams.entrySet())
|
||||||
|
if (entry.getValue().contains(player))
|
||||||
|
return Optional.of(entry.getKey());
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addObjective(String name) {
|
||||||
|
objectives.add(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeObjective(String name) {
|
||||||
|
objectives.remove(name);
|
||||||
|
colorDependentSidebar.values().remove(name);
|
||||||
|
if (name.equals(colorIndependentSidebar)) {
|
||||||
|
colorIndependentSidebar = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean objectiveExists(String name) {
|
||||||
|
return objectives.contains(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String sendTeamForScore(String score) {
|
||||||
|
if (score.length()<=16) return score;
|
||||||
|
if (scoreTeams.containsKey(score)) return scoreTeams.get(score).name;
|
||||||
|
int l = 16;
|
||||||
|
int i = Math.min(16, score.length()-16);
|
||||||
|
String name = score.substring(i, i+l);
|
||||||
|
while (scoreTeamNames.contains(name) || teams.containsKey(name)) {
|
||||||
|
i--;
|
||||||
|
while (score.length()-l-i>16) {
|
||||||
|
l--;
|
||||||
|
if (l<1) return score;
|
||||||
|
i = Math.min(16, score.length()-l);
|
||||||
|
}
|
||||||
|
name = score.substring(i, i+l);
|
||||||
|
}
|
||||||
|
String prefix = score.substring(0, i);
|
||||||
|
String suffix = i+l>=score.length() ? "" : score.substring(i+l, score.length());
|
||||||
|
|
||||||
|
ScoreTeam scoreTeam = new ScoreTeam(name, prefix, suffix);
|
||||||
|
scoreTeams.put(score, scoreTeam);
|
||||||
|
scoreTeamNames.add(name);
|
||||||
|
|
||||||
|
PacketWrapper teamPacket = PacketWrapper.create(0x3E, null, getUser());
|
||||||
|
teamPacket.write(Type.STRING, name);
|
||||||
|
teamPacket.write(Type.BYTE, (byte) 0);
|
||||||
|
teamPacket.write(Type.STRING, "ViaRewind");
|
||||||
|
teamPacket.write(Type.STRING, prefix);
|
||||||
|
teamPacket.write(Type.STRING, suffix);
|
||||||
|
teamPacket.write(Type.BYTE, (byte) 0);
|
||||||
|
teamPacket.write(Type.SHORT, (short) 1);
|
||||||
|
teamPacket.write(Type.STRING, name);
|
||||||
|
PacketUtil.sendPacket(teamPacket, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String removeTeamForScore(String score) {
|
||||||
|
ScoreTeam scoreTeam = scoreTeams.remove(score);
|
||||||
|
if (scoreTeam==null) return score;
|
||||||
|
scoreTeamNames.remove(scoreTeam.name);
|
||||||
|
|
||||||
|
PacketWrapper teamPacket = PacketWrapper.create(0x3E, null, getUser());
|
||||||
|
teamPacket.write(Type.STRING, scoreTeam.name);
|
||||||
|
teamPacket.write(Type.BYTE, (byte) 1);
|
||||||
|
PacketUtil.sendPacket(teamPacket, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
|
||||||
|
return scoreTeam.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getColorIndependentSidebar() {
|
||||||
|
return this.colorIndependentSidebar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMap<Byte, String> getColorDependentSidebar() {
|
||||||
|
return this.colorDependentSidebar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColorIndependentSidebar(String colorIndependentSidebar) {
|
||||||
|
this.colorIndependentSidebar = colorIndependentSidebar;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ScoreTeam {
|
||||||
|
private String prefix;
|
||||||
|
private String suffix;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public ScoreTeam(String name, String prefix, String suffix) {
|
||||||
|
this.prefix = prefix;
|
||||||
|
this.suffix = suffix;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,132 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.storage;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.StoredObject;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class Windows extends StoredObject {
|
||||||
|
public HashMap<Short, Short> types = new HashMap<>();
|
||||||
|
public HashMap<Short, Furnace> furnace = new HashMap<>();
|
||||||
|
public short levelCost = 0;
|
||||||
|
public short anvilId = -1;
|
||||||
|
|
||||||
|
public Windows(UserConnection user) {
|
||||||
|
super(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public short get(short windowId) {
|
||||||
|
return types.getOrDefault(windowId, (short)-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(short windowId) {
|
||||||
|
types.remove(windowId);
|
||||||
|
furnace.remove(windowId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getInventoryType(String name) {
|
||||||
|
switch(name) {
|
||||||
|
case "minecraft:container":
|
||||||
|
return 0;
|
||||||
|
case "minecraft:chest":
|
||||||
|
return 0;
|
||||||
|
case "minecraft:crafting_table":
|
||||||
|
return 1;
|
||||||
|
case "minecraft:furnace":
|
||||||
|
return 2;
|
||||||
|
case "minecraft:dispenser":
|
||||||
|
return 3;
|
||||||
|
case "minecraft:enchanting_table":
|
||||||
|
return 4;
|
||||||
|
case "minecraft:brewing_stand":
|
||||||
|
return 5;
|
||||||
|
case "minecraft:villager":
|
||||||
|
return 6;
|
||||||
|
case "minecraft:beacon":
|
||||||
|
return 7;
|
||||||
|
case "minecraft:anvil":
|
||||||
|
return 8;
|
||||||
|
case "minecraft:hopper":
|
||||||
|
return 9;
|
||||||
|
case "minecraft:dropper":
|
||||||
|
return 10;
|
||||||
|
case "EntityHorse":
|
||||||
|
return 11;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unknown type " + name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Furnace {
|
||||||
|
private short fuelLeft = 0;
|
||||||
|
private short maxFuel = 0;
|
||||||
|
private short progress = 0;
|
||||||
|
private short maxProgress = 200;
|
||||||
|
|
||||||
|
public Furnace() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getFuelLeft() {
|
||||||
|
return this.fuelLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getMaxFuel() {
|
||||||
|
return this.maxFuel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getProgress() {
|
||||||
|
return this.progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getMaxProgress() {
|
||||||
|
return this.maxProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFuelLeft(short fuelLeft) {
|
||||||
|
this.fuelLeft = fuelLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxFuel(short maxFuel) {
|
||||||
|
this.maxFuel = maxFuel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProgress(short progress) {
|
||||||
|
this.progress = progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxProgress(short maxProgress) {
|
||||||
|
this.maxProgress = maxProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(final Object o) {
|
||||||
|
if (o == this) return true;
|
||||||
|
if (!(o instanceof Furnace))
|
||||||
|
return false;
|
||||||
|
final Furnace other = (Furnace) o;
|
||||||
|
if (!other.canEqual((Object) this)) return false;
|
||||||
|
if (this.getFuelLeft() != other.getFuelLeft()) return false;
|
||||||
|
if (this.getMaxFuel() != other.getMaxFuel()) return false;
|
||||||
|
if (this.getProgress() != other.getProgress()) return false;
|
||||||
|
if (this.getMaxProgress() != other.getMaxProgress()) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean canEqual(final Object other) {
|
||||||
|
return other instanceof Furnace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
final int PRIME = 59;
|
||||||
|
int result = 1;
|
||||||
|
result = result * PRIME + this.getFuelLeft();
|
||||||
|
result = result * PRIME + this.getMaxFuel();
|
||||||
|
result = result * PRIME + this.getProgress();
|
||||||
|
result = result * PRIME + this.getMaxProgress();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "Windows.Furnace(fuelLeft=" + this.getFuelLeft() + ", maxFuel=" + this.getMaxFuel() + ", progress=" + this.getProgress() + ", maxProgress=" + this.getMaxProgress() + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,192 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.storage;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10TO1_8;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.PacketUtil;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.Tickable;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.StoredObject;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
|
||||||
|
public class WorldBorder extends StoredObject implements Tickable {
|
||||||
|
private double x, z;
|
||||||
|
private double oldDiameter, newDiameter;
|
||||||
|
private long lerpTime;
|
||||||
|
private long lerpStartTime;
|
||||||
|
private int portalTeleportBoundary;
|
||||||
|
private int warningTime, warningBlocks;
|
||||||
|
private boolean init = false;
|
||||||
|
|
||||||
|
private final int VIEW_DISTANCE = 16;
|
||||||
|
|
||||||
|
public WorldBorder(UserConnection user) {
|
||||||
|
super(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
if (!isInit()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendPackets();
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum Side {
|
||||||
|
NORTH(0, -1),
|
||||||
|
EAST(1, 0),
|
||||||
|
SOUTH(0, 1),
|
||||||
|
WEST(-1, 0),
|
||||||
|
;
|
||||||
|
|
||||||
|
private int modX;
|
||||||
|
private int modZ;
|
||||||
|
|
||||||
|
Side(int modX, int modZ) {
|
||||||
|
this.modX = modX;
|
||||||
|
this.modZ = modZ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendPackets() {
|
||||||
|
PlayerPosition position = getUser().get(PlayerPosition.class);
|
||||||
|
|
||||||
|
double radius = getSize() / 2.0;
|
||||||
|
|
||||||
|
for (Side side : Side.values()) {
|
||||||
|
double d;
|
||||||
|
double pos;
|
||||||
|
double center;
|
||||||
|
if (side.modX!=0) {
|
||||||
|
pos = position.getPosZ();
|
||||||
|
center = z;
|
||||||
|
d = Math.abs(x + radius * side.modX - position.getPosX());
|
||||||
|
} else {
|
||||||
|
center = x;
|
||||||
|
pos = position.getPosX();
|
||||||
|
d = Math.abs(z + radius * side.modZ - position.getPosZ());
|
||||||
|
}
|
||||||
|
if (d >= VIEW_DISTANCE) continue;
|
||||||
|
|
||||||
|
double r = Math.sqrt(VIEW_DISTANCE * VIEW_DISTANCE - d * d);
|
||||||
|
|
||||||
|
double minH = Math.ceil(pos - r);
|
||||||
|
double maxH = Math.floor(pos + r);
|
||||||
|
double minV = Math.ceil(position.getPosY() - r);
|
||||||
|
double maxV = Math.floor(position.getPosY() + r);
|
||||||
|
|
||||||
|
if (minH<center-radius) minH = Math.ceil(center-radius);
|
||||||
|
if (maxH>center+radius) maxH = Math.floor(center+radius);
|
||||||
|
if (minV<0.0) minV = 0.0;
|
||||||
|
|
||||||
|
double centerH = (minH+maxH) / 2.0;
|
||||||
|
double centerV = (minV+maxV) / 2.0;
|
||||||
|
|
||||||
|
int a = (int) Math.floor((maxH-minH) * (maxV-minV) * 0.5);
|
||||||
|
|
||||||
|
double b = 2.5;
|
||||||
|
|
||||||
|
PacketWrapper particles = PacketWrapper.create(0x2A, null, getUser());
|
||||||
|
particles.write(Type.STRING, "fireworksSpark");
|
||||||
|
particles.write(Type.FLOAT, (float)(side.modX!=0 ? x + (radius * side.modX) : centerH));
|
||||||
|
particles.write(Type.FLOAT, (float)centerV);
|
||||||
|
particles.write(Type.FLOAT, (float)(side.modX==0 ? z + (radius * side.modZ) : centerH));
|
||||||
|
particles.write(Type.FLOAT, (float)(side.modX!=0 ? 0f : (maxH-minH) / b));
|
||||||
|
particles.write(Type.FLOAT, (float)((maxV-minV) / b));
|
||||||
|
particles.write(Type.FLOAT, (float)(side.modX==0 ? 0f : (maxH-minH) / b));
|
||||||
|
particles.write(Type.FLOAT, 0f);
|
||||||
|
particles.write(Type.INT, a);
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(particles, Protocol1_7_6_10TO1_8.class, true, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isInit() {
|
||||||
|
return init;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(double x, double z, double oldDiameter, double newDiameter, long lerpTime, int portalTeleportBoundary, int warningTime, int warningBlocks) {
|
||||||
|
this.x = x;
|
||||||
|
this.z = z;
|
||||||
|
this.oldDiameter = oldDiameter;
|
||||||
|
this.newDiameter = newDiameter;
|
||||||
|
this.lerpTime = lerpTime;
|
||||||
|
this.portalTeleportBoundary = portalTeleportBoundary;
|
||||||
|
this.warningTime = warningTime;
|
||||||
|
this.warningBlocks = warningBlocks;
|
||||||
|
init = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getZ() {
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCenter(double x, double z) {
|
||||||
|
this.x = x;
|
||||||
|
this.z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getOldDiameter() {
|
||||||
|
return oldDiameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getNewDiameter() {
|
||||||
|
return newDiameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLerpTime() {
|
||||||
|
return lerpTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void lerpSize(double oldDiameter, double newDiameter, long lerpTime) {
|
||||||
|
this.oldDiameter = oldDiameter;
|
||||||
|
this.newDiameter = newDiameter;
|
||||||
|
this.lerpTime = lerpTime;
|
||||||
|
this.lerpStartTime = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSize(double size) {
|
||||||
|
this.oldDiameter = size;
|
||||||
|
this.newDiameter = size;
|
||||||
|
this.lerpTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getSize() {
|
||||||
|
if (lerpTime==0) return newDiameter;
|
||||||
|
|
||||||
|
long time = System.currentTimeMillis() - lerpStartTime;
|
||||||
|
double percent = ((double)(time) / (double)(lerpTime));
|
||||||
|
if (percent>1.0d) percent = 1.0d;
|
||||||
|
else if (percent<0.0d) percent = 0.0d;
|
||||||
|
|
||||||
|
return oldDiameter + (newDiameter-oldDiameter) * percent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPortalTeleportBoundary() {
|
||||||
|
return portalTeleportBoundary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPortalTeleportBoundary(int portalTeleportBoundary) {
|
||||||
|
this.portalTeleportBoundary = portalTeleportBoundary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWarningTime() {
|
||||||
|
return warningTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWarningTime(int warningTime) {
|
||||||
|
this.warningTime = warningTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWarningBlocks() {
|
||||||
|
return warningBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWarningBlocks(int warningBlocks) {
|
||||||
|
this.warningBlocks = warningBlocks;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,99 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.Environment;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.chunks.Chunk;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.chunks.ChunkSection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.PartialType;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
|
||||||
|
|
||||||
|
import java.util.zip.Deflater;
|
||||||
|
|
||||||
|
public class Chunk1_7_10Type extends PartialType<Chunk, ClientWorld> {
|
||||||
|
|
||||||
|
public Chunk1_7_10Type(ClientWorld param) {
|
||||||
|
super(param, Chunk.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Chunk read(ByteBuf byteBuf, ClientWorld clientWorld) throws Exception {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(ByteBuf output, ClientWorld clientWorld, Chunk chunk) throws Exception {
|
||||||
|
output.writeInt(chunk.getX());
|
||||||
|
output.writeInt(chunk.getZ());
|
||||||
|
output.writeBoolean(chunk.isFullChunk());
|
||||||
|
output.writeShort(chunk.getBitmask());
|
||||||
|
output.writeShort(0);
|
||||||
|
|
||||||
|
ByteBuf dataToCompress = output.alloc().buffer();
|
||||||
|
|
||||||
|
// Half byte per block data
|
||||||
|
ByteBuf blockData = output.alloc().buffer();
|
||||||
|
|
||||||
|
for (int i = 0; i < chunk.getSections().length; i++) {
|
||||||
|
if ((chunk.getBitmask() & 1 << i) == 0) continue;
|
||||||
|
ChunkSection section = chunk.getSections()[i];
|
||||||
|
for (int y = 0; y < 16; y++) {
|
||||||
|
for (int z = 0; z < 16; z++) {
|
||||||
|
int previousData = 0;
|
||||||
|
for (int x = 0; x < 16; x++) {
|
||||||
|
int block = section.getFlatBlock(x, y, z);
|
||||||
|
dataToCompress.writeByte(block >> 4);
|
||||||
|
|
||||||
|
int data = block & 0xF;
|
||||||
|
if (x % 2 == 0) {
|
||||||
|
previousData = data;
|
||||||
|
} else {
|
||||||
|
blockData.writeByte((data << 4) | previousData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dataToCompress.writeBytes(blockData);
|
||||||
|
blockData.release();
|
||||||
|
|
||||||
|
for (int i = 0; i < chunk.getSections().length; i++) {
|
||||||
|
if ((chunk.getBitmask() & 1 << i) == 0) continue;
|
||||||
|
chunk.getSections()[i].getLight().writeBlockLight(dataToCompress);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean skyLight = clientWorld != null && clientWorld.getEnvironment() == Environment.NORMAL;
|
||||||
|
if (skyLight) {
|
||||||
|
for (int i = 0; i < chunk.getSections().length; i++) {
|
||||||
|
if ((chunk.getBitmask() & 1 << i) == 0) continue;
|
||||||
|
chunk.getSections()[i].getLight().writeSkyLight(dataToCompress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chunk.isFullChunk() && chunk.isBiomeData()) {
|
||||||
|
for (int biome : chunk.getBiomeData()) {
|
||||||
|
dataToCompress.writeByte((byte) biome);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dataToCompress.readerIndex(0);
|
||||||
|
byte[] data = new byte[dataToCompress.readableBytes()];
|
||||||
|
dataToCompress.readBytes(data);
|
||||||
|
dataToCompress.release();
|
||||||
|
|
||||||
|
Deflater deflater = new Deflater(4); // todo let user choose compression
|
||||||
|
byte[] compressedData;
|
||||||
|
int compressedSize;
|
||||||
|
try {
|
||||||
|
deflater.setInput(data, 0, data.length);
|
||||||
|
deflater.finish();
|
||||||
|
compressedData = new byte[data.length];
|
||||||
|
compressedSize = deflater.deflate(compressedData);
|
||||||
|
} finally {
|
||||||
|
deflater.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
output.writeInt(compressedSize);
|
||||||
|
|
||||||
|
output.writeBytes(compressedData, 0, compressedSize);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types;
|
||||||
|
|
||||||
|
import com.github.steveice10.opennbt.NBTIO;
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.ByteBufInputStream;
|
||||||
|
import io.netty.buffer.ByteBufOutputStream;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
|
public class CompressedNBTType extends Type<CompoundTag> {
|
||||||
|
public CompressedNBTType() {
|
||||||
|
super(CompoundTag.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompoundTag read(ByteBuf buffer) throws IOException {
|
||||||
|
short length = buffer.readShort();
|
||||||
|
if (length <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteBuf compressed = buffer.readSlice(length);
|
||||||
|
|
||||||
|
try (GZIPInputStream gzipStream = new GZIPInputStream(new ByteBufInputStream(compressed))) {
|
||||||
|
return NBTIO.readTag(gzipStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(ByteBuf buffer, CompoundTag nbt) throws Exception {
|
||||||
|
if (nbt == null) {
|
||||||
|
buffer.writeShort(-1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteBuf compressedBuf = buffer.alloc().buffer();
|
||||||
|
try {
|
||||||
|
try (GZIPOutputStream gzipStream = new GZIPOutputStream(new ByteBufOutputStream(compressedBuf))) {
|
||||||
|
NBTIO.writeTag(gzipStream, nbt);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.writeShort(compressedBuf.readableBytes());
|
||||||
|
buffer.writeBytes(compressedBuf);
|
||||||
|
} finally {
|
||||||
|
compressedBuf.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.PartialType;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
|
||||||
|
public class CustomStringType extends PartialType<String[], Integer> {
|
||||||
|
|
||||||
|
public CustomStringType(Integer param) {
|
||||||
|
super(param, String[].class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] read(ByteBuf buffer, Integer size) throws Exception {
|
||||||
|
if (buffer.readableBytes() < size/4) {
|
||||||
|
throw new RuntimeException("Readable bytes does not match expected!");
|
||||||
|
} else {
|
||||||
|
String[] array = new String[size];
|
||||||
|
for (int i = 0; i<size; i++) {
|
||||||
|
array[i] = Type.STRING.read(buffer);
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(ByteBuf buffer, Integer size, String[] strings) throws Exception {
|
||||||
|
for (String s : strings) Type.STRING.write(buffer, s);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
|
||||||
|
public class IntArrayType extends Type<int[]> {
|
||||||
|
|
||||||
|
public IntArrayType() {
|
||||||
|
super(int[].class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] read(ByteBuf byteBuf) throws Exception {
|
||||||
|
byte size = byteBuf.readByte();
|
||||||
|
int[] array = new int[size];
|
||||||
|
for (byte i = 0; i < size; i++) {
|
||||||
|
array[i] = byteBuf.readInt();
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(ByteBuf byteBuf, int[] array) throws Exception {
|
||||||
|
byteBuf.writeByte(array.length);
|
||||||
|
for (int i : array) byteBuf.writeInt(i);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.item.Item;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
|
||||||
|
public class ItemArrayType extends Type<Item[]> {
|
||||||
|
private final boolean compressed;
|
||||||
|
|
||||||
|
public ItemArrayType(boolean compressed) {
|
||||||
|
super(Item[].class);
|
||||||
|
this.compressed = compressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Item[] read(ByteBuf buffer) throws Exception {
|
||||||
|
int amount = Type.SHORT.read(buffer);
|
||||||
|
Item[] items = new Item[amount];
|
||||||
|
|
||||||
|
for(int i = 0; i < amount; ++i) {
|
||||||
|
items[i] = (compressed ? Types1_7_6_10.COMPRESSED_NBT_ITEM : Types1_7_6_10.ITEM).read(buffer);
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(ByteBuf buffer, Item[] items) throws Exception {
|
||||||
|
Type.SHORT.write(buffer, (short)items.length);
|
||||||
|
for (Item item : items) {
|
||||||
|
(compressed ? Types1_7_6_10.COMPRESSED_NBT_ITEM : Types1_7_6_10.ITEM).write(buffer, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.item.DataItem;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.item.Item;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
|
||||||
|
public class ItemType extends Type<Item> {
|
||||||
|
private final boolean compressed;
|
||||||
|
|
||||||
|
public ItemType(boolean compressed) {
|
||||||
|
super(Item.class);
|
||||||
|
this.compressed = compressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Item read(ByteBuf buffer) throws Exception {
|
||||||
|
int readerIndex = buffer.readerIndex();
|
||||||
|
short id = buffer.readShort();
|
||||||
|
if (id < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Item item = new DataItem();
|
||||||
|
item.setIdentifier(id);
|
||||||
|
item.setAmount(buffer.readByte());
|
||||||
|
item.setData(buffer.readShort());
|
||||||
|
item.setTag((compressed ? Types1_7_6_10.COMPRESSED_NBT : Types1_7_6_10.NBT).read(buffer));
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(ByteBuf buffer, Item item) throws Exception {
|
||||||
|
if (item == null) {
|
||||||
|
buffer.writeShort(-1);
|
||||||
|
} else {
|
||||||
|
buffer.writeShort(item.identifier());
|
||||||
|
buffer.writeByte(item.amount());
|
||||||
|
buffer.writeShort(item.data());
|
||||||
|
(compressed ? Types1_7_6_10.COMPRESSED_NBT : Types1_7_6_10.NBT).write(buffer, item.tag());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.MetaType;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
|
||||||
|
public enum MetaType1_7_6_10 implements MetaType {
|
||||||
|
Byte(0, Type.BYTE),
|
||||||
|
Short(1, Type.SHORT),
|
||||||
|
Int(2, Type.INT),
|
||||||
|
Float(3, Type.FLOAT),
|
||||||
|
String(4, Type.STRING),
|
||||||
|
Slot(5, Types1_7_6_10.COMPRESSED_NBT_ITEM),
|
||||||
|
Position(6, Type.VECTOR),
|
||||||
|
NonExistent(-1, Type.NOTHING);
|
||||||
|
|
||||||
|
private final int typeID;
|
||||||
|
private final Type type;
|
||||||
|
|
||||||
|
public static MetaType1_7_6_10 byId(int id) {
|
||||||
|
return values()[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaType1_7_6_10(int typeID, Type type) {
|
||||||
|
this.typeID = typeID;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int typeId() {
|
||||||
|
return this.typeID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type type() {
|
||||||
|
return this.type;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.Metadata;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.types.minecraft.MetaListTypeTemplate;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MetadataListType extends MetaListTypeTemplate {
|
||||||
|
private MetadataType metadataType = new MetadataType();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Metadata> read(ByteBuf buffer) throws Exception {
|
||||||
|
ArrayList<Metadata> list = new ArrayList<>();
|
||||||
|
|
||||||
|
Metadata m;
|
||||||
|
do {
|
||||||
|
m = Types1_7_6_10.METADATA.read(buffer);
|
||||||
|
if (m != null) {
|
||||||
|
list.add(m);
|
||||||
|
}
|
||||||
|
} while(m != null);
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(ByteBuf buffer, List<Metadata> metadata) throws Exception {
|
||||||
|
for (Metadata meta : metadata) {
|
||||||
|
Types1_7_6_10.METADATA.write(buffer, meta);
|
||||||
|
}
|
||||||
|
if (metadata.isEmpty()) {
|
||||||
|
Types1_7_6_10.METADATA.write(buffer, new Metadata(0, MetaType1_7_6_10.Byte, (byte)0));
|
||||||
|
}
|
||||||
|
buffer.writeByte(127);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.Metadata;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.types.minecraft.MetaTypeTemplate;
|
||||||
|
|
||||||
|
public class MetadataType extends MetaTypeTemplate {
|
||||||
|
@Override
|
||||||
|
public Metadata read(ByteBuf buffer) throws Exception {
|
||||||
|
byte item = buffer.readByte();
|
||||||
|
if (item == 127) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
int typeID = (item & 224) >> 5;
|
||||||
|
MetaType1_7_6_10 type = MetaType1_7_6_10.byId(typeID);
|
||||||
|
int id = item & 31;
|
||||||
|
return new Metadata(id, type, type.type().read(buffer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(ByteBuf buffer, Metadata meta) throws Exception {
|
||||||
|
int item = (meta.metaType().typeId() << 5 | meta.id() & 31) & 255;
|
||||||
|
buffer.writeByte(item);
|
||||||
|
meta.metaType().type().write(buffer, meta.getValue());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types;
|
||||||
|
|
||||||
|
import com.github.steveice10.opennbt.NBTIO;
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.ByteBufInputStream;
|
||||||
|
import io.netty.buffer.ByteBufOutputStream;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
public class NBTType extends Type<CompoundTag> {
|
||||||
|
public NBTType() {
|
||||||
|
super(CompoundTag.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompoundTag read(ByteBuf buffer) {
|
||||||
|
short length = buffer.readShort();
|
||||||
|
if (length < 0) {return null;}
|
||||||
|
ByteBufInputStream byteBufInputStream = new ByteBufInputStream(buffer);
|
||||||
|
DataInputStream dataInputStream = new DataInputStream(byteBufInputStream);
|
||||||
|
try {
|
||||||
|
return (CompoundTag) NBTIO.readTag((DataInput) dataInputStream);
|
||||||
|
} catch (Throwable throwable) {throwable.printStackTrace();}
|
||||||
|
finally {
|
||||||
|
try {
|
||||||
|
dataInputStream.close();
|
||||||
|
} catch (IOException e) {e.printStackTrace();}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(ByteBuf buffer, CompoundTag nbt) throws Exception {
|
||||||
|
if (nbt == null) {
|
||||||
|
buffer.writeShort(-1);
|
||||||
|
} else {
|
||||||
|
ByteBuf buf = buffer.alloc().buffer();
|
||||||
|
ByteBufOutputStream bytebufStream = new ByteBufOutputStream(buf);
|
||||||
|
DataOutputStream dataOutputStream = new DataOutputStream(bytebufStream);
|
||||||
|
NBTIO.writeTag((DataOutput) dataOutputStream, nbt);
|
||||||
|
dataOutputStream.close();
|
||||||
|
buffer.writeShort(buf.readableBytes());
|
||||||
|
buffer.writeBytes(buf);
|
||||||
|
buf.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public enum Particle {
|
||||||
|
EXPLOSION_NORMAL("explode"),
|
||||||
|
EXPLOSION_LARGE("largeexplode"),
|
||||||
|
EXPLOSION_HUGE("hugeexplosion"),
|
||||||
|
FIREWORKS_SPARK("fireworksSpark"),
|
||||||
|
WATER_BUBBLE("bubble"),
|
||||||
|
WATER_SPLASH("splash"),
|
||||||
|
WATER_WAKE("wake"),
|
||||||
|
SUSPENDED("suspended"),
|
||||||
|
SUSPENDED_DEPTH("depthsuspend"),
|
||||||
|
CRIT("crit"),
|
||||||
|
CRIT_MAGIC("magicCrit"),
|
||||||
|
SMOKE_NORMAL("smoke"),
|
||||||
|
SMOKE_LARGE("largesmoke"),
|
||||||
|
SPELL("spell"),
|
||||||
|
SPELL_INSTANT("instantSpell"),
|
||||||
|
SPELL_MOB("mobSpell"),
|
||||||
|
SPELL_MOB_AMBIENT("mobSpellAmbient"),
|
||||||
|
SPELL_WITCH("witchMagic"),
|
||||||
|
DRIP_WATER("dripWater"),
|
||||||
|
DRIP_LAVA("dripLava"),
|
||||||
|
VILLAGER_ANGRY("angryVillager"),
|
||||||
|
VILLAGER_HAPPY("happyVillager"),
|
||||||
|
TOWN_AURA("townaura"),
|
||||||
|
NOTE("note"),
|
||||||
|
PORTAL("portal"),
|
||||||
|
ENCHANTMENT_TABLE("enchantmenttable"),
|
||||||
|
FLAME("flame"),
|
||||||
|
LAVA("lava"),
|
||||||
|
FOOTSTEP("footstep"),
|
||||||
|
CLOUD("cloud"),
|
||||||
|
REDSTONE("reddust"),
|
||||||
|
SNOWBALL("snowballpoof"),
|
||||||
|
SNOW_SHOVEL("snowshovel"),
|
||||||
|
SLIME("slime"),
|
||||||
|
HEART("heart"),
|
||||||
|
BARRIER("barrier"),
|
||||||
|
ICON_CRACK("iconcrack", 2),
|
||||||
|
BLOCK_CRACK("blockcrack", 1),
|
||||||
|
BLOCK_DUST("blockdust", 1),
|
||||||
|
WATER_DROP("droplet"),
|
||||||
|
ITEM_TAKE("take"),
|
||||||
|
MOB_APPEARANCE("mobappearance");
|
||||||
|
|
||||||
|
public final String name;
|
||||||
|
public final int extra;
|
||||||
|
private static final HashMap<String, Particle> particleMap = new HashMap();
|
||||||
|
|
||||||
|
Particle(String name) {
|
||||||
|
this(name, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Particle(String name, int extra) {
|
||||||
|
this.name = name;
|
||||||
|
this.extra = extra;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Particle find(String part) {
|
||||||
|
return particleMap.get(part);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Particle find(int id) {
|
||||||
|
if (id<0) return null;
|
||||||
|
Particle[] values = Particle.values();
|
||||||
|
return id>=values.length ? null : values[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
Particle[] particles = values();
|
||||||
|
|
||||||
|
for (Particle particle : particles) {
|
||||||
|
particleMap.put(particle.name, particle);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types;
|
||||||
|
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.item.Item;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.Metadata;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Types1_7_6_10 {
|
||||||
|
public static final Type<CompoundTag> COMPRESSED_NBT = new CompressedNBTType();
|
||||||
|
public static final Type<Item[]> ITEM_ARRAY = new ItemArrayType(false);
|
||||||
|
public static final Type<Item[]> COMPRESSED_NBT_ITEM_ARRAY = new ItemArrayType(true);
|
||||||
|
public static final Type<Item> ITEM = new ItemType(false);
|
||||||
|
public static final Type<Item> COMPRESSED_NBT_ITEM = new ItemType(true);
|
||||||
|
public static final Type<List<Metadata>> METADATA_LIST = new MetadataListType();
|
||||||
|
public static final Type<Metadata> METADATA = new MetadataType();
|
||||||
|
public static final Type<CompoundTag> NBT = new NBTType();
|
||||||
|
public static final Type<int[]> INT_ARRAY = new IntArrayType();
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_7_6to1_7_2;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.ClientboundPackets1_7;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.ServerboundPackets1_7;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.AbstractProtocol;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.State;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.remapper.PacketRemapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.remapper.ValueTransformer;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
|
||||||
|
public class Protocol1_7_6to1_7_2 extends AbstractProtocol<ClientboundPackets1_7, ClientboundPackets1_7, ServerboundPackets1_7, ServerboundPackets1_7> {
|
||||||
|
public static ValueTransformer<String, String> INSERT_DASHES = new ValueTransformer<String, String>(Type.STRING) {
|
||||||
|
@Override
|
||||||
|
public String transform(PacketWrapper wrapper, String inputValue) throws Exception {
|
||||||
|
StringBuilder builder = new StringBuilder(inputValue);
|
||||||
|
builder.insert(20, "-");
|
||||||
|
builder.insert(16, "-");
|
||||||
|
builder.insert(12, "-");
|
||||||
|
builder.insert(8, "-");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public Protocol1_7_6to1_7_2() {
|
||||||
|
super(ClientboundPackets1_7.class, ClientboundPackets1_7.class, ServerboundPackets1_7.class, ServerboundPackets1_7.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void registerPackets() {
|
||||||
|
//Login Success
|
||||||
|
this.registerClientbound(State.LOGIN, 0x02, 0x02, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.STRING, INSERT_DASHES);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Spawn Player
|
||||||
|
this.registerClientbound(ClientboundPackets1_7.SPAWN_PLAYER, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.STRING, INSERT_DASHES);
|
||||||
|
map(Type.STRING);
|
||||||
|
create(Type.VAR_INT, 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,166 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_7_6_10.metadata;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_7_6_10to1_8.types.MetaType1_7_6_10;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.entities.Entity1_10Types;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.types.MetaType1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.util.Pair;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public enum MetaIndex1_8to1_7_6_10 {
|
||||||
|
|
||||||
|
ENTITY_FLAGS(Entity1_10Types.EntityType.ENTITY, 0, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
ENTITY_AIR(Entity1_10Types.EntityType.ENTITY, 1, MetaType1_7_6_10.Short, MetaType1_8.Short),
|
||||||
|
ENTITY_NAME_TAG(Entity1_10Types.EntityType.ENTITY, -1, MetaType1_7_6_10.NonExistent, 2, MetaType1_8.String),
|
||||||
|
ENTITY_NAME_TAG_VISIBILITY(Entity1_10Types.EntityType.ENTITY, -1, MetaType1_7_6_10.NonExistent, 3, MetaType1_8.Byte),
|
||||||
|
ENTITY_SILENT(Entity1_10Types.EntityType.ENTITY, -1, MetaType1_7_6_10.NonExistent, 4, MetaType1_8.Byte),
|
||||||
|
ENTITY_LIVING_HEALTH(Entity1_10Types.EntityType.ENTITY_LIVING, 6, MetaType1_7_6_10.Float, MetaType1_8.Float),
|
||||||
|
ENTITY_LIVING_POTION_EFFECT_COLOR(Entity1_10Types.EntityType.ENTITY_LIVING, 7, MetaType1_7_6_10.Int, MetaType1_8.Int),
|
||||||
|
ENTITY_LIVING_IS_POTION_EFFECT_AMBIENT(Entity1_10Types.EntityType.ENTITY_LIVING, 8, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
ENTITY_LIVING_ARROWS(Entity1_10Types.EntityType.ENTITY_LIVING, 9, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
ENTITY_LIVING_NAME_TAG(Entity1_10Types.EntityType.ENTITY_LIVING, 10, MetaType1_7_6_10.String, 2, MetaType1_8.String),
|
||||||
|
ENTITY_LIVING_NAME_TAG_VISIBILITY(Entity1_10Types.EntityType.ENTITY_LIVING, 11, MetaType1_7_6_10.Byte, 3, MetaType1_8.Byte),
|
||||||
|
ENTITY_LIVING_AI(Entity1_10Types.EntityType.ENTITY_LIVING, -1, MetaType1_7_6_10.NonExistent, 15, MetaType1_8.Byte),
|
||||||
|
ENTITY_AGEABLE_AGE(Entity1_10Types.EntityType.ENTITY_AGEABLE, 12, MetaType1_7_6_10.Int, MetaType1_8.Byte),
|
||||||
|
ARMOR_STAND_FLAGS(Entity1_10Types.EntityType.ARMOR_STAND, -1, MetaType1_7_6_10.NonExistent, 10, MetaType1_8.Byte),
|
||||||
|
ARMOR_STAND_HEAD_POSITION(Entity1_10Types.EntityType.ARMOR_STAND, -1, MetaType1_7_6_10.NonExistent, 11, MetaType1_8.Rotation),
|
||||||
|
ARMOR_STAND_BODY_POSITION(Entity1_10Types.EntityType.ARMOR_STAND, -1, MetaType1_7_6_10.NonExistent, 12, MetaType1_8.Rotation),
|
||||||
|
ARMOR_STAND_LEFT_ARM_POSITION(Entity1_10Types.EntityType.ARMOR_STAND, -1, MetaType1_7_6_10.NonExistent, 13, MetaType1_8.Rotation),
|
||||||
|
ARMOR_STAND_RIGHT_ARM_POSITION(Entity1_10Types.EntityType.ARMOR_STAND, -1, MetaType1_7_6_10.NonExistent, 14, MetaType1_8.Rotation),
|
||||||
|
ARMOR_STAND_LEFT_LEG_POSITION(Entity1_10Types.EntityType.ARMOR_STAND, -1, MetaType1_7_6_10.NonExistent, 15, MetaType1_8.Rotation),
|
||||||
|
ARMOR_STAND_RIGHT_LEG_POSITION(Entity1_10Types.EntityType.ARMOR_STAND, -1, MetaType1_7_6_10.NonExistent, 16, MetaType1_8.Rotation),
|
||||||
|
HUMAN_SKIN_FLAGS(Entity1_10Types.EntityType.ENTITY_HUMAN, 16, MetaType1_7_6_10.Byte, 10, MetaType1_8.Byte),
|
||||||
|
HUMAN_UNUSED(Entity1_10Types.EntityType.ENTITY_HUMAN, -1, MetaType1_7_6_10.NonExistent, 16, MetaType1_8.Byte),
|
||||||
|
HUMAN_ABSORPTION_HEATS(Entity1_10Types.EntityType.ENTITY_HUMAN, 17, MetaType1_7_6_10.Float, MetaType1_8.Float),
|
||||||
|
HUMAN_SCORE(Entity1_10Types.EntityType.ENTITY_HUMAN, 18, MetaType1_7_6_10.Int, MetaType1_8.Int),
|
||||||
|
HORSE_FLAGS(Entity1_10Types.EntityType.HORSE, 16, MetaType1_7_6_10.Int, MetaType1_8.Int),
|
||||||
|
HORSE_TYPE(Entity1_10Types.EntityType.HORSE, 19, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
HORSE_COLOR(Entity1_10Types.EntityType.HORSE, 20, MetaType1_7_6_10.Int, MetaType1_8.Int),
|
||||||
|
HORSE_OWNER(Entity1_10Types.EntityType.HORSE, 21, MetaType1_7_6_10.String, MetaType1_8.String),
|
||||||
|
HORSE_ARMOR(Entity1_10Types.EntityType.HORSE, 22, MetaType1_7_6_10.Int, MetaType1_8.Int),
|
||||||
|
BAT_HANGING(Entity1_10Types.EntityType.BAT, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
TAMEABLE_FLAGS(Entity1_10Types.EntityType.ENTITY_TAMEABLE_ANIMAL, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
TAMEABLE_OWNER(Entity1_10Types.EntityType.ENTITY_TAMEABLE_ANIMAL, 17, MetaType1_7_6_10.String, MetaType1_8.String),
|
||||||
|
OCELOT_TYPE(Entity1_10Types.EntityType.OCELOT, 18, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
WOLF_FLAGS(Entity1_10Types.EntityType.WOLF, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
WOLF_HEALTH(Entity1_10Types.EntityType.WOLF, 18, MetaType1_7_6_10.Float, MetaType1_8.Float),
|
||||||
|
WOLF_BEGGING(Entity1_10Types.EntityType.WOLF, 19, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
WOLF_COLLAR_COLOR(Entity1_10Types.EntityType.WOLF, 20, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
PIG_SADDLE(Entity1_10Types.EntityType.PIG, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
SHEEP_COLOR_OR_SHEARED(Entity1_10Types.EntityType.SHEEP, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
VILLAGER_TYPE(Entity1_10Types.EntityType.VILLAGER, 16, MetaType1_7_6_10.Int, MetaType1_8.Int),
|
||||||
|
ENDERMAN_CARRIED_BLOCK(Entity1_10Types.EntityType.ENDERMAN, 16, MetaType1_7_6_10.NonExistent, MetaType1_8.Short),
|
||||||
|
ENDERMAN_CARRIED_BLOCK_DATA(Entity1_10Types.EntityType.ENDERMAN, 17, MetaType1_7_6_10.NonExistent, MetaType1_8.Byte),
|
||||||
|
ENDERMAN_IS_SCREAMING(Entity1_10Types.EntityType.ENDERMAN, 18, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
ZOMBIE_CHILD(Entity1_10Types.EntityType.ZOMBIE, 12, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
ZOMBIE_VILLAGER(Entity1_10Types.EntityType.ZOMBIE, 13, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
ZOMBIE_CONVERTING(Entity1_10Types.EntityType.ZOMBIE, 14, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
BLAZE_ON_FIRE(Entity1_10Types.EntityType.BLAZE, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
SPIDER_CLIMBING(Entity1_10Types.EntityType.SPIDER, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
CREEPER_STATE(Entity1_10Types.EntityType.CREEPER, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
CREEPER_POWERED(Entity1_10Types.EntityType.CREEPER, 17, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
GHAST_STATE(Entity1_10Types.EntityType.GHAST, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
GHAST_IS_POWERED(Entity1_10Types.EntityType.GHAST, 17, MetaType1_7_6_10.NonExistent, MetaType1_8.Byte),
|
||||||
|
SLIME_SIZE(Entity1_10Types.EntityType.SLIME, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
SKELETON_TYPE(Entity1_10Types.EntityType.SKELETON, 13, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
WITCH_AGRESSIVE(Entity1_10Types.EntityType.WITCH, 21, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
IRON_GOLEM_IS_PLAYER_CREATED(Entity1_10Types.EntityType.IRON_GOLEM, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
WITHER_WATCHED_TAGRET_1(Entity1_10Types.EntityType.WITHER, 17, MetaType1_7_6_10.Int, MetaType1_8.Int),
|
||||||
|
WITHER_WATCHED_TAGRET_2(Entity1_10Types.EntityType.WITHER, 18, MetaType1_7_6_10.Int, MetaType1_8.Int),
|
||||||
|
WITHER_WATCHED_TAGRET_3(Entity1_10Types.EntityType.WITHER, 19, MetaType1_7_6_10.Int, MetaType1_8.Int),
|
||||||
|
WITHER_INVULNERABLE_TIME(Entity1_10Types.EntityType.WITHER, 20, MetaType1_7_6_10.Int, MetaType1_8.Int),
|
||||||
|
GUARDIAN_FLAGS(Entity1_10Types.EntityType.GUARDIAN, 16, MetaType1_7_6_10.NonExistent, MetaType1_8.Byte),
|
||||||
|
GUARDIAN_TARGET(Entity1_10Types.EntityType.GUARDIAN, 17, MetaType1_7_6_10.NonExistent, MetaType1_8.Int),
|
||||||
|
BOAT_TIME_SINCE_HIT(Entity1_10Types.EntityType.BOAT, 17, MetaType1_7_6_10.Int, MetaType1_8.Int),
|
||||||
|
BOAT_FORWARD_DIRECTION(Entity1_10Types.EntityType.BOAT, 18, MetaType1_7_6_10.Int, MetaType1_8.Int),
|
||||||
|
BOAT_DAMAGE_TAKEN(Entity1_10Types.EntityType.BOAT, 19, MetaType1_7_6_10.Float, MetaType1_8.Float),
|
||||||
|
MINECART_SHAKING_POWER(Entity1_10Types.EntityType.MINECART_ABSTRACT, 17, MetaType1_7_6_10.Int, MetaType1_8.Int),
|
||||||
|
MINECART_SHAKING_DIRECTION(Entity1_10Types.EntityType.MINECART_ABSTRACT, 18, MetaType1_7_6_10.Int, MetaType1_8.Int),
|
||||||
|
MINECART_DAMAGE_TAKEN(Entity1_10Types.EntityType.MINECART_ABSTRACT, 19, MetaType1_7_6_10.Float, MetaType1_8.Float),
|
||||||
|
MINECART_BLOCK_INSIDE(Entity1_10Types.EntityType.MINECART_ABSTRACT, 20, MetaType1_7_6_10.Int, MetaType1_8.Int),
|
||||||
|
MINECART_BLOCK_Y(Entity1_10Types.EntityType.MINECART_ABSTRACT, 21, MetaType1_7_6_10.Int, MetaType1_8.Int),
|
||||||
|
MINECART_SHOW_BLOCK(Entity1_10Types.EntityType.MINECART_ABSTRACT, 22, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
FURNACE_MINECART_IS_POWERED(Entity1_10Types.EntityType.MINECART_FURNACE, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
ITEM_ITEM(Entity1_10Types.EntityType.DROPPED_ITEM, 10, MetaType1_7_6_10.Slot, MetaType1_8.Slot),
|
||||||
|
ARROW_IS_CRITICAL(Entity1_10Types.EntityType.ARROW, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
|
||||||
|
FIREWORK_INFO(Entity1_10Types.EntityType.FIREWORK, 8, MetaType1_7_6_10.Slot, MetaType1_8.Slot),
|
||||||
|
ITEM_FRAME_ITEM(Entity1_10Types.EntityType.ITEM_FRAME, 2, MetaType1_7_6_10.Slot, 8, MetaType1_8.Slot),
|
||||||
|
ITEM_FRAME_ROTATION(Entity1_10Types.EntityType.ITEM_FRAME, 3, MetaType1_7_6_10.Byte, 9, MetaType1_8.Byte),
|
||||||
|
ENDER_CRYSTAL_HEALTH(Entity1_10Types.EntityType.ENDER_CRYSTAL, 8, MetaType1_7_6_10.Int, 9, MetaType1_8.Int),
|
||||||
|
;
|
||||||
|
|
||||||
|
private static final HashMap<Pair<Entity1_10Types.EntityType, Integer>, MetaIndex1_8to1_7_6_10> metadataRewrites = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
for (MetaIndex1_8to1_7_6_10 index : MetaIndex1_8to1_7_6_10.values())
|
||||||
|
metadataRewrites.put(new Pair<>(index.getClazz(), index.getIndex()), index);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Entity1_10Types.EntityType clazz;
|
||||||
|
private int newIndex;
|
||||||
|
private MetaType1_8 newType;
|
||||||
|
private MetaType1_7_6_10 oldType;
|
||||||
|
private int index;
|
||||||
|
|
||||||
|
MetaIndex1_8to1_7_6_10(Entity1_10Types.EntityType type, int index, MetaType1_7_6_10 oldType, MetaType1_8 newType) {
|
||||||
|
this.clazz = type;
|
||||||
|
this.index = index;
|
||||||
|
this.newIndex = index;
|
||||||
|
this.oldType = oldType;
|
||||||
|
this.newType = newType;
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaIndex1_8to1_7_6_10(Entity1_10Types.EntityType type, int index, MetaType1_7_6_10 oldType, int newIndex, MetaType1_8 newType) {
|
||||||
|
this.clazz = type;
|
||||||
|
this.index = index;
|
||||||
|
this.oldType = oldType;
|
||||||
|
this.newIndex = newIndex;
|
||||||
|
this.newType = newType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Optional<MetaIndex1_8to1_7_6_10> getIndex(Entity1_10Types.EntityType type, int index) {
|
||||||
|
Pair pair = new Pair<>(type, index);
|
||||||
|
if (metadataRewrites.containsKey(pair)) {
|
||||||
|
return Optional.of(metadataRewrites.get(pair));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Entity1_10Types.EntityType getClazz() {
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNewIndex() {
|
||||||
|
return newIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MetaType1_8 getNewType() {
|
||||||
|
return newType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MetaType1_7_6_10 getOldType() {
|
||||||
|
return oldType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MetaIndex1_8to1_7_6_10 searchIndex(Entity1_10Types.EntityType type, int index) {
|
||||||
|
Entity1_10Types.EntityType currentType = type;
|
||||||
|
do {
|
||||||
|
Optional<MetaIndex1_8to1_7_6_10> optMeta = getIndex(currentType, index);
|
||||||
|
|
||||||
|
if (optMeta.isPresent()) {
|
||||||
|
return optMeta.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
currentType = currentType.getParent();
|
||||||
|
} while (currentType != null);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.packets.*;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.storage.*;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.Ticker;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.AbstractProtocol;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.remapper.ValueTransformer;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_8.ServerboundPackets1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9to1_8.ServerboundPackets1_9;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Timer;
|
||||||
|
|
||||||
|
public class Protocol1_8TO1_9 extends AbstractProtocol<ClientboundPackets1_9, ClientboundPackets1_8,
|
||||||
|
ServerboundPackets1_9, ServerboundPackets1_8> {
|
||||||
|
public static final Timer TIMER = new Timer("ViaRewind-1_8TO1_9", true);
|
||||||
|
public static final Set<String> VALID_ATTRIBUTES = new HashSet<>();
|
||||||
|
public static final ValueTransformer<Double, Integer> TO_OLD_INT = new ValueTransformer<Double, Integer>(Type.INT) {
|
||||||
|
public Integer transform(PacketWrapper wrapper, Double inputValue) {
|
||||||
|
return (int) (inputValue * 32.0D);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
public static final ValueTransformer<Float, Byte> DEGREES_TO_ANGLE = new ValueTransformer<Float, Byte>(Type.BYTE) {
|
||||||
|
@Override
|
||||||
|
public Byte transform(PacketWrapper packetWrapper, Float degrees) throws Exception {
|
||||||
|
return (byte) ((degrees / 360F) * 256);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static {
|
||||||
|
VALID_ATTRIBUTES.add("generic.maxHealth");
|
||||||
|
VALID_ATTRIBUTES.add("generic.followRange");
|
||||||
|
VALID_ATTRIBUTES.add("generic.knockbackResistance");
|
||||||
|
VALID_ATTRIBUTES.add("generic.movementSpeed");
|
||||||
|
VALID_ATTRIBUTES.add("generic.attackDamage");
|
||||||
|
VALID_ATTRIBUTES.add("horse.jumpStrength");
|
||||||
|
VALID_ATTRIBUTES.add("zombie.spawnReinforcements");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Protocol1_8TO1_9() {
|
||||||
|
super(ClientboundPackets1_9.class, ClientboundPackets1_8.class, ServerboundPackets1_9.class, ServerboundPackets1_8.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void registerPackets() {
|
||||||
|
EntityPackets.register(this);
|
||||||
|
InventoryPackets.register(this);
|
||||||
|
PlayerPackets.register(this);
|
||||||
|
ScoreboardPackets.register(this);
|
||||||
|
SpawnPackets.register(this);
|
||||||
|
WorldPackets.register(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(UserConnection userConnection) {
|
||||||
|
Ticker.init();
|
||||||
|
|
||||||
|
userConnection.put(new Windows(userConnection));
|
||||||
|
userConnection.put(new EntityTracker(userConnection));
|
||||||
|
userConnection.put(new Levitation(userConnection));
|
||||||
|
userConnection.put(new PlayerPosition(userConnection));
|
||||||
|
userConnection.put(new Cooldown(userConnection));
|
||||||
|
userConnection.put(new BlockPlaceDestroyTracker(userConnection));
|
||||||
|
userConnection.put(new BossBarStorage(userConnection));
|
||||||
|
userConnection.put(new ClientWorld(userConnection));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,231 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.bossbar;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.Protocol1_8TO1_9;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.PacketUtil;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.legacy.bossbar.BossBar;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.legacy.bossbar.BossColor;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.legacy.bossbar.BossFlag;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.legacy.bossbar.BossStyle;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.Metadata;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.types.MetaType1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.types.version.Types1_8;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class WitherBossBar implements BossBar {
|
||||||
|
private static int highestId = Integer.MAX_VALUE-10000;
|
||||||
|
|
||||||
|
private final UUID uuid;
|
||||||
|
private String title;
|
||||||
|
private float health;
|
||||||
|
private boolean visible = false;
|
||||||
|
|
||||||
|
private UserConnection connection;
|
||||||
|
|
||||||
|
private final int entityId = highestId++;
|
||||||
|
private double locX, locY, locZ;
|
||||||
|
|
||||||
|
public WitherBossBar(UserConnection connection, UUID uuid, String title, float health) {
|
||||||
|
this.connection = connection;
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.title = title;
|
||||||
|
this.health = health;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BossBar setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
if (this.visible) updateMetadata();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getHealth() {
|
||||||
|
return health;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BossBar setHealth(float health) {
|
||||||
|
this.health = health;
|
||||||
|
if (this.health<=0) this.health = 0.0001f;
|
||||||
|
if (this.visible) updateMetadata();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BossColor getColor() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BossBar setColor(BossColor bossColor) {
|
||||||
|
throw new UnsupportedOperationException(this.getClass().getName() + " does not support color");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BossStyle getStyle() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BossBar setStyle(BossStyle bossStyle) {
|
||||||
|
throw new UnsupportedOperationException(this.getClass().getName() + " does not support styles");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BossBar addPlayer(UUID uuid) {
|
||||||
|
throw new UnsupportedOperationException(this.getClass().getName() + " is only for one UserConnection!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BossBar addConnection(UserConnection userConnection) {
|
||||||
|
throw new UnsupportedOperationException(this.getClass().getName() + " is only for one UserConnection!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BossBar removePlayer(UUID uuid) {
|
||||||
|
throw new UnsupportedOperationException(this.getClass().getName() + " is only for one UserConnection!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BossBar removeConnection(UserConnection userConnection) {
|
||||||
|
throw new UnsupportedOperationException(this.getClass().getName() + " is only for one UserConnection!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BossBar addFlag(BossFlag bossFlag) {
|
||||||
|
throw new UnsupportedOperationException(this.getClass().getName() + " does not support flags");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BossBar removeFlag(BossFlag bossFlag) {
|
||||||
|
throw new UnsupportedOperationException(this.getClass().getName() + " does not support flags");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasFlag(BossFlag bossFlag) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<UUID> getPlayers() {
|
||||||
|
return Collections.singleton(connection.getProtocolInfo().getUuid());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<UserConnection> getConnections() {
|
||||||
|
throw new UnsupportedOperationException(this.getClass().getName() + " is only for one UserConnection!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BossBar show() {
|
||||||
|
if (!this.visible) {
|
||||||
|
this.visible = true;
|
||||||
|
spawnWither();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BossBar hide() {
|
||||||
|
if (this.visible) {
|
||||||
|
this.visible = false;
|
||||||
|
despawnWither();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isVisible() {
|
||||||
|
return visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UUID getId() {
|
||||||
|
return this.uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocation(double x, double y, double z) {
|
||||||
|
locX = x;
|
||||||
|
locY = y;
|
||||||
|
locZ = z;
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void spawnWither() {
|
||||||
|
PacketWrapper packetWrapper = PacketWrapper.create(0x0F, null, this.connection);
|
||||||
|
packetWrapper.write(Type.VAR_INT, entityId);
|
||||||
|
packetWrapper.write(Type.UNSIGNED_BYTE, (short)64);
|
||||||
|
packetWrapper.write(Type.INT, (int) (locX * 32d));
|
||||||
|
packetWrapper.write(Type.INT, (int) (locY * 32d));
|
||||||
|
packetWrapper.write(Type.INT, (int) (locZ * 32d));
|
||||||
|
packetWrapper.write(Type.BYTE, (byte)0);
|
||||||
|
packetWrapper.write(Type.BYTE, (byte)0);
|
||||||
|
packetWrapper.write(Type.BYTE, (byte)0);
|
||||||
|
packetWrapper.write(Type.SHORT, (short)0);
|
||||||
|
packetWrapper.write(Type.SHORT, (short)0);
|
||||||
|
packetWrapper.write(Type.SHORT, (short)0);
|
||||||
|
|
||||||
|
List<Metadata> metadata = new ArrayList<>();
|
||||||
|
metadata.add(new Metadata(0, MetaType1_8.Byte, (byte) 0x20));
|
||||||
|
metadata.add(new Metadata(2, MetaType1_8.String, title));
|
||||||
|
metadata.add(new Metadata(3, MetaType1_8.Byte, (byte) 1));
|
||||||
|
metadata.add(new Metadata(6, MetaType1_8.Float, health * 300f));
|
||||||
|
|
||||||
|
packetWrapper.write(Types1_8.METADATA_LIST, metadata);
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(packetWrapper, Protocol1_8TO1_9.class, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateLocation() {
|
||||||
|
PacketWrapper packetWrapper = PacketWrapper.create(0x18, null, this.connection);
|
||||||
|
packetWrapper.write(Type.VAR_INT, entityId);
|
||||||
|
packetWrapper.write(Type.INT, (int) (locX * 32d));
|
||||||
|
packetWrapper.write(Type.INT, (int) (locY * 32d));
|
||||||
|
packetWrapper.write(Type.INT, (int) (locZ * 32d));
|
||||||
|
packetWrapper.write(Type.BYTE, (byte)0);
|
||||||
|
packetWrapper.write(Type.BYTE, (byte)0);
|
||||||
|
packetWrapper.write(Type.BOOLEAN, false);
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(packetWrapper, Protocol1_8TO1_9.class, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateMetadata() {
|
||||||
|
PacketWrapper packetWrapper = PacketWrapper.create(0x1C, null, this.connection);
|
||||||
|
packetWrapper.write(Type.VAR_INT, entityId);
|
||||||
|
|
||||||
|
List<Metadata> metadata = new ArrayList<>();
|
||||||
|
metadata.add(new Metadata(2, MetaType1_8.String, title));
|
||||||
|
metadata.add(new Metadata(6, MetaType1_8.Float, health * 300f));
|
||||||
|
|
||||||
|
packetWrapper.write(Types1_8.METADATA_LIST, metadata);
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(packetWrapper, Protocol1_8TO1_9.class, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void despawnWither() {
|
||||||
|
PacketWrapper packetWrapper = PacketWrapper.create(0x13, null, this.connection);
|
||||||
|
packetWrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, new int[] {entityId});
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(packetWrapper, Protocol1_8TO1_9.class, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlayerLocation(double posX, double posY, double posZ, float yaw, float pitch) {
|
||||||
|
double yawR = Math.toRadians(yaw);
|
||||||
|
double pitchR = Math.toRadians(pitch);
|
||||||
|
|
||||||
|
posX -= Math.cos(pitchR) * Math.sin(yawR) * 48;
|
||||||
|
posY -= Math.sin(pitchR) * 48;
|
||||||
|
posZ += Math.cos(pitchR) * Math.cos(yawR) * 48;
|
||||||
|
|
||||||
|
setLocation(posX, posY, posZ);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,104 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.entityreplacement;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.Protocol1_8TO1_9;
|
||||||
|
import com.elevatemc.spigot.viarewind.replacement.EntityReplacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.PacketUtil;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.Metadata;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ShulkerBulletReplacement implements EntityReplacement {
|
||||||
|
private int entityId;
|
||||||
|
private List<Metadata> datawatcher = new ArrayList<>();
|
||||||
|
private double locX, locY, locZ;
|
||||||
|
private float yaw, pitch;
|
||||||
|
private float headYaw;
|
||||||
|
private UserConnection user;
|
||||||
|
|
||||||
|
public ShulkerBulletReplacement(int entityId, UserConnection user) {
|
||||||
|
this.entityId = entityId;
|
||||||
|
this.user = user;
|
||||||
|
spawn();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocation(double x, double y, double z) {
|
||||||
|
if (x!=this.locX || y!=this.locY || z!=this.locZ) {
|
||||||
|
this.locX = x;
|
||||||
|
this.locY = y;
|
||||||
|
this.locZ = z;
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void relMove(double x, double y, double z) {
|
||||||
|
if (x==0.0 && y==0.0 && z==0.0) return;
|
||||||
|
this.locX += x;
|
||||||
|
this.locY += y;
|
||||||
|
this.locZ += z;
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYawPitch(float yaw, float pitch) {
|
||||||
|
if (this.yaw!=yaw && this.pitch!=pitch) {
|
||||||
|
this.yaw = yaw;
|
||||||
|
this.pitch = pitch;
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeadYaw(float yaw) {
|
||||||
|
this.headYaw = yaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateMetadata(List<Metadata> metadataList) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateLocation() {
|
||||||
|
PacketWrapper teleport = PacketWrapper.create(0x18, null, user);
|
||||||
|
teleport.write(Type.VAR_INT, entityId);
|
||||||
|
teleport.write(Type.INT, (int) (locX * 32.0));
|
||||||
|
teleport.write(Type.INT, (int) (locY * 32.0));
|
||||||
|
teleport.write(Type.INT, (int) (locZ * 32.0));
|
||||||
|
teleport.write(Type.BYTE, (byte) ((yaw / 360f) * 256));
|
||||||
|
teleport.write(Type.BYTE, (byte) ((pitch / 360f) * 256));
|
||||||
|
teleport.write(Type.BOOLEAN, true);
|
||||||
|
|
||||||
|
PacketWrapper head = PacketWrapper.create(0x19, null, user);
|
||||||
|
head.write(Type.VAR_INT, entityId);
|
||||||
|
head.write(Type.BYTE, (byte)((headYaw / 360f) * 256));
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(teleport, Protocol1_8TO1_9.class, true, true);
|
||||||
|
PacketUtil.sendPacket(head, Protocol1_8TO1_9.class, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void spawn() {
|
||||||
|
PacketWrapper spawn = PacketWrapper.create(0x0E, null, user);
|
||||||
|
spawn.write(Type.VAR_INT, entityId);
|
||||||
|
spawn.write(Type.BYTE, (byte) 66);
|
||||||
|
spawn.write(Type.INT, 0);
|
||||||
|
spawn.write(Type.INT, 0);
|
||||||
|
spawn.write(Type.INT, 0);
|
||||||
|
spawn.write(Type.BYTE, (byte) 0);
|
||||||
|
spawn.write(Type.BYTE, (byte) 0);
|
||||||
|
spawn.write(Type.INT, 0);
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(spawn, Protocol1_8TO1_9.class, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void despawn() {
|
||||||
|
PacketWrapper despawn = PacketWrapper.create(0x13, null, user);
|
||||||
|
despawn.write(Type.VAR_INT_ARRAY_PRIMITIVE, new int[] {entityId});
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(despawn, Protocol1_8TO1_9.class, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEntityId() {
|
||||||
|
return this.entityId;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,119 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.entityreplacement;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.Protocol1_8TO1_9;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.metadata.MetadataRewriter;
|
||||||
|
import com.elevatemc.spigot.viarewind.replacement.EntityReplacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.PacketUtil;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.entities.Entity1_10Types;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.Metadata;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.types.MetaType1_9;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.types.version.Types1_8;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ShulkerReplacement implements EntityReplacement {
|
||||||
|
private int entityId;
|
||||||
|
private List<Metadata> datawatcher = new ArrayList<>();
|
||||||
|
private double locX, locY, locZ;
|
||||||
|
private UserConnection user;
|
||||||
|
|
||||||
|
public ShulkerReplacement(int entityId, UserConnection user) {
|
||||||
|
this.entityId = entityId;
|
||||||
|
this.user = user;
|
||||||
|
spawn();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocation(double x, double y, double z) {
|
||||||
|
this.locX = x;
|
||||||
|
this.locY = y;
|
||||||
|
this.locZ = z;
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void relMove(double x, double y, double z) {
|
||||||
|
this.locX += x;
|
||||||
|
this.locY += y;
|
||||||
|
this.locZ += z;
|
||||||
|
updateLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYawPitch(float yaw, float pitch) { }
|
||||||
|
|
||||||
|
public void setHeadYaw(float yaw) { }
|
||||||
|
|
||||||
|
public void updateMetadata(List<Metadata> metadataList) {
|
||||||
|
for (Metadata metadata : metadataList) {
|
||||||
|
datawatcher.removeIf(m -> m.id()==metadata.id());
|
||||||
|
datawatcher.add(metadata);
|
||||||
|
}
|
||||||
|
updateMetadata();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateLocation() {
|
||||||
|
PacketWrapper teleport = PacketWrapper.create(0x18, null, user);
|
||||||
|
teleport.write(Type.VAR_INT, entityId);
|
||||||
|
teleport.write(Type.INT, (int) (locX * 32.0));
|
||||||
|
teleport.write(Type.INT, (int) (locY * 32.0));
|
||||||
|
teleport.write(Type.INT, (int) (locZ * 32.0));
|
||||||
|
teleport.write(Type.BYTE, (byte) 0);
|
||||||
|
teleport.write(Type.BYTE, (byte) 0);
|
||||||
|
teleport.write(Type.BOOLEAN, true);
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(teleport, Protocol1_8TO1_9.class, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateMetadata() {
|
||||||
|
PacketWrapper metadataPacket = PacketWrapper.create(0x1C, null, user);
|
||||||
|
metadataPacket.write(Type.VAR_INT, entityId);
|
||||||
|
|
||||||
|
List<Metadata> metadataList = new ArrayList<>();
|
||||||
|
for (Metadata metadata : datawatcher) {
|
||||||
|
if (metadata.id()==11 || metadata.id()==12 || metadata.id()==13) continue;
|
||||||
|
metadataList.add(new Metadata(metadata.id(), metadata.metaType(), metadata.getValue()));
|
||||||
|
}
|
||||||
|
metadataList.add(new Metadata(11, MetaType1_9.VarInt, 2));
|
||||||
|
|
||||||
|
MetadataRewriter.transform(Entity1_10Types.EntityType.MAGMA_CUBE, metadataList);
|
||||||
|
|
||||||
|
metadataPacket.write(Types1_8.METADATA_LIST, metadataList);
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(metadataPacket, Protocol1_8TO1_9.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void spawn() {
|
||||||
|
PacketWrapper spawn = PacketWrapper.create(0x0F, null, user);
|
||||||
|
spawn.write(Type.VAR_INT, entityId);
|
||||||
|
spawn.write(Type.UNSIGNED_BYTE, (short) 62);
|
||||||
|
spawn.write(Type.INT, 0);
|
||||||
|
spawn.write(Type.INT, 0);
|
||||||
|
spawn.write(Type.INT, 0);
|
||||||
|
spawn.write(Type.BYTE, (byte) 0);
|
||||||
|
spawn.write(Type.BYTE, (byte) 0);
|
||||||
|
spawn.write(Type.BYTE, (byte) 0);
|
||||||
|
spawn.write(Type.SHORT, (short) 0);
|
||||||
|
spawn.write(Type.SHORT, (short) 0);
|
||||||
|
spawn.write(Type.SHORT, (short) 0);
|
||||||
|
List<Metadata> list = new ArrayList<>();
|
||||||
|
list.add(new Metadata(0, MetaType1_9.Byte, (byte) 0)); // Old clients don't like empty metadata
|
||||||
|
spawn.write(Types1_8.METADATA_LIST, list);
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(spawn, Protocol1_8TO1_9.class, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void despawn() {
|
||||||
|
PacketWrapper despawn = PacketWrapper.create(0x13, null, user);
|
||||||
|
despawn.write(Type.VAR_INT_ARRAY_PRIMITIVE, new int[] {entityId});
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(despawn, Protocol1_8TO1_9.class, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEntityId() {
|
||||||
|
return this.entityId;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,292 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.items;
|
||||||
|
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.*;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.Protocol1_8TO1_9;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.Enchantments;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.item.Item;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static com.elevatemc.spigot.viaversion.protocols.protocol1_9to1_8.ItemRewriter.potionNameFromDamage;
|
||||||
|
|
||||||
|
@SuppressWarnings({"MismatchedQueryAndUpdateOfCollection", "unused"})
|
||||||
|
public class ItemRewriter {
|
||||||
|
private static Map<String, Integer> ENTTIY_NAME_TO_ID;
|
||||||
|
private static Map<Integer, String> ENTTIY_ID_TO_NAME;
|
||||||
|
private static Map<String, Integer> POTION_NAME_TO_ID;
|
||||||
|
private static Map<Integer, String> POTION_ID_TO_NAME;
|
||||||
|
private static Map<String, String> POTION_NAME_INDEX = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
for (Field field : com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.items.ItemRewriter.class.getDeclaredFields()) {
|
||||||
|
try {
|
||||||
|
Field other = com.elevatemc.spigot.viaversion.protocols.protocol1_9to1_8.ItemRewriter.class.getDeclaredField(field.getName());
|
||||||
|
other.setAccessible(true);
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(null, other.get(null));
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
POTION_NAME_TO_ID.put("luck", 8203);
|
||||||
|
|
||||||
|
POTION_NAME_INDEX.put("water", "§rWater Bottle");
|
||||||
|
POTION_NAME_INDEX.put("mundane", "§rMundane Potion");
|
||||||
|
POTION_NAME_INDEX.put("thick", "§rThick Potion");
|
||||||
|
POTION_NAME_INDEX.put("awkward", "§rAwkward Potion");
|
||||||
|
POTION_NAME_INDEX.put("water_splash", "§rSplash Water Bottle");
|
||||||
|
POTION_NAME_INDEX.put("mundane_splash", "§rMundane Splash Potion");
|
||||||
|
POTION_NAME_INDEX.put("thick_splash", "§rThick Splash Potion");
|
||||||
|
POTION_NAME_INDEX.put("awkward_splash", "§rAwkward Splash Potion");
|
||||||
|
POTION_NAME_INDEX.put("water_lingering", "§rLingering Water Bottle");
|
||||||
|
POTION_NAME_INDEX.put("mundane_lingering", "§rMundane Lingering Potion");
|
||||||
|
POTION_NAME_INDEX.put("thick_lingering", "§rThick Lingering Potion");
|
||||||
|
POTION_NAME_INDEX.put("awkward_lingering", "§rAwkward Lingering Potion");
|
||||||
|
POTION_NAME_INDEX.put("night_vision_lingering", "§rLingering Potion of Night Vision");
|
||||||
|
POTION_NAME_INDEX.put("long_night_vision_lingering", "§rLingering Potion of Night Vision");
|
||||||
|
POTION_NAME_INDEX.put("invisibility_lingering", "§rLingering Potion of Invisibility");
|
||||||
|
POTION_NAME_INDEX.put("long_invisibility_lingering", "§rLingering Potion of Invisibility");
|
||||||
|
POTION_NAME_INDEX.put("leaping_lingering", "§rLingering Potion of Leaping");
|
||||||
|
POTION_NAME_INDEX.put("long_leaping_lingering", "§rLingering Potion of Leaping");
|
||||||
|
POTION_NAME_INDEX.put("strong_leaping_lingering", "§rLingering Potion of Leaping");
|
||||||
|
POTION_NAME_INDEX.put("fire_resistance_lingering", "§rLingering Potion of Fire Resistance");
|
||||||
|
POTION_NAME_INDEX.put("long_fire_resistance_lingering", "§rLingering Potion of Fire Resistance");
|
||||||
|
POTION_NAME_INDEX.put("swiftness_lingering", "§rLingering Potion of Swiftness");
|
||||||
|
POTION_NAME_INDEX.put("long_swiftness_lingering", "§rLingering Potion of Swiftness");
|
||||||
|
POTION_NAME_INDEX.put("strong_swiftness_lingering", "§rLingering Potion of Swiftness");
|
||||||
|
POTION_NAME_INDEX.put("slowness_lingering", "§rLingering Potion of Slowness");
|
||||||
|
POTION_NAME_INDEX.put("long_slowness_lingering", "§rLingering Potion of Slowness");
|
||||||
|
POTION_NAME_INDEX.put("water_breathing_lingering", "§rLingering Potion of Water Breathing");
|
||||||
|
POTION_NAME_INDEX.put("long_water_breathing_lingering", "§rLingering Potion of Water Breathing");
|
||||||
|
POTION_NAME_INDEX.put("healing_lingering", "§rLingering Potion of Healing");
|
||||||
|
POTION_NAME_INDEX.put("strong_healing_lingering", "§rLingering Potion of Healing");
|
||||||
|
POTION_NAME_INDEX.put("harming_lingering", "§rLingering Potion of Harming");
|
||||||
|
POTION_NAME_INDEX.put("strong_harming_lingering", "§rLingering Potion of Harming");
|
||||||
|
POTION_NAME_INDEX.put("poison_lingering", "§rLingering Potion of Poisen");
|
||||||
|
POTION_NAME_INDEX.put("long_poison_lingering", "§rLingering Potion of Poisen");
|
||||||
|
POTION_NAME_INDEX.put("strong_poison_lingering", "§rLingering Potion of Poisen");
|
||||||
|
POTION_NAME_INDEX.put("regeneration_lingering", "§rLingering Potion of Regeneration");
|
||||||
|
POTION_NAME_INDEX.put("long_regeneration_lingering", "§rLingering Potion of Regeneration");
|
||||||
|
POTION_NAME_INDEX.put("strong_regeneration_lingering", "§rLingering Potion of Regeneration");
|
||||||
|
POTION_NAME_INDEX.put("strength_lingering", "§rLingering Potion of Strength");
|
||||||
|
POTION_NAME_INDEX.put("long_strength_lingering", "§rLingering Potion of Strength");
|
||||||
|
POTION_NAME_INDEX.put("strong_strength_lingering", "§rLingering Potion of Strength");
|
||||||
|
POTION_NAME_INDEX.put("weakness_lingering", "§rLingering Potion of Weakness");
|
||||||
|
POTION_NAME_INDEX.put("long_weakness_lingering", "§rLingering Potion of Weakness");
|
||||||
|
POTION_NAME_INDEX.put("luck_lingering", "§rLingering Potion of Luck");
|
||||||
|
POTION_NAME_INDEX.put("luck", "§rPotion of Luck");
|
||||||
|
POTION_NAME_INDEX.put("luck_splash", "§rSplash Potion of Luck");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Item toClient(Item item) {
|
||||||
|
if (item==null) return null;
|
||||||
|
|
||||||
|
CompoundTag tag = item.tag();
|
||||||
|
if (tag==null) item.setTag(tag = new CompoundTag());
|
||||||
|
|
||||||
|
CompoundTag viaVersionTag = new CompoundTag();
|
||||||
|
tag.put("ViaRewind1_8to1_9", viaVersionTag);
|
||||||
|
|
||||||
|
viaVersionTag.put("id", new ShortTag((short) item.identifier()));
|
||||||
|
viaVersionTag.put("data", new ShortTag(item.data()));
|
||||||
|
|
||||||
|
CompoundTag display = tag.get("display");
|
||||||
|
if (display!=null && display.contains("Name")) {
|
||||||
|
viaVersionTag.put("displayName", new StringTag((String) display.get("Name").getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (display!=null && display.contains("Lore")) {
|
||||||
|
viaVersionTag.put("lore", new ListTag(((ListTag)display.get("Lore")).getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tag.contains("ench") || tag.contains("StoredEnchantments")) {
|
||||||
|
ListTag enchTag = tag.contains("ench") ? tag.get("ench") : tag.get("StoredEnchantments");
|
||||||
|
List<Tag> lore = new ArrayList<>();
|
||||||
|
for (Tag ench : new ArrayList<>(enchTag.getValue())) {
|
||||||
|
short id = ((NumberTag) ((CompoundTag)ench).get("id")).asShort();
|
||||||
|
short lvl = ((NumberTag) ((CompoundTag)ench).get("lvl")).asShort();
|
||||||
|
String s;
|
||||||
|
if (id==70) {
|
||||||
|
s = "§r§7Mending ";
|
||||||
|
} else if (id==9) {
|
||||||
|
s = "§r§7Frost Walker ";
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
enchTag.remove(ench);
|
||||||
|
s += Enchantments.ENCHANTMENTS.getOrDefault(lvl, "enchantment.level." + lvl);
|
||||||
|
lore.add(new StringTag(s));
|
||||||
|
}
|
||||||
|
if (!lore.isEmpty()) {
|
||||||
|
if (display==null) {
|
||||||
|
tag.put("display", display = new CompoundTag());
|
||||||
|
viaVersionTag.put("noDisplay", new ByteTag());
|
||||||
|
}
|
||||||
|
ListTag loreTag = display.get("Lore");
|
||||||
|
if (loreTag==null) display.put("Lore", loreTag = new ListTag(StringTag.class));
|
||||||
|
lore.addAll(loreTag.getValue());
|
||||||
|
loreTag.setValue(lore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.data()!=0 && tag.contains("Unbreakable")) {
|
||||||
|
ByteTag unbreakable = tag.get("Unbreakable");
|
||||||
|
if (unbreakable.asByte()!=0) {
|
||||||
|
viaVersionTag.put("Unbreakable", new ByteTag(unbreakable.asByte()));
|
||||||
|
tag.remove("Unbreakable");
|
||||||
|
|
||||||
|
if (display==null) {
|
||||||
|
tag.put("display", display = new CompoundTag());
|
||||||
|
viaVersionTag.put("noDisplay", new ByteTag());
|
||||||
|
}
|
||||||
|
ListTag loreTag = display.get("Lore");
|
||||||
|
if (loreTag==null) display.put("Lore", loreTag = new ListTag(StringTag.class));
|
||||||
|
loreTag.add(new StringTag("§9Unbreakable"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tag.contains("AttributeModifiers")) {
|
||||||
|
viaVersionTag.put("AttributeModifiers", tag.get("AttributeModifiers").clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.identifier()==383 && item.data()==0) {
|
||||||
|
int data = 0;
|
||||||
|
if (tag.contains("EntityTag")) {
|
||||||
|
CompoundTag entityTag = tag.get("EntityTag");
|
||||||
|
if (entityTag.contains("id")) {
|
||||||
|
StringTag id = entityTag.get("id");
|
||||||
|
if (ENTTIY_NAME_TO_ID.containsKey(id.getValue())) {
|
||||||
|
data = ENTTIY_NAME_TO_ID.get(id.getValue());
|
||||||
|
} else if (display==null) {
|
||||||
|
tag.put("display", display = new CompoundTag());
|
||||||
|
viaVersionTag.put("noDisplay", new ByteTag());
|
||||||
|
display.put("Name", new StringTag("§rSpawn " + id.getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item.setData((short)data);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReplacementRegistry1_8to1_9.replace(item);
|
||||||
|
|
||||||
|
if (item.identifier()==373 || item.identifier()==438 || item.identifier()==441) {
|
||||||
|
int data = 0;
|
||||||
|
if (tag.contains("Potion")) {
|
||||||
|
StringTag potion = tag.get("Potion");
|
||||||
|
String potionName = potion.getValue().replace("minecraft:", "");
|
||||||
|
if (POTION_NAME_TO_ID.containsKey(potionName)) {
|
||||||
|
data = POTION_NAME_TO_ID.get(potionName);
|
||||||
|
}
|
||||||
|
if (item.identifier()==438) potionName += "_splash";
|
||||||
|
else if (item.identifier()==441) potionName += "_lingering";
|
||||||
|
if ((display==null || !display.contains("Name")) && POTION_NAME_INDEX.containsKey(potionName)) {
|
||||||
|
if (display==null) {
|
||||||
|
tag.put("display", display = new CompoundTag());
|
||||||
|
viaVersionTag.put("noDisplay", new ByteTag());
|
||||||
|
}
|
||||||
|
display.put("Name", new StringTag(POTION_NAME_INDEX.get(potionName)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.identifier()==438 || item.identifier()==441) {
|
||||||
|
item.setIdentifier(373);
|
||||||
|
data += 8192;
|
||||||
|
}
|
||||||
|
|
||||||
|
item.setData((short)data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tag.contains("AttributeModifiers")) {
|
||||||
|
ListTag attributes = tag.get("AttributeModifiers");
|
||||||
|
for (int i = 0; i<attributes.size(); i++) {
|
||||||
|
CompoundTag attribute = attributes.get(i);
|
||||||
|
String name = (String) attribute.get("AttributeName").getValue();
|
||||||
|
if (!Protocol1_8TO1_9.VALID_ATTRIBUTES.contains(attribute)) {
|
||||||
|
attributes.remove(attribute);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (viaVersionTag.size()==2 && (short)viaVersionTag.get("id").getValue()==item.identifier() && (short)viaVersionTag.get("data").getValue()==item.data()) {
|
||||||
|
item.tag().remove("ViaRewind1_8to1_9");
|
||||||
|
if (item.tag().isEmpty()) item.setTag(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Item toServer(Item item) {
|
||||||
|
if (item==null) return null;
|
||||||
|
|
||||||
|
CompoundTag tag = item.tag();
|
||||||
|
|
||||||
|
if (item.identifier() == 383 && item.data() != 0) {
|
||||||
|
if (tag == null) item.setTag(tag = new CompoundTag());
|
||||||
|
if (!tag.contains("EntityTag") && ENTTIY_ID_TO_NAME.containsKey((int) item.data())) {
|
||||||
|
CompoundTag entityTag = new CompoundTag();
|
||||||
|
entityTag.put("id", new StringTag(ENTTIY_ID_TO_NAME.get((int) item.data())));
|
||||||
|
tag.put("EntityTag", entityTag);
|
||||||
|
}
|
||||||
|
|
||||||
|
item.setData((short) 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.identifier() == 373 && (tag==null || !tag.contains("Potion"))) {
|
||||||
|
if (tag == null) item.setTag(tag = new CompoundTag());
|
||||||
|
|
||||||
|
if (item.data() >= 16384) {
|
||||||
|
item.setIdentifier(438);
|
||||||
|
item.setData((short) (item.data() - 8192));
|
||||||
|
}
|
||||||
|
|
||||||
|
String name = item.data() == 8192 ? "water" : potionNameFromDamage(item.data());
|
||||||
|
tag.put("Potion", new StringTag("minecraft:" + name));
|
||||||
|
item.setData((short) 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tag==null || !item.tag().contains("ViaRewind1_8to1_9")) return item;
|
||||||
|
|
||||||
|
CompoundTag viaVersionTag = tag.remove("ViaRewind1_8to1_9");
|
||||||
|
|
||||||
|
item.setIdentifier((short) viaVersionTag.get("id").getValue());
|
||||||
|
item.setData((Short) viaVersionTag.get("data").getValue());
|
||||||
|
|
||||||
|
if (viaVersionTag.contains("noDisplay")) tag.remove("display");
|
||||||
|
|
||||||
|
if (viaVersionTag.contains("Unbreakable")) {
|
||||||
|
tag.put("Unbreakable", viaVersionTag.get("Unbreakable").clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (viaVersionTag.contains("displayName")) {
|
||||||
|
CompoundTag display = tag.get("display");
|
||||||
|
if (display==null) tag.put("display", display = new CompoundTag());
|
||||||
|
StringTag name = display.get("Name");
|
||||||
|
if (name==null) display.put("Name", new StringTag((String) viaVersionTag.get("displayName").getValue()));
|
||||||
|
else name.setValue((String) viaVersionTag.get("displayName").getValue());
|
||||||
|
} else if (tag.contains("display")) {
|
||||||
|
((CompoundTag)tag.get("display")).remove("Name");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (viaVersionTag.contains("lore")) {
|
||||||
|
CompoundTag display = tag.get("display");
|
||||||
|
if (display==null) tag.put("display", display = new CompoundTag());
|
||||||
|
ListTag lore = display.get("Lore");
|
||||||
|
if (lore==null) display.put("Lore", new ListTag((List<Tag>) viaVersionTag.get("lore").getValue()));
|
||||||
|
else lore.setValue((List<Tag>) viaVersionTag.get("lore").getValue());
|
||||||
|
} else if (tag.contains("display")) {
|
||||||
|
((CompoundTag)tag.get("display")).remove("Lore");
|
||||||
|
}
|
||||||
|
|
||||||
|
tag.remove("AttributeModifiers");
|
||||||
|
if (viaVersionTag.contains("AttributeModifiers")) {
|
||||||
|
tag.put("AttributeModifiers", viaVersionTag.get("AttributeModifiers"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.items;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.replacement.Replacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.replacement.ReplacementRegistry;
|
||||||
|
import com.elevatemc.spigot.viarewind.storage.BlockState;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.item.Item;
|
||||||
|
|
||||||
|
public class ReplacementRegistry1_8to1_9 {
|
||||||
|
private static final ReplacementRegistry registry = new ReplacementRegistry();
|
||||||
|
|
||||||
|
static {
|
||||||
|
registry.registerItem(198, new Replacement(50, 0, "End Rod"));
|
||||||
|
registry.registerItem(434, new Replacement(391, "Beetroot"));
|
||||||
|
registry.registerItem(435, new Replacement(361, "Beetroot Seeds"));
|
||||||
|
registry.registerItem(436, new Replacement(282, "Beetroot Soup"));
|
||||||
|
registry.registerItem(432, new Replacement(322, "Chorus Fruit"));
|
||||||
|
registry.registerItem(433, new Replacement(393, "Popped Chorus Fruit"));
|
||||||
|
registry.registerItem(437, new Replacement(373, "Dragons Breath"));
|
||||||
|
registry.registerItem(443, new Replacement(299, "Elytra"));
|
||||||
|
registry.registerItem(426, new Replacement(410, "End Crystal"));
|
||||||
|
registry.registerItem(442, new Replacement(425, "Shield"));
|
||||||
|
registry.registerItem(439, new Replacement(262, "Spectral Arrow"));
|
||||||
|
registry.registerItem(440, new Replacement(262, "Tipped Arrow"));
|
||||||
|
registry.registerItem(444, new Replacement(333, "Spruce Boat"));
|
||||||
|
registry.registerItem(445, new Replacement(333, "Birch Boat"));
|
||||||
|
registry.registerItem(446, new Replacement(333, "Jungle Boat"));
|
||||||
|
registry.registerItem(447, new Replacement(333, "Acacia Boat"));
|
||||||
|
registry.registerItem(448, new Replacement(333, "Dark Oak Boat"));
|
||||||
|
registry.registerItem(204, new Replacement(43, 7, "Purpur Double Slab"));
|
||||||
|
registry.registerItem(205, new Replacement(44, 7, "Purpur Slab"));
|
||||||
|
|
||||||
|
registry.registerBlock(209, new Replacement(119));
|
||||||
|
registry.registerBlock(198, 0, new Replacement(50, 5));
|
||||||
|
registry.registerBlock(198, 1, new Replacement(50, 5));
|
||||||
|
registry.registerBlock(198, 2, new Replacement(50, 4));
|
||||||
|
registry.registerBlock(198, 3, new Replacement(50, 3));
|
||||||
|
registry.registerBlock(198, 4, new Replacement(50, 2));
|
||||||
|
registry.registerBlock(198, 5, new Replacement(50, 1));
|
||||||
|
registry.registerBlock(204, new Replacement(43, 7));
|
||||||
|
registry.registerBlock(205, 0, new Replacement(44, 7));
|
||||||
|
registry.registerBlock(205, 8, new Replacement(44, 15));
|
||||||
|
registry.registerBlock(207, new Replacement(141));
|
||||||
|
registry.registerBlock(137, new Replacement(137, 0));
|
||||||
|
|
||||||
|
registry.registerItemBlock(199, new Replacement(35, 10, "Chorus Plant"));
|
||||||
|
registry.registerItemBlock(200, new Replacement(35, 2, "Chorus Flower"));
|
||||||
|
registry.registerItemBlock(201, new Replacement(155, 0, "Purpur Block"));
|
||||||
|
registry.registerItemBlock(202, new Replacement(155, 2, "Purpur Pillar"));
|
||||||
|
registry.registerItemBlock(203, 0, new Replacement(156, 0, "Purpur Stairs"));
|
||||||
|
registry.registerItemBlock(203, 1, new Replacement(156, 1, "Purpur Stairs"));
|
||||||
|
registry.registerItemBlock(203, 2, new Replacement(156, 2, "Purpur Stairs"));
|
||||||
|
registry.registerItemBlock(203, 3, new Replacement(156, 3, "Purpur Stairs"));
|
||||||
|
registry.registerItemBlock(203, 4, new Replacement(156, 4, "Purpur Stairs"));
|
||||||
|
registry.registerItemBlock(203, 5, new Replacement(156, 5, "Purpur Stairs"));
|
||||||
|
registry.registerItemBlock(203, 6, new Replacement(156, 6, "Purpur Stairs"));
|
||||||
|
registry.registerItemBlock(203, 7, new Replacement(156, 7, "Purpur Stairs"));
|
||||||
|
registry.registerItemBlock(203, 8, new Replacement(156, 8, "Purpur Stairs"));
|
||||||
|
registry.registerItemBlock(206, new Replacement(121, 0, "Endstone Bricks"));
|
||||||
|
registry.registerItemBlock(207, new Replacement(141, "Beetroot Block"));
|
||||||
|
registry.registerItemBlock(208, new Replacement(2, 0, "Grass Path"));
|
||||||
|
registry.registerItemBlock(209, new Replacement(90, "End Gateway"));
|
||||||
|
registry.registerItemBlock(210, new Replacement(137, 0, "Repeating Command Block"));
|
||||||
|
registry.registerItemBlock(211, new Replacement(137, 0, "Chain Command Block"));
|
||||||
|
registry.registerItemBlock(212, new Replacement(79, 0, "Frosted Ice"));
|
||||||
|
registry.registerItemBlock(214, new Replacement(87, 0, "Nether Wart Block"));
|
||||||
|
registry.registerItemBlock(215, new Replacement(112, 0, "Red Nether Brick"));
|
||||||
|
registry.registerItemBlock(217, new Replacement(166, 0, "Structure Void"));
|
||||||
|
registry.registerItemBlock(255, new Replacement(137, 0, "Structure Block"));
|
||||||
|
registry.registerItemBlock(397, 5, new Replacement(397, 0, "Dragon Head"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Item replace(Item item) {
|
||||||
|
return registry.replace(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int replace(int raw) {
|
||||||
|
int data = BlockState.extractData(raw);
|
||||||
|
Replacement replace = registry.replace(BlockState.extractId(raw), data);
|
||||||
|
if (replace == null) return raw;
|
||||||
|
return BlockState.stateToRaw(replace.getId(), replace.replaceData(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Replacement getReplacement(int id, int data) {
|
||||||
|
return registry.replace(id, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.metadata;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.entities.Entity1_10Types;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9to1_8.metadata.MetaIndex;
|
||||||
|
import com.elevatemc.spigot.viaversion.util.Pair;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class MetaIndex1_8to1_9 {
|
||||||
|
|
||||||
|
private static final HashMap<Pair<Entity1_10Types.EntityType, Integer>, MetaIndex> metadataRewrites = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
for (MetaIndex index : MetaIndex.values())
|
||||||
|
metadataRewrites.put(new Pair<>(index.getClazz(), index.getNewIndex()), index);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Optional<MetaIndex> getIndex(Entity1_10Types.EntityType type, int index) {
|
||||||
|
Pair pair = new Pair<>(type, index);
|
||||||
|
if (metadataRewrites.containsKey(pair)) {
|
||||||
|
return Optional.of(metadataRewrites.get(pair));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MetaIndex searchIndex(Entity1_10Types.EntityType type, int index) {
|
||||||
|
Entity1_10Types.EntityType currentType = type;
|
||||||
|
do {
|
||||||
|
Optional<MetaIndex> optMeta = getIndex(currentType, index);
|
||||||
|
|
||||||
|
if (optMeta.isPresent()) {
|
||||||
|
return optMeta.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
currentType = currentType.getParent();
|
||||||
|
} while (currentType != null);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,106 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.metadata;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.ViaRewind;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.items.ItemRewriter;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.EulerAngle;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.Vector;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.entities.Entity1_10Types;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.item.Item;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.Metadata;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.types.MetaType1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9to1_8.metadata.MetaIndex;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class MetadataRewriter {
|
||||||
|
public static void transform(Entity1_10Types.EntityType type, List<Metadata> list) {
|
||||||
|
for (Metadata entry : new ArrayList<>(list)) {
|
||||||
|
MetaIndex metaIndex = MetaIndex1_8to1_9.searchIndex(type, entry.id());
|
||||||
|
try {
|
||||||
|
if (metaIndex != null) {
|
||||||
|
if (metaIndex.getOldType() == MetaType1_8.NonExistent || metaIndex.getNewType()==null) {
|
||||||
|
list.remove(entry);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Object value = entry.getValue();
|
||||||
|
entry.setMetaTypeUnsafe(metaIndex.getOldType());
|
||||||
|
entry.setId(metaIndex.getIndex());
|
||||||
|
switch (metaIndex.getNewType()) {
|
||||||
|
case Byte:
|
||||||
|
if (metaIndex.getOldType() == MetaType1_8.Byte) {
|
||||||
|
entry.setValue(value);
|
||||||
|
}
|
||||||
|
if (metaIndex.getOldType() == MetaType1_8.Int) {
|
||||||
|
entry.setValue(((Byte) value).intValue());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OptUUID:
|
||||||
|
if (metaIndex.getOldType()!=MetaType1_8.String) {
|
||||||
|
list.remove(entry);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
UUID owner = (UUID) value;
|
||||||
|
if (owner == null) entry.setValue("");
|
||||||
|
else entry.setValue(owner.toString());
|
||||||
|
break;
|
||||||
|
case BlockID:
|
||||||
|
list.remove(entry);
|
||||||
|
list.add(new Metadata(metaIndex.getIndex(), MetaType1_8.Short, ((Integer) value).shortValue()));
|
||||||
|
break;
|
||||||
|
case VarInt:
|
||||||
|
if (metaIndex.getOldType() == MetaType1_8.Byte) {
|
||||||
|
entry.setValue(((Integer) value).byteValue());
|
||||||
|
}
|
||||||
|
if (metaIndex.getOldType() == MetaType1_8.Short) {
|
||||||
|
entry.setValue(((Integer) value).shortValue());
|
||||||
|
}
|
||||||
|
if (metaIndex.getOldType() == MetaType1_8.Int) {
|
||||||
|
entry.setValue(value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Float:
|
||||||
|
entry.setValue(value);
|
||||||
|
break;
|
||||||
|
case String:
|
||||||
|
entry.setValue(value);
|
||||||
|
break;
|
||||||
|
case Boolean:
|
||||||
|
if (metaIndex == MetaIndex.AGEABLE_AGE) entry.setValue((byte)((Boolean) value ? -1 : 0));
|
||||||
|
else entry.setValue((byte)((Boolean) value ? 1 : 0));
|
||||||
|
break;
|
||||||
|
case Slot:
|
||||||
|
entry.setValue(ItemRewriter.toClient((Item) value));
|
||||||
|
break;
|
||||||
|
case Position:
|
||||||
|
Vector vector = (Vector) value;
|
||||||
|
entry.setValue(vector);
|
||||||
|
break;
|
||||||
|
case Vector3F:
|
||||||
|
EulerAngle angle = (EulerAngle) value;
|
||||||
|
entry.setValue(angle);
|
||||||
|
break;
|
||||||
|
case Chat:
|
||||||
|
entry.setValue(value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ViaRewind.getPlatform().getLogger().warning("[Out] Unhandled MetaDataType: " + metaIndex.getNewType());
|
||||||
|
list.remove(entry);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!metaIndex.getOldType().type().getOutputClass().isAssignableFrom(entry.getValue().getClass())) {
|
||||||
|
list.remove(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw new Exception("Could not find valid metadata");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
list.remove(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,473 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.packets;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.Protocol1_8TO1_9;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.items.ItemRewriter;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.metadata.MetadataRewriter;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.storage.Cooldown;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.storage.EntityTracker;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.storage.Levitation;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.storage.PlayerPosition;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.util.RelativeMoveUtil;
|
||||||
|
import com.elevatemc.spigot.viarewind.replacement.EntityReplacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.PacketUtil;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.Vector;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.entities.Entity1_10Types;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.Metadata;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.Protocol;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.remapper.PacketRemapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.types.version.Types1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.types.version.Types1_9;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_8.ServerboundPackets1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9to1_8.ServerboundPackets1_9;
|
||||||
|
import com.elevatemc.spigot.viaversion.util.Pair;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.Protocol1_8TO1_9.VALID_ATTRIBUTES;
|
||||||
|
|
||||||
|
public class EntityPackets {
|
||||||
|
|
||||||
|
public static void register(Protocol<ClientboundPackets1_9, ClientboundPackets1_8,
|
||||||
|
ServerboundPackets1_9, ServerboundPackets1_8> protocol) {
|
||||||
|
/* OUTGOING */
|
||||||
|
|
||||||
|
//Entity Status
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.ENTITY_STATUS, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.INT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
byte status = packetWrapper.read(Type.BYTE);
|
||||||
|
if (status > 23) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
packetWrapper.write(Type.BYTE, status);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Entity Relative Move
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.ENTITY_POSITION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
int relX = packetWrapper.read(Type.SHORT);
|
||||||
|
int relY = packetWrapper.read(Type.SHORT);
|
||||||
|
int relZ = packetWrapper.read(Type.SHORT);
|
||||||
|
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
|
||||||
|
if (replacement != null) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
replacement.relMove(relX / 4096.0, relY / 4096.0, relZ / 4096.0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector[] moves = RelativeMoveUtil.calculateRelativeMoves(packetWrapper.user(), entityId, relX, relY, relZ);
|
||||||
|
|
||||||
|
packetWrapper.write(Type.BYTE, (byte) moves[0].getBlockX());
|
||||||
|
packetWrapper.write(Type.BYTE, (byte) moves[0].getBlockY());
|
||||||
|
packetWrapper.write(Type.BYTE, (byte) moves[0].getBlockZ());
|
||||||
|
|
||||||
|
boolean onGround = packetWrapper.passthrough(Type.BOOLEAN);
|
||||||
|
|
||||||
|
if (moves.length > 1) {
|
||||||
|
PacketWrapper secondPacket = PacketWrapper.create(0x15, null, packetWrapper.user());
|
||||||
|
secondPacket.write(Type.VAR_INT, packetWrapper.get(Type.VAR_INT, 0));
|
||||||
|
secondPacket.write(Type.BYTE, (byte) moves[1].getBlockX());
|
||||||
|
secondPacket.write(Type.BYTE, (byte) moves[1].getBlockY());
|
||||||
|
secondPacket.write(Type.BYTE, (byte) moves[1].getBlockZ());
|
||||||
|
secondPacket.write(Type.BOOLEAN, onGround);
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(secondPacket, Protocol1_8TO1_9.class);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Entity Relative Move And Look
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.ENTITY_POSITION_AND_ROTATION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
int relX = packetWrapper.read(Type.SHORT);
|
||||||
|
int relY = packetWrapper.read(Type.SHORT);
|
||||||
|
int relZ = packetWrapper.read(Type.SHORT);
|
||||||
|
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
|
||||||
|
if (replacement != null) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
replacement.relMove(relX / 4096.0, relY / 4096.0, relZ / 4096.0);
|
||||||
|
replacement.setYawPitch(packetWrapper.read(Type.BYTE) * 360f / 256, packetWrapper.read(Type.BYTE) * 360f / 256);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector[] moves = RelativeMoveUtil.calculateRelativeMoves(packetWrapper.user(), entityId, relX, relY, relZ);
|
||||||
|
|
||||||
|
packetWrapper.write(Type.BYTE, (byte) moves[0].getBlockX());
|
||||||
|
packetWrapper.write(Type.BYTE, (byte) moves[0].getBlockY());
|
||||||
|
packetWrapper.write(Type.BYTE, (byte) moves[0].getBlockZ());
|
||||||
|
|
||||||
|
byte yaw = packetWrapper.passthrough(Type.BYTE);
|
||||||
|
byte pitch = packetWrapper.passthrough(Type.BYTE);
|
||||||
|
boolean onGround = packetWrapper.passthrough(Type.BOOLEAN);
|
||||||
|
|
||||||
|
Entity1_10Types.EntityType type = packetWrapper.user().get(EntityTracker.class).getClientEntityTypes().get(entityId);
|
||||||
|
if (type == Entity1_10Types.EntityType.BOAT) {
|
||||||
|
yaw -= 64;
|
||||||
|
packetWrapper.set(Type.BYTE, 3, yaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (moves.length > 1) {
|
||||||
|
PacketWrapper secondPacket = PacketWrapper.create(0x17, null, packetWrapper.user());
|
||||||
|
secondPacket.write(Type.VAR_INT, packetWrapper.get(Type.VAR_INT, 0));
|
||||||
|
secondPacket.write(Type.BYTE, (byte) moves[1].getBlockX());
|
||||||
|
secondPacket.write(Type.BYTE, (byte) moves[1].getBlockY());
|
||||||
|
secondPacket.write(Type.BYTE, (byte) moves[1].getBlockZ());
|
||||||
|
secondPacket.write(Type.BYTE, yaw);
|
||||||
|
secondPacket.write(Type.BYTE, pitch);
|
||||||
|
secondPacket.write(Type.BOOLEAN, onGround);
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(secondPacket, Protocol1_8TO1_9.class);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Entity Look
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.ENTITY_ROTATION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.BOOLEAN);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
|
||||||
|
if (replacement != null) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
int yaw = packetWrapper.get(Type.BYTE, 0);
|
||||||
|
int pitch = packetWrapper.get(Type.BYTE, 1);
|
||||||
|
replacement.setYawPitch(yaw * 360f / 256, pitch * 360f / 256);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
Entity1_10Types.EntityType type = packetWrapper.user().get(EntityTracker.class).getClientEntityTypes().get(entityId);
|
||||||
|
if (type == Entity1_10Types.EntityType.BOAT) {
|
||||||
|
byte yaw = packetWrapper.get(Type.BYTE, 0);
|
||||||
|
yaw -= 64;
|
||||||
|
packetWrapper.set(Type.BYTE, 0, yaw);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Entity
|
||||||
|
|
||||||
|
//Vehicle Move -> Entity Teleport
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.VEHICLE_MOVE, ClientboundPackets1_8.ENTITY_TELEPORT, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
int vehicle = tracker.getVehicle(tracker.getPlayerId());
|
||||||
|
if (vehicle == -1) packetWrapper.cancel();
|
||||||
|
packetWrapper.write(Type.VAR_INT, vehicle);
|
||||||
|
});
|
||||||
|
map(Type.DOUBLE, Protocol1_8TO1_9.TO_OLD_INT);
|
||||||
|
map(Type.DOUBLE, Protocol1_8TO1_9.TO_OLD_INT);
|
||||||
|
map(Type.DOUBLE, Protocol1_8TO1_9.TO_OLD_INT);
|
||||||
|
map(Type.FLOAT, Protocol1_8TO1_9.DEGREES_TO_ANGLE);
|
||||||
|
map(Type.FLOAT, Protocol1_8TO1_9.DEGREES_TO_ANGLE);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
if (packetWrapper.isCancelled()) return;
|
||||||
|
PlayerPosition position = packetWrapper.user().get(PlayerPosition.class);
|
||||||
|
double x = packetWrapper.get(Type.INT, 0) / 32d;
|
||||||
|
double y = packetWrapper.get(Type.INT, 1) / 32d;
|
||||||
|
double z = packetWrapper.get(Type.INT, 2) / 32d;
|
||||||
|
position.setPos(x, y, z);
|
||||||
|
});
|
||||||
|
create(Type.BOOLEAN, true);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
Entity1_10Types.EntityType type = packetWrapper.user().get(EntityTracker.class).getClientEntityTypes().get(entityId);
|
||||||
|
if (type == Entity1_10Types.EntityType.BOAT) {
|
||||||
|
byte yaw = packetWrapper.get(Type.BYTE, 1);
|
||||||
|
yaw -= 64;
|
||||||
|
packetWrapper.set(Type.BYTE, 0, yaw);
|
||||||
|
int y = packetWrapper.get(Type.INT, 1);
|
||||||
|
y += 10;
|
||||||
|
packetWrapper.set(Type.INT, 1, y);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Use Bed
|
||||||
|
|
||||||
|
//Destroy Entities
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.DESTROY_ENTITIES, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT_ARRAY_PRIMITIVE);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
for (int entityId : packetWrapper.get(Type.VAR_INT_ARRAY_PRIMITIVE, 0))
|
||||||
|
tracker.removeEntity(entityId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Remove Entity Effect
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.REMOVE_ENTITY_EFFECT, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.BYTE);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int id = packetWrapper.get(Type.BYTE, 0);
|
||||||
|
if (id > 23) packetWrapper.cancel();
|
||||||
|
if (id == 25) {
|
||||||
|
if (packetWrapper.get(Type.VAR_INT, 0) != packetWrapper.user().get(EntityTracker.class).getPlayerId())
|
||||||
|
return;
|
||||||
|
Levitation levitation = packetWrapper.user().get(Levitation.class);
|
||||||
|
levitation.setActive(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Entity Head Look
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.ENTITY_HEAD_LOOK, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.BYTE);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
|
||||||
|
if (replacement != null) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
int yaw = packetWrapper.get(Type.BYTE, 0);
|
||||||
|
replacement.setHeadYaw(yaw * 360f / 256);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Entity Metadata
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.ENTITY_METADATA, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Types1_9.METADATA_LIST, Types1_8.METADATA_LIST);
|
||||||
|
handler(wrapper -> {
|
||||||
|
List<Metadata> metadataList = wrapper.get(Types1_8.METADATA_LIST, 0);
|
||||||
|
int entityId = wrapper.get(Type.VAR_INT, 0);
|
||||||
|
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
|
||||||
|
if (tracker.getClientEntityTypes().containsKey(entityId)) {
|
||||||
|
MetadataRewriter.transform(tracker.getClientEntityTypes().get(entityId), metadataList);
|
||||||
|
if (metadataList.isEmpty()) wrapper.cancel();
|
||||||
|
} else {
|
||||||
|
tracker.addMetadataToBuffer(entityId, metadataList);
|
||||||
|
wrapper.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Attach Entity
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.ATTACH_ENTITY, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.INT);
|
||||||
|
create(Type.BOOLEAN, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Entity Velocity
|
||||||
|
|
||||||
|
//Entity Equipment
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.ENTITY_EQUIPMENT, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int slot = packetWrapper.read(Type.VAR_INT);
|
||||||
|
if (slot == 1) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
} else if (slot > 1) {
|
||||||
|
slot -= 1;
|
||||||
|
}
|
||||||
|
packetWrapper.write(Type.SHORT, (short) slot);
|
||||||
|
});
|
||||||
|
map(Type.ITEM);
|
||||||
|
handler(packetWrapper -> packetWrapper.set(Type.ITEM, 0, ItemRewriter.toClient(packetWrapper.get(Type.ITEM, 0))));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Set Passengers
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.SET_PASSENGERS, null, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
EntityTracker entityTracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
int vehicle = packetWrapper.read(Type.VAR_INT);
|
||||||
|
int count = packetWrapper.read(Type.VAR_INT);
|
||||||
|
ArrayList<Integer> passengers = new ArrayList<>();
|
||||||
|
for (int i = 0; i < count; i++) passengers.add(packetWrapper.read(Type.VAR_INT));
|
||||||
|
List<Integer> oldPassengers = entityTracker.getPassengers(vehicle);
|
||||||
|
entityTracker.setPassengers(vehicle, passengers);
|
||||||
|
if (!oldPassengers.isEmpty()) {
|
||||||
|
for (Integer passenger : oldPassengers) {
|
||||||
|
PacketWrapper detach = PacketWrapper.create(0x1B, null, packetWrapper.user());
|
||||||
|
detach.write(Type.INT, passenger);
|
||||||
|
detach.write(Type.INT, -1);
|
||||||
|
detach.write(Type.BOOLEAN, false);
|
||||||
|
PacketUtil.sendPacket(detach, Protocol1_8TO1_9.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
int v = i == 0 ? vehicle : passengers.get(i - 1);
|
||||||
|
int p = passengers.get(i);
|
||||||
|
PacketWrapper attach = PacketWrapper.create(0x1B, null, packetWrapper.user());
|
||||||
|
attach.write(Type.INT, p);
|
||||||
|
attach.write(Type.INT, v);
|
||||||
|
attach.write(Type.BOOLEAN, false);
|
||||||
|
PacketUtil.sendPacket(attach, Protocol1_8TO1_9.class);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Collect Item
|
||||||
|
|
||||||
|
//Entity Teleport
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.ENTITY_TELEPORT, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.DOUBLE, Protocol1_8TO1_9.TO_OLD_INT);
|
||||||
|
map(Type.DOUBLE, Protocol1_8TO1_9.TO_OLD_INT);
|
||||||
|
map(Type.DOUBLE, Protocol1_8TO1_9.TO_OLD_INT);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.BOOLEAN);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
Entity1_10Types.EntityType type = packetWrapper.user().get(EntityTracker.class).getClientEntityTypes().get(entityId);
|
||||||
|
if (type == Entity1_10Types.EntityType.BOAT) {
|
||||||
|
byte yaw = packetWrapper.get(Type.BYTE, 1);
|
||||||
|
yaw -= 64;
|
||||||
|
packetWrapper.set(Type.BYTE, 0, yaw);
|
||||||
|
int y = packetWrapper.get(Type.INT, 1);
|
||||||
|
y += 10;
|
||||||
|
packetWrapper.set(Type.INT, 1, y);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
packetWrapper.user().get(EntityTracker.class).resetEntityOffset(entityId);
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
|
||||||
|
if (replacement != null) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
int x = packetWrapper.get(Type.INT, 0);
|
||||||
|
int y = packetWrapper.get(Type.INT, 1);
|
||||||
|
int z = packetWrapper.get(Type.INT, 2);
|
||||||
|
int yaw = packetWrapper.get(Type.BYTE, 0);
|
||||||
|
int pitch = packetWrapper.get(Type.BYTE, 1);
|
||||||
|
replacement.setLocation(x / 32.0, y / 32.0, z / 32.0);
|
||||||
|
replacement.setYawPitch(yaw * 360f / 256, pitch * 360f / 256);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Entity Properties
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.ENTITY_PROPERTIES, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.INT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
boolean player = packetWrapper.get(Type.VAR_INT, 0) == packetWrapper.user().get(EntityTracker.class).getPlayerId();
|
||||||
|
int size = packetWrapper.get(Type.INT, 0);
|
||||||
|
int removed = 0;
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
String key = packetWrapper.read(Type.STRING);
|
||||||
|
boolean skip = !VALID_ATTRIBUTES.contains(key);
|
||||||
|
double value = packetWrapper.read(Type.DOUBLE);
|
||||||
|
int modifiersize = packetWrapper.read(Type.VAR_INT);
|
||||||
|
if (!skip) {
|
||||||
|
packetWrapper.write(Type.STRING, key);
|
||||||
|
packetWrapper.write(Type.DOUBLE, value);
|
||||||
|
packetWrapper.write(Type.VAR_INT, modifiersize);
|
||||||
|
} else {
|
||||||
|
removed++;
|
||||||
|
}
|
||||||
|
ArrayList<Pair<Byte, Double>> modifiers = new ArrayList<>();
|
||||||
|
for (int j = 0; j < modifiersize; j++) {
|
||||||
|
UUID uuid = packetWrapper.read(Type.UUID);
|
||||||
|
double amount = packetWrapper.read(Type.DOUBLE);
|
||||||
|
byte operation = packetWrapper.read(Type.BYTE);
|
||||||
|
modifiers.add(new Pair<>(operation, amount));
|
||||||
|
if (skip) continue;
|
||||||
|
packetWrapper.write(Type.UUID, uuid);
|
||||||
|
packetWrapper.write(Type.DOUBLE, amount);
|
||||||
|
packetWrapper.write(Type.BYTE, operation);
|
||||||
|
}
|
||||||
|
if (player && key.equals("generic.attackSpeed")) {
|
||||||
|
packetWrapper.user().get(Cooldown.class).setAttackSpeed(value, modifiers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
packetWrapper.set(Type.INT, 0, size - removed);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Entity Effect
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.ENTITY_EFFECT, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.BYTE);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int id = packetWrapper.get(Type.BYTE, 0);
|
||||||
|
if (id > 23) packetWrapper.cancel();
|
||||||
|
if (id == 25) {
|
||||||
|
if (packetWrapper.get(Type.VAR_INT, 0) != packetWrapper.user().get(EntityTracker.class).getPlayerId())
|
||||||
|
return;
|
||||||
|
Levitation levitation = packetWrapper.user().get(Levitation.class);
|
||||||
|
levitation.setActive(true);
|
||||||
|
levitation.setAmplifier(packetWrapper.get(Type.BYTE, 1));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,182 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.packets;
|
||||||
|
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.items.ItemRewriter;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.storage.Windows;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.item.Item;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.Protocol;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.remapper.PacketRemapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_8.ServerboundPackets1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9to1_8.ServerboundPackets1_9;
|
||||||
|
|
||||||
|
public class InventoryPackets {
|
||||||
|
|
||||||
|
public static void register(Protocol<ClientboundPackets1_9, ClientboundPackets1_8,
|
||||||
|
ServerboundPackets1_9, ServerboundPackets1_8> protocol) {
|
||||||
|
/* OUTGOING */
|
||||||
|
|
||||||
|
//Confirm Transaction
|
||||||
|
|
||||||
|
//Close Window
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.CLOSE_WINDOW, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
short windowsId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
|
||||||
|
packetWrapper.user().get(Windows.class).remove(windowsId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Open Window
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.OPEN_WINDOW, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
map(Type.STRING);
|
||||||
|
map(Type.COMPONENT);
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
String type = packetWrapper.get(Type.STRING, 0);
|
||||||
|
if (type.equals("EntityHorse")) packetWrapper.passthrough(Type.INT);
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
short windowId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
|
||||||
|
String windowType = packetWrapper.get(Type.STRING, 0);
|
||||||
|
packetWrapper.user().get(Windows.class).put(windowId, windowType);
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
String type = packetWrapper.get(Type.STRING, 0);
|
||||||
|
if (type.equalsIgnoreCase("minecraft:shulker_box")) {
|
||||||
|
packetWrapper.set(Type.STRING, 0, type = "minecraft:container");
|
||||||
|
}
|
||||||
|
String name = packetWrapper.get(Type.COMPONENT, 0).toString();
|
||||||
|
if (name.equalsIgnoreCase("{\"translate\":\"container.shulkerBox\"}")) {
|
||||||
|
packetWrapper.set(Type.COMPONENT, 0, new JsonParser().parse("{\"text\":\"Shulker Box\"}"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Window Items
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.WINDOW_ITEMS, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
short windowId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
|
||||||
|
Item[] items = packetWrapper.read(Type.ITEM_ARRAY);
|
||||||
|
for (int i = 0; i < items.length; i++) {
|
||||||
|
items[i] = ItemRewriter.toClient(items[i]);
|
||||||
|
}
|
||||||
|
if (windowId == 0 && items.length == 46) {
|
||||||
|
Item[] old = items;
|
||||||
|
items = new Item[45];
|
||||||
|
System.arraycopy(old, 0, items, 0, 45);
|
||||||
|
} else {
|
||||||
|
String type = packetWrapper.user().get(Windows.class).get(windowId);
|
||||||
|
if (type != null && type.equalsIgnoreCase("minecraft:brewing_stand")) {
|
||||||
|
System.arraycopy(items, 0, packetWrapper.user().get(Windows.class).getBrewingItems(windowId), 0, 4);
|
||||||
|
Windows.updateBrewingStand(packetWrapper.user(), items[4], windowId);
|
||||||
|
Item[] old = items;
|
||||||
|
items = new Item[old.length - 1];
|
||||||
|
System.arraycopy(old, 0, items, 0, 4);
|
||||||
|
System.arraycopy(old, 5, items, 4, old.length - 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
packetWrapper.write(Type.ITEM_ARRAY, items);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Window Property
|
||||||
|
|
||||||
|
//Set Slot
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.SET_SLOT, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
map(Type.SHORT);
|
||||||
|
map(Type.ITEM);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
packetWrapper.set(Type.ITEM, 0, ItemRewriter.toClient(packetWrapper.get(Type.ITEM, 0)));
|
||||||
|
byte windowId = packetWrapper.get(Type.UNSIGNED_BYTE, 0).byteValue();
|
||||||
|
short slot = packetWrapper.get(Type.SHORT, 0);
|
||||||
|
if (windowId == 0 && slot == 45) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String type = packetWrapper.user().get(Windows.class).get(windowId);
|
||||||
|
if (type == null) return;
|
||||||
|
if (type.equalsIgnoreCase("minecraft:brewing_stand")) {
|
||||||
|
if (slot > 4) {
|
||||||
|
packetWrapper.set(Type.SHORT, 0, slot -= 1);
|
||||||
|
} else if (slot == 4) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
Windows.updateBrewingStand(packetWrapper.user(), packetWrapper.get(Type.ITEM, 0), windowId);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
packetWrapper.user().get(Windows.class).getBrewingItems(windowId)[slot] = packetWrapper.get(Type.ITEM, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* INCMOING */
|
||||||
|
|
||||||
|
//Close Window
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_8.CLOSE_WINDOW, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
short windowsId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
|
||||||
|
packetWrapper.user().get(Windows.class).remove(windowsId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Click Window
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_8.CLICK_WINDOW, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
map(Type.SHORT);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.SHORT);
|
||||||
|
map(Type.BYTE, Type.VAR_INT);
|
||||||
|
map(Type.ITEM);
|
||||||
|
handler(packetWrapper -> packetWrapper.set(Type.ITEM, 0, ItemRewriter.toServer(packetWrapper.get(Type.ITEM, 0))));
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
short windowId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
|
||||||
|
Windows windows = packetWrapper.user().get(Windows.class);
|
||||||
|
String type = windows.get(windowId);
|
||||||
|
if (type == null) return;
|
||||||
|
if (type.equalsIgnoreCase("minecraft:brewing_stand")) {
|
||||||
|
short slot = packetWrapper.get(Type.SHORT, 0);
|
||||||
|
if (slot > 3) {
|
||||||
|
packetWrapper.set(Type.SHORT, 0, slot += 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Creative Inventory Action
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_8.CREATIVE_INVENTORY_ACTION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.SHORT);
|
||||||
|
map(Type.ITEM);
|
||||||
|
handler(packetWrapper -> packetWrapper.set(Type.ITEM, 0, ItemRewriter.toServer(packetWrapper.get(Type.ITEM, 0))));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Enchant Item
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,596 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.packets;
|
||||||
|
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||||
|
import com.elevatemc.spigot.viarewind.ViaRewind;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.Protocol1_8TO1_9;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.items.ItemRewriter;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.storage.*;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.ChatUtil;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.PacketUtil;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.Position;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.entities.Entity1_10Types;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.item.Item;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.Metadata;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.types.MetaType1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.Protocol;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.remapper.PacketRemapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.types.version.Types1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_8.ServerboundPackets1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9to1_8.ServerboundPackets1_9;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class PlayerPackets {
|
||||||
|
|
||||||
|
public static void register(Protocol<ClientboundPackets1_9, ClientboundPackets1_8,
|
||||||
|
ServerboundPackets1_9, ServerboundPackets1_8> protocol) {
|
||||||
|
/* OUTGOING */
|
||||||
|
|
||||||
|
//Animation
|
||||||
|
//Statistics
|
||||||
|
|
||||||
|
//Boss Bar
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.BOSSBAR, null, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
|
||||||
|
UUID uuid = packetWrapper.read(Type.UUID);
|
||||||
|
int action = packetWrapper.read(Type.VAR_INT);
|
||||||
|
BossBarStorage bossBarStorage = packetWrapper.user().get(BossBarStorage.class);
|
||||||
|
if (action == 0) {
|
||||||
|
bossBarStorage.add(uuid, ChatUtil.jsonToLegacy(packetWrapper.read(Type.COMPONENT)), packetWrapper.read(Type.FLOAT));
|
||||||
|
packetWrapper.read(Type.VAR_INT);
|
||||||
|
packetWrapper.read(Type.VAR_INT);
|
||||||
|
packetWrapper.read(Type.UNSIGNED_BYTE);
|
||||||
|
} else if (action == 1) {
|
||||||
|
bossBarStorage.remove(uuid);
|
||||||
|
} else if (action == 2) {
|
||||||
|
bossBarStorage.updateHealth(uuid, packetWrapper.read(Type.FLOAT));
|
||||||
|
} else if (action == 3) {
|
||||||
|
String title = ChatUtil.jsonToLegacy(packetWrapper.read(Type.COMPONENT));
|
||||||
|
bossBarStorage.updateTitle(uuid, title);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Tab-Complete
|
||||||
|
//Chat Message
|
||||||
|
|
||||||
|
//Set Cooldown
|
||||||
|
protocol.cancelClientbound(ClientboundPackets1_9.COOLDOWN);
|
||||||
|
|
||||||
|
//Custom Payload
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.PLUGIN_MESSAGE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.STRING);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
String channel = packetWrapper.get(Type.STRING, 0);
|
||||||
|
if (channel.equalsIgnoreCase("MC|TrList")) {
|
||||||
|
packetWrapper.passthrough(Type.INT); //Window Id
|
||||||
|
|
||||||
|
int size;
|
||||||
|
if (packetWrapper.isReadable(Type.BYTE, 0)) {
|
||||||
|
size = packetWrapper.passthrough(Type.BYTE);
|
||||||
|
} else {
|
||||||
|
size = packetWrapper.passthrough(Type.UNSIGNED_BYTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
packetWrapper.write(Type.ITEM, ItemRewriter.toClient(packetWrapper.read(Type.ITEM))); //Buy Item 1
|
||||||
|
packetWrapper.write(Type.ITEM, ItemRewriter.toClient(packetWrapper.read(Type.ITEM))); //Buy Item 3
|
||||||
|
|
||||||
|
boolean has3Items = packetWrapper.passthrough(Type.BOOLEAN);
|
||||||
|
if (has3Items) {
|
||||||
|
packetWrapper.write(Type.ITEM, ItemRewriter.toClient(packetWrapper.read(Type.ITEM))); //Buy Item 2
|
||||||
|
}
|
||||||
|
|
||||||
|
packetWrapper.passthrough(Type.BOOLEAN); //Unavailable
|
||||||
|
packetWrapper.passthrough(Type.INT); //Uses
|
||||||
|
packetWrapper.passthrough(Type.INT); //Max Uses
|
||||||
|
}
|
||||||
|
} else if (channel.equalsIgnoreCase("MC|BOpen")) {
|
||||||
|
packetWrapper.read(Type.VAR_INT);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Disconnect
|
||||||
|
//Change Game State
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.GAME_EVENT, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int reason = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
|
||||||
|
if (reason == 3)
|
||||||
|
packetWrapper.user().get(EntityTracker.class).setPlayerGamemode(packetWrapper.get(Type.FLOAT, 0).intValue());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Join Game
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.JOIN_GAME, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
map(Type.STRING);
|
||||||
|
map(Type.BOOLEAN);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
tracker.setPlayerId(packetWrapper.get(Type.INT, 0));
|
||||||
|
tracker.setPlayerGamemode(packetWrapper.get(Type.UNSIGNED_BYTE, 0));
|
||||||
|
tracker.getClientEntityTypes().put(tracker.getPlayerId(), Entity1_10Types.EntityType.ENTITY_HUMAN);
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
ClientWorld world = packetWrapper.user().get(ClientWorld.class);
|
||||||
|
world.setEnvironment(packetWrapper.get(Type.BYTE, 0));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Open Sign Editor
|
||||||
|
//Player Abilities
|
||||||
|
//Player List Item
|
||||||
|
|
||||||
|
//Player Position And Look
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.PLAYER_POSITION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.DOUBLE);
|
||||||
|
map(Type.DOUBLE);
|
||||||
|
map(Type.DOUBLE);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.BYTE);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
PlayerPosition pos = packetWrapper.user().get(PlayerPosition.class);
|
||||||
|
|
||||||
|
int teleportId = packetWrapper.read(Type.VAR_INT);
|
||||||
|
pos.setConfirmId(teleportId);
|
||||||
|
|
||||||
|
byte flags = packetWrapper.get(Type.BYTE, 0);
|
||||||
|
double x = packetWrapper.get(Type.DOUBLE, 0);
|
||||||
|
double y = packetWrapper.get(Type.DOUBLE, 1);
|
||||||
|
double z = packetWrapper.get(Type.DOUBLE, 2);
|
||||||
|
float yaw = packetWrapper.get(Type.FLOAT, 0);
|
||||||
|
float pitch = packetWrapper.get(Type.FLOAT, 1);
|
||||||
|
|
||||||
|
packetWrapper.set(Type.BYTE, 0, (byte) 0);
|
||||||
|
|
||||||
|
if (flags != 0) {
|
||||||
|
if ((flags & 0x01) != 0) {
|
||||||
|
x += pos.getPosX();
|
||||||
|
packetWrapper.set(Type.DOUBLE, 0, x);
|
||||||
|
}
|
||||||
|
if ((flags & 0x02) != 0) {
|
||||||
|
y += pos.getPosY();
|
||||||
|
packetWrapper.set(Type.DOUBLE, 1, y);
|
||||||
|
}
|
||||||
|
if ((flags & 0x04) != 0) {
|
||||||
|
z += pos.getPosZ();
|
||||||
|
packetWrapper.set(Type.DOUBLE, 2, z);
|
||||||
|
}
|
||||||
|
if ((flags & 0x08) != 0) {
|
||||||
|
yaw += pos.getYaw();
|
||||||
|
packetWrapper.set(Type.FLOAT, 0, yaw);
|
||||||
|
}
|
||||||
|
if ((flags & 0x10) != 0) {
|
||||||
|
pitch += pos.getPitch();
|
||||||
|
packetWrapper.set(Type.FLOAT, 1, pitch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pos.setPos(x, y, z);
|
||||||
|
pos.setYaw(yaw);
|
||||||
|
pos.setPitch(pitch);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Resource Pack Send
|
||||||
|
|
||||||
|
//Respawn
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.RESPAWN, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
map(Type.STRING);
|
||||||
|
handler(packetWrapper -> packetWrapper.user().get(EntityTracker.class).setPlayerGamemode(packetWrapper.get(Type.UNSIGNED_BYTE, 1)));
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
packetWrapper.user().get(BossBarStorage.class).updateLocation();
|
||||||
|
packetWrapper.user().get(BossBarStorage.class).changeWorld();
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
ClientWorld world = packetWrapper.user().get(ClientWorld.class);
|
||||||
|
world.setEnvironment(packetWrapper.get(Type.INT, 0));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Camera
|
||||||
|
//Held Item Change
|
||||||
|
//Set Experience
|
||||||
|
//Update Health
|
||||||
|
//Spawn Position
|
||||||
|
//Title
|
||||||
|
//Player List Header And Footer
|
||||||
|
|
||||||
|
/* INCMOING */
|
||||||
|
|
||||||
|
//Chat Message
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_8.CHAT_MESSAGE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.STRING);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
String msg = packetWrapper.get(Type.STRING, 0);
|
||||||
|
if (msg.toLowerCase().startsWith("/offhand")) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
PacketWrapper swapItems = PacketWrapper.create(0x13, null, packetWrapper.user());
|
||||||
|
swapItems.write(Type.VAR_INT, 6);
|
||||||
|
swapItems.write(Type.POSITION, new Position(0, (short) 0, 0));
|
||||||
|
swapItems.write(Type.BYTE, (byte) 255);
|
||||||
|
|
||||||
|
PacketUtil.sendToServer(swapItems, Protocol1_8TO1_9.class, true, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Confirm Transaction
|
||||||
|
|
||||||
|
//Use Entity
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_8.INTERACT_ENTITY, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int type = packetWrapper.get(Type.VAR_INT, 1);
|
||||||
|
if (type == 2) {
|
||||||
|
packetWrapper.passthrough(Type.FLOAT);
|
||||||
|
packetWrapper.passthrough(Type.FLOAT);
|
||||||
|
packetWrapper.passthrough(Type.FLOAT);
|
||||||
|
}
|
||||||
|
if (type == 2 || type == 0) {
|
||||||
|
packetWrapper.write(Type.VAR_INT, 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Player
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_8.PLAYER_MOVEMENT, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.BOOLEAN);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
int playerId = tracker.getPlayerId();
|
||||||
|
if (tracker.isInsideVehicle(playerId)) packetWrapper.cancel();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Player Position
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_8.PLAYER_POSITION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.DOUBLE);
|
||||||
|
map(Type.DOUBLE);
|
||||||
|
map(Type.DOUBLE);
|
||||||
|
map(Type.BOOLEAN);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
PlayerPosition pos = packetWrapper.user().get(PlayerPosition.class);
|
||||||
|
if (pos.getConfirmId() != -1) return;
|
||||||
|
pos.setPos(packetWrapper.get(Type.DOUBLE, 0), packetWrapper.get(Type.DOUBLE, 1), packetWrapper.get(Type.DOUBLE, 2));
|
||||||
|
pos.setOnGround(packetWrapper.get(Type.BOOLEAN, 0));
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> packetWrapper.user().get(BossBarStorage.class).updateLocation());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Player Look
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_8.PLAYER_ROTATION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.BOOLEAN);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
PlayerPosition pos = packetWrapper.user().get(PlayerPosition.class);
|
||||||
|
if (pos.getConfirmId() != -1) return;
|
||||||
|
pos.setYaw(packetWrapper.get(Type.FLOAT, 0));
|
||||||
|
pos.setPitch(packetWrapper.get(Type.FLOAT, 1));
|
||||||
|
pos.setOnGround(packetWrapper.get(Type.BOOLEAN, 0));
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> packetWrapper.user().get(BossBarStorage.class).updateLocation());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Player Position And Look
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_8.PLAYER_POSITION_AND_ROTATION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.DOUBLE);
|
||||||
|
map(Type.DOUBLE);
|
||||||
|
map(Type.DOUBLE);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.BOOLEAN);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
double x = packetWrapper.get(Type.DOUBLE, 0);
|
||||||
|
double y = packetWrapper.get(Type.DOUBLE, 1);
|
||||||
|
double z = packetWrapper.get(Type.DOUBLE, 2);
|
||||||
|
float yaw = packetWrapper.get(Type.FLOAT, 0);
|
||||||
|
float pitch = packetWrapper.get(Type.FLOAT, 1);
|
||||||
|
boolean onGround = packetWrapper.get(Type.BOOLEAN, 0);
|
||||||
|
|
||||||
|
PlayerPosition pos = packetWrapper.user().get(PlayerPosition.class);
|
||||||
|
if (pos.getConfirmId() != -1) {
|
||||||
|
if (pos.getPosX() == x && pos.getPosY() == y && pos.getPosZ() == z && pos.getYaw() == yaw && pos.getPitch() == pitch) {
|
||||||
|
PacketWrapper confirmTeleport = packetWrapper.create(0x00);
|
||||||
|
confirmTeleport.write(Type.VAR_INT, pos.getConfirmId());
|
||||||
|
PacketUtil.sendToServer(confirmTeleport, Protocol1_8TO1_9.class, true, true);
|
||||||
|
|
||||||
|
pos.setConfirmId(-1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pos.setPos(x, y, z);
|
||||||
|
pos.setYaw(yaw);
|
||||||
|
pos.setPitch(pitch);
|
||||||
|
pos.setOnGround(onGround);
|
||||||
|
packetWrapper.user().get(BossBarStorage.class).updateLocation();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Player Digging
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_8.PLAYER_DIGGING, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.POSITION);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int state = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
if (state == 0) {
|
||||||
|
packetWrapper.user().get(BlockPlaceDestroyTracker.class).setMining(true);
|
||||||
|
} else if (state == 2) {
|
||||||
|
BlockPlaceDestroyTracker tracker = packetWrapper.user().get(BlockPlaceDestroyTracker.class);
|
||||||
|
tracker.setMining(false);
|
||||||
|
tracker.setLastMining(System.currentTimeMillis() + 100);
|
||||||
|
packetWrapper.user().get(Cooldown.class).setLastHit(0);
|
||||||
|
} else if (state == 1) {
|
||||||
|
BlockPlaceDestroyTracker tracker = packetWrapper.user().get(BlockPlaceDestroyTracker.class);
|
||||||
|
tracker.setMining(false);
|
||||||
|
tracker.setLastMining(0);
|
||||||
|
packetWrapper.user().get(Cooldown.class).hit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Player Block Placement
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_8.PLAYER_BLOCK_PLACEMENT, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.POSITION);
|
||||||
|
map(Type.BYTE, Type.VAR_INT);
|
||||||
|
map(Type.ITEM, Type.NOTHING);
|
||||||
|
create(Type.VAR_INT, 0); //Main Hand
|
||||||
|
map(Type.BYTE, Type.UNSIGNED_BYTE);
|
||||||
|
map(Type.BYTE, Type.UNSIGNED_BYTE);
|
||||||
|
map(Type.BYTE, Type.UNSIGNED_BYTE);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
if (packetWrapper.get(Type.VAR_INT, 0) == -1) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
PacketWrapper useItem = PacketWrapper.create(0x1D, null, packetWrapper.user());
|
||||||
|
useItem.write(Type.VAR_INT, 0);
|
||||||
|
|
||||||
|
PacketUtil.sendToServer(useItem, Protocol1_8TO1_9.class, true, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
if (packetWrapper.get(Type.VAR_INT, 0) != -1) {
|
||||||
|
packetWrapper.user().get(BlockPlaceDestroyTracker.class).place();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Held Item Change
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_8.HELD_ITEM_CHANGE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> packetWrapper.user().get(Cooldown.class).hit());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Animation
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_8.ANIMATION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
final PacketWrapper delayedPacket = PacketWrapper.create(0x1A, null, packetWrapper.user());
|
||||||
|
delayedPacket.write(Type.VAR_INT, 0); //Main Hand
|
||||||
|
//delay packet in order to deal damage to entities
|
||||||
|
//the cooldown value gets reset by this packet
|
||||||
|
//1.8 sends it before the use entity packet
|
||||||
|
//1.9 afterwards
|
||||||
|
Protocol1_8TO1_9.TIMER.schedule(new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
PacketUtil.sendToServer(delayedPacket, Protocol1_8TO1_9.class);
|
||||||
|
}
|
||||||
|
}, 5);
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
packetWrapper.user().get(BlockPlaceDestroyTracker.class).updateMining();
|
||||||
|
packetWrapper.user().get(Cooldown.class).hit();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Entity Action
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_8.ENTITY_ACTION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int action = packetWrapper.get(Type.VAR_INT, 1);
|
||||||
|
if (action == 6) {
|
||||||
|
packetWrapper.set(Type.VAR_INT, 1, 7);
|
||||||
|
} else if (action == 0) {
|
||||||
|
PlayerPosition pos = packetWrapper.user().get(PlayerPosition.class);
|
||||||
|
if (!pos.isOnGround()) {
|
||||||
|
PacketWrapper elytra = PacketWrapper.create(0x14, null, packetWrapper.user());
|
||||||
|
elytra.write(Type.VAR_INT, packetWrapper.get(Type.VAR_INT, 0));
|
||||||
|
elytra.write(Type.VAR_INT, 8);
|
||||||
|
elytra.write(Type.VAR_INT, 0);
|
||||||
|
PacketUtil.sendToServer(elytra, Protocol1_8TO1_9.class, true, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Steer Vehicle
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_8.STEER_VEHICLE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
int playerId = tracker.getPlayerId();
|
||||||
|
int vehicle = tracker.getVehicle(playerId);
|
||||||
|
if (vehicle != -1 && tracker.getClientEntityTypes().get(vehicle) == Entity1_10Types.EntityType.BOAT) {
|
||||||
|
PacketWrapper steerBoat = PacketWrapper.create(0x11, null, packetWrapper.user());
|
||||||
|
float left = packetWrapper.get(Type.FLOAT, 0);
|
||||||
|
float forward = packetWrapper.get(Type.FLOAT, 1);
|
||||||
|
steerBoat.write(Type.BOOLEAN, forward != 0.0f || left < 0.0f);
|
||||||
|
steerBoat.write(Type.BOOLEAN, forward != 0.0f || left > 0.0f);
|
||||||
|
PacketUtil.sendToServer(steerBoat, Protocol1_8TO1_9.class);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Update Sign
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_8.UPDATE_SIGN, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.POSITION);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
packetWrapper.write(Type.STRING, ChatUtil.jsonToLegacy(packetWrapper.read(Type.COMPONENT)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Player Abilities
|
||||||
|
|
||||||
|
//Tab Complete
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_8.TAB_COMPLETE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.STRING);
|
||||||
|
handler(packetWrapper -> packetWrapper.write(Type.BOOLEAN, false));
|
||||||
|
map(Type.OPTIONAL_POSITION);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Client Settings
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_8.CLIENT_SETTINGS, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.STRING);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.BYTE, Type.VAR_INT);
|
||||||
|
map(Type.BOOLEAN);
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
create(Type.VAR_INT, 1);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
short flags = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
|
||||||
|
|
||||||
|
PacketWrapper updateSkin = PacketWrapper.create(0x1C, null, packetWrapper.user());
|
||||||
|
updateSkin.write(Type.VAR_INT, packetWrapper.user().get(EntityTracker.class).getPlayerId());
|
||||||
|
|
||||||
|
ArrayList<Metadata> metadata = new ArrayList<>();
|
||||||
|
metadata.add(new Metadata(10, MetaType1_8.Byte, (byte) flags));
|
||||||
|
|
||||||
|
updateSkin.write(Types1_8.METADATA_LIST, metadata);
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(updateSkin, Protocol1_8TO1_9.class);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Client Status
|
||||||
|
|
||||||
|
//Custom Payload
|
||||||
|
protocol.registerServerbound(ServerboundPackets1_8.PLUGIN_MESSAGE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.STRING);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
String channel = packetWrapper.get(Type.STRING, 0);
|
||||||
|
if (channel.equalsIgnoreCase("MC|BEdit") || channel.equalsIgnoreCase("MC|BSign")) {
|
||||||
|
Item book = packetWrapper.passthrough(Type.ITEM);
|
||||||
|
book.setIdentifier(386);
|
||||||
|
CompoundTag tag = book.tag();
|
||||||
|
if (tag.contains("pages")) {
|
||||||
|
ListTag pages = tag.get("pages");
|
||||||
|
if (pages.size() > ViaRewind.getConfig().getMaxBookPages()) {
|
||||||
|
packetWrapper.user().disconnect("Too many book pages");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < pages.size(); i++) {
|
||||||
|
StringTag page = pages.get(i);
|
||||||
|
String value = page.getValue();
|
||||||
|
if (value.length() > ViaRewind.getConfig().getMaxBookPageSize()) {
|
||||||
|
packetWrapper.user().disconnect("Book page too large");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
value = ChatUtil.jsonToLegacy(value);
|
||||||
|
page.setValue(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (channel.equalsIgnoreCase("MC|AdvCdm")) {
|
||||||
|
packetWrapper.set(Type.STRING, 0, channel = "MC|AdvCmd");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Spectate
|
||||||
|
//Resource Pack Status
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.packets;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.Protocol;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.remapper.PacketRemapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_8.ServerboundPackets1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9to1_8.ServerboundPackets1_9;
|
||||||
|
|
||||||
|
public class ScoreboardPackets {
|
||||||
|
|
||||||
|
public static void register(Protocol<ClientboundPackets1_9, ClientboundPackets1_8,
|
||||||
|
ServerboundPackets1_9, ServerboundPackets1_8> protocol) {
|
||||||
|
/* OUTGOING */
|
||||||
|
|
||||||
|
//Display Scoreboard
|
||||||
|
//Scoreboard Objective
|
||||||
|
|
||||||
|
//Scoreboard Team
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.TEAMS, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.STRING);
|
||||||
|
map(Type.BYTE);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
byte mode = packetWrapper.get(Type.BYTE, 0);
|
||||||
|
if (mode == 0 || mode == 2) {
|
||||||
|
packetWrapper.passthrough(Type.STRING); //Display Name
|
||||||
|
packetWrapper.passthrough(Type.STRING); //Prefix
|
||||||
|
packetWrapper.passthrough(Type.STRING); //Suffix
|
||||||
|
packetWrapper.passthrough(Type.BYTE); //Friendly Flags
|
||||||
|
packetWrapper.passthrough(Type.STRING); //Name Tag Visibility
|
||||||
|
packetWrapper.read(Type.STRING); //Skip Collision Rule
|
||||||
|
packetWrapper.passthrough(Type.BYTE); //Friendly Flags
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == 0 || mode == 3 || mode == 4) {
|
||||||
|
packetWrapper.passthrough(Type.STRING_ARRAY);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Update Score
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,263 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.packets;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.ViaRewind;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.Protocol1_8TO1_9;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.entityreplacement.ShulkerBulletReplacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.entityreplacement.ShulkerReplacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.items.ReplacementRegistry1_8to1_9;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.metadata.MetadataRewriter;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.storage.EntityTracker;
|
||||||
|
import com.elevatemc.spigot.viarewind.replacement.EntityReplacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.replacement.Replacement;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.PacketUtil;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.entities.Entity1_10Types;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.Metadata;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.Protocol;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.remapper.PacketRemapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.types.version.Types1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.types.version.Types1_9;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_8.ServerboundPackets1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9to1_8.ServerboundPackets1_9;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SpawnPackets {
|
||||||
|
|
||||||
|
public static void register(Protocol<ClientboundPackets1_9, ClientboundPackets1_8,
|
||||||
|
ServerboundPackets1_9, ServerboundPackets1_8> protocol) {
|
||||||
|
/* OUTGOING */
|
||||||
|
|
||||||
|
//Spawn Object
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.SPAWN_ENTITY, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.UUID, Type.NOTHING);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.DOUBLE, Protocol1_8TO1_9.TO_OLD_INT);
|
||||||
|
map(Type.DOUBLE, Protocol1_8TO1_9.TO_OLD_INT);
|
||||||
|
map(Type.DOUBLE, Protocol1_8TO1_9.TO_OLD_INT);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.INT);
|
||||||
|
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
final int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
final int typeId = packetWrapper.get(Type.BYTE, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
final Entity1_10Types.EntityType type = Entity1_10Types.getTypeFromId(typeId, true);
|
||||||
|
|
||||||
|
//cancel AREA_EFFECT_CLOUD = 3, SPECTRAL_ARROW = 91, DRAGON_FIREBALL = 93
|
||||||
|
if (typeId == 3 || typeId == 91 || typeId == 92 || typeId == 93) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == null) {
|
||||||
|
ViaRewind.getPlatform().getLogger().warning("[ViaRewind] Unhandled Spawn Object Type: " + typeId);
|
||||||
|
packetWrapper.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x = packetWrapper.get(Type.INT, 0);
|
||||||
|
int y = packetWrapper.get(Type.INT, 1);
|
||||||
|
int z = packetWrapper.get(Type.INT, 2);
|
||||||
|
|
||||||
|
if (type.is(Entity1_10Types.EntityType.BOAT)) {
|
||||||
|
byte yaw = packetWrapper.get(Type.BYTE, 1);
|
||||||
|
yaw -= 64;
|
||||||
|
packetWrapper.set(Type.BYTE, 1, yaw);
|
||||||
|
y += 10;
|
||||||
|
packetWrapper.set(Type.INT, 1, y);
|
||||||
|
} else if (type.is(Entity1_10Types.EntityType.SHULKER_BULLET)) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
ShulkerBulletReplacement shulkerBulletReplacement = new ShulkerBulletReplacement(entityId, packetWrapper.user());
|
||||||
|
shulkerBulletReplacement.setLocation(x / 32.0, y / 32.0, z / 32.0);
|
||||||
|
tracker.addEntityReplacement(shulkerBulletReplacement);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int data = packetWrapper.get(Type.INT, 3);
|
||||||
|
|
||||||
|
//Rewrite Object Data
|
||||||
|
if (type.isOrHasParent(Entity1_10Types.EntityType.ARROW) && data != 0) {
|
||||||
|
packetWrapper.set(Type.INT, 3, --data);
|
||||||
|
}
|
||||||
|
if (type.is(Entity1_10Types.EntityType.FALLING_BLOCK)) {
|
||||||
|
int blockId = data & 0xFFF;
|
||||||
|
int blockData = data >> 12 & 0xF;
|
||||||
|
Replacement replace = ReplacementRegistry1_8to1_9.getReplacement(blockId, blockData);
|
||||||
|
if (replace != null) {
|
||||||
|
packetWrapper.set(Type.INT, 3, replace.getId() | replace.replaceData(data) << 12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data > 0) {
|
||||||
|
packetWrapper.passthrough(Type.SHORT);
|
||||||
|
packetWrapper.passthrough(Type.SHORT);
|
||||||
|
packetWrapper.passthrough(Type.SHORT);
|
||||||
|
} else {
|
||||||
|
short vX = packetWrapper.read(Type.SHORT);
|
||||||
|
short vY = packetWrapper.read(Type.SHORT);
|
||||||
|
short vZ = packetWrapper.read(Type.SHORT);
|
||||||
|
PacketWrapper velocityPacket = PacketWrapper.create(0x12, null, packetWrapper.user());
|
||||||
|
velocityPacket.write(Type.VAR_INT, entityId);
|
||||||
|
velocityPacket.write(Type.SHORT, vX);
|
||||||
|
velocityPacket.write(Type.SHORT, vY);
|
||||||
|
velocityPacket.write(Type.SHORT, vZ);
|
||||||
|
PacketUtil.sendPacket(velocityPacket, Protocol1_8TO1_9.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
tracker.getClientEntityTypes().put(entityId, type);
|
||||||
|
tracker.sendMetadataBuffer(entityId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Spawn Experience Orb
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.SPAWN_EXPERIENCE_ORB, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.DOUBLE, Protocol1_8TO1_9.TO_OLD_INT);
|
||||||
|
map(Type.DOUBLE, Protocol1_8TO1_9.TO_OLD_INT);
|
||||||
|
map(Type.DOUBLE, Protocol1_8TO1_9.TO_OLD_INT);
|
||||||
|
map(Type.SHORT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
tracker.getClientEntityTypes().put(entityId, Entity1_10Types.EntityType.EXPERIENCE_ORB);
|
||||||
|
tracker.sendMetadataBuffer(entityId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Spawn Global Entity
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.SPAWN_GLOBAL_ENTITY, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.DOUBLE, Protocol1_8TO1_9.TO_OLD_INT);
|
||||||
|
map(Type.DOUBLE, Protocol1_8TO1_9.TO_OLD_INT);
|
||||||
|
map(Type.DOUBLE, Protocol1_8TO1_9.TO_OLD_INT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
tracker.getClientEntityTypes().put(entityId, Entity1_10Types.EntityType.LIGHTNING);
|
||||||
|
tracker.sendMetadataBuffer(entityId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Spawn Mob
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.SPAWN_MOB, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.UUID, Type.NOTHING);
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
map(Type.DOUBLE, Protocol1_8TO1_9.TO_OLD_INT);
|
||||||
|
map(Type.DOUBLE, Protocol1_8TO1_9.TO_OLD_INT);
|
||||||
|
map(Type.DOUBLE, Protocol1_8TO1_9.TO_OLD_INT);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.SHORT);
|
||||||
|
map(Type.SHORT);
|
||||||
|
map(Type.SHORT);
|
||||||
|
map(Types1_9.METADATA_LIST, Types1_8.METADATA_LIST);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
int typeId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
|
||||||
|
int x = packetWrapper.get(Type.INT, 0);
|
||||||
|
int y = packetWrapper.get(Type.INT, 1);
|
||||||
|
int z = packetWrapper.get(Type.INT, 2);
|
||||||
|
byte pitch = packetWrapper.get(Type.BYTE, 1);
|
||||||
|
byte yaw = packetWrapper.get(Type.BYTE, 0);
|
||||||
|
byte headYaw = packetWrapper.get(Type.BYTE, 2);
|
||||||
|
|
||||||
|
if (typeId == 69) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
ShulkerReplacement shulkerReplacement = new ShulkerReplacement(entityId, packetWrapper.user());
|
||||||
|
shulkerReplacement.setLocation(x / 32.0, y / 32.0, z / 32.0);
|
||||||
|
shulkerReplacement.setYawPitch(yaw * 360f / 256, pitch * 360f / 256);
|
||||||
|
shulkerReplacement.setHeadYaw(headYaw * 360f / 256);
|
||||||
|
tracker.addEntityReplacement(shulkerReplacement);
|
||||||
|
} else if (typeId == -1 || typeId == 255) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
int typeId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
tracker.getClientEntityTypes().put(entityId, Entity1_10Types.getTypeFromId(typeId, false));
|
||||||
|
tracker.sendMetadataBuffer(entityId);
|
||||||
|
});
|
||||||
|
handler(wrapper -> {
|
||||||
|
List<Metadata> metadataList = wrapper.get(Types1_8.METADATA_LIST, 0);
|
||||||
|
int entityId = wrapper.get(Type.VAR_INT, 0);
|
||||||
|
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
|
||||||
|
EntityReplacement replacement;
|
||||||
|
if ((replacement = tracker.getEntityReplacement(entityId)) != null) {
|
||||||
|
replacement.updateMetadata(metadataList);
|
||||||
|
} else if (tracker.getClientEntityTypes().containsKey(entityId)) {
|
||||||
|
MetadataRewriter.transform(tracker.getClientEntityTypes().get(entityId), metadataList);
|
||||||
|
} else {
|
||||||
|
wrapper.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Spawn Painting
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.SPAWN_PAINTING, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.UUID, Type.NOTHING);
|
||||||
|
map(Type.STRING);
|
||||||
|
map(Type.POSITION);
|
||||||
|
map(Type.BYTE, Type.UNSIGNED_BYTE);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
tracker.getClientEntityTypes().put(entityId, Entity1_10Types.EntityType.PAINTING);
|
||||||
|
tracker.sendMetadataBuffer(entityId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Spawn Player
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.SPAWN_PLAYER, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.UUID);
|
||||||
|
map(Type.DOUBLE, Protocol1_8TO1_9.TO_OLD_INT);
|
||||||
|
map(Type.DOUBLE, Protocol1_8TO1_9.TO_OLD_INT);
|
||||||
|
map(Type.DOUBLE, Protocol1_8TO1_9.TO_OLD_INT);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.BYTE);
|
||||||
|
handler(packetWrapper -> packetWrapper.write(Type.SHORT, (short) 0));
|
||||||
|
map(Types1_9.METADATA_LIST, Types1_8.METADATA_LIST);
|
||||||
|
this.handler(wrapper -> {
|
||||||
|
List<Metadata> metadataList = wrapper.get(Types1_8.METADATA_LIST, 0);
|
||||||
|
MetadataRewriter.transform(Entity1_10Types.EntityType.PLAYER, metadataList);
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int entityId = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
|
||||||
|
tracker.getClientEntityTypes().put(entityId, Entity1_10Types.EntityType.PLAYER);
|
||||||
|
tracker.sendMetadataBuffer(entityId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,324 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.packets;
|
||||||
|
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||||
|
import com.elevatemc.spigot.viarewind.ViaRewind;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.Protocol1_8TO1_9;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.items.ReplacementRegistry1_8to1_9;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.sound.Effect;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.sound.SoundRemapper;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.PacketUtil;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.BlockChangeRecord;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.Environment;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.Position;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.chunks.BaseChunk;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.chunks.Chunk;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.chunks.ChunkSection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.chunks.ChunkSectionImpl;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.Protocol;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.remapper.PacketRemapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_8.ServerboundPackets1_8;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9_3to1_9_1_2.types.Chunk1_9_1_2Type;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9to1_8.ServerboundPackets1_9;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9to1_8.types.Chunk1_8Type;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class WorldPackets {
|
||||||
|
|
||||||
|
public static void register(Protocol<ClientboundPackets1_9, ClientboundPackets1_8,
|
||||||
|
ServerboundPackets1_9, ServerboundPackets1_8> protocol) {
|
||||||
|
/* OUTGOING */
|
||||||
|
|
||||||
|
//Block Break Animation
|
||||||
|
|
||||||
|
//Update Block Entity
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.BLOCK_ENTITY_DATA, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.POSITION);
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
map(Type.NBT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
CompoundTag tag = packetWrapper.get(Type.NBT, 0);
|
||||||
|
if (tag != null && tag.contains("SpawnData")) {
|
||||||
|
String entity = (String) ((CompoundTag) tag.get("SpawnData")).get("id").getValue();
|
||||||
|
tag.remove("SpawnData");
|
||||||
|
tag.put("entityId", new StringTag(entity));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Block Action
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.BLOCK_ACTION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.POSITION);
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int block = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
if (block >= 219 && block <= 234) {
|
||||||
|
packetWrapper.set(Type.VAR_INT, 0, block = 130);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Block Change
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.BLOCK_CHANGE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.POSITION);
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int combined = packetWrapper.get(Type.VAR_INT, 0);
|
||||||
|
int replacedCombined = ReplacementRegistry1_8to1_9.replace(combined);
|
||||||
|
packetWrapper.set(Type.VAR_INT, 0, replacedCombined);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Server Difficulty
|
||||||
|
|
||||||
|
//Multi Block Change
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.MULTI_BLOCK_CHANGE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.BLOCK_CHANGE_RECORD_ARRAY);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
for (BlockChangeRecord record : packetWrapper.get(Type.BLOCK_CHANGE_RECORD_ARRAY, 0)) {
|
||||||
|
int replacedCombined = ReplacementRegistry1_8to1_9.replace(record.getBlockId());
|
||||||
|
record.setBlockId(replacedCombined);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Named Sound Effect
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.NAMED_SOUND, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.STRING);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
String name = packetWrapper.get(Type.STRING, 0);
|
||||||
|
name = SoundRemapper.getOldName(name);
|
||||||
|
if (name == null) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
} else {
|
||||||
|
packetWrapper.set(Type.STRING, 0, name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
map(Type.VAR_INT, Type.NOTHING);
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Explosion
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.EXPLOSION, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int count = packetWrapper.read(Type.INT);
|
||||||
|
packetWrapper.write(Type.INT, count);
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
packetWrapper.passthrough(Type.UNSIGNED_BYTE);
|
||||||
|
packetWrapper.passthrough(Type.UNSIGNED_BYTE);
|
||||||
|
packetWrapper.passthrough(Type.UNSIGNED_BYTE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Unload Chunk
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.UNLOAD_CHUNK, ClientboundPackets1_8.CHUNK_DATA, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int chunkX = packetWrapper.read(Type.INT);
|
||||||
|
int chunkZ = packetWrapper.read(Type.INT);
|
||||||
|
ClientWorld world = packetWrapper.user().get(ClientWorld.class);
|
||||||
|
packetWrapper.write(new Chunk1_8Type(world), new BaseChunk(chunkX, chunkZ, true, false, 0, new ChunkSection[16], null, new ArrayList<>()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Chunk Data
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.CHUNK_DATA, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
ClientWorld world = packetWrapper.user().get(ClientWorld.class);
|
||||||
|
|
||||||
|
Chunk chunk = packetWrapper.read(new Chunk1_9_1_2Type(world));
|
||||||
|
|
||||||
|
for (ChunkSection section : chunk.getSections()) {
|
||||||
|
if (section == null) continue;
|
||||||
|
for (int i = 0; i < section.getPaletteSize(); i++) {
|
||||||
|
int block = section.getPaletteEntry(i);
|
||||||
|
int replacedBlock = ReplacementRegistry1_8to1_9.replace(block);
|
||||||
|
section.setPaletteEntry(i, replacedBlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chunk.isFullChunk() && chunk.getBitmask() == 0) { //This would be an unload packet for 1.8 clients. Just set one air section
|
||||||
|
boolean skylight = world.getEnvironment() == Environment.NORMAL;
|
||||||
|
ChunkSection[] sections = new ChunkSection[16];
|
||||||
|
ChunkSection section = new ChunkSectionImpl(true);
|
||||||
|
sections[0] = section;
|
||||||
|
section.addPaletteEntry(0);
|
||||||
|
if (skylight) section.getLight().setSkyLight(new byte[2048]);
|
||||||
|
chunk = new BaseChunk(chunk.getX(), chunk.getZ(), true, false, 1, sections, chunk.getBiomeData(), chunk.getBlockEntities());
|
||||||
|
}
|
||||||
|
|
||||||
|
packetWrapper.write(new Chunk1_8Type(world), chunk);
|
||||||
|
|
||||||
|
final UserConnection user = packetWrapper.user();
|
||||||
|
chunk.getBlockEntities().forEach(nbt -> {
|
||||||
|
if (!nbt.contains("x") || !nbt.contains("y") || !nbt.contains("z") || !nbt.contains("id"))
|
||||||
|
return;
|
||||||
|
Position position = new Position((int) nbt.get("x").getValue(), (short) (int) nbt.get("y").getValue(), (int) nbt.get("z").getValue());
|
||||||
|
String id = (String) nbt.get("id").getValue();
|
||||||
|
|
||||||
|
short action;
|
||||||
|
switch (id) {
|
||||||
|
case "minecraft:mob_spawner":
|
||||||
|
action = 1;
|
||||||
|
break;
|
||||||
|
case "minecraft:command_block":
|
||||||
|
action = 2;
|
||||||
|
break;
|
||||||
|
case "minecraft:beacon":
|
||||||
|
action = 3;
|
||||||
|
break;
|
||||||
|
case "minecraft:skull":
|
||||||
|
action = 4;
|
||||||
|
break;
|
||||||
|
case "minecraft:flower_pot":
|
||||||
|
action = 5;
|
||||||
|
break;
|
||||||
|
case "minecraft:banner":
|
||||||
|
action = 6;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketWrapper updateTileEntity = PacketWrapper.create(0x09, null, user);
|
||||||
|
updateTileEntity.write(Type.POSITION, position);
|
||||||
|
updateTileEntity.write(Type.UNSIGNED_BYTE, action);
|
||||||
|
updateTileEntity.write(Type.NBT, nbt);
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(updateTileEntity, Protocol1_8TO1_9.class, false, false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Effect
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.EFFECT, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.POSITION);
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.BOOLEAN);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int id = packetWrapper.get(Type.INT, 0);
|
||||||
|
id = Effect.getOldId(id);
|
||||||
|
if (id == -1) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
packetWrapper.set(Type.INT, 0, id);
|
||||||
|
if (id == 2001) {
|
||||||
|
int replacedBlock = ReplacementRegistry1_8to1_9.replace(packetWrapper.get(Type.INT, 1));
|
||||||
|
packetWrapper.set(Type.INT, 1, replacedBlock);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Particle
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.SPAWN_PARTICLE, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.INT);
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int type = packetWrapper.get(Type.INT, 0);
|
||||||
|
if (type > 41 && !ViaRewind.getConfig().isReplaceParticles()) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (type == 42) { // Dragon Breath
|
||||||
|
packetWrapper.set(Type.INT, 0, 24); // Portal
|
||||||
|
} else if (type == 43) { // End Rod
|
||||||
|
packetWrapper.set(Type.INT, 0, 3); // Firework Spark
|
||||||
|
} else if (type == 44) { // Damage Indicator
|
||||||
|
packetWrapper.set(Type.INT, 0, 34); // Heart
|
||||||
|
} else if (type == 45) { // Sweep Attack
|
||||||
|
packetWrapper.set(Type.INT, 0, 1); // Large Explosion
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Map
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.MAP_DATA, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
map(Type.VAR_INT);
|
||||||
|
map(Type.BYTE);
|
||||||
|
map(Type.BOOLEAN, Type.NOTHING);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Combat Event
|
||||||
|
//World Border
|
||||||
|
//Update Time
|
||||||
|
//Update Sign
|
||||||
|
|
||||||
|
//Sound Effects
|
||||||
|
protocol.registerClientbound(ClientboundPackets1_9.SOUND, ClientboundPackets1_8.NAMED_SOUND, new PacketRemapper() {
|
||||||
|
@Override
|
||||||
|
public void registerMap() {
|
||||||
|
handler(packetWrapper -> {
|
||||||
|
int soundId = packetWrapper.read(Type.VAR_INT);
|
||||||
|
String sound = SoundRemapper.oldNameFromId(soundId);
|
||||||
|
if (sound == null) {
|
||||||
|
packetWrapper.cancel();
|
||||||
|
} else {
|
||||||
|
packetWrapper.write(Type.STRING, sound);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
handler(packetWrapper -> packetWrapper.read(Type.VAR_INT));
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.INT);
|
||||||
|
map(Type.FLOAT);
|
||||||
|
map(Type.UNSIGNED_BYTE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.sound;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class Effect {
|
||||||
|
private static final HashMap<Integer, Integer> effects = new HashMap<>();
|
||||||
|
|
||||||
|
public static int getOldId(int id) {
|
||||||
|
return effects.getOrDefault(id, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
effects.put(1003, 1002);
|
||||||
|
effects.put(1005, 1003);
|
||||||
|
effects.put(1006, 1003);
|
||||||
|
effects.put(1007, 1003);
|
||||||
|
effects.put(1008, 1003);
|
||||||
|
effects.put(1009, 1004);
|
||||||
|
effects.put(1010, 1005);
|
||||||
|
effects.put(1011, 1006);
|
||||||
|
effects.put(1012, 1006);
|
||||||
|
effects.put(1013, 1006);
|
||||||
|
effects.put(1014, 1006);
|
||||||
|
effects.put(1015, 1007);
|
||||||
|
effects.put(1016, 1008);
|
||||||
|
effects.put(1017, 1008);
|
||||||
|
effects.put(1018, 1009);
|
||||||
|
effects.put(1019, 1010);
|
||||||
|
effects.put(1020, 1011);
|
||||||
|
effects.put(1021, 1012);
|
||||||
|
effects.put(1022, 1012);
|
||||||
|
effects.put(1023, 1013);
|
||||||
|
effects.put(1024, 1014);
|
||||||
|
effects.put(1025, 1015);
|
||||||
|
effects.put(1026, 1016);
|
||||||
|
effects.put(1027, 1017);
|
||||||
|
effects.put(1028, 1018);
|
||||||
|
effects.put(1029, 1020);
|
||||||
|
effects.put(1030, 1021);
|
||||||
|
effects.put(1031, 1022);
|
||||||
|
effects.put(1032, -1);
|
||||||
|
effects.put(1033, -1);
|
||||||
|
effects.put(1034, -1);
|
||||||
|
effects.put(1035, -1);
|
||||||
|
effects.put(1036, 1003);
|
||||||
|
effects.put(1037, 1006);
|
||||||
|
|
||||||
|
effects.put(3000, -1);
|
||||||
|
effects.put(3001, -1);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,867 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.sound;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class SoundRemapper {
|
||||||
|
private static final HashMap<Integer, String> sounds1_9 = new HashMap<>();
|
||||||
|
private static final HashMap<String, String> sound1_9to1_8 = new HashMap<>();
|
||||||
|
private static int id;
|
||||||
|
|
||||||
|
private static void register1_9Sound(String sound1_9) {
|
||||||
|
sounds1_9.put(id++, sound1_9);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void registerSoundRemapping(String sound1_9, String sound1_8) {
|
||||||
|
sound1_9to1_8.put(sound1_9, sound1_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String oldNameFromId(int id) {
|
||||||
|
String sound1_9 = sounds1_9.get(id);
|
||||||
|
if (sound1_9==null) return null;
|
||||||
|
return getOldName(sound1_9);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getOldName(String sound1_9) {
|
||||||
|
return sound1_9to1_8.getOrDefault(sound1_9, sound1_9);
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
registerSoundRemapping("entity.zombie_horse.ambient", "mob.horse.zombie.idle");
|
||||||
|
registerSoundRemapping("block.note.snare", "note.snare");
|
||||||
|
registerSoundRemapping("block.wood_button.click_off", "random.wood_click");
|
||||||
|
registerSoundRemapping("block.wood_button.click_on", "random.wood_click");
|
||||||
|
registerSoundRemapping("block.gravel.break", "dig.gravel");
|
||||||
|
registerSoundRemapping("block.gravel.place", "dig.gravel");
|
||||||
|
registerSoundRemapping("entity.arrow.hit", "random.bowhit");
|
||||||
|
registerSoundRemapping("block.tripwire.detach", "random.bowhit");
|
||||||
|
registerSoundRemapping("entity.splash_potion.break", "dig.glass");
|
||||||
|
registerSoundRemapping("block.glass.break", "dig.glass");
|
||||||
|
registerSoundRemapping("entity.zombie.ambient", "mob.zombie.say");
|
||||||
|
registerSoundRemapping("entity.zombie_villager.ambient", "mob.zombie.say");
|
||||||
|
registerSoundRemapping("entity.pig.death", "mob.pig.death");
|
||||||
|
registerSoundRemapping("entity.mule.hurt", "mob.horse.donkey.hit");
|
||||||
|
registerSoundRemapping("entity.donkey.hurt", "mob.horse.donkey.hit");
|
||||||
|
registerSoundRemapping("entity.endermen.ambient", "mob.endermen.idle");
|
||||||
|
registerSoundRemapping("block.portal.ambient", "portal.portal");
|
||||||
|
registerSoundRemapping("entity.generic.burn", "random.fizz");
|
||||||
|
registerSoundRemapping("block.fire.extinguish", "random.fizz");
|
||||||
|
registerSoundRemapping("block.redstone_torch.burnout", "random.fizz");
|
||||||
|
registerSoundRemapping("block.lava.extinguish", "random.fizz");
|
||||||
|
registerSoundRemapping("entity.generic.extinguish_fire", "random.fizz");
|
||||||
|
registerSoundRemapping("block.note.harp", "note.harp");
|
||||||
|
registerSoundRemapping("block.snow.hit", "step.snow");
|
||||||
|
registerSoundRemapping("block.snow.fall", "step.snow");
|
||||||
|
registerSoundRemapping("block.snow.step", "step.snow");
|
||||||
|
registerSoundRemapping("entity.arrow.hit_player", "random.successful_hit");
|
||||||
|
registerSoundRemapping("entity.zombie_pig.hurt", "mob.zombiepig.zpighurt");
|
||||||
|
registerSoundRemapping("entity.wolf.howl", "mob.wolf.howl");
|
||||||
|
registerSoundRemapping("entity.firework.launch", "fireworks.launch");
|
||||||
|
registerSoundRemapping("entity.cow.hurt", "mob.cow.hurt");
|
||||||
|
registerSoundRemapping("entity.cow.death", "mob.cow.hurt");
|
||||||
|
registerSoundRemapping("entity.firework.large_blast", "fireworks.largeBlast");
|
||||||
|
registerSoundRemapping("entity.blaze.hurt", "mob.blaze.hit");
|
||||||
|
registerSoundRemapping("entity.villager.death", "mob.villager.death");
|
||||||
|
registerSoundRemapping("entity.blaze.death", "mob.blaze.death");
|
||||||
|
registerSoundRemapping("entity.zombie_horse.death", "mob.horse.zombie.death");
|
||||||
|
registerSoundRemapping("entity.silverfish.death", "mob.silverfish.kill");
|
||||||
|
registerSoundRemapping("entity.endermite.death", "mob.silverfish.kill");
|
||||||
|
registerSoundRemapping("record.ward", "records.ward");
|
||||||
|
registerSoundRemapping("entity.wolf.pant", "mob.wolf.panting");
|
||||||
|
registerSoundRemapping("block.metal.break", "dig.stone");
|
||||||
|
registerSoundRemapping("block.metal.place", "dig.stone");
|
||||||
|
registerSoundRemapping("entity.armorstand.place", "dig.stone");
|
||||||
|
registerSoundRemapping("block.stone.break", "dig.stone");
|
||||||
|
registerSoundRemapping("block.stone.place", "dig.stone");
|
||||||
|
registerSoundRemapping("block.anvil.break", "dig.stone");
|
||||||
|
registerSoundRemapping("block.glass.place", "dig.stone");
|
||||||
|
registerSoundRemapping("entity.endermen.stare", "mob.endermen.stare");
|
||||||
|
registerSoundRemapping("entity.small_magmacube.hurt", "mob.slime.small");
|
||||||
|
registerSoundRemapping("block.slime.fall", "mob.slime.small");
|
||||||
|
registerSoundRemapping("entity.small_slime.death", "mob.slime.small");
|
||||||
|
registerSoundRemapping("block.slime.step", "mob.slime.small");
|
||||||
|
registerSoundRemapping("entity.small_magmacube.death", "mob.slime.small");
|
||||||
|
registerSoundRemapping("entity.small_slime.hurt", "mob.slime.small");
|
||||||
|
registerSoundRemapping("block.slime.hit", "mob.slime.small");
|
||||||
|
registerSoundRemapping("music.nether", "music.game.nether");
|
||||||
|
registerSoundRemapping("entity.ghast.death", "mob.ghast.death");
|
||||||
|
registerSoundRemapping("entity.guardian.attack", "mob.guardian.attack");
|
||||||
|
registerSoundRemapping("block.dispenser.fail", "random.click");
|
||||||
|
registerSoundRemapping("block.comparator.click", "random.click");
|
||||||
|
registerSoundRemapping("block.stone_button.click_on", "random.click");
|
||||||
|
registerSoundRemapping("block.stone_button.click_off", "random.click");
|
||||||
|
registerSoundRemapping("block.tripwire.click_on", "random.click");
|
||||||
|
registerSoundRemapping("block.dispenser.dispense", "random.click");
|
||||||
|
registerSoundRemapping("ui.button.click", "random.click");
|
||||||
|
registerSoundRemapping("block.lever.click", "random.click");
|
||||||
|
registerSoundRemapping("block.tripwire.attach", "random.click");
|
||||||
|
registerSoundRemapping("block.stone_pressureplate.click_on", "random.click");
|
||||||
|
registerSoundRemapping("block.wood_pressureplate.click_off", "random.click");
|
||||||
|
registerSoundRemapping("block.stone_pressureplate.click_off", "random.click");
|
||||||
|
registerSoundRemapping("block.metal_pressureplate.click_off", "random.click");
|
||||||
|
registerSoundRemapping("block.tripwire.click_off", "random.click");
|
||||||
|
registerSoundRemapping("block.metal_pressureplate.click_on", "random.click");
|
||||||
|
registerSoundRemapping("block.wood_pressureplate.click_on", "random.click");
|
||||||
|
registerSoundRemapping("entity.zombie_pig.ambient", "mob.zombiepig.zpig");
|
||||||
|
registerSoundRemapping("music.dragon", "music.game.end.dragon");
|
||||||
|
registerSoundRemapping("entity.firework.twinkle_far", "fireworks.twinkle_far");
|
||||||
|
registerSoundRemapping("entity.elder_guardian.ambient_land", "mob.guardian.land.idle");
|
||||||
|
registerSoundRemapping("entity.guardian.ambient_land", "mob.guardian.land.idle");
|
||||||
|
registerSoundRemapping("block.grass.break", "dig.grass");
|
||||||
|
registerSoundRemapping("block.grass.place", "dig.grass");
|
||||||
|
registerSoundRemapping("entity.skeleton.step", "mob.skeleton.step");
|
||||||
|
registerSoundRemapping("entity.wither.death", "mob.wither.death");
|
||||||
|
registerSoundRemapping("entity.wolf.hurt", "mob.wolf.hurt");
|
||||||
|
registerSoundRemapping("entity.pig.saddle", "mob.horse.leather");
|
||||||
|
registerSoundRemapping("entity.horse.saddle", "mob.horse.leather");
|
||||||
|
registerSoundRemapping("entity.bat.loop", "mob.bat.loop");
|
||||||
|
registerSoundRemapping("entity.ghast.hurt", "mob.ghast.scream");
|
||||||
|
registerSoundRemapping("entity.creeper.death", "mob.creeper.death");
|
||||||
|
registerSoundRemapping("entity.horse.gallop", "mob.horse.gallop");
|
||||||
|
registerSoundRemapping("entity.wither.spawn", "mob.wither.spawn");
|
||||||
|
registerSoundRemapping("entity.endermen.hurt", "mob.endermen.hit");
|
||||||
|
registerSoundRemapping("entity.creeper.hurt", "mob.creeper.say");
|
||||||
|
registerSoundRemapping("entity.horse.step_wood", "mob.horse.wood");
|
||||||
|
registerSoundRemapping("entity.rabbit.death", "mob.rabbit.death");
|
||||||
|
registerSoundRemapping("entity.zombie_villager.converted", "mob.zombie.unfect");
|
||||||
|
registerSoundRemapping("block.anvil.use", "random.anvil_use");
|
||||||
|
registerSoundRemapping("block.enderchest.close", "random.chestclosed");
|
||||||
|
registerSoundRemapping("entity.mooshroom.shear", "mob.sheep.shear");
|
||||||
|
registerSoundRemapping("entity.sheep.shear", "mob.sheep.shear");
|
||||||
|
registerSoundRemapping("entity.item.pickup", "random.pop");
|
||||||
|
registerSoundRemapping("entity.bat.death", "mob.bat.death");
|
||||||
|
registerSoundRemapping("block.wood.place", "dig.wood");
|
||||||
|
registerSoundRemapping("block.wood.break", "dig.wood");
|
||||||
|
registerSoundRemapping("block.ladder.place", "dig.wood");
|
||||||
|
registerSoundRemapping("entity.armorstand.fall", "dig.wood");
|
||||||
|
registerSoundRemapping("block.ladder.break", "dig.wood");
|
||||||
|
registerSoundRemapping("record.chirp", "records.chirp");
|
||||||
|
registerSoundRemapping("entity.mule.death", "mob.horse.donkey.death");
|
||||||
|
registerSoundRemapping("entity.donkey.death", "mob.horse.donkey.death");
|
||||||
|
registerSoundRemapping("entity.firework.blast", "fireworks.blast");
|
||||||
|
registerSoundRemapping("entity.zombie_pig.angry", "mob.zombiepig.zpigangry");
|
||||||
|
registerSoundRemapping("entity.guardian.flop", "mob.guardian.flop");
|
||||||
|
registerSoundRemapping("entity.villager.yes", "mob.villager.yes");
|
||||||
|
registerSoundRemapping("entity.ghast.warn", "mob.ghast.charge");
|
||||||
|
registerSoundRemapping("entity.tnt.primed", "creeper.primed");
|
||||||
|
registerSoundRemapping("entity.creeper.primed", "creeper.primed");
|
||||||
|
registerSoundRemapping("block.sand.place", "dig.sand");
|
||||||
|
registerSoundRemapping("block.sand.break", "dig.sand");
|
||||||
|
registerSoundRemapping("entity.chicken.ambient", "mob.chicken.say");
|
||||||
|
registerSoundRemapping("record.13", "records.13");
|
||||||
|
registerSoundRemapping("record.11", "records.11");
|
||||||
|
registerSoundRemapping("entity.elder_guardian.death", "mob.guardian.elder.death");
|
||||||
|
registerSoundRemapping("entity.firework.twinkle", "fireworks.twinkle");
|
||||||
|
registerSoundRemapping("entity.skeleton_horse.death", "mob.horse.skeleton.death");
|
||||||
|
registerSoundRemapping("weather.rain", "ambient.weather.rain");
|
||||||
|
registerSoundRemapping("weather.rain.above", "ambient.weather.rain");
|
||||||
|
registerSoundRemapping("block.portal.trigger", "portal.trigger");
|
||||||
|
registerSoundRemapping("block.enderchest.open", "random.chestopen");
|
||||||
|
registerSoundRemapping("entity.horse.land", "mob.horse.land");
|
||||||
|
registerSoundRemapping("entity.endermite.step", "mob.silverfish.step");
|
||||||
|
registerSoundRemapping("entity.silverfish.step", "mob.silverfish.step");
|
||||||
|
registerSoundRemapping("entity.bat.takeoff", "mob.bat.takeoff");
|
||||||
|
registerSoundRemapping("entity.villager.no", "mob.villager.no");
|
||||||
|
registerSoundRemapping("entity.irongolem.step", "mob.irongolem.walk");
|
||||||
|
registerSoundRemapping("block.note.hat", "note.hat");
|
||||||
|
registerSoundRemapping("entity.zombie.attack_iron_door", "mob.zombie.metal");
|
||||||
|
registerSoundRemapping("entity.villager.trading", "mob.villager.haggle");
|
||||||
|
registerSoundRemapping("item.firecharge.use", "mob.ghast.fireball");
|
||||||
|
registerSoundRemapping("entity.ghast.shoot", "mob.ghast.fireball");
|
||||||
|
registerSoundRemapping("entity.enderdragon.shoot", "mob.ghast.fireball");
|
||||||
|
registerSoundRemapping("entity.blaze.shoot", "mob.ghast.fireball");
|
||||||
|
registerSoundRemapping("music.credits", "music.game.end.credits");
|
||||||
|
registerSoundRemapping("entity.irongolem.death", "mob.irongolem.death");
|
||||||
|
registerSoundRemapping("entity.item.break", "random.break");
|
||||||
|
registerSoundRemapping("item.shield.break", "random.break");
|
||||||
|
registerSoundRemapping("record.mellohi", "records.mellohi");
|
||||||
|
registerSoundRemapping("entity.zombie_villager.cure", "mob.zombie.remedy");
|
||||||
|
registerSoundRemapping("entity.enderpearl.throw", "random.bow");
|
||||||
|
registerSoundRemapping("block.dispenser.launch", "random.bow");
|
||||||
|
registerSoundRemapping("entity.skeleton.shoot", "random.bow");
|
||||||
|
registerSoundRemapping("entity.endereye.launch", "random.bow");
|
||||||
|
registerSoundRemapping("entity.firework.shoot", "random.bow");
|
||||||
|
registerSoundRemapping("entity.experience_bottle.throw", "random.bow");
|
||||||
|
registerSoundRemapping("entity.snowman.shoot", "random.bow");
|
||||||
|
registerSoundRemapping("entity.arrow.shoot", "random.bow");
|
||||||
|
registerSoundRemapping("entity.egg.throw", "random.bow");
|
||||||
|
registerSoundRemapping("entity.snowball.throw", "random.bow");
|
||||||
|
registerSoundRemapping("entity.bobber.throw", "random.bow");
|
||||||
|
registerSoundRemapping("entity.lingeringpotion.throw", "random.bow");
|
||||||
|
registerSoundRemapping("entity.splash_potion.throw", "random.bow");
|
||||||
|
registerSoundRemapping("entity.villager.ambient", "mob.villager.idle");
|
||||||
|
registerSoundRemapping("block.cloth.hit", "step.cloth");
|
||||||
|
registerSoundRemapping("block.cloth.step", "step.cloth");
|
||||||
|
registerSoundRemapping("block.cloth.fall", "step.cloth");
|
||||||
|
registerSoundRemapping("entity.silverfish.hurt", "mob.silverfish.hit");
|
||||||
|
registerSoundRemapping("entity.endermite.hurt", "mob.silverfish.hit");
|
||||||
|
registerSoundRemapping("music.game", "music.game");
|
||||||
|
registerSoundRemapping("block.lava.ambient", "liquid.lava");
|
||||||
|
registerSoundRemapping("record.mall", "records.mall");
|
||||||
|
registerSoundRemapping("entity.blaze.burn", "fire.fire");
|
||||||
|
registerSoundRemapping("block.fire.ambient", "fire.fire");
|
||||||
|
registerSoundRemapping("entity.zombie.attack_door_wood", "mob.zombie.wood");
|
||||||
|
registerSoundRemapping("entity.chicken.step", "mob.chicken.step");
|
||||||
|
registerSoundRemapping("record.stal", "records.stal");
|
||||||
|
registerSoundRemapping("entity.elder_guardian.hurt_land", "mob.guardian.land.hit");
|
||||||
|
registerSoundRemapping("entity.guardian.hurt_land", "mob.guardian.land.hit");
|
||||||
|
registerSoundRemapping("entity.chicken.egg", "mob.chicken.plop");
|
||||||
|
registerSoundRemapping("entity.donkey.chest", "mob.chicken.plop");
|
||||||
|
registerSoundRemapping("entity.enderdragon.flap", "mob.enderdragon.wings");
|
||||||
|
registerSoundRemapping("block.grass.step", "step.grass");
|
||||||
|
registerSoundRemapping("block.grass.fall", "step.grass");
|
||||||
|
registerSoundRemapping("block.grass.hit", "step.grass");
|
||||||
|
registerSoundRemapping("entity.horse.breathe", "mob.horse.breathe");
|
||||||
|
registerSoundRemapping("entity.mule.ambient", "mob.horse.donkey.idle");
|
||||||
|
registerSoundRemapping("entity.donkey.ambient", "mob.horse.donkey.idle");
|
||||||
|
registerSoundRemapping("record.far", "records.far");
|
||||||
|
registerSoundRemapping("entity.spider.step", "mob.spider.step");
|
||||||
|
registerSoundRemapping("entity.cow.ambient", "mob.cow.say");
|
||||||
|
registerSoundRemapping("entity.horse.jump", "mob.horse.jump");
|
||||||
|
registerSoundRemapping("entity.horse.step", "mob.horse.soft");
|
||||||
|
registerSoundRemapping("entity.guardian.hurt", "mob.guardian.hit");
|
||||||
|
registerSoundRemapping("entity.enderdragon.death", "mob.enderdragon.end");
|
||||||
|
registerSoundRemapping("entity.zombie_villager.step", "mob.zombie.step");
|
||||||
|
registerSoundRemapping("entity.zombie.step", "mob.zombie.step");
|
||||||
|
registerSoundRemapping("entity.enderdragon.ambient", "mob.enderdragon.growl");
|
||||||
|
registerSoundRemapping("entity.enderdragon.growl", "mob.enderdragon.growl");
|
||||||
|
registerSoundRemapping("entity.wolf.shake", "mob.wolf.shake");
|
||||||
|
registerSoundRemapping("entity.endermen.death", "mob.endermen.death");
|
||||||
|
registerSoundRemapping("block.anvil.place", "random.anvil_land");
|
||||||
|
registerSoundRemapping("block.anvil.land", "random.anvil_land");
|
||||||
|
registerSoundRemapping("entity.minecart.inside", "minecart.inside");
|
||||||
|
registerSoundRemapping("entity.slime.squish", "mob.slime.big");
|
||||||
|
registerSoundRemapping("entity.magmacube.hurt", "mob.slime.big");
|
||||||
|
registerSoundRemapping("entity.magmacube.death", "mob.slime.big");
|
||||||
|
registerSoundRemapping("block.slime.break", "mob.slime.big");
|
||||||
|
registerSoundRemapping("block.slime.place", "mob.slime.big");
|
||||||
|
registerSoundRemapping("entity.slime.jump", "mob.slime.big");
|
||||||
|
registerSoundRemapping("entity.slime.hurt", "mob.slime.big");
|
||||||
|
registerSoundRemapping("entity.slime.death", "mob.slime.big");
|
||||||
|
registerSoundRemapping("block.water.ambient", "liquid.water");
|
||||||
|
registerSoundRemapping("entity.pig.hurt", "mob.pig.say");
|
||||||
|
registerSoundRemapping("entity.pig.ambient", "mob.pig.say");
|
||||||
|
registerSoundRemapping("entity.wither.shoot", "mob.wither.shoot");
|
||||||
|
registerSoundRemapping("record.blocks", "records.blocks");
|
||||||
|
registerSoundRemapping("item.firecharge.use", "item.fireCharge.use");
|
||||||
|
registerSoundRemapping("entity.ghast.shoot", "item.fireCharge.use");
|
||||||
|
registerSoundRemapping("entity.enderdragon.shoot", "item.fireCharge.use");
|
||||||
|
registerSoundRemapping("entity.blaze.shoot", "item.fireCharge.use");
|
||||||
|
registerSoundRemapping("block.sand.hit", "step.sand");
|
||||||
|
registerSoundRemapping("block.sand.step", "step.sand");
|
||||||
|
registerSoundRemapping("block.sand.fall", "step.sand");
|
||||||
|
registerSoundRemapping("music.creative", "music.game.creative");
|
||||||
|
registerSoundRemapping("entity.irongolem.hurt", "mob.irongolem.hit");
|
||||||
|
registerSoundRemapping("entity.horse.death", "mob.horse.death");
|
||||||
|
registerSoundRemapping("entity.bat.hurt", "mob.bat.hurt");
|
||||||
|
registerSoundRemapping("entity.ghast.scream", "mob.ghast.affectionate_scream");
|
||||||
|
registerSoundRemapping("entity.elder_guardian.ambient", "mob.guardian.elder.idle");
|
||||||
|
registerSoundRemapping("entity.zombie_pig.death", "mob.zombiepig.zpigdeath");
|
||||||
|
registerSoundRemapping("entity.lightning.thunder", "ambient.weather.thunder");
|
||||||
|
registerSoundRemapping("entity.minecart.riding", "minecart.base");
|
||||||
|
registerSoundRemapping("block.ladder.step", "step.ladder");
|
||||||
|
registerSoundRemapping("block.ladder.fall", "step.ladder");
|
||||||
|
registerSoundRemapping("block.ladder.hit", "step.ladder");
|
||||||
|
registerSoundRemapping("entity.donkey.angry", "mob.horse.donkey.angry");
|
||||||
|
registerSoundRemapping("ambient.cave", "ambient.cave.cave");
|
||||||
|
registerSoundRemapping("record.wait", "records.wait");
|
||||||
|
registerSoundRemapping("entity.firework.blast_far", "fireworks.blast_far");
|
||||||
|
registerSoundRemapping("entity.generic.drink", "random.drink");
|
||||||
|
registerSoundRemapping("music.menu", "music.menu");
|
||||||
|
registerSoundRemapping("entity.cat.hiss", "mob.cat.hiss");
|
||||||
|
registerSoundRemapping("block.note.basedrum", "note.bd");
|
||||||
|
registerSoundRemapping("entity.spider.ambient", "mob.spider.say");
|
||||||
|
registerSoundRemapping("entity.spider.hurt", "mob.spider.say");
|
||||||
|
registerSoundRemapping("block.stone.fall", "step.stone");
|
||||||
|
registerSoundRemapping("block.anvil.fall", "step.stone");
|
||||||
|
registerSoundRemapping("block.metal.step", "step.stone");
|
||||||
|
registerSoundRemapping("block.stone.hit", "step.stone");
|
||||||
|
registerSoundRemapping("block.glass.fall", "step.stone");
|
||||||
|
registerSoundRemapping("block.stone.step", "step.stone");
|
||||||
|
registerSoundRemapping("block.anvil.step", "step.stone");
|
||||||
|
registerSoundRemapping("block.metal.hit", "step.stone");
|
||||||
|
registerSoundRemapping("block.glass.step", "step.stone");
|
||||||
|
registerSoundRemapping("block.metal.fall", "step.stone");
|
||||||
|
registerSoundRemapping("block.glass.hit", "step.stone");
|
||||||
|
registerSoundRemapping("block.anvil.hit", "step.stone");
|
||||||
|
registerSoundRemapping("entity.player.levelup", "random.levelup");
|
||||||
|
registerSoundRemapping("block.lava.pop", "liquid.lavapop");
|
||||||
|
registerSoundRemapping("entity.sheep.hurt", "mob.sheep.say");
|
||||||
|
registerSoundRemapping("entity.sheep.death", "mob.sheep.say");
|
||||||
|
registerSoundRemapping("entity.sheep.ambient", "mob.sheep.say");
|
||||||
|
registerSoundRemapping("entity.skeleton.ambient", "mob.skeleton.say");
|
||||||
|
registerSoundRemapping("entity.blaze.ambient", "mob.blaze.breathe");
|
||||||
|
registerSoundRemapping("entity.bat.ambient", "mob.bat.idle");
|
||||||
|
registerSoundRemapping("entity.magmacube.squish", "mob.magmacube.big");
|
||||||
|
registerSoundRemapping("entity.horse.ambient", "mob.horse.idle");
|
||||||
|
registerSoundRemapping("entity.zombie_horse.hurt", "mob.horse.zombie.hit");
|
||||||
|
registerSoundRemapping("entity.irongolem.attack", "mob.irongolem.throw");
|
||||||
|
registerSoundRemapping("block.cloth.break", "dig.cloth");
|
||||||
|
registerSoundRemapping("block.cloth.place", "dig.cloth");
|
||||||
|
registerSoundRemapping("block.gravel.fall", "step.gravel");
|
||||||
|
registerSoundRemapping("block.gravel.step", "step.gravel");
|
||||||
|
registerSoundRemapping("block.gravel.hit", "step.gravel");
|
||||||
|
registerSoundRemapping("entity.endermite.ambient", "mob.silverfish.say");
|
||||||
|
registerSoundRemapping("entity.silverfish.ambient", "mob.silverfish.say");
|
||||||
|
registerSoundRemapping("entity.cat.purr", "mob.cat.purr");
|
||||||
|
registerSoundRemapping("entity.zombie.infect", "mob.zombie.infect");
|
||||||
|
registerSoundRemapping("entity.generic.eat", "random.eat");
|
||||||
|
registerSoundRemapping("entity.wolf.ambient", "mob.wolf.bark");
|
||||||
|
registerSoundRemapping("entity.tnt.primed", "game.tnt.primed");
|
||||||
|
registerSoundRemapping("entity.creeper.primed", "game.tnt.primed");
|
||||||
|
registerSoundRemapping("entity.sheep.step", "mob.sheep.step");
|
||||||
|
registerSoundRemapping("entity.zombie_villager.death", "mob.zombie.death");
|
||||||
|
registerSoundRemapping("entity.zombie.death", "mob.zombie.death");
|
||||||
|
registerSoundRemapping("entity.shulker.teleport", "mob.endermen.portal");
|
||||||
|
registerSoundRemapping("item.chorus_fruit.teleport", "mob.endermen.portal");
|
||||||
|
registerSoundRemapping("entity.endermen.teleport", "mob.endermen.portal");
|
||||||
|
registerSoundRemapping("entity.horse.angry", "mob.horse.angry");
|
||||||
|
registerSoundRemapping("entity.wolf.growl", "mob.wolf.growl");
|
||||||
|
registerSoundRemapping("block.snow.break", "dig.snow");
|
||||||
|
registerSoundRemapping("block.snow.place", "dig.snow");
|
||||||
|
registerSoundRemapping("block.piston.extend", "tile.piston.out");
|
||||||
|
registerSoundRemapping("entity.player.burp", "random.burp");
|
||||||
|
registerSoundRemapping("entity.cow.step", "mob.cow.step");
|
||||||
|
registerSoundRemapping("entity.wither.hurt", "mob.wither.hurt");
|
||||||
|
registerSoundRemapping("entity.guardian.death_land", "mob.guardian.land.death");
|
||||||
|
registerSoundRemapping("entity.elder_guardian.death_land", "mob.guardian.land.death");
|
||||||
|
registerSoundRemapping("music.end", "music.game.end");
|
||||||
|
registerSoundRemapping("entity.chicken.hurt", "mob.chicken.hurt");
|
||||||
|
registerSoundRemapping("entity.chicken.death", "mob.chicken.hurt");
|
||||||
|
registerSoundRemapping("entity.wolf.step", "mob.wolf.step");
|
||||||
|
registerSoundRemapping("entity.wolf.death", "mob.wolf.death");
|
||||||
|
registerSoundRemapping("entity.wolf.whine", "mob.wolf.whine");
|
||||||
|
registerSoundRemapping("block.note.pling", "note.pling");
|
||||||
|
registerSoundRemapping("entity.rabbit.hurt", "mob.rabbit.hurt");
|
||||||
|
registerSoundRemapping("entity.cat.purreow", "mob.cat.purreow");
|
||||||
|
registerSoundRemapping("entity.firework.large_blast_far", "fireworks.largeBlast_far");
|
||||||
|
registerSoundRemapping("entity.skeleton.hurt", "mob.skeleton.hurt");
|
||||||
|
registerSoundRemapping("entity.spider.death", "mob.spider.death");
|
||||||
|
registerSoundRemapping("block.anvil.destroy", "random.anvil_break");
|
||||||
|
registerSoundRemapping("record.cat", "records.cat");
|
||||||
|
registerSoundRemapping("entity.wither.ambient", "mob.wither.idle");
|
||||||
|
registerSoundRemapping("entity.elder_guardian.hurt", "mob.guardian.elder.hit");
|
||||||
|
registerSoundRemapping("entity.endermen.scream", "mob.endermen.scream");
|
||||||
|
registerSoundRemapping("entity.cat.death", "mob.cat.hitt");
|
||||||
|
registerSoundRemapping("entity.cat.hurt", "mob.cat.hitt");
|
||||||
|
registerSoundRemapping("entity.small_magmacube.squish", "mob.magmacube.small");
|
||||||
|
registerSoundRemapping("item.flintandsteel.use", "fire.ignite");
|
||||||
|
registerSoundRemapping("entity.enderdragon.hurt", "mob.enderdragon.hit");
|
||||||
|
registerSoundRemapping("entity.zombie.hurt", "mob.zombie.hurt");
|
||||||
|
registerSoundRemapping("entity.zombie_villager.hurt", "mob.zombie.hurt");
|
||||||
|
registerSoundRemapping("entity.enderdragon_fireball.explode", "random.explode");
|
||||||
|
registerSoundRemapping("entity.generic.explode", "random.explode");
|
||||||
|
registerSoundRemapping("entity.lightning.impact", "random.explode");
|
||||||
|
registerSoundRemapping("block.end_gateway.spawn", "random.explode");
|
||||||
|
registerSoundRemapping("entity.slime.attack", "mob.slime.attack");
|
||||||
|
registerSoundRemapping("entity.magmacube.jump", "mob.magmacube.jump");
|
||||||
|
registerSoundRemapping("entity.bobber.splash", "random.splash");
|
||||||
|
registerSoundRemapping("entity.skeleton_horse.hurt", "mob.horse.skeleton.hit");
|
||||||
|
registerSoundRemapping("entity.rabbit.jump", "mob.rabbit.hop");
|
||||||
|
registerSoundRemapping("entity.ghast.ambient", "mob.ghast.moan");
|
||||||
|
registerSoundRemapping("entity.elder_guardian.curse", "mob.guardian.curse");
|
||||||
|
registerSoundRemapping("entity.splash_potion.break", "game.potion.smash");
|
||||||
|
registerSoundRemapping("block.glass.break", "game.potion.smash");
|
||||||
|
registerSoundRemapping("block.note.bass", "note.bassattack");
|
||||||
|
registerSoundRemapping("block.dispenser.fail", "gui.button.press");
|
||||||
|
registerSoundRemapping("block.comparator.click", "gui.button.press");
|
||||||
|
registerSoundRemapping("block.stone_button.click_on", "gui.button.press");
|
||||||
|
registerSoundRemapping("block.stone_button.click_off", "gui.button.press");
|
||||||
|
registerSoundRemapping("block.tripwire.click_on", "gui.button.press");
|
||||||
|
registerSoundRemapping("block.dispenser.dispense", "gui.button.press");
|
||||||
|
registerSoundRemapping("ui.button.click", "gui.button.press");
|
||||||
|
registerSoundRemapping("block.lever.click", "gui.button.press");
|
||||||
|
registerSoundRemapping("block.tripwire.attach", "gui.button.press");
|
||||||
|
registerSoundRemapping("block.stone_pressureplate.click_on", "gui.button.press");
|
||||||
|
registerSoundRemapping("block.wood_pressureplate.click_off", "gui.button.press");
|
||||||
|
registerSoundRemapping("block.stone_pressureplate.click_off", "gui.button.press");
|
||||||
|
registerSoundRemapping("block.metal_pressureplate.click_off", "gui.button.press");
|
||||||
|
registerSoundRemapping("block.tripwire.click_off", "gui.button.press");
|
||||||
|
registerSoundRemapping("block.metal_pressureplate.click_on", "gui.button.press");
|
||||||
|
registerSoundRemapping("block.wood_pressureplate.click_on", "gui.button.press");
|
||||||
|
registerSoundRemapping("entity.experience_orb.touch", "random.orb");
|
||||||
|
registerSoundRemapping("entity.experience_orb.pickup", "random.orb");
|
||||||
|
registerSoundRemapping("entity.wither.break_block", "mob.zombie.woodbreak");
|
||||||
|
registerSoundRemapping("entity.zombie.break_door_wood", "mob.zombie.woodbreak");
|
||||||
|
registerSoundRemapping("entity.horse.armor", "mob.horse.armor");
|
||||||
|
registerSoundRemapping("entity.rabbit.ambient", "mob.rabbit.idle");
|
||||||
|
registerSoundRemapping("block.piston.contract", "tile.piston.in");
|
||||||
|
registerSoundRemapping("entity.cat.ambient", "mob.cat.meow");
|
||||||
|
registerSoundRemapping("entity.pig.step", "mob.pig.step");
|
||||||
|
registerSoundRemapping("record.strad", "records.strad");
|
||||||
|
registerSoundRemapping("block.wood.hit", "step.wood");
|
||||||
|
registerSoundRemapping("block.wood.fall", "step.wood");
|
||||||
|
registerSoundRemapping("block.wood.step", "step.wood");
|
||||||
|
registerSoundRemapping("block.portal.travel", "portal.travel");
|
||||||
|
registerSoundRemapping("entity.guardian.death", "mob.guardian.death");
|
||||||
|
registerSoundRemapping("entity.skeleton.death", "mob.skeleton.death");
|
||||||
|
registerSoundRemapping("entity.horse.hurt", "mob.horse.hit");
|
||||||
|
registerSoundRemapping("entity.villager.hurt", "mob.villager.hit");
|
||||||
|
registerSoundRemapping("entity.skeleton_horse.ambient", "mob.horse.skeleton.idle");
|
||||||
|
registerSoundRemapping("block.chest.open", "random.chestopen");
|
||||||
|
registerSoundRemapping("block.chest.close", "random.chestclosed");
|
||||||
|
registerSoundRemapping("entity.player.hurt_on_fire", "game.player.hurt");
|
||||||
|
registerSoundRemapping("entity.player.hurt_drown", "game.player.hurt");
|
||||||
|
registerSoundRemapping("entity.generic.swim", "game.neutral.swim");
|
||||||
|
registerSoundRemapping("entity.hostile.swim", "game.hostile.swim");
|
||||||
|
registerSoundRemapping("entity.player.swim", "game.player.swim");
|
||||||
|
registerSoundRemapping("entity.player.splash", "game.player.swim.splash");
|
||||||
|
registerSoundRemapping("entity.hostile.splash", "game.hostile.swim.splash");
|
||||||
|
registerSoundRemapping("entity.generic.splash", "game.neutral.swim.splash");
|
||||||
|
registerSoundRemapping("entity.generic.death", "game.neutral.die");
|
||||||
|
registerSoundRemapping("entity.hostile.hurt", "game.hostile.hurt");
|
||||||
|
registerSoundRemapping("entity.player.hurt", "game.player.hurt");
|
||||||
|
registerSoundRemapping("entity.hostile.death", "game.hostile.die");
|
||||||
|
registerSoundRemapping("entity.generic.hurt", "game.neutral.hurt");
|
||||||
|
registerSoundRemapping("entity.player.death", "game.player.die");
|
||||||
|
registerSoundRemapping("entity.player.big_fall", "game.player.hurt.fall.big");
|
||||||
|
registerSoundRemapping("entity.generic.big_fall", "game.neutral.hurt.fall.big");
|
||||||
|
registerSoundRemapping("entity.hostile.big_fall", "game.hostile.hurt.fall.big");
|
||||||
|
registerSoundRemapping("entity.hostile.small_fall", "game.hostile.hurt.fall.small");
|
||||||
|
registerSoundRemapping("entity.player.small_fall", "game.player.hurt.fall.small");
|
||||||
|
registerSoundRemapping("entity.generic.small_fall", "game.neutral.hurt.fall.small");
|
||||||
|
|
||||||
|
register1_9Sound("ambient.cave");
|
||||||
|
register1_9Sound("block.anvil.break");
|
||||||
|
register1_9Sound("block.anvil.destroy");
|
||||||
|
register1_9Sound("block.anvil.fall");
|
||||||
|
register1_9Sound("block.anvil.hit");
|
||||||
|
register1_9Sound("block.anvil.land");
|
||||||
|
register1_9Sound("block.anvil.place");
|
||||||
|
register1_9Sound("block.anvil.step");
|
||||||
|
register1_9Sound("block.anvil.use");
|
||||||
|
register1_9Sound("block.brewing_stand.brew");
|
||||||
|
register1_9Sound("block.chest.close");
|
||||||
|
register1_9Sound("block.chest.locked");
|
||||||
|
register1_9Sound("block.chest.open");
|
||||||
|
register1_9Sound("block.chorus_flower.death");
|
||||||
|
register1_9Sound("block.chorus_flower.grow");
|
||||||
|
register1_9Sound("block.cloth.break");
|
||||||
|
register1_9Sound("block.cloth.fall");
|
||||||
|
register1_9Sound("block.cloth.hit");
|
||||||
|
register1_9Sound("block.cloth.place");
|
||||||
|
register1_9Sound("block.cloth.step");
|
||||||
|
register1_9Sound("block.comparator.click");
|
||||||
|
register1_9Sound("block.dispenser.dispense");
|
||||||
|
register1_9Sound("block.dispenser.fail");
|
||||||
|
register1_9Sound("block.dispenser.launch");
|
||||||
|
register1_9Sound("block.end_gateway.spawn");
|
||||||
|
register1_9Sound("block.enderchest.close");
|
||||||
|
register1_9Sound("block.enderchest.open");
|
||||||
|
register1_9Sound("block.fence_gate.close");
|
||||||
|
register1_9Sound("block.fence_gate.open");
|
||||||
|
register1_9Sound("block.fire.ambient");
|
||||||
|
register1_9Sound("block.fire.extinguish");
|
||||||
|
register1_9Sound("block.furnace.fire_crackle");
|
||||||
|
register1_9Sound("block.glass.break");
|
||||||
|
register1_9Sound("block.glass.fall");
|
||||||
|
register1_9Sound("block.glass.hit");
|
||||||
|
register1_9Sound("block.glass.place");
|
||||||
|
register1_9Sound("block.glass.step");
|
||||||
|
register1_9Sound("block.grass.break");
|
||||||
|
register1_9Sound("block.grass.fall");
|
||||||
|
register1_9Sound("block.grass.hit");
|
||||||
|
register1_9Sound("block.grass.place");
|
||||||
|
register1_9Sound("block.grass.step");
|
||||||
|
register1_9Sound("block.gravel.break");
|
||||||
|
register1_9Sound("block.gravel.fall");
|
||||||
|
register1_9Sound("block.gravel.hit");
|
||||||
|
register1_9Sound("block.gravel.place");
|
||||||
|
register1_9Sound("block.gravel.step");
|
||||||
|
register1_9Sound("block.iron_door.close");
|
||||||
|
register1_9Sound("block.iron_door.open");
|
||||||
|
register1_9Sound("block.iron_trapdoor.close");
|
||||||
|
register1_9Sound("block.iron_trapdoor.open");
|
||||||
|
register1_9Sound("block.ladder.break");
|
||||||
|
register1_9Sound("block.ladder.fall");
|
||||||
|
register1_9Sound("block.ladder.hit");
|
||||||
|
register1_9Sound("block.ladder.place");
|
||||||
|
register1_9Sound("block.ladder.step");
|
||||||
|
register1_9Sound("block.lava.ambient");
|
||||||
|
register1_9Sound("block.lava.extinguish");
|
||||||
|
register1_9Sound("block.lava.pop");
|
||||||
|
register1_9Sound("block.lever.click");
|
||||||
|
register1_9Sound("block.metal.break");
|
||||||
|
register1_9Sound("block.metal.fall");
|
||||||
|
register1_9Sound("block.metal.hit");
|
||||||
|
register1_9Sound("block.metal.place");
|
||||||
|
register1_9Sound("block.metal.step");
|
||||||
|
register1_9Sound("block.metal_pressureplate.click_off");
|
||||||
|
register1_9Sound("block.metal_pressureplate.click_on");
|
||||||
|
register1_9Sound("block.note.basedrum");
|
||||||
|
register1_9Sound("block.note.bass");
|
||||||
|
register1_9Sound("block.note.harp");
|
||||||
|
register1_9Sound("block.note.hat");
|
||||||
|
register1_9Sound("block.note.pling");
|
||||||
|
register1_9Sound("block.note.snare");
|
||||||
|
register1_9Sound("block.piston.contract");
|
||||||
|
register1_9Sound("block.piston.extend");
|
||||||
|
register1_9Sound("block.portal.ambient");
|
||||||
|
register1_9Sound("block.portal.travel");
|
||||||
|
register1_9Sound("block.portal.trigger");
|
||||||
|
register1_9Sound("block.redstone_torch.burnout");
|
||||||
|
register1_9Sound("block.sand.break");
|
||||||
|
register1_9Sound("block.sand.fall");
|
||||||
|
register1_9Sound("block.sand.hit");
|
||||||
|
register1_9Sound("block.sand.place");
|
||||||
|
register1_9Sound("block.sand.step");
|
||||||
|
register1_9Sound("block.slime.break");
|
||||||
|
register1_9Sound("block.slime.fall");
|
||||||
|
register1_9Sound("block.slime.hit");
|
||||||
|
register1_9Sound("block.slime.place");
|
||||||
|
register1_9Sound("block.slime.step");
|
||||||
|
register1_9Sound("block.snow.break");
|
||||||
|
register1_9Sound("block.snow.fall");
|
||||||
|
register1_9Sound("block.snow.hit");
|
||||||
|
register1_9Sound("block.snow.place");
|
||||||
|
register1_9Sound("block.snow.step");
|
||||||
|
register1_9Sound("block.stone.break");
|
||||||
|
register1_9Sound("block.stone.fall");
|
||||||
|
register1_9Sound("block.stone.hit");
|
||||||
|
register1_9Sound("block.stone.place");
|
||||||
|
register1_9Sound("block.stone.step");
|
||||||
|
register1_9Sound("block.stone_button.click_off");
|
||||||
|
register1_9Sound("block.stone_button.click_on");
|
||||||
|
register1_9Sound("block.stone_pressureplate.click_off");
|
||||||
|
register1_9Sound("block.stone_pressureplate.click_on");
|
||||||
|
register1_9Sound("block.tripwire.attach");
|
||||||
|
register1_9Sound("block.tripwire.click_off");
|
||||||
|
register1_9Sound("block.tripwire.click_on");
|
||||||
|
register1_9Sound("block.tripwire.detach");
|
||||||
|
register1_9Sound("block.water.ambient");
|
||||||
|
register1_9Sound("block.waterlily.place");
|
||||||
|
register1_9Sound("block.wood.break");
|
||||||
|
register1_9Sound("block.wood.fall");
|
||||||
|
register1_9Sound("block.wood.hit");
|
||||||
|
register1_9Sound("block.wood.place");
|
||||||
|
register1_9Sound("block.wood.step");
|
||||||
|
register1_9Sound("block.wood_button.click_off");
|
||||||
|
register1_9Sound("block.wood_button.click_on");
|
||||||
|
register1_9Sound("block.wood_pressureplate.click_off");
|
||||||
|
register1_9Sound("block.wood_pressureplate.click_on");
|
||||||
|
register1_9Sound("block.wooden_door.close");
|
||||||
|
register1_9Sound("block.wooden_door.open");
|
||||||
|
register1_9Sound("block.wooden_trapdoor.close");
|
||||||
|
register1_9Sound("block.wooden_trapdoor.open");
|
||||||
|
register1_9Sound("enchant.thorns.hit");
|
||||||
|
register1_9Sound("entity.armorstand.break");
|
||||||
|
register1_9Sound("entity.armorstand.fall");
|
||||||
|
register1_9Sound("entity.armorstand.hit");
|
||||||
|
register1_9Sound("entity.armorstand.place");
|
||||||
|
register1_9Sound("entity.arrow.hit");
|
||||||
|
register1_9Sound("entity.arrow.hit_player");
|
||||||
|
register1_9Sound("entity.arrow.shoot");
|
||||||
|
register1_9Sound("entity.bat.ambient");
|
||||||
|
register1_9Sound("entity.bat.death");
|
||||||
|
register1_9Sound("entity.bat.hurt");
|
||||||
|
register1_9Sound("entity.bat.loop");
|
||||||
|
register1_9Sound("entity.bat.takeoff");
|
||||||
|
register1_9Sound("entity.blaze.ambient");
|
||||||
|
register1_9Sound("entity.blaze.burn");
|
||||||
|
register1_9Sound("entity.blaze.death");
|
||||||
|
register1_9Sound("entity.blaze.hurt");
|
||||||
|
register1_9Sound("entity.blaze.shoot");
|
||||||
|
register1_9Sound("entity.bobber.splash");
|
||||||
|
register1_9Sound("entity.bobber.throw");
|
||||||
|
register1_9Sound("entity.cat.ambient");
|
||||||
|
register1_9Sound("entity.cat.death");
|
||||||
|
register1_9Sound("entity.cat.hiss");
|
||||||
|
register1_9Sound("entity.cat.hurt");
|
||||||
|
register1_9Sound("entity.cat.purr");
|
||||||
|
register1_9Sound("entity.cat.purreow");
|
||||||
|
register1_9Sound("entity.chicken.ambient");
|
||||||
|
register1_9Sound("entity.chicken.death");
|
||||||
|
register1_9Sound("entity.chicken.egg");
|
||||||
|
register1_9Sound("entity.chicken.hurt");
|
||||||
|
register1_9Sound("entity.chicken.step");
|
||||||
|
register1_9Sound("entity.cow.ambient");
|
||||||
|
register1_9Sound("entity.cow.death");
|
||||||
|
register1_9Sound("entity.cow.hurt");
|
||||||
|
register1_9Sound("entity.cow.milk");
|
||||||
|
register1_9Sound("entity.cow.step");
|
||||||
|
register1_9Sound("entity.creeper.death");
|
||||||
|
register1_9Sound("entity.creeper.hurt");
|
||||||
|
register1_9Sound("entity.creeper.primed");
|
||||||
|
register1_9Sound("entity.donkey.ambient");
|
||||||
|
register1_9Sound("entity.donkey.angry");
|
||||||
|
register1_9Sound("entity.donkey.chest");
|
||||||
|
register1_9Sound("entity.donkey.death");
|
||||||
|
register1_9Sound("entity.donkey.hurt");
|
||||||
|
register1_9Sound("entity.egg.throw");
|
||||||
|
register1_9Sound("entity.elder_guardian.ambient");
|
||||||
|
register1_9Sound("entity.elder_guardian.ambient_land");
|
||||||
|
register1_9Sound("entity.elder_guardian.curse");
|
||||||
|
register1_9Sound("entity.elder_guardian.death");
|
||||||
|
register1_9Sound("entity.elder_guardian.death_land");
|
||||||
|
register1_9Sound("entity.elder_guardian.hurt");
|
||||||
|
register1_9Sound("entity.elder_guardian.hurt_land");
|
||||||
|
register1_9Sound("entity.enderdragon.ambient");
|
||||||
|
register1_9Sound("entity.enderdragon.death");
|
||||||
|
register1_9Sound("entity.enderdragon.flap");
|
||||||
|
register1_9Sound("entity.enderdragon.growl");
|
||||||
|
register1_9Sound("entity.enderdragon.hurt");
|
||||||
|
register1_9Sound("entity.enderdragon.shoot");
|
||||||
|
register1_9Sound("entity.enderdragon_fireball.explode");
|
||||||
|
register1_9Sound("entity.endereye.launch");
|
||||||
|
register1_9Sound("entity.endermen.ambient");
|
||||||
|
register1_9Sound("entity.endermen.death");
|
||||||
|
register1_9Sound("entity.endermen.hurt");
|
||||||
|
register1_9Sound("entity.endermen.scream");
|
||||||
|
register1_9Sound("entity.endermen.stare");
|
||||||
|
register1_9Sound("entity.endermen.teleport");
|
||||||
|
register1_9Sound("entity.endermite.ambient");
|
||||||
|
register1_9Sound("entity.endermite.death");
|
||||||
|
register1_9Sound("entity.endermite.hurt");
|
||||||
|
register1_9Sound("entity.endermite.step");
|
||||||
|
register1_9Sound("entity.enderpearl.throw");
|
||||||
|
register1_9Sound("entity.experience_bottle.throw");
|
||||||
|
register1_9Sound("entity.experience_orb.pickup");
|
||||||
|
register1_9Sound("entity.experience_orb.touch");
|
||||||
|
register1_9Sound("entity.firework.blast");
|
||||||
|
register1_9Sound("entity.firework.blast_far");
|
||||||
|
register1_9Sound("entity.firework.large_blast");
|
||||||
|
register1_9Sound("entity.firework.large_blast_far");
|
||||||
|
register1_9Sound("entity.firework.launch");
|
||||||
|
register1_9Sound("entity.firework.shoot");
|
||||||
|
register1_9Sound("entity.firework.twinkle");
|
||||||
|
register1_9Sound("entity.firework.twinkle_far");
|
||||||
|
register1_9Sound("entity.generic.big_fall");
|
||||||
|
register1_9Sound("entity.generic.burn");
|
||||||
|
register1_9Sound("entity.generic.death");
|
||||||
|
register1_9Sound("entity.generic.drink");
|
||||||
|
register1_9Sound("entity.generic.eat");
|
||||||
|
register1_9Sound("entity.generic.explode");
|
||||||
|
register1_9Sound("entity.generic.extinguish_fire");
|
||||||
|
register1_9Sound("entity.generic.hurt");
|
||||||
|
register1_9Sound("entity.generic.small_fall");
|
||||||
|
register1_9Sound("entity.generic.splash");
|
||||||
|
register1_9Sound("entity.generic.swim");
|
||||||
|
register1_9Sound("entity.ghast.ambient");
|
||||||
|
register1_9Sound("entity.ghast.death");
|
||||||
|
register1_9Sound("entity.ghast.hurt");
|
||||||
|
register1_9Sound("entity.ghast.scream");
|
||||||
|
register1_9Sound("entity.ghast.shoot");
|
||||||
|
register1_9Sound("entity.ghast.warn");
|
||||||
|
register1_9Sound("entity.guardian.ambient");
|
||||||
|
register1_9Sound("entity.guardian.ambient_land");
|
||||||
|
register1_9Sound("entity.guardian.attack");
|
||||||
|
register1_9Sound("entity.guardian.death");
|
||||||
|
register1_9Sound("entity.guardian.death_land");
|
||||||
|
register1_9Sound("entity.guardian.flop");
|
||||||
|
register1_9Sound("entity.guardian.hurt");
|
||||||
|
register1_9Sound("entity.guardian.hurt_land");
|
||||||
|
register1_9Sound("entity.horse.ambient");
|
||||||
|
register1_9Sound("entity.horse.angry");
|
||||||
|
register1_9Sound("entity.horse.armor");
|
||||||
|
register1_9Sound("entity.horse.breathe");
|
||||||
|
register1_9Sound("entity.horse.death");
|
||||||
|
register1_9Sound("entity.horse.eat");
|
||||||
|
register1_9Sound("entity.horse.gallop");
|
||||||
|
register1_9Sound("entity.horse.hurt");
|
||||||
|
register1_9Sound("entity.horse.jump");
|
||||||
|
register1_9Sound("entity.horse.land");
|
||||||
|
register1_9Sound("entity.horse.saddle");
|
||||||
|
register1_9Sound("entity.horse.step");
|
||||||
|
register1_9Sound("entity.horse.step_wood");
|
||||||
|
register1_9Sound("entity.hostile.big_fall");
|
||||||
|
register1_9Sound("entity.hostile.death");
|
||||||
|
register1_9Sound("entity.hostile.hurt");
|
||||||
|
register1_9Sound("entity.hostile.small_fall");
|
||||||
|
register1_9Sound("entity.hostile.splash");
|
||||||
|
register1_9Sound("entity.hostile.swim");
|
||||||
|
register1_9Sound("entity.irongolem.attack");
|
||||||
|
register1_9Sound("entity.irongolem.death");
|
||||||
|
register1_9Sound("entity.irongolem.hurt");
|
||||||
|
register1_9Sound("entity.irongolem.step");
|
||||||
|
register1_9Sound("entity.item.break");
|
||||||
|
register1_9Sound("entity.item.pickup");
|
||||||
|
register1_9Sound("entity.itemframe.add_item");
|
||||||
|
register1_9Sound("entity.itemframe.break");
|
||||||
|
register1_9Sound("entity.itemframe.place");
|
||||||
|
register1_9Sound("entity.itemframe.remove_item");
|
||||||
|
register1_9Sound("entity.itemframe.rotate_item");
|
||||||
|
register1_9Sound("entity.leashknot.break");
|
||||||
|
register1_9Sound("entity.leashknot.place");
|
||||||
|
register1_9Sound("entity.lightning.impact");
|
||||||
|
register1_9Sound("entity.lightning.thunder");
|
||||||
|
register1_9Sound("entity.lingeringpotion.throw");
|
||||||
|
register1_9Sound("entity.magmacube.death");
|
||||||
|
register1_9Sound("entity.magmacube.hurt");
|
||||||
|
register1_9Sound("entity.magmacube.jump");
|
||||||
|
register1_9Sound("entity.magmacube.squish");
|
||||||
|
register1_9Sound("entity.minecart.inside");
|
||||||
|
register1_9Sound("entity.minecart.riding");
|
||||||
|
register1_9Sound("entity.mooshroom.shear");
|
||||||
|
register1_9Sound("entity.mule.ambient");
|
||||||
|
register1_9Sound("entity.mule.death");
|
||||||
|
register1_9Sound("entity.mule.hurt");
|
||||||
|
register1_9Sound("entity.painting.break");
|
||||||
|
register1_9Sound("entity.painting.place");
|
||||||
|
register1_9Sound("entity.pig.ambient");
|
||||||
|
register1_9Sound("entity.pig.death");
|
||||||
|
register1_9Sound("entity.pig.hurt");
|
||||||
|
register1_9Sound("entity.pig.saddle");
|
||||||
|
register1_9Sound("entity.pig.step");
|
||||||
|
register1_9Sound("entity.player.attack.crit");
|
||||||
|
register1_9Sound("entity.player.attack.knockback");
|
||||||
|
register1_9Sound("entity.player.attack.nodamage");
|
||||||
|
register1_9Sound("entity.player.attack.strong");
|
||||||
|
register1_9Sound("entity.player.attack.sweep");
|
||||||
|
register1_9Sound("entity.player.attack.weak");
|
||||||
|
register1_9Sound("entity.player.big_fall");
|
||||||
|
register1_9Sound("entity.player.breath");
|
||||||
|
register1_9Sound("entity.player.burp");
|
||||||
|
register1_9Sound("entity.player.death");
|
||||||
|
register1_9Sound("entity.player.hurt");
|
||||||
|
register1_9Sound("entity.player.levelup");
|
||||||
|
register1_9Sound("entity.player.small_fall");
|
||||||
|
register1_9Sound("entity.player.splash");
|
||||||
|
register1_9Sound("entity.player.swim");
|
||||||
|
register1_9Sound("entity.rabbit.ambient");
|
||||||
|
register1_9Sound("entity.rabbit.attack");
|
||||||
|
register1_9Sound("entity.rabbit.death");
|
||||||
|
register1_9Sound("entity.rabbit.hurt");
|
||||||
|
register1_9Sound("entity.rabbit.jump");
|
||||||
|
register1_9Sound("entity.sheep.ambient");
|
||||||
|
register1_9Sound("entity.sheep.death");
|
||||||
|
register1_9Sound("entity.sheep.hurt");
|
||||||
|
register1_9Sound("entity.sheep.shear");
|
||||||
|
register1_9Sound("entity.sheep.step");
|
||||||
|
register1_9Sound("entity.shulker.ambient");
|
||||||
|
register1_9Sound("entity.shulker.close");
|
||||||
|
register1_9Sound("entity.shulker.death");
|
||||||
|
register1_9Sound("entity.shulker.hurt");
|
||||||
|
register1_9Sound("entity.shulker.hurt_closed");
|
||||||
|
register1_9Sound("entity.shulker.open");
|
||||||
|
register1_9Sound("entity.shulker.shoot");
|
||||||
|
register1_9Sound("entity.shulker.teleport");
|
||||||
|
register1_9Sound("entity.shulker_bullet.hit");
|
||||||
|
register1_9Sound("entity.shulker_bullet.hurt");
|
||||||
|
register1_9Sound("entity.silverfish.ambient");
|
||||||
|
register1_9Sound("entity.silverfish.death");
|
||||||
|
register1_9Sound("entity.silverfish.hurt");
|
||||||
|
register1_9Sound("entity.silverfish.step");
|
||||||
|
register1_9Sound("entity.skeleton.ambient");
|
||||||
|
register1_9Sound("entity.skeleton.death");
|
||||||
|
register1_9Sound("entity.skeleton.hurt");
|
||||||
|
register1_9Sound("entity.skeleton.shoot");
|
||||||
|
register1_9Sound("entity.skeleton.step");
|
||||||
|
register1_9Sound("entity.skeleton_horse.ambient");
|
||||||
|
register1_9Sound("entity.skeleton_horse.death");
|
||||||
|
register1_9Sound("entity.skeleton_horse.hurt");
|
||||||
|
register1_9Sound("entity.slime.attack");
|
||||||
|
register1_9Sound("entity.slime.death");
|
||||||
|
register1_9Sound("entity.slime.hurt");
|
||||||
|
register1_9Sound("entity.slime.jump");
|
||||||
|
register1_9Sound("entity.slime.squish");
|
||||||
|
register1_9Sound("entity.small_magmacube.death");
|
||||||
|
register1_9Sound("entity.small_magmacube.hurt");
|
||||||
|
register1_9Sound("entity.small_magmacube.squish");
|
||||||
|
register1_9Sound("entity.small_slime.death");
|
||||||
|
register1_9Sound("entity.small_slime.hurt");
|
||||||
|
register1_9Sound("entity.small_slime.jump");
|
||||||
|
register1_9Sound("entity.small_slime.squish");
|
||||||
|
register1_9Sound("entity.snowball.throw");
|
||||||
|
register1_9Sound("entity.snowman.ambient");
|
||||||
|
register1_9Sound("entity.snowman.death");
|
||||||
|
register1_9Sound("entity.snowman.hurt");
|
||||||
|
register1_9Sound("entity.snowman.shoot");
|
||||||
|
register1_9Sound("entity.spider.ambient");
|
||||||
|
register1_9Sound("entity.spider.death");
|
||||||
|
register1_9Sound("entity.spider.hurt");
|
||||||
|
register1_9Sound("entity.spider.step");
|
||||||
|
register1_9Sound("entity.splash_potion.break");
|
||||||
|
register1_9Sound("entity.splash_potion.throw");
|
||||||
|
register1_9Sound("entity.squid.ambient");
|
||||||
|
register1_9Sound("entity.squid.death");
|
||||||
|
register1_9Sound("entity.squid.hurt");
|
||||||
|
register1_9Sound("entity.tnt.primed");
|
||||||
|
register1_9Sound("entity.villager.ambient");
|
||||||
|
register1_9Sound("entity.villager.death");
|
||||||
|
register1_9Sound("entity.villager.hurt");
|
||||||
|
register1_9Sound("entity.villager.no");
|
||||||
|
register1_9Sound("entity.villager.trading");
|
||||||
|
register1_9Sound("entity.villager.yes");
|
||||||
|
register1_9Sound("entity.witch.ambient");
|
||||||
|
register1_9Sound("entity.witch.death");
|
||||||
|
register1_9Sound("entity.witch.drink");
|
||||||
|
register1_9Sound("entity.witch.hurt");
|
||||||
|
register1_9Sound("entity.witch.throw");
|
||||||
|
register1_9Sound("entity.wither.ambient");
|
||||||
|
register1_9Sound("entity.wither.break_block");
|
||||||
|
register1_9Sound("entity.wither.death");
|
||||||
|
register1_9Sound("entity.wither.hurt");
|
||||||
|
register1_9Sound("entity.wither.shoot");
|
||||||
|
register1_9Sound("entity.wither.spawn");
|
||||||
|
register1_9Sound("entity.wolf.ambient");
|
||||||
|
register1_9Sound("entity.wolf.death");
|
||||||
|
register1_9Sound("entity.wolf.growl");
|
||||||
|
register1_9Sound("entity.wolf.howl");
|
||||||
|
register1_9Sound("entity.wolf.hurt");
|
||||||
|
register1_9Sound("entity.wolf.pant");
|
||||||
|
register1_9Sound("entity.wolf.shake");
|
||||||
|
register1_9Sound("entity.wolf.step");
|
||||||
|
register1_9Sound("entity.wolf.whine");
|
||||||
|
register1_9Sound("entity.zombie.ambient");
|
||||||
|
register1_9Sound("entity.zombie.attack_door_wood");
|
||||||
|
register1_9Sound("entity.zombie.attack_iron_door");
|
||||||
|
register1_9Sound("entity.zombie.break_door_wood");
|
||||||
|
register1_9Sound("entity.zombie.death");
|
||||||
|
register1_9Sound("entity.zombie.hurt");
|
||||||
|
register1_9Sound("entity.zombie.infect");
|
||||||
|
register1_9Sound("entity.zombie.step");
|
||||||
|
register1_9Sound("entity.zombie_horse.ambient");
|
||||||
|
register1_9Sound("entity.zombie_horse.death");
|
||||||
|
register1_9Sound("entity.zombie_horse.hurt");
|
||||||
|
register1_9Sound("entity.zombie_pig.ambient");
|
||||||
|
register1_9Sound("entity.zombie_pig.angry");
|
||||||
|
register1_9Sound("entity.zombie_pig.death");
|
||||||
|
register1_9Sound("entity.zombie_pig.hurt");
|
||||||
|
register1_9Sound("entity.zombie_villager.ambient");
|
||||||
|
register1_9Sound("entity.zombie_villager.converted");
|
||||||
|
register1_9Sound("entity.zombie_villager.cure");
|
||||||
|
register1_9Sound("entity.zombie_villager.death");
|
||||||
|
register1_9Sound("entity.zombie_villager.hurt");
|
||||||
|
register1_9Sound("entity.zombie_villager.step");
|
||||||
|
register1_9Sound("item.armor.equip_chain");
|
||||||
|
register1_9Sound("item.armor.equip_diamond");
|
||||||
|
register1_9Sound("item.armor.equip_generic");
|
||||||
|
register1_9Sound("item.armor.equip_gold");
|
||||||
|
register1_9Sound("item.armor.equip_iron");
|
||||||
|
register1_9Sound("item.armor.equip_leather");
|
||||||
|
register1_9Sound("item.bottle.fill");
|
||||||
|
register1_9Sound("item.bottle.fill_dragonbreath");
|
||||||
|
register1_9Sound("item.bucket.empty");
|
||||||
|
register1_9Sound("item.bucket.empty_lava");
|
||||||
|
register1_9Sound("item.bucket.fill");
|
||||||
|
register1_9Sound("item.bucket.fill_lava");
|
||||||
|
register1_9Sound("item.chorus_fruit.teleport");
|
||||||
|
register1_9Sound("item.firecharge.use");
|
||||||
|
register1_9Sound("item.flintandsteel.use");
|
||||||
|
register1_9Sound("item.hoe.till");
|
||||||
|
register1_9Sound("item.shield.block");
|
||||||
|
register1_9Sound("item.shield.break");
|
||||||
|
register1_9Sound("item.shovel.flatten");
|
||||||
|
register1_9Sound("music.creative");
|
||||||
|
register1_9Sound("music.credits");
|
||||||
|
register1_9Sound("music.dragon");
|
||||||
|
register1_9Sound("music.end");
|
||||||
|
register1_9Sound("music.game");
|
||||||
|
register1_9Sound("music.menu");
|
||||||
|
register1_9Sound("music.nether");
|
||||||
|
register1_9Sound("record.11");
|
||||||
|
register1_9Sound("record.13");
|
||||||
|
register1_9Sound("record.blocks");
|
||||||
|
register1_9Sound("record.cat");
|
||||||
|
register1_9Sound("record.chirp");
|
||||||
|
register1_9Sound("record.far");
|
||||||
|
register1_9Sound("record.mall");
|
||||||
|
register1_9Sound("record.mellohi");
|
||||||
|
register1_9Sound("record.stal");
|
||||||
|
register1_9Sound("record.strad");
|
||||||
|
register1_9Sound("record.wait");
|
||||||
|
register1_9Sound("record.ward");
|
||||||
|
register1_9Sound("ui.button.click");
|
||||||
|
register1_9Sound("weather.rain");
|
||||||
|
register1_9Sound("weather.rain.above");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.storage;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.StoredObject;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
|
||||||
|
public class BlockPlaceDestroyTracker extends StoredObject {
|
||||||
|
private long blockPlaced, lastMining;
|
||||||
|
private boolean mining;
|
||||||
|
|
||||||
|
public BlockPlaceDestroyTracker(UserConnection user) {
|
||||||
|
super(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getBlockPlaced() {
|
||||||
|
return blockPlaced;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void place() {
|
||||||
|
blockPlaced = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMining() {
|
||||||
|
long time = System.currentTimeMillis()-lastMining;
|
||||||
|
return mining && time<75 || time<75;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMining(boolean mining) {
|
||||||
|
this.mining = mining && getUser().get(EntityTracker.class).getPlayerGamemode()!=1;
|
||||||
|
lastMining = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLastMining() {
|
||||||
|
return lastMining;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateMining() {
|
||||||
|
if (this.isMining()) {
|
||||||
|
lastMining = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastMining(long lastMining) {
|
||||||
|
this.lastMining = lastMining;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.storage;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.bossbar.WitherBossBar;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.StoredObject;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class BossBarStorage extends StoredObject {
|
||||||
|
private Map<UUID, WitherBossBar> bossBars = new HashMap<>();
|
||||||
|
|
||||||
|
public BossBarStorage(UserConnection user) {
|
||||||
|
super(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(UUID uuid, String title, float health) {
|
||||||
|
WitherBossBar bossBar = new WitherBossBar(this.getUser(), uuid, title, health);
|
||||||
|
PlayerPosition playerPosition = this.getUser().get(PlayerPosition.class);
|
||||||
|
bossBar.setPlayerLocation(playerPosition.getPosX(), playerPosition.getPosY(), playerPosition.getPosZ(), playerPosition.getYaw(), playerPosition.getPitch());
|
||||||
|
bossBar.show();
|
||||||
|
bossBars.put(uuid, bossBar);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(UUID uuid) {
|
||||||
|
WitherBossBar bossBar = bossBars.remove(uuid);
|
||||||
|
if (bossBar==null) return;
|
||||||
|
bossBar.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateLocation() {
|
||||||
|
PlayerPosition playerPosition = this.getUser().get(PlayerPosition.class);
|
||||||
|
bossBars.values().forEach(bossBar -> bossBar.setPlayerLocation(playerPosition.getPosX(), playerPosition.getPosY(), playerPosition.getPosZ(), playerPosition.getYaw(), playerPosition.getPitch()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void changeWorld() {
|
||||||
|
bossBars.values().forEach(bossBar -> {
|
||||||
|
bossBar.hide();
|
||||||
|
bossBar.show();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateHealth(UUID uuid, float health) {
|
||||||
|
WitherBossBar bossBar = bossBars.get(uuid);
|
||||||
|
if (bossBar==null) return;
|
||||||
|
bossBar.setHealth(health);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateTitle(UUID uuid, String title) {
|
||||||
|
WitherBossBar bossBar = bossBars.get(uuid);
|
||||||
|
if (bossBar==null) return;
|
||||||
|
bossBar.setTitle(title);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,211 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.storage;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.ViaRewind;
|
||||||
|
import com.elevatemc.spigot.viarewind.api.ViaRewindConfig;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.Protocol1_8TO1_9;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.PacketUtil;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.Tickable;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.StoredObject;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
import com.elevatemc.spigot.viaversion.util.Pair;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class Cooldown extends StoredObject implements Tickable {
|
||||||
|
|
||||||
|
private double attackSpeed = 4.0;
|
||||||
|
private long lastHit = 0;
|
||||||
|
private final ViaRewindConfig.CooldownIndicator cooldownIndicator;
|
||||||
|
private UUID bossUUID;
|
||||||
|
private boolean lastSend;
|
||||||
|
|
||||||
|
public Cooldown(final UserConnection user) {
|
||||||
|
super(user);
|
||||||
|
|
||||||
|
ViaRewindConfig.CooldownIndicator indicator;
|
||||||
|
try {
|
||||||
|
indicator = ViaRewind.getConfig().getCooldownIndicator();
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
ViaRewind.getPlatform().getLogger().warning("Invalid cooldown-indicator setting");
|
||||||
|
indicator = ViaRewindConfig.CooldownIndicator.DISABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.cooldownIndicator = indicator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
if (!hasCooldown()) {
|
||||||
|
if (lastSend) {
|
||||||
|
hide();
|
||||||
|
lastSend = false;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockPlaceDestroyTracker tracker = getUser().get(BlockPlaceDestroyTracker.class);
|
||||||
|
if (tracker.isMining()) {
|
||||||
|
lastHit = 0;
|
||||||
|
if (lastSend) {
|
||||||
|
hide();
|
||||||
|
lastSend = false;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
showCooldown();
|
||||||
|
lastSend = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showCooldown() {
|
||||||
|
if (cooldownIndicator==ViaRewindConfig.CooldownIndicator.TITLE) {
|
||||||
|
sendTitle("", getTitle(), 0, 2, 5);
|
||||||
|
} else if (cooldownIndicator==ViaRewindConfig.CooldownIndicator.ACTION_BAR) {
|
||||||
|
sendActionBar(getTitle());
|
||||||
|
} else if (cooldownIndicator==ViaRewindConfig.CooldownIndicator.BOSS_BAR) {
|
||||||
|
sendBossBar((float) getCooldown());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hide() {
|
||||||
|
if (cooldownIndicator==ViaRewindConfig.CooldownIndicator.ACTION_BAR) {
|
||||||
|
sendActionBar("§r");
|
||||||
|
} else if (cooldownIndicator==ViaRewindConfig.CooldownIndicator.TITLE) {
|
||||||
|
hideTitle();
|
||||||
|
} else if (cooldownIndicator==ViaRewindConfig.CooldownIndicator.BOSS_BAR) {
|
||||||
|
hideBossBar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hideBossBar() {
|
||||||
|
if (bossUUID==null) return;
|
||||||
|
PacketWrapper wrapper = PacketWrapper.create(0x0C, null, getUser());
|
||||||
|
wrapper.write(Type.UUID, bossUUID);
|
||||||
|
wrapper.write(Type.VAR_INT, 1);
|
||||||
|
PacketUtil.sendPacket(wrapper, Protocol1_8TO1_9.class, false, true);
|
||||||
|
bossUUID = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendBossBar(float cooldown) {
|
||||||
|
PacketWrapper wrapper = PacketWrapper.create(0x0C, null, getUser());
|
||||||
|
if (bossUUID==null) {
|
||||||
|
bossUUID = UUID.randomUUID();
|
||||||
|
wrapper.write(Type.UUID, bossUUID);
|
||||||
|
wrapper.write(Type.VAR_INT, 0);
|
||||||
|
wrapper.write(Type.STRING, "{\"text\":\" \"}");
|
||||||
|
wrapper.write(Type.FLOAT, cooldown);
|
||||||
|
wrapper.write(Type.VAR_INT, 0);
|
||||||
|
wrapper.write(Type.VAR_INT, 0);
|
||||||
|
wrapper.write(Type.UNSIGNED_BYTE, (short) 0);
|
||||||
|
} else {
|
||||||
|
wrapper.write(Type.UUID, bossUUID);
|
||||||
|
wrapper.write(Type.VAR_INT, 2);
|
||||||
|
wrapper.write(Type.FLOAT, cooldown);
|
||||||
|
}
|
||||||
|
PacketUtil.sendPacket(wrapper, Protocol1_8TO1_9.class, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hideTitle() {
|
||||||
|
PacketWrapper hide = PacketWrapper.create(0x45, null, getUser());
|
||||||
|
hide.write(Type.VAR_INT, 3);
|
||||||
|
PacketUtil.sendPacket(hide, Protocol1_8TO1_9.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendTitle(String title, String subTitle, int fadeIn, int stay, int fadeOut) {
|
||||||
|
PacketWrapper timePacket = PacketWrapper.create(0x45, null, getUser());
|
||||||
|
timePacket.write(Type.VAR_INT, 2);
|
||||||
|
timePacket.write(Type.INT, fadeIn);
|
||||||
|
timePacket.write(Type.INT, stay);
|
||||||
|
timePacket.write(Type.INT, fadeOut);
|
||||||
|
PacketWrapper titlePacket = PacketWrapper.create(0x45, null, getUser());
|
||||||
|
titlePacket.write(Type.VAR_INT, 0);
|
||||||
|
titlePacket.write(Type.STRING, title);
|
||||||
|
PacketWrapper subtitlePacket = PacketWrapper.create(0x45, null, getUser());
|
||||||
|
subtitlePacket.write(Type.VAR_INT, 1);
|
||||||
|
subtitlePacket.write(Type.STRING, subTitle);
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(titlePacket, Protocol1_8TO1_9.class);
|
||||||
|
PacketUtil.sendPacket(subtitlePacket, Protocol1_8TO1_9.class);
|
||||||
|
PacketUtil.sendPacket(timePacket, Protocol1_8TO1_9.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendActionBar(String bar) {
|
||||||
|
PacketWrapper actionBarPacket = PacketWrapper.create(0x02, null, getUser());
|
||||||
|
actionBarPacket.write(Type.STRING, bar);
|
||||||
|
actionBarPacket.write(Type.BYTE, (byte) 2);
|
||||||
|
|
||||||
|
PacketUtil.sendPacket(actionBarPacket, Protocol1_8TO1_9.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasCooldown() {
|
||||||
|
long time = System.currentTimeMillis()-lastHit;
|
||||||
|
double cooldown = restrain(((double)time) * attackSpeed / 1000d, 0, 1.5);
|
||||||
|
return cooldown>0.1 && cooldown<1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getCooldown() {
|
||||||
|
long time = System.currentTimeMillis()-lastHit;
|
||||||
|
return restrain(((double)time) * attackSpeed / 1000d, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private double restrain(double x, double a, double b) {
|
||||||
|
if (x<a) return a;
|
||||||
|
if (x>b) return b;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int max = 10;
|
||||||
|
private String getTitle() {
|
||||||
|
String symbol = cooldownIndicator==ViaRewindConfig.CooldownIndicator.ACTION_BAR ? "■" : "˙";
|
||||||
|
|
||||||
|
double cooldown = getCooldown();
|
||||||
|
int green = (int) Math.floor(((double)max) * cooldown);
|
||||||
|
int grey = max-green;
|
||||||
|
StringBuilder builder = new StringBuilder("§8");
|
||||||
|
while(green-->0) builder.append(symbol);
|
||||||
|
builder.append("§7");
|
||||||
|
while(grey-->0) builder.append(symbol);
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getAttackSpeed() {
|
||||||
|
return attackSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttackSpeed(double attackSpeed) {
|
||||||
|
this.attackSpeed = attackSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttackSpeed(double base, ArrayList<Pair<Byte, Double>> modifiers) {
|
||||||
|
attackSpeed = base;
|
||||||
|
for (int j = 0; j<modifiers.size(); j++) {
|
||||||
|
if (modifiers.get(j).getKey()==0) {
|
||||||
|
attackSpeed += modifiers.get(j).getValue();
|
||||||
|
modifiers.remove(j--);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int j = 0; j<modifiers.size(); j++) {
|
||||||
|
if (modifiers.get(j).getKey()==1) {
|
||||||
|
attackSpeed += base * modifiers.get(j).getValue();
|
||||||
|
modifiers.remove(j--);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int j = 0; j<modifiers.size(); j++) {
|
||||||
|
if (modifiers.get(j).getKey()==2) {
|
||||||
|
attackSpeed *= (1.0 + modifiers.get(j).getValue());
|
||||||
|
modifiers.remove(j--);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hit() {
|
||||||
|
lastHit = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastHit(long lastHit) {
|
||||||
|
this.lastHit = lastHit;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,176 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.storage;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.Protocol1_8TO1_9;
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.metadata.MetadataRewriter;
|
||||||
|
import com.elevatemc.spigot.viarewind.replacement.EntityReplacement;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.StoredObject;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.data.entity.ClientEntityIdChangeListener;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.Vector;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.entities.Entity1_10Types;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.Metadata;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.types.version.Types1_8;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public class EntityTracker extends StoredObject implements ClientEntityIdChangeListener {
|
||||||
|
private final Map<Integer, List<Integer>> vehicleMap = new ConcurrentHashMap<>();
|
||||||
|
private final Map<Integer, Entity1_10Types.EntityType> clientEntityTypes = new ConcurrentHashMap<>();
|
||||||
|
private final Map<Integer, List<Metadata>> metadataBuffer = new ConcurrentHashMap<>();
|
||||||
|
private final Map<Integer, EntityReplacement> entityReplacements = new ConcurrentHashMap<>();
|
||||||
|
private final Map<Integer, Vector> entityOffsets = new ConcurrentHashMap<>();
|
||||||
|
private int playerId;
|
||||||
|
private int playerGamemode = 0;
|
||||||
|
|
||||||
|
public EntityTracker(UserConnection user) {
|
||||||
|
super(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlayerId(int entityId) {
|
||||||
|
playerId = entityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPlayerId() {
|
||||||
|
return playerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPlayerGamemode() {
|
||||||
|
return playerGamemode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlayerGamemode(int playerGamemode) {
|
||||||
|
this.playerGamemode = playerGamemode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeEntity(int entityId) {
|
||||||
|
vehicleMap.remove(entityId);
|
||||||
|
vehicleMap.forEach((vehicle, passengers) -> passengers.remove((Integer)entityId));
|
||||||
|
vehicleMap.entrySet().removeIf(entry -> entry.getValue().isEmpty());
|
||||||
|
clientEntityTypes.remove(entityId);
|
||||||
|
entityOffsets.remove(entityId);
|
||||||
|
if (entityReplacements.containsKey(entityId)) {
|
||||||
|
entityReplacements.remove(entityId).despawn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetEntityOffset(int entityId) {
|
||||||
|
entityOffsets.remove(entityId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector getEntityOffset(int entityId) {
|
||||||
|
return entityOffsets.computeIfAbsent(entityId, key -> new Vector(0, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addToEntityOffset(int entityId, short relX, short relY, short relZ) {
|
||||||
|
entityOffsets.compute(entityId, (key, offset) -> {
|
||||||
|
if (offset == null) {
|
||||||
|
return new Vector(relX, relY, relZ);
|
||||||
|
} else {
|
||||||
|
offset.setBlockX(offset.getBlockX() + relX);
|
||||||
|
offset.setBlockY(offset.getBlockY() + relY);
|
||||||
|
offset.setBlockZ(offset.getBlockZ() + relZ);
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEntityOffset(int entityId, short relX, short relY, short relZ) {
|
||||||
|
entityOffsets.compute(entityId, (key, offset) -> {
|
||||||
|
if (offset == null) {
|
||||||
|
return new Vector(relX, relY, relZ);
|
||||||
|
} else {
|
||||||
|
offset.setBlockX(relX);
|
||||||
|
offset.setBlockY(relY);
|
||||||
|
offset.setBlockZ(relZ);
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEntityOffset(int entityId, Vector offset) {
|
||||||
|
entityOffsets.put(entityId, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Integer> getPassengers(int entityId) {
|
||||||
|
return vehicleMap.getOrDefault(entityId, new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassengers(int entityId, List<Integer> passengers) {
|
||||||
|
vehicleMap.put(entityId, passengers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addEntityReplacement(EntityReplacement entityReplacement) {
|
||||||
|
entityReplacements.put(entityReplacement.getEntityId(), entityReplacement);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityReplacement getEntityReplacement(int entityId) {
|
||||||
|
return entityReplacements.get(entityId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<Integer, Entity1_10Types.EntityType> getClientEntityTypes() {
|
||||||
|
return this.clientEntityTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMetadataToBuffer(int entityID, List<Metadata> metadataList) {
|
||||||
|
if (this.metadataBuffer.containsKey(entityID)) {
|
||||||
|
this.metadataBuffer.get(entityID).addAll(metadataList);
|
||||||
|
} else if (!metadataList.isEmpty()) {
|
||||||
|
this.metadataBuffer.put(entityID, metadataList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Metadata> getBufferedMetadata(int entityId) {
|
||||||
|
return metadataBuffer.get(entityId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInsideVehicle(int entityId) {
|
||||||
|
for (List<Integer> vehicle : vehicleMap.values()) {
|
||||||
|
if (vehicle.contains(entityId)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVehicle(int passenger) {
|
||||||
|
for (Map.Entry<Integer, List<Integer>> vehicle : vehicleMap.entrySet()) {
|
||||||
|
if (vehicle.getValue().contains(passenger)) return vehicle.getKey();
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPassenger(int vehicle, int passenger) {
|
||||||
|
return vehicleMap.containsKey(vehicle) && vehicleMap.get(vehicle).contains(passenger);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendMetadataBuffer(int entityId) {
|
||||||
|
if (!this.metadataBuffer.containsKey(entityId)) return;
|
||||||
|
if (entityReplacements.containsKey(entityId)) {
|
||||||
|
entityReplacements.get(entityId).updateMetadata(this.metadataBuffer.remove(entityId));
|
||||||
|
} else {
|
||||||
|
PacketWrapper wrapper = PacketWrapper.create(0x1C, null, this.getUser());
|
||||||
|
wrapper.write(Type.VAR_INT, entityId);
|
||||||
|
wrapper.write(Types1_8.METADATA_LIST, this.metadataBuffer.get(entityId));
|
||||||
|
MetadataRewriter.transform(this.getClientEntityTypes().get(entityId), this.metadataBuffer.get(entityId));
|
||||||
|
if (!this.metadataBuffer.get(entityId).isEmpty()) {
|
||||||
|
try {
|
||||||
|
wrapper.send(Protocol1_8TO1_9.class);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.metadataBuffer.remove(entityId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setClientEntityId(int playerEntityId) {
|
||||||
|
clientEntityTypes.remove(this.playerId);
|
||||||
|
this.playerId = playerEntityId;
|
||||||
|
clientEntityTypes.put(this.playerId, Entity1_10Types.EntityType.ENTITY_HUMAN);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.storage;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.Protocol1_8TO1_9;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.PacketUtil;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.Tickable;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.StoredObject;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
|
||||||
|
public class Levitation extends StoredObject implements Tickable {
|
||||||
|
private int amplifier;
|
||||||
|
private volatile boolean active = false;
|
||||||
|
|
||||||
|
public Levitation(UserConnection user) {
|
||||||
|
super(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
if (!active) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vY = (amplifier+1) * 360;
|
||||||
|
PacketWrapper packet = PacketWrapper.create(0x12, null, Levitation.this.getUser());
|
||||||
|
packet.write(Type.VAR_INT, getUser().get(EntityTracker.class).getPlayerId());
|
||||||
|
packet.write(Type.SHORT, (short)0);
|
||||||
|
packet.write(Type.SHORT, (short)vY);
|
||||||
|
packet.write(Type.SHORT, (short)0);
|
||||||
|
PacketUtil.sendPacket(packet, Protocol1_8TO1_9.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActive(boolean active) {
|
||||||
|
this.active = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmplifier(int amplifier) {
|
||||||
|
this.amplifier = amplifier;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,116 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.storage;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.StoredObject;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
|
||||||
|
public class PlayerPosition extends StoredObject {
|
||||||
|
private double posX, posY, posZ;
|
||||||
|
private float yaw, pitch;
|
||||||
|
private boolean onGround;
|
||||||
|
private int confirmId = -1;
|
||||||
|
|
||||||
|
public PlayerPosition(UserConnection user) {
|
||||||
|
super(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPos(double x, double y, double z) {
|
||||||
|
this.posX = x;
|
||||||
|
this.posY = y;
|
||||||
|
this.posZ = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYaw(float yaw) {
|
||||||
|
this.yaw = yaw % 360f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPitch(float pitch) {
|
||||||
|
this.pitch = pitch % 360f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getPosX() {
|
||||||
|
return this.posX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getPosY() {
|
||||||
|
return this.posY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getPosZ() {
|
||||||
|
return this.posZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getYaw() {
|
||||||
|
return this.yaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getPitch() {
|
||||||
|
return this.pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOnGround() {
|
||||||
|
return this.onGround;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getConfirmId() {
|
||||||
|
return this.confirmId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPosX(double posX) {
|
||||||
|
this.posX = posX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPosY(double posY) {
|
||||||
|
this.posY = posY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPosZ(double posZ) {
|
||||||
|
this.posZ = posZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnGround(boolean onGround) {
|
||||||
|
this.onGround = onGround;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfirmId(int confirmId) {
|
||||||
|
this.confirmId = confirmId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(final Object o) {
|
||||||
|
if (o == this) return true;
|
||||||
|
if (!(o instanceof PlayerPosition)) return false;
|
||||||
|
final PlayerPosition other = (PlayerPosition) o;
|
||||||
|
if (!other.canEqual((Object) this)) return false;
|
||||||
|
if (Double.compare(this.getPosX(), other.getPosX()) != 0) return false;
|
||||||
|
if (Double.compare(this.getPosY(), other.getPosY()) != 0) return false;
|
||||||
|
if (Double.compare(this.getPosZ(), other.getPosZ()) != 0) return false;
|
||||||
|
if (Float.compare(this.getYaw(), other.getYaw()) != 0) return false;
|
||||||
|
if (Float.compare(this.getPitch(), other.getPitch()) != 0) return false;
|
||||||
|
if (this.isOnGround() != other.isOnGround()) return false;
|
||||||
|
if (this.getConfirmId() != other.getConfirmId()) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean canEqual(final Object other) {
|
||||||
|
return other instanceof PlayerPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
final int PRIME = 59;
|
||||||
|
int result = 1;
|
||||||
|
final long $posX = Double.doubleToLongBits(this.getPosX());
|
||||||
|
result = result * PRIME + (int) ($posX >>> 32 ^ $posX);
|
||||||
|
final long $posY = Double.doubleToLongBits(this.getPosY());
|
||||||
|
result = result * PRIME + (int) ($posY >>> 32 ^ $posY);
|
||||||
|
final long $posZ = Double.doubleToLongBits(this.getPosZ());
|
||||||
|
result = result * PRIME + (int) ($posZ >>> 32 ^ $posZ);
|
||||||
|
result = result * PRIME + Float.floatToIntBits(this.getYaw());
|
||||||
|
result = result * PRIME + Float.floatToIntBits(this.getPitch());
|
||||||
|
result = result * PRIME + (this.isOnGround() ? 79 : 97);
|
||||||
|
result = result * PRIME + this.getConfirmId();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "PlayerPosition(posX=" + this.getPosX() + ", posY=" + this.getPosY() + ", posZ=" + this.getPosZ() + ", yaw=" + this.getYaw() + ", pitch=" + this.getPitch() + ", onGround=" + this.isOnGround() + ", confirmId=" + this.getConfirmId() + ")";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.storage;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.Protocol1_8TO1_9;
|
||||||
|
import com.elevatemc.spigot.viarewind.utils.PacketUtil;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.StoredObject;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.item.DataItem;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.item.Item;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class Windows extends StoredObject {
|
||||||
|
private HashMap<Short, String> types = new HashMap<>();
|
||||||
|
private HashMap<Short, Item[]> brewingItems = new HashMap<>();
|
||||||
|
|
||||||
|
public Windows(UserConnection user) {
|
||||||
|
super(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String get(short windowId) {
|
||||||
|
return types.get(windowId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(short windowId, String type) {
|
||||||
|
types.put(windowId, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(short windowId) {
|
||||||
|
types.remove(windowId);
|
||||||
|
brewingItems.remove(windowId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item[] getBrewingItems(short windowId) {
|
||||||
|
return brewingItems.computeIfAbsent(windowId, key -> new Item[] {
|
||||||
|
new DataItem(),
|
||||||
|
new DataItem(),
|
||||||
|
new DataItem(),
|
||||||
|
new DataItem()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void updateBrewingStand(UserConnection user, Item blazePowder, short windowId) {
|
||||||
|
if (blazePowder != null && blazePowder.identifier() != 377) return;
|
||||||
|
int amount = blazePowder == null ? 0 : blazePowder.amount();
|
||||||
|
PacketWrapper openWindow = PacketWrapper.create(0x2D, null, user);
|
||||||
|
openWindow.write(Type.UNSIGNED_BYTE, windowId);
|
||||||
|
openWindow.write(Type.STRING, "minecraft:brewing_stand");
|
||||||
|
openWindow.write(Type.STRING, "[{\"translate\":\"container.brewing\"},{\"text\":\": \",\"color\":\"dark_gray\"},{\"text\":\"§4" + amount + " \",\"color\":\"dark_red\"},{\"translate\":\"item.blazePowder.name\",\"color\":\"dark_red\"}]");
|
||||||
|
openWindow.write(Type.UNSIGNED_BYTE, (short) 420);
|
||||||
|
PacketUtil.sendPacket(openWindow, Protocol1_8TO1_9.class);
|
||||||
|
|
||||||
|
Item[] items = user.get(Windows.class).getBrewingItems(windowId);
|
||||||
|
for (int i = 0; i < items.length; i++) {
|
||||||
|
PacketWrapper setSlot = PacketWrapper.create(0x2F, null, user);
|
||||||
|
setSlot.write(Type.BYTE, (byte) windowId);
|
||||||
|
setSlot.write(Type.SHORT, (short) i);
|
||||||
|
setSlot.write(Type.ITEM, items[i]);
|
||||||
|
PacketUtil.sendPacket(setSlot, Protocol1_8TO1_9.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.util;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viarewind.protocol.protocol1_8to1_9.storage.EntityTracker;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.Vector;
|
||||||
|
|
||||||
|
public class RelativeMoveUtil {
|
||||||
|
|
||||||
|
public static Vector[] calculateRelativeMoves(UserConnection user, int entityId, int relX, int relY, int relZ) {
|
||||||
|
EntityTracker tracker = user.get(EntityTracker.class);
|
||||||
|
|
||||||
|
Vector offset = tracker.getEntityOffset(entityId);
|
||||||
|
relX += offset.getBlockX();
|
||||||
|
relY += offset.getBlockY();
|
||||||
|
relZ += offset.getBlockZ();
|
||||||
|
|
||||||
|
if (relX > Short.MAX_VALUE) {
|
||||||
|
offset.setBlockX(relX - Short.MAX_VALUE);
|
||||||
|
relX = Short.MAX_VALUE;
|
||||||
|
} else if (relX < Short.MIN_VALUE) {
|
||||||
|
offset.setBlockX(relX - Short.MIN_VALUE);
|
||||||
|
relX = Short.MIN_VALUE;
|
||||||
|
} else {
|
||||||
|
offset.setBlockX(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (relY > Short.MAX_VALUE) {
|
||||||
|
offset.setBlockY(relY - Short.MAX_VALUE);
|
||||||
|
relY = Short.MAX_VALUE;
|
||||||
|
} else if (relY < Short.MIN_VALUE) {
|
||||||
|
offset.setBlockY(relY - Short.MIN_VALUE);
|
||||||
|
relY = Short.MIN_VALUE;
|
||||||
|
} else {
|
||||||
|
offset.setBlockY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (relZ > Short.MAX_VALUE) {
|
||||||
|
offset.setBlockZ(relZ - Short.MAX_VALUE);
|
||||||
|
relZ = Short.MAX_VALUE;
|
||||||
|
} else if (relZ < Short.MIN_VALUE) {
|
||||||
|
offset.setBlockZ(relZ - Short.MIN_VALUE);
|
||||||
|
relZ = Short.MIN_VALUE;
|
||||||
|
} else {
|
||||||
|
offset.setBlockZ(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sentRelX, sentRelY, sentRelZ;
|
||||||
|
Vector[] moves;
|
||||||
|
|
||||||
|
if (relX > Byte.MAX_VALUE * 128 || relX < Byte.MIN_VALUE * 128 || relY > Byte.MAX_VALUE * 128 || relY < Byte.MIN_VALUE * 128 || relZ > Byte.MAX_VALUE * 128 || relZ < Byte.MIN_VALUE * 128) {
|
||||||
|
byte relX1 = (byte) (relX / 256);
|
||||||
|
byte relX2 = (byte) (Math.round((relX - relX1 * 128) / 128f));
|
||||||
|
byte relY1 = (byte) (relY / 256);
|
||||||
|
byte relY2 = (byte) (Math.round((relY - relY1 * 128) / 128f));
|
||||||
|
byte relZ1 = (byte) (relZ / 256);
|
||||||
|
byte relZ2 = (byte) (Math.round((relZ - relZ1 * 128) / 128f));
|
||||||
|
|
||||||
|
sentRelX = relX1 + relX2;
|
||||||
|
sentRelY = relY1 + relY2;
|
||||||
|
sentRelZ = relZ1 + relZ2;
|
||||||
|
|
||||||
|
moves = new Vector[] {new Vector(relX1, relY1, relZ1), new Vector(relX2, relY2, relZ2)};
|
||||||
|
} else {
|
||||||
|
sentRelX = Math.round(relX / 128f);
|
||||||
|
sentRelY = Math.round(relY / 128f);
|
||||||
|
sentRelZ = Math.round(relZ / 128f);
|
||||||
|
|
||||||
|
moves = new Vector[] {new Vector(sentRelX, sentRelY, sentRelZ)};
|
||||||
|
}
|
||||||
|
|
||||||
|
offset.setBlockX(offset.getBlockX() + relX - sentRelX * 128);
|
||||||
|
offset.setBlockY(offset.getBlockY() + relY - sentRelY * 128);
|
||||||
|
offset.setBlockZ(offset.getBlockZ() + relZ - sentRelZ * 128);
|
||||||
|
|
||||||
|
tracker.setEntityOffset(entityId, offset);
|
||||||
|
|
||||||
|
return moves;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.replacement;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.metadata.Metadata;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface EntityReplacement {
|
||||||
|
|
||||||
|
int getEntityId();
|
||||||
|
|
||||||
|
void setLocation(double x, double y, double z);
|
||||||
|
|
||||||
|
void relMove(double x, double y, double z);
|
||||||
|
|
||||||
|
void setYawPitch(float yaw, float pitch);
|
||||||
|
|
||||||
|
void setHeadYaw(float yaw);
|
||||||
|
|
||||||
|
void spawn();
|
||||||
|
|
||||||
|
void despawn();
|
||||||
|
|
||||||
|
void updateMetadata(List<Metadata> metadataList);
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.replacement;
|
||||||
|
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.item.Item;
|
||||||
|
|
||||||
|
public class Replacement {
|
||||||
|
private int id, data;
|
||||||
|
private String name, resetName, bracketName;
|
||||||
|
|
||||||
|
public Replacement(int id) {
|
||||||
|
this(id, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Replacement(int id, int data) {
|
||||||
|
this(id, data, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Replacement(int id, String name) {
|
||||||
|
this(id, -1, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Replacement(int id, int data, String name) {
|
||||||
|
this.id = id;
|
||||||
|
this.data = data;
|
||||||
|
this.name = name;
|
||||||
|
if (name!=null) {
|
||||||
|
this.resetName = "§r" + name;
|
||||||
|
this.bracketName = " §r§7(" + name + "§r§7)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item replace(Item item) {
|
||||||
|
item.setIdentifier(id);
|
||||||
|
if (data!=-1) item.setData((short)data);
|
||||||
|
if (name!=null) {
|
||||||
|
CompoundTag compoundTag = item.tag()==null ? new CompoundTag() : item.tag();
|
||||||
|
if (!compoundTag.contains("display")) compoundTag.put("display", new CompoundTag());
|
||||||
|
CompoundTag display = compoundTag.get("display");
|
||||||
|
if (display.contains("Name")) {
|
||||||
|
StringTag name = display.get("Name");
|
||||||
|
if (!name.getValue().equals(resetName) && !name.getValue().endsWith(bracketName))
|
||||||
|
name.setValue(name.getValue() + bracketName);
|
||||||
|
} else {
|
||||||
|
display.put("Name", new StringTag(resetName));
|
||||||
|
}
|
||||||
|
item.setTag(compoundTag);
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int replaceData(int data) {
|
||||||
|
return this.data == -1 ? data : this.data;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.replacement;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.minecraft.item.Item;
|
||||||
|
|
||||||
|
|
||||||
|
public class ReplacementRegistry {
|
||||||
|
private final Int2ObjectMap<Replacement> itemReplacements = new Int2ObjectOpenHashMap<>();
|
||||||
|
private final Int2ObjectMap<Replacement> blockReplacements = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
public void registerItem(int id, Replacement replacement) {
|
||||||
|
registerItem(id, -1, replacement);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerBlock(int id, Replacement replacement) {
|
||||||
|
registerBlock(id, -1, replacement);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerItemBlock(int id, Replacement replacement) {
|
||||||
|
registerItemBlock(id, -1, replacement);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerItem(int id, int data, Replacement replacement) {
|
||||||
|
itemReplacements.put(combine(id, data), replacement);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerBlock(int id, int data, Replacement replacement) {
|
||||||
|
blockReplacements.put(combine(id, data), replacement);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerItemBlock(int id, int data, Replacement replacement) {
|
||||||
|
registerItem(id, data, replacement);
|
||||||
|
registerBlock(id, data, replacement);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item replace(Item item) {
|
||||||
|
Replacement replacement = itemReplacements.get(combine(item.identifier(), item.data()));
|
||||||
|
if (replacement==null) replacement = itemReplacements.get(combine(item.identifier(), -1));
|
||||||
|
return replacement==null ? item : replacement.replace(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Replacement replace(int id, int data) {
|
||||||
|
Replacement replacement = blockReplacements.get(combine(id, data));
|
||||||
|
if (replacement == null) {
|
||||||
|
replacement = blockReplacements.get(combine(id, -1));
|
||||||
|
}
|
||||||
|
return replacement;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int combine(int id, int data) {
|
||||||
|
return (id << 16) | (data & 0xFFFF);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.storage;
|
||||||
|
|
||||||
|
public class BlockState {
|
||||||
|
|
||||||
|
public static int extractId(int raw) {
|
||||||
|
return raw >> 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int extractData(int raw) {
|
||||||
|
return raw & 0xF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int stateToRaw(int id, int data) {
|
||||||
|
return (id << 4) | (data & 0xF);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.types;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.type.Type;
|
||||||
|
|
||||||
|
public class VarLongType extends Type<Long> {
|
||||||
|
|
||||||
|
public static final VarLongType VAR_LONG = new VarLongType();
|
||||||
|
|
||||||
|
public VarLongType() {
|
||||||
|
super("VarLong", Long.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long read(ByteBuf byteBuf) throws Exception {
|
||||||
|
long i = 0L;
|
||||||
|
int j = 0;
|
||||||
|
byte b0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
b0 = byteBuf.readByte();
|
||||||
|
i |= (b0 & 0x7F) << j++ * 7;
|
||||||
|
if (j > 10) {
|
||||||
|
throw new RuntimeException("VarLong too big");
|
||||||
|
}
|
||||||
|
} while ((b0 & 0x80) == 128);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(ByteBuf byteBuf, Long i) throws Exception {
|
||||||
|
while ((i & 0xFFFFFFFFFFFFFF80L) != 0L)
|
||||||
|
{
|
||||||
|
byteBuf.writeByte((int)(i & 0x7F) | 0x80);
|
||||||
|
i >>>= 7;
|
||||||
|
}
|
||||||
|
byteBuf.writeByte(i.intValue());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.utils;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
|
import com.elevatemc.spigot.viarewind.ViaRewind;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_13to1_12_2.ChatRewriter;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class ChatUtil {
|
||||||
|
private static final Pattern UNUSED_COLOR_PATTERN = Pattern.compile("(?>(?>§[0-fk-or])*(§r|\\Z))|(?>(?>§[0-f])*(§[0-f]))");
|
||||||
|
|
||||||
|
public static String jsonToLegacy(String json) {
|
||||||
|
if (json == null || json.equals("null") || json.isEmpty()) return "";
|
||||||
|
try {
|
||||||
|
String legacy = LegacyComponentSerializer.legacySection().serialize(ChatRewriter.HOVER_GSON_SERIALIZER.deserialize(json));
|
||||||
|
while (legacy.startsWith("§f")) legacy = legacy.substring(2);
|
||||||
|
return legacy;
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ViaRewind.getPlatform().getLogger().log(Level.WARNING, "Could not convert component to legacy text: " + json, ex);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String jsonToLegacy(JsonElement component) {
|
||||||
|
if (component.isJsonNull() || component.isJsonArray() && component.getAsJsonArray().size() == 0 ||
|
||||||
|
component.isJsonObject() && component.getAsJsonObject().entrySet().isEmpty()) {
|
||||||
|
return "";
|
||||||
|
} else if (component.isJsonPrimitive()) {
|
||||||
|
return component.getAsString();
|
||||||
|
} else {
|
||||||
|
return jsonToLegacy(component.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String legacyToJson(String legacy) {
|
||||||
|
if (legacy == null) return "";
|
||||||
|
return GsonComponentSerializer.gson().serialize(LegacyComponentSerializer.legacySection().deserialize(legacy));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String removeUnusedColor(String legacy, char last) {
|
||||||
|
if (legacy == null) return null;
|
||||||
|
legacy = UNUSED_COLOR_PATTERN.matcher(legacy).replaceAll("$1$2");
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
for (int i = 0; i < legacy.length(); i++) {
|
||||||
|
char current = legacy.charAt(i);
|
||||||
|
if (current != '§' || i == legacy.length() - 1) {
|
||||||
|
builder.append(current);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
current = legacy.charAt(++i);
|
||||||
|
if (current == last) continue;
|
||||||
|
builder.append('§').append(current);
|
||||||
|
last = current;
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.utils;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class Enchantments {
|
||||||
|
public static final Map<Short, String> ENCHANTMENTS = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
ENCHANTMENTS.put((short) 1, "I");
|
||||||
|
ENCHANTMENTS.put((short) 2, "II");
|
||||||
|
ENCHANTMENTS.put((short) 3, "III");
|
||||||
|
ENCHANTMENTS.put((short) 4, "IV");
|
||||||
|
ENCHANTMENTS.put((short) 5, "V");
|
||||||
|
ENCHANTMENTS.put((short) 6, "VI");
|
||||||
|
ENCHANTMENTS.put((short) 7, "VII");
|
||||||
|
ENCHANTMENTS.put((short) 8, "VIII");
|
||||||
|
ENCHANTMENTS.put((short) 9, "IX");
|
||||||
|
ENCHANTMENTS.put((short) 10, "X");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.utils;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.Protocol;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
import com.elevatemc.spigot.viaversion.exception.CancelException;
|
||||||
|
|
||||||
|
public class PacketUtil {
|
||||||
|
|
||||||
|
public static void sendToServer(PacketWrapper packet, Class<? extends Protocol> packetProtocol) {
|
||||||
|
sendToServer(packet, packetProtocol, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendToServer(PacketWrapper packet, Class<? extends Protocol> packetProtocol, boolean skipCurrentPipeline) {
|
||||||
|
sendToServer(packet, packetProtocol, skipCurrentPipeline, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendToServer(PacketWrapper packet, Class<? extends Protocol> packetProtocol, boolean skipCurrentPipeline, boolean currentThread) {
|
||||||
|
try {
|
||||||
|
if (currentThread) {
|
||||||
|
packet.sendToServer(packetProtocol, skipCurrentPipeline);
|
||||||
|
} else {
|
||||||
|
packet.scheduleSendToServer(packetProtocol, skipCurrentPipeline);
|
||||||
|
}
|
||||||
|
} catch (CancelException ignored) {
|
||||||
|
;
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean sendPacket(PacketWrapper packet, Class<? extends Protocol> packetProtocol) {
|
||||||
|
return sendPacket(packet, packetProtocol, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean sendPacket(PacketWrapper packet, Class<? extends Protocol> packetProtocol, boolean skipCurrentPipeline) {
|
||||||
|
return sendPacket(packet, packetProtocol, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean sendPacket(PacketWrapper packet, Class<? extends Protocol> packetProtocol, boolean skipCurrentPipeline, boolean currentThread) {
|
||||||
|
try {
|
||||||
|
if (currentThread) {
|
||||||
|
packet.send(packetProtocol, skipCurrentPipeline);
|
||||||
|
} else {
|
||||||
|
packet.scheduleSend(packetProtocol, skipCurrentPipeline);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch (CancelException ignored) {
|
||||||
|
;
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.utils;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.Protocol;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
|
|
||||||
|
public interface ServerSender {
|
||||||
|
|
||||||
|
void sendToServer(PacketWrapper packet, Class<? extends Protocol> packetProtocol, boolean skipCurrentPipeline, boolean currentThread) throws Exception;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.utils;
|
||||||
|
|
||||||
|
public interface Tickable {
|
||||||
|
void tick();
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.utils;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viaversion.api.Via;
|
||||||
|
|
||||||
|
public class Ticker {
|
||||||
|
private static boolean init = false;
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
if (init) return;
|
||||||
|
synchronized (Ticker.class) {
|
||||||
|
if (init) return;
|
||||||
|
init = true;
|
||||||
|
}
|
||||||
|
Via.getPlatform().runRepeatingSync(() ->
|
||||||
|
Via.getManager().getConnectionManager().getConnections().forEach(user ->
|
||||||
|
user.getStoredObjects().values().stream()
|
||||||
|
.filter(Tickable.class::isInstance)
|
||||||
|
.map(Tickable.class::cast)
|
||||||
|
.forEach(Tickable::tick)
|
||||||
|
), 1L);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.utils;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class Utils {
|
||||||
|
|
||||||
|
public static UUID getUUID(UserConnection user) {
|
||||||
|
return user.getProtocolInfo().getUuid();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.utils.math;
|
||||||
|
|
||||||
|
public class AABB {
|
||||||
|
Vector3d min;
|
||||||
|
Vector3d max;
|
||||||
|
|
||||||
|
public AABB(Vector3d min, Vector3d max) {
|
||||||
|
this.min = min;
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3d getMin() {
|
||||||
|
return this.min;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3d getMax() {
|
||||||
|
return this.max;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.utils.math;
|
||||||
|
|
||||||
|
public class Ray3d {
|
||||||
|
Vector3d start;
|
||||||
|
Vector3d dir;
|
||||||
|
|
||||||
|
public Ray3d(Vector3d start, Vector3d dir) {
|
||||||
|
this.start = start;
|
||||||
|
this.dir = dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3d getStart() {
|
||||||
|
return this.start;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3d getDir() {
|
||||||
|
return this.dir;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.utils.math;
|
||||||
|
|
||||||
|
public class RayTracing {
|
||||||
|
|
||||||
|
public static Vector3d trace(Ray3d ray, AABB aabb, double distance) {
|
||||||
|
Vector3d invDir = new Vector3d(1f / ray.dir.x, 1f / ray.dir.y, 1f / ray.dir.z);
|
||||||
|
|
||||||
|
boolean signDirX = invDir.x < 0;
|
||||||
|
boolean signDirY = invDir.y < 0;
|
||||||
|
boolean signDirZ = invDir.z < 0;
|
||||||
|
|
||||||
|
Vector3d bbox = signDirX ? aabb.max : aabb.min;
|
||||||
|
double tmin = (bbox.x - ray.start.x) * invDir.x;
|
||||||
|
bbox = signDirX ? aabb.min : aabb.max;
|
||||||
|
double tmax = (bbox.x - ray.start.x) * invDir.x;
|
||||||
|
bbox = signDirY ? aabb.max : aabb.min;
|
||||||
|
double tymin = (bbox.y - ray.start.y) * invDir.y;
|
||||||
|
bbox = signDirY ? aabb.min : aabb.max;
|
||||||
|
double tymax = (bbox.y - ray.start.y) * invDir.y;
|
||||||
|
|
||||||
|
if (tmin > tymax || tymin > tmax) return null;
|
||||||
|
|
||||||
|
if (tymin > tmin) tmin = tymin;
|
||||||
|
|
||||||
|
if (tymax < tmax) tmax = tymax;
|
||||||
|
|
||||||
|
bbox = signDirZ ? aabb.max : aabb.min;
|
||||||
|
double tzmin = (bbox.z - ray.start.z) * invDir.z;
|
||||||
|
bbox = signDirZ ? aabb.min : aabb.max;
|
||||||
|
double tzmax = (bbox.z - ray.start.z) * invDir.z;
|
||||||
|
|
||||||
|
if (tmin > tzmax || tzmin > tmax) return null;
|
||||||
|
|
||||||
|
if (tzmin > tmin) tmin = tzmin;
|
||||||
|
|
||||||
|
if (tzmax < tmax) tmax = tzmax;
|
||||||
|
|
||||||
|
return tmin <= distance && tmax > 0 ? ray.start.clone().add(ray.dir.clone().normalize().multiply(tmin)) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,110 @@
|
|||||||
|
package com.elevatemc.spigot.viarewind.utils.math;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class Vector3d {
|
||||||
|
double x, y, z;
|
||||||
|
|
||||||
|
public Vector3d(double x, double y, double z) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3d() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(Vector3d vec) {
|
||||||
|
this.x = vec.x;
|
||||||
|
this.y = vec.y;
|
||||||
|
this.z = vec.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3d set(double x, double y, double z) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3d multiply(double a) {
|
||||||
|
this.x *= a;
|
||||||
|
this.y *= a;
|
||||||
|
this.z *= a;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3d add(Vector3d vec) {
|
||||||
|
this.x += vec.x;
|
||||||
|
this.y += vec.y;
|
||||||
|
this.z += vec.z;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3d substract(Vector3d vec) {
|
||||||
|
this.x -= vec.x;
|
||||||
|
this.y -= vec.y;
|
||||||
|
this.z -= vec.z;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double length() {
|
||||||
|
return Math.sqrt(lengthSquared());
|
||||||
|
}
|
||||||
|
|
||||||
|
public double lengthSquared() {
|
||||||
|
return this.x * this.x + this.y * this.y + this.z * this.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3d normalize() {
|
||||||
|
double length = length();
|
||||||
|
multiply(1.0 / length);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3d clone() {
|
||||||
|
return new Vector3d(this.x, this.y, this.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
Vector3d vector3d = (Vector3d) o;
|
||||||
|
return Double.compare(vector3d.x, x) == 0 && Double.compare(vector3d.y, y) == 0 && Double.compare(vector3d.z, z) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Vector3d{" + "x=" + x + ", y=" + y + ", z=" + z + '}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getX() {
|
||||||
|
return this.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getY() {
|
||||||
|
return this.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getZ() {
|
||||||
|
return this.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(double x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setY(double y) {
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setZ(double z) {
|
||||||
|
this.z = z;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||||
|
* Copyright (C) 2016-2021 ViaVersion and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.elevatemc.spigot.viaversion;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.Via;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.ViaAPI;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.legacy.LegacyViaAPI;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.version.BlockedProtocolVersions;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.version.ServerProtocolVersion;
|
||||||
|
import com.elevatemc.spigot.viaversion.legacy.LegacyAPI;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
import java.util.SortedSet;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public abstract class ViaAPIBase<T> implements ViaAPI<T> {
|
||||||
|
|
||||||
|
private final LegacyAPI<T> legacy = new LegacyAPI<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerProtocolVersion getServerVersion() {
|
||||||
|
return Via.getManager().getProtocolManager().getServerProtocolVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPlayerVersion(UUID uuid) {
|
||||||
|
UserConnection connection = Via.getManager().getConnectionManager().getConnectedClient(uuid);
|
||||||
|
return connection != null ? connection.getProtocolInfo().getProtocolVersion() : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getVersion() {
|
||||||
|
return Via.getPlatform().getPluginVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInjected(UUID uuid) {
|
||||||
|
return Via.getManager().getConnectionManager().isClientConnected(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable UserConnection getConnection(final UUID uuid) {
|
||||||
|
return Via.getManager().getConnectionManager().getConnectedClient(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRawPacket(UUID uuid, ByteBuf packet) throws IllegalArgumentException {
|
||||||
|
if (!isInjected(uuid)) {
|
||||||
|
throw new IllegalArgumentException("This player is not controlled by ViaVersion!");
|
||||||
|
}
|
||||||
|
|
||||||
|
UserConnection user = Via.getManager().getConnectionManager().getConnectedClient(uuid);
|
||||||
|
user.scheduleSendRawPacket(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SortedSet<Integer> getSupportedVersions() {
|
||||||
|
SortedSet<Integer> outputSet = new TreeSet<>(Via.getManager().getProtocolManager().getSupportedVersions());
|
||||||
|
BlockedProtocolVersions blockedVersions = Via.getPlatform().getConf().blockedProtocolVersions();
|
||||||
|
outputSet.removeIf(blockedVersions::contains);
|
||||||
|
return outputSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SortedSet<Integer> getFullSupportedVersions() {
|
||||||
|
return Via.getManager().getProtocolManager().getSupportedVersions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LegacyViaAPI<T> legacyAPI() {
|
||||||
|
return legacy;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||||
|
* Copyright (C) 2016-2021 ViaVersion and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.elevatemc.spigot.viaversion;
|
||||||
|
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viaversion.api.Via;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.Protocol;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public abstract class ViaListener {
|
||||||
|
private final Class<? extends Protocol> requiredPipeline;
|
||||||
|
private boolean registered;
|
||||||
|
|
||||||
|
protected ViaListener(Class<? extends Protocol> requiredPipeline) {
|
||||||
|
this.requiredPipeline = requiredPipeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the UserConnection from an UUID
|
||||||
|
*
|
||||||
|
* @param uuid UUID object
|
||||||
|
* @return The UserConnection
|
||||||
|
*/
|
||||||
|
protected @Nullable UserConnection getUserConnection(UUID uuid) {
|
||||||
|
return Via.getManager().getConnectionManager().getConnectedClient(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the UUID is on the selected pipe
|
||||||
|
*
|
||||||
|
* @param uuid UUID Object
|
||||||
|
* @return True if on pipe
|
||||||
|
*/
|
||||||
|
protected boolean isOnPipe(UUID uuid) {
|
||||||
|
UserConnection userConnection = getUserConnection(uuid);
|
||||||
|
return userConnection != null &&
|
||||||
|
(requiredPipeline == null || userConnection.getProtocolInfo().getPipeline().contains(requiredPipeline));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the event
|
||||||
|
*/
|
||||||
|
public abstract void register();
|
||||||
|
|
||||||
|
protected Class<? extends Protocol> getRequiredPipeline() {
|
||||||
|
return requiredPipeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isRegistered() {
|
||||||
|
return registered;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setRegistered(boolean registered) {
|
||||||
|
this.registered = registered;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,319 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||||
|
* Copyright (C) 2016-2021 ViaVersion and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.elevatemc.spigot.viaversion;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntSortedSet;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.Via;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.ViaManager;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.ConnectionManager;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.debug.DebugHandler;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.platform.*;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.platform.providers.ViaProviders;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.ProtocolManager;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.version.ProtocolVersion;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.version.ServerProtocolVersion;
|
||||||
|
import com.elevatemc.spigot.viaversion.commands.ViaCommandHandler;
|
||||||
|
import com.elevatemc.spigot.viaversion.connection.ConnectionManagerImpl;
|
||||||
|
import com.elevatemc.spigot.viaversion.debug.DebugHandlerImpl;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocol.ProtocolManagerImpl;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocol.ServerProtocolVersionRange;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocol.ServerProtocolVersionSingleton;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_13to1_12_2.TabCompleteThread;
|
||||||
|
import com.elevatemc.spigot.viaversion.protocols.protocol1_9to1_8.ViaIdleThread;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class ViaManagerImpl implements ViaManager {
|
||||||
|
private final ProtocolManagerImpl protocolManager = new ProtocolManagerImpl();
|
||||||
|
private final ConnectionManager connectionManager = new ConnectionManagerImpl();
|
||||||
|
private final DebugHandler debugHandler = new DebugHandlerImpl();
|
||||||
|
private final ViaProviders providers = new ViaProviders();
|
||||||
|
private final ViaPlatform<?> platform;
|
||||||
|
private final ViaInjector injector;
|
||||||
|
private final ViaCommandHandler commandHandler;
|
||||||
|
private final ViaPlatformLoader loader;
|
||||||
|
private final Set<String> subPlatforms = new HashSet<>();
|
||||||
|
private List<Runnable> enableListeners = new ArrayList<>();
|
||||||
|
private PlatformTask mappingLoadingTask;
|
||||||
|
private boolean debug;
|
||||||
|
|
||||||
|
public ViaManagerImpl(ViaPlatform<?> platform, ViaInjector injector, ViaCommandHandler commandHandler, ViaPlatformLoader loader) {
|
||||||
|
this.platform = platform;
|
||||||
|
this.injector = injector;
|
||||||
|
this.commandHandler = commandHandler;
|
||||||
|
this.loader = loader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ViaManagerBuilder builder() {
|
||||||
|
return new ViaManagerBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init() {
|
||||||
|
if (System.getProperty("ViaVersion") != null) {
|
||||||
|
// Reload?
|
||||||
|
platform.onReload();
|
||||||
|
}
|
||||||
|
// Check for updates
|
||||||
|
|
||||||
|
|
||||||
|
// Load supported protocol versions if we can
|
||||||
|
if (!injector.lateProtocolVersionSetting()) {
|
||||||
|
loadServerProtocol();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register protocols
|
||||||
|
protocolManager.registerProtocols();
|
||||||
|
|
||||||
|
// Inject
|
||||||
|
try {
|
||||||
|
injector.inject();
|
||||||
|
} catch (Exception e) {
|
||||||
|
platform.getLogger().severe("ViaVersion failed to inject:");
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark as injected
|
||||||
|
System.setProperty("ViaVersion", platform.getPluginVersion());
|
||||||
|
|
||||||
|
for (Runnable listener : enableListeners) {
|
||||||
|
listener.run();
|
||||||
|
}
|
||||||
|
enableListeners = null;
|
||||||
|
|
||||||
|
// If successful
|
||||||
|
platform.runSync(this::onServerLoaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onServerLoaded() {
|
||||||
|
if (!protocolManager.getServerProtocolVersion().isKnown()) {
|
||||||
|
// Try again
|
||||||
|
loadServerProtocol();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if there are any pipes to this version
|
||||||
|
ServerProtocolVersion protocolVersion = protocolManager.getServerProtocolVersion();
|
||||||
|
|
||||||
|
checkJavaVersion();
|
||||||
|
|
||||||
|
// Check for unsupported plugins/software
|
||||||
|
unsupportedSoftwareWarning();
|
||||||
|
|
||||||
|
// Load Listeners / Tasks
|
||||||
|
protocolManager.onServerLoaded();
|
||||||
|
|
||||||
|
// Load Platform
|
||||||
|
loader.load();
|
||||||
|
// Common tasks
|
||||||
|
mappingLoadingTask = Via.getPlatform().runRepeatingSync(() -> {
|
||||||
|
if (protocolManager.checkForMappingCompletion()) {
|
||||||
|
mappingLoadingTask.cancel();
|
||||||
|
mappingLoadingTask = null;
|
||||||
|
}
|
||||||
|
}, 10L);
|
||||||
|
|
||||||
|
int serverProtocolVersion = protocolManager.getServerProtocolVersion().lowestSupportedVersion();
|
||||||
|
if (serverProtocolVersion < ProtocolVersion.v1_9.getVersion()) {
|
||||||
|
if (Via.getConfig().isSimulatePlayerTick()) {
|
||||||
|
Via.getPlatform().runRepeatingSync(new ViaIdleThread(), 1L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (serverProtocolVersion < ProtocolVersion.v1_13.getVersion()) {
|
||||||
|
if (Via.getConfig().get1_13TabCompleteDelay() > 0) {
|
||||||
|
Via.getPlatform().runRepeatingSync(new TabCompleteThread(), 1L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh Versions
|
||||||
|
protocolManager.refreshVersions();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadServerProtocol() {
|
||||||
|
try {
|
||||||
|
ProtocolVersion serverProtocolVersion = ProtocolVersion.getProtocol(injector.getServerProtocolVersion());
|
||||||
|
ServerProtocolVersion versionInfo;
|
||||||
|
if (platform.isProxy()) {
|
||||||
|
IntSortedSet supportedVersions = injector.getServerProtocolVersions();
|
||||||
|
versionInfo = new ServerProtocolVersionRange(supportedVersions.firstInt(), supportedVersions.lastInt(), supportedVersions);
|
||||||
|
} else {
|
||||||
|
versionInfo = new ServerProtocolVersionSingleton(serverProtocolVersion.getVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
protocolManager.setServerProtocol(versionInfo);
|
||||||
|
} catch (Exception e) {
|
||||||
|
platform.getLogger().severe("ViaVersion failed to get the server protocol!");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroy() {
|
||||||
|
// Uninject
|
||||||
|
platform.getLogger().info("ViaVersion is disabling, if this is a reload and you experience issues consider rebooting.");
|
||||||
|
try {
|
||||||
|
injector.uninject();
|
||||||
|
} catch (Exception e) {
|
||||||
|
platform.getLogger().severe("ViaVersion failed to uninject:");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unload
|
||||||
|
loader.unload();
|
||||||
|
}
|
||||||
|
|
||||||
|
private final void checkJavaVersion() { // Stolen from Paper
|
||||||
|
String javaVersion = System.getProperty("java.version");
|
||||||
|
Matcher matcher = Pattern.compile("(?:1\\.)?(\\d+)").matcher(javaVersion);
|
||||||
|
if (!matcher.find()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String versionString = matcher.group(1);
|
||||||
|
int version;
|
||||||
|
try {
|
||||||
|
version = Integer.parseInt(versionString);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version < 17) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final void unsupportedSoftwareWarning() {
|
||||||
|
boolean found = false;
|
||||||
|
for (UnsupportedSoftware software : platform.getUnsupportedSoftwareClasses()) {
|
||||||
|
if (!software.findMatch()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Found something
|
||||||
|
if (!found) {
|
||||||
|
platform.getLogger().severe("************************************************");
|
||||||
|
platform.getLogger().severe("You are using unsupported software and may encounter unforeseeable issues.");
|
||||||
|
platform.getLogger().severe("");
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
platform.getLogger().severe("We strongly advise against using " + software.getName() + ":");
|
||||||
|
platform.getLogger().severe(software.getReason());
|
||||||
|
platform.getLogger().severe("");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
platform.getLogger().severe("We will not provide support in case you encounter issues possibly related to this software.");
|
||||||
|
platform.getLogger().severe("************************************************");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ViaPlatform<?> getPlatform() {
|
||||||
|
return platform;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConnectionManager getConnectionManager() {
|
||||||
|
return connectionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProtocolManager getProtocolManager() {
|
||||||
|
return protocolManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ViaProviders getProviders() {
|
||||||
|
return providers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DebugHandler debugHandler() {
|
||||||
|
return debugHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ViaInjector getInjector() {
|
||||||
|
return injector;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ViaCommandHandler getCommandHandler() {
|
||||||
|
return commandHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ViaPlatformLoader getLoader() {
|
||||||
|
return loader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a mutable set of self-added subplatform version strings.
|
||||||
|
* This set is expanded by the subplatform itself (e.g. ViaBackwards), and may not contain all running ones.
|
||||||
|
*
|
||||||
|
* @return mutable set of subplatform versions
|
||||||
|
*/
|
||||||
|
public Set<String> getSubPlatforms() {
|
||||||
|
return subPlatforms;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a runnable to be executed when ViaVersion has finished its init before the full server load.
|
||||||
|
*
|
||||||
|
* @param runnable runnable to be executed
|
||||||
|
*/
|
||||||
|
public void addEnableListener(Runnable runnable) {
|
||||||
|
enableListeners.add(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class ViaManagerBuilder {
|
||||||
|
private ViaPlatform<?> platform;
|
||||||
|
private ViaInjector injector;
|
||||||
|
private ViaCommandHandler commandHandler;
|
||||||
|
private ViaPlatformLoader loader;
|
||||||
|
|
||||||
|
public ViaManagerBuilder platform(ViaPlatform<?> platform) {
|
||||||
|
this.platform = platform;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ViaManagerBuilder injector(ViaInjector injector) {
|
||||||
|
this.injector = injector;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ViaManagerBuilder loader(ViaPlatformLoader loader) {
|
||||||
|
this.loader = loader;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ViaManagerBuilder commandHandler(ViaCommandHandler commandHandler) {
|
||||||
|
this.commandHandler = commandHandler;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ViaManagerImpl build() {
|
||||||
|
return new ViaManagerImpl(platform, injector, commandHandler, loader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||||
|
* Copyright (C) 2016-2022 ViaVersion and contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.elevatemc.spigot.viaversion.api;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.configuration.ViaVersionConfig;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.platform.ViaPlatform;
|
||||||
|
|
||||||
|
public final class Via {
|
||||||
|
private static ViaManager manager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the API associated with the current platform.
|
||||||
|
*
|
||||||
|
* @return API instance
|
||||||
|
* @throws IllegalArgumentException if the platform has not loaded yet
|
||||||
|
*/
|
||||||
|
public static ViaAPI getAPI() {
|
||||||
|
return manager().getPlatform().getApi();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the ViaManager with methods beyond the simple API {@link ViaAPI} provides.
|
||||||
|
*
|
||||||
|
* @return manager to interact with various Via parts
|
||||||
|
* @throws IllegalArgumentException if the platform has not loaded yet
|
||||||
|
*/
|
||||||
|
public static ViaManager getManager() {
|
||||||
|
return manager();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the config associated with the current platform.
|
||||||
|
*
|
||||||
|
* @return config instance
|
||||||
|
* @throws IllegalArgumentException if the platform has not loaded yet
|
||||||
|
*/
|
||||||
|
public static ViaVersionConfig getConfig() {
|
||||||
|
return manager().getPlatform().getConf();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ViaPlatform getPlatform() {
|
||||||
|
return manager().getPlatform();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the ViaManager associated with the platform.
|
||||||
|
*
|
||||||
|
* @param viaManager The ViaManager
|
||||||
|
* @throws IllegalArgumentException if the manager has already been set
|
||||||
|
*/
|
||||||
|
public static void init(ViaManager viaManager) {
|
||||||
|
Preconditions.checkArgument(manager == null, "ViaManager is already set");
|
||||||
|
Via.manager = viaManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ViaManager manager() {
|
||||||
|
Preconditions.checkArgument(manager != null, "ViaVersion has not loaded the platform yet");
|
||||||
|
return manager;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,160 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||||
|
* Copyright (C) 2016-2022 ViaVersion and contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.elevatemc.spigot.viaversion.api;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.ConnectionManager;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.UserConnection;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.legacy.LegacyViaAPI;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.platform.ViaPlatform;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.ProtocolManager;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.version.ServerProtocolVersion;
|
||||||
|
|
||||||
|
import java.util.SortedSet;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* General api point. For more specialized api methods, see {@link Via#getManager()}.
|
||||||
|
*
|
||||||
|
* @param <T> player type for the specific platform
|
||||||
|
* @see ViaManager
|
||||||
|
* @see ProtocolManager
|
||||||
|
* @see ConnectionManager
|
||||||
|
* @see ViaPlatform
|
||||||
|
*/
|
||||||
|
public interface ViaAPI<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the <b>major version</b> matching {@link #getVersion()}.
|
||||||
|
* It is highly advised to check against the major version and to disable/not initiate
|
||||||
|
* any hooks into ViaVersion if given and expected versions do not match.
|
||||||
|
*
|
||||||
|
* @return major plugin version
|
||||||
|
* @since 4.0.2
|
||||||
|
*/
|
||||||
|
default int majorVersion() {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an <b>internally based API version</b> incremented with meaningful API changes.
|
||||||
|
* This includes breaking changes to existing API and larger additions.
|
||||||
|
*
|
||||||
|
* @return API version incremented with meaningful API changes
|
||||||
|
*/
|
||||||
|
default int apiVersion() {
|
||||||
|
return 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the server's protocol version info.
|
||||||
|
*
|
||||||
|
* @return the server's protocol version info
|
||||||
|
*/
|
||||||
|
ServerProtocolVersion getServerVersion();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the protocol version of a player.
|
||||||
|
* This will also retrieve the version from ProtocolSupport if it's being used.
|
||||||
|
*
|
||||||
|
* @param player the platform's player object, e.g. Bukkit this is Player
|
||||||
|
* @return protocol version, for example (47=1.8-1.8.8, 107=1.9, 108=1.9.1), or -1 if no longer connected
|
||||||
|
*/
|
||||||
|
int getPlayerVersion(T player);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the protocol version of a player.
|
||||||
|
*
|
||||||
|
* @param uuid UUID of a player
|
||||||
|
* @return protocol version, for example (47=1.8-1.8.8, 107=1.9, 108=1.9.1), or -1 if not connected
|
||||||
|
*/
|
||||||
|
int getPlayerVersion(UUID uuid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether Via injected into this player connection.
|
||||||
|
*
|
||||||
|
* @param uuid uuid of the player
|
||||||
|
* @return whether Via has a cached a UserConnection for this player
|
||||||
|
*/
|
||||||
|
boolean isInjected(UUID uuid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Via injected UserConnection if present.
|
||||||
|
*
|
||||||
|
* @param uuid uuid of the player
|
||||||
|
* @return user connection if present
|
||||||
|
*/
|
||||||
|
@Nullable UserConnection getConnection(UUID uuid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the version of the plugin.
|
||||||
|
*
|
||||||
|
* @return plugin version
|
||||||
|
*/
|
||||||
|
String getVersion();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a raw packet to the player.
|
||||||
|
*
|
||||||
|
* @param player the platform's player object, e.g. for Bukkit this is Player
|
||||||
|
* @param packet the packet; you need a VarInt Id, then the packet contents
|
||||||
|
* @throws IllegalArgumentException if the player is not injected by Via
|
||||||
|
*/
|
||||||
|
void sendRawPacket(T player, ByteBuf packet);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a raw packet to the player.
|
||||||
|
*
|
||||||
|
* @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 the player is not injected by Via
|
||||||
|
*/
|
||||||
|
void sendRawPacket(UUID uuid, ByteBuf packet);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the supported protocol versions.
|
||||||
|
* This method removes any blocked protocol versions.
|
||||||
|
*
|
||||||
|
* @return a list of protocol versions
|
||||||
|
* @see #getFullSupportedVersions() for a full list
|
||||||
|
*/
|
||||||
|
SortedSet<Integer> getSupportedVersions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the supported protocol versions, including blocked protocols.
|
||||||
|
*
|
||||||
|
* @return a list of protocol versions
|
||||||
|
*/
|
||||||
|
SortedSet<Integer> getFullSupportedVersions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns legacy api only applicable on/to legacy versions.
|
||||||
|
* <p>
|
||||||
|
* These methods are safe to use and are unlikely to be removed,
|
||||||
|
* but it is important to be aware of their limited use.
|
||||||
|
*
|
||||||
|
* @return legacy api only applicable on/to legacy versions
|
||||||
|
*/
|
||||||
|
LegacyViaAPI<T> legacyAPI();
|
||||||
|
}
|
@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||||
|
* Copyright (C) 2016-2022 ViaVersion and contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.elevatemc.spigot.viaversion.api;
|
||||||
|
|
||||||
|
import com.elevatemc.spigot.viaversion.api.command.ViaVersionCommand;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.connection.ConnectionManager;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.debug.DebugHandler;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.platform.ViaInjector;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.platform.ViaPlatform;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.platform.ViaPlatformLoader;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.platform.providers.ViaProviders;
|
||||||
|
import com.elevatemc.spigot.viaversion.api.protocol.ProtocolManager;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public interface ViaManager {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the protocol manager for registering/getting protocols and their mapping data loading.
|
||||||
|
*
|
||||||
|
* @return protocol manager
|
||||||
|
*/
|
||||||
|
ProtocolManager getProtocolManager();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns platform for handling platform specific configuration, tasks, and plugin data.
|
||||||
|
*
|
||||||
|
* @return platform
|
||||||
|
*/
|
||||||
|
ViaPlatform<?> getPlatform();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the userconnection manager for handling clients connected to the server.
|
||||||
|
*
|
||||||
|
* @return userconnection manager
|
||||||
|
*/
|
||||||
|
ConnectionManager getConnectionManager();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the manager for Via providers.
|
||||||
|
*
|
||||||
|
* @return provider manager
|
||||||
|
*/
|
||||||
|
ViaProviders getProviders();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the injector for injecting netty handlers and initially getting the server protocol version.
|
||||||
|
*
|
||||||
|
* @return injector
|
||||||
|
*/
|
||||||
|
ViaInjector getInjector();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the command handler for managing ViaVersion subcommands.
|
||||||
|
*
|
||||||
|
* @return command handler
|
||||||
|
*/
|
||||||
|
ViaVersionCommand getCommandHandler();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the platform loader responsible for registering listeners, providers and such.
|
||||||
|
*
|
||||||
|
* @return platform loader
|
||||||
|
*/
|
||||||
|
ViaPlatformLoader getLoader();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If debug is enabled, packets and other otherwise suppressed warnings will be logged.
|
||||||
|
*
|
||||||
|
* @return true if enabled
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
default boolean isDebug() {
|
||||||
|
return debugHandler().enabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the debug mode. If enabled, packets and other otherwise suppressed warnings will be logged.
|
||||||
|
*
|
||||||
|
* @param debug whether debug should be enabled
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
default void setDebug(boolean debug) {
|
||||||
|
debugHandler().setEnabled(debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the debug handler.
|
||||||
|
*
|
||||||
|
* @return debug handler
|
||||||
|
*/
|
||||||
|
DebugHandler debugHandler();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a mutable set of self-added subplatform version strings.
|
||||||
|
* This set is expanded by the subplatform itself (e.g. ViaBackwards), and may not contain all running ones.
|
||||||
|
*
|
||||||
|
* @return mutable set of subplatform versions
|
||||||
|
*/
|
||||||
|
Set<String> getSubPlatforms();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a runnable to be executed when ViaVersion has finished its init before the full server load.
|
||||||
|
*
|
||||||
|
* @param runnable runnable to be executed
|
||||||
|
*/
|
||||||
|
void addEnableListener(Runnable runnable);
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user