本文章转载自github.com
本页面用于分享对制作Among Us模组以及在Innersloth的《Among Us》后端上运行模组可能有用的技术信息。
有关Innersloth的模组政策,请参阅:https://www.innersloth.com/among-us-mod-policy/
有关模组制作的咨询,请联系:modding@innersloth.com
Innersloth不官方支持模组,并可能随时更改要求或限制,尤其是在为了增强安全性或保护玩家而需要更改时!
模组分类
从使用Innersloth后端的模组角度来看,模组主要分为两大类,Innersloth的服务器会对它们进行不同处理。
1 – 仅主机模组 (Host-only Mods)
这类模组只需要主机(房主)的客户端安装了模组即可运行,依赖主机对游戏状态的控制权来实现模组功能。虽然附加功能有限,但提高了未安装模组的用户的可访问性。
2 – 全客户端模组 (All-client Mods)
这类模组需要连接到房间的所有客户端都安装了相同的模组才能运行。这为修改游戏行为提供了更大的自由度,代价是降低了未安装模组用户的可访问性。
模组注册 / 标识
通过向托管你模组房间的《Among Us》游戏服务器注册你的模组,你的模组房间在状态控制和验证方面将获得特殊处理。
仅主机模组注册:+25 模组标志 (Modded Flag)
仅适用于仅主机模组
《Among Us》客户端包含一个 int32 类型的网络版本号,我们称之为协议版本。将此版本号加上 25,即可为房间启用“主机权威模式”。
在“主机权威模式”下,原本由服务器拥有权威的大多数《Among Us》游戏玩法功能将切换为由主机拥有权威。这允许主机掌控各种游戏玩法功能的结果,从而能够改变游戏的行为。
限制
主机并未获得所有状态的权威,例如与用户数据或玩家保护相关的状态。
虽然反作弊措施有所放宽,但不能保证在所有情况下都被关闭。
速率限制和其他安全保护措施可能仍然适用。
全客户端模组:客户端标识
仅适用于全客户端模组
内侧洛斯很高兴推出《Among Us》模组客户端标识(AU MCI)工具。AU MCI 工具使模组社区能够(通过选择加入的方式)声明他们的模组作为游戏主机处理流程的一部分,并获得如下功能:
一个房间搜索功能,可以专门查找运行相同模组的游戏。
未安装模组的客户端无法加入的房间。
针对反作弊措施的特定豁免。
虽然我们不官方提供对模组的技术支持(请参阅我们的模组政策:https://www.innersloth.com/among-us-mod-policy/),但我们希望为模组社区提供更好的透明度和洞察力,同时加强非模组游戏中的反作弊措施。
技术摘要
AU MCI 由三个部分组成:
一个自行分配的模组 GUID
一个使用你自己的模组 GUID 托管模组游戏的专用路径
用于根据你自己的模组 GUID 筛选房间的匹配过滤器
下面的代码示例使用 C# 提供,并假设你对修改《Among Us》客户端代码有实际操作的熟悉度。
模组 GUID / UUID
自行分配的模组 GUID 是一个标识工具,供模组制作者将自己的游戏与其他模组区分开来。示例如下:
text
501f405a-7d89-4505-b5a8-f4200c10d625
8afb3cb8-ad33-4fe5-a125-e4741ff116fe
bc634373-dd53-453b-8711-86e4ba3d0c32
72784e1c-13b0-4118-bf01-144b9371c6c4
6ba99692-6f5e-4e46-9774-77704cb595b6
728b931b-badf-46b0-9d7c-90a6bc6ddf0a
b887635f-e35e-42a3-b950-0ebf2b05f9f8
73f2dd39-106c-4422-aa51-0f89f12b42cb这些都是通用的 V4 UUID,你可以在网上如 https://www.uuidgenerator.net/ 等网站获取一个随机生成的模组 GUID。这个 GUID 是我们区分你的模组与其他模组的方式,因此在下面的其他步骤中使用相同的 GUID 非常重要。
托管模组游戏
托管模组游戏需要使用客户端中新的 Tags.HostModdedGame(字节值为 25)标签。在 InnerNetClient 的 HostGame 方法中,将下面这行
msg.StartMessage(Tags.HostGame);
修改为
msg.StartMessage(Tags.HostModdedGame);
接下来,将你的模组 GUID 附加到主机游戏消息中:
csharp
// 标准 HostGame 方法体
MessageWriter msg = MessageWriter.Get(SendOption.Reliable);
msg.StartMessage(Tags.HostModdedGame);
msg.WriteBytesAndSize(this.gameOptionsFactory.ToBytes(settings, AprilFoolsMode.IsAprilFoolsModeToggledOn));
msg.Write(CrossplayMode.GetCrossplayFlags());
filterOpts.Serialize(msg);
// 将你的 GUID 作为字节序列化到消息中
bool guidSucceeded = Guid.TryParse("316e7f61-f150-4ac0-b2cd-7f3cc7225963", out Guid guid); // 示例 GUID
if (!guidSucceeded)
{
Debug.LogError("Whoa guid failed to generate");
return;
}
msg.Write(guid.ToByteArray());
// 标准 HostGame 方法结尾
msg.EndMessage();
this.SendOrDisconnect(msg);
msg.Recycle();这样,我们的游戏服务器和匹配器就能将你模组托管的所有游戏标记为使用相同的模组,并使它们可用于匹配。此时,这些房间将被排除在普通匹配池之外,并且也将获得反作弊系统的豁免。
筛选你自己的模组房间
修改匹配过滤器系统,将允许我们在常规的“寻找游戏”房间搜索界面中提供带有你模组 GUID 的房间。
首先,你需要定义一个匹配过滤器,并将其打包到你的游戏搜索中。重要的是,你上面选择的模组 GUID 需要存在于 AcceptedValues 属性中,并且 FilterType 应对应于字符串值 "mod":
csharp
[Serializable]
public class ModFilter : ISubFilter
{
public Guid AcceptedValues;
public string FilterType { get; } = "mod";
} 然后,在匹配流程中,将一个包含你 GUID 的过滤器添加到现有的过滤器集合中:
csharp
Guid guid = new Guid("316e7f61-f150-4ac0-b2cd-7f3cc7225963");
filterSet.Filters.Add(new GameFilter("mod",
new ModFilter()
{
AcceptedValues = guid,
}));通过添加这些组件,“寻找游戏”界面会告诉我们的匹配器,你是一个带有特定模组 GUID 的模组客户端,正在寻找运行相同模组的其他游戏。
感谢你帮助我们让《Among Us》变得更大更好!如果你有任何问题或疑虑,请参考我们的模组政策或通过 modding@innersloth.com 与我们联系。
常见问题解答
这会取代 +25 模组标志吗?
不会,+25 模组标志是一个独立的选项,它可以将某些服务器权威逻辑更改为主机权威逻辑,常用于仅主机模组。
AU MCI 和 +25 模组标志可以根据模组的需求结合使用。
模组功能
仅主机模组
聊天命令
我们为仅主机模组中的非主机玩家增加了直接向主机发送聊天命令的功能。这使得主机能够利用聊天作为使用特殊能力的方式,来实现具有特殊行为的角色。
任何带有 +25 模组标志的模组都会在其游玩的房间中激活此功能。激活后,当非主机玩家发送以 /cmd 开头的聊天消息时,该聊天消息将仅发送给主机,而不会发送给房间中的任何其他玩家。
使用示例:
一个具有可以猜测谁是内鬼(Impostor)角色的仅主机模组,可能会使用如下格式:
/cmd guess IsThisTheImpostor 1
安装模组的主机可以解析此消息,以理解命令 guess 和怀疑的内鬼名称 IsThisTheImpostor 1,然后可以使用 GameDataTo 响应仅向发出猜测的玩家私下发送聊天消息。