FallbackResourceManager.java
net.minecraft.server.packs.resources.FallbackResourceManager
信息
- 全限定名:net.minecraft.server.packs.resources.FallbackResourceManager
- 类型:public class
- 包:net.minecraft.server.packs.resources
- 源码路径:src/main/java/net/minecraft/server/packs/resources/FallbackResourceManager.java
- 起始行号:L31
- 实现:ResourceManager
- 职责:
TODO
字段/常量
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L32 - 说明:
TODO
- 类型:
-
fallbacks- 类型:
List<FallbackResourceManager.PackEntry> - 修饰符:
protected final - 源码定位:
L33 - 说明:
TODO
- 类型:
-
type- 类型:
PackType - 修饰符:
private final - 源码定位:
L34 - 说明:
TODO
- 类型:
-
namespace- 类型:
String - 修饰符:
private final - 源码定位:
L35 - 说明:
TODO
- 类型:
内部类/嵌套类型
-
net.minecraft.server.packs.resources.FallbackResourceManager.ResourceWithSourceAndIndex- 类型:
record - 修饰符:
package-private - 源码定位:
L154 - 说明:
TODO
- 类型:
-
net.minecraft.server.packs.resources.FallbackResourceManager.EntryStack- 类型:
record - 修饰符:
private - 源码定位:
L312 - 说明:
TODO
- 类型:
-
net.minecraft.server.packs.resources.FallbackResourceManager.LeakedResourceWarningInputStream- 类型:
class - 修饰符:
private static - 源码定位:
L323 - 说明:
TODO
- 类型:
-
net.minecraft.server.packs.resources.FallbackResourceManager.PackEntry- 类型:
record - 修饰符:
private - 源码定位:
L353 - 说明:
TODO
- 类型:
-
net.minecraft.server.packs.resources.FallbackResourceManager.ResourceWithSource- 类型:
record - 修饰符:
private - 源码定位:
L365 - 说明:
TODO
- 类型:
构造器
public FallbackResourceManager(PackType type, String namespace) @ L37
- 构造器名:FallbackResourceManager
- 源码定位:L37
- 修饰符:public
参数:
- type: PackType
- namespace: String
说明:
TODO
方法
下面的方法块按源码顺序生成。
public void push(PackResources pack) @ L42
- 方法名:push
- 源码定位:L42
- 返回类型:void
- 修饰符:public
参数:
- pack: PackResources
说明:
TODO
public void push(PackResources pack, Predicate<Identifier> filter) @ L46
- 方法名:push
- 源码定位:L46
- 返回类型:void
- 修饰符:public
参数:
- pack: PackResources
- filter: Predicate
说明:
TODO
public void pushFilterOnly(String name, Predicate<Identifier> filter) @ L50
- 方法名:pushFilterOnly
- 源码定位:L50
- 返回类型:void
- 修饰符:public
参数:
- name: String
- filter: Predicate
说明:
TODO
private void pushInternal(String name, PackResources pack, Predicate<Identifier> contentFilter) @ L54
- 方法名:pushInternal
- 源码定位:L54
- 返回类型:void
- 修饰符:private
参数:
- name: String
- pack: PackResources
- contentFilter: Predicate
说明:
TODO
public Set<String> getNamespaces() @ L58
- 方法名:getNamespaces
- 源码定位:L58
- 返回类型:Set
- 修饰符:public
参数:
- 无
说明:
TODO
public Optional<Resource> getResource(Identifier location) @ L63
- 方法名:getResource
- 源码定位:L63
- 返回类型:Optional
- 修饰符:public
参数:
- location: Identifier
说明:
TODO
private static Resource createResource(PackResources source, Identifier location, IoSupplier<InputStream> resource, IoSupplier<ResourceMetadata> metadata) @ L85
- 方法名:createResource
- 源码定位:L85
- 返回类型:Resource
- 修饰符:private static
参数:
- source: PackResources
- location: Identifier
- resource: IoSupplier
- metadata: IoSupplier
说明:
TODO
private static IoSupplier<InputStream> wrapForDebug(Identifier location, PackResources source, IoSupplier<InputStream> resource) @ L89
- 方法名:wrapForDebug
- 源码定位:L89
- 返回类型:IoSupplier
- 修饰符:private static
参数:
- location: Identifier
- source: PackResources
- resource: IoSupplier
说明:
TODO
public List<Resource> getResourceStack(Identifier location) @ L95
- 方法名:getResourceStack
- 源码定位:L95
- 返回类型:List
- 修饰符:public
参数:
- location: Identifier
说明:
TODO
private static boolean isMetadata(Identifier location) @ L139
- 方法名:isMetadata
- 源码定位:L139
- 返回类型:boolean
- 修饰符:private static
参数:
- location: Identifier
说明:
TODO
private static Identifier getIdentifierFromMetadata(Identifier identifier) @ L143
- 方法名:getIdentifierFromMetadata
- 源码定位:L143
- 返回类型:Identifier
- 修饰符:private static
参数:
- identifier: Identifier
说明:
TODO
private static Identifier getMetadataLocation(Identifier identifier) @ L148
- 方法名:getMetadataLocation
- 源码定位:L148
- 返回类型:Identifier
- 修饰符:private static
参数:
- identifier: Identifier
说明:
TODO
public Map<Identifier,Resource> listResources(String directory, Predicate<Identifier> filter) @ L152
- 方法名:listResources
- 源码定位:L152
- 返回类型:Map<Identifier,Resource>
- 修饰符:public
参数:
- directory: String
- filter: Predicate
说明:
TODO
private IoSupplier<ResourceMetadata> createStackMetadataFinder(Identifier location, int finalPackIndex) @ L196
- 方法名:createStackMetadataFinder
- 源码定位:L196
- 返回类型:IoSupplier
- 修饰符:private
参数:
- location: Identifier
- finalPackIndex: int
说明:
TODO
private static IoSupplier<ResourceMetadata> convertToMetadata(IoSupplier<InputStream> input) @ L219
- 方法名:convertToMetadata
- 源码定位:L219
- 返回类型:IoSupplier
- 修饰符:private static
参数:
- input: IoSupplier
说明:
TODO
private static ResourceMetadata parseMetadata(IoSupplier<InputStream> input) @ L223
- 方法名:parseMetadata
- 源码定位:L223
- 返回类型:ResourceMetadata
- 修饰符:private static
参数:
- input: IoSupplier
说明:
TODO
private static void applyPackFiltersToExistingResources(FallbackResourceManager.PackEntry entry, Map<Identifier,FallbackResourceManager.EntryStack> foundResources) @ L232
- 方法名:applyPackFiltersToExistingResources
- 源码定位:L232
- 返回类型:void
- 修饰符:private static
参数:
- entry: FallbackResourceManager.PackEntry
- foundResources: Map<Identifier,FallbackResourceManager.EntryStack>
说明:
TODO
private void listPackResources(FallbackResourceManager.PackEntry entry, String directory, Predicate<Identifier> filter, Map<Identifier,FallbackResourceManager.EntryStack> foundResources) @ L244
- 方法名:listPackResources
- 源码定位:L244
- 返回类型:void
- 修饰符:private
参数:
- entry: FallbackResourceManager.PackEntry
- directory: String
- filter: Predicate
- foundResources: Map<Identifier,FallbackResourceManager.EntryStack>
说明:
TODO
public Map<Identifier,List<Resource>> listResourceStacks(String directory, Predicate<Identifier> filter) @ L278
- 方法名:listResourceStacks
- 源码定位:L278
- 返回类型:Map<Identifier,List
> - 修饰符:public
参数:
- directory: String
- filter: Predicate
说明:
TODO
public Stream<PackResources> listPacks() @ L307
- 方法名:listPacks
- 源码定位:L307
- 返回类型:Stream
- 修饰符:public
参数:
- 无
说明:
TODO
代码
public class FallbackResourceManager implements ResourceManager {
private static final Logger LOGGER = LogUtils.getLogger();
protected final List<FallbackResourceManager.PackEntry> fallbacks = Lists.newArrayList();
private final PackType type;
private final String namespace;
public FallbackResourceManager(PackType type, String namespace) {
this.type = type;
this.namespace = namespace;
}
public void push(PackResources pack) {
this.pushInternal(pack.packId(), pack, null);
}
public void push(PackResources pack, Predicate<Identifier> filter) {
this.pushInternal(pack.packId(), pack, filter);
}
public void pushFilterOnly(String name, Predicate<Identifier> filter) {
this.pushInternal(name, null, filter);
}
private void pushInternal(String name, @Nullable PackResources pack, @Nullable Predicate<Identifier> contentFilter) {
this.fallbacks.add(new FallbackResourceManager.PackEntry(name, pack, contentFilter));
}
@Override
public Set<String> getNamespaces() {
return ImmutableSet.of(this.namespace);
}
@Override
public Optional<Resource> getResource(Identifier location) {
for (int i = this.fallbacks.size() - 1; i >= 0; i--) {
FallbackResourceManager.PackEntry entry = this.fallbacks.get(i);
PackResources fallback = entry.resources;
if (fallback != null) {
IoSupplier<InputStream> resource = fallback.getResource(this.type, location);
if (resource != null) {
IoSupplier<ResourceMetadata> metadataGetter = this.createStackMetadataFinder(location, i);
return Optional.of(createResource(fallback, location, resource, metadataGetter));
}
}
if (entry.isFiltered(location)) {
LOGGER.warn("Resource {} not found, but was filtered by pack {}", location, entry.name);
return Optional.empty();
}
}
return Optional.empty();
}
private static Resource createResource(PackResources source, Identifier location, IoSupplier<InputStream> resource, IoSupplier<ResourceMetadata> metadata) {
return new Resource(source, wrapForDebug(location, source, resource), metadata);
}
private static IoSupplier<InputStream> wrapForDebug(Identifier location, PackResources source, IoSupplier<InputStream> resource) {
return LOGGER.isDebugEnabled()
? () -> new FallbackResourceManager.LeakedResourceWarningInputStream(resource.get(), location, source.packId())
: resource;
}
@Override
public List<Resource> getResourceStack(Identifier location) {
Identifier metadataLocation = getMetadataLocation(location);
List<Resource> result = new ArrayList<>();
boolean filterMeta = false;
String lastFilterName = null;
for (int i = this.fallbacks.size() - 1; i >= 0; i--) {
FallbackResourceManager.PackEntry entry = this.fallbacks.get(i);
PackResources fileSource = entry.resources;
if (fileSource != null) {
IoSupplier<InputStream> resource = fileSource.getResource(this.type, location);
if (resource != null) {
IoSupplier<ResourceMetadata> metadataGetter;
if (filterMeta) {
metadataGetter = ResourceMetadata.EMPTY_SUPPLIER;
} else {
metadataGetter = () -> {
IoSupplier<InputStream> metaResource = fileSource.getResource(this.type, metadataLocation);
return metaResource != null ? parseMetadata(metaResource) : ResourceMetadata.EMPTY;
};
}
result.add(new Resource(fileSource, resource, metadataGetter));
}
}
if (entry.isFiltered(location)) {
lastFilterName = entry.name;
break;
}
if (entry.isFiltered(metadataLocation)) {
filterMeta = true;
}
}
if (result.isEmpty() && lastFilterName != null) {
LOGGER.warn("Resource {} not found, but was filtered by pack {}", location, lastFilterName);
}
return Lists.reverse(result);
}
private static boolean isMetadata(Identifier location) {
return location.getPath().endsWith(".mcmeta");
}
private static Identifier getIdentifierFromMetadata(Identifier identifier) {
String newPath = identifier.getPath().substring(0, identifier.getPath().length() - ".mcmeta".length());
return identifier.withPath(newPath);
}
private static Identifier getMetadataLocation(Identifier identifier) {
return identifier.withPath(identifier.getPath() + ".mcmeta");
}
@Override
public Map<Identifier, Resource> listResources(String directory, Predicate<Identifier> filter) {
record ResourceWithSourceAndIndex(PackResources packResources, IoSupplier<InputStream> resource, int packIndex) {
}
Map<Identifier, ResourceWithSourceAndIndex> topResourceForFileLocation = new HashMap<>();
Map<Identifier, ResourceWithSourceAndIndex> topResourceForMetaLocation = new HashMap<>();
int packCount = this.fallbacks.size();
for (int i = 0; i < packCount; i++) {
FallbackResourceManager.PackEntry entry = this.fallbacks.get(i);
entry.filterAll(topResourceForFileLocation.keySet());
entry.filterAll(topResourceForMetaLocation.keySet());
PackResources packResources = entry.resources;
if (packResources != null) {
int packIndex = i;
packResources.listResources(this.type, this.namespace, directory, (resource, streamSupplier) -> {
if (isMetadata(resource)) {
if (filter.test(getIdentifierFromMetadata(resource))) {
topResourceForMetaLocation.put(resource, new ResourceWithSourceAndIndex(packResources, streamSupplier, packIndex));
}
} else if (filter.test(resource)) {
topResourceForFileLocation.put(resource, new ResourceWithSourceAndIndex(packResources, streamSupplier, packIndex));
}
});
}
}
Map<Identifier, Resource> result = Maps.newTreeMap();
topResourceForFileLocation.forEach((location, resource) -> {
Identifier metadataLocation = getMetadataLocation(location);
ResourceWithSourceAndIndex metaResource = topResourceForMetaLocation.get(metadataLocation);
IoSupplier<ResourceMetadata> metaGetter;
if (metaResource != null && metaResource.packIndex >= resource.packIndex) {
metaGetter = convertToMetadata(metaResource.resource);
} else {
metaGetter = ResourceMetadata.EMPTY_SUPPLIER;
}
result.put(location, createResource(resource.packResources, location, resource.resource, metaGetter));
});
return result;
}
private IoSupplier<ResourceMetadata> createStackMetadataFinder(Identifier location, int finalPackIndex) {
return () -> {
Identifier metadataLocation = getMetadataLocation(location);
for (int i = this.fallbacks.size() - 1; i >= finalPackIndex; i--) {
FallbackResourceManager.PackEntry entry = this.fallbacks.get(i);
PackResources metadataPackCandidate = entry.resources;
if (metadataPackCandidate != null) {
IoSupplier<InputStream> resource = metadataPackCandidate.getResource(this.type, metadataLocation);
if (resource != null) {
return parseMetadata(resource);
}
}
if (entry.isFiltered(metadataLocation)) {
break;
}
}
return ResourceMetadata.EMPTY;
};
}
private static IoSupplier<ResourceMetadata> convertToMetadata(IoSupplier<InputStream> input) {
return () -> parseMetadata(input);
}
private static ResourceMetadata parseMetadata(IoSupplier<InputStream> input) throws IOException {
ResourceMetadata var2;
try (InputStream metadata = input.get()) {
var2 = ResourceMetadata.fromJsonStream(metadata);
}
return var2;
}
private static void applyPackFiltersToExistingResources(
FallbackResourceManager.PackEntry entry, Map<Identifier, FallbackResourceManager.EntryStack> foundResources
) {
for (FallbackResourceManager.EntryStack e : foundResources.values()) {
if (entry.isFiltered(e.fileLocation)) {
e.fileSources.clear();
} else if (entry.isFiltered(e.metadataLocation())) {
e.metaSources.clear();
}
}
}
private void listPackResources(
FallbackResourceManager.PackEntry entry,
String directory,
Predicate<Identifier> filter,
Map<Identifier, FallbackResourceManager.EntryStack> foundResources
) {
PackResources pack = entry.resources;
if (pack != null) {
pack.listResources(
this.type,
this.namespace,
directory,
(id, resource) -> {
if (isMetadata(id)) {
Identifier actualId = getIdentifierFromMetadata(id);
if (!filter.test(actualId)) {
return;
}
foundResources.computeIfAbsent(actualId, FallbackResourceManager.EntryStack::new).metaSources.put(pack, resource);
} else {
if (!filter.test(id)) {
return;
}
foundResources.computeIfAbsent(id, FallbackResourceManager.EntryStack::new)
.fileSources
.add(new FallbackResourceManager.ResourceWithSource(pack, resource));
}
}
);
}
}
@Override
public Map<Identifier, List<Resource>> listResourceStacks(String directory, Predicate<Identifier> filter) {
Map<Identifier, FallbackResourceManager.EntryStack> foundResources = Maps.newHashMap();
for (FallbackResourceManager.PackEntry entry : this.fallbacks) {
applyPackFiltersToExistingResources(entry, foundResources);
this.listPackResources(entry, directory, filter, foundResources);
}
TreeMap<Identifier, List<Resource>> result = Maps.newTreeMap();
for (FallbackResourceManager.EntryStack entry : foundResources.values()) {
if (!entry.fileSources.isEmpty()) {
List<Resource> resources = new ArrayList<>();
for (FallbackResourceManager.ResourceWithSource stackEntry : entry.fileSources) {
PackResources source = stackEntry.source;
IoSupplier<InputStream> metaSource = entry.metaSources.get(source);
IoSupplier<ResourceMetadata> metaGetter = metaSource != null ? convertToMetadata(metaSource) : ResourceMetadata.EMPTY_SUPPLIER;
resources.add(createResource(source, entry.fileLocation, stackEntry.resource, metaGetter));
}
result.put(entry.fileLocation, resources);
}
}
return result;
}
@Override
public Stream<PackResources> listPacks() {
return this.fallbacks.stream().map(p -> p.resources).filter(Objects::nonNull);
}
private record EntryStack(
Identifier fileLocation,
Identifier metadataLocation,
List<FallbackResourceManager.ResourceWithSource> fileSources,
Map<PackResources, IoSupplier<InputStream>> metaSources
) {
EntryStack(Identifier fileLocation) {
this(fileLocation, FallbackResourceManager.getMetadataLocation(fileLocation), new ArrayList<>(), new Object2ObjectArrayMap<>());
}
}
private static class LeakedResourceWarningInputStream extends FilterInputStream {
private final Supplier<String> message;
private boolean closed;
public LeakedResourceWarningInputStream(InputStream wrapped, Identifier location, String name) {
super(wrapped);
Exception exception = new Exception("Stacktrace");
this.message = () -> {
StringWriter data = new StringWriter();
exception.printStackTrace(new PrintWriter(data));
return "Leaked resource: '" + location + "' loaded from pack: '" + name + "'\n" + data;
};
}
@Override
public void close() throws IOException {
super.close();
this.closed = true;
}
@Override
protected void finalize() throws Throwable {
if (!this.closed) {
FallbackResourceManager.LOGGER.warn("{}", this.message.get());
}
super.finalize();
}
}
private record PackEntry(String name, @Nullable PackResources resources, @Nullable Predicate<Identifier> filter) {
public void filterAll(Collection<Identifier> collection) {
if (this.filter != null) {
collection.removeIf(this.filter);
}
}
public boolean isFiltered(Identifier location) {
return this.filter != null && this.filter.test(location);
}
}
private record ResourceWithSource(PackResources source, IoSupplier<InputStream> resource) {
}
}引用的其他类
-
- 引用位置:
参数/返回值
- 引用位置:
-
- 引用位置:
参数/返回值
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
参数/返回值
- 引用位置:
-
- 引用位置:
构造调用/返回值 - 关联成员:
Resource()
- 引用位置:
-
- 引用位置:
实现
- 引用位置:
-
- 引用位置:
参数/方法调用/返回值 - 关联成员:
ResourceMetadata.fromJsonStream()
- 引用位置: