玩家资料管理器

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

通过使用 ProfilePropertyGameProfile 可以用来存储关于玩家的任意数据。但是,这不能用作永久数据存储,因为数据不会在服务器重新启动时保留。我们可以使用 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 用于存储 GameProfileGameProfileCache 。为此,只需调用 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() 的返回值即可。