Posted February 12, 20223 yr Hi I have a TileEntity and want to save NBT data for this I have the following methods @Override public CompoundNBT getUpdateTag() { // TODO Auto-generated method stub return this.save(new CompoundNBT()); } @Override public SUpdateTileEntityPacket getUpdatePacket() { CompoundNBT compoundnbt = this.getUpdateTag(); return new SUpdateTileEntityPacket(this.worldPosition, 2, compoundnbt); } @Override public CompoundNBT save(CompoundNBT p_189515_1_) { super.save(p_189515_1_); // if (!this.trySaveLootTable(p_189515_1_)) { // ItemStackHelper.saveAllItems(p_189515_1_, this.items); // } LogManager.getLogger().info("save-start"); java.lang.System.out.println("save-start"); ListNBT listnbt = new ListNBT(); LogManager.getLogger(System.modid).info(listnbt.getElementType()); int i = 0; for (String s:list) { System.out.println("save-write-" + i); CompoundNBT compoundnbt = new CompoundNBT(); compoundnbt.putInt("id", i); i++; compoundnbt.putString("message", s); listnbt.add(compoundnbt); } System.out.println("save-save"); p_189515_1_.put("Text", listnbt); System.out.println("save-finished"); return p_189515_1_; } @Override public void load(BlockState p_230337_1_, CompoundNBT p_230337_2_) { super.load(p_230337_1_, p_230337_2_); // this.items = NonNullList.withSize(getContainerSize(), ItemStack.EMPTY); // if (!this.tryLoadLootTable(p_230337_2_)) { // ItemStackHelper.loadAllItems(p_230337_2_, this.items); // } ListNBT lnbt = p_230337_2_.getList("Text", 10); for(int i = 0; i < lnbt.size(); ++i) { CompoundNBT compoundnbt = lnbt.getCompound(i); String ms = compoundnbt.getString("message"); list.add(compoundnbt.getInt("id"), ms); } } However, the save method is not called What am I doing wrong Edited February 12, 20223 yr by ErfinderLabyrinth
February 12, 20223 yr Author Quote Please keep this forum in English. Sorry, forgot to translate the text Quote Use the predefined tag type constants, don't hardcode random magic numbers here. How do I get the predefined tag type constants Quote Show more of your code, specifically the whole TileEntity class, your Block class and the registration for both. Tile Entity Class: package net.lager.system.common.te; import java.util.ArrayList; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; import net.lager.system.System; import net.lager.system.common.container.DisplayC; import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.ItemStackHelper; import net.minecraft.inventory.container.Container; import net.minecraft.inventory.container.INamedContainerProvider; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.ListNBT; import net.minecraft.network.play.server.SUpdateTileEntityPacket; import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.LockableLootTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.IItemProvider; import net.minecraft.util.NonNullList; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TranslationTextComponent; public class DisplayTE extends TileEntity implements ITickableTileEntity, INamedContainerProvider{ public static int slot = 1; @Nonnull public ArrayList<String> list; protected NonNullList<ItemStack> items = NonNullList.withSize(slot, ItemStack.EMPTY); public DisplayTE(TileEntityType<?> tet) { super(tet); java.lang.System.out.println("Item-put"); LogManager.getLogger(System.modid).info("Item-put"); items.add(new ItemStack(new IItemProvider() { @Override public Item asItem() { return Items.ACACIA_BOAT; } })); } public DisplayTE() { this(net.lager.system.init.TileEntity.display.get()); } @Override public void tick() { super.getUpdatePacket(); } @Override public CompoundNBT getUpdateTag() { return this.save(new CompoundNBT()); } @Override public SUpdateTileEntityPacket getUpdatePacket() { CompoundNBT compoundnbt = this.getUpdateTag(); return new SUpdateTileEntityPacket(this.worldPosition, 2, compoundnbt); } /* @Override protected ITextComponent getDefaultName() { return new TranslationTextComponent("container."+ System.modid + ".display"); } @Override protected NonNullList<ItemStack> getItems() { return this.items; } @Override protected void setItems(NonNullList<ItemStack> p_199721_1_) { this.items = p_199721_1_; }*/ @Override public CompoundNBT save(CompoundNBT p_189515_1_) { super.save(p_189515_1_); // if (!this.trySaveLootTable(p_189515_1_)) { // ItemStackHelper.saveAllItems(p_189515_1_, this.items); // } LogManager.getLogger().info("save-start"); java.lang.System.out.println("save-start"); ListNBT listnbt = new ListNBT(); LogManager.getLogger(System.modid).info(listnbt.getElementType()); int i = 0; for (String s:list) { System.out.println("save-write-" + i); CompoundNBT compoundnbt = new CompoundNBT(); compoundnbt.putInt("id", i); i++; compoundnbt.putString("message", s); listnbt.add(compoundnbt); } System.out.println("save-save"); p_189515_1_.put("Text", listnbt); System.out.println("save-finished"); return p_189515_1_; } @Override public void load(BlockState p_230337_1_, CompoundNBT p_230337_2_) { super.load(p_230337_1_, p_230337_2_); // this.items = NonNullList.withSize(getContainerSize(), ItemStack.EMPTY); // if (!this.tryLoadLootTable(p_230337_2_)) { // ItemStackHelper.loadAllItems(p_230337_2_, this.items); // } ListNBT lnbt = p_230337_2_.getList("Text", 10); for(int i = 0; i < lnbt.size(); ++i) { CompoundNBT compoundnbt = lnbt.getCompound(i); String ms = compoundnbt.getString("message"); list.add(compoundnbt.getInt("id"), ms); } } @Override public Container createMenu(int p_createMenu_1_, PlayerInventory p_createMenu_2_, PlayerEntity p_createMenu_3_) { return new DisplayC(p_createMenu_1_, p_createMenu_2_, this); } @Override public ITextComponent getDisplayName() { return null; } } Block Class: package net.lager.system.common.block; import net.lager.system.common.te.DisplayTE; import net.minecraft.block.AbstractBlock; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.material.Material; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ActionResultType; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; import net.minecraftforge.fml.network.NetworkHooks; public class DisplayBlock extends Block{ public DisplayBlock() { super(AbstractBlock.Properties.of(Material.BAMBOO)); } @Override public boolean hasTileEntity(BlockState state) { return true; } @Override public TileEntity createTileEntity(BlockState state, IBlockReader world) { return net.lager.system.init.TileEntity.display.get().create(); } @SuppressWarnings("deprecation") @Override public ActionResultType use(BlockState p_225533_1_, World p_225533_2_, BlockPos p_225533_3_, PlayerEntity p_225533_4_, Hand p_225533_5_, BlockRayTraceResult p_225533_6_) { if (!p_225533_2_.isClientSide) { TileEntity te = p_225533_2_.getBlockEntity(p_225533_3_); if (te instanceof DisplayTE) { NetworkHooks.openGui((ServerPlayerEntity) p_225533_4_, (DisplayTE) te, p_225533_3_); } } return super.use(p_225533_1_, p_225533_2_, p_225533_3_, p_225533_4_, p_225533_5_, p_225533_6_); } } DisplayC Class: package net.lager.system.common.container; import java.util.Objects; import net.lager.system.common.te.DisplayTE; import net.lager.system.init.Block; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.container.Container; import net.minecraft.inventory.container.Slot; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.IWorldPosCallable; public class DisplayC extends Container{ public PlayerInventory inv; public static DisplayTE te; private final IWorldPosCallable canInteractWithCallable; @SuppressWarnings("static-access") public DisplayC(final int window, final PlayerInventory inv, final DisplayTE te) { super(net.lager.system.init.Container.display.get(), window); this.te = te; this.canInteractWithCallable = IWorldPosCallable.create(te.getLevel(), te.getBlockPos()); this.inv = inv; for (int row = 0; row<3; row ++) { for (int col = 0; col < 9;col++) { this.addSlot(new Slot(inv, col + row * 9 + 9, 8 + col * 18, 166 - (4 - row) * 18 - 10)); } } for (int col = 0; col < 9;col++) { this.addSlot(new Slot(inv, col, 8 + col * 18, 142)); } } public DisplayC(final int window, final PlayerInventory inv, final PacketBuffer data) { this(window, inv, getTileEntity(inv, data)); } private static DisplayTE getTileEntity(final PlayerInventory playerInventory, final PacketBuffer data){ Objects.requireNonNull(playerInventory, "Player Inventory cannot be null"); Objects.requireNonNull(data, "Packet Buffer cannot be null"); @SuppressWarnings("unused") final TileEntity tileEntity = playerInventory.player.level.getBlockEntity(data.readBlockPos()); if (te instanceof DisplayTE) { return (DisplayTE) te; } throw new IllegalStateException("Tile Entity is not correct"); } @Override public boolean stillValid(PlayerEntity p_75145_1_) { return stillValid(canInteractWithCallable, p_75145_1_, Block.ITEM.get()); } @Override public ItemStack quickMoveStack(PlayerEntity p_82846_1_, int p_82846_2_) { ItemStack stack = ItemStack.EMPTY; Slot slot = this.slots.get(p_82846_2_); if (slot != null && slot.hasItem()) { ItemStack stack2 = slot.getItem(); stack = stack2.copy(); if (p_82846_2_ < DisplayTE.slot && !this.moveItemStackTo(stack2, DisplayTE.slot, this.slots.size(), true)) { return ItemStack.EMPTY; } if (!this.moveItemStackTo(stack2, 0, DisplayTE.slot, false)) { return ItemStack.EMPTY; } if (stack2.isEmpty()) { slot.set(ItemStack.EMPTY); }else { slot.setChanged(); } } return stack; } } DisplayS Class: package net.lager.system.client.screen; import java.util.HashMap; import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.systems.RenderSystem; import net.lager.system.System; import net.lager.system.Textfeld.TextContainerScreen; import net.lager.system.Textfeld.Textfeld; import net.lager.system.common.container.DisplayC; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.widget.TextFieldWidget; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.util.ResourceLocation; import net.minecraft.util.text.ITextComponent; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @OnlyIn(Dist.CLIENT) public class DisplayS extends TextContainerScreen<DisplayC>{ public static HashMap<String, TextFieldWidget> guistate = new HashMap<String, TextFieldWidget>(); private static final ResourceLocation Display_Gui = new ResourceLocation(System.modid, "/textures/gui/display.png"); private Textfeld textfeld; public DisplayS(DisplayC p_i51105_1_, PlayerInventory p_i51105_2_, ITextComponent p_i51105_3_) { super(p_i51105_1_, p_i51105_2_, p_i51105_3_); this.leftPos = 0; this.topPos = 0; this.inventoryLabelX = 175; this.inventoryLabelY = 201; } @SuppressWarnings("deprecation") @Override protected void renderBg(MatrixStack p_230450_1_, float p_230450_2_, int p_230450_3_, int p_230450_4_) { RenderSystem.color4f(1, 1, 1, 1); // RenderSystem.defaultBlendFunc(); Minecraft.getInstance().getTextureManager().bind(Display_Gui); int k = (this.width - this.inventoryLabelX) / 2; int l = (this.height - this.inventoryLabelY) / 2; // this.blit(p_230450_1_, k, l, 0, 0, this.inventoryLabelX, this.titleLabelY); } @Override protected void renderLabels(MatrixStack p_230451_1_, int p_230451_2_, int p_230451_3_) { } @Override public void render(MatrixStack p_230430_1_, int p_230430_2_, int p_230430_3_, float p_230430_4_) { this.renderBackground(p_230430_1_); super.render(p_230430_1_, p_230430_2_, p_230430_3_, p_230430_4_); this.renderLabels(p_230430_1_, p_230430_2_, p_230430_3_); textfeld.getText( 0 , -300 , this, p_230430_1_, 100); } @SuppressWarnings("static-access") @Override public void init(Minecraft p_231158_1_, int p_231158_2_, int p_231158_3_) { super.init(p_231158_1_, p_231158_2_, p_231158_3_); if (getMenu().te.list == null) { textfeld = new Textfeld(true); } else { textfeld = new Textfeld(true, getMenu().te.list); } this.minecraft.keyboardHandler.setSendRepeatsToGui(true); } @Override public boolean keyPressed(int key, int b, int c) { textfeld.keyPressed(key); java.lang.System.out.println(key); if (key == 256) { return false; } return true; } @Override public void tick() { super.tick(); textfeld.tick(); } @SuppressWarnings("static-access") @Override public void onClose() { super.onClose(); this.minecraft.keyboardHandler.setSendRepeatsToGui(false); getMenu().te.list = textfeld.getArray(); java.lang.System.out.println("save"); } @Override public boolean mouseClicked(double p_231044_1_, double p_231044_3_, int p_231044_5_) { textfeld.Click(p_231044_1_ - 200, p_231044_3_ - 100); return super.mouseClicked(p_231044_1_, p_231044_3_, p_231044_5_); } } TileEntity Registerclass: package net.lager.system.init; import net.lager.system.System; import net.lager.system.common.te.DisplayTE; import net.minecraft.tileentity.TileEntityType; import net.minecraftforge.fml.RegistryObject; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; public class TileEntity { public static final DeferredRegister<TileEntityType<?>> tileentity = DeferredRegister.create(ForgeRegistries.TILE_ENTITIES, System.modid); public static final RegistryObject<TileEntityType<DisplayTE>> display = tileentity.register("display", () -> TileEntityType.Builder.of(DisplayTE::new, Block.ITEM.get()).build(null)); } Container Registerclass: package net.lager.system.init; import net.lager.system.System; import net.lager.system.common.container.DisplayC; import net.minecraft.inventory.container.ContainerType; import net.minecraftforge.common.extensions.IForgeContainerType; import net.minecraftforge.fml.RegistryObject; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; public class Container { public static final DeferredRegister<ContainerType<?>> container = DeferredRegister.create(ForgeRegistries.CONTAINERS, System.modid); public static final RegistryObject<ContainerType<DisplayC>> display = container.register("dc", () -> IForgeContainerType.create(DisplayC::new)); } Block RegisterClass: package net.lager.system.init; import net.lager.system.System; import net.lager.system.common.block.ControllerBlock; import net.lager.system.common.block.DisplayBlock; import net.minecraftforge.fml.RegistryObject; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; public class Block { public static final DeferredRegister<net.minecraft.block.Block> block = DeferredRegister.create(ForgeRegistries.BLOCKS, System.modid); public static final RegistryObject<DisplayBlock> ITEM = block.register("display", () -> new DisplayBlock()); public static final RegistryObject<ControllerBlock> Controller = block.register("controller", () -> new ControllerBlock()); } Have fun reading through Edited February 12, 20223 yr by ErfinderLabyrinth
February 12, 20223 yr Author Quote Constants.NBT. Thank you Quote Why not new ItemStack(Items.ACACIA_BOAT)? Didn't know this was possible Quote Uh, what? This was only temporary to get to the super method getUpdatePacket (I noticed the green arrow to the left of the method afterwards) Quote Why is this static? It makes no sense for it to be. For the static method getTileEntity()? (PS: I have to look here again in the tutorial, because I think that I made a mistake here) Quote You must also call TileEntity#setChanged after changing any data that is saved to disk. What does the method do? Does it send the NBT data to the server? If so, how can I check the NBT data from the server? Edited February 12, 20223 yr by ErfinderLabyrinth Translation from German to English
February 12, 20223 yr Author Quote Neither should be static. However, the getTileEntity() method from the constructor in code this(window, inv, getTileEntity(inv, data)); is called and without the static Java would complain 2.Question: How do I save the NBT(i.e. how do I run the save() method), setChanged() did not work Quote And again: Please keep this forum in English. Sorry, forgot it again, but I just translated it again
February 12, 20223 yr Author Quote You must send a packet to the server with the data. The server must then validate that the player can do this (the client can lie, never trust it blindly). Then the server must save this data. How?????
February 12, 20223 yr Author Thanks for the link, but I don't understand which parameters to pass on registerMessage() (see Registering Packets) Edited February 12, 20223 yr by ErfinderLabyrinth Translation from German to English
February 12, 20223 yr Author Where can I find Forge's code? Edited February 12, 20223 yr by ErfinderLabyrinth Translation from German to English
February 12, 20223 yr Author Under which link are the codes of the tutorial in Github or where can I find the code in the IDE PS: Sorry that I forget to translate some Reply into English, but as soon as I notice this I change it to English
February 12, 20223 yr Author And what is the name of the sample file? According to Eclipse, there is no SimpleImpl class
February 13, 20223 yr Author One more question: How can I check if the code is running at the client or at the server
February 13, 20223 yr Author For the Level class I have the class io.netty.util.ResourceLeakDetector.Level, java.lang.System.Logger.Level, java.util.logging.Level, org.apache.logging.log4j.Level and org.spongepowered.asm.logging.Level, but none of the classes has the method isClientSide(). What am I doing wrong or is the class a subclass of another class?
February 13, 20223 yr Author Sorry I forgot this. I'm still programming on 1.16.5, but will soon switch to 1.18.1+.
February 13, 20223 yr Author But how do I get a world instance(I dont programming this in a class extends TileEntity).
February 13, 20223 yr Author I have now solved the problem like this: DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> /*CODE to execute when the method is executed on the client*/); DistExecutor.unsafeRunWhenOn(Dist.DEDICATED_SERVER, () -> () -> /*CODE to run when the method is executed on the server*/)); Can you solve the problem in this way or does this cause problems?
February 13, 20223 yr Author Thanks for the link. I have now improved the code a bit and I want to know if the code is still causing problems DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> { if (Thread.currentThread().getThreadGroup() == SidedThreadGroups.SERVER) { SimpleChannelMessage.handleServer(msg, ctx); } else { SimpleChannelMessage.handleClient(msg, ctx); } }); DistExecutor.unsafeRunWhenOn(Dist.DEDICATED_SERVER, () -> () -> SimpleChannelMessage.handleServer(msg, ctx));
February 13, 20223 yr Author The only problem is that I build this module-based and I can't be sure if the packet is sent to the server or to the client.
February 13, 20223 yr Author 9 minutes ago, diesieben07 said: Das bedeutet nichts. Sie sind derjenige, der die Nachricht sendet. Dieselbe Nachricht sollte immer vom Client zum Server oder vom Server zum Client gesendet werden, niemals beides. Durch diese Logik wird Ihr Message-Handler immer entweder auf dem Server oder immer auf dem Client ausgeführt. Eine Überprüfung ist daher nicht erforderlich. Unfortunately, I can't prevent this, because you should also write mods on this mod again
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.