Jump to content

[1.6.4] Problem adding a String to the NBTTag


MagicHaze

Recommended Posts

I am trying to code a Mod that will add a codeLock (atm its just a block without a texture). In a GUI with buttons i want to change the password for the codeLock if no password was set. ATM it works until i unload the map. If i load it again the password is "" (so it wont save the password corretly). I read some tutorials about NBTTags but they didnt help me.

 

I would be happy about some hints.

 

Here is my code:

 

(ATM i am changing the lockCode in my GUICodeLockBlock class file and i dont know if that is right - and yes, i registered the tileentity in my basemod class file)

 

 

package codelockmod.tileentity;

import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.Packet132TileEntityData;
import net.minecraft.tileentity.TileEntity;

public class TileEntityCodeLockBlock extends TileEntity {

public String lockCode = "";

//Anzahl der Slots bestimmen (inventar)
public TileEntityCodeLockBlock() {

}

public void setLockCode(String lockCode){
	this.lockCode = lockCode;
	updateEntity();
}

public boolean hasCode(){
	if(lockCode != "" && lockCode != " ")
		return true;
	else
		return false;
}

public boolean checkInput(String input){
	if(input.matches(lockCode))
		return true;
	else
		return false;
}

public void updateEntity(){
	super.updateEntity();
}

@Override
public void readFromNBT(NBTTagCompound nbt){
	super.readFromNBT(nbt);
	if (nbt.hasKey("lockCode"));
        	this.lockCode = nbt.getString("lockCode");
        System.out.println(nbt.getString("lockCode") + " hallo");
}
@Override
    public void writeToNBT(NBTTagCompound nbt){
        super.writeToNBT(nbt);
        nbt.setString("lockCode", lockCode);
    }

@Override
public Packet getDescriptionPacket(){
	NBTTagCompound tileTag = new NBTTagCompound();
	this.writeToNBT(tileTag);
	return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord,
			1, tileTag);
}

@Override
public void onDataPacket(INetworkManager net, Packet132TileEntityData pkt){
	this.readFromNBT(pkt.data); //Only found pkt.customParam1 in tutorials so i dont       
                                                            //know if pkt.data is right for 1.6.4
}
}

 

 

 

 

 

package codelockmod.client.gui;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.util.ResourceLocation;

import org.lwjgl.opengl.GL11;

import codelockmod.client.container.ContainerCodeLockBlock;
import codelockmod.lib.ModInfo;
import codelockmod.tileentity.TileEntityCodeLockBlock;

public class GuiCodeLockBlock extends GuiContainer {
public static final ResourceLocation texture = new ResourceLocation(ModInfo.ID.toLowerCase(), 
		"textures/gui/codelock.png");
public String codeInput = "";
public String output = "haha";
public TileEntityCodeLockBlock entity;

public GuiCodeLockBlock(InventoryPlayer invPlayer, TileEntityCodeLockBlock entity) {
	super(new ContainerCodeLockBlock(invPlayer, entity));

	this.entity = entity;
	this.xSize = 176;
	this.ySize = 133;
}

@Override
public void drawGuiContainerBackgroundLayer(float f, int j, int i) {
	//Imagefarbe
	GL11.glColor4f(1F, 1F, 1F, 1F);
	//"Rendering Registry" finden und Textur binden
	Minecraft.getMinecraft().getTextureManager().bindTexture(texture);
	//guiLeft = X-Achse (von oben links)	//guiRight = Y-Achse (von oben links)
	//0 = X-Achse (GUI in der Sourcedatei)	//0 = Y-Achse (GUI in der Sourcedatei)
	//xSize = Breite der GUI				//xSize = Hoehe der GUI
	drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize);
	fontRenderer.drawString(codeInput, guiLeft, guiTop, 4210752);
	fontRenderer.drawString(output, guiLeft, guiTop + 10, 4210752);
	fontRenderer.drawString(entity.lockCode, guiLeft, guiTop + 20, 4210752);
}

public void initGui(){
	buttonList.clear();
	//buttonList.add(new GuiButton(1, guiLeft, guiTop, 20, 20, "1"));
	buttonList.add(new GuiButton(1, guiLeft + 10, guiTop + 40, 20, 20, "1"));
	buttonList.add(new GuiButton(2, guiLeft + 40, guiTop + 40, 20, 20, "2"));
	buttonList.add(new GuiButton(3, guiLeft + 70, guiTop + 40, 20, 20, "3"));
	buttonList.add(new GuiButton(4, guiLeft + 10, guiTop + 70, 20, 20, "4"));
	buttonList.add(new GuiButton(5, guiLeft + 40, guiTop + 70, 20, 20, "5"));
	buttonList.add(new GuiButton(6, guiLeft + 70, guiTop + 70, 20, 20, "6"));
	buttonList.add(new GuiButton(7, guiLeft + 10, guiTop + 100, 20, 20, "7"));
	buttonList.add(new GuiButton(8, guiLeft + 40, guiTop + 100, 20, 20, "8"));
	buttonList.add(new GuiButton(9, guiLeft + 70, guiTop + 100, 20, 20, "9"));
	buttonList.add(new GuiButton(10, guiLeft + 100, guiTop + 40, 50, 20, "ok"));
}

