mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-27 02:49:15 +00:00
feat(network): 添加严格校验用户申请资源包使用的UUID
This commit is contained in:
@@ -60,6 +60,7 @@ import net.momirealms.craftengine.core.plugin.context.NetworkTextReplaceContext;
|
||||
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
|
||||
import net.momirealms.craftengine.core.plugin.context.event.EventTrigger;
|
||||
import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters;
|
||||
import net.momirealms.craftengine.core.plugin.locale.TranslationManager;
|
||||
import net.momirealms.craftengine.core.plugin.logger.Debugger;
|
||||
import net.momirealms.craftengine.core.plugin.network.*;
|
||||
import net.momirealms.craftengine.core.plugin.text.component.ComponentProvider;
|
||||
@@ -1239,17 +1240,17 @@ public class PacketConsumers {
|
||||
try {
|
||||
BukkitServerPlayer player = (BukkitServerPlayer) user;
|
||||
String name = (String) NetworkReflections.methodHandle$ServerboundHelloPacket$nameGetter.invokeExact(packet);
|
||||
player.setName(name);
|
||||
player.setUnverifiedName(name);
|
||||
if (VersionHelper.isOrAbove1_20_2()) {
|
||||
UUID uuid = (UUID) NetworkReflections.methodHandle$ServerboundHelloPacket$uuidGetter.invokeExact(packet);
|
||||
player.setUUID(uuid);
|
||||
player.setUnverifiedUUID(uuid);
|
||||
} else {
|
||||
@SuppressWarnings("unchecked")
|
||||
Optional<UUID> uuid = (Optional<UUID>) NetworkReflections.methodHandle$ServerboundHelloPacket$uuidGetter.invokeExact(packet);
|
||||
if (uuid.isPresent()) {
|
||||
player.setUUID(uuid.get());
|
||||
player.setUnverifiedUUID(uuid.get());
|
||||
} else {
|
||||
player.setUUID(UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(StandardCharsets.UTF_8)));
|
||||
player.setUnverifiedUUID(UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(StandardCharsets.UTF_8)));
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
@@ -2499,6 +2500,18 @@ public class PacketConsumers {
|
||||
// 防止后续加入的JoinWorldTask再次处理
|
||||
user.setShouldProcessFinishConfiguration(false);
|
||||
|
||||
// 检查用户UUID是否已经校验
|
||||
if (!user.isVerifiedUUID()) {
|
||||
if (Config.strictPlayerUuidValidation()) {
|
||||
TranslationManager.instance().log("warning.network.resource_pack.unverified_uuid", user.name(), user.uuid().toString());
|
||||
user.kick(Component.translatable("disconnect.loginFailed"));
|
||||
return;
|
||||
}
|
||||
if (Config.debugResourcePack()) {
|
||||
TranslationManager.instance().log("warning.network.resource_pack.unverified_uuid", user.name(), user.uuid().toString());
|
||||
}
|
||||
}
|
||||
|
||||
// 取消 ClientboundFinishConfigurationPacket,让客户端发呆,并结束掉当前的进入世界任务
|
||||
event.setCancelled(true);
|
||||
try {
|
||||
@@ -2548,8 +2561,8 @@ public class PacketConsumers {
|
||||
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> LOGIN_FINISHED = (user, event, packet) -> {
|
||||
try {
|
||||
GameProfile gameProfile = FastNMS.INSTANCE.field$ClientboundLoginFinishedPacket$gameProfile(packet);
|
||||
user.setName(gameProfile.getName());
|
||||
user.setUUID(gameProfile.getId());
|
||||
user.setVerifiedName(gameProfile.getName());
|
||||
user.setVerifiedUUID(gameProfile.getId());
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ClientboundLoginFinishedPacket", e);
|
||||
}
|
||||
|
||||
@@ -72,6 +72,8 @@ public class BukkitServerPlayer extends Player {
|
||||
private ChannelHandler connection;
|
||||
private String name;
|
||||
private UUID uuid;
|
||||
private boolean isVerifiedName;
|
||||
private boolean isVerifiedUUID;
|
||||
private ConnectionState decoderState;
|
||||
private ConnectionState encoderState;
|
||||
private boolean shouldProcessFinishConfiguration = true;
|
||||
@@ -140,7 +142,9 @@ public class BukkitServerPlayer extends Player {
|
||||
this.playerRef = new WeakReference<>(player);
|
||||
this.serverPlayerRef = new WeakReference<>(FastNMS.INSTANCE.method$CraftPlayer$getHandle(player));
|
||||
this.uuid = player.getUniqueId();
|
||||
this.isVerifiedUUID = true;
|
||||
this.name = player.getName();
|
||||
this.isVerifiedName = true;
|
||||
byte[] bytes = player.getPersistentDataContainer().get(KeyUtils.toNamespacedKey(CooldownData.COOLDOWN_KEY), PersistentDataType.BYTE_ARRAY);
|
||||
this.trackedChunks = ConcurrentLong2ReferenceChainedHashTable.createWithCapacity(768, 0.5f);
|
||||
this.entityTypeView = new ConcurrentHashMap<>(256);
|
||||
@@ -321,22 +325,46 @@ public class BukkitServerPlayer extends Player {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
if (this.name != null) return;
|
||||
public boolean isVerifiedName() {
|
||||
return this.isVerifiedName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUnverifiedName(String name) {
|
||||
if (this.isVerifiedName) return;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVerifiedName(String name) {
|
||||
if (this.isVerifiedName) return;
|
||||
this.name = name;
|
||||
this.isVerifiedName = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID uuid() {
|
||||
return this.uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUUID(UUID uuid) {
|
||||
if (this.uuid != null) return;
|
||||
public boolean isVerifiedUUID() {
|
||||
return this.isVerifiedUUID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUnverifiedUUID(UUID uuid) {
|
||||
if (this.isVerifiedUUID) return;
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVerifiedUUID(UUID uuid) {
|
||||
if (this.isVerifiedUUID) return;
|
||||
this.uuid = uuid;
|
||||
this.isVerifiedUUID = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playSound(Key sound, SoundSource source, float volume, float pitch) {
|
||||
platformPlayer().playSound(platformPlayer(), sound.toString(), SoundUtils.toBukkit(source), volume, pitch);
|
||||
|
||||
@@ -98,6 +98,8 @@ resource-pack:
|
||||
file-to-upload: "./generated/resource_pack.zip"
|
||||
# Resend the resource pack to players upon successful upload
|
||||
resend-on-upload: true
|
||||
# Whether a verified player UUID is required to get the resource pack
|
||||
strict-player-uuid-validation: true
|
||||
duplicated-files-handler:
|
||||
- term:
|
||||
type: any_of
|
||||
|
||||
@@ -63,7 +63,8 @@ command.upload.failure.not_supported: "<red>Current hosting method '<arg:0>' doe
|
||||
command.upload.on_progress: "<white>Started uploading progress. Check the console for more information.</white>"
|
||||
command.send_resource_pack.success.single: "<white>Sent resource pack to <arg:0>.</white>"
|
||||
command.send_resource_pack.success.multiple: "<white>Send resource packs to <arg:0> players.</white>"
|
||||
warning.config.pack.duplicated_files: "</red>Duplicated files Found. Please resolve them through config.yml 'resource-pack.duplicated-files-handler' section.</red>"
|
||||
warning.network.resource_pack.unverified_uuid: "<yellow>Player <arg:0> attempts to request a resource package using a UUID (<arg:1>) that is not authenticated by the server.</yellow>"
|
||||
warning.config.pack.duplicated_files: "<red>Duplicated files Found. Please resolve them through config.yml 'resource-pack.duplicated-files-handler' section.</red>"
|
||||
warning.config.yaml.duplicated_key: "<red>Issue found in file <arg:0> - Found duplicated key '<arg:1>' at line <arg:2>, this might cause unexpected results.</red>"
|
||||
warning.config.yaml.inconsistent_value_type: "<red>Issue found in file <arg:0> - Found duplicated key '<arg:1>' at line <arg:2> with different value types, this might cause unexpected results.</red>"
|
||||
warning.config.type.int: "<yellow>Issue found in file <arg:0> - Failed to load '<arg:1>': Cannot cast '<arg:2>' to integer type for option '<arg:3>'.</yellow>"
|
||||
|
||||
@@ -63,7 +63,8 @@ command.upload.failure.not_supported: "<red>当前托管模式 '<arg:0>' 不支
|
||||
command.upload.on_progress: "<white>已开始上传进程. 检查控制台以获取详细信息</white>"
|
||||
command.send_resource_pack.success.single: "<white>发送资源包给 <arg:0></white>"
|
||||
command.send_resource_pack.success.multiple: "<white>发送资源包给 <arg:0> 个玩家</white>"
|
||||
warning.config.pack.duplicated_files: "</red>发现重复文件 请通过 config.yml 的 'resource-pack.duplicated-files-handler' 部分解决</red>"
|
||||
warning.network.resource_pack.unverified_uuid: "<yellow>玩家 <arg:0> 使用未经服务器验证的 UUID (<arg:1>) 尝试请求获取资源包</yellow>"
|
||||
warning.config.pack.duplicated_files: "<red>发现重复文件 请通过 config.yml 的 'resource-pack.duplicated-files-handler' 部分解决</red>"
|
||||
warning.config.yaml.duplicated_key: "<red>在文件 <arg:0> 发现问题 - 在第<arg:2>行发现重复的键 '<arg:1>', 这可能会导致一些意料之外的问题</red>"
|
||||
warning.config.yaml.inconsistent_value_type: "<red>在文件 <arg:0> 发现问题 - 在第<arg:2>行发现重复且值类型不同的键 '<arg:1>', 这可能会导致一些意料之外的问题</red>"
|
||||
warning.config.type.int: "<yellow>在文件 <arg:0> 发现问题 - 无法加载 '<arg:1>': 无法将 '<arg:2>' 转换为整数类型 (选项 '<arg:3>')</yellow>"
|
||||
|
||||
@@ -93,6 +93,7 @@ public class Config {
|
||||
protected boolean resource_pack$delivery$send_on_join;
|
||||
protected boolean resource_pack$delivery$resend_on_upload;
|
||||
protected boolean resource_pack$delivery$auto_upload;
|
||||
protected boolean resource_pack$delivery$strict_player_uuid_validation;
|
||||
protected Path resource_pack$delivery$file_to_upload;
|
||||
protected Component resource_pack$send$prompt;
|
||||
|
||||
@@ -271,6 +272,7 @@ public class Config {
|
||||
resource_pack$delivery$kick_if_declined = config.getBoolean("resource-pack.delivery.kick-if-declined", true);
|
||||
resource_pack$delivery$kick_if_failed_to_apply = config.getBoolean("resource-pack.delivery.kick-if-failed-to-apply", true);
|
||||
resource_pack$delivery$auto_upload = config.getBoolean("resource-pack.delivery.auto-upload", true);
|
||||
resource_pack$delivery$strict_player_uuid_validation = config.getBoolean("resource-pack.delivery.strict-player-uuid-validation", true);
|
||||
resource_pack$delivery$file_to_upload = resolvePath(config.getString("resource-pack.delivery.file-to-upload", "./generated/resource_pack.zip"));
|
||||
resource_pack$send$prompt = AdventureHelper.miniMessage().deserialize(config.getString("resource-pack.delivery.prompt", "<yellow>To fully experience our server, please accept our custom resource pack.</yellow>"));
|
||||
resource_pack$protection$crash_tools$method_1 = config.getBoolean("resource-pack.protection.crash-tools.method-1", false);
|
||||
@@ -590,6 +592,9 @@ public class Config {
|
||||
public static boolean autoUpload() {
|
||||
return instance.resource_pack$delivery$auto_upload;
|
||||
}
|
||||
public static boolean strictPlayerUuidValidation() {
|
||||
return instance.resource_pack$delivery$strict_player_uuid_validation;
|
||||
}
|
||||
|
||||
public static Path fileToUpload() {
|
||||
return instance.resource_pack$delivery$file_to_upload;
|
||||
|
||||
@@ -31,11 +31,19 @@ public interface NetWorkUser {
|
||||
|
||||
String name();
|
||||
|
||||
void setName(String name);
|
||||
boolean isVerifiedName();
|
||||
|
||||
void setUnverifiedName(String name);
|
||||
|
||||
void setVerifiedName(String name);
|
||||
|
||||
UUID uuid();
|
||||
|
||||
void setUUID(UUID uuid);
|
||||
boolean isVerifiedUUID();
|
||||
|
||||
void setUnverifiedUUID(UUID uuid);
|
||||
|
||||
void setVerifiedUUID(UUID uuid);
|
||||
|
||||
void sendPacket(Object packet, boolean immediately);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user