Jump to content

[1.7.2] !world.isRemote and SideOnly(Side.SERVER)


TLHPoE

Recommended Posts

Ok, I have a method that I ONLY want to use when I'm working on the server. I'm checking to see if it's server side by doing the normal isRemote check. For some reason, it thinks I am on client-side.

 

Code that calls the method:

@SubscribeEvent
public void EntityJoinWorldEvent(EntityJoinWorldEvent event) {
	if(event.entity instanceof EntityPlayer) {
		EntityPlayer player = (EntityPlayer) event.entity;
		if(!player.worldObj.isRemote) {
			if(Util.isNewPlayer(player) && !player.inventory.hasItem(ItemHelper.getItem("raceStone"))) {
				int es = player.inventory.getFirstEmptyStack();
				player.inventory.setInventorySlotContents(es, new ItemStack(ItemHelper.getItem("raceStone"), 1));
			} else {
				Util.applyStats(player);
			}
		}
	}
}

 

And here's the method:

@SideOnly(Side.SERVER)
public static void applyStats(EntityPlayer player) {
	final AttributeModifier health = new AttributeModifier(player.getPersistentID(), "rpg_health", (((double) Util.getIntegerStat(player, Reference.MHP)) / 10) - 1, 1);
	float current = player.getHealth();
	IAttributeInstance iaiHealth = player.getEntityAttribute(SharedMonsterAttributes.maxHealth);
	if(iaiHealth.getModifier(health.getID()) == null) {
		iaiHealth.applyModifier(health);
	} else {
		iaiHealth.removeModifier(health);
		iaiHealth.applyModifier(health);
	}
	player.setHealth(current);
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	final AttributeModifier speed = new AttributeModifier(player.getPersistentID(), "rpg_speed", (((double) Util.getIntegerStat(player, Reference.SPEED)) / 10), 1);
	IAttributeInstance iaiSpeed = player.getEntityAttribute(SharedMonsterAttributes.movementSpeed);
	if(iaiSpeed.getModifier(speed.getID()) == null) {
		iaiSpeed.applyModifier(speed);
	} else {
		iaiSpeed.removeModifier(speed);
		iaiSpeed.applyModifier(speed);
	}
}

Kain

Link to comment
Share on other sites

An explanation:

@SideOnly differentiates between Minecraft Client (the one you start from the launcher) and Dedicated Server.

That means: If you do @SideOnly(Side.SERVER) your method will be completely removed from the class file if your mod is running on the Minecraft Client.

isRemote checks for the logical side. The Integrated Server will give isRemote == false, even though it is running in the Minecraft Client.

 

This is one of the tricky points to understand when first modding -- the "Client" is actually what TheGreyGhost would call the "Combined Client" because it also includes a server.  It really shouldn't be called "Client" because it causes exactly the confusion you mentioned.

 

Basically, when Run your mod with @SideOnly(Side.SERVER) it won't be available in the combined client even though there is actually still a server operating there (that may need the class).

 

I think actually that @SideOnly(Side.SERVER) is fairly useless for most of us because the Server Run Configuration is a subset of Client Run Configuration -- if you used this and you're going to run a Client Run Configuration you'd have to add a bunch of extra proxy side checking to ensure that the suppressed class is never called. 

 

On the other hand @SideOnly(Side.CLIENT) is more useful since the Client Run Configuration is a superset, and there are several client-side classes that don't make sense on the server. 

 

However, I'm beginning to think the @SideOnly is sort of pointless generally as long as you don't call the class (and your proxy and side checking can take care of that).  Who cares if there is a Renderer class on the server as long as it is never registered (your proxy will ensure that)?  The disk space and memory used by the unused classes is likely insignificant in most cases. 

 

Anyone have a good reason why you should use @SideOnly except as an optimization?

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

@SideOnly is not intended for use by modders at all.

Don't do it, it only causes trouble. If you need client-specific code, do it through your ClientProxy (or classes that are only referenced from there).

Interesting. I always add the at client-side-only in my render classes and such, and occasionally use it for methods that I only need on the client - such as ones that are interacting with keyboard or mouse - as a way to make sure I'm not accidentally calling it on the wrong side (by crashing the game, which I suppose would happen anyway in some cases :P).

 

Even if it's not intended for use by modders, I find it useful in these situations... but it sounds like you are saying there is absolutely no time that it should ever be used. I haven't noticed any problems resulting from its judicious use, so I'm curious what sorts of trouble it could cause that I should be aware of, aside from the obvious crashing on the server when incorrectly accessing such a method / field.

Link to comment
Share on other sites

You are right coolAlias, there is nothing wrong with you using it, provided with you knowing what you are doing.

But it also gives you no notable benefit:

  • Accidental usage of client-only methods / classes: It would crash anyways, probably with a ClassNotFoundException
  • It has some problems, the following code for example will crash on a Server, even if the field is never accessed:
    @SideOnly(Side.CLIENT)
    public String someString = SomeOtherClass.method();

That combined with the fact that unexperienced modders usually understand @SideOnly as a way to differentiate between Client and Server Thread ("logical side") leads to me not recommending it (unless you are overriding a Minecraft method which already has it, then you should in fact add it).

Thanks, that's how I've understood it as well. Well, that clears that up, and congrats on reaching 1000! xD

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.