use of net.minecraft.world.level.block.Block 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.world.level.block.Block in project MinecraftForge by MinecraftForge.
the class FluidUtil method tryPickUpFluid.
/**
* Attempts to pick up a fluid in the world and put it in an empty container item.
*
* @param emptyContainer The empty container to fill.
* Will not be modified directly, if modifications are necessary a modified copy is returned in the result.
* @param playerIn The player filling the container. Optional.
* @param worldIn The world the fluid is in.
* @param pos The position of the fluid in the world.
* @param side The side of the fluid that is being drained.
* @return a {@link FluidActionResult} holding the result and the resulting container.
*/
@Nonnull
public static FluidActionResult tryPickUpFluid(@Nonnull ItemStack emptyContainer, @Nullable Player playerIn, Level worldIn, BlockPos pos, Direction side) {
if (emptyContainer.isEmpty() || worldIn == null || pos == null) {
return FluidActionResult.FAILURE;
}
BlockState state = worldIn.getBlockState(pos);
Block block = state.getBlock();
IFluidHandler targetFluidHandler;
if (block instanceof IFluidBlock) {
targetFluidHandler = new FluidBlockWrapper((IFluidBlock) block, worldIn, pos);
} else if (block instanceof BucketPickup) {
targetFluidHandler = new BucketPickupHandlerWrapper((BucketPickup) block, worldIn, pos);
} else {
Optional<IFluidHandler> fluidHandler = getFluidHandler(worldIn, pos, side).resolve();
if (!fluidHandler.isPresent()) {
return FluidActionResult.FAILURE;
}
targetFluidHandler = fluidHandler.get();
}
return tryFillContainer(emptyContainer, targetFluidHandler, Integer.MAX_VALUE, playerIn, true);
}
use of net.minecraft.world.level.block.Block in project MinecraftForge by MinecraftForge.
the class ForgeItemTagsProvider method copyColored.
private void copyColored(Tag.Named<Block> blockGroup, Tag.Named<Item> itemGroup) {
String blockPre = blockGroup.getName().getPath().toUpperCase(Locale.ENGLISH) + '_';
String itemPre = itemGroup.getName().getPath().toUpperCase(Locale.ENGLISH) + '_';
for (DyeColor color : DyeColor.values()) {
Tag.Named<Block> from = getForgeBlockTag(blockPre + color.getName());
Tag.Named<Item> to = getForgeItemTag(itemPre + color.getName());
copy(from, to);
}
copy(getForgeBlockTag(blockPre + "colorless"), getForgeItemTag(itemPre + "colorless"));
}
use of net.minecraft.world.level.block.Block in project MinecraftForge by MinecraftForge.
the class RegistryCodecTest method commonSetup.
public void commonSetup(final FMLCommonSetupEvent event) {
// Create our Json to decode
JsonObject json = new JsonObject();
json.addProperty("block", "minecraft:diamond_block");
json.addProperty("item", "minecraft:diamond_pickaxe");
// Decode our Json and log an info in case of success or a warning in case of error
DataResult<Pair<Pair<Block, Item>, JsonElement>> result = CODEC.decode(JsonOps.INSTANCE, json);
result.resultOrPartial(LOGGER::warn).ifPresent(pair -> LOGGER.info("Successfully decoded a diamond block and a diamond pickaxe from json to Block/Item"));
// Create a Pair<Block, Item> to test the serialization of our codec
Pair<Block, Item> pair = Pair.of(Blocks.DIAMOND_BLOCK, Items.DIAMOND_PICKAXE);
// Serialize the Pair to NBT, and log an info in case of success or a warning in case of error
DataResult<Tag> result2 = CODEC.encodeStart(NbtOps.INSTANCE, pair);
result2.resultOrPartial(LOGGER::warn).ifPresent(tag -> LOGGER.info("Successfully encoded a Pair<Block, Item> to a nbt tag: {}", tag));
// Serialize the Pair to JSON using the COMPRESSED JsonOps, this will use the int registry id instead of the ResourceLocation one,
// This is not recommended because int IDs can change, so you should not rely on them
DataResult<JsonElement> result3 = CODEC.encodeStart(JsonOps.COMPRESSED, pair);
result3.resultOrPartial(LOGGER::warn).ifPresent(compressedJson -> LOGGER.info("Successfully encoded a Pair<Block, Item> to a compressed json: {}", compressedJson));
// Create a json to decode using numerical IDs, to be decoded by JsonOps.COMPRESSED
JsonArray jsonCompressed = new JsonArray();
jsonCompressed.add(((ForgeRegistry<Block>) ForgeRegistries.BLOCKS).getID(Blocks.DIAMOND_BLOCK));
jsonCompressed.add(((ForgeRegistry<Item>) ForgeRegistries.ITEMS).getID(Items.DIAMOND_PICKAXE));
// Decode a compressed json to the corresponding Pair<Block, Item>, this time using Codec#parse
DataResult<Pair<Block, Item>> result4 = CODEC.parse(JsonOps.COMPRESSED, jsonCompressed);
result4.resultOrPartial(LOGGER::warn).ifPresent(pair2 -> LOGGER.info("Successfully decoded a diamond block and a diamond pickaxe from compressed json to Block/Item"));
}
use of net.minecraft.world.level.block.Block in project Denizen-For-Bukkit by DenizenScript.
the class PacketHelperImpl method showBlockAction.
@Override
public void showBlockAction(Player player, Location location, int action, int state) {
BlockPos position = new BlockPos(location.getX(), location.getY(), location.getZ());
Block block = ((CraftWorld) location.getWorld()).getHandle().getBlockState(position).getBlock();
send(player, new ClientboundBlockEventPacket(position, block, action, state));
}
Aggregations