public void actionPerformed(GuiButton button){
	if(button.id <= 9)
		codeInput += button.displayString.toString();
	else
		if(!entity.hasCode())
			entity.setLockCode(codeInput);
		else
			if(entity.checkInput(codeInput))
				output = "true";
			else
				output = "fasle";
}
}

 

 

Link to comment
Share on other sites

Nice thank you very much. I read some tutorials about packethandler, but didn't figure out how to realize this in my special case (in the tutorials were send messages in chat). The problem is nearly solved, but if you know a tutorial how to send packages between GUI and tile entity I would be happy if you could post a link.

 

greets

MagicHaze

Link to comment
Share on other sites

Hi

 

Here is some more information about Packet Handling in vanilla, which might be useful for background information.

http://greyminecraftcoder.blogspot.com/2013/10/client-server-communication-using.html

 

I think your best bet is to use the custom packet as shown in the tutorial you already looked at.

On the client, send the new code to the server along with the [x,y,z] of the TileEntity using Packet250

On the server, find the TileEntity with that [x,y,z] and set the new code, then send the TileEntity information back to all the Clients using Packet132 (for example see TileEntityMobSpawner.getDescriptionPacket().  (The method name is misleading.))

 

-TGG

 

 

Link to comment
Share on other sites

I copied this code to my project now. It sends packets, it writes/reads fromt the nbt but if i close minecraft and start it again he loads the right passwords from the nbt (i saw it in the console) but if i activate the block again the nbt entry for the password is null. Another problem is, that all blocks get the same password. If i change the password for any block all blocks get these password.

 

Thank you for the link. Looks complicated but ill give it a try.

 

 

 

public class TileEntityCodeLockBlock extends TileEntity {

public String lockCode = "";
public String ausgabe = "";

public TileEntityCodeLockBlock() {

}

public void update(World world) {
	world.notifyBlockChange(xCoord, yCoord, zCoord, 2);
	worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}

@Override
public void readFromNBT(NBTTagCompound nbt) {
   super.readFromNBT(nbt);
   this.lockCode = nbt.getString("codeLock");
   System.out.println("NBT: " + this.lockCode);
   PacketHandlerCodeLockBlock.setIdentificationName(lockCode);
}

@Override
public void writeToNBT(NBTTagCompound nbt) {
   super.writeToNBT(nbt);
   if (PacketHandlerCodeLockBlock.getIdentificationName() != null) {
	   nbt.setString("codeLock", PacketHandlerCodeLockBlock.getIdentificationName());
   }
   System.out.println("NBT - Write");
}
   
public String getName(){
	return lockCode;
}
}

 

 

 

 

 

package codelockmod;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.ref.Reference;

import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.Packet250CustomPayload;
import codelockmod.lib.ModInfo;

import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteStreams;

import cpw.mods.fml.common.network.IPacketHandler;
import cpw.mods.fml.common.network.PacketDispatcher;
import cpw.mods.fml.common.network.Player;

public class PacketHandlerCodeLockBlock implements IPacketHandler {
public static String codeInput;

@Override
public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player) {
	ByteArrayDataInput reader = ByteStreams.newDataInput(packet.data);
	codeInput = reader.readUTF();
}

public static void setIdentificationName(String name) {
	ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
	DataOutputStream dataStream = new DataOutputStream(byteStream);

	try {
		dataStream.writeUTF(name);
	} catch (IOException e) {
		System.err.append("Failed to send identification name packet");
	}

	System.out.println("Packet: " + name);
	PacketDispatcher.sendPacketToServer(PacketDispatcher.getPacket(ModInfo.CHANNEL, byteStream.toByteArray()));
}

public static String getIdentificationName() {
	System.out.println("Packet Read: " + codeInput);
	return codeInput;
}
}

 

 

 

 

Link to comment
Share on other sites

public static String codeInput;

This is why all blocks have the same password.

You don't even use the block coordinates to set the password, how would you expect that to work  ?

 

Yeah, that question wasnt smart. I copied the code from the tutorial i read and changed it step by step (i had to change some code to get it work without the static String). But now i figured out how it to code it and it works well. There is only one more question, i have. Is it possible to realize it without a new packet handler? ATM i am comparing attributes of the tileentity in the gui class (here its the clientcopy of the fileentity, isnt it?) file and comparing/changing them in the packet handler (here its the tileentity of the server, isnt it?). I would like to remove the packethandler and handle the packets directly in the tileentity (looks better for me). Then i would just create a packethelper, that i just need to pass the data for the packet to the packethelper which sends them in a packet (so i wont need to write tons of code for every packet i want to send in the gui class file).

 

Thank you guys, i am very happy that it works now and i think i figured out how sending packets (put the information in a packet, send it, get them on the server side, handle them and by the update method the client gets a copie of the server tileentity?) works.

 

 

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.