Jump to content

[1.7.10] Get Player's Capabilities In OnUpdate & Key Handling With Packets


Recommended Posts

Posted

Was just putting it out there. I agree its best not to take short cuts but in my opinion simpler is always better but as you are doing this as a learning experience that dosnt really matter. 

 

PS: You could still do it without the potion effect by simply checking if the player has the item in their inventory however you would only have one timer available so you wouldn't be able to have a timer for both the flight and cool down before reactivation unless you use the item damage for both.

I am the author of Draconic Evolution

Posted

It would seem there's an issue with the packet sending on dedicated servers.  To make sure it wasn't any of the non-packet stuff that was causing it, I added packets to another item that needs them, but doesn't need IEEP or anything fancy, and it's giving the same error that the flight talisman is giving.  It seems like it's something obvious I'm overlooking :/

 

Error Log

 

Item

Message

ClientProxy

Main

Posted

if(!world.isRemote)
{
if(stack.stackTagCompound.getBoolean("Mode"))
{
	ArcaneArtificing.snw.sendToServer(new MessageBreakBlock(1));
}
else
{
	ArcaneArtificing.snw.sendToServer(new MessageBreakBlock(0));
}
}

It looks like you are trying to send a packet from the server to the server perhaps that is the problem?

I am the author of Draconic Evolution

Posted

Wait wait wait...is world.isRemote client side?  I thought it was server...if that's actually client, that could explain a lot of the issues I've had with this.  <__>  I thought I was saying that the mode checking and sending should only run on client side in there when I put !world.isRemote...

Posted

Ok, I fixed that, and cleaned everything up, and added logging.  The message is being received, but it's not executing the method in the proxy like I told it to in onMessage, and I can't figure out why.  It seems client/server related again, but I don't know what to do about it.

 

Item

Message

ClientProxy

Main

 

EDIT: No wait, it's not being received...wth is going on here?

 

EDIT 2: Through some witchcraft that left my code identical to the way it was before, the message is being received now, but it's running the CommonProxy methods, instead of the overridden methods in ClientProxy. :/  Is there something else I'm missing?

Posted

Looking at how you registered your messages, you are sending them to the server, so why would any of your ClientProxy methods be getting called? Of course it is calling CommonProxy version - that's what it does on the server side.

 

You do not want to do anything that changes the world from your client proxy - stuff like 'setBlock' should ONLY be done on the server (the client usually gets notified of the changes automatically).

Posted

Who told you raytracing has to be done on the client? You can do it on the server just as well:

Vec3 vec31 = Vec3.createVectorHelper(player.posX, player.posY + player.getEyeHeight(), player.posZ);
Vec3 vec32 = Vec3.createVectorHelper(i, j, k);
MovingObjectPosition mop = world.rayTraceBlocks(vec31, vec32);

Use the player's look vector for the i/j/k coordinates.

i would be (player.posX + (look.xCoord * 64)) for a range of 64 blocks, j would be the same for y, and k for z.

Posted

@Override
public void breakBlockST(EntityPlayer player)
{
	System.out.println("break block ST");
	Vec3 vector1 = Vec3.createVectorHelper(player.posX, player.posY, player.posZ);
	Vec3 vector2 = Vec3.createVectorHelper(player.posX + (player.getLookVec().xCoord * 4), player.posY + (player.getLookVec().yCoord * 4), player.posZ + (player.getLookVec().zCoord * 4));
	MovingObjectPosition mop = player.worldObj.rayTraceBlocks(vector1, vector2);
	int blockX = mop.blockX;
	int blockY = mop.blockY;
	int blockZ = mop.blockZ;
	Block targetBlock = player.worldObj.getBlock(blockX, blockY, blockZ);
	System.out.println(targetBlock + " " + blockX + " " + blockY + " " + blockZ);
	if(targetBlock instanceof BlockOre || targetBlock instanceof BlockRedstoneOre || targetBlock instanceof BlockModOre)
	{
		player.worldObj.spawnEntityInWorld(new EntityItem(player.worldObj, blockX, blockY, blockZ, new ItemStack(targetBlock)));
		player.worldObj.playAuxSFX(2001, blockX, blockY, blockZ, targetBlock.getIdFromBlock(targetBlock));
		player.worldObj.setBlockToAir(blockX, blockY, blockZ);
		if(player.inventory.getCurrentItem() != null)
		{
			//--player.inventory.getCurrentItem().stackSize;
			//player.inventory.setInventorySlotContents(player.inventory.currentItem, null);
		}
	}
}

 

