Jump to content

[Solved][1.11.2] Using isRemote before Minecraft.getMinecraft can still cause a crash?


Kriptikz

Recommended Posts

In my code I am trying to stop the player from moving when they are stunned. So using PlayerTickEvent I disable some of the keys used for movement.

Here is the code:

Spoiler

    @SubscribeEvent
    public void onPlayerTick(PlayerTickEvent event)
    {
        if (event.phase == TickEvent.Phase.START)
        {
            EntityPlayer player = event.player;
            IPlayerData playerData = PlayerDataProvider.getPlayerCapability(player);

            // Ensure the code within this if statement is only ran on Client
            if (player.world.isRemote)
            {
                // if this clients player is stunned, increment tickStunned and disable movement
                if (playerData.getIsStunned())
                {
                    playerData.setTicksStunned(playerData.getTicksStunned() + 1);

                    if (playerData.getTicksStunned() < playerData.getStunDuration())
                    {
                        // disable movement
                        KeyBinding.setKeyBindState(Minecraft.getMinecraft().gameSettings.keyBindForward.getKeyCode(), false);
                        KeyBinding.setKeyBindState(Minecraft.getMinecraft().gameSettings.keyBindBack.getKeyCode(), false);
                        KeyBinding.setKeyBindState(Minecraft.getMinecraft().gameSettings.keyBindLeft.getKeyCode(), false);
                        KeyBinding.setKeyBindState(Minecraft.getMinecraft().gameSettings.keyBindRight.getKeyCode(), false);
                    }
                    else
                    {
                        playerData.setIsStunned(false);
                        playerData.setTicksStunned(0);
                    }
                }

                return;
            }
    }

 

 

From what I understand is even if I use world.isRemote before using Minecraft.getMinecraft() this can still cause the server to crash, but it doesn't. I did test it on a dedicated server, but I was still running the server and client on the same computer idk if that affects it.

If using Minecraft.getMinecraft() even after making sure world.isRemote can cause a crash on the server, what's the proper way to go about this? Maybe create a method in my proxy to handle this, where the ServerProxy does nothing and ClientProxy has this code?

Edited by Kriptikz
Link to comment
Share on other sites

The answer is "yes it will." The reason it isn't has to do with the fact that the server isn't even loading your class, which invalidates the test. 

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Why wouldn't the server be loading the class? I do have other methods in this class I just only posted the piece I was wondering about. I also do register this for both client and server I'm pretty sure.

Here is the actual entire class:

Spoiler

public class ModEventHandler
{
    public static Field floatingTickCount = null;
    
    public ModEventHandler()
    {
        try
        {
            floatingTickCount = ReflectionHelper.findField(NetHandlerPlayServer.class, "floatingTickCount");
        } catch (Exception e)
        {
            System.out.println("Unable to find field floatingTickCount");
            e.printStackTrace();
        }
    }
    
	@SubscribeEvent
	public void onLivingEvent(LivingUpdateEvent event)
	{
		if (!event.getEntity().world.isRemote)
		{
			if (event.getEntityLiving() instanceof EntityLiving)
			{
				EntityLiving entity = (EntityLiving) event.getEntityLiving();
				IMobData mobData = MobDataProvider.getMobCapability(entity);
				if (entity.isAIDisabled())
				{
					mobData.setTicksStunned(mobData.getTicksStunned() + 1);
				}
				if (entity.isAIDisabled() && (mobData.getTicksStunned() % mobData.getStunnedDuration() == 0))
				{
					entity.setNoAI(false);
				}
			}
			
			if (event.getEntityLiving() instanceof EntityGhast)
			{

			}
			
			if (event.getEntityLiving() instanceof EntityMob)
			{
				EntityMob mob = (EntityMob) event.getEntityLiving();

				mob.targetTasks.addTask(0, new EntityAINearestAttackableTarget<>(mob, EntityDummyTarget.class, true));
			} 
		}

		
	}
	
	@SubscribeEvent
	public void onPlayerLogin(PlayerLoggedInEvent event)
	{
		EntityPlayer player = event.player;
		IPlayerData playerData = PlayerDataProvider.getPlayerCapability(player);

		MagicMastery.network.sendTo(new MessageSyncAllPlayerData(playerData), (EntityPlayerMP) player);
	}
	
	@SubscribeEvent
	public void onPlayerLoggout(PlayerLoggedOutEvent event)
	{
		
	}

    @SubscribeEvent
    public void onPlayerTick(PlayerTickEvent event)
    {
        if (event.phase == TickEvent.Phase.START)
        {
            EntityPlayer player = event.player;
            IPlayerData playerData = PlayerDataProvider.getPlayerCapability(player);

            // Check if on server and apply levitation code
            if (!player.world.isRemote)
            {
                if (playerData.getIsLevitating())
                {
                    // reset fall distance because technically they are
                    // levitating but minecraft thinks they are falling which
                    // means when they land they would take insane fall damage.
                    player.fallDistance = 0;

                    // prevent the player from getting kicked from the server
                    // for flying while using levitation spell.
                    if (player instanceof EntityPlayerMP)
                    {

                        try
                        {
                            floatingTickCount.setInt(((EntityPlayerMP) player).connection, 0);
                        } catch (IllegalAccessException e)
                        {
                            e.printStackTrace();
                        }

                    }

                    // decrease mana every second.
                    if (player.ticksExisted % 20 == 0)
                    {
                        if (playerData.getMana() - 2 >= 0)
                        {
                            playerData.setMana(playerData.getMana() - 2);
                        }
                        else
                        {
                            playerData.setIsLevitating(false);
                            MagicMastery.network.sendTo(new MessagePlayerIsLevitatingToClient(playerData.getIsLevitating()), (EntityPlayerMP) player);
                        }
                    }

                }
            }

            // Ensure the code within this if statement is only ran on Client
            if (player.world.isRemote)
            {
                if (Keybinds.levitate_down.isKeyDown())
                {
                    playerData.setLevitationAmp(1);
                }
                else if (Keybinds.levitate_up.isKeyDown())
                {
                    playerData.setLevitationAmp(9);
                }
                else
                {
                    playerData.setLevitationAmp(5);
                }

                if (playerData.getIsLevitating())
                {
                    player.motionY += (0.05D * (double) (playerData.getLevitationAmp() + 1) - player.motionY) * 0.2D;
                    player.fallDistance = 0;
                }

                // if this clients player is stunned, increment tickStunned and
                // disable all hotkey other than settings Gui key, open
                // inventory key, and swap items keys
                if (playerData.getIsStunned())
                {
                    playerData.setTicksStunned(playerData.getTicksStunned() + 1);

                    if (playerData.getTicksStunned() < playerData.getStunDuration())
                    {
                        // disable all hotkey other than settings Gui key, open
                        // inventory key, and swap items keys
                        //KeyBinding.unPressAllKeys();
                        KeyBinding.setKeyBindState(Minecraft.getMinecraft().gameSettings.keyBindForward.getKeyCode(), false);
                        KeyBinding.setKeyBindState(Minecraft.getMinecraft().gameSettings.keyBindBack.getKeyCode(), false);
                        KeyBinding.setKeyBindState(Minecraft.getMinecraft().gameSettings.keyBindLeft.getKeyCode(), false);
                        KeyBinding.setKeyBindState(Minecraft.getMinecraft().gameSettings.keyBindRight.getKeyCode(), false);
                        KeyBinding.setKeyBindState(Minecraft.getMinecraft().gameSettings.keyBindJump.getKeyCode(), false);
                        KeyBinding.setKeyBindState(Minecraft.getMinecraft().gameSettings.keyBindInventory.getKeyCode(), false);
                    }
                    else
                    {
                        playerData.setIsStunned(false);
                        playerData.setTicksStunned(0);
                    }
                }

                return;
            }

            // ensure player mana doesn't exceed player max mana every tick.
            // this makes adding mana though items or any other means easier to
            // handle. if any item sets players mana above the players max mana
            // it will be fixed on player tick (almost instantly).
            if (playerData.getMana() > playerData.getMaxMana())
            {
                playerData.setMana(playerData.getMaxMana());
            }

            // sync player mana every 5 ticks
            if (player.ticksExisted % 5 == 0)
            {
                MagicMastery.network.sendTo(new MessageSyncMana(playerData), (EntityPlayerMP) player);
            }

            // regen player mana every second
            if (player.ticksExisted % 20 == 0)
            {
                if ((playerData.getMana() + playerData.getManaRegenPerSecond()) <= playerData.getMaxMana())
                {
                    playerData.setMana(playerData.getMana() + playerData.getManaRegenPerSecond());
                }
            }

            // sync player selected spell to all tracking players every half
            // second.
            if (player.ticksExisted % 10 == 0)
            {
                EntityTracker entityTracker = ((WorldServer) player.world).getEntityTracker();
                entityTracker.sendToTracking(player,
                        MagicMastery.network.getPacketFrom(new MessageSyncSelectedSpellToTrackingClients(playerData.getSelectedSpell(), player)));
            }
        }

    }
}

 

 

Here is the @Mod class:

Spoiler

@Mod(modid = Reference.MODID, name = Reference.NAME, version = Reference.VERSION)
public class MagicMastery
{
	@SidedProxy(serverSide = Reference.SERVER_PROXY_CLASS, clientSide = Reference.CLIENT_PROXY_CLASS)
	public static IProxy proxy;
	
	@Instance(Reference.MODID)
	public static MagicMastery instance;
	
	public static SimpleNetworkWrapper network;
	
	@EventHandler
	public void preInit(FMLPreInitializationEvent event)
	{
		CapabilityManager.INSTANCE.register(IPlayerData.class, new PlayerDataStorage(), PlayerData.class);
		CapabilityManager.INSTANCE.register(IMobData.class, new MobDataStorage(), MobData.class);
		network = NetworkRegistry.INSTANCE.newSimpleChannel(Reference.MODID);
		
		ModMessages.registerMessages();
		ModEntities.init();
		
		proxy.preInit();
	}
	
	@EventHandler
	public void init(FMLInitializationEvent event)
	{
		MinecraftForge.EVENT_BUS.register(new AttachCapabilityHandler());
		MinecraftForge.EVENT_BUS.register(new ModEventHandler());
		
		NetworkRegistry.INSTANCE.registerGuiHandler(instance, new GuiHandler());
		proxy.init();
	}
	
	@EventHandler
	public void postInit(FMLPostInitializationEvent event)
	{
		
		proxy.postInit();
	}	
}

 

 

Link to comment
Share on other sites

2 hours ago, Kriptikz said:

Maybe create a method in my proxy to handle this, where the ServerProxy does nothing and ClientProxy has this code?

This is the proper approach. Create a method in your proxy which returns the Minecraft instance on the Client-side only, then use this in your code after the isRemote check. The Server-side implementation should really throw an exception (since the method must never be called server-side).

Link to comment
Share on other sites

16 hours ago, Kriptikz said:

still no idea why it doesn't crash

You said it yourself up above: You had both server and client running on the same machine, so the client was there to load the Minecraft class. As long as the class is loaded in the JVM, the server can load with a reference to a class that it would not load for itself (because class Minecraft is client side-only).

 

It's probably the most common source of "My mod worked in Eclipse and SP but blew a gasket as soon as I tried it in true MP" threads that run like a rash throughout this help forum. I myself tripped over class Minecraft's client-only restriction in my first mod and found help in threads going back to 1.6.2 and earlier.

 

Someday this forum will have a dynamic FAQ AI that detects that predictable error text in the crash report and sends a stock reply plus an admonition to Google the error message to see the thousands (ok, hundreds) of identical past threads. Until then, each newbie has the privilege of repeating the lore to the next who comes along -- so you're now the officer of the watch, please field the next instance (which will probably come within the next week or two).

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Link to comment
Share on other sites

17 hours ago, Jay Avery said:

Create a method in your proxy which returns the Minecraft instance

Returns? That could lead to the same sort of reference to a missing class. I recommend a proxy method that uses the Minecraft class to do what needs doing client-side (if indeed that's even the best way to design this mod).

 

Looking at that design, it doesn't fit with "proper" client-server purposes. The server is the authority, and the client is the UI. Therefore, if the "stun" effect is to prevent player movement, it should do its work on the server (the authority). It should not hack the keys (or even trust a player to be limited by them). In theory, a devious player could have a second set of movement controls (e.g. a joystick mod) to continue moving, and your server-side would not be enforcing the stun.

 

I hate to say it, but it looks like you should go back to the drawing board and find a hook server side to do what you want.

  • Like 1

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Link to comment
Share on other sites

3 minutes ago, jeffryfisher said:

Looking at that design, it doesn't fit with "proper" client-server purposes. The server is the authority, and the client is the UI. Therefore, if the "stun" effect is to prevent player movement, it should do its work on the server (the authority). It should not hack the keys (or even trust a player to be limited by them). In theory, a devious player could have a second set of movement controls (e.g. a joystick mod) to continue moving, and your server-side would not be enforcing the stun.

Yea I figured this could end up becoming a problem. From what I understand the client is what moves the player and the server validates that movement correct? But yea, back to the drawing board.

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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • the mods are crashing and I'm not sure why so heres everything  crash log https://pastebin.com/RxLKbMNR  L2 Library (12library) has failed to load correctly java.lang.NoClassDefFoundError: org/antarcticgardens/newage/content/energiser/EnergiserBlock L2 Screen Tracker (12screentracker) has failed to load correctly java.lang.NoClassDefFoundError: Could not initialize class dev.xkmc.12library.base.L2Registrate Create: Interiors (interiors) has failed to load correctly java.lang.NoClassDefFoundError: Could not initialize class com.tterrag.registrate.AbstractRegistrate L2 Damage Tracker (12damagetracker) has failed to load correctly java.lang.NoClassDefFoundError: Could not initialize class dev.xkmc.l2library.base.L2Registrate Create Enchantment Industry (create_enchantment_industry) has failed to load correctly java.lang.NoClassDefFoundError: Could not initialize class com.simibubi.create.foundation.data.Createfiegistrate Create Crafts & Additions (createaddition) has failed to load correctly java.lang.NoClassDefFoundError: Could not initialize class com.simibubi.create.foundation.data.CreateRegistrate Create Slice & Dice (sliceanddice) has failed to load correctly java.lang.NoClassDefFoundError: Could not initialize class com.simibubi.create.foundation.data.CreateRegistrate L2 Tabs (12tabs) has failed to load correctly java.lang.NoClassDefFoundError: Could not initialize class dev.xkmc.l2library.base.L2Registrate Modular Golems (modulargolems) has failed to load correctly java.lang.NoClassDefFoundError: Could not initialize class dev.xkmc.l2library.base.L2Registrate Create: Steam 'n' FRails (railways) has failed to load correctly java.lang.NoClassDefFoundError : Could not initialize class com.simibubi.create.foundation.data.Createfregistrate Cuisine Delight (cuisinedelight) has failed to load correctly java.lang.NoClassDefFoundError: Could not initialize class dev.xkmc.12library.base.L2Registrate Create (create) has failed to load correctly java.lang.NoClassDefFoundError: Could not initialize class com.simibubi.create.Create Guardian Beam Defense (creategbd) has failed to load correctly java.lang.NoClassDefFoundError: Could not initialize class com.simibubi.create.foundation.data.CreateRegistrate L2 Item Selector (12itemselector) has failed to load correctly java.lang.NoClassDefFoundError: Could not initialize class dev.xkmc.l2library.base.L2Registrate
    • hey there, I have been using Forge for years without any problems, but for some time now I have been getting this error message when I click on “Installer” under the downloads. This happens on all versions. I have tried various things but have not gotten any results. If anyone has a solution, I would be very grateful!
    • I don't have mcreator installed.
    • the session has expired, what if the modified LAN Server displays the same screen after logging in as after logging in to the premium server from a non-premium account? Minecraft Forge 1.20.1 CurseForge. I also use Mod LAN World Plug n Play
    • Hello There! In today's video I will be showing you guys the Minecraft and Google Collaboration they are doing for the 15th anniversary for Minecraft! If you guys wanna try this out for yourself go to google and type in "Minecraft"!  
  • Topics

×
×
  • Create New...

Important Information

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