Jump to content

[1.7.10]How to make your mod not work in singleplayer.


Recommended Posts

Posted

Hello everyone,

 

as the title says I currently develop a mod that I would the code to execute only if it is connected to a server with my mod on it (Ideally my server). If the player is logged in single player I would just want my mod to behave like it is not even installed.

 

I apologize for my English and I hope you get what I want to do :)

Posted

Because of the subtle distinction between them, there's probably a combination of SideOnly and isRemote that would distinguish between SP and MP. However, mods load before a player even chooses how and where to play. The trick would be for the mod to ignore itself if/when an SP world is created or loaded.

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Posted

Well, the main Idea is to mine block coordinates out of a database and then spawn them to my servers's world. I need though work only if the player is connected to my server. I want to avoid single player worlds spawning the blocks. If I use world.isRemote and use setBlock here will only work on server? Will it spawn the block to client side? And when a player use it in singleplayer wont get any blocks spawned?

Posted

Thanks diesieben07 I tested and this is what I was looking for. :)

I dont want to work single player because I couldnt be sure in which singleplayer worlds the blocks are spawned or need to be spawned. The number of blocks that my database will have is not fixed. So I want to spawn the blocks on the world of the singleplayer clients and if there is new blocks I need to add them too. The only way I can think of doing this is too check if there is a block placed in every block's coordinates I have in my database. But if I got 10.000 (thousand) blocks I think this wouldnt be efficient at all, it may cause lag etc.

 

I would really appreciate if anyone got any ideas to offer. :)

Posted

Yeah I understand. It is kinda hard to explain. So, I got a database table with 3 fields that are X,Y and Z. This are coordinates of a block and I got plenty of entries, each entrie represent the position the block should have in the world, and by time I add more and more entries so there are more blocks represented by the coordinates. I want to spawn these blocks to the signleplayer worlds, but I couldnt be sure which are the worlds that blocks need to be spawned. My idea was to check every entrie with observe if they are spawned in the world. But with 10000 entries that would be extremely inefficient.

 

By executing my code (that spawns the blocks) only my multiplayer server will solve the problem because there is only one world to worry about.

 

I hope I explained better this time.

Posted

I think he meant it would be much faster on a single world (the one on the server) than for all worlds in one's Minecraft, though I do have to wonder why it would apply to all worlds at once, unless he's thinking that having a bunch of crap accessing an online spreadsheet would bog it down.

Posted

Forget about the Dedicated Server. I 've gotten off topic to discuss how I can make my mod work on singleplayer too.

 

Lets take the case I wanted my mod to work on single player worlds. 2 players download my mod and the start playing and by their first log in I spawn all the blocks available in the db. After that I got a thousand more blocks to my db and I need them spawned to both players world as well. In this point I could not possible know where the last block was builded so I am not able to identify where the new entries of block should start.

 

Sorry for confusing you guys. This is an academic project and I am neither Java veteran or very experienced in Minecraft moding.

Posted

Just to clarify things:

 

You are using a rational database (MySQL, etc) hosted independently of any server to store block information (for some purpose that is irrelevant here)?

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

Yeah I am using MySQL database. I am running a script that calculates the position of blocks so when they spawned all together they will form "houses" on minecraft. The script will run on some irrelevant conditions and will continuously add more blocks to the database.

Posted

I think he's planning a private mod for a private server.

 

But yeah, this kind of stuff should just be stored in WorldSavedData.

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

I want to spawn the blocks on the world of the singleplayer clients and if there is new blocks I need to add them too.

 

I think that English translation is an issue. Please bring in a native English speaker/writer.

 

Server is always the canonical authority on block values. A client may only tell its server what its player has attempted to do. Does that help?

 

To summarize: Player acts, client tells server of action, server changes blocks/data (and server automatically tells client of block changes). If you are rigidly methodical, then your code should work both SP and MP.

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Posted

