diff --git a/bukkit/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java b/bukkit/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java index fe9d09438..a8fa210fc 100644 --- a/bukkit/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java +++ b/bukkit/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java @@ -174,6 +174,11 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform { } } + @Override + public TaskId runSync(Runnable runnable, Long ticks) { + return new BukkitTaskId(getServer().getScheduler().runTaskLater(this, runnable, ticks).getTaskId()); + } + @Override public TaskId runRepeatingSync(Runnable runnable, Long ticks) { return new BukkitTaskId(getServer().getScheduler().runTaskTimer(this, runnable, ticks, 0).getTaskId()); diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitConfigAPI.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitConfigAPI.java index b4ccbc593..b95e0b5c1 100644 --- a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitConfigAPI.java +++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitConfigAPI.java @@ -164,6 +164,11 @@ public class BukkitConfigAPI extends Config implements ViaVersionConfig { public boolean is1_12NBTArrayFix() { return getBoolean("chat-nbt-fix", true); } + + @Override + public boolean is1_12QuickMoveActionFix() { + return getBoolean("quick-move-action-fix", true); + } @Override public List getBlockedProtocols() { diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaLoader.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaLoader.java index 49bf0aa91..a6525ae32 100644 --- a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaLoader.java +++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaLoader.java @@ -1,10 +1,12 @@ package us.myles.ViaVersion.bukkit.platform; import lombok.AllArgsConstructor; + import org.bukkit.Bukkit; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerQuitEvent; + import us.myles.ViaVersion.ViaVersionPlugin; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.data.UserConnection; @@ -12,9 +14,11 @@ import us.myles.ViaVersion.api.minecraft.item.Item; import us.myles.ViaVersion.api.platform.ViaPlatformLoader; import us.myles.ViaVersion.bukkit.listeners.UpdateListener; import us.myles.ViaVersion.bukkit.listeners.protocol1_9to1_8.*; +import us.myles.ViaVersion.bukkit.providers.BukkitInventoryQuickMoveProvider; import us.myles.ViaVersion.bukkit.providers.BukkitViaBulkChunkTranslator; import us.myles.ViaVersion.bukkit.providers.BukkitViaMovementTransmitter; import us.myles.ViaVersion.protocols.base.ProtocolInfo; +import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.providers.InventoryQuickMoveProvider; import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider; import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.HandItemProvider; import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider; @@ -60,6 +64,9 @@ public class BukkitViaLoader implements ViaPlatformLoader { /* Providers */ Via.getManager().getProviders().use(BulkChunkTranslatorProvider.class, new BukkitViaBulkChunkTranslator()); Via.getManager().getProviders().use(MovementTransmitterProvider.class, new BukkitViaMovementTransmitter()); + if (plugin.getConf().is1_12QuickMoveActionFix()) { + Via.getManager().getProviders().use(InventoryQuickMoveProvider.class, new BukkitInventoryQuickMoveProvider()); + } Via.getManager().getProviders().use(HandItemProvider.class, new HandItemProvider() { @Override public Item getHandItem(final UserConnection info) { diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/providers/BukkitInventoryQuickMoveProvider.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/providers/BukkitInventoryQuickMoveProvider.java new file mode 100644 index 000000000..df0c48e62 --- /dev/null +++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/providers/BukkitInventoryQuickMoveProvider.java @@ -0,0 +1,162 @@ +package us.myles.ViaVersion.bukkit.providers; + +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; +import us.myles.ViaVersion.api.Via; +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.bukkit.tasks.protocol1_12to1_11_1.BukkitInventoryUpdateTask; +import us.myles.ViaVersion.bukkit.util.NMSUtil; +import us.myles.ViaVersion.protocols.base.ProtocolInfo; +import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.providers.InventoryQuickMoveProvider; +import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.storage.ItemTransaction; +import us.myles.ViaVersion.util.ReflectionUtil; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +public class BukkitInventoryQuickMoveProvider extends InventoryQuickMoveProvider { + + private static Map updateTasks = new ConcurrentHashMap(); + private boolean supported; + // packet class + private Class windowClickPacketClass; + private Object clickTypeEnum; + // Use for nms + private Method nmsItemMethod; + private Method craftPlayerHandle; + private Field connection; + private Method packetMethod; + + public BukkitInventoryQuickMoveProvider() { + this.supported = isSupported(); + setupReflection(); + } + + @Override + public boolean registerQuickMove(short windowId, short slotId, short actionId, UserConnection userConnection) { + if (!supported) { + return false; + } + ProtocolInfo info = userConnection.get(ProtocolInfo.class); + UUID uuid = info.getUuid(); + BukkitInventoryUpdateTask updateTask = updateTasks.get(uuid); + final boolean registered = updateTask != null; + if (!registered) { + updateTask = new BukkitInventoryUpdateTask(this, uuid); + updateTasks.put(uuid, updateTask); + } + // http://wiki.vg/index.php?title=Protocol&oldid=13223#Click_Window + updateTask.addItem(windowId, slotId, actionId); + if (!registered) { + Via.getPlatform().runSync(updateTask, 5L); + } + return true; + } + + public Object buildWindowClickPacket(Player p, ItemTransaction storage) { + if (!supported) { + return null; + } + InventoryView inv = p.getOpenInventory(); + short slotId = storage.getSlotId(); + if (slotId < 0) { // clicked out of inv slot + return null; + } + if (slotId > inv.countSlots()) { + return null; // wrong container open? + } + ItemStack itemstack = inv.getItem(slotId); + if (itemstack == null) { + return null; + } + Object packet = null; + try { + packet = windowClickPacketClass.newInstance(); + Object nmsItem = nmsItemMethod.invoke(null, itemstack); + ReflectionUtil.set(packet, "a", (int) storage.getWindowId()); + ReflectionUtil.set(packet, "slot", (int) slotId); + ReflectionUtil.set(packet, "button", 0); // shift + left mouse click + ReflectionUtil.set(packet, "d", storage.getActionId()); + ReflectionUtil.set(packet, "item", nmsItem); + int protocolId = ProtocolRegistry.SERVER_PROTOCOL; + if (protocolId == ProtocolVersion.v1_8.getId()) { + ReflectionUtil.set(packet, "shift", 1); + } else if (protocolId >= ProtocolVersion.v1_9.getId()) { // 1.9+ + ReflectionUtil.set(packet, "shift", clickTypeEnum); + } + } catch (Exception e) { + e.printStackTrace(); + } + return packet; + } + + public boolean sendPlayer(Player p, Object packet) { + if (packet == null) { + return false; + } + try { + Object entityPlayer = craftPlayerHandle.invoke(p); + Object playerConnection = connection.get(entityPlayer); + // send + packetMethod.invoke(playerConnection, packet); + } catch (IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + return false; + } + return true; + } + + public void onTaskExecuted(UUID uuid) { + updateTasks.remove(uuid); + } + + private void setupReflection() { + if (!supported) { + return; + } + try { + this.windowClickPacketClass = NMSUtil.nms("PacketPlayInWindowClick"); + int protocolId = ProtocolRegistry.SERVER_PROTOCOL; + if (protocolId >= ProtocolVersion.v1_9.getId()) { + Class eclassz = NMSUtil.nms("InventoryClickType"); + Object[] constants = eclassz.getEnumConstants(); + this.clickTypeEnum = constants[1]; // QUICK_MOVE + } + Class craftItemStack = NMSUtil.obc("inventory.CraftItemStack"); + this.nmsItemMethod = craftItemStack.getDeclaredMethod("asNMSCopy", ItemStack.class); + } catch (Exception e) { + throw new RuntimeException("Couldn't find required inventory classes", e); + } + try { + this.craftPlayerHandle = NMSUtil.obc("entity.CraftPlayer").getDeclaredMethod("getHandle"); + } catch (NoSuchMethodException | ClassNotFoundException e) { + throw new RuntimeException("Couldn't find CraftPlayer", e); + } + try { + this.connection = NMSUtil.nms("EntityPlayer").getDeclaredField("playerConnection"); + } catch (NoSuchFieldException | ClassNotFoundException e) { + throw new RuntimeException("Couldn't find Player Connection", e); + } + try { + this.packetMethod = NMSUtil.nms("PlayerConnection").getDeclaredMethod("a", windowClickPacketClass); + } catch (NoSuchMethodException | ClassNotFoundException e) { + throw new RuntimeException("Couldn't find CraftPlayer", e); + } + } + + private boolean isSupported() { + int protocolId = ProtocolRegistry.SERVER_PROTOCOL; + if (protocolId >= ProtocolVersion.v1_8.getId() && protocolId <= ProtocolVersion.v1_11_1.getId()) { + return true; // 1.8-1.11.2 + } + // this is not needed on 1.12+ servers + return false; + } +} \ No newline at end of file diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/tasks/protocol1_12to1_11_1/BukkitInventoryUpdateTask.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/tasks/protocol1_12to1_11_1/BukkitInventoryUpdateTask.java new file mode 100644 index 000000000..e83d3772d --- /dev/null +++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/tasks/protocol1_12to1_11_1/BukkitInventoryUpdateTask.java @@ -0,0 +1,53 @@ +package us.myles.ViaVersion.bukkit.tasks.protocol1_12to1_11_1; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import us.myles.ViaVersion.bukkit.providers.BukkitInventoryQuickMoveProvider; +import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.storage.ItemTransaction; + +public class BukkitInventoryUpdateTask implements Runnable { + + private BukkitInventoryQuickMoveProvider provider; + private final UUID uuid; + private final List items; + + public BukkitInventoryUpdateTask(BukkitInventoryQuickMoveProvider provider, UUID uuid) { + this.provider = provider; + this.uuid = uuid; + this.items = Collections.synchronizedList(new ArrayList()); + } + + public void addItem(short windowId, short slotId, short actionId) { + ItemTransaction storage = new ItemTransaction(windowId, slotId, actionId); + items.add(storage); + } + + @Override + public void run() { + Player p = Bukkit.getServer().getPlayer(uuid); + if (p == null) { + provider.onTaskExecuted(uuid); + return; + } + try { + synchronized (items) { + for (ItemTransaction storage : items) { + Object packet = provider.buildWindowClickPacket(p, storage); + boolean result = provider.sendPlayer(p, packet); + if (!result) { + break; + } + } + items.clear(); + } + } finally { + provider.onTaskExecuted(uuid); + } + } +} \ No newline at end of file diff --git a/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java b/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java index 2f22fce64..a8a66d113 100644 --- a/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java +++ b/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java @@ -79,6 +79,11 @@ public class BungeePlugin extends Plugin implements ViaPlatform, Listener { return runAsync(runnable); } + @Override + public TaskId runSync(Runnable runnable, Long ticks) { + return new BungeeTaskId(getProxy().getScheduler().schedule(this, runnable, ticks * 50, TimeUnit.MILLISECONDS).getId()); + } + @Override public TaskId runRepeatingSync(Runnable runnable, Long ticks) { return new BungeeTaskId(getProxy().getScheduler().schedule(this, runnable, 0, ticks * 50, TimeUnit.MILLISECONDS).getId()); diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeConfigAPI.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeConfigAPI.java index a69b8e056..e4f8d7a1f 100644 --- a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeConfigAPI.java +++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeConfigAPI.java @@ -10,7 +10,7 @@ import java.net.URL; import java.util.*; public class BungeeConfigAPI extends Config implements ViaVersionConfig { - private static List UNSUPPORTED = Arrays.asList("nms-player-ticking", "item-cache", "anti-xray-patch"); + private static List UNSUPPORTED = Arrays.asList("nms-player-ticking", "item-cache", "anti-xray-patch", "quick-move-action-fix"); public BungeeConfigAPI(File configFile) { super(new File(configFile, "config.yml")); @@ -203,6 +203,11 @@ public class BungeeConfigAPI extends Config implements ViaVersionConfig { public boolean is1_12NBTArrayFix() { return getBoolean("chat-nbt-fix", true); } + + @Override + public boolean is1_12QuickMoveActionFix() { + return false; + } @Override public List getBlockedProtocols() { diff --git a/common/src/main/java/us/myles/ViaVersion/api/PacketWrapper.java b/common/src/main/java/us/myles/ViaVersion/api/PacketWrapper.java index 6182d5d92..6421495e8 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/PacketWrapper.java +++ b/common/src/main/java/us/myles/ViaVersion/api/PacketWrapper.java @@ -149,10 +149,11 @@ public class PacketWrapper { } } else { Pair read = readableObjects.poll(); - if (read.getKey().equals(type) || (type.getBaseClass().equals(read.getKey().getBaseClass()) && type.getOutputClass().equals(read.getKey().getOutputClass()))) { + Type rtype = read.getKey(); + if (rtype.equals(type) || (type.getBaseClass().equals(rtype.getBaseClass()) && type.getOutputClass().equals(rtype.getOutputClass()))) { return (T) read.getValue(); } else { - if (type == Type.NOTHING) { + if (rtype == Type.NOTHING) { return read(type); // retry } else { Exception e = new IOException("Unable to read type " + type.getTypeName() + ", found " + read.getKey().getTypeName()); diff --git a/common/src/main/java/us/myles/ViaVersion/api/ViaVersionConfig.java b/common/src/main/java/us/myles/ViaVersion/api/ViaVersionConfig.java index 90f85ff39..98578e5d0 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/ViaVersionConfig.java +++ b/common/src/main/java/us/myles/ViaVersion/api/ViaVersionConfig.java @@ -209,7 +209,14 @@ public interface ViaVersionConfig { * @return True if enabled */ boolean is1_12NBTArrayFix(); - + + /** + * Should we fix shift quick move action for 1.12 clients + * + * @return True if enabled + */ + boolean is1_12QuickMoveActionFix(); + /** * Get the blocked protocols * diff --git a/common/src/main/java/us/myles/ViaVersion/api/platform/ViaPlatform.java b/common/src/main/java/us/myles/ViaVersion/api/platform/ViaPlatform.java index d241dbc03..796910a52 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/platform/ViaPlatform.java +++ b/common/src/main/java/us/myles/ViaVersion/api/platform/ViaPlatform.java @@ -59,6 +59,16 @@ public interface ViaPlatform { */ TaskId runSync(Runnable runnable); + /** + * Run a task Sync after a interval + * This must be only used after plugin enable. + * + * @param runnable The task to run + * @param ticks The interval to run it after + * @return The Task ID + */ + TaskId runSync(Runnable runnable, Long ticks); + /** * Run a task at a repeating interval. * Initial interval is the same as repeat. diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/Protocol1_12To1_11_1.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/Protocol1_12To1_11_1.java index f153ea234..89ffcb518 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/Protocol1_12To1_11_1.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/Protocol1_12To1_11_1.java @@ -12,6 +12,7 @@ import us.myles.ViaVersion.api.data.UserConnection; import us.myles.ViaVersion.api.entities.Entity1_12Types; import us.myles.ViaVersion.api.minecraft.chunks.Chunk; import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; +import us.myles.ViaVersion.api.platform.providers.ViaProviders; import us.myles.ViaVersion.api.protocol.Protocol; import us.myles.ViaVersion.api.remapper.PacketHandler; import us.myles.ViaVersion.api.remapper.PacketRemapper; @@ -19,6 +20,7 @@ import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.api.type.types.version.Types1_12; import us.myles.ViaVersion.packets.State; import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.packets.InventoryPackets; +import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.providers.InventoryQuickMoveProvider; import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.storage.EntityTracker; 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; @@ -384,6 +386,11 @@ public class Protocol1_12To1_11_1 extends Protocol { newId += 3; return newId; } + + @Override + protected void register(ViaProviders providers) { + providers.register(InventoryQuickMoveProvider.class, new InventoryQuickMoveProvider()); + } @Override public void init(UserConnection userConnection) { diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/packets/InventoryPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/packets/InventoryPackets.java index d59b713a2..08231ad12 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/packets/InventoryPackets.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/packets/InventoryPackets.java @@ -1,6 +1,7 @@ package us.myles.ViaVersion.protocols.protocol1_12to1_11_1.packets; import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.minecraft.item.Item; import us.myles.ViaVersion.api.remapper.PacketHandler; import us.myles.ViaVersion.api.remapper.PacketRemapper; @@ -8,6 +9,7 @@ import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.packets.State; import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.BedRewriter; import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.Protocol1_12To1_11_1; +import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.providers.InventoryQuickMoveProvider; public class InventoryPackets { public static void register(Protocol1_12To1_11_1 protocol) { @@ -119,7 +121,26 @@ public class InventoryPackets { @Override public void handle(PacketWrapper wrapper) throws Exception { Item item = wrapper.get(Type.ITEM, 0); - BedRewriter.toServerItem(item); + if (!Via.getConfig().is1_12QuickMoveActionFix()) { + BedRewriter.toServerItem(item); + return; + } + byte button = wrapper.get(Type.BYTE, 0); + int mode = wrapper.get(Type.VAR_INT, 0); + // QUICK_MOVE PATCH (Shift + (click/double click)) + if (mode == 1 && button == 0 && item == null) { + short windowId = wrapper.get(Type.UNSIGNED_BYTE, 0); + short slotId = wrapper.get(Type.SHORT, 0); + short actionId = wrapper.get(Type.SHORT, 1); + InventoryQuickMoveProvider provider = Via.getManager().getProviders().get(InventoryQuickMoveProvider.class); + boolean succeed = provider.registerQuickMove(windowId, slotId, actionId, wrapper.user()); + if (succeed) { + wrapper.cancel(); + } + // otherwise just pass through so the server sends the PacketPlayOutTransaction packet. + } else { + BedRewriter.toServerItem(item); + } } }); } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/providers/InventoryQuickMoveProvider.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/providers/InventoryQuickMoveProvider.java new file mode 100644 index 000000000..906b72dc4 --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/providers/InventoryQuickMoveProvider.java @@ -0,0 +1,11 @@ +package us.myles.ViaVersion.protocols.protocol1_12to1_11_1.providers; + +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.platform.providers.Provider; + +public class InventoryQuickMoveProvider implements Provider { + + public boolean registerQuickMove(short windowId, short slotId, short actionId, UserConnection userConnection) { + return false; // not supported :/ plays very sad violin + } +} \ No newline at end of file diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/storage/ItemTransaction.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/storage/ItemTransaction.java new file mode 100644 index 000000000..9ae0109c2 --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/storage/ItemTransaction.java @@ -0,0 +1,14 @@ +package us.myles.ViaVersion.protocols.protocol1_12to1_11_1.storage; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; + +@AllArgsConstructor +@ToString +@Getter +public class ItemTransaction { + private short windowId; + private short slotId; + private short actionId; +} \ No newline at end of file diff --git a/common/src/main/resources/assets/viaversion/config.yml b/common/src/main/resources/assets/viaversion/config.yml index 43855685b..a90a40505 100644 --- a/common/src/main/resources/assets/viaversion/config.yml +++ b/common/src/main/resources/assets/viaversion/config.yml @@ -84,6 +84,8 @@ hologram-y: -0.96 piston-animation-patch: false # Should we fix nbt for 1.12 and above clients in chat messages (causes invalid item) chat-nbt-fix: true +# Should we fix shift quick move action for 1.12 clients (causes shift + double click not to work when moving items) (only works on 1.8-1.11.2 bukkit based servers) +quick-move-action-fix: true # #----------------------------------------------------------# # 1.9 & 1.10 CLIENTS ON 1.8 SERVERS OPTIONS # diff --git a/sponge/src/main/java/us/myles/ViaVersion/SpongePlugin.java b/sponge/src/main/java/us/myles/ViaVersion/SpongePlugin.java index b5ba95b7d..b20365674 100644 --- a/sponge/src/main/java/us/myles/ViaVersion/SpongePlugin.java +++ b/sponge/src/main/java/us/myles/ViaVersion/SpongePlugin.java @@ -3,7 +3,6 @@ package us.myles.ViaVersion; import com.google.gson.JsonObject; import com.google.inject.Inject; import org.spongepowered.api.Game; -import org.spongepowered.api.Sponge; import org.spongepowered.api.config.DefaultConfig; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.event.Listener; @@ -113,6 +112,12 @@ public class SpongePlugin implements ViaPlatform { return new SpongeTaskId(null); } + @Override + public TaskId runSync(Runnable runnable, Long ticks) { + Long delay = ticks * 50L; + return new SpongeTaskId(syncExecutor.schedule(runnable, delay, TimeUnit.MILLISECONDS).getTask()); + } + @Override public TaskId runRepeatingSync(Runnable runnable, Long ticks) { Long time = ticks * 50L; diff --git a/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeConfigAPI.java b/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeConfigAPI.java index 5910be1f1..da5cd7dcc 100644 --- a/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeConfigAPI.java +++ b/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeConfigAPI.java @@ -13,7 +13,7 @@ import java.util.Map; import java.util.Optional; public class SpongeConfigAPI extends Config implements ViaVersionConfig { - private static List UNSUPPORTED = Arrays.asList("anti-xray-patch", "bungee-ping-interval", "bungee-ping-save", "bungee-servers"); + private static List UNSUPPORTED = Arrays.asList("anti-xray-patch", "bungee-ping-interval", "bungee-ping-save", "bungee-servers", "quick-move-action-fix"); private final PluginContainer pluginContainer; public SpongeConfigAPI(PluginContainer pluginContainer, File configFile) { @@ -185,6 +185,11 @@ public class SpongeConfigAPI extends Config implements ViaVersionConfig { public boolean is1_12NBTArrayFix() { return getBoolean("chat-nbt-fix", true); } + + @Override + public boolean is1_12QuickMoveActionFix() { + return false; + } @Override public List getBlockedProtocols() {