Properly handle 1.19 acks on backend

Fixes #2935
This commit is contained in:
Nassim Jahnke 2022-06-12 11:13:48 +02:00
parent 702ced200e
commit 24d887a53d
No known key found for this signature in database
GPG Key ID: 6BE3B555EBC5982B
7 changed files with 182 additions and 10 deletions

View File

@ -32,12 +32,14 @@ import com.viaversion.viaversion.bukkit.listeners.protocol1_9to1_8.BlockListener
import com.viaversion.viaversion.bukkit.listeners.protocol1_9to1_8.DeathListener;
import com.viaversion.viaversion.bukkit.listeners.protocol1_9to1_8.HandItemCache;
import com.viaversion.viaversion.bukkit.listeners.protocol1_9to1_8.PaperPatch;
import com.viaversion.viaversion.bukkit.providers.BukkitAckSequenceProvider;
import com.viaversion.viaversion.bukkit.providers.BukkitBlockConnectionProvider;
import com.viaversion.viaversion.bukkit.providers.BukkitInventoryQuickMoveProvider;
import com.viaversion.viaversion.bukkit.providers.BukkitViaMovementTransmitter;
import com.viaversion.viaversion.protocols.protocol1_12to1_11_1.providers.InventoryQuickMoveProvider;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.blockconnections.ConnectionData;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.blockconnections.providers.BlockConnectionProvider;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.provider.AckSequenceProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.HandItemProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
import org.bukkit.Bukkit;
@ -47,7 +49,6 @@ import org.bukkit.event.Listener;
import org.bukkit.scheduler.BukkitTask;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@ -174,6 +175,9 @@ public class BukkitViaLoader implements ViaPlatformLoader {
ConnectionData.blockConnectionProvider = blockConnectionProvider;
}
}
if (serverProtocolVersion < ProtocolVersion.v1_19.getVersion()) {
Via.getManager().getProviders().use(AckSequenceProvider.class, new BukkitAckSequenceProvider(plugin));
}
}
@Override

View File

@ -0,0 +1,42 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.bukkit.providers;
import com.viaversion.viaversion.ViaVersionPlugin;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.bukkit.tasks.protocol1_19to1_18_2.AckSequenceTask;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.provider.AckSequenceProvider;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.storage.SequenceStorage;
public final class BukkitAckSequenceProvider extends AckSequenceProvider {
private final ViaVersionPlugin plugin;
public BukkitAckSequenceProvider(final ViaVersionPlugin plugin) {
this.plugin = plugin;
}
@Override
public void handleSequence(final UserConnection connection, final int sequence) {
final SequenceStorage sequenceStorage = connection.get(SequenceStorage.class);
final int previousSequence = sequenceStorage.setSequenceId(sequence);
if (previousSequence == -1) {
plugin.getServer().getScheduler().runTask(plugin, new AckSequenceTask(connection, sequenceStorage));
}
}
}

View File

@ -0,0 +1,48 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.bukkit.tasks.protocol1_19to1_18_2;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.ClientboundPackets1_19;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.Protocol1_19To1_18_2;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.storage.SequenceStorage;
public final class AckSequenceTask implements Runnable {
private final UserConnection connection;
private final SequenceStorage sequenceStorage;
public AckSequenceTask(final UserConnection connection, final SequenceStorage sequenceStorage) {
this.connection = connection;
this.sequenceStorage = sequenceStorage;
}
@Override
public void run() {
final int sequence = sequenceStorage.setSequenceId(-1);
try {
final PacketWrapper ackPacket = PacketWrapper.create(ClientboundPackets1_19.BLOCK_CHANGED_ACK, connection);
ackPacket.write(Type.VAR_INT, sequence);
ackPacket.scheduleSend(Protocol1_19To1_18_2.class);
} catch (final Exception e) {
e.printStackTrace();
}
}
}

View File

@ -23,6 +23,7 @@ import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.MappingData;
import com.viaversion.viaversion.api.data.MappingDataBase;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_19Types;
import com.viaversion.viaversion.api.platform.providers.ViaProviders;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
@ -42,8 +43,10 @@ import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.ClientboundPacke
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.packets.EntityPackets;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.packets.InventoryPackets;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.packets.WorldPackets;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.provider.AckSequenceProvider;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.storage.DimensionRegistryStorage;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.storage.NonceStorage;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.storage.SequenceStorage;
import com.viaversion.viaversion.rewriter.CommandRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
@ -316,11 +319,17 @@ public final class Protocol1_19To1_18_2 extends AbstractProtocol<ClientboundPack
entityRewriter.onMappingDataLoaded();
}
@Override
public void register(final ViaProviders providers) {
providers.register(AckSequenceProvider.class, new AckSequenceProvider());
}
@Override
public void init(final UserConnection user) {
if (!user.has(DimensionRegistryStorage.class)) {
user.put(new DimensionRegistryStorage());
}
user.put(new SequenceStorage());
addEntityTracker(user, new EntityTrackerBase(user, Entity1_19Types.PLAYER));
}

View File

@ -17,15 +17,15 @@
*/
package com.viaversion.viaversion.protocols.protocol1_19to1_18_2.packets;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.data.RecipeRewriter1_16;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.ClientboundPackets1_18;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.ClientboundPackets1_19;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.Protocol1_19To1_18_2;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.ServerboundPackets1_19;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.provider.AckSequenceProvider;
import com.viaversion.viaversion.rewriter.ItemRewriter;
public final class InventoryPackets extends ItemRewriter<Protocol1_19To1_18_2> {
@ -127,14 +127,9 @@ public final class InventoryPackets extends ItemRewriter<Protocol1_19To1_18_2> {
private PacketHandler sequenceHandler() {
return wrapper -> {
// Manually send and follow up with an acknowledgement
final int sequence = wrapper.read(Type.VAR_INT);
wrapper.sendToServer(Protocol1_19To1_18_2.class);
wrapper.cancel();
final PacketWrapper ackPacket = wrapper.create(ClientboundPackets1_19.BLOCK_CHANGED_ACK);
ackPacket.write(Type.VAR_INT, sequence);
ackPacket.scheduleSend(Protocol1_19To1_18_2.class);
final AckSequenceProvider provider = Via.getManager().getProviders().get(AckSequenceProvider.class);
provider.handleSequence(wrapper.user(), sequence);
};
}
}

View File

@ -0,0 +1,34 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.protocols.protocol1_19to1_18_2.provider;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.platform.providers.Provider;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.ClientboundPackets1_19;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.Protocol1_19To1_18_2;
public class AckSequenceProvider implements Provider {
public void handleSequence(final UserConnection connection, final int sequence) throws Exception {
final PacketWrapper ackPacket = PacketWrapper.create(ClientboundPackets1_19.BLOCK_CHANGED_ACK, connection);
ackPacket.write(Type.VAR_INT, sequence);
ackPacket.scheduleSend(Protocol1_19To1_18_2.class);
}
}

View File

@ -0,0 +1,40 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.protocols.protocol1_19to1_18_2.storage;
import com.viaversion.viaversion.api.connection.StorableObject;
public final class SequenceStorage implements StorableObject {
private final Object lock = new Object();
private int sequenceId = -1;
public int sequenceId() {
synchronized (lock) {
return sequenceId;
}
}
public int setSequenceId(final int sequenceId) {
synchronized (lock) {
final int previousSequence = this.sequenceId;
this.sequenceId = sequenceId;
return previousSequence;
}
}
}