Jump to content

For some reason stackTagCompound isn't syncing with the server.


cmchenry

Recommended Posts

My addInformation class seems to not have a stackTagCompound for the ItemStack, so there is no lore for my item. I first grab and set all the information on the server, which I figured once I set it, it would sync it with the client, but it does not. I have tried restarting the server and rejoining the server, the server has all the values even after a restart but the client has none. I won't use packets because then I would have to send a packet to each client all the time and that could get laggy. Any solutions anyone?

 

public class ItemDrugTest extends Item implements Callback {

    public static final DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public ItemDrugTest() {
        setUnlocalizedName("drug_test");
        setTextureName(Minelife.MOD_ID + ":drug_test");
        setCreativeTab(ModDrugs.tab_drugs);
    }

    @Override
    public boolean itemInteractionForEntity(ItemStack item_stack, EntityPlayer player, EntityLivingBase entity_clicked) {
        if (!(entity_clicked instanceof EntityPlayer)) return false;
        if (player.worldObj.isRemote) return true;

        if (ModDrugs.check_for_cocaine((EntityPlayer) entity_clicked, 7)) {
            player.addChatComponentMessage(new ChatComponentText(EnumChatFormatting.RED + "Cocaine detected!"));
        } else {
            player.addChatComponentMessage(new ChatComponentText(EnumChatFormatting.GREEN + "Cocaine not detected."));
        }

        if (ModDrugs.check_for_marijuana((EntityPlayer) entity_clicked, 7)) {
            player.addChatComponentMessage(new ChatComponentText(EnumChatFormatting.RED + "Marijuana detected!"));
        } else {
            player.addChatComponentMessage(new ChatComponentText(EnumChatFormatting.GREEN + "Marijuana not detected."));
        }

        add_drug_test_results(item_stack, (EntityPlayer) entity_clicked);
        player.inventoryContainer.detectAndSendChanges();
        ((EntityPlayerMP) player).sendContainerToPlayer(player.inventoryContainer);
        return true;
    }

    @Override
    public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean bool) {
        if (stack.hasTagCompound() && stack.stackTagCompound.hasKey("player") && stack.stackTagCompound.hasKey("player_name")) {
            try {
                list.add("Player: " + stack.stackTagCompound.getString("player_name"));
                Date now = Calendar.getInstance().getTime();

                if (stack.stackTagCompound.hasKey("marijuana")) {
                    list.add(EnumChatFormatting.RED + "Tested POSITIVE for marijuana " + ModDrugs.convert_to_mc_days(now, df.parse(stack.stackTagCompound.getString("marijuana"))) + " days ago.");
                } else {
                    list.add(EnumChatFormatting.GREEN + "Tested NEGATIVE for marijuana.");
                }

                if (stack.stackTagCompound.hasKey("cocaine")) {
                    list.add(EnumChatFormatting.RED + "Tested POSITIVE for cocaine " + ModDrugs.convert_to_mc_days(now, df.parse(stack.stackTagCompound.getString("cocaine"))) + " days ago.");
                } else {
                    list.add(EnumChatFormatting.GREEN + "Tested NEGATIVE for cocaine.");
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }

        }
    }

    private void add_drug_test_results(ItemStack item_stack, EntityPlayer player) {
        NBTTagCompound tag_compound = item_stack.hasTagCompound() ? item_stack.stackTagCompound : new NBTTagCompound();

        tag_compound.setString("player", player.getUniqueID().toString());

        if (ModDrugs.check_for_marijuana(player, 7)) {
            tag_compound.setString("marijuana", df.format(Calendar.getInstance().getTime()));
        }

        if (ModDrugs.check_for_cocaine(player, 7)) {
            tag_compound.setString("cocaine", df.format(Calendar.getInstance().getTime()));
        }

        item_stack.stackTagCompound = tag_compound;

        // thread the NameFetcher class so that it doesn't cause lag
        new Thread(new FetchName(this, item_stack, player.getUniqueID())).start();
    }


    @Override
    public void callback(Object... objects) {
        ItemStack stack = (ItemStack) objects[0];
        UUID player_uuid = (UUID) objects[1];
        String player_name = (String) objects[2];
        stack.stackTagCompound.setString("player_name", player_name);
        System.out.println(stack.stackTagCompound.getString("player") + stack.stackTagCompound.getString("player_name"));
    }

    class FetchName implements Runnable {

        Callback callback;
        ItemStack stack;
        UUID player;
        String name;

        public FetchName(Callback callback, ItemStack stack, UUID player) {
            this.callback = callback;
            this.stack = stack;
            this.player = player;
        }

        @Override
        public void run() {
            name = NameFetcher.get(player);
            callback.callback(stack, player, name);
        }
    }
}

 

