use of net.minecraft.core.Registry in project MinecraftForge by MinecraftForge.
the class ForgeTagHandler method createCustomTagTypeReaders.
/**
* Creates a map for custom tag type to tag reader
*
* @apiNote Internal: For use by TagManager
*/
public static Map<ResourceLocation, TagLoader<?>> createCustomTagTypeReaders() {
LOGGER.debug("Gathering custom tag collection reader from types.");
ImmutableMap.Builder<ResourceLocation, TagLoader<?>> builder = ImmutableMap.builder();
for (ResourceLocation registryName : customTagTypeNames) {
ForgeRegistry<?> registry = RegistryManager.ACTIVE.getRegistry(registryName);
if (registry != null && registry.getTagFolder() != null) {
builder.put(registryName, new TagLoader<>(rl -> Optional.ofNullable(registry.getValue(rl)), "tags/" + registry.getTagFolder()));
}
}
return builder.build();
}
use of net.minecraft.core.Registry in project MinecraftForge by MinecraftForge.
the class GameData method injectSnapshot.
@SuppressWarnings({ "unchecked", "rawtypes" })
public static Multimap<ResourceLocation, ResourceLocation> injectSnapshot(Map<ResourceLocation, ForgeRegistry.Snapshot> snapshot, boolean injectFrozenData, boolean isLocalWorld) {
LOGGER.info(REGISTRIES, "Injecting existing registry data into this {} instance", EffectiveSide.get());
RegistryManager.ACTIVE.registries.forEach((name, reg) -> reg.validateContent(name));
RegistryManager.ACTIVE.registries.forEach((name, reg) -> reg.dump(name));
RegistryManager.ACTIVE.registries.forEach((name, reg) -> reg.resetDelegates());
// Update legacy names
snapshot = snapshot.entrySet().stream().sorted(// FIXME Registries need dependency ordering, this makes sure blocks are done before items (for ItemCallbacks) but it's lazy as hell
Map.Entry.comparingByKey()).collect(Collectors.toMap(e -> RegistryManager.ACTIVE.updateLegacyName(e.getKey()), Map.Entry::getValue, (k1, k2) -> k1, LinkedHashMap::new));
if (isLocalWorld) {
List<ResourceLocation> missingRegs = snapshot.keySet().stream().filter(name -> !RegistryManager.ACTIVE.registries.containsKey(name)).collect(Collectors.toList());
if (missingRegs.size() > 0) {
String header = "Forge Mod Loader detected missing/unknown registrie(s).\n\n" + "There are " + missingRegs.size() + " missing registries in this save.\n" + "If you continue the missing registries will get removed.\n" + "This may cause issues, it is advised that you create a world backup before continuing.\n\n";
StringBuilder text = new StringBuilder("Missing Registries:\n");
for (ResourceLocation s : missingRegs) text.append(s).append("\n");
LOGGER.warn(REGISTRIES, header);
LOGGER.warn(REGISTRIES, text.toString());
}
}
RegistryManager STAGING = new RegistryManager("STAGING");
final Map<ResourceLocation, Map<ResourceLocation, Integer[]>> remaps = Maps.newHashMap();
final LinkedHashMap<ResourceLocation, Map<ResourceLocation, Integer>> missing = Maps.newLinkedHashMap();
// Load the snapshot into the "STAGING" registry
snapshot.forEach((key, value) -> {
final Class<? extends IForgeRegistryEntry> clazz = RegistryManager.ACTIVE.getSuperType(key);
remaps.put(key, Maps.newLinkedHashMap());
missing.put(key, Maps.newLinkedHashMap());
loadPersistentDataToStagingRegistry(RegistryManager.ACTIVE, STAGING, remaps.get(key), missing.get(key), key, value, clazz);
});
snapshot.forEach((key, value) -> {
value.dummied.forEach(dummy -> {
Map<ResourceLocation, Integer> m = missing.get(key);
ForgeRegistry<?> reg = STAGING.getRegistry(key);
// Currently missing locally, we just inject and carry on
if (m.containsKey(dummy)) {
if (reg.markDummy(dummy, m.get(dummy)))
m.remove(dummy);
} else if (isLocalWorld) {
LOGGER.debug(REGISTRIES, "Registry {}: Resuscitating dummy entry {}", key, dummy);
} else {
// The server believes this is a dummy block identity, but we seem to have one locally. This is likely a conflict
// in mod setup - Mark this entry as a dummy
int id = reg.getID(dummy);
LOGGER.warn(REGISTRIES, "Registry {}: The ID {} @ {} is currently locally mapped - it will be replaced with a dummy for this session", dummy, key, id);
reg.markDummy(dummy, id);
}
});
});
int count = missing.values().stream().mapToInt(Map::size).sum();
if (count > 0) {
LOGGER.debug(REGISTRIES, "There are {} mappings missing - attempting a mod remap", count);
Multimap<ResourceLocation, ResourceLocation> defaulted = ArrayListMultimap.create();
Multimap<ResourceLocation, ResourceLocation> failed = ArrayListMultimap.create();
missing.entrySet().stream().filter(e -> e.getValue().size() > 0).forEach(m -> {
ResourceLocation name = m.getKey();
ForgeRegistry<?> reg = STAGING.getRegistry(name);
RegistryEvent.MissingMappings<?> event = reg.getMissingEvent(name, m.getValue());
MinecraftForge.EVENT_BUS.post(event);
List<MissingMappings.Mapping<?>> lst = event.getAllMappings().stream().filter(e -> e.getAction() == MissingMappings.Action.DEFAULT).sorted((a, b) -> a.toString().compareTo(b.toString())).collect(Collectors.toList());
if (!lst.isEmpty()) {
LOGGER.error(REGISTRIES, () -> LogMessageAdapter.adapt(sb -> {
sb.append("Unidentified mapping from registry ").append(name).append('\n');
lst.stream().sorted().forEach(map -> sb.append('\t').append(map.key).append(": ").append(map.id).append('\n'));
}));
}
event.getAllMappings().stream().filter(e -> e.getAction() == MissingMappings.Action.FAIL).forEach(fail -> failed.put(name, fail.key));
final Class<? extends IForgeRegistryEntry> clazz = RegistryManager.ACTIVE.getSuperType(name);
processMissing(clazz, name, STAGING, event, m.getValue(), remaps.get(name), defaulted.get(name), failed.get(name), !isLocalWorld);
});
if (!defaulted.isEmpty() && !isLocalWorld)
return defaulted;
if (!defaulted.isEmpty()) {
String header = "Forge Mod Loader detected missing registry entries.\n\n" + "There are " + defaulted.size() + " missing entries in this save.\n" + "If you continue the missing entries will get removed.\n" + "A world backup will be automatically created in your saves directory.\n\n";
StringBuilder buf = new StringBuilder();
defaulted.asMap().forEach((name, entries) -> {
buf.append("Missing ").append(name).append(":\n");
entries.stream().sorted((o1, o2) -> o1.compareNamespaced(o2)).forEach(rl -> buf.append(" ").append(rl).append("\n"));
buf.append("\n");
});
LOGGER.warn(REGISTRIES, header);
LOGGER.warn(REGISTRIES, buf.toString());
}
if (!defaulted.isEmpty()) {
if (isLocalWorld)
LOGGER.error(REGISTRIES, "There are unidentified mappings in this world - we are going to attempt to process anyway");
}
}
if (injectFrozenData) {
// If we're loading from disk, we can actually substitute air in the block map for anything that is otherwise "missing". This keeps the reference in the map, in case
// the block comes back later
missing.forEach((name, m) -> {
if (m.isEmpty())
return;
ForgeRegistry<?> reg = STAGING.getRegistry(name);
m.forEach((rl, id) -> reg.markDummy(rl, id));
});
// If we're loading up the world from disk, we want to add in the new data that might have been provisioned by mods
// So we load it from the frozen persistent registry
RegistryManager.ACTIVE.registries.forEach((name, reg) -> {
final Class<? extends IForgeRegistryEntry> clazz = RegistryManager.ACTIVE.getSuperType(name);
loadFrozenDataToStagingRegistry(STAGING, name, remaps.get(name), clazz);
});
}
// Validate that all the STAGING data is good
STAGING.registries.forEach((name, reg) -> reg.validateContent(name));
// Load the STAGING registry into the ACTIVE registry
// for (Map.Entry<ResourceLocation, IForgeRegistry<? extends IForgeRegistryEntry<?>>> r : RegistryManager.ACTIVE.registries.entrySet())
RegistryManager.ACTIVE.registries.forEach((key, value) -> {
final Class<? extends IForgeRegistryEntry> registrySuperType = RegistryManager.ACTIVE.getSuperType(key);
loadRegistry(key, STAGING, RegistryManager.ACTIVE, registrySuperType, true);
});
RegistryManager.ACTIVE.registries.forEach((name, reg) -> {
reg.bake();
// Dump the active registry
reg.dump(name);
});
// Tell mods that the ids have changed
fireRemapEvent(remaps, false);
// The id map changed, ensure we apply object holders
ObjectHolderRegistry.applyObjectHolders();
// Return an empty list, because we're good
return ArrayListMultimap.create();
}
use of net.minecraft.core.Registry in project MinecraftForge by MinecraftForge.
the class DimensionsCommand method register.
static ArgumentBuilder<CommandSourceStack, ?> register() {
return Commands.literal("dimensions").requires(// permission
cs -> cs.hasPermission(0)).executes(ctx -> {
ctx.getSource().sendSuccess(new TranslatableComponent("commands.forge.dimensions.list"), true);
final Registry<DimensionType> reg = ctx.getSource().registryAccess().registryOrThrow(Registry.DIMENSION_TYPE_REGISTRY);
Map<ResourceLocation, List<ResourceLocation>> types = new HashMap<>();
for (ServerLevel dim : ctx.getSource().getServer().getAllLevels()) {
types.computeIfAbsent(reg.getKey(dim.dimensionType()), k -> new ArrayList<>()).add(dim.dimension().location());
}
types.keySet().stream().sorted().forEach(key -> {
ctx.getSource().sendSuccess(new TextComponent(key + ": " + types.get(key).stream().map(ResourceLocation::toString).sorted().collect(Collectors.joining(", "))), false);
});
return 0;
});
}
use of net.minecraft.core.Registry in project SpongeCommon by SpongePowered.
the class LevelChunkMixin_API method biomeStream.
@Override
public VolumeStream<WorldChunk, Biome> biomeStream(final Vector3i min, final Vector3i max, final StreamOptions options) {
VolumeStreamUtils.validateStreamArgs(Objects.requireNonNull(min, "min"), Objects.requireNonNull(max, "max"), Objects.requireNonNull(options, "options"));
final boolean shouldCarbonCopy = options.carbonCopy();
final Vector3i size = max.sub(min).add(1, 1, 1);
@MonotonicNonNull final ObjectArrayMutableBiomeBuffer backingVolume;
if (shouldCarbonCopy) {
final Registry<net.minecraft.world.level.biome.Biome> biomeRegistry = this.level.registryAccess().registry(Registry.BIOME_REGISTRY).map(wr -> ((Registry<net.minecraft.world.level.biome.Biome>) wr)).orElse(BuiltinRegistries.BIOME);
backingVolume = new ObjectArrayMutableBiomeBuffer(min, size, VolumeStreamUtils.nativeToSpongeRegistry(biomeRegistry));
} else {
backingVolume = null;
}
return VolumeStreamUtils.<WorldChunk, Biome, net.minecraft.world.level.biome.Biome, ChunkAccess, BlockPos>generateStream(options, // Ref
(WorldChunk) this, (LevelChunk) (Object) this, // Entity Accessor
VolumeStreamUtils.getBiomesForChunkByPos((LevelReader) (Object) this, min, max), // IdentityFunction
(pos, biome) -> {
if (shouldCarbonCopy) {
backingVolume.setBiome(pos, biome);
}
}, // Biome by block position
(key, biome) -> key, // Filtered Position Entity Accessor
(blockPos, world) -> {
final net.minecraft.world.level.biome.Biome biome = shouldCarbonCopy ? backingVolume.getNativeBiome(blockPos.getX(), blockPos.getY(), blockPos.getZ()) : ((LevelReader) world.world()).getBiome(blockPos);
return new Tuple<>(blockPos, biome);
});
}
use of net.minecraft.core.Registry in project SpongeCommon by SpongePowered.
the class TimingsExport method reportTimings.
/**
* Builds an XML report of the timings to be uploaded for parsing.
*/
static void reportTimings() {
if (TimingsExport.requestingReport.isEmpty()) {
return;
}
TimingsReportListener listeners = new TimingsReportListener(TimingsExport.requestingReport);
TimingsExport.requestingReport.clear();
long now = System.currentTimeMillis();
final long lastReportDiff = now - TimingsExport.lastReport;
if (lastReportDiff < 60000) {
listeners.send(Component.text("Please wait at least 1 minute in between Timings reports. (" + (int) ((60000 - lastReportDiff) / 1000) + " seconds)", NamedTextColor.RED));
listeners.done();
return;
}
final long lastStartDiff = now - TimingsManager.timingStart;
if (lastStartDiff < 180000) {
listeners.send(Component.text("Please wait at least 3 minutes before generating a Timings report. Unlike Timings v1, v2 benefits from longer timings and is not as useful with short timings. (" + (int) ((180000 - lastStartDiff) / 1000) + " seconds)", NamedTextColor.RED));
listeners.done();
return;
}
listeners.send(Component.text("Preparing Timings Report...", NamedTextColor.GREEN));
TimingsExport.lastReport = now;
Platform platform = SpongeCommon.game().platform();
JsonObjectBuilder builder = JSONUtil.objectBuilder().add("version", platform.container(IMPLEMENTATION).metadata().version()).add("maxplayers", SpongeCommon.game().server().maxPlayers()).add("start", TimingsManager.timingStart / 1000).add("end", System.currentTimeMillis() / 1000).add("sampletime", (System.currentTimeMillis() - TimingsManager.timingStart) / 1000);
if (!TimingsManager.privacy) {
builder.add("server", TimingsExport.getServerName()).add("motd", PlainTextComponentSerializer.plainText().serialize(Sponge.server().motd())).add("online-mode", Sponge.server().isOnlineModeEnabled()).add("icon", SpongeCommon.server().getStatus().getFavicon());
}
final Runtime runtime = Runtime.getRuntime();
RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
builder.add("system", JSONUtil.objectBuilder().add("timingcost", TimingsExport.getCost()).add("name", System.getProperty("os.name")).add("version", System.getProperty("os.version")).add("jvmversion", System.getProperty("java.version")).add("arch", System.getProperty("os.arch")).add("maxmem", runtime.maxMemory()).add("cpu", runtime.availableProcessors()).add("runtime", ManagementFactory.getRuntimeMXBean().getUptime()).add("flags", TimingsExport.RUNTIME_FLAG_JOINER.join(runtimeBean.getInputArguments())).add("gc", JSONUtil.mapArrayToObject(ManagementFactory.getGarbageCollectorMXBeans(), (input) -> {
return JSONUtil.singleObjectPair(input.getName(), JSONUtil.arrayOf(input.getCollectionCount(), input.getCollectionTime()));
})));
Set<BlockEntityType> blockEntityTypeSet = Sets.newHashSet();
Set<EntityType<?>> entityTypeSet = Sets.newHashSet();
int size = TimingsManager.HISTORY.size();
TimingHistory[] history = new TimingHistory[size + 1];
int i = 0;
for (TimingHistory timingHistory : TimingsManager.HISTORY) {
blockEntityTypeSet.addAll(timingHistory.tileEntityTypeSet);
entityTypeSet.addAll(timingHistory.entityTypeSet);
history[i++] = timingHistory;
}
// Current snapshot
history[i] = new TimingHistory();
blockEntityTypeSet.addAll(history[i].tileEntityTypeSet);
entityTypeSet.addAll(history[i].entityTypeSet);
JsonObjectBuilder handlersBuilder = JSONUtil.objectBuilder();
for (TimingIdentifier.TimingGroup group : TimingIdentifier.GROUP_MAP.values()) {
for (TimingHandler id : group.handlers) {
if (!id.timed && !id.isSpecial()) {
continue;
}
handlersBuilder.add(id.id, JSONUtil.arrayOf(group.id, id.name));
}
}
builder.add("idmap", JSONUtil.objectBuilder().add("groups", JSONUtil.mapArrayToObject(TimingIdentifier.GROUP_MAP.values(), (group) -> JSONUtil.singleObjectPair(group.id, group.name))).add("handlers", handlersBuilder).add("worlds", JSONUtil.mapArrayToObject(TimingHistory.worldMap.entrySet(), (entry) -> JSONUtil.singleObjectPair(entry.getValue(), entry.getKey()))).add("blockentity", JSONUtil.mapArrayToObject(blockEntityTypeSet, (blockEntityType) -> {
final ResourceKey resourceKey = Sponge.game().registry(RegistryTypes.BLOCK_ENTITY_TYPE).valueKey(blockEntityType);
return JSONUtil.singleObjectPair(TimingsPls.getBlockEntityId(blockEntityType), resourceKey);
})).add("entity", JSONUtil.mapArrayToObject(entityTypeSet, (entityType) -> {
final ResourceKey resourceKey = (ResourceKey) (Object) Registry.ENTITY_TYPE.getKey((net.minecraft.world.entity.EntityType<?>) entityType);
return JSONUtil.singleObjectPair(TimingsPls.getEntityId(entityType), resourceKey);
})));
// Information about loaded plugins
builder.add("plugins", JSONUtil.mapArrayToObject(SpongeCommon.game().pluginManager().plugins(), (plugin) -> {
@Nullable final URL homepageUrl = plugin.metadata().links().homepage().orElse(null);
final String homepage = homepageUrl != null ? homepageUrl.toString() : "<not specified>";
return JSONUtil.objectBuilder().add(plugin.metadata().id(), JSONUtil.objectBuilder().add("version", plugin.metadata().version()).add("description", plugin.metadata().description().orElse("")).add("website", homepage).add("authors", TimingsExport.AUTHOR_LIST_JOINER.join(plugin.metadata().contributors()))).build();
}));
// Information on the users Config
builder.add("config", JSONUtil.objectBuilder().add("sponge", TimingsExport.serializeConfigNode(SpongeConfigs.getCommon().getNode())));
new TimingsExport(listeners, builder.build(), history).start();
}
Aggregations