Jump to content

Recommended Posts

Posted

Hello i want to save some data to world and i have the WorldSavedData implementation but i am not sure what i shloud fill in those functions and how to add data docs are not really too clear about that all they say is "The existing data can be obtained using MapStorage#getOrLoadData, and new data can be attached using MapStorage#setData". Wich does not really tell me much i have this code:

package io.github.lukas2005.spymod;

import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import net.minecraft.world.WorldSavedData;
import net.minecraft.world.storage.MapStorage;

public class MyWorldSavedData extends WorldSavedData {
	private static final String DATA_NAME = Reference.MOD_ID + "_MyWorldSavedData";
	
	
	public MyWorldSavedData() {
		super(DATA_NAME);
	}


	@Override
	public void readFromNBT(NBTTagCompound nbt) {
	}


	@Override
	public NBTTagCompound writeToNBT(NBTTagCompound compound) {
		return null;
	}

	public static MyWorldSavedData get(World world) {
		MapStorage storage = world.getMapStorage();
		MyWorldSavedData instance = (MyWorldSavedData) storage.getOrLoadData(MyWorldSavedData.class, DATA_NAME);

		if (instance == null) {
			instance = new MyWorldSavedData();
			storage.setData(DATA_NAME, instance);
		}
		return instance;
	}	

}

 

Posted

You mean readFromNBT and writeToNBT? That's simple.

readFromNBT: read from nbt to fill up the fields of WorldSavedData.

writeToNBT: write to nbt with the fields of WorldSavedData.

 

So basically, you save your fields to NBT using writeToNBT, and load it later using readFromNBT.

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Posted

Ok now i have those classes now the only thing i am wondering about is to where but markDirty calls. The goal is to make a hashmap of all cameras in all dimensions in world that is synced to all clients and server and is saved to world file

MyWorldSavedData:

package io.github.lukas2005.spymod;

import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.world.World;
import net.minecraft.world.WorldSavedData;
import net.minecraft.world.storage.MapStorage;

public class MyWorldSavedData extends WorldSavedData {
	private static final String DATA_NAME = Reference.MOD_ID + "_MyWorldSavedData";
	
	
	public MyWorldSavedData() {
		super(DATA_NAME);
	}


	@Override
	public void readFromNBT(NBTTagCompound nbt) {
		Camera.REGISTRY.clear();
		NBTTagList list = (NBTTagList) nbt.getTag("CameraRegistry");
		for (int i=0;i < list.tagCount();i++) {
			NBTTagCompound camnbt = (NBTTagCompound) list.get(0);
			Camera.registerCamera(new Camera(camnbt.getUniqueId("UUID")).readFromNBT(camnbt));
		}
	}


	@Override
	public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
		NBTTagList list = new NBTTagList(); 
		for (Camera cam : Camera.REGISTRY.values()) {
			NBTTagCompound camnbt = new NBTTagCompound();
			camnbt.setUniqueId("UUID", cam.getUUID());
			cam.writeToNBT(camnbt);
			list.appendTag(camnbt);
		}
		nbt.setTag("CameraRegistry", list);
		Camera.REGISTRY.clear();
		return nbt;
	}

	public static MyWorldSavedData get(World world) {
		MapStorage storage = world.getMapStorage();
		MyWorldSavedData instance = (MyWorldSavedData) storage.getOrLoadData(MyWorldSavedData.class, DATA_NAME);

		if (instance == null) {
			instance = new MyWorldSavedData();
			storage.setData(DATA_NAME, instance);
		}
		return instance;
	}	

}

 

Camera:

package io.github.lukas2005.spymod;

import java.util.HashMap;
import java.util.UUID;

import io.github.lukas2005.spymod.Network.CameraRegistryChangeMessage;
import io.github.lukas2005.spymod.Network.CameraRegistryChangeMessage.Type;
import io.github.lukas2005.spymod.Network.NetworkManager;
import io.netty.buffer.ByteBuf;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fml.common.network.ByteBufUtils;

public class Camera {

	public static HashMap<UUID, Camera> REGISTRY = new HashMap<UUID, Camera>();
	
	private final UUID uuid;
	private String name;
	private UUID attachment;
	
	public Camera() {
		this.uuid = UUID.randomUUID();
	}
	
	public Camera(UUID uuid) {
		this.uuid = uuid;
	}
	
	public Camera(UUID uuid, Object...data) {
		this.uuid = uuid;
		this.name = (String) data[0];
		this.attachment = (UUID) data[1];
	}
	
	public static Camera getCamera(UUID uuid) {
		return REGISTRY.get(uuid);
	}
	
	public static void registerCamera(Camera cam) {
		
		REGISTRY.put(cam.getUUID(), cam);
		NetworkManager.INSTANCE.sendToServer(new CameraRegistryChangeMessage(Type.ADD_CAMERA, cam.uuid));
		
	}

	public static void registerCameraNoUpdate(Camera cam) {
		
		REGISTRY.put(cam.getUUID(), cam);
		
	}
	