Link to comment
Share on other sites

You can't do this.

The server is in control.

You need to tell the server what you want to do, the server verifies it and sets the itemstack data, and that will sync to the clients.

 

Remember:

The client always lies.

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

Yes, as I said I set the stackTagCompound on the server. If you look at the start of itemInteractionForEntity I say (player.worldObj.isRemote) return true; This prevents the client from doing anything and only the server. I'm not trying to be mean, if I'm understanding what you are saying correctly?

Edited by cmchenry
Link to comment
Share on other sites

I set player_name right here

 

stack.stackTagCompound.setString("player_name", player_name);

 

in the callback method. Also that's a good point, I will make sure it can't be reused if it's already been used. I can't do it on the client because that will cause them to have too many requests error from Mojang, I do it on the server and store the names and uuids in a hashmap, so it's relatively quick. But if you do the NameFetcher without a separate thread it will hang-up either the client or server due to it waiting on the response from Mojang, so it must be threaded. 

Link to comment
Share on other sites

The callback is meant to give a response from the thread to the main thread, that's why I did it. It is in the main thread, but good point I need to check to make sure the itemstack is not null at that point. I know you can only interact from the main thread. I also don't want to cache on client because if they restart or something it could pose issues for them, and i'm not storing it in a file or something that's not a good way to do it. Also I'm not sure what you mean by a threadpool, I'll have to look that one up. But as far as the client not sycing with the server is the issue at hand here. If the server has the info for the nbtTagCompound so should the client at any given moment. There must be some way to sync them.

Edited by cmchenry
Link to comment
Share on other sites

I need to add, the name is not null on the server. The stackTagCompound is not null either. But when the player hovers over addInformation the stackTagCompound is null. This makes no since as to why the stackTagCompound is not null on server and null on client if they sync automatically as you say. I've been coding forge for around 6 years now, I know a lot more than you'd probably be lead to believe. This is an odd issue that I can't seem to figure out. So if the stackTagCompound is null on the client then trying to obtain the uuid from the client for the nameFetcher will not work as it will not have the uuid. Not to mention I already store the player_uuid on the server stackTagCompound along with the name.

Link to comment
Share on other sites

2 minutes ago, cmchenry said:

Not to mention I already store the player_uuid on the server stackTagCompound along with the name.

While this may be true, you're still fetching the name from Mojang's server when you don't need to: the player is right there, their name is already cached, just query the cache as D7 has indicated. No need to request from the auth server, no need for a child thread, no need for a callback.

 

EntityPlayer::getGameProfile().getName()

 

Boop, done.

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

Low and behold, it didn't work.

 

package com.minelife.drug.item;

