grand_gibus Posted May 9, 2017 Posted May 9, 2017 Hello everyone, I'd like to make a client gui that updates a tile entitie data, on server and client side, and for every player. How would I go about doing that? I looked at the command block gui, it sends a packet to somewhere but I don't know what happens next. Also, totally unrealted: I made a TESR that renders stuff in a large area. The thing is, that if you look away from the tile entity block, the render disepears where I'd like to still be able to see the render. How could I fix that? The StructureBlock TESR has a field @Override public boolean isGlobalRenderer(TileEntityStructure te) { return true; } ,but I tried to integrate it and it didn't change anything, so yeah. Thanks in advance! Quote
tattyseal Posted May 9, 2017 Posted May 9, 2017 To send data to the server you would have to create a custom packet (IMessage) along with a handler (IMessageHandler) and a NetworkWrapper for your mod using NetworkRegistry.INSTANCE.newSimpleChannel. All it'd have to do is contain the relevant data (x,y,z) and on the handler get the tile entity at that location and update your data. Hope this helps in some way 1 Quote
grand_gibus Posted May 9, 2017 Author Posted May 9, 2017 Thank you for the answer. When I tried to make the gui and tile entity, I did a thing that sent a packet and updated the server tile entity. But it the problem seemed that the server wasnt updating the client tile entities Quote
Abastro Posted May 10, 2017 Posted May 10, 2017 On 5/9/2017 at 7:12 PM, grand_gibus said: I made a TESR that renders stuff in a large area. The thing is, that if you look away from the tile entity block, the render disepears where I'd like to still be able to see the render. How could I fix that? Expand Override TileEntity::getRenderBoundingBox to return appropriate size of the rendered object. On 5/9/2017 at 10:03 PM, grand_gibus said: But it the problem seemed that the server wasnt updating the client tile entities Expand If it's about rendering, you are not marking the TE as updated for rendering. I think you should call World#markAndNotifyBlock. (The flag parameter is explained on World#setBlockState) 2 Quote I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP) II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.
grand_gibus Posted May 10, 2017 Author Posted May 10, 2017 Thanks Abastro! It works for the TESR. For the TileEntity, where should I call the World#markAndNotifyBlock from? I've tried on both sides with no success. Quote
Abastro Posted May 10, 2017 Posted May 10, 2017 On 5/10/2017 at 12:17 PM, grand_gibus said: Thanks Abastro! It works for the TESR. For the TileEntity, where should I call the World#markAndNotifyBlock from? I've tried on both sides with no success. Expand It should work on either side, as it sends the update packet. How and where did you call it? Also how are you syncing the tileentity? Please post the relevant code. Quote I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP) II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.
grand_gibus Posted May 10, 2017 Author Posted May 10, 2017 Here is my code: (TileEntity, IMessage, IMessageHandler, Client GUI) public class TileEntityWorkBench extends TileEntity{ private String schematicName = ""; public TileEntityWorkBench(){ } public void updateSchematicName(String name){ this.schematicName = name; } public String getSchematicName(){ return this.schematicName; } public void readFromNBT(NBTTagCompound compound) { this.schematicName = compound.getString("schematicName"); super.readFromNBT(compound); } public NBTTagCompound writeToNBT(NBTTagCompound compound) { NBTTagCompound nbt = super.writeToNBT(compound); nbt.setString("schematicName", schematicName); return nbt; } @Override public AxisAlignedBB getRenderBoundingBox(){ return INFINITE_EXTENT_AABB; } } public class ServerMessage implements IMessage { public ServerMessage(){} public int messageType; public NBTTagCompound tag; public ServerMessage(int messageType, NBTTagCompound tag) { this.tag = tag; this.messageType = messageType; } @Override public void toBytes(ByteBuf buf) { buf.writeInt(messageType); ByteBufUtils.writeTag(buf, tag); } @Override public void fromBytes(ByteBuf buf) { this.messageType = buf.readInt(); this.tag = ByteBufUtils.readTag(buf); } public static ServerMessage createUpdateWorkbenchMessage(int x, int y, int z, String schematicName){ NBTTagCompound nbt = new NBTTagCompound(); nbt.setString("schematicname", schematicName); nbt.setInteger("x", x); nbt.setInteger("y", y); nbt.setInteger("z", z); return new ServerMessage(ServerReciever.UPDATE_WORKBENCH_MESSAGE, nbt); } } public class ServerReciever implements IMessageHandler<ServerMessage, IMessage> { public static final int UPDATE_WORKBENCH_MESSAGE = 0; @Override public IMessage onMessage(ServerMessage message, MessageContext ctx) { switch(message.messageType){ case UPDATE_WORKBENCH_MESSAGE: updateWorkBenchInfo(message, ctx.getServerHandler().playerEntity.getServerWorld()); break; default: break; } return null; } public static void updateWorkBenchInfo(ServerMessage message, WorldServer world){ NBTTagCompound nbt = message.tag; TileEntityWorkBench workbench = (TileEntityWorkBench) world.getTileEntity(new BlockPos(nbt.getInteger("x"), nbt.getInteger("y"), nbt.getInteger("z"))); workbench.updateSchematicName(nbt.getString("schematicname")); BlockPos pos = new BlockPos(nbt.getInteger("x"), nbt.getInteger("y"), nbt.getInteger("z")); world.markAndNotifyBlock(pos, null, world.getBlockState(pos), world.getBlockState(pos), 1); return; } } public class GuiWorkBench extends GuiScreen{ public TileEntityWorkBench workbench; public BlockPos position; private GuiButton exportButton; private GuiTextField schematicName; public GuiWorkBench(TileEntityWorkBench workbench){ this.workbench = workbench; this.position = workbench.getPos(); } @Override public void initGui() { this.workbench = (TileEntityWorkBench) this.mc.world.getTileEntity(this.position); super.initGui(); this.buttonList.add(this.exportButton = new GuiButton(0, this.width / 2 - 100, this.height / 2 + 30, MillenaireLanguage.getGuiTraduction("workbench.export_button", new Object[0]))); this.schematicName = new GuiTextField(1, fontRendererObj, this.width / 2 - 90, this.height / 2, 180, 20); this.schematicName.setText(this.workbench.getSchematicName()); Keyboard.enableRepeatEvents(true); } @Override public void drawScreen(int mouseX, int mouseY, float partialTicks) { String welcomeText = MillenaireLanguage.getGuiTraduction("workbench.welcome", new Object[] {this.mc.player.getName()}); this.drawDefaultBackground(); super.drawScreen(mouseX, mouseY, partialTicks); this.schematicName.drawTextBox(); this.schematicName.setFocused(true); this.schematicName.updateCursorCounter(); this.drawCenteredString(mc.fontRendererObj, welcomeText, this.width / 2 , this.height / 2 - 24, 0xFFFFFF); } @Override protected void actionPerformed(GuiButton button) throws IOException { if (button == this.exportButton) { MillenaireNetwork.sendToServer(ServerMessage.createUpdateWorkbenchMessage(this.position.getX(), this.position.getY(), this.position.getZ(), schematicName.getText())); this.mc.displayGuiScreen(null); if (this.mc.currentScreen == null){ this.mc.setIngameFocus(); } } } /** * Returns true if this GUI should pause the game when it is displayed in single-player */ public boolean doesGuiPauseGame() { return false; } /** * Fired when a key is typed (except F11 which toggles full screen). This is the equivalent of * KeyListener.keyTyped(KeyEvent e). Args : character (character on the key), keyCode (lwjgl Keyboard key code) */ protected void keyTyped(char typedChar, int keyCode) throws IOException{ if(keyCode == 1){ this.mc.displayGuiScreen(null); if (this.mc.currentScreen == null){ this.mc.setIngameFocus(); } }else{ this.schematicName.textboxKeyTyped(typedChar, keyCode); } } /** * Called when the screen is unloaded. Used to disable keyboard repeat events */ public void onGuiClosed() { Keyboard.enableRepeatEvents(false); } public class MathGuiButton extends GuiButton{ public MathGuiButton(int buttonId, int x, int y, String buttonText) { super(buttonId, x, y, buttonText); this.width = 20; this.height = 20; } } } Sorry, didn't know what would be the most relevant code to show Quote
Abastro Posted May 11, 2017 Posted May 11, 2017 So it's client->server update from the gui. You need to implement tileentity syncing. I think this post will cover your case. You can manually read the data from the update packet with TileEntity#onDataPacket. Use it if you don't want readFromNBT to do the work. (e.g. update packet has a different format) 1 Quote I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP) II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.
grand_gibus Posted May 11, 2017 Author Posted May 11, 2017 Thank you Abastro! It didn't really work out in the first place but then I messed a bit around and it ended up working by adding an onDataPacket() override . Here is my code if anyone from the future has this problem: @Override public void readFromNBT(NBTTagCompound compound) { this.schematicName = compound.getString("schematicName"); super.readFromNBT(compound); } @Override public NBTTagCompound writeToNBT(NBTTagCompound compound) { NBTTagCompound nbt = super.writeToNBT(compound); nbt.setString("schematicName", schematicName); return nbt; } @Override public NBTTagCompound getUpdateTag() { return this.writeToNBT(new NBTTagCompound()); } @Nullable @Override public SPacketUpdateTileEntity getUpdatePacket() { return new SPacketUpdateTileEntity(this.getPos(), 1, this.getUpdateTag()); } @Override public void onDataPacket(net.minecraft.network.NetworkManager net, net.minecraft.network.play.server.SPacketUpdateTileEntity pkt) { this.readFromNBT(pkt.getNbtCompound()); } When the client the custom server packet handler recieve a message from the client gui, it executes this code: public static void updateWorkBenchInfo(ServerMessage message, WorldServer world){ NBTTagCompound nbt = message.tag; TileEntityWorkBench workbench = (TileEntityWorkBench) world.getTileEntity(new BlockPos(nbt.getInteger("x"), nbt.getInteger("y"), nbt.getInteger("z"))); workbench.updateSchematicName(nbt.getString("schematicname")); BlockPos pos = new BlockPos(nbt.getInteger("x"), nbt.getInteger("y"), nbt.getInteger("z")); world.markAndNotifyBlock(pos, null, world.getBlockState(pos), world.getBlockState(pos), 2); return; } Quote
Recommended Posts
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.