2021-03-22 23:06:40 +01:00
|
|
|
/*
|
|
|
|
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
2023-01-12 12:45:53 +01:00
|
|
|
* Copyright (C) 2016-2023 ViaVersion and contributors
|
2021-03-22 23:06:40 +01:00
|
|
|
*
|
|
|
|
* 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/>.
|
|
|
|
*/
|
2021-04-26 20:52:34 +02:00
|
|
|
package com.viaversion.viaversion.bukkit.providers;
|
2016-09-25 19:26:14 +02:00
|
|
|
|
2021-04-26 20:52:34 +02:00
|
|
|
import com.viaversion.viaversion.api.Via;
|
2021-04-26 21:35:29 +02:00
|
|
|
import com.viaversion.viaversion.api.connection.UserConnection;
|
2021-04-26 20:52:34 +02:00
|
|
|
import com.viaversion.viaversion.bukkit.util.NMSUtil;
|
|
|
|
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
|
|
|
|
import com.viaversion.viaversion.protocols.protocol1_9to1_8.storage.MovementTracker;
|
2021-04-27 13:41:39 +02:00
|
|
|
import org.bukkit.Bukkit;
|
|
|
|
import org.bukkit.entity.Player;
|
2016-09-25 19:26:14 +02:00
|
|
|
|
|
|
|
import java.lang.reflect.Field;
|
|
|
|
import java.lang.reflect.InvocationTargetException;
|
|
|
|
import java.lang.reflect.Method;
|
|
|
|
|
|
|
|
public class BukkitViaMovementTransmitter extends MovementTransmitterProvider {
|
|
|
|
private static boolean USE_NMS = true;
|
|
|
|
// Used for packet mode
|
|
|
|
private Object idlePacket;
|
|
|
|
private Object idlePacket2;
|
|
|
|
// Use for nms
|
|
|
|
private Method getHandle;
|
|
|
|
private Field connection;
|
|
|
|
private Method handleFlying;
|
|
|
|
|
|
|
|
public BukkitViaMovementTransmitter() {
|
|
|
|
USE_NMS = Via.getConfig().isNMSPlayerTicking();
|
|
|
|
|
|
|
|
Class<?> idlePacketClass;
|
|
|
|
try {
|
2016-09-26 14:50:20 +02:00
|
|
|
idlePacketClass = NMSUtil.nms("PacketPlayInFlying");
|
2016-09-25 19:26:14 +02:00
|
|
|
} catch (ClassNotFoundException e) {
|
2016-09-26 14:11:46 +02:00
|
|
|
return; // We'll hope this is 1.9.4+
|
2016-09-25 19:26:14 +02:00
|
|
|
}
|
|
|
|
try {
|
|
|
|
idlePacket = idlePacketClass.newInstance();
|
|
|
|
idlePacket2 = idlePacketClass.newInstance();
|
|
|
|
|
|
|
|
Field flying = idlePacketClass.getDeclaredField("f");
|
|
|
|
flying.setAccessible(true);
|
|
|
|
|
|
|
|
flying.set(idlePacket2, true);
|
|
|
|
} catch (NoSuchFieldException | InstantiationException | IllegalArgumentException | IllegalAccessException e) {
|
|
|
|
throw new RuntimeException("Couldn't make player idle packet, help!", e);
|
|
|
|
}
|
|
|
|
if (USE_NMS) {
|
|
|
|
try {
|
2016-09-26 14:50:20 +02:00
|
|
|
getHandle = NMSUtil.obc("entity.CraftPlayer").getDeclaredMethod("getHandle");
|
2016-09-25 19:26:14 +02:00
|
|
|
} catch (NoSuchMethodException | ClassNotFoundException e) {
|
|
|
|
throw new RuntimeException("Couldn't find CraftPlayer", e);
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
2016-09-26 14:50:20 +02:00
|
|
|
connection = NMSUtil.nms("EntityPlayer").getDeclaredField("playerConnection");
|
2016-09-25 19:26:14 +02:00
|
|
|
} catch (NoSuchFieldException | ClassNotFoundException e) {
|
|
|
|
throw new RuntimeException("Couldn't find Player Connection", e);
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
2016-09-26 14:50:20 +02:00
|
|
|
handleFlying = NMSUtil.nms("PlayerConnection").getDeclaredMethod("a", idlePacketClass);
|
2016-09-25 19:26:14 +02:00
|
|
|
} catch (NoSuchMethodException | ClassNotFoundException e) {
|
|
|
|
throw new RuntimeException("Couldn't find CraftPlayer", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Object getFlyingPacket() {
|
2016-09-26 14:11:46 +02:00
|
|
|
if (idlePacket == null)
|
|
|
|
throw new NullPointerException("Could not locate flying packet");
|
2022-05-23 20:29:21 +02:00
|
|
|
return idlePacket;
|
2016-09-25 19:26:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Object getGroundPacket() {
|
2016-09-26 14:11:46 +02:00
|
|
|
if (idlePacket == null)
|
|
|
|
throw new NullPointerException("Could not locate flying packet");
|
2022-05-23 20:29:21 +02:00
|
|
|
return idlePacket2;
|
2016-09-25 19:26:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void sendPlayer(UserConnection info) {
|
|
|
|
if (USE_NMS) {
|
2020-06-07 12:19:36 +02:00
|
|
|
Player player = Bukkit.getPlayer(info.getProtocolInfo().getUuid());
|
2016-09-25 19:26:14 +02:00
|
|
|
if (player != null) {
|
|
|
|
try {
|
|
|
|
// Tick player
|
|
|
|
Object entityPlayer = getHandle.invoke(player);
|
|
|
|
Object pc = connection.get(entityPlayer);
|
|
|
|
if (pc != null) {
|
|
|
|
handleFlying.invoke(pc, (info.get(MovementTracker.class).isGround() ? idlePacket2 : idlePacket));
|
|
|
|
// Tick world
|
|
|
|
info.get(MovementTracker.class).incrementIdlePacket();
|
|
|
|
}
|
|
|
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
super.sendPlayer(info);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|