Jump to content

[1.16.5] [SOLVED] Block NBT being modified every other tick


NoEffort

Recommended Posts

Long time no see,

I've got this block that I want to update on a button press in it's respective screen. The block data does technically update, but it seems to switch back to it's default values every other tick (or at least, that's what it seems like visibly). Have a look:

Related Code: https://gist.github.com/NoEffort/5cd66d7d5c8165338b9ae89c6036f3c3
The Bug:

Spoiler

image.png.251a96ec0ae3bf3710801f259fd0bfe1.png

 

Edited by NoEffort
Problem Resolved
Link to comment
Share on other sites

There's nothing wrong with your block class.

The reason you're seeing the difference is because there's two threads: the server thread and the client thread. Notice at the left how it says "Server thread" and the next line "Render thread"? You have a synchronization problem.

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

5 minutes ago, Draco18s said:

There's nothing wrong with your block class.

The reason you're seeing the difference is because there's two threads: the server thread and the client thread. Notice at the left how it says "Server thread" and the next line "Render thread"? You have a synchronization problem.

So what you're saying is my Client is correct, but the server is not? The docs lead me to believe I've done everything I should be doing, but it seems like that isn't the case. How can I go about syncing the data correctly?

Link to comment
Share on other sites

Seeing as that logging isn't coming from the block, I can't say. You only shared your block code and the problem isn't in your block code.

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

6 hours ago, diesieben07 said:

I do a combination of these to achieve the same result (on paper, I suppose).

WeatherPedestalTileEntity.java (Snippet):

Spoiler

    @Nonnull
    @Override
    public CompoundNBT save(@Nonnull CompoundNBT nbt) {
        nbt = super.save(nbt);
        nbt.putBoolean("WeatherRain", this.raining);
        nbt.putBoolean("WeatherThunder", this.thundering);
        nbt.putBoolean("WeatherClear", this.clear);
        return nbt;
    }

    @Override
    public void load(@Nonnull BlockState state, @Nonnull CompoundNBT nbt) {
        super.load(state, nbt);
        this.raining = nbt.getBoolean("WeatherRain");
        this.thundering = nbt.getBoolean("WeatherThunder");
        this.clear = nbt.getBoolean("WeatherClear");
    }

    @Nullable
    @Override
    public SUpdateTileEntityPacket getUpdatePacket() {
        return new SUpdateTileEntityPacket(this.getBlockPos(), 1, this.getUpdateTag());
    }

    @Nonnull
    @Override
    public CompoundNBT getUpdateTag() {
        return this.save(new CompoundNBT());
    }

    @Override
    public void handleUpdateTag(BlockState state, CompoundNBT tag) {
        this.load(state, tag);
    }

    @Override
    public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) {
        this.handleUpdateTag(this.getBlockState(), pkt.getTag());
    }

 

 

Link to comment
Share on other sites

Ah yes. I wondered if this was the case.

You're trying to change the weather using a GUI screen.

https://github.com/NoEffort/NuggetMod/blob/main/src/main/java/me/noeffort/nuggetmod/client/screen/WeatherPedestalScreen.java#L82

That code cannot and will not ever work because only the client knows about it.

Edited by Draco18s
  • Thanks 1

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

12 minutes ago, Draco18s said:

That code cannot and will not ever work because only the client knows about it.

How can I resolve this? Network messages? Maybe my design is wrong and I should be using another method?
EDIT: Method, as in plan of attack not functional Java method

Edited by NoEffort
Clarification
Link to comment
Share on other sites

Thanks for all the help guys, praise be the internet!

If you're curious, I created a new message & registered it. Here's the handler for said message:

    public static void handle(WeatherPedestalUpdateMessage message, Supplier<NetworkEvent.Context> context) {
        NetworkEvent.Context ctx = context.get();
        ctx.enqueueWork(() -> {
            ServerPlayerEntity player = ctx.getSender();
            TileEntity tile = player.level.getBlockEntity(message.pos);
            if(tile == null || !player.level.isLoaded(message.pos) || !(tile instanceof WeatherPedestalTileEntity))
                return;
            WeatherPedestalTileEntity pedestal = (WeatherPedestalTileEntity) tile;
            pedestal.setRaining(message.rain);
            pedestal.setThundering(message.thunder);
            pedestal.setClear(message.clear);
            player.level.sendBlockUpdated(message.pos, pedestal.getBlockState(), pedestal.getBlockState(), Constants.BlockFlags.BLOCK_UPDATE);
        });
        ctx.setPacketHandled(true);
    }

I also removed half of my update() method in WeatherPedestalScreen, and replaced it with this single line:

NuggetMod.CHANNEL.sendToServer(new WeatherPedestalUpdateMessage(this.pos, rain, thunder, clear));

 

Link to comment
Share on other sites

  • NoEffort changed the title to [1.16.5] [SOLVED] Block NBT being modified every other tick
22 minutes ago, diesieben07 said:

Do not send the position. The server knows this position by the container the playing is looking at. By sending the position again and blindly trusting it, you allow the client to modify any TE.

Noted and resolved.

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.