CachedUserNameToIdResolver.java
net.minecraft.server.players.CachedUserNameToIdResolver
信息
- 全限定名:net.minecraft.server.players.CachedUserNameToIdResolver
- 类型:public class
- 包:net.minecraft.server.players
- 源码路径:src/main/java/net/minecraft/server/players/CachedUserNameToIdResolver.java
- 起始行号:L38
- 实现:UserNameToIdResolver
- 职责:
TODO
字段/常量
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L39 - 说明:
TODO
- 类型:
-
GAMEPROFILES_MRU_LIMIT- 类型:
int - 修饰符:
private static final - 源码定位:
L40 - 说明:
TODO
- 类型:
-
GAMEPROFILES_EXPIRATION_MONTHS- 类型:
int - 修饰符:
private static final - 源码定位:
L41 - 说明:
TODO
- 类型:
-
resolveOfflineUsers- 类型:
boolean - 修饰符:
private - 源码定位:
L42 - 说明:
TODO
- 类型:
-
profilesByName- 类型:
Map<String,CachedUserNameToIdResolver.GameProfileInfo> - 修饰符:
private final - 源码定位:
L43 - 说明:
TODO
- 类型:
-
profilesByUUID- 类型:
Map<UUID,CachedUserNameToIdResolver.GameProfileInfo> - 修饰符:
private final - 源码定位:
L44 - 说明:
TODO
- 类型:
-
profileRepository- 类型:
GameProfileRepository - 修饰符:
private final - 源码定位:
L45 - 说明:
TODO
- 类型:
-
gson- 类型:
Gson - 修饰符:
private final - 源码定位:
L46 - 说明:
TODO
- 类型:
-
file- 类型:
File - 修饰符:
private final - 源码定位:
L47 - 说明:
TODO
- 类型:
-
operationCount- 类型:
AtomicLong - 修饰符:
private final - 源码定位:
L48 - 说明:
TODO
- 类型:
内部类/嵌套类型
net.minecraft.server.players.CachedUserNameToIdResolver.GameProfileInfo- 类型:
class - 修饰符:
private static - 源码定位:
L223 - 说明:
TODO
- 类型:
构造器
public CachedUserNameToIdResolver(GameProfileRepository profileRepository, File file) @ L50
- 构造器名:CachedUserNameToIdResolver
- 源码定位:L50
- 修饰符:public
参数:
- profileRepository: GameProfileRepository
- file: File
说明:
TODO
方法
下面的方法块按源码顺序生成。
private void safeAdd(CachedUserNameToIdResolver.GameProfileInfo profileInfo) @ L56
- 方法名:safeAdd
- 源码定位:L56
- 返回类型:void
- 修饰符:private
参数:
- profileInfo: CachedUserNameToIdResolver.GameProfileInfo
说明:
TODO
private Optional<NameAndId> lookupGameProfile(GameProfileRepository profileRepository, String name) @ L63
- 方法名:lookupGameProfile
- 源码定位:L63
- 返回类型:Optional
- 修饰符:private
参数:
- profileRepository: GameProfileRepository
- name: String
说明:
TODO
private Optional<NameAndId> createUnknownProfile(String name) @ L72
- 方法名:createUnknownProfile
- 源码定位:L72
- 返回类型:Optional
- 修饰符:private
参数:
- name: String
说明:
TODO
public void resolveOfflineUsers(boolean value) @ L76
- 方法名:resolveOfflineUsers
- 源码定位:L76
- 返回类型:void
- 修饰符:public
参数:
- value: boolean
说明:
TODO
public void add(NameAndId nameAndId) @ L81
- 方法名:add
- 源码定位:L81
- 返回类型:void
- 修饰符:public
参数:
- nameAndId: NameAndId
说明:
TODO
private CachedUserNameToIdResolver.GameProfileInfo addInternal(NameAndId profile) @ L86
- 方法名:addInternal
- 源码定位:L86
- 返回类型:CachedUserNameToIdResolver.GameProfileInfo
- 修饰符:private
参数:
- profile: NameAndId
说明:
TODO
private long getNextOperation() @ L97
- 方法名:getNextOperation
- 源码定位:L97
- 返回类型:long
- 修饰符:private
参数:
- 无
说明:
TODO
public Optional<NameAndId> get(String name) @ L101
- 方法名:get
- 源码定位:L101
- 返回类型:Optional
- 修饰符:public
参数:
- name: String
说明:
TODO
public Optional<NameAndId> get(UUID id) @ L134
- 方法名:get
- 源码定位:L134
- 返回类型:Optional
- 修饰符:public
参数:
- id: UUID
说明:
TODO
private static DateFormat createDateFormat() @ L145
- 方法名:createDateFormat
- 源码定位:L145
- 返回类型:DateFormat
- 修饰符:private static
参数:
- 无
说明:
TODO
private List<CachedUserNameToIdResolver.GameProfileInfo> load() @ L149
- 方法名:load
- 源码定位:L149
- 返回类型:List<CachedUserNameToIdResolver.GameProfileInfo>
- 修饰符:private
参数:
- 无
说明:
TODO
public void save() @ L174
- 方法名:save
- 源码定位:L174
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
private Stream<CachedUserNameToIdResolver.GameProfileInfo> getTopMRUProfiles(int limit) @ L187
- 方法名:getTopMRUProfiles
- 源码定位:L187
- 返回类型:Stream<CachedUserNameToIdResolver.GameProfileInfo>
- 修饰符:private
参数:
- limit: int
说明:
TODO
private static JsonElement writeGameProfile(CachedUserNameToIdResolver.GameProfileInfo src, DateFormat dateFormat) @ L194
- 方法名:writeGameProfile
- 源码定位:L194
- 返回类型:JsonElement
- 修饰符:private static
参数:
- src: CachedUserNameToIdResolver.GameProfileInfo
- dateFormat: DateFormat
说明:
TODO
private static Optional<CachedUserNameToIdResolver.GameProfileInfo> readGameProfile(JsonElement json, DateFormat dateFormat) @ L201
- 方法名:readGameProfile
- 源码定位:L201
- 返回类型:Optional<CachedUserNameToIdResolver.GameProfileInfo>
- 修饰符:private static
参数:
- json: JsonElement
- dateFormat: DateFormat
说明:
TODO
代码
public class CachedUserNameToIdResolver implements UserNameToIdResolver {
private static final Logger LOGGER = LogUtils.getLogger();
private static final int GAMEPROFILES_MRU_LIMIT = 1000;
private static final int GAMEPROFILES_EXPIRATION_MONTHS = 1;
private boolean resolveOfflineUsers = true;
private final Map<String, CachedUserNameToIdResolver.GameProfileInfo> profilesByName = new ConcurrentHashMap<>();
private final Map<UUID, CachedUserNameToIdResolver.GameProfileInfo> profilesByUUID = new ConcurrentHashMap<>();
private final GameProfileRepository profileRepository;
private final Gson gson = new GsonBuilder().create();
private final File file;
private final AtomicLong operationCount = new AtomicLong();
public CachedUserNameToIdResolver(GameProfileRepository profileRepository, File file) {
this.profileRepository = profileRepository;
this.file = file;
Lists.reverse(this.load()).forEach(this::safeAdd);
}
private void safeAdd(CachedUserNameToIdResolver.GameProfileInfo profileInfo) {
NameAndId nameAndId = profileInfo.nameAndId();
profileInfo.setLastAccess(this.getNextOperation());
this.profilesByName.put(nameAndId.name().toLowerCase(Locale.ROOT), profileInfo);
this.profilesByUUID.put(nameAndId.id(), profileInfo);
}
private Optional<NameAndId> lookupGameProfile(GameProfileRepository profileRepository, String name) {
if (!StringUtil.isValidPlayerName(name)) {
return this.createUnknownProfile(name);
} else {
Optional<NameAndId> profile = profileRepository.findProfileByName(name).map(NameAndId::new);
return profile.isEmpty() ? this.createUnknownProfile(name) : profile;
}
}
private Optional<NameAndId> createUnknownProfile(String name) {
return this.resolveOfflineUsers ? Optional.of(NameAndId.createOffline(name)) : Optional.empty();
}
@Override
public void resolveOfflineUsers(boolean value) {
this.resolveOfflineUsers = value;
}
@Override
public void add(NameAndId nameAndId) {
this.addInternal(nameAndId);
}
private CachedUserNameToIdResolver.GameProfileInfo addInternal(NameAndId profile) {
Calendar c = Calendar.getInstance(TimeZone.getDefault(), Locale.ROOT);
c.setTime(new Date());
c.add(2, 1);
Date expirationDate = c.getTime();
CachedUserNameToIdResolver.GameProfileInfo profileInfo = new CachedUserNameToIdResolver.GameProfileInfo(profile, expirationDate);
this.safeAdd(profileInfo);
this.save();
return profileInfo;
}
private long getNextOperation() {
return this.operationCount.incrementAndGet();
}
@Override
public Optional<NameAndId> get(String name) {
String userName = name.toLowerCase(Locale.ROOT);
CachedUserNameToIdResolver.GameProfileInfo profileInfo = this.profilesByName.get(userName);
boolean needsSave = false;
if (profileInfo != null && new Date().getTime() >= profileInfo.expirationDate.getTime()) {
this.profilesByUUID.remove(profileInfo.nameAndId().id());
this.profilesByName.remove(profileInfo.nameAndId().name().toLowerCase(Locale.ROOT));
needsSave = true;
profileInfo = null;
}
Optional<NameAndId> result;
if (profileInfo != null) {
profileInfo.setLastAccess(this.getNextOperation());
result = Optional.of(profileInfo.nameAndId());
} else {
Optional<NameAndId> profile = this.lookupGameProfile(this.profileRepository, userName);
if (profile.isPresent()) {
result = Optional.of(this.addInternal(profile.get()).nameAndId());
needsSave = false;
} else {
result = Optional.empty();
}
}
if (needsSave) {
this.save();
}
return result;
}
@Override
public Optional<NameAndId> get(UUID id) {
CachedUserNameToIdResolver.GameProfileInfo profileInfo = this.profilesByUUID.get(id);
if (profileInfo == null) {
return Optional.empty();
} else {
profileInfo.setLastAccess(this.getNextOperation());
return Optional.of(profileInfo.nameAndId());
}
}
private static DateFormat createDateFormat() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z", Locale.ROOT);
}
private List<CachedUserNameToIdResolver.GameProfileInfo> load() {
List<CachedUserNameToIdResolver.GameProfileInfo> result = Lists.newArrayList();
try {
Object var9;
try (Reader reader = Files.newReader(this.file, StandardCharsets.UTF_8)) {
JsonArray entryList = this.gson.fromJson(reader, JsonArray.class);
if (entryList != null) {
DateFormat dateFormat = createDateFormat();
entryList.forEach(element -> readGameProfile(element, dateFormat).ifPresent(result::add));
return result;
}
var9 = result;
}
return (List<CachedUserNameToIdResolver.GameProfileInfo>)var9;
} catch (FileNotFoundException var7) {
} catch (JsonParseException | IOException var8) {
LOGGER.warn("Failed to load profile cache {}", this.file, var8);
}
return result;
}
@Override
public void save() {
JsonArray entryList = new JsonArray();
DateFormat dateFormat = createDateFormat();
this.getTopMRUProfiles(1000).forEach(entry -> entryList.add(writeGameProfile(entry, dateFormat)));
String toSave = this.gson.toJson((JsonElement)entryList);
try (Writer writer = Files.newWriter(this.file, StandardCharsets.UTF_8)) {
writer.write(toSave);
} catch (IOException var9) {
}
}
private Stream<CachedUserNameToIdResolver.GameProfileInfo> getTopMRUProfiles(int limit) {
return ImmutableList.copyOf(this.profilesByUUID.values())
.stream()
.sorted(Comparator.comparing(CachedUserNameToIdResolver.GameProfileInfo::lastAccess).reversed())
.limit(limit);
}
private static JsonElement writeGameProfile(CachedUserNameToIdResolver.GameProfileInfo src, DateFormat dateFormat) {
JsonObject object = new JsonObject();
src.nameAndId().appendTo(object);
object.addProperty("expiresOn", dateFormat.format(src.expirationDate()));
return object;
}
private static Optional<CachedUserNameToIdResolver.GameProfileInfo> readGameProfile(JsonElement json, DateFormat dateFormat) {
if (json.isJsonObject()) {
JsonObject object = json.getAsJsonObject();
NameAndId nameAndId = NameAndId.fromJson(object);
if (nameAndId != null) {
JsonElement expirationElement = object.get("expiresOn");
if (expirationElement != null) {
String dateAsString = expirationElement.getAsString();
try {
Date expirationDate = dateFormat.parse(dateAsString);
return Optional.of(new CachedUserNameToIdResolver.GameProfileInfo(nameAndId, expirationDate));
} catch (ParseException var7) {
LOGGER.warn("Failed to parse date {}", dateAsString, var7);
}
}
}
}
return Optional.empty();
}
private static class GameProfileInfo {
private final NameAndId nameAndId;
private final Date expirationDate;
private volatile long lastAccess;
private GameProfileInfo(NameAndId nameAndId, Date expirationDate) {
this.nameAndId = nameAndId;
this.expirationDate = expirationDate;
}
public NameAndId nameAndId() {
return this.nameAndId;
}
public Date expirationDate() {
return this.expirationDate;
}
public void setLastAccess(long currentOperation) {
this.lastAccess = currentOperation;
}
public long lastAccess() {
return this.lastAccess;
}
}
}引用的其他类
-
- 引用位置:
参数/方法调用/返回值 - 关联成员:
NameAndId.createOffline(), NameAndId.fromJson()
- 引用位置:
-
- 引用位置:
实现
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
StringUtil.isValidPlayerName()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置: