Jump to content

1.19.2 Writing and reading HashMap server -> client buf.writeMap() and buf.readMap()


andreybadrey

Recommended Posts

Hello everyone, I'm new, I'm working on an RPG mod and have achieved good results

now I'm working on compressing the package system, namely, I want to combine all the player variable synchronization packages into one multifunctional package

at the moment I have to synchronize each player characteristic with a separate package, because if you combine all the characteristics in one package, then in my opinion this will give a huge load on the server with good online

I want to write a package that will send data to the client in the form of a HashMap()

something like this: if the player's experience is updated, The server sends to the client Map<"exp", 200 000>

If the level of the player has changed during the increase in experience, the server sends to the client Map<"exp", 200 000><"lvl", 3>

The client, having received this packet, reads the entire HashMap in turn, and updates only those data that have been changed and transmitted

 

I am facing the following difficulties:

1. buf.writeMap(Map<K, V> p_236832_, FriendlyByteBuf.Writer<K> p_236833_, FriendlyByteBuf.Writer<V> p_236834_)

as far as I understand Map<K, V> p_236832_  the read source is passed to this parameter, namely the Map() object, I managed to send it

FriendlyByteBuf.Writer<K> & FriendlyByteBuf.Writer<V> I don’t understand how to format it correctly, after many attempts and sorting through everything I already know, it turned out to make these parameters accepted through lambdas and did not cause errors, but most likely it was not correct

2. buf.readMap(FriendlyByteBuf.Reader<K> p_236848_, FriendlyByteBuf.Reader<V> p_236849_)

FriendlyByteBuf.Reader<K> & FriendlyByteBuf.Reader<V> What is it?

because the method returns this.readMap(Maps::newHashMapWithExpectedSize, p_236848_, p_236849_);

I realized that there is a bork in a new map, but again I don’t understand how to count from the transferred map keys & values

please help me to write these two methods in correct syntax

show any example, at least in which it will be clear what data is passed to these methods

Link to comment
Share on other sites

Posted (edited)

It seems that I won one part, but still not completely

public void toBytes(Map<String, Long> map,FriendlyByteBuf buf) {
          buf.writeMap(map, 
(friendlyByteBuf, s) -> {},   (friendlyByteBuf, aLong) -> {});

}

But it's still not right, is it?

and how to arrange {....} ?

 

following the logic, I wrote this


public void toBytes(Map<String, Long> map,FriendlyByteBuf buf) {
buf.writeMap(map, FriendlyByteBuf::writeUtf, FriendlyByteBuf::writeLong);
}

 

in short, I won

Edited by andreybadrey
Link to comment
Share on other sites

Posted (edited)

I saw that the forum was also interested in this topic, so I will prescribe the package template


import com.bodryak.gmod.variables.client.PDC;
import com.google.common.collect.Maps;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.network.NetworkEvent;

import java.util.Map;
import java.util.function.Supplier;

public class PDSyncS2CPacket {
    private final Map<String, Long> toSync ;

    public PDSyncS2CPacket(Map<String, Long> map) {
        this.toSync = map;
    }

    public PDSyncS2CPacket(FriendlyByteBuf buf) {
        this.toSync = buf.readMap(Maps::newHashMapWithExpectedSize,FriendlyByteBuf::readUtf, FriendlyByteBuf::readLong);
    }

    public void toBytes(FriendlyByteBuf buf) {
        buf.writeMap(this.toSync, FriendlyByteBuf::writeUtf, FriendlyByteBuf::writeLong);
    }

    public boolean handle(Supplier<NetworkEvent.Context> supplier) {
        NetworkEvent.Context context = supplier.get();
        context.enqueueWork(() -> {
            // HERE WE ARE ON THE CLIENT!
            if (this.toSync.get("lvl") != null){
                PDC.setLvl(this.toSync.get("lvl"));
                System.out.println("Server send lvl " + this.toSync.get("lvl"));
            }
            if (this.toSync.get("exp") != null){
                PDC.setExp(this.toSync.get("exp"));
                System.out.println("server send exp " + this.toSync.get("exp"));
            }
            if (this.toSync.get("nlv") != null){
                PDC.setNlv(this.toSync.get("nlv"));
                System.out.println("server send exp to next lvl " + this.toSync.get("nlv"));
            }

        });
        return true;
    }
}

Please, I beg you, if all this is not written correctly, give feedback

Edited by andreybadrey
fix error
Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • https://pastebin.com/FaQ43RnJ  Este es un error que me lanza al momento de querer iniciar forge Intente de todo pero no sirve nada. This is an error that I get when I want to start forge. I tried everything but nothing works.
    • It was a stupid Eclipse problem ,the debugger was set to a lower version of java.  In what world would i want my development version different from the debugger version.   ty for looking
    • Caused by: java.lang.NullPointerException: Cannot read field "level" because "this.minecraft" is null This is my first big error when coding. I looked it up, but there are a bunch of references to Dawncraft and not enough to figure out what was going wrong. I found this, but it involves a command and my GUI only opens when you shift + right-click while holding an item. They fixed it by not calling it with a command, but I am not using a command. Here's the render of my menu, which is the only part that changed between it working and not:   @Override public void render(@Nonnull PoseStack mstack, int mouseX, int mouseY, float partialTicks) { int midx = this.width / 2; int midy = this.height / 2; this.renderBackground(mstack); drawCenteredString(mstack, font, I18n.get("config.shape_tool"), midx, 4, 0xC3D1D8); Utils.renderImage(midx - 12, midy, 20, 20, "textures/gui/plus.png", mstack); addRenderableWidget(new Button(midx - 12, midy, 10, 10, Component.translatable(""), this::increaseax)); Utils.renderImage(midx + 12, midy, 20, 20, "textures/gui/minus.png", mstack); addRenderableWidget(new Button(midx + 12, midy, 10, 10, Component.translatable(""), this::decreaseax)); drawCenteredString(mstack, font, String.valueOf(shapetoolax), midx, midy + 10, 0xC3D1D8); super.render(mstack, mouseX, mouseY, partialTicks); } Utils.renderImage is this:   public static void renderImage(int x, int y, int width, int height, String img, PoseStack mstack) { RenderSystem.setShaderColor(1, 1, 1, 1); RenderSystem.enableBlend(); RenderSystem.defaultBlendFunc(); RenderSystem.setShaderTexture(0, new ResourceLocation(PNegative.MODID, img)); blit(mstack, x, y, 0, 0, width, height, width, height); RenderSystem.disableBlend(); } I have used it before and it has worked, so it can't be a problem. 
    • I found a topic  with the very simmilar problems. I run modpack Direwolf20 1.19.2 version from FTB with dedicated server with my friends and i am the only who have this type of crashes. It has been through login process and after 5-6 crashes i can connect. And randombly it could crash me in game but mostly when i am tp'ing using Nether portals etc. I already setted up all privileges for javaw in firewall, flushed dns, reset network settings and etc. Changed java version to from FAQ too. Here's some logs from client side https://gnomebot.dev/paste/1158502890168664194 https://gnomebot.dev/paste/1158187264657063946    
    • Don't know why game keeps crashing after a few seconds or walking towards something, tried removing larger mods and someaddon performance mods but it's not working. Minecraft launchers telling me "Exit Code 1"
  • Topics

×
×
  • Create New...

Important Information

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