That's in ServerProxy, and running on a server, it detects the block below the player instead of where the player's aiming, it does break the block below the player correctly if it's an ore, and if the player's looking anywhere but relatively downward when you right click, it crashes on a NPE thrown at:

 

int blockX = mop.blockX;

 

PS just check out SSP, it doesn't work at all, doesn't call the method in the ServerProxy.

Posted

Did you not see "player.posY + player.getEyeHeight()" in my code snippet? There's a reason for adding the player's eye height, and that is that on the server, player.posY is the player's feet.

 

As for your NPE, it is clearly possible for no block to be hit by the ray trace (looking up into the sky or looking at an entity), so you need to check for that.

 

 

Posted

No, I didn't see that. <_<

 

PS. Is there a more accurate way to do this?  It doesn't detect the block half the time when you're pointing right at it, which makes it very frustrating to use.

Posted

That aside, there's 2 more things that aren't working.  Most important is, how do you properly check if the server allows flight?  I put

 

if(MinecraftServer.getServer().isFlightAllowed())

 

in as a check before sending the packet, and this causes a crash with no error beyond the "a client unexpectedly left" one.

 

Second is, the raytracing doesn't work at all on SSP, is there a solution that works on either an integrated or dedicated server?

Posted

Regarding isFlightAllowed That only exists on a dedicated server so use.

if(!world.isRemote && MinecraftServer.getServer().isDedicatedServer()) LogHelper.info(MinecraftServer.getServer().isFlightAllowed());

 

Edit: it looks like MinecraftServer.getServer().isFlightAllowed() actually dose work in ssp it just returns true. Is it possible you are trying to call it client side?

I am the author of Draconic Evolution

Posted

What's LogHelper?  Also, clarification, I was referring to it crashing on a dedicated server after putting in the isFlightAllowed check, so putting in the isDedicatedServer check before it doesn't solve the crash.

 

Didn't see your edit before posting, added the isRemote check, and it works fine now.

Posted

Ok, so last 2 issues,  the raytracing is only working on a dedicated server, and on my normal server, the flight talisman regains all of its durability when you open an Ender Pouch, change Mystcraft ages, or dimensions.  Anyone know what either of those are about or how to fix them?  The durability issue seems like an interaction bug with one of the mods on the server, because it doesnt happen on a clean server, or a server running in the dev environment.

Posted

Regarding your NBTHelper. That all looks fine but it really only dose half the job if you still have to check that the stack has a tag and if not add it that should all be handled by your handler so you can do setValue(stack, "Tag", value) and getValue(stack, "Tag", default) and not have to worry about anything else. If your not sure how to do that check out my NBTHelper

 

public final class ItemNBTHelper {

public static NBTTagCompound getCompound(ItemStack stack){
	if (stack.getTagCompound() == null)
		return new NBTTagCompound();
	else
		return stack.getTagCompound();	
}

        // SETTERS ///////////////////////////////////////////////////////////////////

public static ItemStack setBoolean(ItemStack stack, String tag, boolean b)
{
	NBTTagCompound compound = getCompound(stack);
	compound.setBoolean(tag, b);
	stack.setTagCompound(compound);
	return stack;
}

public static ItemStack setShort(ItemStack stack, String tag, short s)
{
	NBTTagCompound compound = getCompound(stack);
	compound.setShort(tag, s);
	stack.setTagCompound(compound);
	return stack;
}

public static ItemStack setInteger(ItemStack stack, String tag, int i)
{
	NBTTagCompound compound = getCompound(stack);
	compound.setInteger(tag, i);
	stack.setTagCompound(compound);
	return stack;
}

public static ItemStack setFloat(ItemStack stack, String tag, float f)
{
	NBTTagCompound compound = getCompound(stack);
	compound.setFloat(tag, f);
	stack.setTagCompound(compound);
	return stack;
}

public static ItemStack setDouble(ItemStack stack, String tag, double d)
{
	NBTTagCompound compound = getCompound(stack);
	compound.setDouble(tag, d);
	stack.setTagCompound(compound);
	return stack;
}

public static ItemStack setString(ItemStack stack, String tag, String s) {
	NBTTagCompound compound = getCompound(stack);
	compound.setString(tag, s);
	stack.setTagCompound(compound);
	return stack;
}

// GETTERS ///////////////////////////////////////////////////////////////////

public static boolean verifyExistance(ItemStack stack, String tag) {
	NBTTagCompound compound = stack.getTagCompound();
	if (compound == null)
		return false;
	else
		return stack.getTagCompound().hasKey(tag);
}

public static boolean getBoolean(ItemStack stack, String tag, boolean defaultExpected) {
	return verifyExistance(stack, tag) ? stack.getTagCompound().getBoolean(tag) : defaultExpected;
}

public static short getShort(ItemStack stack, String tag, short defaultExpected) {
	return verifyExistance(stack, tag) ? stack.getTagCompound().getShort(tag) : defaultExpected;
}

public static int getInteger(ItemStack stack, String tag, int defaultExpected) {
	return verifyExistance(stack, tag) ? stack.getTagCompound().getInteger(tag) : defaultExpected;
}

public static float getFloat(ItemStack stack, String tag, float defaultExpected) {
	return verifyExistance(stack, tag) ? stack.getTagCompound().getFloat(tag) : defaultExpected;
}

public static double getDouble(ItemStack stack, String tag, double defaultExpected) {
	return verifyExistance(stack, tag) ? stack.getTagCompound().getDouble(tag) : defaultExpected;
}

public static String getString(ItemStack stack, String tag, String defaultExpected) {
	return verifyExistance(stack, tag) ? stack.getTagCompound().getString(tag) : defaultExpected;
}
}

 

