Customizable Player Models (Fabric)

Customizable Player Models (Fabric)

287k Downloads

API Usage Issue: Uncaught IOException

JadedChara opened this issue ยท 6 comments

commented

I've inquired about this previously on the Discord (@\Nightstrike), but I keep hitting a bit of a snag. I've been using MCreator with heavy code modification in order to achieve several mechanics for a Transformers mod. Thus far, I've tackled some huge aspects of the progression, given the Scape And Run -inspired theme. Initially, I was going to try and create a new renderer, but the process for that was decidedly tricky to pull off without mixins, something I'm not at all well-versed in, as my specialty is primarily modelling. My code is as follows:

public void execute(RenderPlayerEvent.Pre event) {
		Player player = event.getEntity();
		ResourceLocation resLoc = new ResourceLocation("pentamorph", "cpm/quintessonjuror.cpmproject");
		ResourceManager resman = Minecraft.getInstance().getResourceManager();
		InputStream juror = resman.open(resLoc);
		ModelFile mf = ModelFile.load(juror);
		this.setPlayerModel(Player.class, player, mf,true);
		
	}

It's not ideal, but it was just a quick way to get the player for testing before I bump it over to a command-based procedure that doesn't repeatedly call.

However, the error is as follows:

Executing Gradle task: build
Build info: MCreator 2023.1.10610, forge-1.19.2, 64-bit, 7123 MB, Windows 10, JVM 17.0.5, JAVA_HOME: C:\Program Files\Pylo\MCreator\jdk, started on: 2023-05-22-21:33:11
 
> Configure project :
The code of this workspace uses official obfuscation mappings provided by Mojang. These mappings fall under their associated license you should be fully aware of.
(c) 2020 Microsoft Corporation. These mappings are provided "as-is" and you bear the risk of using them. You may copy and use the mappings for development purposes,
but you may not redistribute the mappings complete and unmodified. Microsoft makes no warranties, express or implied, with respect to the mappings provided here.
Use and modification of this document or the source code (in any form) of Minecraft: Java Edition is governed by the Minecraft End User License Agreement available
at https://account.mojang.com/documents/minecraft_eula.
 
> Task :compileJava
C:\Users\Famil\MCreatorWorkspaces\pentamorph\src\main\java\net\mcreator\pentamorph\procedures\MorphTestProcedure.java:39: error: unreported exception IOException; must be caught or declared to be thrown  InputStream juror = resman.open(resLoc);
      ^
C:\Users\Famil\MCreatorWorkspaces\pentamorph\src\main\java\net\mcreator\pentamorph\procedures\MorphTestProcedure.java:40: error: unreported exception IOException; must be caught or declared to be thrown  ModelFile mf = ModelFile.load(juror);
     ^
2 errors
> Task :compileJava FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':compileJava'.
> Compilation failed; see the compiler error output for details.
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 31s
1 actionable task: 1 executed
 
BUILD FAILED
Task completed in 34 seconds

It seems like the error lies with the file, but honestly, I don't know.
If you need the full stacktrace I can share that, but I was unable to glean anything useful from it.

commented

(After a few days of sleeping for more than 2 hours, and bouncing between a few different projects)

Thank you for the explanation, though to be fair the recommendation for mcjty's content wasn't particularly useful, as I've been messing around since 2020. I had consulted directly with him and he couldn't make heads nor tails of the API, so after about 2 hours of going through the directory here, I did figure out part of the issue, and it was an unrelated thing with how my main mod file got generated, so I ended up rewriting part of that because it would just call the default init. As for the other part, I had no idea 'IMC' was a dedicated thing beyond just dependencies, so that's something else to note for future projects.

I still have a few things to test, but as for the ResourceLocations, weirdly enough MCreator seems to allow that, at least in my experience, but just to be safe, I've made the adjustment.

I'll update this at some later point, but my main issue was just trying to figure out what to do about the ResourceManager lol

Once again, thank you for the assist despite how annoying I probably was about this.

commented

Please learn basic Java!
You have to handle the exception

import java.io.IOException;

