mcpField
R
roblox-text-chat

roblox-text-chat

github.com/el4cteo开发54460 次安装2 周前更新
代码仓库

关于 roblox-text-chat

面向 Roblox 开发者的聊天与文本安全技能,指导使用 TextChatService、在服务器端过滤玩家撰写的文本、检查隐私设置、配置自定义频道,以及按玩家应用政策限制。

主要功能

  1. 01TextChatService 聊天配置
  2. 02服务器端文本过滤
  3. 03隐私与消息投递控制
  4. 04自定义频道配置
  5. 05玩家政策限制检查
  6. 06Quick Words 使用指引

适用场景

  1. 01展示玩家书写的告示前先进行过滤
  2. 02创建团队、派对或近距离频道
  3. 03在私聊中应用隐私检查
  4. 04依据玩家政策限制付费物品或链接

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/el4cteo/roblox-skills --skill roblox-text-chat

安装后在 Claude Code 中输入/roblox-text-chat确认已加载。

附带文件references/chat-recipes.md

详细介绍

聊天与文本安全

不可妥协的规则(Roblox 社区标准)

  1. 玩家之间的对话必须通过 TextChatService TextChannel 进行(它会处理过滤、隐私和家长设置,以及滥用举报)。旧版 Chat 服务和 ChatService Lua 模块已不再使用——TextChatService 是唯一的聊天系统。
  2. 任何由一名玩家编写、并展示给另一名玩家的文本(宠物名称、标牌、公会名称、交易备注、自定义 UI)都必须先在服务器上通过 TextService:FilterStringAsync 过滤,然后才能显示;之后从 DataStore 加载时也必须重新过滤。
  3. 其他人可见的可编辑文本(标牌、公告板)需要设置至少 1 分钟的速率限制。
  4. 通过 CanUserChatAsync/CanUsersChatAsync/CanUsersDirectChatAsync 遵守隐私设置,并使用 TextChannel:SetDirectChatRequester() 标记私信频道。

不属于聊天的内容(无需过滤):自己的 UI 文本、游戏状态消息、由你撰写的管理员公告。

过滤玩家编写的文本

--!strict
local TextService = game:GetService("TextService")

-- Broadcast (e.g. a sign everyone sees). Returns nil if filtering failed: then show nothing.
local function filterForEveryone(text: string, fromUserId: number): string?
	local ok, result = pcall(function()
		local filterResult = TextService:FilterStringAsync(text, fromUserId, Enum.TextFilterContext.PublicChat)
		return filterResult:GetNonChatStringForBroadcastAsync()
	end)
	return if ok then result else nil
end

-- Per-recipient (respects each viewer's age/settings; e.g. a private note).
local function filterForUser(text: string, fromUserId: number, toUserId: number): string?
	local ok, result = pcall(function()
		local filterResult = TextService:FilterStringAsync(text, fromUserId, Enum.TextFilterContext.PrivateChat)
		return filterResult:GetNonChatStringForUserAsync(toUserId)
	end)
	return if ok then result else nil
end

return { forEveryone = filterForEveryone, forUser = filterForUser }
  • 在玩家提交后于服务器上进行过滤(而不是逐次击键时);先执行速率限制并限制文本长度。
  • 过滤失败时,默认拒绝(不显示任何内容或显示占位符),绝不显示未过滤的原始文本。
  • 如有需要,可以存储原始文本,但显示时始终要过滤(过滤规则和查看者设置可能会变化)。
  • 纯数字或较短的字符串也可能被过滤(显示为井号 ###);设计 UI 时要考虑这一点。

TextChatService 要点

  • 默认行为:CreateDefaultTextChannels 会创建 RBXGeneral 和 RBXSystem;CreateDefaultCommands 会添加内置命令(/whisper、/team、/mute 等)。使用 ChatWindowConfiguration、ChatInputBarConfiguration、BubbleChatConfiguration 配置外观(也可以禁用这些功能,并使用 TextChannel:SendAsync 和 TextChatService.MessageReceived 构建自己的 UI)。
  • 流程:客户端调用 TextChannel:SendAsync(text) → 服务器对每位接收者调用 TextChannel.ShouldDeliverCallback(message, textSource) → 过滤 → 客户端的 OnIncomingMessage 回调 → 显示。
  • 回调不得让出执行。ShouldDeliverCallback 仅限服务器端;TextChatService.OnIncomingMessage 和 TextChannel.OnIncomingMessage 仅限客户端(用于格式化)。
  • 系统消息:在客户端调用 channel:DisplaySystemMessage(text)(仅本地显示)。
  • 自定义频道(团队、队伍、近距离):在服务器上于 TextChatService 下创建 TextChannel,通过 channel:AddUserAsync(userId) 添加成员;检查返回的 TextSource 的 CanSend。
--!strict
-- Client: chat tags and colors via OnIncomingMessage (formatting only; never yields).
local Players = game:GetService("Players")
local TextChatService = game:GetService("TextChatService")

TextChatService.OnIncomingMessage = function(message: TextChatMessage)
	local properties = Instance.new("TextChatMessageProperties")
	local source = message.TextSource
	if source then
		local player = Players:GetPlayerByUserId(source.UserId)
		if player and player:GetAttribute("VIP") then
			properties.PrefixText = `<font color="#F5CD30">[VIP]</font> {message.PrefixText}`
		end
	end
	return properties
end
--!strict
-- Server: a /spawn command, restricted to admins.
local Players = game:GetService("Players")
local TextChatService = game:GetService("TextChatService")

local ADMINS: { [number]: boolean } = { [123456] = true }

local command = Instance.new("TextChatCommand")
command.Name = "SpawnCommand"
command.PrimaryAlias = "/spawn"
command.Parent = TextChatService

command.Triggered:Connect(function(source: TextSource, unfilteredText: string)
	if not ADMINS[source.UserId] then
		return
	end
	local player = Players:GetPlayerByUserId(source.UserId)
	print(`{player and player.Name} ran: {unfilteredText}`)
end)

更多内容:近距离聊天、团队频道、自定义 UI,以及从旧版聊天迁移: references/chat-recipes.md。

Quick Words(适合所有年龄段的预设安全短语,可在自由聊天受限时用于协调):在 Creator Hub → 游戏 → Configure → Chat → Quick Words 中添加游戏专属短语——最多可设置 3 个类别,每个类别包含 3–10 条短语;短语使用英语(自动翻译),上线前会经过审核。它们会替换默认类别;General 保持不变。

PolicyService(按用户限制)

PolicyService:GetPolicyInfoForPlayerAsync(player)(在服务器上通过 pcall 调用)会返回 ArePaidRandomItemsRestricted、IsPaidItemTradingAllowed、AreAdsAllowed、AllowedExternalLinkReferences、IsSubjectToChinaPolicies、IsContentSharingAllowed 等标志。根据每位玩家的限制,控制战利品箱、交易、广告和指向社交媒体的链接(只显示 AllowedExternalLinkReferences 中列出的平台)。

相关技能

roblox-security(速率限制、验证)、roblox-ui(文本输入 UI)、roblox-monetization(付费随机物品)、roblox-data-stores(存储用户文本)。

评论

支持 Markdown