玩家资料管理器
GameProfile 表示一个玩家的资料,包括诸如名称、UUID、或者其他任意的被称为属性的数据。SpongeAPI 提供了 GameProfileManager 用于获取、创建、并填充 GameProfile
。你可能需要通过下面的代码获取一个 GameProfileManager
的实例:
import org.spongepowered.api.Sponge;
import org.spongepowered.api.profile.GameProfileManager;
GameProfileManager profileManager = Sponge.getServer().getGameProfileManager();
获取 GameProfile
需要注意的很重要的一点是,Sponge 维护着一个 GameProfile
的缓存,用来代替每当请求一个 GameProfile
时向 Mojang API 的请求。我们可以向获取 GameProfile
的方法提供一个 boolean
作为第二个参数来决定是否使用缓存。默认情况下,将尽可能地使用缓存。
可以通过使用 UUID 或者玩家名检索 GameProfile
。当使用 UUID
检索时,将返回相同的配置文件,但玩家的用户名是可以被更改的 ,所以用玩家名检索他们的资料时可能会出现问题。
通过玩家名检索
import org.spongepowered.api.profile.GameProfile;
import java.util.concurrent.CompletableFuture;
CompletableFuture<GameProfile> futureGameProfile = profileManager.get("Notch");
通过 UUID 检索
import java.util.UUID;
CompletableFuture<GameProfile> futureGameProfile =
profileManager.get(UUID.fromString("069a79f4-44e9-4726-a5be-fca90e38aaf5"));
小技巧
你也可以使用 GameProfileManager#getAllById(Iterable<UUID>, boolean) 或 GameProfileManager#getAllByName(Iterable<String>, boolean) 两个方法一次检索很多 GameProfile
。这两种方法都返回 CompletableFuture<Collection<GameProfile>>
。
注意到每个方法都返回的是 CompletableFuture
,也就是说不管是 GameProfile
,还是 Collection<GameProfile>
,都不会立刻从 Mojang API 中获取资料。这段关于 CompletableFuture 的 JavaDoc 解释了整个类的所有功能,虽然我们可能只会用到 get
一个方法。
换句话说,如果你只是想要获取一个 GameProfile
,直接调用 CompletableFuture#get
方法就行了。
GameProfile gameProfile = futureGameProfile.get();
警告
如果 GameProfile
方法不是立等可取,也就是说需要从 Mojang API 中获取,那么 get
方法将一直阻塞住线程直到获取到返回值。因此我们不建议你在服务端的主线程调用该方法。此外,你也可以使用 CompletableFuture#thenAccept(Consumer<? super T>)
方法并传入一个 Consumer
以异步地等待回调。
创建 GameProfile
你可以通过 GameProfile#of(UUID, String) 方法直接手动生成一个 GameProfile
。请注意,用户名不一定需要对应玩家的 UUID
。同样, UUID
也不需要代表一个真实的玩家。
GameProfile gameProfile = GameProfile.of(
UUID.fromString("00000000-0000-0000-0000-000000000000"),
"Herobrine");
注解
GameProfile
的名称是可选的(也就是说传入一个 null
甚至都可以)。
填充 GameProfile 类
通过从 Mojang API 获取诸如玩家的皮肤等信息,我们可以填充一个 GameProfile
。请注意,如果伪造的数据(如玩家名称)与某个 UUID 相关联,则它将被来自 Mojang API 的真实数据替换。
GameProfile filledProfile = profileManager.fill(gameProfile).get();
ProfileProperties
通过使用 ProfileProperty , GameProfile
可以用来存储关于玩家的任意数据。但是,这不能用作永久数据存储,因为数据不会在服务器重新启动时保留。我们可以使用 GameProfile#getPropertyMap() 方法来检索 GameProfile
的所有属性,该方法返回一个 Multimap
。通过这个 Multimap
你可以检索现有的或存储新的 ProfileProperty
,它表现为一个键值对。若要生成一个新的 ProfileProperty
,只需调用 ProfileProperty#of(String, String) 方法。第三个参数(签名)是可选的,然而对于某些属性,你必须要为他们指定 Mojang 的有效签名。
import org.spongepowered.api.profile.property.ProfileProperty;
import java.util.Collection;
profile.getPropertyMap().put(
"key", ProfileProperty.of("foo", "bar", null));
Collection<ProfileProperty> customProperties = profile.getPropertyMap().get("key");
GameProfileCache
你也可以直接访问 Sponge 用于存储 GameProfile
的 GameProfileCache 。为此,只需调用 GameProfileManager#getCache() 方法。通过使用 GameProfileCache
,你可以查找 GameProfile
,添加新的 GameProfile
,并用高速缓存中存储的数据填充配置文件。
import org.spongepowered.api.profile.GameProfileCache;
GameProfile fakeProfile =
GameProfile.of(UUID.fromString("00000000-0000-0000-0000-000000000000"),
"Herobrine");
GameProfileCache cache = profileManager.getCache();
cache.add(profile);
小技巧
GameProfileCache#add(GameProfile) 方法同样接受一个 boolean
作为第二个参数。这将决定旧的缓存是否被覆盖。同时,作为第三个参数的 Date
设置了 GameProfile
的有效期。
如果你已决定,你需要从缓存中删除一个 GameProfile
,你可以调用 GameProfileCache#remove(GameProfile) 方法。如果你需要从缓存中删除所有 GameProfile
,你可以调用 GameProfileCache#clear() 方法。
GameProfileCache
也可以通过 GameProfileManager#setCache(GameProfileCache) 由插件自己设置。如果想要恢复原来的 GameProfileCache
,只需要调用相同的方法,并传入 GameProfileManager#getDefaultCache() 的返回值即可。