	public static void unRegisterCamera(Camera cam) {
		
		REGISTRY.remove(cam.getUUID());
		NetworkManager.INSTANCE.sendToServer(new CameraRegistryChangeMessage(Type.REMOVE_CAMERA, cam.uuid));
		
	}
	
	public static void unRegisterCameraNoUpdate(Camera cam) {
		
		REGISTRY.remove(cam.getUUID());
		
	}
	
	public static void unRegisterCamera(UUID cam) {
		
		REGISTRY.remove(cam);
		NetworkManager.INSTANCE.sendToServer(new CameraRegistryChangeMessage(Type.REMOVE_CAMERA, cam));
		
	}
	
	public static void unRegisterCameraNoUpdate(UUID cam) {
		
		REGISTRY.remove(cam);
		
	}
	
	public String getName() {
		return name;
	}

	public Camera setName(String name) {
		this.name = name;
		NetworkManager.INSTANCE.sendToServer(new CameraRegistryChangeMessage(Type.UPDATE_CAMERA, getUUID(), name, null));
		return this;
	}
	
	public Camera setNameNoUpdate(String name) {
		this.name = name;
		return this;
	}

	public UUID getAttachment() {
		return attachment;
	}

	public Camera setAttachment(UUID attachment) {
		this.attachment = attachment;
		NetworkManager.INSTANCE.sendToServer(new CameraRegistryChangeMessage(Type.UPDATE_CAMERA, getUUID(), null, attachment));
		return this;
	}

	public Camera setAttachmentNoUpdate(UUID attachment) {
		this.attachment = attachment;
		return this;
	}
	
	public UUID getUUID() {
		return uuid;
	}
	
	public Camera writeToNBT(NBTTagCompound nbt) {
		nbt.setString("Name", getName());
		nbt.setUniqueId("Attach", getAttachment());
		return this;
	}
	
	public Camera readFromNBT(NBTTagCompound nbt) {
		setName(nbt.getString("Name"));
		setAttachment(nbt.getUniqueId("Attach"));
		return this;
	}

	public void writeToByteBuf(ByteBuf buf) {
		ByteBufUtils.writeUTF8String(buf, getName()); // New camera name
		ByteBufUtils.writeUTF8String(buf, ((UUID)getAttachment()).toString()); 	
	}
	
	public Camera readFromByteBuf(ByteBuf buf) {
		setName(ByteBufUtils.readUTF8String(buf)); // New camera name
		setAttachment(UUID.fromString(ByteBufUtils.readUTF8String(buf))); //New camera block pos attachment
		return this;
	}
	
}

CameraRegistryChangeMessage:

package io.github.lukas2005.spymod.Network;

import java.util.UUID;

import io.github.lukas2005.spymod.Camera;
import io.netty.buffer.ByteBuf;
import net.minecraftforge.fml.common.network.ByteBufUtils;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;

public class CameraRegistryChangeMessage implements IMessage {

	int type = 0;
	Type etype;
	Object[] data;
	
	public CameraRegistryChangeMessage() {}
	
	public CameraRegistryChangeMessage(Type type, Object...data) {
		switch(type) {
		case ADD_CAMERA:
			this.type = 0;
			break;
		case REMOVE_CAMERA:
			this.type = 1;
			break;
		case UPDATE_CAMERA:
			this.type = 2;
			break;
		}
		this.etype = type;
		this.data = data;
	}
	
	@Override
	public void fromBytes(ByteBuf buf) {
		switch(buf.readInt()) {
		case 0:
			this.etype = Type.ADD_CAMERA;
			data = new Object[1];
			data[0] = UUID.fromString(ByteBufUtils.readUTF8String(buf));
			break;
		case 1:
			this.etype = Type.REMOVE_CAMERA;
			data = new Object[1];
			data[0] = UUID.fromString(ByteBufUtils.readUTF8String(buf)); // UUID of camera to remove
			break;
		case 2:
			this.etype = Type.UPDATE_CAMERA;
			data = new Object[3];
			data[0] = UUID.fromString(ByteBufUtils.readUTF8String(buf));
			Camera cam = new Camera((UUID) data[0]).readFromByteBuf(buf);
			data[1] = cam.getName();
			data[2] = cam.getAttachment();
			break;
		}
	}

	@Override
	public void toBytes(ByteBuf buf) {
		buf.writeInt(type);
		switch(etype) {
		case ADD_CAMERA:
			ByteBufUtils.writeUTF8String(buf, ((UUID)data[0]).toString());
			break;
		case REMOVE_CAMERA:
			ByteBufUtils.writeUTF8String(buf, ((UUID)data[0]).toString());
			break;
		case UPDATE_CAMERA:
			ByteBufUtils.writeUTF8String(buf, ((UUID)data[0]).toString()); //UUID of camera to update
			new Camera((UUID)data[0], (String)data[1], data[2]).writeToByteBuf(buf);
			break;
		}
	}
	