It is not the same. In a deticated server you have only one world to spawn the blocks and then the server do its job and send this world to the connected clients. But if the players play singlepalyer their worlds will be random. My problem is that I couldnt sync (Spawn all the blocks that need to be spawned) my db with all these different worlds.

 

Is there any way to store an integer for every world a player creates?

Posted

I will repeate questions that have already been asked. Please answer all of them precisely and we will be able to help you:

-You want to generate blocks in worlds from remote database, right?

-Database can be changed by you at any time?

-Blocks, should they be generated in already generated chunks?

-How many dimensions do you want to affect (only overworld, all vanilla or you can configure for any dimension from database)?

 

If you do not understand a question please ask us to say it in different way.

Posted

I will repeate questions that have already been asked. Please answer all of them precisely and we will be able to help you:

-You want to generate blocks in worlds from remote database, right?

-Database can be changed by you at any time?

-Blocks, should they be generated in already generated chunks?

-How many dimensions do you want to affect (only overworld, all vanilla or you can configure for any dimension from database)?

 

If you do not understand a question please ask us to say it in different way.

 

Hello,

I will happily answer all the questions the best I can.

 

-You want to generate blocks in worlds from remote database, right?

  Yes, I got a remote MySQL database that holds coordinates of Blocks. This is the structure of my table:

 

  ID  |  posX  |  posY  |  posX

 

  posX, posY and posZ is the block should be in the world.

 

-Database can be changed by you at any time?

  Yes. I got a script running that affects the table I mention above. It is not changing the table, it is just adds more and more coordinates to the database.

 

-Blocks, should they be generated in already generated chunks?

  Well, I am not sure I understand this question.

 

-How many dimensions do you want to affect (only overworld, all vanilla or you can configure for any dimension from database)?

  The only dimension I want to affect is the overworld.

Posted

Well guys, I figured something out. I need to store an integer that will hold the ID value of the last block builded on the world. Then I will query my database and fetch the coordinates past the stored ID and then updated with the latest value. I am searching over the internet and I found I can use WorldSavedData to achieve that but I really dont know how to do it. Can anyone guide me through it. This is my class:


public class BlockIDWorldData extends WorldSavedData{

private final static String ident = "LatestBlockIDWorldData";
public int blockID ;

public BlockIDWorldData() {
	super(ident);

}

@Override
public void readFromNBT(NBTTagCompound p_76184_1_) {

}

@Override
public void writeToNBT(NBTTagCompound p_76187_1_) {

}

}

Posted

I will repeate questions that have already been asked. Please answer all of them precisely and we will be able to help you:

-You want to generate blocks in worlds from remote database, right?

-Database can be changed by you at any time?

-Blocks, should they be generated in already generated chunks?

-How many dimensions do you want to affect (only overworld, all vanilla or you can configure for any dimension from database)?

 

If you do not understand a question please ask us to say it in different way.

 

Hello,

I will happily answer all the questions the best I can.

 

-You want to generate blocks in worlds from remote database, right?

  Yes, I got a remote MySQL database that holds coordinates of Blocks. This is the structure of my table:

 

  ID  |  posX  |  posY  |  posX

 

  posX, posY and posZ is the block should be in the world.

 

-Database can be changed by you at any time?

  Yes. I got a script running that affects the table I mention above. It is not changing the table, it is just adds more and more coordinates to the database.

 

-Blocks, should they be generated in already generated chunks?

  Well, I am not sure I understand this question.

 

-How many dimensions do you want to affect (only overworld, all vanilla or you can configure for any dimension from database)?

  The only dimension I want to affect is the overworld.

Thanks for answer.

 

Question 3 is very important, so i will try to explain it to you:

When you explore a world, new chunks are generated. When you exit the world, they are stored. When you load world back up, it loads chunks from drive, but it does not generate them.

So, question 3 is asking: if one day you change your database, and add coordinates that for "the given player" are in already generated chunk (chunk stored on drive), do you want to place (from code) blocks you just added in this chunk?

