Jump to content

INSTANCE.sendToDimension Bug! [Build 1635 - 1.8.8]


Mr_Rockers

Recommended Posts

Hello modder's support. (And Forge Support :P. Sorry about that)

I have come across a bug within Build 1635 - 1.8.8 with the Netty's SimpleNetworkWrapper.

When trying to send an IMessage through the Simple Channel, with .sendToDimension passing in a dimensionID as the second parameter (an Integer) then it doesn't work most of the time.

It affects the packet's discriminator by setting it to -1, presumably because there's an error or something isn't getting set some place in the code.

An example Stack-trace can be found here. It starts at around Line 112.

 

You can recreate this bug by setting up a standard packet system using the SimpleNetworkWrapper like so:

 

MOD Class:


/* Let's presume that we have set-up a new message based off of the code example from diesieben07's tutorial-guide.
This message will be called 'ExampleMessage'.
This is based off the fact that the packet's direction is SERVER -> CLIENT*/

public class ExampleMod
{
        //...
        public static SimpleNetworkWrapper INSTANCE;
@EventHandler
public void preInit(FMLPreInitializationEvent event)
{
	INSTANCE = NetworkRegistry.INSTANCE.newSimpleChannel("exampleChannel");
	INSTANCE.registerMessage(ExampleMessage.HANDLER.class, ExampleMessage.class, 0, Side.CLIENT);
	MinecraftForge.EVENT_BUS.register(new PlayerInteractEvents());
	//...
}
//...
}

 

.sendToDimension Example Class: (The .sendToDimension snippet can be called anywhere that only the server has access and only when the game is running. i.e. not at the Minecraft-Title Screen.  I make sure code is server-only by using a SideOnly.SERVER, using an if statement to check if the world is not remote or calling it from a Server Proxy.)


/* Let's also presume we have a block called 'ModBlocks.ExampleBlock' registered... */

public class PlayerInteractEvents {

@SubscribeEvent
public void onPlayerInteract(PlayerInteractEvent e)
{
	if(e.action != null && !e.world.isRemote)
	{
		if(e.action == Action.RIGHT_CLICK_BLOCK)
		{
			if(e.world.getBlockState(e.pos).getBlock() == ModBlocks.ExampleBlock)
			{
				ModNetworkHandler.sendToDimension(new ExampleMessage(), e.entityPlayer.dimension, e.world);
			}
		}
	}
}
}

 

If this code is executed correctly (with necessary additions) then it will work, but it is incredibly sketchy. It can produce a bit of lag and 'force-disconnects' the client at what appears to be "random chance". I had taken a look at the .sendToDimension code and it eventually leads to this:

            @Override
            public List<NetworkDispatcher> selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet)
            {
                int dimension = (Integer)args;
                ImmutableList.Builder<NetworkDispatcher> builder = ImmutableList.<NetworkDispatcher>builder();
                for (EntityPlayerMP player : (List<EntityPlayerMP>)FMLCommonHandler.instance().getMinecraftServerInstance().getConfigurationManager().playerEntityList)
                {
                    if (dimension == player.dimension)
                    {
                        NetworkDispatcher dispatcher = player.playerNetServerHandler.netManager.channel().attr(NetworkDispatcher.FML_DISPATCHER).get();
                        // Null dispatchers may exist for fake players - skip them
                        if (dispatcher != null) builder.add(dispatcher);
                    }
                }
                return builder.build();
            }

 

I am assuming that there is something fishy going on either in there or the SimpleNetworkWrapper class.

Classes to check may be:

  • SimpleNetworkWrapper class at line 220
  • FMLOutboundHandler class at line 144

 

For anyone with this error, an easy, fool-proof fix is available:

public static void sendToDimension(IMessage message, int dimensionId, World world)
{
	for(EntityPlayer player : world.playerEntities)
	{
		if(player instanceof EntityPlayerMP && player.dimension == dimensionId)
		{
			INSTANCE.sendTo(message, (EntityPlayerMP) player);
		}
	}
}

NOTE that the world passed in must be from a server, in this case. Do the checks that I mentioned above.

This is not the *most* efficient way of doing things either, but it works.

 

It appears that this bug has been in Forge for a while. (The earliest I can date back to is August.) Apparently it had been mentioned in the changelogs that this bug had been fixed a while ago but I still have managed to find it. There is also a chance that there is no bug and I just had bad-luck but I updated my forge to the most recent version and still, to no avail. I had diesieben07 and alot of other people that have been modding for a long time help me out on IRC by looking through my code and they couldn't find the solution either. I have only been modding for a month and Java coding for about half a year, so excuse my lack of understanding if something does come up. I am not new to programming, (I have been doing it for 3 to 5 years) but I am quite new to Java concepts and even modding concepts, if there are any.

 

I am open for constructive criticism either on IRC or on this thread here if you think I am wrong about something or other. I just wanted to post this "bug" for it drove me around the bend for a week.

 

That is all.

Took a year long hiatus in modding and have forgotten *everything*. (yay)

 

Now not working on a mod that supports satanism.

Now working on another mod, "Trinkets and Sabres"

Link to comment
Share on other sites

If you can write up a full slim test mod that would be good.

It SHOULD be fixed as the issue before was that the buffer was shared and things wernt resetting correctly.

However, people are using these methods all over the place and its the same concept sending to one person as it is to an entire dimension. We just build a list of users to send it to.

But ya, if you could write up a mod I can toss in dev i'll take a look.

I do Forge for free, however the servers to run it arn't free, so anything is appreciated.
Consider supporting the team on Patreon

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.