数据 API
Sponge 提供了一套统一的数据 API 旨在提供一致的方式访问和修改数据。“数据”,在这里指的是所有始终保持客户端和服务端的同步的数据,可以在服务端被更改,然后同步到所有已连接的客户端内。这些数据包括但远远不限于,一块木牌上的文字、一匹马的外貌、和任何有生命的实体的生命值。
尽管其他的 API 通过继承和接口的方式去访问和修改数据(比如一个 LivingEntity
提供对于当前生命值和最大生命值的 Getter 和 Setter 来访问和修改),然而在 Sponge 中,每一个实体、方块等,都不能直接地看出其拥有什么数据。和直接了当地获取数据相比,这可能并不那么直观,但是其强大的可扩展性却是非常重要的。由于增加了 Key,访问特定的数据还是那么简单。
小技巧
如果这套数据 API 中有和你预期不一致的行为(例如在本应返回有意义数据的地方返回了空 Optional
),或你需要的数据这套 API 中没有,请前往实现追踪器查询,亦可前往 esper.net 的 #spongedev
频道、Sponge 论坛或 Sponge Discord 服务器的 #dev
频道询问有关开发者。
概念
如果你第一次接触数据 API 的文档,可能已经被多如牛毛的接口(Interface)和包(Package)吓得喘不过气了。不过如果只是想要使用数据 API,你并不需要完全理解它们,因为大部分的接口只是用于操纵特定的数据。
索引类型(CatalogType)
索引类型 代表在特定上下文中有意义的数据。一些索引类型我们早已耳熟能详,比如说 BlockType 、 EntityType 、以及 EntityType 等。
数据访问器(DataHolder)
一个数据访问器其实仅仅是——用于读写数据的一个东西。它提供了一些方法用于检索和设置数据。接口本身和其存储的数据类型一点关系都没有。因为只有实现才关系到存储的数据类型,所以访问一个其根本没有存在的数据,或者设置一个其根本无法使用的数据,在 DataHolder 身上是完全有可能的。在这些情况下,返回值便会提供对于数据不可读(通过 Optional.empty()
)或者不可写(通过 DataTransactionResult )的信息。
属性名
一个属性也是数据,但并不在客户端和服务端之间同步。因此,对其的修改只能在客户端和服务端进行。因为 Sponge 并不打算提供一个客户端,所以属性均是不可修改(Not Modifiable)的。一些属性的示例有:工具的采掘等级(Harvesting Ability,以 HarvestingProperty 的形式存在)、盔甲的伤害吸收等级(Damage Absorption,以 DamageAbsorptionProperty 的形式存在)等。
数据操纵器(DataManipulator)
一个数据操纵器表示描述特定数据的内聚的数据点。比如 HealthData 同时包含了当前生命值和最大生命值两个数据。如果一个数据访问器(DataHolder)拥有 HealthData
,那么它就有着生命值,这一生命值可以,不管以什么样的方式,被扣除或者补充,同时在生命值为零时死亡。通过这样的组合,可以有效地防止多余的方法定义。比如羊、染色玻璃、以及皮革盔甲都拥有着 DyeableData 表示其被染的颜色。
键
一个数据键是单个数据的唯一标识符,被用于直接获取或者设置数据而无需使用较为复杂的数据操纵器(DataManipulator)。它被设计为提供类似于 Getter 或者 Setter 的方式访问数据。 Keys 工具类以常量的形式包含了在 Sponge 中使用的所有数据键。
数据值(Value)
在数据 API 中,一个数据键(Key)对应的数据值是一个被包装起来的对象。在本文档中,将会使用“数据值”一词,以防止和实际值混淆。一个数据值封装了一个实际值(如果有的话),一个默认值(在实际值未定义时使用),和对应的数据键。