9
0
mirror of https://github.com/Xiao-MoMi/Custom-Nameplates.git synced 2026-01-06 15:42:00 +00:00

improve spectator mode

This commit is contained in:
XiaoMoMi
2024-10-07 17:23:57 +08:00
parent 5df341b2a1
commit f6de779090
18 changed files with 260 additions and 47 deletions

View File

@@ -20,6 +20,7 @@ package net.momirealms.customnameplates.bukkit;
import net.momirealms.customnameplates.api.AbstractCNPlayer;
import net.momirealms.customnameplates.api.CustomNameplates;
import net.momirealms.customnameplates.api.util.Vector3;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
@@ -96,6 +97,11 @@ public class BukkitCNPlayer extends AbstractCNPlayer {
return player.isOnline();
}
@Override
public boolean isSpectator() {
return player.getGameMode() == GameMode.SPECTATOR;
}
@Override
public Set<Integer> passengers() {
return player.getPassengers().stream().map(Entity::getEntityId).collect(Collectors.toSet());

View File

@@ -40,6 +40,7 @@ import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
public class BukkitPlatform implements Platform {
@@ -178,6 +179,29 @@ public class BukkitPlatform implements Platform {
}
}, "PacketPlayOutEntityDestroy", "ClientboundRemoveEntitiesPacket");
registerPacketConsumer((player, event, packet) -> {
try {
EnumSet<?> enums = (EnumSet<?>) Reflections.field$ClientboundPlayerInfoUpdatePacket$actions.get(packet);
if (enums == null) return;
if (!enums.contains(Reflections.enum$ClientboundPlayerInfoUpdatePacket$Action$UPDATE_GAME_MODE)) return;
List<Object> entries = (List<Object>) Reflections.field$ClientboundPlayerInfoUpdatePacket$entries.get(packet);
for (Object entry : entries) {
UUID uuid = (UUID) Reflections.field$ClientboundPlayerInfoUpdatePacket$Entry$profileId.get(entry);
if (uuid == null) continue;
Object gameType = Reflections.field$ClientboundPlayerInfoUpdatePacket$Entry$gameMode.get(entry);
if (gameType == null) continue;
int mode = (int) Reflections.method$GameType$getId.invoke(gameType);
boolean isSpectator = mode == 3;
CNPlayer another = CustomNameplates.getInstance().getPlayer(uuid);
if (another != null) {
CustomNameplates.getInstance().getUnlimitedTagManager().onPlayerGameModeChange(another, player, isSpectator);
}
}
} catch (ReflectiveOperationException e) {
CustomNameplates.getInstance().getPluginLogger().severe("Failed to handle ClientboundPlayerInfoUpdatePacket", e);
}
}, "ClientboundPlayerInfoUpdatePacket");
// for cosmetic plugin compatibility
registerPacketConsumer((player, event, packet) -> {
try {

View File

@@ -49,6 +49,7 @@ public class BukkitCommandManager extends AbstractCommandManager<CommandSender>
new DebugPerformanceCommand(this, plugin),
new DebugWidthCommand(this, plugin),
new DebugLinesCommand(this, plugin),
new DebugTestCommand(this, plugin),
new NameplatesEquipCommand(this, plugin),
new NameplatesUnEquipCommand(this, plugin),
new NameplatesListCommand(this, plugin),

View File

@@ -0,0 +1,46 @@
/*
* Copyright (C) <2024> <XiaoMoMi>
*
* 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
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customnameplates.bukkit.command.feature;
import net.momirealms.customnameplates.bukkit.BukkitCustomNameplates;
import net.momirealms.customnameplates.bukkit.command.BukkitCommandFeature;
import net.momirealms.customnameplates.common.command.CustomNameplatesCommandManager;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.incendo.cloud.Command;
import org.incendo.cloud.CommandManager;
public class DebugTestCommand extends BukkitCommandFeature<CommandSender> {
public DebugTestCommand(CustomNameplatesCommandManager<CommandSender> commandManager, BukkitCustomNameplates plugin) {
super(commandManager, plugin);
}
@Override
public Command.Builder<? extends CommandSender> assembleCommand(CommandManager<CommandSender> manager, Command.Builder<CommandSender> builder) {
return builder
.senderType(Player.class)
.handler(context -> {
});
}
@Override
public String getFeatureID() {
return "debug_test";
}
}

View File

@@ -26,6 +26,7 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
import java.util.UUID;
@@ -741,4 +742,106 @@ public class Reflections {
clazz$AttributeModifier, double.class, 0
)
);
public static final Class<?> clazz$ClientboundGameEventPacket = requireNonNull(
ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundGameEventPacket"),
BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutGameStateChange")
)
);
public static final Class<?> clazz$ClientboundGameEventPacket$Type = requireNonNull(
ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundGameEventPacket$Type"),
BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutGameStateChange$a")
)
);
public static final Field field$ClientboundGameEventPacket$event = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ClientboundGameEventPacket, clazz$ClientboundGameEventPacket$Type, 0
)
);
public static final Field field$ClientboundGameEventPacket$param = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ClientboundGameEventPacket, float.class, 0
)
);
public static final Field field$ClientboundGameEventPacket$Type$id = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ClientboundGameEventPacket$Type, int.class, 0
)
);
public static final Class<?> clazz$ClientboundPlayerInfoUpdatePacket = requireNonNull(
ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundPlayerInfoUpdatePacket")
)
);
public static final Field field$ClientboundPlayerInfoUpdatePacket$actions = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ClientboundPlayerInfoUpdatePacket, EnumSet.class, 0
)
);
public static final Field field$ClientboundPlayerInfoUpdatePacket$entries = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ClientboundPlayerInfoUpdatePacket, List.class, 0
)
);
public static final Class<?> clazz$ClientboundPlayerInfoUpdatePacket$Action = requireNonNull(
ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundPlayerInfoUpdatePacket$Action"),
BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundPlayerInfoUpdatePacket$a")
)
);
public static final Enum<?> enum$ClientboundPlayerInfoUpdatePacket$Action$UPDATE_GAME_MODE;
static {
Enum<?> updateGameMode;
try {
updateGameMode = Enum.valueOf((Class<Enum>) clazz$ClientboundPlayerInfoUpdatePacket$Action, "UPDATE_GAME_MODE");
} catch (Exception e) {
updateGameMode = Enum.valueOf((Class<Enum>) clazz$ClientboundPlayerInfoUpdatePacket$Action, "c");
}
enum$ClientboundPlayerInfoUpdatePacket$Action$UPDATE_GAME_MODE = updateGameMode;
}
public static final Class<?> clazz$ClientboundPlayerInfoUpdatePacket$Entry = requireNonNull(
ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundPlayerInfoUpdatePacket$Entry"),
BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundPlayerInfoUpdatePacket$b")
)
);
public static final Class<?> clazz$GameType = requireNonNull(
ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleMCClass("world.level.GameType"),
BukkitReflectionUtils.assembleMCClass("world.level.EnumGamemode")
)
);
public static final Field field$ClientboundPlayerInfoUpdatePacket$Entry$gameMode = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ClientboundPlayerInfoUpdatePacket$Entry, clazz$GameType, 0
)
);
public static final Field field$ClientboundPlayerInfoUpdatePacket$Entry$profileId = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ClientboundPlayerInfoUpdatePacket$Entry, UUID.class, 0
)
);
public static final Method method$GameType$getId = requireNonNull(
ReflectionUtils.getMethod(
clazz$GameType, new String[] { "getId", "a" }
)
);
}

View File

@@ -133,4 +133,12 @@ bubbles_list:
enable: true
permission: bubbles.command.list
usage:
- /bubbles list
- /bubbles list
# A command to test some stuffs
# Usage: [COMMAND]
debug_test:
enable: false
permission: nameplates.command.debug.test
usage:
- /nameplates debug test