Jump to content

Error trying to read files from folder outside .jar (1.16.5)


Sedixed

Recommended Posts

Hello there,

We are trying with some friends to create a mod that allows random structures generation. To do so, user puts his structures (.schem) in a Schematics folder, which are then converted to .nbt to get generated. We faced a problem while building the .jar : the ResourceLocation cannot find our structures because they are outside the .jar

We tried the solution exposed in this topic ( 

 ) but the attribute defaultResourcePacks doesnt seem to exist anymore.

Another solution we wanted to try was keeping these .nbt files generated in the .jar, but we don't know how to make them generate inside the .jar (and not inside a folder).

Do you guys have any clue or solution ?

Here is the link to the pastebin from the most recent crash : http://pastebin.fr/107104

And here is the link to our git repo (actually, we are beginners so we don't master git neither java, sorry :c)

Switch to the parsing branch, we didnt merge atm https://github.com/KinderPinGuiin/schematics-in-world/tree/parsing

 

Thanks ! :D

 

Link to comment
Share on other sites

Actually, I tried to do something that looks similar in the mod main class :

 

IResourcePack rp = new FolderPack(assetsDir);
ResourcePackList defaultResourcePacks = null;
defaultResourcePacks = ObfuscationReflectionHelper.getPrivateValue(Minecraft.class, Minecraft.getInstance(), "resourcePackRepository");
defaultResourcePacks.addPackFinder(new FolderPackFinder(assetsDir, IPackNameDecorator.PLAIN));

Here, assetsDir is a File (folder) where we want to locate our files.

I've looked just now at the method AddPackFindersEvent but couldn't find any class having it

Link to comment
Share on other sites

Actually we found (maybe) something that may work, however it doesn't but maybe some of y'all know about this trick :

with event an instance of FMLClientSetupEvent :

 

event.enqueueWork(() -> {
	((SimpleReloadableResourceManager) Minecraft.getInstance().getResourceManager()).addResourcePack(new FolderPack(assetsDir));
});

However, it doesn't seem to do anything..

Link to comment
Share on other sites

No problem, I will try to find where I can find this FMLConstructModEvent or where to create it ! 

 

Edit : I've read the documentation (https://nekoyue.github.io/ForgeJavaDocs-NG/javadoc/1.16.5/net/minecraftforge/fml/event/lifecycle/FMLConstructModEvent.html) and this : https://forge.gemwire.uk/wiki/Stages_of_Modloading
 

If I get it right, this event is called when the constructor of our mod is called ? So should I register this thing in the constructor ?

Edited by Sedixed
Link to comment
Share on other sites

So if I get it, I would have to create a method like this in the mod constructor :

private void registerTheThing(final FMLConstructModEvent event)
    {

        event.enqueueWork(() -> {
           // Here we add the FolderPack
        });
    }

and then register it in the modEventBus like that

modEventBus.addListener(this::registerTheThing);

Something like that ? :D

Link to comment
Share on other sites

Well after a few tries, modifying our paths, it still doesn't work and I cant figure why..

We are trying to define our folder assets/resources (located in the run directory) as a resource directory but it doesn't seem to work.

@SubscribeEvent
    public void initConstruct(FMLConstructModEvent event){
        System.out.println("Hello there");
        event.enqueueWork(() -> {
            ((SimpleReloadableResourceManager) Minecraft.getInstance().getResourceManager()).addResourcePack(new FolderPack(new File("./assets/resources")));
        });
    }

However, "Hello there" is printed so the method is correctly called.

https://drive.google.com/file/d/1bArAV6w4UJw1rBbfD7aSvA-uuaREdvQv/view?usp=sharing
Here is a link to an image of our file architecture, maybe it could help :/

Link to comment
Share on other sites

We found a way to escape the exception (by adding a conditional around the logger), we can then get into the world, and when using the /locate our structures are available (auto-completion), but that's all : it seems that the structures aren't even generated now ! 

 

Here is the link for the screenshot of the result of /locate : https://drive.google.com/file/d/1P9bso9rTcZAngd3oeVI0Apfw8sCREGI2/view?usp=sharing

Here is our method for structure generation : (the NETHER biome test is only for Nether generation, it doesn't affect the overall generation)

@Override // GeneratePieces
public void func_230364_a_(DynamicRegistries dynamicRegistryManager, ChunkGenerator chunkGenerator,
                           TemplateManager templateManagerIn, int chunkX, int chunkZ, Biome biomeIn,
                           NoFeatureConfig config) {
    int x = (chunkX << 4) + 8;
    int z = (chunkZ << 4) + 8;


    BlockPos blockpos;
    if (biomeIn.getCategory().toString().equals("NETHER")) {
        int y = getLowestLand(chunkGenerator, x, z).getY();
        blockpos = new BlockPos(x, structureHigh() - y + 1, z);
    } else {
        blockpos = new BlockPos(x, structureHigh(), z);
    }

    try {
        JigsawManager.func_242837_a(dynamicRegistryManager,
                new VillageConfig(() -> dynamicRegistryManager.getRegistry(Registry.JIGSAW_POOL_KEY)
                        .getOrDefault(new ResourceLocation(SchematicsInWorld.MOD_ID,
                                name() + "/" + name() + "_pool")),
                        10), AbstractVillagePiece::new, chunkGenerator, templateManagerIn,
                blockpos, this.components, this.rand, false, true);
    } catch (NullPointerException e) {
        // First launch after adding structures
    }


    this.components.forEach(piece -> piece.offset(0, 1, 0));
    this.components.forEach(piece -> piece.getBoundingBox().minY -= 1);

    this.recalculateStructureSize();

    if (this.components.size() > 0) {
        LogManager.getLogger().log(Level.DEBUG, name() +" at " +
                this.components.get(0).getBoundingBox().minX + " " +
                this.components.get(0).getBoundingBox().minY + " " +
                this.components.get(0).getBoundingBox().minZ);
    }
}

 

Edited by Sedixed
Link to comment
Share on other sites

Well, if you run the client a run directory will be created, you can then provide some schematics in the run/Schematics folder and rerun the mod. In this case it'll work. Here are some schematics files if you want (https://drive.google.com/drive/folders/1uy-x40n5nLCgfYoEZIQLnWmF9UvIuDUT?usp=sharing)

But if you try to build the mod with ./gradlew build, and run Minecraft, it'll not generate the structures because resources are outside the .jar file.

PS : In the build case, you need to put the schematics in .minecraft/schematics folder

Edited by KinderPinGuiin
Link to comment
Share on other sites

Sorry we messed up with our commits in the urge xd

 

We use only git in command-line.

And actually we found a sort of fix for our problem, using a script to regenerate our JAR using an extern resources folder.

Anyway thanks for the help ! :D

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.