	public static class Handler implements IMessageHandler<CameraRegistryChangeMessage, IMessage> {
		@Override
		public IMessage onMessage(final CameraRegistryChangeMessage message, MessageContext ctx) {	
			UUID uuid = (UUID)message.data[0];
			switch(message.etype) {
			case ADD_CAMERA:
				if (!Camera.REGISTRY.containsKey(uuid)) {
					Camera.registerCameraNoUpdate(new Camera(uuid));
				}
				break;
			case REMOVE_CAMERA:
				if (Camera.REGISTRY.containsKey(uuid)) {
					Camera.unRegisterCameraNoUpdate(uuid);
				}
				break;
			case UPDATE_CAMERA:
				if (Camera.REGISTRY.containsKey(uuid)) {
					String name = (String) message.data[1];
					UUID attachment = (UUID) message.data[2];
					Camera cam = Camera.REGISTRY.get(uuid);
					if (name != null) cam.setNameNoUpdate(name);
					if (attachment != null) cam.setAttachmentNoUpdate(attachment);
				}
				break;
			}
			NetworkManager.INSTANCE.sendToAll(message);
			return null;
		}
	}
	
	public static enum Type {
		
		ADD_CAMERA,
		REMOVE_CAMERA,
		UPDATE_CAMERA
		
	}
	
}

 

Posted
18 minutes ago, lukas2005 said:

camnbt = (NBTTagCompound) list.get(0);

You got something wrong here. 0 seems to be i instead

Oh, and about markDirty, I forgot that! You should call it whereever you change WorldSavedData field value. In your case, it's whereever a camera changes.

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Posted
2 minutes ago, lukas2005 said:

Ok one thing how shloud i get world instance from my Camera class?

You can't. If you really need it, provide it on WorldEvent.Load .

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Posted

Ok now i did it but it does not save/load even added prints in writeNBT readNBT and markDirty functions looks like writeNBT  and readNBT are not called shloud i call them manually??

Posted

Before that, check if it's called. Use either breakpoint or print statements.

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Posted (edited)
Just now, Abastro said:

Before that, check if it's called. Use either breakpoint or print statements.

i arelady did that markDirty does gets called but those other 2 func dont

Edited by lukas2005
Posted

Interesting that the MySavedWorldData constructor can take no parameters. Forge complains when I try that.

 

What works for me is: Message sent from client -> Message received on Server -> onMessage calls a method in MySavedWorldData that updates your HashMap.

markDirty(); should be placed at the end of that last method.

Posted

Strange. Would you update your code?

Just in case you don't know: markDirty calls should be on server side.

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Posted

Ok i removed the markDirty call from all methods except my sync packet handler and added a constructor with String and still the same i think that i will just create a Github Repo instead of posting walls of code here

Posted (edited)

Don't remove it from all methods; just try putting it at the end of the method that updates your HashMap.

Edit: Oh well if you can call markDirty on the MyWorldSavedData instance from the message handler, then I think we should see your code as it is now

Edited by FredTargaryen
Posted

1. For the worldsaveddata on map storage, you should only register it once(it's shared throughout worlds(. WorldEvent.Load is called every time the world is loaded, so you should find another event or check to allow only one world to load the data.

 Same for WorldEvent.Unload.

2. Why did you register the packet to both server and client? The logic should be on the server side. Client is only for the rendering and sending input to the server.

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Posted
Just now, Abastro said:

2. Why did you register the packet to both server and client? The logic should be on the server side. Client is only for the rendering and sending input to the server.

Because i need data about cameras on both server and client

Posted
1 minute ago, lukas2005 said:

Because i need data about cameras on both server and client

Just sync it from the server to the client, otherwise by editing client plauers could cheat.

Client to server packet is mostly for sending the user input to the server.

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Posted
3 minutes ago, diesieben07 said:

Oh god. No, no no no. You must obtain the WorldSavedData instance from the World, you can't just stuff it into some random static field.

fixed that and still nothing

Posted

1. Don't reference Minecraft in the packet - it will crash on dedicated server.

2. Why bidirectional packet? No need to send it from client to server. Just move all non-rendeing logics to the server, and only send packet from client to server.

3. So you have the item ItemCamera to represent the camera. Why to have separate registry.

4. Certainly this is not the way to go; don't put the registry as WorldSavedData. Also don't make static reference of it. (It means it won't be loaded on time. Also WorldEvent are only called on server. So client-side one won't exist. Try running dedicated server to try this)

5. What's the supposed function of the camera and the monitor?

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

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

    • So me and a couple of friends are playing with a shitpost mod pack and one of the mods in the pack is corail tombstone and for some reason there is a problem with it, where on death to fire the player will get kicked out of the server and the tombstone will not spawn basically deleting an entire inventory, it doesn't matter what type of fire it is, whether it's from vanilla fire/lava, or from modded fire like ice&fire/lycanites and it's common enough to where everyone on the server has experienced at least once or twice and it doesn't give any crash log. a solution to this would be much appreciated thank you!
    • It is 1.12.2 - I have no idea if there is a 1.12 pack
    • Okay, but does the modpack works with 1.12 or just with 1.12.2, because I need the Forge client specifically for Minecraft 1.12, not 1.12.2
    • 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() ); } }  
  • Topics

  • Who's Online (See full list)

×
×
  • Create New...

Important Information

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