As for the rest im still looking for the cause of your talismen problem i will get back to you if i find anything.

 

Edit: In onUpdate in the item class why are you sending a message to the client? onUpdate is called both client and server side. Also it dosnt look like you are using extended properties correctly.

@Override
public void handleKeys()
{
if(Minecraft.getMinecraft().inGameHasFocus && Minecraft.getMinecraft().gameSettings.keyBindJump.getIsKeyPressed())
{
	ExtendedPlayer.spaceDown = true;
}
else
{
	ExtendedPlayer.spaceDown = false;
}
}

You are just changing the field in your ExtendedPlayer class which works because its client side but its not actually saving anything to the player.

 

Edit 2: --stack.stackSize; should be all you need here.

--stack.stackSize;
if(player instanceof EntityPlayer)
{
((EntityPlayer)player).inventory.setInventorySlotContents(((EntityPlayer)player).inventory.currentItem, null);
}

 

Regarding the durability resetting it dosnt look like you are actually changing the damage value so do you mean the nbt value is resetting? or did i miss something?

 

Edit 3: found the problem because you are only setting ExtendedPlayer.isSpaceDown client side the following code is only running client side

if(ExtendedPlayer.isSpaceDown((EntityPlayer)player))
{
if(player.posY < Reference.HEIGHTLIMIT)
{
	player.motionY += Reference.TERMINAL * Reference.THRUST;
	if(player.motionY > Reference.TERMINAL)
	{
		player.motionY = Reference.TERMINAL;
		}
}
NBTHelper.incrementIntSetDamage(stack, "Mana");
if(stack.stackTagCompound.getInteger("Mana") > this.getMaxDamage())
{
	--stack.stackSize;
	if(player instanceof EntityPlayer)
	{
		((EntityPlayer)player).inventory.setInventorySlotContents(((EntityPlayer)player).inventory.currentItem, null);
	}
}
}

Which means you are only changing the nbt client side so as soon as the client re syncs with the server by something such as the player relogging or going to another dimension the value is reset back to default.

 

So to fix your problem you need to

a) Learn how properly use IExtendedEntityPropertiys

b) Use your key input handler to send a packet to the server when space is pressed that packet should contain a Boolean that says wether space is pressed or not and on reviving that packet set the property "isSpaceDown" for the player (you will have to set it client side aswell but that will be exactly the same just do it before you send the message to the server)

 

BTW the reason it lets you fly as it is is because player motion is handled client side.

I am the author of Draconic Evolution

Posted

1. The server doesn't know about the clients keyboard, so the message has to be sent to the client for it to handle the checking of said keyboard.  It's also gated to only send on the server side.

2. --stack.stackSize leaves the player with a phantom item in their inventory, you have to right click with it, pick it up in the inventory, try to drop it, try to use it, or break a block with it for it to disappear, so I always set the slots contents to null to graphically remove it immediately.

 

 

And this works now, assuming this is what you meant for me to do:

 

 

Flight Talisman

MessageKeys

ClientProxy

ExtendedPlayer

ServerProxy

MessageFly

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.