// Be sure to offset based on your texture size or your texture will not be truly centered:
// int xPos = (event.resolution.getScaledWidth() + textureWidth) / 2;
// int yPos = (event.resolution.getScaledHeight() + textureHeight) / 2;
While it didn't work for me, I figured out it should be:
int xPos = (event.resolution.getScaledWidth() - textureWidth) / 2;
int yPos = (event.resolution.getScaledHeight() - textureHeight) / 2;
Since you want to subtract half the length to get the Gui to the center, because we want to move the top-left corner from the center up and left for half the height and width, respectively
// Be sure to offset based on your texture size or your texture will not be truly centered:
// int xPos = (event.resolution.getScaledWidth() + textureWidth) / 2;
// int yPos = (event.resolution.getScaledHeight() + textureHeight) / 2;
While it didn't work for me, I figured out it should be:
int xPos = (event.resolution.getScaledWidth() - textureWidth) / 2;
int yPos = (event.resolution.getScaledHeight() - textureHeight) / 2;
Since you want to subtract half the length to get the Gui to the center, because we want to move the top-left corner from the center up and left for half the height and width, respectively
Lol, yeah, you're right - looks like I pressed the wrong key while typing, but the code in the demo mod is correct Thanks for pointing that out, I'll have to fix it once the forum's editing features are working properly.
First off, many thanks. I'm updating a very old mod to 1.7.10, and it had previously used base edits to add a blink meter to the player. I am now using IExtendedEntityProperties/DataWatcher to do so without base edits, so many thanks on that.
My problem is, when I hit the keybind I set to trigger a voluntary blink, it renders the blink on screen, but the blink meter (GUI overlay like the mana meter you used in the example) itself continues to count down at its prior rate and doesn't reset itself to max (eg, blink when half-full, blink visually occurs, but the meter is still at halfway and counting down from there). I believe its a client/server sync issue, butI can't figure out how to update it, packets or no.
You managed to decompile and continue without me giving source code? O_O Bro, you are a god. Of course do whatever the [REDACTED] you want!!!! Good luck on it
First off, many thanks. I'm updating a very old mod to 1.7.10, and it had previously used base edits to add a blink meter to the player. I am now using IExtendedEntityProperties/DataWatcher to do so without base edits, so many thanks on that.
My problem is, when I hit the keybind I set to trigger a voluntary blink, it renders the blink on screen, but the blink meter (GUI overlay like the mana meter you used in the example) itself continues to count down at its prior rate and doesn't reset itself to max (eg, blink when half-full, blink visually occurs, but the meter is still at halfway and counting down from there). I believe its a client/server sync issue, butI can't figure out how to update it, packets or no.
Move all the processing out of your keybinding class and into a packet - you cannot update datawatcher from the client side. See my OpenGuiPacket for an example of sending a packet on a key press, but in your case you need to send the key that was pressed in the packet and process on the server side based on that information.
Hello, first of all I want to thank coolAlias for making this guide, but i'm having a problem. I have been following this guide but I can't get the extended properties to work correctly. Basically I'm doing a GUI that stores client side data for each player and obviously I want the data to persist after death. Making it as clear and short as I can, the GUI removes an item from the player inv and stores it as data. Data stores correctly, but for some reason after you exit the GUI and then open it again, the item comes back to the player inventory but the data stored is unaffected. Also data does not persist after death nor on relogging. I have followed the EventHandler tutorial and the extended properties tutorial but I'm not using syncing because I just want data to be stored on the player. I have done some debugging and for what I have seen, when I die the "saveProxyData" on my extended properties is not being called. I have tries many ways to get this working, but I keep failing. I would appreciate any help.
@Onthecode, it sounds like you are manipulating data on the client side which, by its very nature, is not stored anywhere. You absolutely MUST handle your data exclusively on the server and only use it for displaying things on the client side.
What I mean is, if you want to change something from a GUI, you can't change it there, you have to send a packet saying "player A pressed button 2 in Gui Q", and the server then decides what to do with that information, e.g. store a diamond sword somewhere for Player A. Then, whenever the Gui is opened, it requests the data it needs (such as current contents) from the server.
That whole process is generally taken care of for you by the Container class, but if you are implementing a Gui only without a Container, you have to do that all yourself.
@Onthecode, it sounds like you are manipulating data on the client side which, by its very nature, is not stored anywhere. You absolutely MUST handle your data exclusively on the server and only use it for displaying things on the client side.
What I mean is, if you want to change something from a GUI, you can't change it there, you have to send a packet saying "player A pressed button 2 in Gui Q", and the server then decides what to do with that information, e.g. store a diamond sword somewhere for Player A. Then, whenever the Gui is opened, it requests the data it needs (such as current contents) from the server.
That whole process is generally taken care of for you by the Container class, but if you are implementing a Gui only without a Container, you have to do that all yourself.
Thanks for your quick response. So basically I do need to use packets? Would using the SimpleNetworkWrapper work for this? And yes, I'm implementing the GUI without a container.
If you are dealing with an IInventory, I recommend you use a Container, but if you can't for whatever reason, yes, you need to use whatever network system you feel comfortable with to send packets.
I think I'm doing this more complicated than it should be. Basically it is just a GUI that opens from block that acts as an ATM. I'm saving the money of the player using an extended property and that's all I want to do, that is why I'm not using a container. I'm confused with the use of packets as I have never used packets, currently I send a packet to the server when the player press a button on the GUI, but I don't understand what I need to do with that packet. How do I translate that press of the button packet to modifying the player's extended properties?
Move all the processing out of your keybinding class and into a packet - you cannot update datawatcher from the client side. See my OpenGuiPacket for an example of sending a packet on a key press, but in your case you need to send the key that was pressed in the packet and process on the server side based on that information.
You managed to decompile and continue without me giving source code? O_O Bro, you are a god. Of course do whatever the [REDACTED] you want!!!! Good luck on it
I think I'm doing this more complicated than it should be. Basically it is just a GUI that opens from block that acts as an ATM. I'm saving the money of the player using an extended property and that's all I want to do, that is why I'm not using a container. I'm confused with the use of packets as I have never used packets, currently I send a packet to the server when the player press a button on the GUI, but I don't understand what I need to do with that packet. How do I translate that press of the button packet to modifying the player's extended properties?
How did you do it in the Gui? Just do it the same way, but on the server, so that you can save your data.
Using SimpleNetworkWrapper I send a package when pressing the GUI Button that contains the data I want to save on the extended properties and in the handler class in the onMessage method I save that data into the extended properties, but I assume I'm doing wrong cause it crashes giving me this error "There was a critical exception handling a packet on channel".
EDIT: I saw you had a tutorial on SimpleNetworkWrapper, so I read it. I ended up way more confused that I was, I just don't understand why I need to send a package when the GUI actually stores nothing, everything is stored in the player's extended properties. But you already told me that I need to send a package to the server for it to save my extended properties, but I just don't understand how I'm supposed to do that.
I just can't get it working properly, I just can't get the extended properties to persist. How should I handle the packets I'm sending when pressing the button in the GUI.
Using SimpleNetworkWrapper I send a package when pressing the GUI Button that contains the data I want to save on the extended properties and in the handler class in the onMessage method I save that data into the extended properties, but I assume I'm doing wrong cause it crashes giving me this error "There was a critical exception handling a packet on channel".
EDIT: I saw you had a tutorial on SimpleNetworkWrapper, so I read it. I ended up way more confused that I was, I just don't understand why I need to send a package when the GUI actually stores nothing, everything is stored in the player's extended properties. But you already told me that I need to send a package to the server for it to save my extended properties, but I just don't understand how I'm supposed to do that.
In Minecraft (and many many applications), all of the data is stored on the server. When the client (i.e. the player) connects, the client requests whatever data it needs to process things on its side, such as what blocks are in the world, what items the player has, etc., so that they can be rendered. The server also maintains lots of other information that the client doesn't need to know about, and handles all the processing of information.
Imagine if each player's computer was telling the server what state the world was supposed to be in, rather than the other way around. Even with just 2 players, there will probably be discrepancies, and it also opens up the game to hacking: "Yeah, of course I have 30 stacks of diamond blocks in my inventory, Mr. Server, didn't you know about that? No? Well I do, so you should update."
So it's not really about storing the data, it's about processing everything on the server, and every time the client player wants to do something, you should be sending a packet to the server saying, "Hey, I am trying to do X", then the server takes all of the information it has and figures out if the player is allowed to do X or not, and sends a packet back with the results of the action. Packets (not 'packages') are how the client and server communicate with each other - I suggest you do some further research into the basics of the client-server relationship, structure, and usage.
Btw, I don't recommend using my tutorial on SimpleNetworkWrapper if you don't understand yet how to use SimpleNetworkWrapper, which is why I linked to more basic tutorials at the top, and reminded you to use the basic version several times throughout the tutorial.
Thanks for the reply. I am indeed using the basic version of SimpleNetworkWrapper, I just read your tutorial for any extra information that could be useful for me. So from what you have explained to me I understand that my main problem is that I'm doing things from a GUI and the GUI doesn't automatically sends packets to the server and this is why my extended properties are not saving, am I right? If so what I have currently done is that when the button in the GUI is clicked the client sends a packet telling the server that the button has been clicked. But I don't understand what I need to do with that packet when it arrives to the server, where do I insert my code to write to the player extended properties? My code to do this is in the onMessage method in my MessageHandler class, but it doesn't works this way. How should I respond from getting that message from the client?
Aren't you just trying to give the player an item? I think you are making this out to be way more complicated than it is.
1. Player presses button in Gui (client)
2. Packet gets sent from client to server with the button pressed (still on client)
3. Server receives the packet, opens it up, 'oh, player A pressed button 2 in the GiveItemToPlayer Gui... what should I do about that?'
4. Server (i.e. your code in the onMessage method) processes the information it has received to determine what should happen, such as:
// please note this is not real code
onMessage(YourMessageClass message, other parameters) {
if (message.button == 2) {
givePlayer(Items.diamondSword);
// or if you need to do something in your IEEP:
ExtendedPlayer.get(player).doSomething(message.whateverInfoYouSent);
} else {
print("Wrong button! No item for you!");
}
}
5. That's it. Now the player has a new item, and maybe you want to send a packet back to the client if the client needs to know about something, but usually you don't need to bother.
Please follow my advice and read up on the client-server paradigm, packets, etc., in general, not just in relation to Minecraft. It will make a lot more sense if you have a basic understanding of what's going on, and then you can figure out what to do in the context of modding MC.
Aren't you just trying to give the player an item? I think you are making this out to be way more complicated than it is.
1. Player presses button in Gui (client)
2. Packet gets sent from client to server with the button pressed (still on client)
3. Server receives the packet, opens it up, 'oh, player A pressed button 2 in the GiveItemToPlayer Gui... what should I do about that?'
4. Server (i.e. your code in the onMessage method) processes the information it has received to determine what should happen, such as:
// please note this is not real code
onMessage(YourMessageClass message, other parameters) {
if (message.button == 2) {
givePlayer(Items.diamondSword);
// or if you need to do something in your IEEP:
ExtendedPlayer.get(player).doSomething(message.whateverInfoYouSent);
} else {
print("Wrong button! No item for you!");
}
}
5. That's it. Now the player has a new item, and maybe you want to send a packet back to the client if the client needs to know about something, but usually you don't need to bother.
Please follow my advice and read up on the client-server paradigm, packets, etc., in general, not just in relation to Minecraft. It will make a lot more sense if you have a basic understanding of what's going on, and then you can figure out what to do in the context of modding MC.
I was actually doing something very similar to this, but anyways I just rewrote some of my code and the packet thing now seems to be working, but still my player extended properties doesn't persist. I did some debugging and both saveProxyData and loadProxyData are called when I die and respawn, respectively, but my extended properties get erased. They also don't persist when I relog into the game. I don't know why but currently the GUI sends the packet to the server that I pressed a specific button, the server gets things done, it removes an item from my inventory and adds value to a variable that is saved in my extended properties, but then when I die the item that was removed from me spawns as if I had dropped it from my inv, when actually when I died I had nothing with me, and it "returns" me the same amount that it removed from me, as if it was never removed. Hopefully I'm being clear explaining this.
Sounds like you are not saving your data to NBT, and also that you are not removing the item from your inventory properly. This would go faster if you posted some code.
public static final String ExtendedProperty = "playermoney";
private final EntityPlayer player;
public int pmoney;public PlayerMoney(EntityPlayer player){
this.player = player;
}
public static final void register(EntityPlayer player){
player.registerExtendedProperties(PlayerMoney.ExtendedProperty, new PlayerMoney(player));
}
public static final PlayerMoney get(EntityPlayer player) {
return (PlayerMoney) player.getExtendedProperties(ExtendedProperty);
}
@Override
public void saveNBTData(NBTTagCompound compound) {
NBTTagCompound money = new NBTTagCompound();
money.setInteger("money", pmoney);
compound.setTag(ExtendedProperty, money);
}
@Override
public void loadNBTData(NBTTagCompound compound) {
@SubscribeEvent
public void onLivingDeathEvent(LivingDeathEvent event){
if (!event.entity.worldObj.isRemote && event.entity instanceof EntityPlayer){
PlayerMoney.saveProxyData((EntityPlayer) event.entity);
}
}
@SubscribeEvent
public void onEntityJoinWorld(EntityJoinWorldEvent event){
if (!event.entity.worldObj.isRemote && event.entity instanceof EntityPlayer){
PlayerMoney.loadProxyData((EntityPlayer) event.entity);
}
}
}
Common and ClientProxy Class:
class CommonProxy {private static final Map<String, NBTTagCompound> extendedEntityData = new HashMap<String, NBTTagCompound>();
public EntityPlayer getPlayerEntity(MessageContext ctx) {
return ctx.getServerHandler().playerEntity;
}
public static void storeEntityData(String name, NBTTagCompound compound){
extendedEntityData.put(name, compound);
}
public static NBTTagCompound getEntityData(String name){
return extendedEntityData.remove(name);
}
}
public class ClientProxy extends CommonProxy {
@Override
public EntityPlayer getPlayerEntity(MessageContext ctx) {
return Minecraft.getMinecraft().thePlayer;
}
}
My Message and Message Handler Class:
class BankPacket implements IMessage{public int button;
public BankPacket() { }
public BankPacket(int button) {
this.button = button;
}
@Override
public void fromBytes(ByteBuf buf) {
this.button = buf.readInt();
}
@Override
public void toBytes(ByteBuf buf) {
buf.writeInt(button);
}
public static class BankPacketHandler implements IMessageHandler<BankPacket, IMessage> {
@Override
public IMessage onMessage(BankPacket message, MessageContext ctx) {
if (message.button == 1){
EntityPlayer player = Main.proxy.getPlayerEntity(ctx);
PlayerMoney money = PlayerMoney.get(player);
Where do you remove the item from the player? That needs to be done on the server, too, not just the adding of money.
How do you know that your money is not persisting across death / re-log-in ? Do you print the amount to the console? Keep in mind that there are TWO money variables, one on the server and one on the client, and you need to print them both to see if they are what they should be. My guess is that the server has the correct value, but you are seeing 0 on the client because you never tell the client (by sending a packet) how much money the player has.
Btw, you should seriously consider rewriting your depostAllMoney method... and please name your ExtendedPlayer String either EXTENDED_PLAYER or extendedPlayer - right now it looks like a class name I used to have a good link for Java naming conventions, but it's broken, so I'll leave it to you to do a search.
Rollback Post to RevisionRollBack
To post a comment, please login or register a new account.
While it didn't work for me, I figured out it should be:
Since you want to subtract half the length to get the Gui to the center, because we want to move the top-left corner from the center up and left for half the height and width, respectively
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumLol, yeah, you're right - looks like I pressed the wrong key while typing, but the code in the demo mod is correct
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumFirst off, many thanks. I'm updating a very old mod to 1.7.10, and it had previously used base edits to add a blink meter to the player. I am now using IExtendedEntityProperties/DataWatcher to do so without base edits, so many thanks on that.
My problem is, when I hit the keybind I set to trigger a voluntary blink, it renders the blink on screen, but the blink meter (GUI overlay like the mana meter you used in the example) itself continues to count down at its prior rate and doesn't reset itself to max (eg, blink when half-full, blink visually occurs, but the meter is still at halfway and counting down from there). I believe its a client/server sync issue, butI can't figure out how to update it, packets or no.
Source code: SecureCraftProtect, branch netz
Patreon
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumMove all the processing out of your keybinding class and into a packet - you cannot update datawatcher from the client side. See my OpenGuiPacket for an example of sending a packet on a key press, but in your case you need to send the key that was pressed in the packet and process on the server side based on that information.
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumWhat I mean is, if you want to change something from a GUI, you can't change it there, you have to send a packet saying "player A pressed button 2 in Gui Q", and the server then decides what to do with that information, e.g. store a diamond sword somewhere for Player A. Then, whenever the Gui is opened, it requests the data it needs (such as current contents) from the server.
That whole process is generally taken care of for you by the Container class, but if you are implementing a Gui only without a Container, you have to do that all yourself.
Thanks for your quick response. So basically I do need to use packets? Would using the SimpleNetworkWrapper work for this? And yes, I'm implementing the GUI without a container.
-
View User Profile
-
View Posts
-
Send Message
Curse Premium-
View User Profile
-
View Posts
-
Send Message
Curse PremiumAh, gotcher. many thanks, was driving me batty
Patreon
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumHow did you do it in the Gui? Just do it the same way, but on the server, so that you can save your data.
EDIT: I saw you had a tutorial on SimpleNetworkWrapper, so I read it. I ended up way more confused that I was, I just don't understand why I need to send a package when the GUI actually stores nothing, everything is stored in the player's extended properties. But you already told me that I need to send a package to the server for it to save my extended properties, but I just don't understand how I'm supposed to do that.
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumIn Minecraft (and many many applications), all of the data is stored on the server. When the client (i.e. the player) connects, the client requests whatever data it needs to process things on its side, such as what blocks are in the world, what items the player has, etc., so that they can be rendered. The server also maintains lots of other information that the client doesn't need to know about, and handles all the processing of information.
Imagine if each player's computer was telling the server what state the world was supposed to be in, rather than the other way around. Even with just 2 players, there will probably be discrepancies, and it also opens up the game to hacking: "Yeah, of course I have 30 stacks of diamond blocks in my inventory, Mr. Server, didn't you know about that? No? Well I do, so you should update."
So it's not really about storing the data, it's about processing everything on the server, and every time the client player wants to do something, you should be sending a packet to the server saying, "Hey, I am trying to do X", then the server takes all of the information it has and figures out if the player is allowed to do X or not, and sends a packet back with the results of the action. Packets (not 'packages') are how the client and server communicate with each other - I suggest you do some further research into the basics of the client-server relationship, structure, and usage.
Btw, I don't recommend using my tutorial on SimpleNetworkWrapper if you don't understand yet how to use SimpleNetworkWrapper, which is why I linked to more basic tutorials at the top, and reminded you to use the basic version several times throughout the tutorial.
-
View User Profile
-
View Posts
-
Send Message
Curse Premium1. Player presses button in Gui (client)
2. Packet gets sent from client to server with the button pressed (still on client)
3. Server receives the packet, opens it up, 'oh, player A pressed button 2 in the GiveItemToPlayer Gui... what should I do about that?'
4. Server (i.e. your code in the onMessage method) processes the information it has received to determine what should happen, such as:
// please note this is not real code onMessage(YourMessageClass message, other parameters) { if (message.button == 2) { givePlayer(Items.diamondSword); // or if you need to do something in your IEEP: ExtendedPlayer.get(player).doSomething(message.whateverInfoYouSent); } else { print("Wrong button! No item for you!"); } }5. That's it. Now the player has a new item, and maybe you want to send a packet back to the client if the client needs to know about something, but usually you don't need to bother.
Please follow my advice and read up on the client-server paradigm, packets, etc., in general, not just in relation to Minecraft. It will make a lot more sense if you have a basic understanding of what's going on, and then you can figure out what to do in the context of modding MC.
I was actually doing something very similar to this, but anyways I just rewrote some of my code and the packet thing now seems to be working, but still my player extended properties doesn't persist. I did some debugging and both saveProxyData and loadProxyData are called when I die and respawn, respectively, but my extended properties get erased. They also don't persist when I relog into the game. I don't know why but currently the GUI sends the packet to the server that I pressed a specific button, the server gets things done, it removes an item from my inventory and adds value to a variable that is saved in my extended properties, but then when I die the item that was removed from me spawns as if I had dropped it from my inv, when actually when I died I had nothing with me, and it "returns" me the same amount that it removed from me, as if it was never removed. Hopefully I'm being clear explaining this.
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumMy IExtendedEntityProperties class:
My Message and Message Handler Class:
The actionPerformed method from my GUI:
And finally how the event handler and network wrapper are registered:
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumHow do you know that your money is not persisting across death / re-log-in ? Do you print the amount to the console? Keep in mind that there are TWO money variables, one on the server and one on the client, and you need to print them both to see if they are what they should be. My guess is that the server has the correct value, but you are seeing 0 on the client because you never tell the client (by sending a packet) how much money the player has.
Btw, you should seriously consider rewriting your depostAllMoney method... and please name your ExtendedPlayer String either EXTENDED_PLAYER or extendedPlayer - right now it looks like a class name