Posted

Thanks for answer.

 

Question 3 is very important, so i will try to explain it to you:

When you explore a world, new chunks are generated. When you exit the world, they are stored. When you load world back up, it loads chunks from drive, but it does not generate them.

So, question 3 is asking: if one day you change your database, and add coordinates that for "the given player" are in already generated chunk (chunk stored on drive), do you want to place (from code) blocks you just added in this chunk?

 

I want the blocks to be spawned in the world no matter what. I am using world.setBlock() to spawn the blocks and I got no problem with blocks spawning or dissapearing after a player exits the world. The only problem I got was how I could sync the new coordinates added to my table with the world since I cant know where the last block was builded. I searched over the internet and saw that I can save custom data with the WorldSavedData but I cant impement it.

 

Thanks for taking the time to try helping me :)

Posted

Thanks for answer.

 

Question 3 is very important, so i will try to explain it to you:

When you explore a world, new chunks are generated. When you exit the world, they are stored. When you load world back up, it loads chunks from drive, but it does not generate them.

So, question 3 is asking: if one day you change your database, and add coordinates that for "the given player" are in already generated chunk (chunk stored on drive), do you want to place (from code) blocks you just added in this chunk?

 

I want the blocks to be spawned in the world no matter what. I am using world.setBlock() to spawn the blocks and I got no problem with blocks spawning or dissapearing after a player exits the world. The only problem I got was how I could sync the new coordinates added to my table with the world since I cant know where the last block was builded. I searched over the internet and saw that I can save custom data with the WorldSavedData but I cant impement it.

 

Thanks for taking the time to try helping me :)

Ok. That clarifies a lot of things.

 

I suppose that you already have a class that connects to your database and reads blocks.

 

Now, you have 3 things to do:

1) Considering you are in 1.7.10, create BlockPos (holding x, y, z), read and write to nbt methods and with your IDE generate

hashCode

and

equals

methods.

2) Create your WorldSavedData class, following tutorial, including

get(World)

method to get data instance. You can use

perMapStorage

, I suppose you already have one. In there, add

Set<BlockPos>

field. This set will hold all blocks that were already generated. To save and load

Set

to/from nbt, use NBTTagList.

3) Use world generator and chunk load events to generate blocks.

 

Do first 2 steps, and try to do 3rd yourself. If you have any problems, ask them here, we will help.

 

EDIT: Official

WorldSavedData

tutorial: https://mcforge.readthedocs.org/en/latest/datastorage/worldsaveddata/.

Posted

I still do not see how this is an issue of server vs. Singleplayer. A singleplayer game runs one world at a time (with multiple dimensions). A server also runs one world at a time (with multiple dimensions).

There is not much difference between playing singleplayer and playing on a dedicated server, it is merely that in singleplayer the server runs on your own computer.

Hello,

in the dedicated server every player are in only one world. The one that the server hosting. In singleplayer this is not the case, every single player has a different world hosted by his integrated server.

 

Thanks for answer.

 

Question 3 is very important, so i will try to explain it to you:

When you explore a world, new chunks are generated. When you exit the world, they are stored. When you load world back up, it loads chunks from drive, but it does not generate them.

So, question 3 is asking: if one day you change your database, and add coordinates that for "the given player" are in already generated chunk (chunk stored on drive), do you want to place (from code) blocks you just added in this chunk?

 

I want the blocks to be spawned in the world no matter what. I am using world.setBlock() to spawn the blocks and I got no problem with blocks spawning or dissapearing after a player exits the world. The only problem I got was how I could sync the new coordinates added to my table with the world since I cant know where the last block was builded. I searched over the internet and saw that I can save custom data with the WorldSavedData but I cant impement it.

 

Thanks for taking the time to try helping me :)

Ok. That clarifies a lot of things.

 

I suppose that you already have a class that connects to your database and reads blocks.

 