public void execute(RenderPlayerEvent.Pre event) {
		Player player = event.getEntity();
		ResourceLocation resLoc = new ResourceLocation("pentamorph", "cpm/quintessonjuror.cpmproject");
		ResourceManager resman = Minecraft.getInstance().getResourceManager();
		try (InputStream juror = resman.open(resLoc)) {
			ModelFile mf = ModelFile.load(juror);
			this.setPlayerModel(Player.class, player, mf,true);
		} catch (IOException e) {
			// Handle the exception or display an error message
			e.printStackTrace();
		}
}
commented

Ouch, but thank you. Never dealt with IOExceptions as I mostly try and bridge stuff between Java and NodeJS since my background's in the latter. My main introduction to Java was a Russian programming supervisor on our robotics team who said error handling was for cowards when I inquired.

I thought I'd have to extend and figure out a way to handle the exception.

Edit: According to the log...

Mixin apply failed cpm.mixins.json:LocalPlayerMixin -> net.minecraft.client.player.LocalPlayer: org.spongepowered.asm.mixin.injection.throwables.InvalidInjectionException Critical injection failure: @Inject annotation on onAiStep could not find any targets matching 'Lnet/minecraft/client/player/LocalPlayer;m_8107_()V' in net.minecraft.client.player.LocalPlayer. Using refmap cpm.mixins.refmap.json [PREINJECT Applicator Phase -> cpm.mixins.json:LocalPlayerMixin -> Prepare Injections ->  -> handler$zzk000$onAiStep(Lorg/spongepowered/asm/mixin/injection/callback/CallbackInfo;)V -> Parse] 
org.spongepowered.asm.mixin.injection.throwables.InvalidInjectionException: Critical injection failure: @Inject annotation on onAiStep could not find any targets matching 'Lnet/minecraft/client/player/LocalPlayer;m_8107_()V' in net.minecraft.client.player.LocalPlayer. Using refmap cpm.mixins.refmap.json [PREINJECT Applicator Phase -> cpm.mixins.json:LocalPlayerMixin -> Prepare Injections ->  -> handler$zzk000$onAiStep(Lorg/spongepowered/asm/mixin/injection/callback/CallbackInfo;)V -> Parse] 

Could it simply be a mapping issue? Or some bug with Blockbench?

commented

Add this to your run configs:

property 'mixin.env.remapRefMap', 'true'
property 'mixin.env.refMapRemappingFile', "${buildDir}/createSrgToMcp/output.srg"

CPM's build.gradle as example
IDK how to do that with MCreator though, ask in their discord or something.

commented

Add this to your run configs:

property 'mixin.env.remapRefMap', 'true'
property 'mixin.env.refMapRemappingFile', "${buildDir}/createSrgToMcp/output.srg"

CPM's build.gradle as example IDK how to do that with MCreator though, ask in their discord or something.

I've added that as per your last recommendation on Discord. It's still just focused on LocalPlayer, so I think it's just something on my end with how I've set it up. I've tested with both RenderPlayerEvent.Pre and OnPlayerLoggedInEvent and both have returned the same issues: The server-side crashing error, and the lack of any rendering. Attempting to open to LAN returns another server crash, with the same error. It could be an issue with how things are handled in MCreator, but as far as I know, MCreator's procedure system is pretty much parallel to the standard event handlers.

In terms of errors, it's primarily pointing towards CPM itself:

21:56.00 [modloading-worker-0/ERROR] [FMLModContainer/LOADING]: Failed to create mod instance. ModID: cpm, class com.tom.cpm.CustomPlayerModels 
java.lang.reflect.InvocationTargetException: null 
   at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:?] {} 
   at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance([NativeConstructorAccessorImpl.java:77](file://jdk.internal.reflect.nativeconstructoraccessorimpl:77/)) ~[?:?] {} 
   at jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance([DelegatingConstructorAccessorImpl.java:45](file://jdk.internal.reflect.delegatingconstructoraccessorimpl:45/)) ~[?:?] {} 
   at java.lang.reflect.Constructor.newInstanceWithCaller([Constructor.java:499](file://java.lang.reflect.constructor:499/)) ~[?:?] {} 
   at java.lang.reflect.Constructor.newInstance([Constructor.java:480](file://java.lang.reflect.constructor:480/)) ~[?:?] {} 
   at net.minecraftforge.fml.javafmlmod.FMLModContainer.constructMod([FMLModContainer.java:68](file://net.minecraftforge.fml.javafmlmod.fmlmodcontainer:68/)) ~[javafmllanguage-1.19.2-43.2.11.jar%23189!/:?] {} 
   at net.minecraftforge.fml.ModContainer.lambda$buildTransitionHandler$10([ModContainer.java:121](file://net.minecraftforge.fml.modcontainer:121/)) ~[fmlcore-1.19.2-43.2.11.jar%23192!/:?] {} 
   at java.util.concurrent.CompletableFuture$AsyncRun.run([CompletableFuture.java:1804](file://java.util.concurrent.completablefuture:1804/)) [?:?] {} 
   at java.util.concurrent.CompletableFuture$AsyncRun.exec([CompletableFuture.java:1796](file://java.util.concurrent.completablefuture:1796/)) [?:?] {} 
   at java.util.concurrent.ForkJoinTask.doExec([ForkJoinTask.java:373](file://java.util.concurrent.forkjointask:373/)) [?:?] {} 
   at java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec([ForkJoinPool.java:1182](file://java.util.concurrent.forkjoinpool:1182/)) [?:?] {} 
   at java.util.concurrent.ForkJoinPool.scan([ForkJoinPool.java:1655](file://java.util.concurrent.forkjoinpool:1655/)) [?:?] {} 
   at java.util.concurrent.ForkJoinPool.runWorker([ForkJoinPool.java:1622](file://java.util.concurrent.forkjoinpool:1622/)) [?:?] {} 
   at java.util.concurrent.ForkJoinWorkerThread.run([ForkJoinWorkerThread.java:165](file://java.util.concurrent.forkjoinworkerthread:165/)) [?:?] {} 
Caused by: java.lang.BootstrapMethodError: java.lang.RuntimeException: Attempted to load class net/minecraft/client/player/LocalPlayer for invalid dist DEDICATED_SERVER 
   at com.tom.cpm.CustomPlayerModels.lambda$new$0([CustomPlayerModels.java:42](file://com.tom.cpm.customplayermodels:42/)) ~[CustomPlayerModels-1.19-0.6.7a_mapped_official_1.19.2.jar%23196!/:0.6.7a] {re:classloading} 
   at net.minecraftforge.fml.DistExecutor.validateSafeReferent([DistExecutor.java:238](file://net.minecraftforge.fml.distexecutor:238/)) ~[fmlcore-1.19.2-43.2.11.jar%23192!/:?] {} 
   at net.minecraftforge.fml.DistExecutor.safeRunWhenOn([DistExecutor.java:121](file://net.minecraftforge.fml.distexecutor:121/)) ~[fmlcore-1.19.2-43.2.11.jar%23192!/:?] {} 
   at com.tom.cpm.CustomPlayerModels.<init>([CustomPlayerModels.java:42](file://com.tom.cpm.customplayermodels:42/)) ~[CustomPlayerModels-1.19-0.6.7a_mapped_official_1.19.2.jar%23196!/:0.6.7a] {re:classloading} 
   ... 14 more 
Caused by: java.lang.RuntimeException: Attempted to load class net/minecraft/client/player/LocalPlayer for invalid dist DEDICATED_SERVER 
   at net.minecraftforge.fml.loading.RuntimeDistCleaner.processClassWithFlags([RuntimeDistCleaner.java:57](file://net.minecraftforge.fml.loading.runtimedistcleaner:57/)) ~[fmlloader-1.19.2-43.2.11.jar:1.0] {} 
   at cpw.mods.modlauncher.LaunchPluginHandler.offerClassNodeToPlugins([LaunchPluginHandler.java:88](file://cpw.mods.modlauncher.launchpluginhandler:88/)) ~[modlauncher-10.0.8.jar:?] {} 
   at cpw.mods.modlauncher.ClassTransformer.transform([ClassTransformer.java:120](file://cpw.mods.modlauncher.classtransformer:120/)) ~[modlauncher-10.0.8.jar:?] {} 
   at cpw.mods.modlauncher.TransformingClassLoader.maybeTransformClassBytes([TransformingClassLoader.java:50](file://cpw.mods.modlauncher.transformingclassloader:50/)) ~[modlauncher-10.0.8.jar:?] {} 
   at cpw.mods.cl.ModuleClassLoader.readerToClass([ModuleClassLoader.java:113](file://cpw.mods.cl.moduleclassloader:113/)) ~[securejarhandler-2.1.4.jar:?] {} 
   at cpw.mods.cl.ModuleClassLoader.lambda$findClass$15([ModuleClassLoader.java:219](file://cpw.mods.cl.moduleclassloader:219/)) ~[securejarhandler-2.1.4.jar:?] {} 
   at cpw.mods.cl.ModuleClassLoader.loadFromModule([ModuleClassLoader.java:229](file://cpw.mods.cl.moduleclassloader:229/)) ~[securejarhandler-2.1.4.jar:?] {} 
   at cpw.mods.cl.ModuleClassLoader.findClass([ModuleClassLoader.java:219](file://cpw.mods.cl.moduleclassloader:219/)) ~[securejarhandler-2.1.4.jar:?] {} 
   at cpw.mods.cl.ModuleClassLoader.loadClass([ModuleClassLoader.java:135](file://cpw.mods.cl.moduleclassloader:135/)) ~[securejarhandler-2.1.4.jar:?] {} 
   at java.lang.ClassLoader.loadClass([ClassLoader.java:520](file://java.lang.classloader:520/)) ~[?:?] {} 
   at com.tom.cpm.CustomPlayerModels.lambda$new$0([CustomPlayerModels.java:42](file://com.tom.cpm.customplayermodels:42/)) ~[CustomPlayerModels-1.19-0.6.7a_mapped_official_1.19.2.jar%23196!/:0.6.7a] {re:classloading} 
   at net.minecraftforge.fml.DistExecutor.validateSafeReferent([DistExecutor.java:238](file://net.minecraftforge.fml.distexecutor:238/)) ~[fmlcore-1.19.2-43.2.11.jar%23192!/:?] {} 
   at net.minecraftforge.fml.DistExecutor.safeRunWhenOn([DistExecutor.java:121](file://net.minecraftforge.fml.distexecutor:121/)) ~[fmlcore-1.19.2-43.2.11.jar%23192!/:?] {} 
   at com.tom.cpm.CustomPlayerModels.<init>([CustomPlayerModels.java:42](file://com.tom.cpm.customplayermodels:42/)) ~[CustomPlayerModels-1.19-0.6.7a_mapped_official_1.19.2.jar%23196!/:0.6.7a] {re:classloading} 
   ... 14 more

It's difficult to parse out the logs because it doesn't give you an option to run the server independent of the client, but this is where the server process just died a miserable death.

Relevant ClientsideProcedure.java file:

package net.mcreator.pentamorph.procedures;

import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.event.entity.player.PlayerEvent;

import javax.annotation.Nullable;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.client.Minecraft;
import net.minecraft.server.packs.resources.ResourceManager;
import com.tom.cpm.shared.io.ModelFile;
import java.io.InputStream;
import java.io.IOException;
import net.minecraft.world.entity.player.Player;
import com.tom.cpm.api.ICommonAPI;
import net.minecraftforge.api.distmarker.Dist;


@Mod.EventBusSubscriber
public abstract class ClientsideProcedure implements ICommonAPI{
	@SubscribeEvent
	public void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) {
		Player player = event.getEntity();
		ResourceLocation resLoc = new ResourceLocation("pentamorph", "cpm/QuintessonJurorCPM.cpmproject");
		ResourceManager resman = Minecraft.getInstance().getResourceManager();
		try(InputStream juror = resman.open(resLoc)){
			ModelFile mf = ModelFile.load(juror);
			this.setPlayerModel(Player.class, player, mf,true);
		}catch(IOException e){
			e.printStackTrace();
		}
	}
}

Like, I've got a lot of speculation as to what could be causing it, and one of the things that's crossed my mind is maybe calling the ResourceManager the way I did inadvertently caused something else, but honestly, I just...don't know.

commented

You have no idea how to write Java code, Learn Java first!
Or any idea how to make a mod for Minecraft.
Please follow a tutorial on creating a simple mod first: https://www.mcjty.eu/docs/1.18/ep1

Don't implement ICommonAPI, read the wiki on how to get an ICommonAPI instance: https://github.com/tom5454/CustomPlayerModels/wiki/API-documentation#create-your-plugin
ICommonAPI won't work on the client either. You have to set the model serverside, where Minecraft.getInstance() will crash.
You can't have Capital letters in ResourceLocations.