Jump to content

Crash caused by forcing PlayerController to break a block


NateKomodo

Recommended Posts

I have the following code (Note it is being run in a separate thread, and the entire thread needs to pause until its done):

public void BreakBlock(boolean enforceRotation){
        Minecraft mc = Minecraft.getMinecraft();
        RayTraceResult result = rayTrace(5);
        int rotation = (int)mc.player.rotationYaw;
        int pitch  = (int)mc.player.rotationPitch;
        try {
            int elapsed = 0;
            while (mc.world.getBlockState(result.getBlockPos()).getMaterial() != Material.AIR && elapsed < 15000) {
                if (enforceRotation) HardSetFacing(rotation, pitch);
                if (mc.playerController.onPlayerDamageBlock(result.getBlockPos(), result.sideHit)) mc.player.swingArm(EnumHand.MAIN_HAND);
                Thread.sleep(40);
                elapsed += 40;
            }
        }
        catch (Exception ex)
        {
            Main.logger.error(ex.getMessage());
        }
    }

However, occasionally, this will lead to the following crash (Game fully crashes and returns to launcher):

[21:55:28] [main/FATAL] [net.minecraft.client.Minecraft]: Unreported exception thrown!
java.util.ConcurrentModificationException: null
	at com.google.common.collect.HashBiMap$Itr.hasNext(HashBiMap.java:401) ~[guava-21.0.jar:?]
	at net.minecraft.client.audio.SoundManager.func_148605_d(SoundManager.java:252) ~[chm.class:?]
	at net.minecraft.client.audio.SoundHandler.func_73660_a(SoundHandler.java:293) ~[cho.class:?]
	at net.minecraft.client.Minecraft.func_71407_l(Minecraft.java:1857) ~[bib.class:?]
	at net.minecraft.client.Minecraft.func_71411_J(Minecraft.java:1097) ~[bib.class:?]
	at net.minecraft.client.Minecraft.func_99999_d(Minecraft.java:397) [bib.class:?]
	at net.minecraft.client.main.Main.main(SourceFile:123) [Main.class:?]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_51]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_51]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_51]
	at java.lang.reflect.Method.invoke(Method.java:497) ~[?:1.8.0_51]
	at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
	at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]

Any thoughts on how to solve this?

Link to comment
Share on other sites

1 minute ago, diesieben07 said:

Minecraft code must be accessed from the main thread only.

Why do you need a separate thread?

As i need to pause execution of my mod until this is done while not blocking the game, i also need to be able to sleep the thread to ensure timing while not blocking the game

Link to comment
Share on other sites

Just now, diesieben07 said:

Do not sleep threads for delays. Count ticks. A tick happens 20 times a second. If you want something to wait for 5 seconds, count to 5x20 = 100.

I'm assuming you mean this in a way similar to the way the java.util timer works. Unfortunately due to the way my codebase is setup, this isnt going to work efficiently. Plus, the while loop in the break block code has a tendency to kill the game if its not threaded.

For the time being i will just write some code for thread cross talk to execute the player controller stuffs on the main thread, seeing as its usually idle at this point, or see if java has an async system similar to .NET

Link to comment
Share on other sites

1 minute ago, NateKomodo said:

I'm assuming you mean this in a way similar to the way the java.util timer works.

Nope that is not what he means. He means use a tick event Such as ClientTickEvent to count ticks until a specified amount has passed. Then do what you need to do like tell the player to break a block.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

4 minutes ago, Animefan8888 said:

Nope that is not what he means. He means use a tick event Such as ClientTickEvent to count ticks until a specified amount has passed. Then do what you need to do like tell the player to break a block.

Yep, im going to move over to the tick event for breaking block and control that via a boolean, seems to be the easiest and most effective solution for my particular situation.

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.