Jump to content

[Solved]Letting Client Player know It Needs to read NBT


Recommended Posts

Posted (edited)

Edit: in order to update the player from the server side properly, you have to call on these in preciously this order or it might screw up. If you don't have access to client side next tick and know it's not possible you could try sending alot of packets but, otherwise do this.

Server: dimension change, readfromNBT(),teleport network manager, manually,

fire forge events[player respawn event, if not teleported entity join world event]

 

Client Next Tick: readFromNBT(), player.respawn()  (I think the second one is an animation but, still nice to call on client side)

Edited by jredfox
Posted
7 hours ago, diesieben07 said:

This has nothing to do with NBT, NBT is for saving to disk, which only happens on the server.

What on earth are you trying to achieve?

Fixing a vanilla/forge/mod specific bug which for a split second has a reading error and wipes your playerdata. So I cache the playerdata and on event of uuid change from it grabs your username cache and tries to make the player read NBT.

 

So I need to know the proper way to make the player update all playerdata, dimension,xyz,inventory, custom forge data, custom properties

Posted (edited)
7 minutes ago, diesieben07 said:

Please clarify when exactly this bug occurs. It should be fixed in Forge if it really is a bug.

It occurs in plain vanilla sometimes, it occurs more when forge is installed, and occurs alot with certain mods.

 

It occurs sometimes randomly in game with a modpack

It occurs alot more if the world doesn't open right just sends you back to the main screen then you double click on the world says shutting down internal server then changes uuid next thing you know your player data is a new playerdata

 

That isn't the point though I would want to know regardless if it get's fixed or not the proper way to update an entire playerdata to the player.

Edited by jredfox
Posted
12 minutes ago, diesieben07 said:

There is no "entire playerdata". The necessary data for the player is synced to the player via some DataParameters in EntityPlayer and some other various packets. You should never have to sync anything manually.

 

You still have not described what the actual bug is, you just described when it occurs. What happens exactly, why is it wrong and what should happen instead?

When your uuid changes it creates you a new playerdata aka your inventory wipes , your dimension overoworld,you pos is at spawn, all you aoa levels gone, your hunger and hearts full etc... 

 

I can't pinpoint where and when It occurs the information given is the most I have seen from it. All I know is it changes the uuid when it has an exception.

Posted
Just now, diesieben07 said:

That is true, however your UUID doesn't just change. That's the point of the UUID.

no you uuid does change and it's synced with the playerdata as proof. first is 6abf... after the bug occurs it's now synced with 86da...

 

So when I cache the playerdata to a file on uuid change I use that playerdata but, I need the player to update all of it's playerdata. You still haven't explained on how to do this. What if I wanted to change the playerdata to someone else's via command dimension pos everything?

Posted (edited)
18 minutes ago, diesieben07 said:

If the UUID really does change, then the fix is not to somehow muck about with the playerdata, but to stop the UUID from changing.