Now, you have 3 things to do:

1) Considering you are in 1.7.10, create BlockPos (holding x, y, z), read and write to nbt methods and with your IDE generate

hashCode

and

equals

methods.

2) Create your WorldSavedData class, following tutorial, including

get(World)

method to get data instance. You can use

perMapStorage

, I suppose you already have one. In there, add

Set<BlockPos>

field. This set will hold all blocks that were already generated. To save and load

Set

to/from nbt, use NBTTagList.

3) Use world generator and chunk load events to generate blocks.

 

Do first 2 steps, and try to do 3rd yourself. If you have any problems, ask them here, we will help.

 

EDIT: Official

WorldSavedData

tutorial: https://mcforge.readthedocs.org/en/latest/datastorage/worldsaveddata/.

 

Thanks for your answer,

I just finished tryint to figured our how WorldSavedData works and I did :)

I only store an integer which is the ID of the last block builded in the world, then when a player log in to the world I will compare the locally stored ID value with the value of the latest block there is in the database and they are not the same I will spawn the remaing block than need to be spawned.

Thank you everyone for help :)

Posted

I only store an integer which is the ID of the last block builded in the world, then when a player log in to the world I will compare the locally stored ID value with the value of the latest block there is in the database and they are not the same I will spawn the remaing block than need to be spawned.

Thank you everyone for help :)

 

Keep in mind that IDs for modded block/items are automatically assigned and will likely be different for every world, they're not a very reliable way to store persistent data.

 

Registry names are a much more reliable identifier for blocks/items.

RegistryNamespaced#getNameForObject

can be called on

Block.blockRegistry

or

Item.itemRegistry

to get the registry name of a

Block

/

Item

respectively.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Posted

I only store an integer which is the ID of the last block builded in the world, then when a player log in to the world I will compare the locally stored ID value with the value of the latest block there is in the database and they are not the same I will spawn the remaing block than need to be spawned.

Thank you everyone for help :)

 

Keep in mind that IDs for modded block/items are automatically assigned and will likely be different for every world, they're not a very reliable way to store persistent data.

 

Registry names are a much more reliable identifier for blocks/items.

RegistryNamespaced#getNameForObject

can be called on

Block.blockRegistry

or

Item.itemRegistry

to get the registry name of a

Block

/

Item

respectively.

I dont mean blocks IDs. By ID I mean a row in my database name ID :)

 

in the dedicated server every player are in only one world. The one that the server hosting. In singleplayer this is not the case, every single player has a different world hosted by his integrated server.

Yes, there are many singleplayer worlds active because every player playing has their own integrated server.

But it's not like there is only one dedicated server out there? :o There are many servers active as well...

 

Oh I see your point. I was thinking that my database only would accessed by my server, but if another server administrator wants my mod to his server then I got more worlds accessing my database. You are totally right. Thank you very much for pointing this out. :)

Posted

I dont mean blocks IDs. By ID I mean a row in my database name ID :)

 

Ah, that makes more sense.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Posted

in the dedicated server every player are in only one world. The one that the server hosting. In singleplayer this is not the case, every single player has a different world hosted by his integrated server.

Yes, there are many singleplayer worlds active because every player playing has their own integrated server.

But it's not like there is only one dedicated server out there? :o There are many servers active as well...

 

Oh I see your point. I was thinking that my database only would accessed by my server, but if another server administrator wants my mod to his server then I got more worlds accessing my database. You are totally right. Thank you very much for pointing this out. :)

 

Cough

 

I think he's planning a private mod for a private server.

 

But yeah, this kind of stuff should just be stored in WorldSavedData.

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

Your table probably needs a new column for metadata value. It would not only distinguish between colors of things but also some orientations. Do your structures also need to store tile entity data? Or will you either accept defaults or simply not use block types needing tile entities?

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

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

    • 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)

    • There are no registered users currently online
×
×
  • Create New...

Important Information

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