Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25a7915c7f | ||
|
|
822d582074 | ||
|
|
f8a73d5fc2 | ||
|
|
a0ad97947d | ||
|
|
6ea5d0849d | ||
|
|
eba512ef0b | ||
|
|
0f96c24c78 | ||
|
|
f2e4c37cd9 | ||
|
|
f159a2250c | ||
|
|
ed311e4059 | ||
|
|
6aae98a8a9 | ||
|
|
0f3daa5dc4 | ||
|
|
f258cf8c89 | ||
|
|
ca759c056e | ||
|
|
d715607826 | ||
|
|
afca92d122 | ||
|
|
ae37b34692 | ||
|
|
9e42a368e0 | ||
|
|
27982efd29 | ||
|
|
c3b343fbc8 | ||
|
|
9bedb6c741 | ||
|
|
873f4dd298 | ||
|
|
693990644f | ||
|
|
b2680d76a6 | ||
|
|
db935b454f | ||
|
|
c207a9bfff | ||
|
|
f5bd041c7b | ||
|
|
07d89b24af | ||
|
|
1d0c0c527c | ||
|
|
7a9cb86563 | ||
|
|
87b1919863 | ||
|
|
d164e413c2 | ||
|
|
76d7db044f | ||
|
|
046ebb8ecc | ||
|
|
bccde04ace | ||
|
|
9385f03722 | ||
|
|
b48fc17ead | ||
|
|
b50d0075ca | ||
|
|
84d006c71d | ||
|
|
212da9c46c | ||
|
|
8edb7048a1 | ||
|
|
abe3c4b0c9 | ||
|
|
c6d3c97c65 | ||
|
|
13c6a9d612 | ||
|
|
7d2ef743ac | ||
|
|
598d0f96d8 | ||
|
|
cbc22922d3 | ||
|
|
49783d36c2 | ||
|
|
70d91b4f87 | ||
|
|
17f3d13267 | ||
|
|
559674bf58 | ||
|
|
fbc298bc30 | ||
|
|
e36902c441 | ||
|
|
805c78989a | ||
|
|
85e416171c | ||
|
|
b55c0d0783 | ||
|
|
33b4b3835f | ||
|
|
8ccd772105 | ||
|
|
8677c632df | ||
|
|
560476c56f | ||
|
|
20bbe7cec6 | ||
|
|
1a002486d0 | ||
|
|
26fcdfe3bc | ||
|
|
4af98b220c | ||
|
|
a79533bf72 | ||
|
|
e3510d01d6 |
No files matched your search
@@ -1,47 +1,29 @@
|
||||
# ViaVersion 0.9.3
|
||||
# ViaVersion 0.9.9
|
||||
[](https://travis-ci.org/MylesIsCool/ViaVersion)
|
||||
[](https://gitter.im/MylesIsCool/ViaVersion)
|
||||
|
||||
**Allows the connection of 1.9 clients to 1.8**
|
||||
**1.10 clients on 1.8 / 1.9 servers**
|
||||
IRC: [#viaversion](http://buzz.spi.gt/iris/?channels=viaversion) on irc.spi.gt for Support.
|
||||
|
||||
This took 100s hours of work, so if you enjoy this consider looking into contacting me and supporting my projects.
|
||||
**Allows the connection of higher client versions to lower server versions**
|
||||
|
||||
Allows 1.10, 1.9 on 1.8 server and 1.10 on a 1.9 server.
|
||||
|
||||
**User Docs:** https://docs.viaversion.com/display/VIAVERSION/
|
||||
|
||||
**Contributor Chat:** https://gitter.im/MylesIsCool/ViaVersion
|
||||
|
||||
|
||||
|
||||
Sources:
|
||||
--------
|
||||
**wiki.vg** (Used for various information, we also contribute back)
|
||||
|
||||
**wiki.vg** (Protocol info, though I did have to find a lot myself)
|
||||
|
||||
**Burger** We use this tool to get protocol and other useful information for new / undocumented Minecraft versions
|
||||
**Burger** (See [PAaaS](https://github.com/Matsv/Paaas))
|
||||
|
||||
**OpenNBT** (used for slot rewriting)
|
||||
|
||||
|
||||
|
||||
Contributors:
|
||||
--------
|
||||
|
||||
**Myself** (harhar)
|
||||
|
||||
**Matsv/StamBoom**
|
||||
|
||||
**HugoDaBosss**
|
||||
|
||||
**SanderGielisse**
|
||||
|
||||
**Paulomart**
|
||||
|
||||
**gigosaurus**
|
||||
|
||||
**fillefilip8**
|
||||
|
||||
**lenis0012**
|
||||
|
||||
|
||||
|
||||
Releases / Dev Builds:
|
||||
--------
|
||||
You can find official releases here:
|
||||
@@ -64,5 +46,5 @@ License:
|
||||
|
||||
MIT License, see LICENSE for more details.
|
||||
|
||||
Thanks!
|
||||
|
||||
Special thanks to all our [Contributors](https://github.com/MylesIsCool/ViaVersion/graphs/contributors)
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>us.myles</groupId>
|
||||
<artifactId>viaversion</artifactId>
|
||||
<version>0.9.4</version>
|
||||
<version>0.9.9</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>ViaVersion</name>
|
||||
|
||||
@@ -4,6 +4,7 @@ import us.myles.ViaVersion.api.ViaVersionConfig;
|
||||
import us.myles.ViaVersion.util.Configuration;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
public class ViaConfig implements ViaVersionConfig {
|
||||
private final ViaVersionPlugin plugin;
|
||||
@@ -150,8 +151,38 @@ public class ViaConfig implements ViaVersionConfig {
|
||||
return plugin.getConfig().getBoolean("nms-player-ticking", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReplacePistons() {
|
||||
return plugin.getConfig().getBoolean("replace-pistons", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPistonReplacementId() {
|
||||
return plugin.getConfig().getInt("replacement-piston-id", 0);
|
||||
}
|
||||
|
||||
public boolean isAutoTeam() {
|
||||
// Collision has to be enabled first
|
||||
return isPreventCollision() && plugin.getConfig().getBoolean("auto-team", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForceJsonTransform() {
|
||||
return plugin.getConfig().getBoolean("force-json-transform", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> getBlockedProtocols() {
|
||||
return plugin.getConfig().getIntegerList("block-protocols");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBlockedDisconnectMsg() {
|
||||
return plugin.getConfig().getString("block-disconnect-msg", "You are using an unsupported Minecraft version!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReloadDisconnectMsg() {
|
||||
return plugin.getConfig().getString("reload-disconnect-msg", "Server reload, please rejoin!");
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
@@ -20,6 +21,7 @@ import us.myles.ViaVersion.api.boss.BossStyle;
|
||||
import us.myles.ViaVersion.api.command.ViaVersionCommand;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
||||
import us.myles.ViaVersion.boss.ViaBossBar;
|
||||
import us.myles.ViaVersion.classgenerator.ClassGenerator;
|
||||
import us.myles.ViaVersion.commands.ViaCommandHandler;
|
||||
@@ -27,6 +29,7 @@ import us.myles.ViaVersion.handlers.ViaVersionInitializer;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.update.UpdateListener;
|
||||
import us.myles.ViaVersion.update.UpdateUtil;
|
||||
import us.myles.ViaVersion.util.ConcurrentList;
|
||||
import us.myles.ViaVersion.util.ListWrapper;
|
||||
import us.myles.ViaVersion.util.ProtocolSupportUtil;
|
||||
import us.myles.ViaVersion.util.ReflectionUtil;
|
||||
@@ -53,6 +56,20 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
||||
@Getter
|
||||
private ViaConfig conf;
|
||||
|
||||
public ViaVersionPlugin() {
|
||||
// Check if we're using protocol support too
|
||||
protocolSupport = Bukkit.getPluginManager().getPlugin("ProtocolSupport") != null;
|
||||
|
||||
if (protocolSupport) {
|
||||
getLogger().info("Hooking into ProtocolSupport, to prevent issues!");
|
||||
try {
|
||||
patchLists();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
// Config magic
|
||||
@@ -64,11 +81,11 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
||||
if (Bukkit.getPluginManager().getPlugin("ProtocolLib") != null) {
|
||||
getLogger().severe("ViaVersion is already loaded, we're going to kick all the players... because otherwise we'll crash because of ProtocolLib.");
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
player.kickPlayer("Server reload, please rejoin!");
|
||||
player.kickPlayer(ChatColor.translateAlternateColorCodes('&', getConf().getReloadDisconnectMsg()));
|
||||
}
|
||||
|
||||
} else {
|
||||
getLogger().severe("ViaVersion is already loaded, this should work fine... Otherwise reboot the server!!!");
|
||||
getLogger().severe("ViaVersion is already loaded, this should work fine. If you get any console errors, try rebooting.");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -87,9 +104,6 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
||||
compatSpigotBuild = false;
|
||||
}
|
||||
|
||||
// Check if we're using protocol support too
|
||||
protocolSupport = Bukkit.getPluginManager().getPlugin("ProtocolSupport") != null;
|
||||
|
||||
// Generate classes needed (only works if it's compat or ps)
|
||||
ClassGenerator.generate();
|
||||
lateBind = !isBinded();
|
||||
@@ -112,9 +126,9 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
||||
gatherProtocolVersion();
|
||||
// Check if there are any pipes to this version
|
||||
if (ProtocolRegistry.SERVER_PROTOCOL != -1) {
|
||||
getLogger().info("ViaVersion detected protocol version: " + ProtocolRegistry.SERVER_PROTOCOL);
|
||||
getLogger().info("ViaVersion detected server version: " + ProtocolVersion.getProtocol(ProtocolRegistry.SERVER_PROTOCOL));
|
||||
if (!ProtocolRegistry.isWorkingPipe()) {
|
||||
getLogger().warning("ViaVersion will not function on the current protocol.");
|
||||
getLogger().warning("ViaVersion does not have any compatible versions for this server version, please read our resource page carefully.");
|
||||
}
|
||||
}
|
||||
ProtocolRegistry.refreshVersions();
|
||||
@@ -138,7 +152,7 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
getLogger().info("ViaVersion is disabling, if this is a reload it may not work.");
|
||||
getLogger().info("ViaVersion is disabling, if this is a reload and you experience issues consider rebooting.");
|
||||
uninject();
|
||||
}
|
||||
|
||||
@@ -209,7 +223,7 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
||||
try {
|
||||
Object connection = getServerConnection();
|
||||
if (connection == null) {
|
||||
getLogger().warning("We failed to find the ServerConnection? :( What server are you running?");
|
||||
getLogger().warning("We failed to find the core component 'ServerConnection', please file an issue on our GitHub.");
|
||||
return;
|
||||
}
|
||||
for (Field field : connection.getClass().getDeclaredFields()) {
|
||||
@@ -243,11 +257,32 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
||||
}
|
||||
System.setProperty("ViaVersion", getDescription().getVersion());
|
||||
} catch (Exception e) {
|
||||
getLogger().severe("Unable to inject handlers, are you on 1.8? ");
|
||||
getLogger().severe("Unable to inject ViaVersion, please post these details on our GitHub and ensure you're using a compatible server version.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void patchLists() throws Exception {
|
||||
Object connection = getServerConnection();
|
||||
if (connection == null) {
|
||||
getLogger().warning("We failed to find the core component 'ServerConnection', please file an issue on our GitHub.");
|
||||
return;
|
||||
}
|
||||
for (Field field : connection.getClass().getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
final Object value = field.get(connection);
|
||||
if (value instanceof List) {
|
||||
if (!(value instanceof ConcurrentList)) {
|
||||
ConcurrentList list = new ConcurrentList();
|
||||
list.addAll((List) value);
|
||||
field.set(connection, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean isBinded() {
|
||||
try {
|
||||
Object connection = getServerConnection();
|
||||
@@ -291,12 +326,12 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
||||
PluginDescriptionFile yaml = ReflectionUtil.get(cl, "description", PluginDescriptionFile.class);
|
||||
throw new Exception("Unable to inject, due to " + bootstrapAcceptor.getClass().getName() + ", try without the plugin " + yaml.getName() + "?");
|
||||
} else {
|
||||
throw new Exception("Unable to find childHandler, weird server version? " + bootstrapAcceptor.getClass().getName());
|
||||
throw new Exception("Unable to find core component 'childHandler', please check your plugins. issue: " + bootstrapAcceptor.getClass().getName());
|
||||
}
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
getLogger().severe("Have you got late-bind enabled with something else?");
|
||||
getLogger().severe("We failed to inject ViaVersion, have you got late-bind enabled with something else?");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@@ -311,7 +346,7 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
||||
ReflectionUtil.set(bootstrapAcceptor, "childHandler", ((ViaVersionInitializer) oldInit).getOriginal());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Failed to remove injection... reload won't work with connections sorry");
|
||||
System.out.println("Failed to remove injection handler, reload won't work with connections, please reboot!");
|
||||
}
|
||||
}
|
||||
injectedFutures.clear();
|
||||
@@ -323,7 +358,7 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
||||
pair.getKey().set(pair.getValue(), ((ListWrapper) o).getOriginalList());
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
System.out.println("Failed to remove injection... reload might not work with connections sorry");
|
||||
System.out.println("Failed to remove injection, reload won't work with connections, please reboot!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,7 +452,10 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
||||
|
||||
@Override
|
||||
public SortedSet<Integer> getSupportedVersions() {
|
||||
return ProtocolRegistry.getSupportedVersions();
|
||||
SortedSet<Integer> outputSet = new TreeSet<>(ProtocolRegistry.getSupportedVersions());
|
||||
outputSet.removeAll(getConf().getBlockedProtocols());
|
||||
|
||||
return outputSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,6 +3,7 @@ package us.myles.ViaVersion.api;
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
@@ -223,6 +224,7 @@ public class PacketWrapper {
|
||||
}
|
||||
if (readableObjects.size() > 0) {
|
||||
packetValues.addAll(readableObjects);
|
||||
readableObjects.clear();
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
@@ -267,10 +269,59 @@ public class PacketWrapper {
|
||||
|
||||
private void writeRemaining(ByteBuf output) {
|
||||
if (inputBuffer != null) {
|
||||
output.writeBytes(inputBuffer);
|
||||
output.writeBytes(inputBuffer, inputBuffer.readableBytes());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send this packet to the associated user.
|
||||
* Be careful not to send packets twice.
|
||||
* (Sends it after current)
|
||||
*
|
||||
* @param packetProtocol - The protocol version of the packet.
|
||||
* @param skipCurrentPipeline - Skip the current pipeline
|
||||
* @throws Exception if it fails to write
|
||||
*/
|
||||
public void send(Class<? extends Protocol> packetProtocol, boolean skipCurrentPipeline) throws Exception {
|
||||
if (!isCancelled()) {
|
||||
ByteBuf output = constructPacket(packetProtocol, skipCurrentPipeline);
|
||||
user().sendRawPacket(output);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Let the packet go through the protocol pipes and write it to ByteBuf
|
||||
*
|
||||
* @param packetProtocol - The protocol version of the packet.
|
||||
* @param skipCurrentPipeline - Skip the current pipeline
|
||||
* @return Packet buffer
|
||||
* @throws Exception if it fails to write
|
||||
*/
|
||||
private ByteBuf constructPacket(Class<? extends Protocol> packetProtocol, boolean skipCurrentPipeline) throws Exception {
|
||||
// Apply current pipeline
|
||||
List<Protocol> protocols = new ArrayList<>(user().get(ProtocolInfo.class).getPipeline().pipes());
|
||||
// Other way if outgoing
|
||||
Collections.reverse(protocols);
|
||||
int index = 0;
|
||||
for (int i = 0; i < protocols.size(); i++) {
|
||||
if (protocols.get(i).getClass().equals(packetProtocol)) {
|
||||
index = skipCurrentPipeline ? (i + 1) : (i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset reader before we start
|
||||
resetReader();
|
||||
|
||||
// Apply other protocols
|
||||
apply(Direction.OUTGOING, user().get(ProtocolInfo.class).getState(), index, protocols);
|
||||
// Send
|
||||
ByteBuf output = inputBuffer == null ? Unpooled.buffer() : inputBuffer.alloc().buffer();
|
||||
writeToBuffer(output);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send this packet to the associated user.
|
||||
* Be careful not to send packets twice.
|
||||
@@ -280,25 +331,25 @@ public class PacketWrapper {
|
||||
* @throws Exception if it fails to write
|
||||
*/
|
||||
public void send(Class<? extends Protocol> packetProtocol) throws Exception {
|
||||
send(packetProtocol, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send this packet to the associated user.
|
||||
* Be careful not to send packets twice.
|
||||
* (Sends it after current)
|
||||
* Also returns the packets ChannelFuture
|
||||
*
|
||||
* @param packetProtocol - The protocol version of the packet.
|
||||
* @return The packets ChannelFuture
|
||||
* @throws Exception if it fails to write
|
||||
*/
|
||||
public ChannelFuture sendFuture(Class<? extends Protocol> packetProtocol) throws Exception {
|
||||
if (!isCancelled()) {
|
||||
// Apply current pipeline
|
||||
List<Protocol> protocols = new ArrayList<>(user().get(ProtocolInfo.class).getPipeline().pipes());
|
||||
// Other way if outgoing
|
||||
Collections.reverse(protocols);
|
||||
int index = 0;
|
||||
for (int i = 0; i < protocols.size(); i++) {
|
||||
if (protocols.get(i).getClass().equals(packetProtocol)) {
|
||||
index = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Apply other protocols
|
||||
apply(Direction.OUTGOING, user().get(ProtocolInfo.class).getState(), index, protocols);
|
||||
// Send
|
||||
ByteBuf output = inputBuffer == null ? Unpooled.buffer() : inputBuffer.alloc().buffer();
|
||||
writeToBuffer(output);
|
||||
user().sendRawPacket(output);
|
||||
ByteBuf output = constructPacket(packetProtocol, true);
|
||||
return user().sendRawPacketFuture(output);
|
||||
}
|
||||
return user().getChannel().newFailedFuture(new Exception("Cancelled packet"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -393,6 +444,10 @@ public class PacketWrapper {
|
||||
* Reset the reader, so that it can be read again.
|
||||
*/
|
||||
public void resetReader() {
|
||||
// Move readable objects are packet values
|
||||
this.packetValues.addAll(readableObjects);
|
||||
this.readableObjects.clear();
|
||||
// Move all packet values to the readable for next packet.
|
||||
this.readableObjects.addAll(packetValues);
|
||||
this.packetValues.clear();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package us.myles.ViaVersion.api;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Listener;
|
||||
import us.myles.ViaVersion.ViaVersionPlugin;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.protocol.Protocol;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter(AccessLevel.PROTECTED)
|
||||
@RequiredArgsConstructor
|
||||
public abstract class ViaListener implements Listener {
|
||||
private final ViaVersionPlugin plugin;
|
||||
private final Class<? extends Protocol> requiredPipeline;
|
||||
private boolean registered = false;
|
||||
|
||||
/**
|
||||
* Get the UserConnection from a player
|
||||
*
|
||||
* @param player Player object
|
||||
* @return The UserConnection
|
||||
*/
|
||||
protected UserConnection getUserConnection(@NonNull Player player) {
|
||||
return getUserConnection(player.getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the UserConnection from an UUID
|
||||
*
|
||||
* @param uuid UUID object
|
||||
* @return The UserConnection
|
||||
*/
|
||||
protected UserConnection getUserConnection(@NonNull UUID uuid) {
|
||||
if (!plugin.isPorted(uuid)) return null;
|
||||
return plugin.getConnection(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player is on the selected pipe
|
||||
*
|
||||
* @param player Player Object
|
||||
* @return True if on pipe
|
||||
*/
|
||||
protected boolean isOnPipe(Player player) {
|
||||
return isOnPipe(player.getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 &&
|
||||
userConnection.get(ProtocolInfo.class).getPipeline().contains(requiredPipeline);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register as Bukkit event
|
||||
*/
|
||||
public void register() {
|
||||
if (registered) return;
|
||||
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
registered = true;
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import us.myles.ViaVersion.api.boss.BossBar;
|
||||
import us.myles.ViaVersion.api.boss.BossColor;
|
||||
import us.myles.ViaVersion.api.boss.BossStyle;
|
||||
import us.myles.ViaVersion.api.command.ViaVersionCommand;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
|
||||
|
||||
import java.util.SortedSet;
|
||||
import java.util.UUID;
|
||||
@@ -16,6 +17,7 @@ public interface ViaVersionAPI {
|
||||
*
|
||||
* @param player Bukkit player object
|
||||
* @return True if the client is modified (At the moment it also means version 1.9 and higher)
|
||||
* @deprecated As of 0.9.9, because all players are ported use {@link #getPlayerVersion(Player)}
|
||||
*/
|
||||
boolean isPorted(Player player);
|
||||
|
||||
@@ -41,7 +43,9 @@ public interface ViaVersionAPI {
|
||||
*
|
||||
* @param playerUUID UUID of a player
|
||||
* @return True if the client is on 1.9
|
||||
* @deprecated As of 0.9.9, because all players are ported use {@link #getPlayerVersion(UUID)}
|
||||
*/
|
||||
@Deprecated
|
||||
boolean isPorted(UUID playerUUID);
|
||||
|
||||
/**
|
||||
@@ -114,8 +118,10 @@ public interface ViaVersionAPI {
|
||||
|
||||
/**
|
||||
* Get the supported protocol versions
|
||||
* This method removes any blocked protocol versions.
|
||||
*
|
||||
* @return a list of protocol versions
|
||||
* @see ProtocolRegistry#getSupportedVersions() for full list.
|
||||
*/
|
||||
SortedSet<Integer> getSupportedVersions();
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package us.myles.ViaVersion.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ViaVersionConfig {
|
||||
|
||||
/**
|
||||
@@ -172,4 +174,47 @@ public interface ViaVersionConfig {
|
||||
* @return if true, enabled
|
||||
*/
|
||||
boolean isNMSPlayerTicking();
|
||||
|
||||
/**
|
||||
* Replace extended pistons on 1.10 chunk loading.
|
||||
*
|
||||
* @return True if to replace them
|
||||
*/
|
||||
boolean isReplacePistons();
|
||||
|
||||
/**
|
||||
* Get the id for replacing extended pistons.
|
||||
*
|
||||
* @return The integer id
|
||||
*/
|
||||
int getPistonReplacementId();
|
||||
|
||||
/**
|
||||
* Force json transform
|
||||
*
|
||||
* @return True if enabled
|
||||
*/
|
||||
boolean isForceJsonTransform();
|
||||
|
||||
/**
|
||||
* Get the blocked protocols
|
||||
*
|
||||
* @return An Integer list
|
||||
*/
|
||||
List<Integer> getBlockedProtocols();
|
||||
|
||||
/**
|
||||
* Get the custom disconnect message
|
||||
*
|
||||
* @return Disconnect message
|
||||
*/
|
||||
String getBlockedDisconnectMsg();
|
||||
|
||||
/**
|
||||
* Get the message sent to players being kicked on reload.
|
||||
* Players are kicked to stop the server crashing
|
||||
*
|
||||
* @return Disconnect message
|
||||
*/
|
||||
String getReloadDisconnectMsg();
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
package us.myles.ViaVersion.api.data;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter(AccessLevel.PROTECTED)
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class StoredObject {
|
||||
private UserConnection user;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package us.myles.ViaVersion.api.data;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import lombok.Data;
|
||||
@@ -85,6 +86,17 @@ public class UserConnection {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a raw packet to the player with returning the future
|
||||
*
|
||||
* @param packet The raw packet to send
|
||||
* @return ChannelFuture of the packet being sent
|
||||
*/
|
||||
public ChannelFuture sendRawPacketFuture(final ByteBuf packet) {
|
||||
final ChannelHandler handler = channel.pipeline().get("encoder");
|
||||
return channel.pipeline().context(handler).writeAndFlush(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a raw packet to the player (netty thread)
|
||||
*
|
||||
|
||||
@@ -1,4 +1,23 @@
|
||||
package us.myles.ViaVersion.api.minecraft.chunks;
|
||||
|
||||
import org.spacehq.opennbt.tag.builtin.CompoundTag;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface Chunk {
|
||||
int getX();
|
||||
|
||||
int getZ();
|
||||
|
||||
ChunkSection[] getSections();
|
||||
|
||||
boolean isGroundUp();
|
||||
|
||||
boolean isBiomeData();
|
||||
|
||||
byte[] getBiomeData();
|
||||
|
||||
int getBitmask();
|
||||
|
||||
List<CompoundTag> getBlockEntities();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package us.myles.ViaVersion.api.minecraft.chunks;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public interface ChunkSection {
|
||||
int getBlockId(int x, int y, int z);
|
||||
|
||||
void writeBlocks(ByteBuf output) throws Exception;
|
||||
|
||||
void writeBlockLight(ByteBuf output) throws Exception;
|
||||
|
||||
boolean hasSkyLight();
|
||||
|
||||
void writeSkyLight(ByteBuf output) throws Exception;
|
||||
}
|
||||
@@ -79,6 +79,11 @@ public class ProtocolRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the versions compatible with the server.
|
||||
*
|
||||
* @return Read-only set of the versions.
|
||||
*/
|
||||
public static SortedSet<Integer> getSupportedVersions() {
|
||||
return Collections.unmodifiableSortedSet(new TreeSet<>(supportedVersions));
|
||||
}
|
||||
|
||||
@@ -91,4 +91,9 @@ public class ProtocolVersion {
|
||||
public int hashCode() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s(%d)", this.getName(), this.getId());
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,6 @@ import us.myles.ViaVersion.api.minecraft.item.Item;
|
||||
import us.myles.ViaVersion.api.type.types.*;
|
||||
import us.myles.ViaVersion.api.type.types.minecraft.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter
|
||||
|
||||
@@ -6,7 +6,7 @@ import us.myles.ViaVersion.api.type.TypeConverter;
|
||||
|
||||
public class UnsignedByteType extends Type<Short> implements TypeConverter<Short> {
|
||||
public UnsignedByteType() {
|
||||
super(Short.class);
|
||||
super("Unsigned Byte", Short.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+6
-10
@@ -1,4 +1,4 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_9to1_8.types;
|
||||
package us.myles.ViaVersion.api.type.types.version;
|
||||
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
@@ -6,7 +6,7 @@ import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
|
||||
import us.myles.ViaVersion.api.type.types.minecraft.MetaTypeTemplate;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.metadata.MetadataTypes;
|
||||
|
||||
public class MetadataType extends MetaTypeTemplate {
|
||||
public class Metadata1_8Type extends MetaTypeTemplate {
|
||||
|
||||
@Override
|
||||
public Metadata read(ByteBuf buffer) throws Exception {
|
||||
@@ -19,13 +19,9 @@ public class MetadataType extends MetaTypeTemplate {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Metadata object) throws Exception {
|
||||
if (object == null) {
|
||||
buffer.writeByte(255);
|
||||
} else {
|
||||
buffer.writeByte(object.getId());
|
||||
buffer.writeByte(object.getTypeID());
|
||||
object.getType().write(buffer, object.getValue());
|
||||
}
|
||||
public void write(ByteBuf buffer, Metadata meta) throws Exception {
|
||||
byte item = (byte) (meta.getTypeID() << 5 | meta.getId() & 0x1F);
|
||||
buffer.writeByte(item);
|
||||
meta.getType().write(buffer, meta.getValue());
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_10to1_9_3.types;
|
||||
package us.myles.ViaVersion.api.type.types.version;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
|
||||
import us.myles.ViaVersion.api.type.types.minecraft.MetaTypeTemplate;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.metadata.NewType;
|
||||
|
||||
public class Meta1_10Type extends MetaTypeTemplate {
|
||||
public class Metadata1_9Type extends MetaTypeTemplate {
|
||||
|
||||
@Override
|
||||
public Metadata read(ByteBuf buffer) throws Exception {
|
||||
+6
-9
@@ -1,21 +1,20 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_9to1_8.types;
|
||||
package us.myles.ViaVersion.api.type.types.version;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
|
||||
import us.myles.ViaVersion.api.type.types.minecraft.MetaListTypeTemplate;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MetadataListType extends MetaListTypeTemplate {
|
||||
public class MetadataList1_8Type extends MetaListTypeTemplate {
|
||||
|
||||
@Override
|
||||
public List<Metadata> read(ByteBuf buffer) throws Exception {
|
||||
List<Metadata> list = new ArrayList<>();
|
||||
Metadata m;
|
||||
do {
|
||||
m = Protocol1_9TO1_8.METADATA.read(buffer);
|
||||
m = Types1_8.METADATA.read(buffer);
|
||||
if (m != null) {
|
||||
list.add(m);
|
||||
}
|
||||
@@ -26,10 +25,8 @@ public class MetadataListType extends MetaListTypeTemplate {
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, List<Metadata> object) throws Exception {
|
||||
for (Metadata m : object) {
|
||||
Protocol1_9TO1_8.METADATA.write(buffer, m);
|
||||
}
|
||||
// Write end of list
|
||||
Protocol1_9TO1_8.METADATA.write(buffer, null);
|
||||
for (Metadata data : object)
|
||||
Types1_8.METADATA.write(buffer, data);
|
||||
buffer.writeByte(127);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package us.myles.ViaVersion.api.type.types.version;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
|
||||
import us.myles.ViaVersion.api.type.types.minecraft.MetaListTypeTemplate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MetadataList1_9Type extends MetaListTypeTemplate {
|
||||
|
||||
@Override
|
||||
public List<Metadata> read(ByteBuf buffer) throws Exception {
|
||||
List<Metadata> list = new ArrayList<>();
|
||||
Metadata meta;
|
||||
do {
|
||||
meta = Types1_9.METADATA.read(buffer);
|
||||
if (meta != null)
|
||||
list.add(meta);
|
||||
} while (meta != null);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, List<Metadata> object) throws Exception {
|
||||
for (Metadata m : object)
|
||||
Types1_9.METADATA.write(buffer, m);
|
||||
|
||||
// Write end of list
|
||||
Types1_9.METADATA.write(buffer, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package us.myles.ViaVersion.api.type.types.version;
|
||||
|
||||
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Types1_8 {
|
||||
/**
|
||||
* Metadata list type for 1.8
|
||||
*/
|
||||
public static Type<List<Metadata>> METADATA_LIST = new MetadataList1_8Type();
|
||||
|
||||
/**
|
||||
* Metadata type for 1.8
|
||||
*/
|
||||
public static Type<Metadata> METADATA = new Metadata1_8Type();
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package us.myles.ViaVersion.api.type.types.version;
|
||||
|
||||
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Types1_9 {
|
||||
/**
|
||||
* Metadata list type for 1.9
|
||||
*/
|
||||
public static final Type<List<Metadata>> METADATA_LIST = new MetadataList1_9Type();
|
||||
|
||||
/**
|
||||
* Metadata type for 1.9
|
||||
*/
|
||||
public static final Type<Metadata> METADATA = new Metadata1_9Type();
|
||||
}
|
||||
@@ -132,6 +132,7 @@ public class ViaCommandHandler implements ViaVersionCommand, CommandExecutor, Ta
|
||||
registerSubCommand(new ListSubCmd());
|
||||
registerSubCommand(new PPSSubCmd());
|
||||
registerSubCommand(new DebugSubCmd());
|
||||
registerSubCommand(new DumpSubCmd());
|
||||
registerSubCommand(new DisplayLeaksSubCmd());
|
||||
registerSubCommand(new DontBugMeSubCmd());
|
||||
registerSubCommand(new AutoTeamSubCmd());
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
package us.myles.ViaVersion.commands.defaultsubs;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import us.myles.ViaVersion.ViaVersionPlugin;
|
||||
import us.myles.ViaVersion.api.ViaVersion;
|
||||
import us.myles.ViaVersion.api.command.ViaSubCommand;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
|
||||
import us.myles.ViaVersion.dump.DumpTemplate;
|
||||
import us.myles.ViaVersion.dump.PluginInfo;
|
||||
import us.myles.ViaVersion.dump.VersionInfo;
|
||||
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class DumpSubCmd extends ViaSubCommand {
|
||||
private final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "dump";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Dump information about your server, this is helpful if you report bugs.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(final CommandSender sender, String[] args) {
|
||||
VersionInfo version = new VersionInfo(
|
||||
Bukkit.getServer().getVersion(),
|
||||
Bukkit.getServer().getBukkitVersion(),
|
||||
System.getProperty("java.version"),
|
||||
System.getProperty("os.name"),
|
||||
ProtocolRegistry.SERVER_PROTOCOL,
|
||||
ProtocolRegistry.getSupportedVersions());
|
||||
|
||||
List<PluginInfo> plugins = new ArrayList<>();
|
||||
for (Plugin p : Bukkit.getPluginManager().getPlugins())
|
||||
plugins.add(new PluginInfo(p.isEnabled(), p.getDescription().getName(), p.getDescription().getVersion(), p.getDescription().getMain(), p.getDescription().getAuthors()));
|
||||
|
||||
Map<String, Object> configuration = ((ViaVersionPlugin) ViaVersion.getInstance()).getConfig().getValues(false);
|
||||
|
||||
final DumpTemplate template = new DumpTemplate(version, configuration, plugins);
|
||||
|
||||
Bukkit.getScheduler().runTaskAsynchronously((ViaVersionPlugin) ViaVersion.getInstance(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
HttpURLConnection con = (HttpURLConnection) new URL("http://hastebin.com/documents").openConnection();
|
||||
|
||||
con.setRequestProperty("Content-Type", "text/plain");
|
||||
con.setRequestMethod("POST");
|
||||
con.setDoOutput(true);
|
||||
|
||||
OutputStream out = con.getOutputStream();
|
||||
out.write(gson.toJson(template).getBytes(Charset.forName("UTF-8")));
|
||||
out.close();
|
||||
|
||||
JsonObject output = gson.fromJson(new InputStreamReader(con.getInputStream()), JsonObject.class);
|
||||
con.getInputStream().close();
|
||||
|
||||
if (!output.has("key"))
|
||||
throw new InvalidObjectException("Key is not given in Hastebin output");
|
||||
|
||||
sender.sendMessage(ChatColor.GREEN + "We've made a dump with useful information, report your issue and provide this url: " + getUrl(output.get("key").getAsString()));
|
||||
} catch (Exception e) {
|
||||
sender.sendMessage(ChatColor.RED + "Failed to dump, please check the console for more information");
|
||||
((ViaVersionPlugin) ViaVersion.getInstance()).getLogger().log(Level.WARNING, "Could not paste ViaVersion dump to Hastebin", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private String getUrl(String id) {
|
||||
return String.format("http://hastebin.com/%s.json", id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package us.myles.ViaVersion.dump;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class DumpTemplate {
|
||||
private VersionInfo versionInfo;
|
||||
private Map<String, Object> configuration;
|
||||
private List<PluginInfo> plugins;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package us.myles.ViaVersion.dump;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class PluginInfo {
|
||||
private boolean enabled;
|
||||
private String name;
|
||||
private String version;
|
||||
private String main;
|
||||
private List<String> authors;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package us.myles.ViaVersion.dump;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class VersionInfo {
|
||||
private String version;
|
||||
private String bukkitVersion;
|
||||
private String javaVersion;
|
||||
private String operatingSystem;
|
||||
private int serverProtocol;
|
||||
private Set<Integer> enabledPipelines;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package us.myles.ViaVersion.protocols.base;
|
||||
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.util.concurrent.Future;
|
||||
import io.netty.util.concurrent.GenericFutureListener;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@@ -21,6 +25,7 @@ import us.myles.ViaVersion.api.remapper.PacketRemapper;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.packets.Direction;
|
||||
import us.myles.ViaVersion.packets.State;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
@@ -31,6 +36,8 @@ public class BaseProtocol extends Protocol {
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
/* Outgoing Packets */
|
||||
|
||||
// Status Response Packet
|
||||
registerOutgoing(State.STATUS, 0x00, 0x00, new PacketRemapper() { // Status Response Packet
|
||||
@Override
|
||||
public void registerMap() {
|
||||
@@ -43,20 +50,26 @@ public class BaseProtocol extends Protocol {
|
||||
try {
|
||||
JSONObject json = (JSONObject) new JSONParser().parse(originalStatus);
|
||||
JSONObject version = (JSONObject) json.get("version");
|
||||
if (ViaVersion.getConfig().isSendSupportedVersions())
|
||||
int protocolVersion = ((Long) version.get("protocol")).intValue();
|
||||
|
||||
if (ViaVersion.getConfig().isSendSupportedVersions()) //Send supported versions
|
||||
version.put("supportedVersions", ViaVersion.getInstance().getSupportedVersions());
|
||||
if (ProtocolRegistry.SERVER_PROTOCOL == -1) {
|
||||
Long original = (Long) version.get("protocol");
|
||||
ProtocolRegistry.SERVER_PROTOCOL = original.intValue();
|
||||
}
|
||||
|
||||
if (ProtocolRegistry.SERVER_PROTOCOL == -1) // Set the Server protocol if the detection on startup failed
|
||||
ProtocolRegistry.SERVER_PROTOCOL = protocolVersion;
|
||||
|
||||
List<Pair<Integer, Protocol>> protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), ProtocolRegistry.SERVER_PROTOCOL);
|
||||
if (protocols != null) {
|
||||
if ((long) version.get("protocol") != 9999) //Fix serverlistplus
|
||||
if (protocolVersion != 9999) //Fix ServerListPlus
|
||||
version.put("protocol", info.getProtocolVersion());
|
||||
} else {
|
||||
// not compatible :(, *plays very sad violin*
|
||||
wrapper.user().setActive(false);
|
||||
}
|
||||
|
||||
if (ViaVersion.getConfig().getBlockedProtocols().contains(info.getProtocolVersion()))
|
||||
version.put("protocol", -1); // Show blocked versions as outdated
|
||||
|
||||
wrapper.set(Type.STRING, 0, json.toJSONString()); // Update value
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
@@ -88,6 +101,10 @@ public class BaseProtocol extends Protocol {
|
||||
info.setUsername(wrapper.get(Type.STRING, 1));
|
||||
// Add to ported clients
|
||||
((ViaVersionPlugin) ViaVersion.getInstance()).addPortedClient(wrapper.user());
|
||||
|
||||
if (info.getPipeline().pipes().size() == 1 && info.getPipeline().pipes().get(0).getClass() == BaseProtocol.class) // Only base protocol
|
||||
wrapper.user().setActive(false);
|
||||
|
||||
if (ViaVersion.getInstance().isDebug()) {
|
||||
// Print out the route to console
|
||||
((ViaVersionPlugin) ViaVersion.getInstance()).getLogger().log(Level.INFO, "{0} logged in with protocol {1}, Route: {2}",
|
||||
@@ -130,11 +147,6 @@ public class BaseProtocol extends Protocol {
|
||||
pipeline.add(prot.getValue());
|
||||
}
|
||||
wrapper.set(Type.VAR_INT, 0, ProtocolRegistry.SERVER_PROTOCOL);
|
||||
} else {
|
||||
if (state == 2) {
|
||||
// not compatible :(, *plays very sad violin*
|
||||
wrapper.user().setActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Change state
|
||||
@@ -151,7 +163,34 @@ public class BaseProtocol extends Protocol {
|
||||
registerIncoming(State.STATUS, 0x00, 0x00); // Status Request Packet
|
||||
registerIncoming(State.STATUS, 0x01, 0x01); // Status Ping Packet
|
||||
|
||||
registerIncoming(State.LOGIN, 0x00, 0x00); // Login Start Packet
|
||||
// Login Start Packet
|
||||
registerIncoming(State.LOGIN, 0x00, 0x00, new PacketRemapper() {
|
||||
@Override
|
||||
public void registerMap() {
|
||||
handler(new PacketHandler() {
|
||||
@Override
|
||||
public void handle(final PacketWrapper wrapper) throws Exception {
|
||||
int protocol = wrapper.user().get(ProtocolInfo.class).getProtocolVersion();
|
||||
if (ViaVersion.getConfig().getBlockedProtocols().contains(protocol)) {
|
||||
if (!wrapper.user().getChannel().isOpen()) return;
|
||||
|
||||
PacketWrapper disconnectPacket = new PacketWrapper(0x00, null, wrapper.user()); // Disconnect Packet
|
||||
Protocol1_9TO1_8.FIX_JSON.write(disconnectPacket, ChatColor.translateAlternateColorCodes('&', ViaVersion.getConfig().getBlockedDisconnectMsg()));
|
||||
wrapper.cancel(); // cancel current
|
||||
|
||||
// Send and close
|
||||
ChannelFuture future = disconnectPacket.sendFuture(BaseProtocol.class);
|
||||
future.addListener(new GenericFutureListener<Future<? super Void>>() {
|
||||
@Override
|
||||
public void operationComplete(Future<? super Void> future) throws Exception {
|
||||
wrapper.user().getChannel().close();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}); // Login Start Packet
|
||||
registerIncoming(State.LOGIN, 0x01, 0x01); // Encryption Response Packet
|
||||
}
|
||||
|
||||
|
||||
+23
-8
@@ -8,21 +8,36 @@ import us.myles.ViaVersion.api.remapper.PacketHandler;
|
||||
import us.myles.ViaVersion.api.remapper.PacketRemapper;
|
||||
import us.myles.ViaVersion.api.remapper.ValueTransformer;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.api.type.types.version.Metadata1_9Type;
|
||||
import us.myles.ViaVersion.api.type.types.version.MetadataList1_9Type;
|
||||
import us.myles.ViaVersion.api.type.types.version.Types1_9;
|
||||
import us.myles.ViaVersion.packets.State;
|
||||
import us.myles.ViaVersion.protocols.protocol1_10to1_9_3.storage.ResourcePackTracker;
|
||||
import us.myles.ViaVersion.protocols.protocol1_10to1_9_3.types.Meta1_10Type;
|
||||
import us.myles.ViaVersion.protocols.protocol1_10to1_9_3.types.MetaList1_10Type;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
public class Protocol1_10To1_9_3_4 extends Protocol {
|
||||
public static final Type<List<Metadata>> METADATA_LIST = new MetaList1_10Type();
|
||||
public static final Type<Metadata> METADATA = new Meta1_10Type();
|
||||
@Deprecated
|
||||
public static final Type<List<Metadata>> METADATA_LIST = new MetadataList1_9Type();
|
||||
@Deprecated
|
||||
public static final Type<Metadata> METADATA = new Metadata1_9Type();
|
||||
|
||||
public static ValueTransformer<Short, Float> toNewPitch = new ValueTransformer<Short, Float>(Type.FLOAT) {
|
||||
@Override
|
||||
public Float transform(PacketWrapper wrapper, Short inputValue) throws Exception {
|
||||
return inputValue / 63.5F;
|
||||
|
||||
}
|
||||
};
|
||||
public static ValueTransformer<List<Metadata>, List<Metadata>> transformMetadata = new ValueTransformer<List<Metadata>, List<Metadata>>(Types1_9.METADATA_LIST) {
|
||||
@Override
|
||||
public List<Metadata> transform(PacketWrapper wrapper, List<Metadata> inputValue) throws Exception {
|
||||
List<Metadata> metaList = new CopyOnWriteArrayList<>(inputValue);
|
||||
for (Metadata m : metaList) {
|
||||
if (m.getId() >= 5)
|
||||
m.setId(m.getId() + 1);
|
||||
}
|
||||
return metaList;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -69,7 +84,7 @@ public class Protocol1_10To1_9_3_4 extends Protocol {
|
||||
@Override
|
||||
public void registerMap() {
|
||||
map(Type.VAR_INT); // 0 - Entity ID
|
||||
map(METADATA_LIST); // 1 - Metadata list
|
||||
map(Types1_9.METADATA_LIST, transformMetadata); // 1 - Metadata list
|
||||
}
|
||||
});
|
||||
|
||||
@@ -89,7 +104,7 @@ public class Protocol1_10To1_9_3_4 extends Protocol {
|
||||
map(Type.SHORT); // 9 - Velocity X
|
||||
map(Type.SHORT); // 10 - Velocity Y
|
||||
map(Type.SHORT); // 11 - Velocity Z
|
||||
map(METADATA_LIST); // 12 - Metadata
|
||||
map(Types1_9.METADATA_LIST, transformMetadata); // 12 - Metadata
|
||||
}
|
||||
});
|
||||
|
||||
@@ -104,7 +119,7 @@ public class Protocol1_10To1_9_3_4 extends Protocol {
|
||||
map(Type.DOUBLE); // 4 - Z
|
||||
map(Type.BYTE); // 5 - Yaw
|
||||
map(Type.BYTE); // 6 - Pitch
|
||||
map(METADATA_LIST); // 7 - Metadata list
|
||||
map(Types1_9.METADATA_LIST, transformMetadata); // 7 - Metadata list
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_10to1_9_3.types;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.api.type.types.minecraft.MetaListTypeTemplate;
|
||||
import us.myles.ViaVersion.protocols.protocol1_10to1_9_3.Protocol1_10To1_9_3_4;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.metadata.NewType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MetaList1_10Type extends MetaListTypeTemplate {
|
||||
|
||||
@Override
|
||||
public List<Metadata> read(ByteBuf buffer) throws Exception {
|
||||
List<Metadata> list = new ArrayList<>();
|
||||
Metadata meta;
|
||||
do {
|
||||
meta = Protocol1_10To1_9_3_4.METADATA.read(buffer);
|
||||
if (meta != null)
|
||||
list.add(meta);
|
||||
} while (meta != null);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, List<Metadata> object) throws Exception {
|
||||
for (Metadata m : object) {
|
||||
if (m.getId() >= 5)
|
||||
m.setId(m.getId() + 1);
|
||||
if (m.getId() == 4)
|
||||
Protocol1_10To1_9_3_4.METADATA.write(buffer, new Metadata(5, NewType.Boolean.getTypeID(), Type.BOOLEAN, false)); // No gravity metadata
|
||||
Protocol1_10To1_9_3_4.METADATA.write(buffer, m);
|
||||
}
|
||||
|
||||
// Write end of list
|
||||
Protocol1_10To1_9_3_4.METADATA.write(buffer, null);
|
||||
}
|
||||
}
|
||||
-54
@@ -1,54 +0,0 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import org.spacehq.opennbt.tag.builtin.CompoundTag;
|
||||
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.api.type.types.minecraft.BaseChunkType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Chunk1_9_3_4Type extends BaseChunkType {
|
||||
public Chunk1_9_3_4Type() {
|
||||
super("1.9.3 Chunk");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk read(ByteBuf input) throws Exception {
|
||||
int chunkX = input.readInt();
|
||||
int chunkZ = input.readInt();
|
||||
|
||||
boolean groundUp = input.readBoolean();
|
||||
int primaryBitmask = Type.VAR_INT.read(input);
|
||||
int size = Type.VAR_INT.read(input);
|
||||
|
||||
byte[] sections = new byte[size];
|
||||
input.readBytes(sections);
|
||||
|
||||
int blockEntities = Type.VAR_INT.read(input);
|
||||
List<CompoundTag> nbtData = new ArrayList<>();
|
||||
for (int i = 0; i < blockEntities; i++) {
|
||||
nbtData.add(Type.NBT.read(input));
|
||||
}
|
||||
return new Chunk1_9_3_4(chunkX, chunkZ, groundUp, primaryBitmask, sections, nbtData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Chunk input) throws Exception {
|
||||
if (!(input instanceof Chunk1_9_3_4))
|
||||
throw new Exception("Tried to send the wrong chunk type from 1.9.3-4 chunk: " + input.getClass());
|
||||
Chunk1_9_3_4 chunk = (Chunk1_9_3_4) input;
|
||||
|
||||
buffer.writeInt(chunk.getX());
|
||||
buffer.writeInt(chunk.getZ());
|
||||
|
||||
buffer.writeBoolean(chunk.isGroundUp());
|
||||
Type.VAR_INT.write(buffer, chunk.getBitmask());
|
||||
|
||||
Type.VAR_INT.write(buffer, chunk.getSections().length);
|
||||
buffer.writeBytes(chunk.getSections());
|
||||
|
||||
// no block entities as it's earlier
|
||||
}
|
||||
}
|
||||
+49
-4
@@ -10,9 +10,11 @@ import us.myles.ViaVersion.api.remapper.PacketHandler;
|
||||
import us.myles.ViaVersion.api.remapper.PacketRemapper;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.packets.State;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks.BlockEntity;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.types.Chunk1_9_3_4Type;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
|
||||
|
||||
public class Protocol1_9_1_2TO1_9_3_4 extends Protocol {
|
||||
public static Type<Chunk> CHUNK = new Chunk1_9_3_4Type();
|
||||
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
@@ -57,8 +59,50 @@ public class Protocol1_9_1_2TO1_9_3_4 extends Protocol {
|
||||
handler(new PacketHandler() {
|
||||
@Override
|
||||
public void handle(PacketWrapper wrapper) throws Exception {
|
||||
Chunk chunk = wrapper.passthrough(CHUNK);
|
||||
BlockEntity.handle(((Chunk1_9_3_4) chunk).getBlockEntities(), wrapper.user());
|
||||
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
|
||||
|
||||
Chunk1_9_3_4Type type = new Chunk1_9_3_4Type(clientWorld);
|
||||
Chunk chunk = wrapper.passthrough(type);
|
||||
|
||||
BlockEntity.handle(chunk.getBlockEntities(), wrapper.user());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Join (save dimension id)
|
||||
registerOutgoing(State.PLAY, 0x23, 0x23, new PacketRemapper() {
|
||||
@Override
|
||||
public void registerMap() {
|
||||
map(Type.INT); // 0 - Entity ID
|
||||
map(Type.UNSIGNED_BYTE); // 1 - Gamemode
|
||||
map(Type.INT); // 2 - Dimension
|
||||
|
||||
handler(new PacketHandler() {
|
||||
@Override
|
||||
public void handle(PacketWrapper wrapper) throws Exception {
|
||||
ClientWorld clientChunks = wrapper.user().get(ClientWorld.class);
|
||||
|
||||
int dimensionId = wrapper.get(Type.INT, 1);
|
||||
clientChunks.setEnvironment(dimensionId);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Respawn (save dimension id)
|
||||
registerOutgoing(State.PLAY, 0x33, 0x33, new PacketRemapper() {
|
||||
@Override
|
||||
public void registerMap() {
|
||||
map(Type.INT); // 0 - Dimension ID
|
||||
|
||||
handler(new PacketHandler() {
|
||||
@Override
|
||||
public void handle(PacketWrapper wrapper) throws Exception {
|
||||
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
|
||||
|
||||
int dimensionId = wrapper.get(Type.INT, 0);
|
||||
clientWorld.setEnvironment(dimensionId);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -67,6 +111,7 @@ public class Protocol1_9_1_2TO1_9_3_4 extends Protocol {
|
||||
|
||||
@Override
|
||||
public void init(UserConnection userConnection) {
|
||||
|
||||
if (!userConnection.has(ClientWorld.class))
|
||||
userConnection.put(new ClientWorld(userConnection));
|
||||
}
|
||||
}
|
||||
+4
-22
@@ -1,4 +1,4 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4;
|
||||
package us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.spacehq.opennbt.tag.builtin.CompoundTag;
|
||||
@@ -7,6 +7,7 @@ import us.myles.ViaVersion.api.ViaVersion;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.minecraft.Position;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.Protocol1_9_1_2TO1_9_3_4;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -26,9 +27,6 @@ public class BlockEntity {
|
||||
types.put("UNKNOWN", 7);
|
||||
types.put("EndGateway", 8);
|
||||
types.put("Sign", 9);
|
||||
|
||||
//I didn't see anything that didn't work about chests
|
||||
// types.put("Chest", -1);
|
||||
}
|
||||
|
||||
public static void handle(List<CompoundTag> tags, UserConnection connection) {
|
||||
@@ -45,21 +43,13 @@ public class BlockEntity {
|
||||
if (newId == -1)
|
||||
continue;
|
||||
|
||||
|
||||
int x = (int) tag.get("x").getValue();
|
||||
int y = (int) tag.get("y").getValue();
|
||||
int z = (int) tag.get("z").getValue();
|
||||
|
||||
Position pos = new Position((long) x, (long) y, (long) z);
|
||||
|
||||
if (newId != 9) {
|
||||
updateBlockEntity(pos, (short) newId, tag, connection);
|
||||
} else {
|
||||
String[] lines = new String[4];
|
||||
for (int i = 1; i < 5; i++)
|
||||
lines[i - 1] = (String) tag.get("Text" + i).getValue();
|
||||
updateSign(pos, lines, connection);
|
||||
}
|
||||
updateBlockEntity(pos, (short) newId, tag, connection);
|
||||
} catch (Exception e) {
|
||||
if (ViaVersion.getInstance().isDebug()) {
|
||||
System.out.println("Block Entity: " + e.getMessage() + ": " + tag);
|
||||
@@ -73,14 +63,6 @@ public class BlockEntity {
|
||||
wrapper.write(Type.POSITION, pos);
|
||||
wrapper.write(Type.UNSIGNED_BYTE, id);
|
||||
wrapper.write(Type.NBT, tag);
|
||||
wrapper.send(Protocol1_9_1_2TO1_9_3_4.class);
|
||||
}
|
||||
|
||||
private static void updateSign(Position pos, String[] lines, UserConnection connection) throws Exception {
|
||||
PacketWrapper wrapper = new PacketWrapper(0x46, null, connection);
|
||||
wrapper.write(Type.POSITION, pos);
|
||||
for (String s : lines)
|
||||
wrapper.write(Type.STRING, s);
|
||||
wrapper.send(Protocol1_9_1_2TO1_9_3_4.class);
|
||||
wrapper.send(Protocol1_9_1_2TO1_9_3_4.class, false);
|
||||
}
|
||||
}
|
||||
+8
-3
@@ -1,4 +1,4 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4;
|
||||
package us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
@@ -14,7 +14,12 @@ public class Chunk1_9_3_4 implements Chunk {
|
||||
private int z;
|
||||
private boolean groundUp;
|
||||
private int bitmask;
|
||||
private byte[] sections;
|
||||
List<CompoundTag> blockEntities;
|
||||
private ChunkSection1_9_3_4[] sections;
|
||||
private byte[] biomeData;
|
||||
private List<CompoundTag> blockEntities;
|
||||
|
||||
@Override
|
||||
public boolean isBiomeData() {
|
||||
return biomeData != null;
|
||||
}
|
||||
}
|
||||
+293
@@ -0,0 +1,293 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.Getter;
|
||||
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
|
||||
import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ChunkSection1_9_3_4 implements ChunkSection {
|
||||
/**
|
||||
* Size (dimensions) of blocks in a chunks section.
|
||||
*/
|
||||
public static final int SIZE = 16 * 16 * 16; // width * depth * height
|
||||
/**
|
||||
* Length of the sky and block light nibble arrays.
|
||||
*/
|
||||
public static final int LIGHT_LENGTH = 16 * 16 * 16 / 2; // size * size * size / 2 (nibble bit count)
|
||||
/**
|
||||
* Length of the block data array.
|
||||
*/
|
||||
@Getter
|
||||
private final List<Integer> palette = Lists.newArrayList();
|
||||
private final int[] blocks;
|
||||
private final NibbleArray blockLight;
|
||||
private NibbleArray skyLight;
|
||||
|
||||
public ChunkSection1_9_3_4() {
|
||||
this.blocks = new int[SIZE];
|
||||
this.blockLight = new NibbleArray(SIZE);
|
||||
palette.add(0); // AIR
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a block in the chunks
|
||||
*
|
||||
* @param x Block X
|
||||
* @param y Block Y
|
||||
* @param z Block Z
|
||||
* @param type The type of the block
|
||||
* @param data The data value of the block
|
||||
*/
|
||||
public void setBlock(int x, int y, int z, int type, int data) {
|
||||
setBlock(index(x, y, z), type, data);
|
||||
}
|
||||
|
||||
public int getBlockId(int x, int y, int z) {
|
||||
int index = blocks[index(x, y, z)];
|
||||
return palette.get(index) >> 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a block in the chunks based on the index
|
||||
*
|
||||
* @param idx Index
|
||||
* @param type The type of the block
|
||||
* @param data The data value of the block
|
||||
*/
|
||||
public void setBlock(int idx, int type, int data) {
|
||||
int hash = type << 4 | (data & 0xF);
|
||||
int index = palette.indexOf(hash);
|
||||
if (index == -1) {
|
||||
index = palette.size();
|
||||
palette.add(hash);
|
||||
}
|
||||
|
||||
blocks[idx] = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the block light array
|
||||
*
|
||||
* @param data The value to set the block light to
|
||||
*/
|
||||
public void setBlockLight(byte[] data) {
|
||||
blockLight.setHandle(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the sky light array
|
||||
*
|
||||
* @param data The value to set the sky light to
|
||||
*/
|
||||
public void setSkyLight(byte[] data) {
|
||||
if (data.length != LIGHT_LENGTH) throw new IllegalArgumentException("Data length != " + LIGHT_LENGTH);
|
||||
this.skyLight = new NibbleArray(data);
|
||||
}
|
||||
|
||||
private int index(int x, int y, int z) {
|
||||
return y << 8 | z << 4 | x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read blocks from input stream.
|
||||
* This reads all the block related data:
|
||||
* <ul>
|
||||
* <li>Block length/palette type</li>
|
||||
* <li>Palette</li>
|
||||
* <li>Block hashes/palette reference</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param input The buffer to read from.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void readBlocks(ByteBuf input) throws Exception {
|
||||
palette.clear();
|
||||
|
||||
// Reaad bits per block
|
||||
int bitsPerBlock = input.readUnsignedByte();
|
||||
long maxEntryValue = (1L << bitsPerBlock) - 1;
|
||||
|
||||
if (bitsPerBlock == 0) {
|
||||
bitsPerBlock = 13;
|
||||
}
|
||||
if (bitsPerBlock < 4) {
|
||||
bitsPerBlock = 4;
|
||||
}
|
||||
if (bitsPerBlock > 8) {
|
||||
bitsPerBlock = 13;
|
||||
}
|
||||
int paletteLength = Type.VAR_INT.read(input);
|
||||
// Read palette
|
||||
for (int i = 0; i < paletteLength; i++) {
|
||||
if (bitsPerBlock != 13) {
|
||||
palette.add(Type.VAR_INT.read(input));
|
||||
} else {
|
||||
Type.VAR_INT.read(input);
|
||||
}
|
||||
}
|
||||
|
||||
// Read blocks
|
||||
Long[] blockData = Type.LONG_ARRAY.read(input);
|
||||
if (blockData.length > 0) {
|
||||
for (int i = 0; i < blocks.length; i++) {
|
||||
int bitIndex = i * bitsPerBlock;
|
||||
int startIndex = bitIndex / 64;
|
||||
int endIndex = ((i + 1) * bitsPerBlock - 1) / 64;
|
||||
int startBitSubIndex = bitIndex % 64;
|
||||
int val;
|
||||
if (startIndex == endIndex) {
|
||||
val = (int) (blockData[startIndex] >>> startBitSubIndex & maxEntryValue);
|
||||
} else {
|
||||
int endBitSubIndex = 64 - startBitSubIndex;
|
||||
val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue);
|
||||
}
|
||||
|
||||
if (bitsPerBlock == 13) {
|
||||
int type = val >> 4;
|
||||
int data = val & 0xF;
|
||||
|
||||
setBlock(i, type, data);
|
||||
} else {
|
||||
blocks[i] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read block light from buffer.
|
||||
*
|
||||
* @param input The buffer to read from
|
||||
*/
|
||||
public void readBlockLight(ByteBuf input) {
|
||||
byte[] handle = new byte[LIGHT_LENGTH];
|
||||
input.readBytes(handle);
|
||||
blockLight.setHandle(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read sky light from buffer.
|
||||
* Note: Only sent in overworld!
|
||||
*
|
||||
* @param input The buffer to read from
|
||||
*/
|
||||
public void readSkyLight(ByteBuf input) {
|
||||
byte[] handle = new byte[LIGHT_LENGTH];
|
||||
input.readBytes(handle);
|
||||
if (skyLight != null) {
|
||||
skyLight.setHandle(handle);
|
||||
return;
|
||||
}
|
||||
|
||||
this.skyLight = new NibbleArray(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the blocks to a buffer.
|
||||
*
|
||||
* @param output The buffer to write to.
|
||||
* @throws Exception Throws if it failed to write.
|
||||
*/
|
||||
public void writeBlocks(ByteBuf output) throws Exception {
|
||||
// Write bits per block
|
||||
int bitsPerBlock = 4;
|
||||
while (palette.size() > 1 << bitsPerBlock) {
|
||||
bitsPerBlock += 1;
|
||||
}
|
||||
long maxEntryValue = (1L << bitsPerBlock) - 1;
|
||||
output.writeByte(bitsPerBlock);
|
||||
|
||||
// Write pallet (or not)
|
||||
Type.VAR_INT.write(output, palette.size());
|
||||
for (int mappedId : palette) {
|
||||
Type.VAR_INT.write(output, mappedId);
|
||||
}
|
||||
|
||||
int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0);
|
||||
Type.VAR_INT.write(output, length);
|
||||
long[] data = new long[length];
|
||||
for (int index = 0; index < blocks.length; index++) {
|
||||
int value = blocks[index];
|
||||
int bitIndex = index * bitsPerBlock;
|
||||
int startIndex = bitIndex / 64;
|
||||
int endIndex = ((index + 1) * bitsPerBlock - 1) / 64;
|
||||
int startBitSubIndex = bitIndex % 64;
|
||||
data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex;
|
||||
if (startIndex != endIndex) {
|
||||
int endBitSubIndex = 64 - startBitSubIndex;
|
||||
data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex;
|
||||
}
|
||||
}
|
||||
for (long l : data) {
|
||||
Type.LONG.write(output, l);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the block light to a buffer
|
||||
*
|
||||
* @param output The buffer to write to
|
||||
*/
|
||||
public void writeBlockLight(ByteBuf output) {
|
||||
output.writeBytes(blockLight.getHandle());
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the sky light to a buffer
|
||||
*
|
||||
* @param output The buffer to write to
|
||||
*/
|
||||
public void writeSkyLight(ByteBuf output) {
|
||||
output.writeBytes(skyLight.getHandle());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if sky light is present
|
||||
*
|
||||
* @return True if skylight is present
|
||||
*/
|
||||
public boolean hasSkyLight() {
|
||||
return skyLight != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get expected size of this chunks section.
|
||||
*
|
||||
* @return Amount of bytes sent by this section
|
||||
* @throws Exception If it failed to calculate bits properly
|
||||
*/
|
||||
public int getExpectedSize() throws Exception {
|
||||
int bitsPerBlock = palette.size() > 255 ? 16 : 8;
|
||||
int bytes = 1; // bits per block
|
||||
bytes += paletteBytes(); // palette
|
||||
bytes += countBytes(bitsPerBlock == 16 ? SIZE * 2 : SIZE); // block data length
|
||||
bytes += (palette.size() > 255 ? 2 : 1) * SIZE; // block data
|
||||
bytes += LIGHT_LENGTH; // block light
|
||||
bytes += hasSkyLight() ? LIGHT_LENGTH : 0; // sky light
|
||||
return bytes;
|
||||
}
|
||||
|
||||
private int paletteBytes() throws Exception {
|
||||
// Count bytes used by pallet
|
||||
int bytes = countBytes(palette.size());
|
||||
for (int mappedId : palette) {
|
||||
bytes += countBytes(mappedId);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
private int countBytes(int value) throws Exception {
|
||||
// Count amount of bytes that would be sent if the value were sent as a VarInt
|
||||
ByteBuf buf = Unpooled.buffer();
|
||||
Type.VAR_INT.write(buf, value);
|
||||
buf.readerIndex(0);
|
||||
int bitCount = buf.readableBytes();
|
||||
buf.release();
|
||||
return bitCount;
|
||||
}
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.types;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import org.bukkit.World;
|
||||
import org.spacehq.opennbt.tag.builtin.CompoundTag;
|
||||
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
|
||||
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
|
||||
import us.myles.ViaVersion.api.type.PartialType;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.api.type.types.minecraft.BaseChunkType;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks.Chunk1_9_3_4;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks.ChunkSection1_9_3_4;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
|
||||
public class Chunk1_9_3_4Type extends PartialType<Chunk, ClientWorld> {
|
||||
|
||||
public Chunk1_9_3_4Type(ClientWorld param) {
|
||||
super(param, Chunk.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk read(ByteBuf input, ClientWorld world) throws Exception {
|
||||
int chunkX = input.readInt();
|
||||
int chunkZ = input.readInt();
|
||||
|
||||
boolean groundUp = input.readBoolean();
|
||||
int primaryBitmask = Type.VAR_INT.read(input);
|
||||
Type.VAR_INT.read(input);
|
||||
|
||||
BitSet usedSections = new BitSet(16);
|
||||
ChunkSection1_9_3_4[] sections = new ChunkSection1_9_3_4[16];
|
||||
// Calculate section count from bitmask
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if ((primaryBitmask & (1 << i)) != 0) {
|
||||
usedSections.set(i);
|
||||
}
|
||||
}
|
||||
|
||||
// Read sections
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (!usedSections.get(i)) continue; // Section not set
|
||||
ChunkSection1_9_3_4 section = new ChunkSection1_9_3_4();
|
||||
sections[i] = section;
|
||||
section.readBlocks(input);
|
||||
section.readBlockLight(input);
|
||||
if (world.getEnvironment() == World.Environment.NORMAL) {
|
||||
section.readSkyLight(input);
|
||||
}
|
||||
}
|
||||
|
||||
byte[] biomeData = groundUp ? new byte[256] : null;
|
||||
if (groundUp) {
|
||||
input.readBytes(biomeData);
|
||||
}
|
||||
|
||||
List<CompoundTag> nbtData = Arrays.asList(Type.NBT_ARRAY.read(input));
|
||||
|
||||
return new Chunk1_9_3_4(chunkX, chunkZ, groundUp, primaryBitmask, sections, biomeData, nbtData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf output, ClientWorld world, Chunk chunk) throws Exception {
|
||||
output.writeInt(chunk.getX());
|
||||
output.writeInt(chunk.getZ());
|
||||
|
||||
output.writeBoolean(chunk.isGroundUp());
|
||||
Type.VAR_INT.write(output, chunk.getBitmask());
|
||||
|
||||
ByteBuf buf = Unpooled.buffer();
|
||||
for (int i = 0; i < 16; i++) {
|
||||
ChunkSection section = chunk.getSections()[i];
|
||||
if (section == null) continue; // Section not set
|
||||
section.writeBlocks(buf);
|
||||
section.writeBlockLight(buf);
|
||||
|
||||
if (!section.hasSkyLight()) continue; // No sky light, we're done here.
|
||||
section.writeSkyLight(buf);
|
||||
|
||||
}
|
||||
buf.readerIndex(0);
|
||||
Type.VAR_INT.write(output, buf.readableBytes() + (chunk.isBiomeData() ? 256 : 0));
|
||||
output.writeBytes(buf);
|
||||
buf.release(); // release buffer
|
||||
|
||||
// Write biome data
|
||||
if (chunk.isBiomeData()) {
|
||||
output.writeBytes(chunk.getBiomeData());
|
||||
}
|
||||
|
||||
// Don't write block entities
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Type> getBaseClass() {
|
||||
return BaseChunkType.class;
|
||||
}
|
||||
}
|
||||
+61
-29
@@ -6,15 +6,16 @@ import org.spacehq.opennbt.tag.builtin.StringTag;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.minecraft.Position;
|
||||
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
|
||||
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
|
||||
import us.myles.ViaVersion.api.protocol.Protocol;
|
||||
import us.myles.ViaVersion.api.remapper.PacketHandler;
|
||||
import us.myles.ViaVersion.api.remapper.PacketRemapper;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.packets.State;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.chunks.Chunk1_9to1_8;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.chunks.ChunkSection1_9to1_8;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.types.ChunkType;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.chunks.FakeTileEntity;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.types.Chunk1_9_1_2Type;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -74,35 +75,65 @@ public class Protocol1_9_3TO1_9_1_2 extends Protocol {
|
||||
handler(new PacketHandler() {
|
||||
@Override
|
||||
public void handle(PacketWrapper wrapper) throws Exception {
|
||||
ClientChunks clientChunks = wrapper.user().get(ClientChunks.class);
|
||||
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
|
||||
|
||||
ChunkType type = new ChunkType(clientChunks);
|
||||
if (wrapper.isReadable(type, 0)) {
|
||||
Chunk1_9to1_8 chunk = (Chunk1_9to1_8) wrapper.read(type);
|
||||
Chunk1_9_1_2Type type = new Chunk1_9_1_2Type(clientWorld);
|
||||
Chunk chunk = wrapper.passthrough(type);
|
||||
|
||||
List<CompoundTag> tags = new ArrayList<>();
|
||||
for (int i = 0; i < chunk.getSections().length; i++) {
|
||||
ChunkSection1_9to1_8 section = chunk.getSections()[i];
|
||||
if (section == null)
|
||||
continue;
|
||||
List<CompoundTag> tags = new ArrayList<>();
|
||||
for (int i = 0; i < chunk.getSections().length; i++) {
|
||||
ChunkSection section = chunk.getSections()[i];
|
||||
if (section == null)
|
||||
continue;
|
||||
|
||||
for (int x = 0; x < 16; x++)
|
||||
for (int y = 0; y < 16; y++)
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int block = section.getBlockId(x, y, z);
|
||||
if (FakeTileEntity.hasBlock(block)) {
|
||||
// NOT SURE WHY Y AND Z WORK THIS WAY, TODO: WORK OUT WHY THIS IS OR FIX W/E BROKE IT
|
||||
tags.add(FakeTileEntity.getFromBlock(x + (chunk.getX() << 4), z + (i << 4), y + (chunk.getZ() << 4), block));
|
||||
}
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int block = section.getBlockId(x, y, z);
|
||||
if (FakeTileEntity.hasBlock(block)) {
|
||||
tags.add(FakeTileEntity.getFromBlock(x + (chunk.getX() << 4), y + (i << 4), z + (chunk.getZ() << 4), block));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wrapper.write(type, chunk);
|
||||
wrapper.write(Type.NBT_ARRAY, tags.toArray(new CompoundTag[0]));
|
||||
} else {
|
||||
wrapper.passthroughAll();
|
||||
wrapper.write(Type.VAR_INT, 0);
|
||||
}
|
||||
|
||||
wrapper.write(Type.NBT_ARRAY, tags.toArray(new CompoundTag[0]));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Join (save dimension id)
|
||||
registerOutgoing(State.PLAY, 0x23, 0x23, new PacketRemapper() {
|
||||
@Override
|
||||
public void registerMap() {
|
||||
map(Type.INT); // 0 - Entity ID
|
||||
map(Type.UNSIGNED_BYTE); // 1 - Gamemode
|
||||
map(Type.INT); // 2 - Dimension
|
||||
|
||||
handler(new PacketHandler() {
|
||||
@Override
|
||||
public void handle(PacketWrapper wrapper) throws Exception {
|
||||
ClientWorld clientChunks = wrapper.user().get(ClientWorld.class);
|
||||
int dimensionId = wrapper.get(Type.INT, 1);
|
||||
clientChunks.setEnvironment(dimensionId);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Respawn (save dimension id)
|
||||
registerOutgoing(State.PLAY, 0x33, 0x33, new PacketRemapper() {
|
||||
@Override
|
||||
public void registerMap() {
|
||||
map(Type.INT); // 0 - Dimension ID
|
||||
handler(new PacketHandler() {
|
||||
@Override
|
||||
public void handle(PacketWrapper wrapper) throws Exception {
|
||||
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
|
||||
int dimensionId = wrapper.get(Type.INT, 0);
|
||||
clientWorld.setEnvironment(dimensionId);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -110,7 +141,8 @@ public class Protocol1_9_3TO1_9_1_2 extends Protocol {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(UserConnection userConnection) {
|
||||
|
||||
public void init(UserConnection user) {
|
||||
if (!user.has(ClientWorld.class))
|
||||
user.put(new ClientWorld(user));
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2;
|
||||
package us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.chunks;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
+102
-6
@@ -1,14 +1,16 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2;
|
||||
package us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.chunks;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.Getter;
|
||||
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
|
||||
import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ChunkSection1_9_1_2 {
|
||||
public class ChunkSection1_9_1_2 implements ChunkSection {
|
||||
/**
|
||||
* Size (dimensions) of blocks in a chunks section.
|
||||
*/
|
||||
@@ -20,7 +22,7 @@ public class ChunkSection1_9_1_2 {
|
||||
/**
|
||||
* Length of the block data array.
|
||||
*/
|
||||
|
||||
@Getter
|
||||
private final List<Integer> palette = Lists.newArrayList();
|
||||
private final int[] blocks;
|
||||
private final NibbleArray blockLight;
|
||||
@@ -45,9 +47,9 @@ public class ChunkSection1_9_1_2 {
|
||||
setBlock(index(x, y, z), type, data);
|
||||
}
|
||||
|
||||
public int getBlockId(int x, int y, int z){
|
||||
public int getBlockId(int x, int y, int z) {
|
||||
int index = blocks[index(x, y, z)];
|
||||
return palette.indexOf(index) >> 4;
|
||||
return palette.get(index) >> 4;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,7 +90,101 @@ public class ChunkSection1_9_1_2 {
|
||||
}
|
||||
|
||||
private int index(int x, int y, int z) {
|
||||
return z << 8 | y << 4 | x;
|
||||
return y << 8 | z << 4 | x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read blocks from input stream.
|
||||
* This reads all the block related data:
|
||||
* <ul>
|
||||
* <li>Block length/palette type</li>
|
||||
* <li>Palette</li>
|
||||
* <li>Block hashes/palette reference</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param input The buffer to read from.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void readBlocks(ByteBuf input) throws Exception {
|
||||
palette.clear();
|
||||
|
||||
// Reaad bits per block
|
||||
int bitsPerBlock = input.readUnsignedByte();
|
||||
long maxEntryValue = (1L << bitsPerBlock) - 1;
|
||||
|
||||
if (bitsPerBlock == 0) {
|
||||
bitsPerBlock = 13;
|
||||
}
|
||||
if (bitsPerBlock < 4) {
|
||||
bitsPerBlock = 4;
|
||||
}
|
||||
if (bitsPerBlock > 8) {
|
||||
bitsPerBlock = 13;
|
||||
}
|
||||
int paletteLength = Type.VAR_INT.read(input);
|
||||
// Read palette
|
||||
for (int i = 0; i < paletteLength; i++) {
|
||||
if (bitsPerBlock != 13) {
|
||||
palette.add(Type.VAR_INT.read(input));
|
||||
} else {
|
||||
Type.VAR_INT.read(input);
|
||||
}
|
||||
}
|
||||
|
||||
// Read blocks
|
||||
Long[] blockData = Type.LONG_ARRAY.read(input);
|
||||
if (blockData.length > 0) {
|
||||
for (int i = 0; i < blocks.length; i++) {
|
||||
int bitIndex = i * bitsPerBlock;
|
||||
int startIndex = bitIndex / 64;
|
||||
int endIndex = ((i + 1) * bitsPerBlock - 1) / 64;
|
||||
int startBitSubIndex = bitIndex % 64;
|
||||
int val;
|
||||
if (startIndex == endIndex) {
|
||||
val = (int) (blockData[startIndex] >>> startBitSubIndex & maxEntryValue);
|
||||
} else {
|
||||
int endBitSubIndex = 64 - startBitSubIndex;
|
||||
val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue);
|
||||
}
|
||||
|
||||
if (bitsPerBlock == 13) {
|
||||
int type = val >> 4;
|
||||
int data = val & 0xF;
|
||||
|
||||
setBlock(i, type, data);
|
||||
} else {
|
||||
blocks[i] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read block light from buffer.
|
||||
*
|
||||
* @param input The buffer to read from
|
||||
*/
|
||||
public void readBlockLight(ByteBuf input) {
|
||||
byte[] handle = new byte[LIGHT_LENGTH];
|
||||
input.readBytes(handle);
|
||||
blockLight.setHandle(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read sky light from buffer.
|
||||
* Note: Only sent in overworld!
|
||||
*
|
||||
* @param input The buffer to read from
|
||||
*/
|
||||
public void readSkyLight(ByteBuf input) {
|
||||
byte[] handle = new byte[LIGHT_LENGTH];
|
||||
input.readBytes(handle);
|
||||
if (skyLight != null) {
|
||||
skyLight.setHandle(handle);
|
||||
return;
|
||||
}
|
||||
|
||||
this.skyLight = new NibbleArray(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2;
|
||||
package us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.chunks;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.spacehq.opennbt.tag.builtin.CompoundTag;
|
||||
@@ -27,7 +27,7 @@ public class FakeTileEntity {
|
||||
register(Arrays.asList(Material.SIGN_POST, Material.WALL_SIGN), "Sign");
|
||||
register(Material.MOB_SPAWNER, "MobSpawner");
|
||||
register(Material.NOTE_BLOCK, "Music");
|
||||
register(Material.PISTON_BASE, "Piston");
|
||||
register(Arrays.asList(Material.PISTON_BASE, Material.PISTON_EXTENSION, Material.PISTON_STICKY_BASE, Material.PISTON_MOVING_PIECE), "Piston");
|
||||
register(Arrays.asList(Material.BREWING_STAND, Material.CAULDRON), "Cauldron");
|
||||
register(Material.ENCHANTMENT_TABLE, "EnchantTable");
|
||||
register(Arrays.asList(Material.ENDER_PORTAL, Material.ENDER_PORTAL_FRAME), "Airportal");
|
||||
@@ -38,7 +38,7 @@ public class FakeTileEntity {
|
||||
register(Arrays.asList(Material.REDSTONE_COMPARATOR, Material.REDSTONE_COMPARATOR_OFF, Material.REDSTONE_COMPARATOR_ON), "Comparator");
|
||||
register(Material.FLOWER_POT, "FlowerPot");
|
||||
register(Arrays.asList(Material.STANDING_BANNER, Material.WALL_BANNER, Material.BANNER), "Banner");
|
||||
register(209, "EndGateway"); // todo test
|
||||
register(209, "EndGateway");
|
||||
register(Material.COMMAND.getId(), "Control");
|
||||
}
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.bukkit.World;
|
||||
import us.myles.ViaVersion.api.data.StoredObject;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
|
||||
@Getter
|
||||
public class ClientWorld extends StoredObject {
|
||||
private World.Environment environment;
|
||||
|
||||
public ClientWorld(UserConnection user) {
|
||||
super(user);
|
||||
}
|
||||
|
||||
public void setEnvironment(int environmentId) {
|
||||
this.environment = getEnvFromId(environmentId);
|
||||
}
|
||||
|
||||
private World.Environment getEnvFromId(int id) {
|
||||
switch(id) {
|
||||
case -1:
|
||||
return World.Environment.NETHER;
|
||||
case 0:
|
||||
return World.Environment.NORMAL;
|
||||
case 1:
|
||||
return World.Environment.THE_END;
|
||||
default:
|
||||
return World.Environment.NETHER;
|
||||
//throw new IllegalArgumentException("Invalid environment id:" + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
+38
-23
@@ -1,23 +1,35 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2;
|
||||
package us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.types;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import org.bukkit.World;
|
||||
import org.spacehq.opennbt.tag.builtin.CompoundTag;
|
||||
import us.myles.ViaVersion.api.ViaVersion;
|
||||
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
|
||||
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
|
||||
import us.myles.ViaVersion.api.type.PartialType;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.api.type.types.minecraft.BaseChunkType;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.chunks.ChunkSection1_9to1_8;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.protocols.protocol1_10to1_9_3.Protocol1_10To1_9_3_4;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.chunks.Chunk1_9_1_2;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.chunks.ChunkSection1_9_1_2;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
|
||||
public class Chunk1_9_1_2Type extends BaseChunkType {
|
||||
public Chunk1_9_1_2Type() {
|
||||
super("1.9.1/2 Chunk");
|
||||
public class Chunk1_9_1_2Type extends PartialType<Chunk, ClientWorld> {
|
||||
|
||||
public Chunk1_9_1_2Type(ClientWorld clientWorld) {
|
||||
super(clientWorld, Chunk.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk read(ByteBuf input) throws Exception {
|
||||
public Chunk read(ByteBuf input, ClientWorld world) throws Exception {
|
||||
boolean replacePistons = world.getUser().get(ProtocolInfo.class).getPipeline().contains(Protocol1_10To1_9_3_4.class) && ViaVersion.getConfig().isReplacePistons();
|
||||
int replacementId = ViaVersion.getConfig().getPistonReplacementId();
|
||||
|
||||
int chunkX = input.readInt();
|
||||
int chunkZ = input.readInt();
|
||||
|
||||
@@ -39,29 +51,29 @@ public class Chunk1_9_1_2Type extends BaseChunkType {
|
||||
if (!usedSections.get(i)) continue; // Section not set
|
||||
ChunkSection1_9_1_2 section = new ChunkSection1_9_1_2();
|
||||
sections[i] = section;
|
||||
// WIP.
|
||||
// section.readBlocks(input);
|
||||
// section.readBlockLight(input);
|
||||
// section.readSkyLight(input);
|
||||
/*
|
||||
BlockStorage blocks = new BlockStorage(in);
|
||||
NibbleArray3d blocklight = new NibbleArray3d(in, 2048); (1024 bytes)
|
||||
NibbleArray3d skylight = hasSkylight ? new NibbleArray3d(in, 2048) : null; (1024 bytes)
|
||||
chunks[index] = new Chunk(blocks, blocklight, skylight);
|
||||
*/
|
||||
section.readBlocks(input);
|
||||
section.readBlockLight(input);
|
||||
if (world.getEnvironment() == World.Environment.NORMAL) {
|
||||
section.readSkyLight(input);
|
||||
}
|
||||
if (replacePistons) {
|
||||
if (section.getPalette().contains(36)) {
|
||||
section.getPalette().set(section.getPalette().indexOf(36), replacementId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byte[] biomeData = groundUp ? new byte[256] : null;
|
||||
if (groundUp)
|
||||
if (groundUp) {
|
||||
input.readBytes(biomeData);
|
||||
}
|
||||
|
||||
return new Chunk1_9_1_2(chunkX, chunkZ, groundUp, primaryBitmask, sections, biomeData, new ArrayList<CompoundTag>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf output, Chunk input) throws Exception {
|
||||
if (!(input instanceof Chunk1_9_1_2))
|
||||
throw new Exception("Tried to send the wrong chunk type from 1.9.3-4 chunk: " + input.getClass());
|
||||
Chunk1_9_1_2 chunk = (Chunk1_9_1_2) input;
|
||||
public void write(ByteBuf output, ClientWorld world, Chunk input) throws Exception {
|
||||
Chunk chunk = input;
|
||||
|
||||
output.writeInt(chunk.getX());
|
||||
output.writeInt(chunk.getZ());
|
||||
@@ -71,7 +83,7 @@ public class Chunk1_9_1_2Type extends BaseChunkType {
|
||||
|
||||
ByteBuf buf = Unpooled.buffer();
|
||||
for (int i = 0; i < 16; i++) {
|
||||
ChunkSection1_9_1_2 section = chunk.getSections()[i];
|
||||
ChunkSection section = chunk.getSections()[i];
|
||||
if (section == null) continue; // Section not set
|
||||
section.writeBlocks(buf);
|
||||
section.writeBlockLight(buf);
|
||||
@@ -89,7 +101,10 @@ public class Chunk1_9_1_2Type extends BaseChunkType {
|
||||
if (chunk.isBiomeData()) {
|
||||
output.writeBytes(chunk.getBiomeData());
|
||||
}
|
||||
}
|
||||
|
||||
// Type.NBT_ARRAY.write(output, tags.toArray(new CompoundTag[0])); Written by the handler
|
||||
@Override
|
||||
public Class<? extends Type> getBaseClass() {
|
||||
return BaseChunkType.class;
|
||||
}
|
||||
}
|
||||
@@ -213,11 +213,9 @@ public class ItemRewriter {
|
||||
item.setId((short) 438); // splash id
|
||||
item.setData((short) (item.getData() - 8192));
|
||||
}
|
||||
if (POTION_ID_TO_NAME.containsKey((int) item.getData())) {
|
||||
String name = POTION_ID_TO_NAME.get((int) item.getData());
|
||||
StringTag potion = new StringTag("Potion", "minecraft:" + name);
|
||||
tag.put(potion);
|
||||
}
|
||||
String name = potionNameFromDamage(item.getData());
|
||||
StringTag potion = new StringTag("Potion", "minecraft:" + name);
|
||||
tag.put(potion);
|
||||
item.setTag(tag);
|
||||
item.setData((short) 0);
|
||||
}
|
||||
@@ -245,10 +243,113 @@ public class ItemRewriter {
|
||||
}
|
||||
}
|
||||
|
||||
public static String potionNameFromDamage(short damage) {
|
||||
String cached = POTION_ID_TO_NAME.get((int) damage);
|
||||
if (cached != null) {
|
||||
return cached;
|
||||
}
|
||||
if (damage == 0) {
|
||||
return "water";
|
||||
}
|
||||
|
||||
int effect = damage & 0xF;
|
||||
int name = damage & 0x3F;
|
||||
boolean enhanced = (damage & 0x20) > 0;
|
||||
boolean extended = (damage & 0x40) > 0;
|
||||
|
||||
boolean canEnhance = true;
|
||||
boolean canExtend = true;
|
||||
|
||||
String id;
|
||||
switch (effect) {
|
||||
case 1:
|
||||
id = "regeneration";
|
||||
break;
|
||||
case 2:
|
||||
id = "swiftness";
|
||||
break;
|
||||
case 3:
|
||||
id = "fire_resistance";
|
||||
canEnhance = false;
|
||||
break;
|
||||
case 4:
|
||||
id = "poison";
|
||||
break;
|
||||
case 5:
|
||||
id = "healing";
|
||||
canExtend = false;
|
||||
break;
|
||||
case 6:
|
||||
id = "night_vision";
|
||||
canEnhance = false;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
id = "weakness";
|
||||
canEnhance = false;
|
||||
break;
|
||||
case 9:
|
||||
id = "strength";
|
||||
break;
|
||||
case 10:
|
||||
id = "slowness";
|
||||
canEnhance = false;
|
||||
break;
|
||||
case 11:
|
||||
id = "leaping";
|
||||
break;
|
||||
case 12:
|
||||
id = "harming";
|
||||
canExtend = false;
|
||||
break;
|
||||
case 13:
|
||||
id = "water_breathing";
|
||||
canEnhance = false;
|
||||
break;
|
||||
case 14:
|
||||
id = "invisibility";
|
||||
canEnhance = false;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
canEnhance = false;
|
||||
canExtend = false;
|
||||
switch (name) {
|
||||
case 0:
|
||||
id = "mundane";
|
||||
break;
|
||||
case 16:
|
||||
id = "awkward";
|
||||
break;
|
||||
case 32:
|
||||
id = "thick";
|
||||
break;
|
||||
default:
|
||||
id = "empty";
|
||||
}
|
||||
}
|
||||
|
||||
if (effect > 0) {
|
||||
if (canEnhance && enhanced) {
|
||||
id = "strong_" + id;
|
||||
} else if (canExtend && extended) {
|
||||
id = "long_" + id;
|
||||
}
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
public static int getNewEffectID(int oldID) {
|
||||
if (oldID >= 16384) {
|
||||
oldID -= 8192;
|
||||
}
|
||||
if (POTION_INDEX.containsKey(oldID)) {
|
||||
return POTION_INDEX.get(oldID);
|
||||
}
|
||||
|
||||
oldID = POTION_NAME_TO_ID.get(potionNameFromDamage((short) oldID));
|
||||
return POTION_INDEX.containsKey(oldID) ? POTION_INDEX.get(oldID) : 0;
|
||||
}
|
||||
|
||||
|
||||
+27
-14
@@ -13,12 +13,12 @@ import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
|
||||
import us.myles.ViaVersion.api.protocol.Protocol;
|
||||
import us.myles.ViaVersion.api.remapper.ValueTransformer;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.api.type.types.version.Metadata1_8Type;
|
||||
import us.myles.ViaVersion.api.type.types.version.MetadataList1_8Type;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners.*;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.packets.*;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.*;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.types.MetadataListType;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.types.MetadataType;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
@@ -26,8 +26,11 @@ import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class Protocol1_9TO1_8 extends Protocol {
|
||||
public static Type<List<Metadata>> METADATA_LIST = new MetadataListType();
|
||||
public static Type<Metadata> METADATA = new MetadataType();
|
||||
@Deprecated
|
||||
public static Type<List<Metadata>> METADATA_LIST = new MetadataList1_8Type();
|
||||
@Deprecated
|
||||
public static Type<Metadata> METADATA = new Metadata1_8Type();
|
||||
|
||||
private static Gson gson = new GsonBuilder().create();
|
||||
public static ValueTransformer<String, String> FIX_JSON = new ValueTransformer<String, String>(Type.STRING) {
|
||||
@Override
|
||||
@@ -41,9 +44,7 @@ public class Protocol1_9TO1_8 extends Protocol {
|
||||
line = "{\"text\":\"\"}";
|
||||
} else {
|
||||
if ((!line.startsWith("\"") || !line.endsWith("\"")) && (!line.startsWith("{") || !line.endsWith("}"))) {
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.addProperty("text", line);
|
||||
return gson.toJson(jsonObject);
|
||||
return constructJson(line);
|
||||
}
|
||||
if (line.startsWith("\"") && line.endsWith("\"")) {
|
||||
line = "{\"text\":" + line + "}";
|
||||
@@ -52,12 +53,22 @@ public class Protocol1_9TO1_8 extends Protocol {
|
||||
try {
|
||||
gson.fromJson(line, JsonObject.class);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Invalid JSON String: \"" + line + "\" Please report this issue to the ViaVersion Github: " + e.getMessage());
|
||||
return "{\"text\":\"\"}";
|
||||
if (ViaVersion.getConfig().isForceJsonTransform()) {
|
||||
return constructJson(line);
|
||||
} else {
|
||||
System.out.println("Invalid JSON String: \"" + line + "\" Please report this issue to the ViaVersion Github: " + e.getMessage());
|
||||
return "{\"text\":\"\"}";
|
||||
}
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
private static String constructJson(String text) {
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.addProperty("text", text);
|
||||
return gson.toJson(jsonObject);
|
||||
}
|
||||
|
||||
public static Item getHandItem(final UserConnection info) {
|
||||
if (HandItemCache.CACHE) {
|
||||
return HandItemCache.getHandItem(info.get(ProtocolInfo.class).getUuid());
|
||||
@@ -94,13 +105,15 @@ public class Protocol1_9TO1_8 extends Protocol {
|
||||
@Override
|
||||
protected void registerListeners() {
|
||||
ViaVersionPlugin plugin = (ViaVersionPlugin) Bukkit.getPluginManager().getPlugin("ViaVersion");
|
||||
Bukkit.getPluginManager().registerEvents(new ArmorListener(plugin), plugin);
|
||||
Bukkit.getPluginManager().registerEvents(new CommandBlockListener(plugin), plugin);
|
||||
Bukkit.getPluginManager().registerEvents(new DeathListener(plugin), plugin);
|
||||
Bukkit.getPluginManager().registerEvents(new BlockListener(plugin), plugin);
|
||||
|
||||
new ArmorListener(plugin).register();
|
||||
new CommandBlockListener(plugin).register();
|
||||
new DeathListener(plugin).register();
|
||||
new BlockListener(plugin).register();
|
||||
|
||||
if (Bukkit.getVersion().toLowerCase().contains("paper") || Bukkit.getVersion().toLowerCase().contains("taco")) {
|
||||
plugin.getLogger().info("Enabling PaperSpigot/TacoSpigot patch: Fixes block placement.");
|
||||
Bukkit.getPluginManager().registerEvents(new PaperPatch(), plugin);
|
||||
new PaperPatch(plugin).register();
|
||||
}
|
||||
if (plugin.getConf().isStimulatePlayerTick())
|
||||
new ViaIdleThread(plugin.getPortedPlayers()).runTaskTimer(plugin, 1L, 1L); // Updates player's idle status
|
||||
|
||||
+19
@@ -3,8 +3,12 @@ package us.myles.ViaVersion.protocols.protocol1_9to1_8.chunks;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import org.spacehq.opennbt.tag.builtin.CompoundTag;
|
||||
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
@ToString
|
||||
@@ -36,4 +40,19 @@ public class Chunk1_9to1_8 implements Chunk {
|
||||
public boolean hasBiomeData() {
|
||||
return biomeData != null && groundUp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBiomeData() {
|
||||
return biomeData != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBitmask() {
|
||||
return primaryBitmask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CompoundTag> getBlockEntities() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -3,12 +3,13 @@ package us.myles.ViaVersion.protocols.protocol1_9to1_8.chunks;
|
||||
import com.google.common.collect.Lists;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
|
||||
import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ChunkSection1_9to1_8 {
|
||||
public class ChunkSection1_9to1_8 implements ChunkSection {
|
||||
/**
|
||||
* Size (dimensions) of blocks in a chunks section.
|
||||
*/
|
||||
@@ -88,7 +89,7 @@ public class ChunkSection1_9to1_8 {
|
||||
}
|
||||
|
||||
private int index(int x, int y, int z) {
|
||||
return z << 8 | y << 4 | x;
|
||||
return y << 8 | z << 4 | x;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+22
-33
@@ -1,12 +1,10 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
||||
@@ -16,30 +14,28 @@ import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
import org.bukkit.inventory.CraftingInventory;
|
||||
import us.myles.ViaVersion.ViaVersionPlugin;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.ViaVersion;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.ViaListener;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.ArmorType;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class ArmorListener implements Listener {
|
||||
public class ArmorListener extends ViaListener {
|
||||
|
||||
private static final UUID ARMOR_ATTRIBUTE = UUID.fromString("2AD3F246-FEE1-4E67-B886-69FD380BB150");
|
||||
private final ViaVersionPlugin plugin;
|
||||
|
||||
public static void sendArmorUpdate(Player player) {
|
||||
public ArmorListener(ViaVersionPlugin plugin) {
|
||||
super(plugin, Protocol1_9TO1_8.class);
|
||||
}
|
||||
|
||||
public void sendArmorUpdate(Player player) {
|
||||
// Ensure that the player is on our pipe
|
||||
UserConnection userConnection = ((ViaVersionPlugin) ViaVersion.getInstance()).getConnection(player);
|
||||
if (userConnection == null) return;
|
||||
if (!userConnection.get(ProtocolInfo.class).getPipeline().contains(Protocol1_9TO1_8.class)) return;
|
||||
if (!isOnPipe(player)) return;
|
||||
|
||||
int armor = ArmorType.calculateArmorPoints(player.getInventory().getArmorContents());
|
||||
|
||||
PacketWrapper wrapper = new PacketWrapper(0x4B, null, userConnection);
|
||||
PacketWrapper wrapper = new PacketWrapper(0x4B, null, getUserConnection(player));
|
||||
try {
|
||||
wrapper.write(Type.VAR_INT, player.getEntityId()); // Player ID
|
||||
wrapper.write(Type.INT, 1); // only 1 property
|
||||
@@ -61,17 +57,15 @@ public class ArmorListener implements Listener {
|
||||
HumanEntity human = e.getWhoClicked();
|
||||
if (human instanceof Player && e.getInventory() instanceof CraftingInventory) {
|
||||
final Player player = (Player) human;
|
||||
if (ViaVersion.getInstance().isPorted(player)) {
|
||||
if (e.getCurrentItem() != null) {
|
||||
if (ArmorType.isArmor(e.getCurrentItem().getType())) {
|
||||
sendDelayedArmorUpdate(player);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (e.getRawSlot() >= 5 && e.getRawSlot() <= 8) {
|
||||
if (e.getCurrentItem() != null) {
|
||||
if (ArmorType.isArmor(e.getCurrentItem().getType())) {
|
||||
sendDelayedArmorUpdate(player);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (e.getRawSlot() >= 5 && e.getRawSlot() <= 8) {
|
||||
sendDelayedArmorUpdate(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,12 +75,10 @@ public class ArmorListener implements Listener {
|
||||
if (e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK) {
|
||||
final Player player = e.getPlayer();
|
||||
// Due to odd bugs it's 3 ticks later
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (ViaVersion.getInstance().isPorted(player)) {
|
||||
sendArmorUpdate(player);
|
||||
}
|
||||
sendArmorUpdate(player);
|
||||
}
|
||||
}, 3L);
|
||||
}
|
||||
@@ -100,23 +92,20 @@ public class ArmorListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onRespawn(PlayerRespawnEvent e) {
|
||||
if (ViaVersion.getInstance().isPorted(e.getPlayer()))
|
||||
sendDelayedArmorUpdate(e.getPlayer());
|
||||
sendDelayedArmorUpdate(e.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onWorldChange(PlayerChangedWorldEvent e) {
|
||||
if (ViaVersion.getInstance().isPorted(e.getPlayer()))
|
||||
sendArmorUpdate(e.getPlayer());
|
||||
sendArmorUpdate(e.getPlayer());
|
||||
}
|
||||
|
||||
public void sendDelayedArmorUpdate(final Player player) {
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
if (!isOnPipe(player)) return; // Don't start a task if the player is not on the pipe
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (ViaVersion.getInstance().isPorted(player)) {
|
||||
sendArmorUpdate(player);
|
||||
}
|
||||
sendArmorUpdate(player);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+9
-11
@@ -1,30 +1,28 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import us.myles.ViaVersion.ViaVersionPlugin;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.ViaListener;
|
||||
import us.myles.ViaVersion.api.minecraft.Position;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class BlockListener implements Listener {
|
||||
public class BlockListener extends ViaListener {
|
||||
|
||||
private final ViaVersionPlugin plugin;
|
||||
public BlockListener(ViaVersionPlugin plugin) {
|
||||
super(plugin, Protocol1_9TO1_8.class);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void placeBlock(BlockPlaceEvent e) {
|
||||
if (plugin.isPorted(e.getPlayer())) {
|
||||
UserConnection c = plugin.getConnection(e.getPlayer());
|
||||
if (!c.get(ProtocolInfo.class).getPipeline().contains(Protocol1_9TO1_8.class)) return;
|
||||
if (isOnPipe(e.getPlayer())) {
|
||||
Block b = e.getBlockPlaced();
|
||||
plugin.getConnection(e.getPlayer()).get(EntityTracker.class).addBlockInteraction(new Position((long) b.getX(), (long) b.getY(), (long) b.getZ()));
|
||||
getUserConnection(e.getPlayer())
|
||||
.get(EntityTracker.class)
|
||||
.addBlockInteraction(new Position((long) b.getX(), (long) b.getY(), (long) b.getZ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
-25
@@ -3,14 +3,12 @@ package us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufOutputStream;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.CommandBlock;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
@@ -20,11 +18,10 @@ import org.spacehq.opennbt.tag.builtin.ByteTag;
|
||||
import org.spacehq.opennbt.tag.builtin.CompoundTag;
|
||||
import us.myles.ViaVersion.ViaVersionPlugin;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.ViaVersion;
|
||||
import us.myles.ViaVersion.api.ViaListener;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.minecraft.Position;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
|
||||
import us.myles.ViaVersion.util.ReflectionUtil;
|
||||
|
||||
@@ -32,10 +29,11 @@ import java.io.DataOutput;
|
||||
import java.io.DataOutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class CommandBlockListener implements Listener {
|
||||
public class CommandBlockListener extends ViaListener {
|
||||
|
||||
private final ViaVersionPlugin plugin;
|
||||
public CommandBlockListener(ViaVersionPlugin plugin) {
|
||||
super(plugin, Protocol1_9TO1_8.class);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void onJoin(PlayerJoinEvent e) {
|
||||
@@ -44,7 +42,9 @@ public class CommandBlockListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onRespawn(final PlayerRespawnEvent e) {
|
||||
Bukkit.getScheduler().runTaskLater(plugin, new Runnable() {
|
||||
if (!isOnPipe(e.getPlayer())) return;
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(getPlugin(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
sendOp(e.getPlayer());
|
||||
@@ -59,12 +59,7 @@ public class CommandBlockListener implements Listener {
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onInteract(PlayerInteractEvent e) {
|
||||
if (e.getAction() == Action.RIGHT_CLICK_BLOCK && plugin.isPorted(e.getPlayer()) && e.getPlayer().isOp()) {
|
||||
// Ensure that the player is on our pipe
|
||||
UserConnection userConnection = ((ViaVersionPlugin) ViaVersion.getInstance()).getConnection(e.getPlayer());
|
||||
if (userConnection == null) return;
|
||||
if (!userConnection.get(ProtocolInfo.class).getPipeline().contains(Protocol1_9TO1_8.class)) return;
|
||||
|
||||
if (e.getAction() == Action.RIGHT_CLICK_BLOCK && isOnPipe(e.getPlayer()) && e.getPlayer().isOp()) {
|
||||
try {
|
||||
sendCommandBlockPacket(e.getClickedBlock(), e.getPlayer());
|
||||
} catch (Exception ex) {
|
||||
@@ -74,16 +69,13 @@ public class CommandBlockListener implements Listener {
|
||||
}
|
||||
|
||||
private void sendOp(Player p) {
|
||||
if (p.isOp() && plugin.isPorted(p)) {
|
||||
// Ensure that the player is on our pipe
|
||||
UserConnection userConnection = ((ViaVersionPlugin) ViaVersion.getInstance()).getConnection(p);
|
||||
if (userConnection == null) return;
|
||||
if (!userConnection.get(ProtocolInfo.class).getPipeline().contains(Protocol1_9TO1_8.class)) return;
|
||||
|
||||
if (p.isOp() && isOnPipe(p)) {
|
||||
try {
|
||||
PacketWrapper wrapper = new PacketWrapper(0x1B, null, userConnection); // Entity status
|
||||
wrapper.write(Type.INT, p.getEntityId());
|
||||
PacketWrapper wrapper = new PacketWrapper(0x1B, null, getUserConnection(p)); // Entity status
|
||||
|
||||
wrapper.write(Type.INT, p.getEntityId()); // Entity ID
|
||||
wrapper.write(Type.BYTE, (byte) 26); //Hardcoded op permission level
|
||||
|
||||
wrapper.send(Protocol1_9TO1_8.class);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -99,9 +91,7 @@ public class CommandBlockListener implements Listener {
|
||||
Object tileEntityCommand = ReflectionUtil.get(cmd, "commandBlock", ReflectionUtil.nms("TileEntityCommand"));
|
||||
Object updatePacket = ReflectionUtil.invoke(tileEntityCommand, "getUpdatePacket");
|
||||
|
||||
UserConnection userConnection = ((ViaVersionPlugin) ViaVersion.getInstance()).getConnection(player);
|
||||
|
||||
PacketWrapper wrapper = generatePacket(updatePacket, userConnection);
|
||||
PacketWrapper wrapper = generatePacket(updatePacket, getUserConnection(player));
|
||||
wrapper.send(Protocol1_9TO1_8.class);
|
||||
}
|
||||
|
||||
|
||||
+12
-24
@@ -1,40 +1,28 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import us.myles.ViaVersion.ViaVersionPlugin;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.ViaListener;
|
||||
import us.myles.ViaVersion.api.ViaVersion;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class DeathListener implements Listener {
|
||||
private final ViaVersionPlugin plugin;
|
||||
public class DeathListener extends ViaListener {
|
||||
public DeathListener(ViaVersionPlugin plugin) {
|
||||
super(plugin, Protocol1_9TO1_8.class);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void onDeath(PlayerDeathEvent e) {
|
||||
Player p = e.getEntity();
|
||||
if (ViaVersion.getConfig().isShowNewDeathMessages() && checkGamerule(p.getWorld()) && e.getDeathMessage() != null && checkPipeline(p)) {
|
||||
if (isOnPipe(p) && ViaVersion.getConfig().isShowNewDeathMessages() && checkGamerule(p.getWorld()) && e.getDeathMessage() != null)
|
||||
sendPacket(p, e.getDeathMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean checkPipeline(Player p) {
|
||||
UserConnection userConnection = plugin.getConnection(p);
|
||||
return userConnection != null && userConnection.get(ProtocolInfo.class).getPipeline().contains(Protocol1_9TO1_8.class);
|
||||
}
|
||||
|
||||
private UserConnection getUserConnection(Player p) {
|
||||
return plugin.getConnection(p);
|
||||
}
|
||||
|
||||
public boolean checkGamerule(World w) {
|
||||
@@ -46,19 +34,19 @@ public class DeathListener implements Listener {
|
||||
}
|
||||
|
||||
private void sendPacket(final Player p, final String msg) {
|
||||
Bukkit.getScheduler().runTask(plugin, new Runnable() {
|
||||
Bukkit.getScheduler().runTask(getPlugin(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
PacketWrapper wrapper = new PacketWrapper(0x2C, null, getUserConnection(p));
|
||||
try {
|
||||
wrapper.write(Type.VAR_INT, 2);
|
||||
wrapper.write(Type.VAR_INT, p.getEntityId());
|
||||
wrapper.write(Type.INT, p.getEntityId());
|
||||
Protocol1_9TO1_8.FIX_JSON.write(wrapper, msg);
|
||||
wrapper.write(Type.VAR_INT, 2); // Event - Entity dead
|
||||
wrapper.write(Type.VAR_INT, p.getEntityId()); // Player ID
|
||||
wrapper.write(Type.INT, p.getEntityId()); // Entity ID
|
||||
Protocol1_9TO1_8.FIX_JSON.write(wrapper, msg); // Message
|
||||
|
||||
wrapper.send(Protocol1_9TO1_8.class);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
wrapper.clearInputBuffer();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
+13
-10
@@ -1,32 +1,35 @@
|
||||
package us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import us.myles.ViaVersion.ViaVersionPlugin;
|
||||
import us.myles.ViaVersion.api.ViaVersion;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.api.ViaListener;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
|
||||
|
||||
public class PaperPatch implements Listener {
|
||||
public class PaperPatch extends ViaListener {
|
||||
|
||||
public PaperPatch(ViaVersionPlugin plugin) {
|
||||
super(plugin, Protocol1_9TO1_8.class);
|
||||
}
|
||||
|
||||
/*
|
||||
This patch is applied when Paper is detected.
|
||||
I'm unsure of what causes this but essentially,
|
||||
placing blocks where your standing works?
|
||||
placing blocks where you're standing works?
|
||||
If there is a better fix then we'll replace this.
|
||||
*/
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlace(BlockPlaceEvent e) {
|
||||
if (ViaVersion.getInstance().isPorted(e.getPlayer())) {
|
||||
UserConnection userConnection = ((ViaVersionPlugin) ViaVersion.getInstance()).getConnection(e.getPlayer());
|
||||
if (userConnection == null) return;
|
||||
if (!userConnection.get(ProtocolInfo.class).getPipeline().contains(Protocol1_9TO1_8.class)) return;
|
||||
if (isOnPipe(e.getPlayer())) {
|
||||
Location diff = e.getPlayer().getLocation().subtract(e.getBlock().getLocation().add(0.5D, 0, 0.5D));
|
||||
Material block = e.getBlockPlaced().getType();
|
||||
if (!block.isSolid()) {
|
||||
return;
|
||||
}
|
||||
if (e.getPlayer().getLocation().getBlock().equals(e.getBlock())) {
|
||||
e.setCancelled(true);
|
||||
} else {
|
||||
|
||||
+6
-4
@@ -10,6 +10,8 @@ import us.myles.ViaVersion.api.remapper.PacketHandler;
|
||||
import us.myles.ViaVersion.api.remapper.PacketRemapper;
|
||||
import us.myles.ViaVersion.api.remapper.ValueTransformer;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.api.type.types.version.Types1_8;
|
||||
import us.myles.ViaVersion.api.type.types.version.Types1_9;
|
||||
import us.myles.ViaVersion.packets.State;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.ItemRewriter;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
|
||||
@@ -175,11 +177,11 @@ public class EntityPackets {
|
||||
@Override
|
||||
public void registerMap() {
|
||||
map(Type.VAR_INT); // 0 - Entity ID
|
||||
map(Protocol1_9TO1_8.METADATA_LIST); // 1 - Metadata List
|
||||
map(Types1_8.METADATA_LIST, Types1_9.METADATA_LIST); // 1 - Metadata List
|
||||
handler(new PacketHandler() {
|
||||
@Override
|
||||
public void handle(PacketWrapper wrapper) throws Exception {
|
||||
List<Metadata> metadataList = wrapper.get(Protocol1_9TO1_8.METADATA_LIST, 0);
|
||||
List<Metadata> metadataList = wrapper.get(Types1_9.METADATA_LIST, 0);
|
||||
int entityID = wrapper.get(Type.VAR_INT, 0);
|
||||
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
|
||||
if (tracker.getClientEntityTypes().containsKey(entityID)) {
|
||||
@@ -196,7 +198,7 @@ public class EntityPackets {
|
||||
handler(new PacketHandler() {
|
||||
@Override
|
||||
public void handle(PacketWrapper wrapper) throws Exception {
|
||||
List<Metadata> metadataList = wrapper.get(Protocol1_9TO1_8.METADATA_LIST, 0);
|
||||
List<Metadata> metadataList = wrapper.get(Types1_9.METADATA_LIST, 0);
|
||||
int entityID = wrapper.get(Type.VAR_INT, 0);
|
||||
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
|
||||
tracker.handleMetadata(entityID, metadataList);
|
||||
@@ -207,7 +209,7 @@ public class EntityPackets {
|
||||
handler(new PacketHandler() {
|
||||
@Override
|
||||
public void handle(PacketWrapper wrapper) throws Exception {
|
||||
List<Metadata> metadataList = wrapper.get(Protocol1_9TO1_8.METADATA_LIST, 0);
|
||||
List<Metadata> metadataList = wrapper.get(Types1_9.METADATA_LIST, 0);
|
||||
if (metadataList.size() == 0) {
|
||||
wrapper.cancel();
|
||||
}
|
||||
|
||||
+9
-7
@@ -11,6 +11,8 @@ import us.myles.ViaVersion.api.remapper.PacketRemapper;
|
||||
import us.myles.ViaVersion.api.remapper.ValueCreator;
|
||||
import us.myles.ViaVersion.api.remapper.ValueTransformer;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.api.type.types.version.Types1_8;
|
||||
import us.myles.ViaVersion.api.type.types.version.Types1_9;
|
||||
import us.myles.ViaVersion.packets.State;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.ItemRewriter;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
|
||||
@@ -107,7 +109,7 @@ public class SpawnPackets {
|
||||
// TEMP FIX FOR POTIONS UNTIL WE FIGURE OUT HOW TO TRANSFORM SENT PACKETS
|
||||
Metadata potion = new Metadata(5, NewType.Slot.getTypeID(), Type.ITEM, item);
|
||||
meta.add(potion);
|
||||
wrapper.write(Protocol1_9TO1_8.METADATA_LIST, meta);
|
||||
wrapper.write(Types1_9.METADATA_LIST, meta);
|
||||
}
|
||||
});
|
||||
metaPacket.send(Protocol1_9TO1_8.class);
|
||||
@@ -206,11 +208,11 @@ public class SpawnPackets {
|
||||
map(Type.SHORT); // 10 - Velocity Y
|
||||
map(Type.SHORT); // 11 - Velocity Z
|
||||
|
||||
map(Protocol1_9TO1_8.METADATA_LIST);
|
||||
map(Types1_8.METADATA_LIST, Types1_9.METADATA_LIST);
|
||||
handler(new PacketHandler() {
|
||||
@Override
|
||||
public void handle(PacketWrapper wrapper) throws Exception {
|
||||
List<Metadata> metadataList = wrapper.get(Protocol1_9TO1_8.METADATA_LIST, 0);
|
||||
List<Metadata> metadataList = wrapper.get(Types1_9.METADATA_LIST, 0);
|
||||
int entityID = wrapper.get(Type.VAR_INT, 0);
|
||||
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
|
||||
if (tracker.getClientEntityTypes().containsKey(entityID)) {
|
||||
@@ -225,7 +227,7 @@ public class SpawnPackets {
|
||||
handler(new PacketHandler() {
|
||||
@Override
|
||||
public void handle(PacketWrapper wrapper) throws Exception {
|
||||
List<Metadata> metadataList = wrapper.get(Protocol1_9TO1_8.METADATA_LIST, 0);
|
||||
List<Metadata> metadataList = wrapper.get(Types1_9.METADATA_LIST, 0);
|
||||
int entityID = wrapper.get(Type.VAR_INT, 0);
|
||||
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
|
||||
tracker.handleMetadata(entityID, metadataList);
|
||||
@@ -311,12 +313,12 @@ public class SpawnPackets {
|
||||
}
|
||||
});
|
||||
|
||||
map(Protocol1_9TO1_8.METADATA_LIST);
|
||||
map(Types1_8.METADATA_LIST, Types1_9.METADATA_LIST);
|
||||
|
||||
handler(new PacketHandler() {
|
||||
@Override
|
||||
public void handle(PacketWrapper wrapper) throws Exception {
|
||||
List<Metadata> metadataList = wrapper.get(Protocol1_9TO1_8.METADATA_LIST, 0);
|
||||
List<Metadata> metadataList = wrapper.get(Types1_9.METADATA_LIST, 0);
|
||||
int entityID = wrapper.get(Type.VAR_INT, 0);
|
||||
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
|
||||
if (tracker.getClientEntityTypes().containsKey(entityID)) {
|
||||
@@ -332,7 +334,7 @@ public class SpawnPackets {
|
||||
handler(new PacketHandler() {
|
||||
@Override
|
||||
public void handle(PacketWrapper wrapper) throws Exception {
|
||||
List<Metadata> metadataList = wrapper.get(Protocol1_9TO1_8.METADATA_LIST, 0);
|
||||
List<Metadata> metadataList = wrapper.get(Types1_9.METADATA_LIST, 0);
|
||||
int entityID = wrapper.get(Type.VAR_INT, 0);
|
||||
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
|
||||
tracker.handleMetadata(entityID, metadataList);
|
||||
|
||||
+4
-4
@@ -35,7 +35,7 @@ public enum SoundEffect {
|
||||
MOB_HORSE_ZOMBIE_DEATH("mob.horse.zombie.death", "entity.zombie_horse.death", SoundCategory.NEUTRAL),
|
||||
MOB_SILVERFISH_KILL("mob.silverfish.kill", "entity.endermite.death", SoundCategory.HOSTILE),
|
||||
MOB_WOLF_PANTING("mob.wolf.panting", "entity.wolf.pant", SoundCategory.NEUTRAL),
|
||||
NOTE_BASS("note.bass", "null", SoundCategory.RECORD),
|
||||
NOTE_BASS("note.bass", "block.note.bass", SoundCategory.RECORD),
|
||||
DIG_STONE("dig.stone", "block.glass.place", SoundCategory.BLOCK),
|
||||
MOB_ENDERMEN_STARE("mob.endermen.stare", "entity.endermen.stare", SoundCategory.HOSTILE),
|
||||
GAME_PLAYER_SWIM_SPLASH("game.player.swim.splash", "entity.generic.splash", SoundCategory.BLOCK),
|
||||
@@ -79,7 +79,7 @@ public enum SoundEffect {
|
||||
CREEPER_PRIMED("creeper.primed", "entity.creeper.primed", SoundCategory.HOSTILE),
|
||||
DIG_SAND("dig.sand", "block.sand.break", SoundCategory.BLOCK),
|
||||
MOB_CHICKEN_SAY("mob.chicken.say", "entity.chicken.ambient", SoundCategory.NEUTRAL),
|
||||
RANDOM_DOOR_CLOSE("random.door_close", "null", SoundCategory.BLOCK),
|
||||
RANDOM_DOOR_CLOSE("random.door_close", "block.wooden_door.close", SoundCategory.BLOCK),
|
||||
MOB_GUARDIAN_ELDER_DEATH("mob.guardian.elder.death", "entity.elder_guardian.death", SoundCategory.HOSTILE),
|
||||
FIREWORKS_TWINKLE("fireworks.twinkle", "entity.firework.twinkle", SoundCategory.AMBIENT),
|
||||
MOB_HORSE_SKELETON_DEATH("mob.horse.skeleton.death", "entity.skeleton_horse.death", SoundCategory.NEUTRAL),
|
||||
@@ -177,7 +177,7 @@ public enum SoundEffect {
|
||||
GAME_TNT_PRIMED("game.tnt.primed", "entity.creeper.primed", SoundCategory.BLOCK),
|
||||
MOB_SHEEP_STEP("mob.sheep.step", "entity.sheep.step", SoundCategory.NEUTRAL),
|
||||
MOB_ZOMBIE_DEATH("mob.zombie.death", "entity.zombie.death", SoundCategory.HOSTILE),
|
||||
RANDOM_DOOR_OPEN("random.door_open", "null", SoundCategory.BLOCK),
|
||||
RANDOM_DOOR_OPEN("random.door_open", "block.wooden_door.open", SoundCategory.BLOCK),
|
||||
MOB_ENDERMEN_PORTAL("mob.endermen.portal", "entity.endermen.teleport", SoundCategory.HOSTILE),
|
||||
MOB_HORSE_ANGRY("mob.horse.angry", "entity.horse.angry", SoundCategory.NEUTRAL),
|
||||
MOB_WOLF_GROWL("mob.wolf.growl", "entity.wolf.growl", SoundCategory.NEUTRAL),
|
||||
@@ -242,7 +242,7 @@ public enum SoundEffect {
|
||||
MOB_RABBIT_IDLE("mob.rabbit.idle", "entity.rabbit.ambient", SoundCategory.NEUTRAL),
|
||||
MUSIC_GAME_END("music.game.end", "music.end", SoundCategory.MUSIC),
|
||||
MUSIC_GAME("music.game", "music.game", SoundCategory.MUSIC),
|
||||
MOB_GUARDIAN_IDLE("mob.guardian.idle", "null", SoundCategory.HOSTILE),
|
||||
MOB_GUARDIAN_IDLE("mob.guardian.idle", "entity.elder_guardian.ambient", SoundCategory.HOSTILE),
|
||||
RECORDS_WARD("records.ward", "record.ward", SoundCategory.RECORD),
|
||||
RECORDS_13("records.13", "record.13", SoundCategory.RECORD),
|
||||
MOB_RABBIT_HOP("mob.rabbit.hop", "entity.rabbit.jump", SoundCategory.NEUTRAL),
|
||||
|
||||
+7
-2
@@ -3,7 +3,10 @@ package us.myles.ViaVersion.protocols.protocol1_9to1_8.storage;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldType;
|
||||
import us.myles.ViaVersion.api.ViaVersion;
|
||||
import us.myles.ViaVersion.api.data.StoredObject;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
@@ -26,8 +29,10 @@ public class ClientChunks extends StoredObject {
|
||||
try {
|
||||
mapChunkBulkRef = new ReflectionUtil.ClassReflection(ReflectionUtil.nms("PacketPlayOutMapChunkBulk"));
|
||||
mapChunkRef = new ReflectionUtil.ClassReflection(ReflectionUtil.nms("PacketPlayOutMapChunk"));
|
||||
obfuscateRef = Class.forName("org.spigotmc.AntiXray").getMethod("obfuscate", int.class, int.class, int.class, byte[].class, ReflectionUtil.nms("World"));
|
||||
worldRef = ReflectionUtil.nms("World");
|
||||
if (ViaVersion.getInstance().isSpigot()) {
|
||||
obfuscateRef = Class.forName("org.spigotmc.AntiXray").getMethod("obfuscate", int.class, int.class, int.class, byte[].class, ReflectionUtil.nms("World"));
|
||||
worldRef = ReflectionUtil.nms("World");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Failed to initialise chunks reflection", e);
|
||||
}
|
||||
|
||||
+2
-1
@@ -19,6 +19,7 @@ import us.myles.ViaVersion.api.minecraft.Position;
|
||||
import us.myles.ViaVersion.api.minecraft.item.Item;
|
||||
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.api.type.types.version.Types1_9;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.chat.GameMode;
|
||||
@@ -274,7 +275,7 @@ public class EntityTracker extends StoredObject {
|
||||
if (metadataBuffer.containsKey(entityID)) {
|
||||
PacketWrapper wrapper = new PacketWrapper(0x39, null, getUser());
|
||||
wrapper.write(Type.VAR_INT, entityID);
|
||||
wrapper.write(Protocol1_9TO1_8.METADATA_LIST, metadataBuffer.get(entityID));
|
||||
wrapper.write(Types1_9.METADATA_LIST, metadataBuffer.get(entityID));
|
||||
MetadataRewriter.transform(getClientEntityTypes().get(entityID), metadataBuffer.get(entityID));
|
||||
handleMetadata(entityID, metadataBuffer.get(entityID));
|
||||
if (metadataBuffer.get(entityID).size() > 0) {
|
||||
|
||||
@@ -3,10 +3,13 @@ package us.myles.ViaVersion.protocols.protocol1_9to1_8.types;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import org.bukkit.Bukkit;
|
||||
import us.myles.ViaVersion.api.ViaVersion;
|
||||
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
|
||||
import us.myles.ViaVersion.api.type.PartialType;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.api.type.types.minecraft.BaseChunkType;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.protocols.protocol1_10to1_9_3.Protocol1_10To1_9_3_4;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.chunks.Chunk1_9to1_8;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.chunks.ChunkSection1_9to1_8;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks;
|
||||
@@ -46,6 +49,9 @@ public class ChunkType extends PartialType<Chunk, ClientChunks> {
|
||||
|
||||
@Override
|
||||
public Chunk read(ByteBuf input, ClientChunks param) throws Exception {
|
||||
boolean replacePistons = param.getUser().get(ProtocolInfo.class).getPipeline().contains(Protocol1_10To1_9_3_4.class) && ViaVersion.getConfig().isReplacePistons();
|
||||
int replacementId = ViaVersion.getConfig().getPistonReplacementId();
|
||||
|
||||
int chunkX = input.readInt();
|
||||
int chunkZ = input.readInt();
|
||||
long chunkHash = toLong(chunkX, chunkZ);
|
||||
@@ -93,7 +99,8 @@ public class ChunkType extends PartialType<Chunk, ClientChunks> {
|
||||
int mask = blockBuf.get();
|
||||
int type = mask >> 4;
|
||||
int data = mask & 0xF;
|
||||
|
||||
if (replacePistons && type == 36)
|
||||
type = replacementId;
|
||||
section.setBlock(j, type, data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,8 +21,9 @@ import java.util.UUID;
|
||||
public class UpdateUtil {
|
||||
|
||||
public final static String PREFIX = ChatColor.GREEN + "" + ChatColor.BOLD + "[ViaVersion] " + ChatColor.GREEN;
|
||||
private final static String URL = "http://api.spiget.org/v1/resources/";
|
||||
private final static String URL = "http://api.spiget.org/v2/resources/";
|
||||
private final static int PLUGIN = 19254;
|
||||
private final static String LATEST_VERSION = "/versions/latest";
|
||||
|
||||
public static void sendUpdateMessage(final UUID uuid, final Plugin plugin) {
|
||||
new BukkitRunnable() {
|
||||
@@ -81,20 +82,24 @@ public class UpdateUtil {
|
||||
try {
|
||||
current = new Version(ViaVersion.getInstance().getVersion());
|
||||
} catch (IllegalArgumentException e) {
|
||||
return "You are using a debug/custom version, consider updating.";
|
||||
return "You are using a custom version, consider updating.";
|
||||
}
|
||||
Version newest = new Version(newestString);
|
||||
if (current.compareTo(newest) < 0)
|
||||
return "There is a newer version available: " + newest.toString();
|
||||
return "There is a newer version available: " + newest.toString() + ", you're on: " + current.toString();
|
||||
else if (console && current.compareTo(newest) != 0) {
|
||||
return "You are running a newer version than is released!";
|
||||
if (current.getTag().toLowerCase().startsWith("dev") || current.getTag().toLowerCase().startsWith("snapshot")) {
|
||||
return "You are running a development version, please report any bugs to GitHub.";
|
||||
} else {
|
||||
return "You are running a newer version than is released!";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getNewestVersion() {
|
||||
try {
|
||||
URL url = new URL(URL + PLUGIN + "?" + System.currentTimeMillis());
|
||||
URL url = new URL(URL + PLUGIN + LATEST_VERSION + "?" + System.currentTimeMillis());
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setUseCaches(true);
|
||||
connection.addRequestProperty("User-Agent", "ViaVersion " + ViaVersion.getInstance().getVersion());
|
||||
@@ -114,7 +119,7 @@ public class UpdateUtil {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
return (String) statistics.get("version");
|
||||
return (String) statistics.get("name");
|
||||
} catch (MalformedURLException e) {
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -2,21 +2,26 @@ package us.myles.ViaVersion.update;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Version implements Comparable<Version> {
|
||||
private int[] parts;
|
||||
private static Pattern semVer = Pattern.compile("(?<a>0|[1-9]\\d*)\\.(?<b>0|[1-9]\\d*)(?:\\.(?<c>0|[1-9]\\d*))?(?:-(?<tag>[A-z0-9.-]*))?");
|
||||
private int[] parts = new int[3];
|
||||
private String tag;
|
||||
|
||||
public Version(String value) {
|
||||
if (value == null)
|
||||
throw new IllegalArgumentException("Version can not be null");
|
||||
|
||||
if (!value.matches("^[0-9]+(\\.[0-9]+)*$"))
|
||||
Matcher matcher = semVer.matcher(value);
|
||||
if (!matcher.matches())
|
||||
throw new IllegalArgumentException("Invalid version format");
|
||||
parts[0] = Integer.parseInt(matcher.group("a"));
|
||||
parts[1] = Integer.parseInt(matcher.group("b"));
|
||||
parts[2] = matcher.group("c") == null ? 0 : Integer.parseInt(matcher.group("c"));
|
||||
|
||||
String[] split = value.split("\\.");
|
||||
parts = new int[split.length];
|
||||
|
||||
for (int i = 0; i < split.length; i += 1)
|
||||
parts[i] = Integer.parseInt(split[i]);
|
||||
tag = matcher.group("tag") == null ? "" : matcher.group("tag");
|
||||
}
|
||||
|
||||
public static int compare(Version verA, Version verB) {
|
||||
@@ -33,6 +38,12 @@ public class Version implements Comparable<Version> {
|
||||
if (partA > partB) return 1;
|
||||
}
|
||||
|
||||
// Simple tag check
|
||||
if (verA.tag.length() == 0 && verB.tag.length() > 0)
|
||||
return 1;
|
||||
if (verA.tag.length() > 0 && verB.tag.length() == 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -47,7 +58,7 @@ public class Version implements Comparable<Version> {
|
||||
for (int i = 0; i < parts.length; i += 1)
|
||||
split[i] = String.valueOf(parts[i]);
|
||||
|
||||
return StringUtils.join(split, ".");
|
||||
return StringUtils.join(split, ".") + (tag.length() != 0 ? "-" + tag : "");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -59,4 +70,8 @@ public class Version implements Comparable<Version> {
|
||||
public boolean equals(Object that) {
|
||||
return that instanceof Version && equals(this, (Version) that);
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
package us.myles.ViaVersion.util;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Created by wea_ondara licensed under MIT
|
||||
* Same license as in LICENSE
|
||||
*
|
||||
* Taken from:
|
||||
* https://github.com/weaondara/BungeePerms/blob/master/src/main/java/net/alpenblock/bungeeperms/util/ConcurrentList.java
|
||||
* @param <E> List Type
|
||||
*/
|
||||
public class ConcurrentList<E> extends ArrayList<E> {
|
||||
|
||||
private final Object lock = new Object();
|
||||
|
||||
@Override
|
||||
public boolean add(E e) {
|
||||
synchronized (lock) {
|
||||
return super.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, E element) {
|
||||
synchronized (lock) {
|
||||
super.add(index, element);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends E> c) {
|
||||
synchronized (lock) {
|
||||
return super.addAll(c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(int index, Collection<? extends E> c) {
|
||||
synchronized (lock) {
|
||||
return super.addAll(index, c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
synchronized (lock) {
|
||||
super.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public Object clone() {
|
||||
synchronized (lock) {
|
||||
ConcurrentList<E> clist = (ConcurrentList<E>) super.clone();
|
||||
clist.modCount = 0;
|
||||
Field f = ArrayList.class.getDeclaredField("elementData");
|
||||
f.setAccessible(true);
|
||||
f.set(clist, Arrays.copyOf((Object[]) f.get(this), this.size()));
|
||||
|
||||
return clist;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
synchronized (lock) {
|
||||
return super.contains(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ensureCapacity(int minCapacity) {
|
||||
synchronized (lock) {
|
||||
super.ensureCapacity(minCapacity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public E get(int index) {
|
||||
synchronized (lock) {
|
||||
return super.get(index);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object o) {
|
||||
synchronized (lock) {
|
||||
return super.indexOf(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object o) {
|
||||
synchronized (lock) {
|
||||
return super.lastIndexOf(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public E remove(int index) {
|
||||
synchronized (lock) {
|
||||
return super.remove(index);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
synchronized (lock) {
|
||||
return super.remove(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
synchronized (lock) {
|
||||
return super.removeAll(c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
synchronized (lock) {
|
||||
return super.retainAll(c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public E set(int index, E element) {
|
||||
synchronized (lock) {
|
||||
return super.set(index, element);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<E> subList(int fromIndex, int toIndex) {
|
||||
synchronized (lock) {
|
||||
return super.subList(fromIndex, toIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
synchronized (lock) {
|
||||
return super.toArray();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] toArray(T[] a) {
|
||||
synchronized (lock) {
|
||||
return super.toArray(a);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trimToSize() {
|
||||
synchronized (lock) {
|
||||
super.trimToSize();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator<E> listIterator() {
|
||||
return new ListItr(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
return new Itr();
|
||||
}
|
||||
|
||||
private class Itr implements Iterator<E> {
|
||||
|
||||
protected int cursor;
|
||||
protected int lastRet;
|
||||
final ConcurrentList l;
|
||||
|
||||
public Itr() {
|
||||
cursor = 0;
|
||||
lastRet = -1;
|
||||
l = (ConcurrentList) ConcurrentList.this.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return cursor < l.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E next() {
|
||||
int i = cursor;
|
||||
if (i >= l.size()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
cursor = i + 1;
|
||||
return (E) l.get(lastRet = i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
if (lastRet < 0) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
l.remove(lastRet);
|
||||
ConcurrentList.this.remove(lastRet);
|
||||
cursor = lastRet;
|
||||
lastRet = -1;
|
||||
}
|
||||
}
|
||||
|
||||
public class ListItr extends Itr implements ListIterator<E> {
|
||||
|
||||
ListItr(int index) {
|
||||
super();
|
||||
cursor = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPrevious() {
|
||||
return cursor > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextIndex() {
|
||||
return cursor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int previousIndex() {
|
||||
return cursor - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E previous() {
|
||||
int i = cursor - 1;
|
||||
if (i < 0) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
cursor = i;
|
||||
return (E) l.get(lastRet = i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(E e) {
|
||||
if (lastRet < 0) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
l.set(lastRet, e);
|
||||
ConcurrentList.this.set(lastRet, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(E e) {
|
||||
int i = cursor;
|
||||
l.add(i, e);
|
||||
ConcurrentList.this.add(i, e);
|
||||
cursor = i + 1;
|
||||
lastRet = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,9 @@
|
||||
package us.myles.ViaVersion.util;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.*;
|
||||
|
||||
public abstract class ListWrapper implements List {
|
||||
public final Object lock = new Object();
|
||||
private final List list;
|
||||
|
||||
public ListWrapper(List inputList) {
|
||||
@@ -20,123 +18,169 @@ public abstract class ListWrapper implements List {
|
||||
|
||||
@Override
|
||||
public synchronized int size() {
|
||||
return this.list.size();
|
||||
synchronized (lock) {
|
||||
return this.list.size();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isEmpty() {
|
||||
return this.list.isEmpty();
|
||||
synchronized (lock) {
|
||||
return this.list.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean contains(Object o) {
|
||||
return this.list.contains(o);
|
||||
synchronized (lock) {
|
||||
return this.list.contains(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Iterator iterator() {
|
||||
return this.list.iterator();
|
||||
synchronized (lock) {
|
||||
return listIterator();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Object[] toArray() {
|
||||
return this.list.toArray();
|
||||
synchronized (lock) {
|
||||
return this.list.toArray();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean add(Object o) {
|
||||
handleAdd(o);
|
||||
return this.list.add(o);
|
||||
synchronized (lock) {
|
||||
handleAdd(o);
|
||||
return this.list.add(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean remove(Object o) {
|
||||
return this.list.remove(o);
|
||||
synchronized (lock) {
|
||||
return this.list.remove(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean addAll(Collection c) {
|
||||
for (Object o : c) {
|
||||
handleAdd(o);
|
||||
synchronized (lock) {
|
||||
for (Object o : c) {
|
||||
handleAdd(o);
|
||||
}
|
||||
return this.list.addAll(c);
|
||||
}
|
||||
return this.list.addAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean addAll(int index, Collection c) {
|
||||
for (Object o : c) {
|
||||
handleAdd(o);
|
||||
synchronized (lock) {
|
||||
for (Object o : c) {
|
||||
handleAdd(o);
|
||||
}
|
||||
return this.list.addAll(index, c);
|
||||
}
|
||||
return this.list.addAll(index, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void clear() {
|
||||
this.list.clear();
|
||||
synchronized (lock) {
|
||||
this.list.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Object get(int index) {
|
||||
return this.list.get(index);
|
||||
synchronized (lock) {
|
||||
return this.list.get(index);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Object set(int index, Object element) {
|
||||
return this.list.set(index, element);
|
||||
synchronized (lock) {
|
||||
return this.list.set(index, element);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void add(int index, Object element) {
|
||||
this.list.add(index, element);
|
||||
synchronized (lock) {
|
||||
this.list.add(index, element);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Object remove(int index) {
|
||||
return this.list.remove(index);
|
||||
synchronized (lock) {
|
||||
return this.list.remove(index);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int indexOf(Object o) {
|
||||
return this.list.indexOf(o);
|
||||
synchronized (lock) {
|
||||
return this.list.indexOf(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int lastIndexOf(Object o) {
|
||||
return this.list.lastIndexOf(o);
|
||||
synchronized (lock) {
|
||||
return this.list.lastIndexOf(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized ListIterator listIterator() {
|
||||
return this.list.listIterator();
|
||||
synchronized (lock) {
|
||||
return this.list.listIterator();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized ListIterator listIterator(int index) {
|
||||
return this.list.listIterator(index);
|
||||
synchronized (lock) {
|
||||
return this.list.listIterator(index);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List subList(int fromIndex, int toIndex) {
|
||||
return this.list.subList(fromIndex, toIndex);
|
||||
synchronized (lock) {
|
||||
return this.list.subList(fromIndex, toIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean retainAll(Collection c) {
|
||||
return this.list.retainAll(c);
|
||||
synchronized (lock) {
|
||||
return this.list.retainAll(c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean removeAll(Collection c) {
|
||||
return this.list.removeAll(c);
|
||||
synchronized (lock) {
|
||||
return this.list.removeAll(c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean containsAll(Collection c) {
|
||||
return this.list.containsAll(c);
|
||||
synchronized (lock) {
|
||||
return this.list.containsAll(c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Object[] toArray(Object[] a) {
|
||||
return this.list.toArray(a);
|
||||
synchronized (lock) {
|
||||
return this.list.toArray(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,28 +12,38 @@
|
||||
checkforupdates: true
|
||||
# Send the supported versions with the Status (Ping) response packet
|
||||
send-supported-versions: false
|
||||
# Block specific Minecraft protocols that ViaVersion allows
|
||||
# List of all Minecraft protocol versions: http://wiki.vg/Protocol_version_numbers
|
||||
block-protocols: []
|
||||
# Change the blocked disconnect message
|
||||
block-disconnect-msg: "You are using an unsupported Minecraft version!"
|
||||
# If you use ProtocolLib, we can't reload without kicking the players.
|
||||
# (We don't suggest using reload either, use a plugin manager)
|
||||
# You can customise the message we kick people with if you use ProtocolLib here.
|
||||
reload-disconnect-msg: "Server reload, please rejoin!"
|
||||
#
|
||||
#----------------------------------------------------------#
|
||||
# GLOBAL PACKET LIMITER #
|
||||
#----------------------------------------------------------#
|
||||
#
|
||||
# Anti-Cheat, Packets Per Second (PPS) limiter
|
||||
#
|
||||
# Packets Per Second (PPS) limiter (Use -1 on max-pps and tracking-period to disable)
|
||||
# Clients by default send around 20-90 packets per second.
|
||||
|
||||
#
|
||||
# What is the maximum per second a client can send (Use %pps to display their pps)
|
||||
# Use -1 to disable.
|
||||
max-pps: 600
|
||||
max-pps-kick-msg: "You are sending too many packets!"
|
||||
|
||||
#
|
||||
# We can also kick them if over a period they send over a threshold a certain amount of times.
|
||||
|
||||
#
|
||||
# Period to track (in seconds)
|
||||
# Use -1 to disable.
|
||||
tracking-period: 6
|
||||
# How many packets per second counts as a warning
|
||||
tracking-warning-pps: 120
|
||||
# How many warnings over the interval can we have
|
||||
# This can never be higher than "tracking-interval"
|
||||
# This can never be higher than "tracking-period"
|
||||
tracking-max-warnings: 4
|
||||
tracking-max-kick-msg: "You are sending too many packets, :("
|
||||
#
|
||||
@@ -70,4 +80,10 @@ use-new-deathmessages: false
|
||||
# Should we cache our items, this will prevent server from being lagged out, however the cost is a constant task caching items
|
||||
item-cache: true
|
||||
# Patch the Anti xray to work on 1.9 & 1.10 (If your server is 1.8) This can cost more performance, so disable it if you don't use it.
|
||||
anti-xray-patch: true
|
||||
anti-xray-patch: true
|
||||
# Should we replace extended pistons to fix 1.10.1 (Only on chunk load)
|
||||
replace-pistons: false
|
||||
# What id should we replace with, default is air. (careful of players getting stuck standing on them)
|
||||
replacement-piston-id: 0
|
||||
# Force the string -> json transform
|
||||
force-json-transform: false
|
||||
@@ -3,8 +3,8 @@ main: us.myles.ViaVersion.ViaVersionPlugin
|
||||
author: _MylesC
|
||||
version: ${project.version}
|
||||
load: postworld
|
||||
loadbefore: [ProtocolLib, ProxyPipe, SpigotLib, PacketListenerApi, SkinRestorer]
|
||||
softdepend: [ProtocolSupport]
|
||||
loadbefore: [ProtocolLib, ProxyPipe, SpigotLib, SkinRestorer]
|
||||
softdepend: [ProtocolSupport, PacketListenerApi]
|
||||
commands:
|
||||
viaversion:
|
||||
description: Shows ViaVersion Version and more.
|
||||
|
||||
Reference in new issue
Block a user