If you are logged in (and if you aren't logged in, there is your problem), your UUID should never change.

 

If you want to change the "playerdata" (whatever you mean by that, you still have not explained that), you call the methods on EntityPlayer to change it. For example if you want to change the game mode for a player, you call EntityPlayer::setGameType. It will automatically update the client.

Well it has and has been doing so in versions 1.7.10+ it's because it had an error reading the playerdata according to the console.

 

I want to update Broken new Players playerdata > with cached playerdata. It involves every single piece of player NBT being updated on both client and server.

 

Don't worry I know how to pull the nbt from the cached file I just don't know how to properly update the player's nbt from there.

Edited by jredfox
Posted (edited)
5 minutes ago, diesieben07 said:

Post that error.

next time it happens I will it doesn't happen too often...

Quote

The client does not have NBT data. And this is not the correct way to fix this issue. A changed UUID will cause issues all over the place, and just monkeying around with "cached playerdata" (whatever the f*** that means) is not going to fix this properly.

clearly you don't know more then I have debugged. Without the client reading the nbt it will not change position, I have manullay tried to sync them but, it didn't work across dimensions.

 

The cached playerdata is the players entire NBT transferred and upon use I get the current uuid most and least before I make the player read it. 

5 minutes ago, diesieben07 said:

A player does not have "nbt". The NBT exists on disk and is then deserialized and applied to the player. It does not exist beyond that point.

If that were true player.writeToNBT(nbt); wouldn't work which in a matter of fact it does.

NBT read and write works like this.

write to nbt > writes it to an nbttagcompound

read > from nbttagcompound > variables 

In order to update the player I need to call player.readFromNBT(...) but, I need to sync it the way it works normally I don't know how to do this this is what I am asking

Edited by jredfox
Posted
1 minute ago, diesieben07 said:

Once again, the client never "reads nbt". The client has no access to the player's NBT file on disk.

 

Yes it does. Now, what do you do with that NBTTagCompound?

 

You don't have to explain serialization to me, I am not stupid. But using it like you are trying to use it is not how it is designed and you should not be doing it.

 

This never happens "normally". The player is deserialized from NBT only on the server and only the necessary data is transferred to the client via DataParameters (formerly DataWatcher) and other packets (such as SPacketPlayerAbilities).

Ok so the server sends packets to the client of the player? Are there any forge packets I should be aware of like forgedata tag? This is great news. What package is this located in the vanilla ones and forges if any? Once I find all these packets I could have a player update method in no time.

Posted (edited)
2 minutes ago, diesieben07 said:

There is no centralized place that this happens. Once again, please do not do this. It will not fix the issue.

what will then? I am not aiming to try and fix the uuid change I am trying to if an exception occurs/corruption/uuid change of the playerdata I plan on updating playerdata. 

 

I mean if forge is willing to put a tick event with my ideas of playerdata cache or just fix it entirely by making everything use playerdata by username then yes that would fix the issue and be nice. But, I doubt they would fix anything more then the uuid changing.

Edited by jredfox
Posted

Ah, good old http://xyproblem.info/

  • Like 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.

Posted (edited)
5 minutes ago, diesieben07 said:

That can not be known without knowing what the actual issue is. So far you have not even provided a stacktrace or any kind of proper error report, much less a way to reproduce it.

 

What exception are you talking about? What "corruption" are you talking about? UUID does not change. The UUID is permanently bound to your Mojang account. If it changes in your local data, then your whole save will be screwed up (wolves won't be associated with your player anymore, just for a start).

If you have an issue where the UUID does change, that must be fixed. Trying to work around a bug that causes the UUID to change is like trying to build a house on quicksand and then trying to stop it from sinking by just building faster. Your issue is not that you're not building fast enough, you need to fix the quicksand issue. Here your issue is not that playerdata is getting lost, your issue is that the UUID changes, which it must never do. You must fix the ground cause of the problem, not try to duct tape things together, it won't work.

there is more then one issue then the uuid changing it's playerdata file corruption alot more rarer but, I have had it happen once or twice in modpacks. I can't recreate it so I can't tell you anything.

I will post a log next time uuid changes here....

Edited by jredfox
Posted (edited)
5 minutes ago, diesieben07 said:

1.7.10 is no longer supported on this forum.

You wanted me to reproduce the bug yes? It occurs the most in 1.7.10 yes? Then when I go back and give the file you do this?

 

My primary goal is actually 1.10.2 but, I need to re-write some stuff. I need to revert the combat system this is the main function of EvilNotchCore mod but, I can't do that till I learn some core modding. Yes it will fix vanilla issues as well like bucket events. Yes I might request several forge pulls sooner or later but, first I want stuff like 1.10.2 to be playable as in no new combat system, and minimum bugs.

 

the problem is that I want the player to update based on cached nbt that I store in a file.

 

The issue is I need to make an update method. How does the world when loading load the player into being I am sure if I copy and paste stuff from that it would work on updating the player.

Edited by jredfox
Posted (edited)

zdoctor figured it out just teleport the player to the location and it will update everything.... after you call read from nbt on both client and server. Haven't tested it but, he is sure you need the read from nbt on client

Edited by jredfox
Posted (edited)
50 minutes ago, diesieben07 said:

He is most definitely wrong.

I think I found some of that out tonight could you please take a look at our code to update the player? pretend the NBT came from the cache. The issue with his update method is it updates everything across dimensions but, isn't syncing with forgedata and other stuff like with other mods

 

@SubscribeEvent(priority = EventPriority.HIGHEST)
public void inventoryFixer(TickEvent.PlayerTickEvent e) {
    World worldIn = e.player.getEntityWorld();
    EntityPlayer playerIn = e.player;
    // Implemet your loading
    NBTTagCompound playerNBT = playerIn.getEntityData();

    if (!playerIn.isDead) {
        int currentDimension = playerIn.dimension;
        int dimensionIn = playerNBT.getInteger("Dimension");

        NBTTagCompound tempNBT = playerNBT.copy();
        tempNBT.setInteger("Dimension", currentDimension);

        if (currentDimension != dimensionIn) {
            if (!worldIn.isRemote) {
                EntityPlayerMP playerMP = (EntityPlayerMP) playerIn;

                SilentTeleport teleporter = new SilentTeleport(playerMP.getServer().getWorld(dimensionIn)) {
                    @Override
                    public boolean placeInExistingPortal(Entity entityIn, float rotationYaw) {
                        super.placeInExistingPortal(entityIn, rotationYaw);
                        playerIn.readFromNBT(playerNBT);
                        return false;
                    }
                };

                playerMP.getServer().getPlayerList().transferPlayerToDimension(playerMP, dimensionIn, teleporter);
            }

        } else {
            playerIn.readFromNBT(playerNBT);
        }
    }
}

 

And Also The teleporter class

package zdoctor.testmod;

import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.world.Teleporter;
import net.minecraft.world.WorldServer;

public class SilentTeleport extends Teleporter {

	public SilentTeleport(WorldServer worldIn) {
		super(worldIn);
	}

	public void silentTransferToDimension(Entity entityIn) {

	}

	@Override
	public boolean placeInExistingPortal(Entity entityIn, float rotationYaw) {
		System.out.println("teleporting silently");
		double d5 = entityIn.posX;
		double d6 = entityIn.posY;
		double d7 = entityIn.posZ;

		if (entityIn instanceof EntityPlayerMP) {
			((EntityPlayerMP) entityIn).connection.setPlayerLocation(d5, d6, d7, entityIn.rotationYaw,
					entityIn.rotationPitch);
		} else {
			entityIn.setLocationAndAngles(d5, d6, d7, entityIn.rotationYaw, entityIn.rotationPitch);
		}
		
		return false;
	}

	@Override
	public void placeInPortal(Entity entityIn, float rotationYaw) {
		placeInExistingPortal(entityIn, rotationYaw);
//		super.placeInPortal(entityIn, rotationYaw);
	}

	@Override
	public void removeStalePortalLocations(long worldTime) {
//		super.removeStalePortalLocations(worldTime);
	}

	@Override
	public boolean makePortal(Entity entityIn) {
		return super.makePortal(entityIn);
	}
}

 

Edited by jredfox
Posted
Just now, diesieben07 said:

getEntityData does not do what you think it does. And this just goes to show that you have no clue what on earth you are doing.

I really have no idea what you are trying to do with this code.

 

I said pretend like it's the cache he get's the entity data from a stick. He wrote this for me so I could fix it up but, after dev testing it doesn't fully work as intended 
https://github.com/Z-Doctor/TestTeleport/blob/master/TestUpdate/src/main/java/zdoctor/testmod/init/ZItems.java

He is attempting to cache all playerdata to an item right click on it and then get everything backed and all synced up

Posted (edited)
2 minutes ago, diesieben07 said:

Which is not at all how any of this works.

He caches the nbt of the player by right click empties inventory goes to a different dimension that part works but, not everything, yes the inventory comes back but, stuff like the rpg mods levels haven't.

 

The Item:

https://github.com/Z-Doctor/TestTeleport/blob/master/TestUpdate/src/main/java/zdoctor/testmod/init/ZItems.java

 

The Teleporter class:

https://github.com/Z-Doctor/TestTeleport/blob/master/TestUpdate/src/main/java/zdoctor/testmod/SilentTeleport.java

Edited by jredfox
Posted (edited)
2 minutes ago, diesieben07 said:

Yes, because not everything related to a player might save to that player's NBT.

Things might be stored globally in a WorldSavedData indexed by UUID. Which is why the UUID must never change. Never. If it does, everything breaks.

Wait what if some stuff get's stored on client and other stuff doesn't? What we cached everything only on the server and it's missing tags. Or it needs another reading after everything is done?

Or packets but, I don't see how I would create such and update method.

Edited by jredfox
Posted
Just now, diesieben07 said:

The client does not permanently store game data. Only the server does.

ok that helps will be debugging their nbt's and if that's not any different I need you to try and tell me or lead me to all the packets the player uses and with forge so I can create an update method.

Posted
4 minutes ago, diesieben07 said:

You will never find them all. Mods have their own stuff that is synced, etc.

Well then upon loading a world how does it know what data to pull and where to make the player read and write on which side? I would like to know where that class is because, it might be the solution.

Posted (edited)
16 hours ago, diesieben07 said:

The player does not "read" or "write".

Mods can sync their data in various ways. For a continuously synced value you usually use PlayerLoggedInEvent for the initial sync and then just send a new packet whenever the data changes. Then there are also values which must be known not only by the actual client player but by players around them (e.g. for visual effects on the player model). These values are synced via an additional event (PlayerEvent.StartTracking) and the value also gets send to all tracking players when it changes. There is no central hub for "please send all data about this player to all necessary targets".

There might even be data that is only ever synchronized once when needed. And some mods employ the (terrible, but oh well) practice of the client requesting data with a packet and the server only then sending it over.

Ok let's do it this way since it's a terrible process. How do I fool the server and client into thinking that it's changed dimensions as if you just went to the nether by normal means without actually teleportation? I can teleport the player across dimensions but, it's still not updating so what is the difference? Second off I know that the player client does have nbt so I don't know what your talking about it had the forge data with rpg mods printed only on the client.

If I use /kill everything updates what does the death of the player do that makes it update all playerdata? Don't tell me it doesn't I already confirmed this.

Edited by jredfox
Posted (edited)
9 hours ago, diesieben07 said:

Please clarify what the "forge data with rpg mods" is.

 

Just because you changed dimensions does not mean everything is magically sent over.

/kill command > respawn or vanilla teleport everything is updated with the exception in dimension change  the hearts/experiance don't update. The hearts don't update with TConstruct/Aether health.

 

The data is in ForgeData:{PlayerPersisted:{//tags go here}} it's something like that and it's synced to a gui with text and numbers.

Edited by jredfox
Posted
18 hours ago, diesieben07 said:

This is an outdated and antiquated way of storing data on players.

 

Sorry, I have no idea what you are trying to say.

When you die your entire playerdata updates

Posted (edited)
2 hours ago, diesieben07 said:

Please stop referring to this concept of "playerdata". It only exists on disk, which we do not care about.

if your not going to help why do you waist my time. I simply asked how do I fool the game into thinking that the player has re-logged into the world or has died fully?

 

By playerdata I refer to the entire players stats, nbt and other stuff written to the disk that I attempt to grab and try to update, the entire playerdata is updated on relog into world and on death. So by playerdata I mean the stats you wanted me to stop calling it NBT since it is nbt reading/writing just across a file on world re-log and packets

Edited by jredfox
  • 2 weeks later...
Posted (edited)
On 9/21/2017 at 6:08 AM, diesieben07 said:

No, you did not. Now that you (kind of) did: You can't.

 

You say you mean the "stuff written to disk". That stuff is not "updated" on death. Dying does not load your playerdata from disk.

 

Again you waisted my time without actually helping me. 

 

You can fool the client that he/she has respawn by simply firing the forge event yourself. I sent the player to another dimension readfromnbt, fired the respawn event then on next tick let the client know that it has new nbt by calling readFromNBT when it has detected an error. This is an official update method I could do alot more with this if I felt like it. 

 

For older versions for AoA compatibility this was made for a fix for AoA yes I will update to 1.10.2

if(currentdim != cached_nbt.getInteger("Dimension"))
				MinecraftServer.getServer().getConfigurationManager().transferPlayerToDimension(player,cached_nbt.getInteger("Dimension") , new CustomTeleport(player.mcServer.worldServerForDimension(currentdim)));
			e.player.readFromNBT(cached_nbt);
			player.playerNetServerHandler.setPlayerLocation(e.player.posX, e.player.posY, e.player.posZ, e.player.cameraYaw, e.player.cameraPitch);
			FMLCommonHandler.instance().firePlayerRespawnEvent(player);//Make Mods Compatible

 

Edited by jredfox

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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Version 1.19 - Forge 41.0.63 I want to create a wolf entity that I can ride, so far it seems to be working, but the problem is that when I get on the wolf, I can’t control it. I then discovered that the issue is that the server doesn’t detect that I’m riding the wolf, so I’m struggling with synchronization. However, it seems to not be working properly. As I understand it, the server receives the packet but doesn’t register it correctly. I’m a bit new to Java, and I’ll try to provide all the relevant code and prints *The comments and prints are translated by chatgpt since they were originally in Spanish* Thank you very much in advance No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. MountableWolfEntity package com.vals.valscraft.entity; import com.vals.valscraft.network.MountSyncPacket; import com.vals.valscraft.network.NetworkHandler; import net.minecraft.client.Minecraft; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.animal.Wolf; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.Entity; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.network.PacketDistributor; public class MountableWolfEntity extends Wolf { private boolean hasSaddle; private static final EntityDataAccessor<Byte> DATA_ID_FLAGS = SynchedEntityData.defineId(MountableWolfEntity.class, EntityDataSerializers.BYTE); public MountableWolfEntity(EntityType<? extends Wolf> type, Level level) { super(type, level); this.hasSaddle = false; } @Override protected void defineSynchedData() { super.defineSynchedData(); this.entityData.define(DATA_ID_FLAGS, (byte)0); } public static AttributeSupplier.Builder createAttributes() { return Wolf.createAttributes() .add(Attributes.MAX_HEALTH, 20.0) .add(Attributes.MOVEMENT_SPEED, 0.3); } @Override public InteractionResult mobInteract(Player player, InteractionHand hand) { ItemStack itemstack = player.getItemInHand(hand); if (itemstack.getItem() == Items.SADDLE && !this.hasSaddle()) { if (!player.isCreative()) { itemstack.shrink(1); } this.setSaddle(true); return InteractionResult.SUCCESS; } else if (!level.isClientSide && this.hasSaddle()) { player.startRiding(this); MountSyncPacket packet = new MountSyncPacket(true); // 'true' means the player is mounted NetworkHandler.CHANNEL.sendToServer(packet); // Ensure the server handles the packet return InteractionResult.SUCCESS; } return InteractionResult.PASS; } @Override public void travel(Vec3 travelVector) { if (this.isVehicle() && this.getControllingPassenger() instanceof Player) { System.out.println("The wolf has a passenger."); System.out.println("The passenger is a player."); Player player = (Player) this.getControllingPassenger(); // Ensure the player is the controller this.setYRot(player.getYRot()); this.yRotO = this.getYRot(); this.setXRot(player.getXRot() * 0.5F); this.setRot(this.getYRot(), this.getXRot()); this.yBodyRot = this.getYRot(); this.yHeadRot = this.yBodyRot; float forward = player.zza; float strafe = player.xxa; if (forward <= 0.0F) { forward *= 0.25F; } this.flyingSpeed = this.getSpeed() * 0.1F; this.setSpeed((float) this.getAttributeValue(Attributes.MOVEMENT_SPEED) * 1.5F); this.setDeltaMovement(new Vec3(strafe, travelVector.y, forward).scale(this.getSpeed())); this.calculateEntityAnimation(this, false); } else { // The wolf does not have a passenger or the passenger is not a player System.out.println("No player is mounted, or the passenger is not a player."); super.travel(travelVector); } } public boolean hasSaddle() { return this.hasSaddle; } public void setSaddle(boolean hasSaddle) { this.hasSaddle = hasSaddle; } @Override protected void dropEquipment() { super.dropEquipment(); if (this.hasSaddle()) { this.spawnAtLocation(Items.SADDLE); this.setSaddle(false); } } @SubscribeEvent public static void onServerTick(TickEvent.ServerTickEvent event) { if (event.phase == TickEvent.Phase.START) { MinecraftServer server = net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer(); if (server != null) { for (ServerPlayer player : server.getPlayerList().getPlayers()) { if (player.isPassenger() && player.getVehicle() instanceof MountableWolfEntity) { MountableWolfEntity wolf = (MountableWolfEntity) player.getVehicle(); System.out.println("Tick: " + player.getName().getString() + " is correctly mounted on " + wolf); } } } } } private boolean lastMountedState = false; @Override public void tick() { super.tick(); if (!this.level.isClientSide) { // Only on the server boolean isMounted = this.isVehicle() && this.getControllingPassenger() instanceof Player; // Only print if the state changed if (isMounted != lastMountedState) { if (isMounted) { Player player = (Player) this.getControllingPassenger(); // Verify the passenger is a player System.out.println("Server: Player " + player.getName().getString() + " is now mounted."); } else { System.out.println("Server: The wolf no longer has a passenger."); } lastMountedState = isMounted; } } } @Override public void addPassenger(Entity passenger) { super.addPassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(true)); } } } @Override public void removePassenger(Entity passenger) { super.removePassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is no longer mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(false)); } } } @Override public boolean isControlledByLocalInstance() { Entity entity = this.getControllingPassenger(); return entity instanceof Player; } @Override public void positionRider(Entity passenger) { if (this.hasPassenger(passenger)) { double xOffset = Math.cos(Math.toRadians(this.getYRot() + 90)) * 0.4; double zOffset = Math.sin(Math.toRadians(this.getYRot() + 90)) * 0.4; passenger.setPos(this.getX() + xOffset, this.getY() + this.getPassengersRidingOffset() + passenger.getMyRidingOffset(), this.getZ() + zOffset); } } } MountSyncPacket package com.vals.valscraft.network; import com.vals.valscraft.entity.MountableWolfEntity; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class MountSyncPacket { private final boolean isMounted; public MountSyncPacket(boolean isMounted) { this.isMounted = isMounted; } public void encode(FriendlyByteBuf buffer) { buffer.writeBoolean(isMounted); } public static MountSyncPacket decode(FriendlyByteBuf buffer) { return new MountSyncPacket(buffer.readBoolean()); } public void handle(NetworkEvent.Context context) { context.enqueueWork(() -> { ServerPlayer player = context.getSender(); // Get the player from the context if (player != null) { // Verifies if the player has dismounted if (!isMounted) { Entity vehicle = player.getVehicle(); if (vehicle instanceof MountableWolfEntity wolf) { // Logic to remove the player as a passenger wolf.removePassenger(player); System.out.println("Server: Player " + player.getName().getString() + " is no longer mounted."); } } } }); context.setPacketHandled(true); // Marks the packet as handled } } networkHandler package com.vals.valscraft.network; import com.vals.valscraft.valscraft; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.network.NetworkRegistry; import net.minecraftforge.network.simple.SimpleChannel; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class NetworkHandler { private static final String PROTOCOL_VERSION = "1"; public static final SimpleChannel CHANNEL = NetworkRegistry.newSimpleChannel( new ResourceLocation(valscraft.MODID, "main"), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals ); public static void init() { int packetId = 0; // Register the mount synchronization packet CHANNEL.registerMessage( packetId++, MountSyncPacket.class, MountSyncPacket::encode, MountSyncPacket::decode, (msg, context) -> msg.handle(context.get()) // Get the context with context.get() ); } }  
    • Do you use features of inventory profiles next (ipnext) or is there a change without it?
    • Remove rubidium - you are already using embeddium, which is a fork of rubidium
  • Topics

×
×
  • Create New...

Important Information

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