import com.minelife.Minelife;
import com.minelife.drug.ModDrugs;
import com.minelife.util.server.Callback;
import com.minelife.util.server.NameFetcher;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class ItemDrugTest extends Item {

    public static final DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public ItemDrugTest() {
        setUnlocalizedName("drug_test");
        setTextureName(Minelife.MOD_ID + ":drug_test");
        setCreativeTab(ModDrugs.tab_drugs);
    }

    @Override
    public boolean itemInteractionForEntity(ItemStack item_stack, EntityPlayer player, EntityLivingBase entity_clicked) {
        if (!(entity_clicked instanceof EntityPlayer)) return false;
        if (player.worldObj.isRemote) return true;

        if (ModDrugs.check_for_cocaine((EntityPlayer) entity_clicked))
            player.addChatComponentMessage(new ChatComponentText(EnumChatFormatting.RED + "Cocaine detected!"));
        else
            player.addChatComponentMessage(new ChatComponentText(EnumChatFormatting.GREEN + "Cocaine not detected."));


        if (ModDrugs.check_for_marijuana((EntityPlayer) entity_clicked))
            player.addChatComponentMessage(new ChatComponentText(EnumChatFormatting.RED + "Marijuana detected!"));
        else
            player.addChatComponentMessage(new ChatComponentText(EnumChatFormatting.GREEN + "Marijuana not detected."));


        add_drug_test_results(item_stack, (EntityPlayer) entity_clicked);
        player.inventoryContainer.detectAndSendChanges();
        ((EntityPlayerMP) player).sendContainerToPlayer(player.inventoryContainer);
        return true;
    }

    @Override
    public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean bool) {
        if (stack.hasTagCompound() && stack.stackTagCompound.hasKey("player") && stack.stackTagCompound.hasKey("player_name")) {
            try {
                list.add("Player: " + stack.stackTagCompound.getString("player_name"));
                Date now = Calendar.getInstance().getTime();

                if (stack.stackTagCompound.hasKey("marijuana")) {
                    list.add(EnumChatFormatting.RED + "Tested POSITIVE for marijuana " + ModDrugs.convert_to_mc_days(now, df.parse(stack.stackTagCompound.getString("marijuana"))) + " days ago.");
                } else {
                    list.add(EnumChatFormatting.GREEN + "Tested NEGATIVE for marijuana.");
                }

                if (stack.stackTagCompound.hasKey("cocaine")) {
                    list.add(EnumChatFormatting.RED + "Tested POSITIVE for cocaine " + ModDrugs.convert_to_mc_days(now, df.parse(stack.stackTagCompound.getString("cocaine"))) + " days ago.");
                } else {
                    list.add(EnumChatFormatting.GREEN + "Tested NEGATIVE for cocaine.");
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }

        }
    }

    private void add_drug_test_results(ItemStack item_stack, EntityPlayer player) {
        NBTTagCompound tag_compound = item_stack.hasTagCompound() ? item_stack.stackTagCompound : new NBTTagCompound();

        tag_compound.setString("player", player.getUniqueID().toString());
        tag_compound.setString("player_name", player.getDisplayName());

        if (ModDrugs.check_for_marijuana(player))
            tag_compound.setString("marijuana", df.format(Calendar.getInstance().getTime()));
        if (ModDrugs.check_for_cocaine(player))
            tag_compound.setString("cocaine", df.format(Calendar.getInstance().getTime()));

        item_stack.stackTagCompound = tag_compound;

        // thread the NameFetcher class so that it doesn't cause lag
//        new Thread(new FetchName(this, item_stack, player.getUniqueID())).start();
    }

//
//    @Override
//    public void callback(Object... objects) {
//        ItemStack stack = (ItemStack) objects[0];
//        UUID player_uuid = (UUID) objects[1];
//        String player_name = (String) objects[2];
//        stack.stackTagCompound.setString("player_name", player_name);
//        System.out.println(stack.stackTagCompound.getString("player") + stack.stackTagCompound.getString("player_name"));
//    }

//    class FetchName implements Runnable {
//
//        Callback callback;
//        ItemStack stack;
//        UUID player;
//        String name;
//
//        public FetchName(Callback callback, ItemStack stack, UUID player) {
//            this.callback = callback;
//            this.stack = stack;
//            this.player = player;
//        }
//
//        @Override
//        public void run() {
//            name = NameFetcher.get(player);
//            callback.callback(stack, player, name);
//        }
//    }
}

 

2017-08-26_12.53.30.png

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.



×
×
  • Create New...

Important Information

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