Jump to content

Recommended Posts

Posted (edited)

Hey,

 

I'm trying to create a mute command that'll add entries to a list (similar to how MC does it for bans). I don't know if the NBT data (with a list of String values for muted player names) saves after server shutdown. Also, what do I attach the capability to? Do I need an interface and storage? I'm just confused as to how I'd do NBT with an ArrayList (NBT is already kind of confusing in and of itself).

 

If anyone could help, that'd be appreciated.

 

Thanks!

Edited by Differentiation
Posted
12 minutes ago, Differentiation said:

Also, what do I attach the capability to?

I wouldn't use a capability for this. I would just save this to a file yourself. For simplicity sake probably a json file like the ops file.

But if you really wanted to use a Capability here you would probably attach it to the Player and not use an ArrayList at all.

16 minutes ago, Differentiation said:

Do I need an interface

No you don't need an interface. You only need to use an interface if your capability is modifiable. IE can have different implementations.

17 minutes ago, Differentiation said:

and storage

Yes all Capabilities need an IStorage component.

17 minutes ago, Differentiation said:

I'm just confused as to how I'd do NBT with an ArrayList (NBT is already kind of confusing in and of itself).

You would use NBTTagList.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted
7 hours ago, Animefan8888 said:

I wouldn't use a capability for this. I would just save this to a file yourself. For simplicity sake probably a json file like the ops file.

But if you really wanted to use a Capability here you would probably attach it to the Player and not use an ArrayList at all.

No you don't need an interface. You only need to use an interface if your capability is modifiable. IE can have different implementations.

Yes all Capabilities need an IStorage component.

You would use NBTTagList.

Currently I have it being put in player capability, however, I want to be able to ban any GameProfile, even if its offline (like how banning does it).

 

I thought of maybe creating a muted.json file, but I  dont know how to do that. How would I add an entry to ops.json without the entry being opped, but instead muted?

Posted
9 hours ago, Differentiation said:

How would I add an entry to ops.json without the entry being opped, but instead muted?

You dont. ops.json is for oped players you wouldn't use it for this.

 

9 hours ago, Differentiation said:

I thought of maybe creating a muted.json file, but I  dont know how to do that.

Create a file in the server directory called muted.json and save that file when the world saves? You would use the Gson library minecraft uses for its json interactions.

 

9 hours ago, Differentiation said:

I want to be able to ban any GameProfile, even if its offline (like how banning does it).

I dont think the vanilla ban command let's you ban people that aren't online unless it's with IPs.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted
2 hours ago, Animefan8888 said:

Create a file in the server directory called muted.json and save that file when the world saves? You would use the Gson library minecraft uses for its json interactions.

 

I want the mod to create it when the server starts for the first time, exactly like Minecraft does bans.json when on a dedicated server, and have it update every time an entry is added (a player is muted). I don't really know how to start a json file like that or what I need to do. Is there any help or tutorial or something I could get?

2 hours ago, Animefan8888 said:

I dont think the vanilla ban command let's you ban people that aren't online unless it's with IPs.

It does, it bans the GameProfile, not EntityPlayer. I've tested this out and it works.

Posted
9 minutes ago, Differentiation said:

I don't really know how to start a json file like that or what I need to do.

Think basic Java file creation. Look up some tutorials on Gson if you need it.

 

9 minutes ago, Differentiation said:

I want the mod to create it when the server starts for the first time,

Use the ServerStartingEvent or ServerStartedEvent.

 

11 minutes ago, Differentiation said:

and have it update every time an entry is added (a player is muted).

Then everytime the command is run update the file.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted (edited)
2 hours ago, Animefan8888 said:

Think basic Java file creation. Look up some tutorials on Gson if you need it.

 

I'll probably just copy UserList and UserListBans, etc. because it's pointless to do this from scratch I think...

Can I attach a capability to MinecraftServer and have it save the list when I exit or something? Is there any other solution for this without making it too complicated?

Edited by Differentiation
Posted
1 hour ago, Differentiation said:

 Can I attach a capability to MinecraftServer and have it save the list when I exit or something?

No you cannot. The server doesn't have capabilities. Because there is only one server in question.

 

1 hour ago, Differentiation said:

Is there any other solution for this without making it too complicated?

It's not that complicated... Use events such as ServerStartingEvent to create a file if it doesnt exist(muted.json).

 

Then whenever you run your mute command save the data to the file using Gson.

 

If you dont want it to save when you run the command use the ServerStoppingEvent to save the data you have.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted (edited)
7 hours ago, Animefan8888 said:

Then whenever you run your mute command save the data to the file using Gson.

I watched the tutorial on Gson and it seemed pretty easy, but how would I create multiple entries in one file?

 

Other than that, everything else seems straight forward.

Edited by Differentiation
Posted
On 9/12/2019 at 10:48 AM, Animefan8888 said:

JSonArray probably.

Okay, so I did everything and the command works. However, when I mute another player the file just replaces the entry that's in it with the one I just added. How do I fix this? Is this only an issue with using Player[number] test GameProfiles?

Posted
1 minute ago, Differentiation said:

However, when I mute another player the file just replaces the entry that's in it with the one I just added.

You'll either have to write all of the entries again. Or append to the file in some way. Look up FIle IO tutorials for Java.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted (edited)
2 hours ago, Animefan8888 said:

You'll either have to write all of the entries again. Or append to the file in some way. Look up FIle IO tutorials for Java.

I don't know, it's whenever I create another MutedList (every time I run the command). I don't know how to really fix this.

Now the entries all go in but when I leave (the server closes), enter, and run the command once more, all the previous entries are deleted and there's just this one. I could send the code if you'd like :S

I'm not sure of a way to avoid that. And that ties back to the problem I had at the very beginning of this thread, a way to read and write the old values

Edited by Differentiation
Posted
Just now, Differentiation said:

Yeah, but where and when should I write the values?

You said you wanted to do it every time the command was ran. So do it then...

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted
4 minutes ago, Differentiation said:

I do, but then it resets anyways once I add an entry (run the command)

Post your code I can't help without it anymore than I already have. My suspicion is that you are just writing the new entry to the file instead of writing the whole thing again.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted
8 minutes ago, Differentiation said:

Thank you for posting your code.

This part right here is your problem.

		File file = new File("muted-players.json");

		try
		{
			file.setWritable(true);
			file.createNewFile();
		}
		catch (IOException exception)
		{
			Log.info("Error creating file 'muted-players.json'!");
		}

 

You create an new file even if the file already exists. You need to check if the file exists before you create it.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted
1 hour ago, Animefan8888 said:

Thank you for posting your code.

This part right here is your problem.


		File file = new File("muted-players.json");

		try
		{
			file.setWritable(true);
			file.createNewFile();
		}
		catch (IOException exception)
		{
			Log.info("Error creating file 'muted-players.json'!");
		}

 

You create an new file even if the file already exists. You need to check if the file exists before you create it.

File::createNewfile(); only creates the file if it does not already exist, I thought.  I'll have to double check 

Posted
6 minutes ago, Differentiation said:

File::createNewfile(); only creates the file if it does not already exist, I thought.  I'll have to double check 

This is true my bad. Try stepping through your read and write methods in the debugger.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted (edited)
1 hour ago, Animefan8888 said:

This is true my bad. Try stepping through your read and write methods in the debugger.

It inevitably creates a new instance of UserListMutes every time the mod is loaded. That's my issue. I could make the class abstract, but then I can't really instantiate it. I have no idea how to resolve this. :/

Edited by Differentiation
Posted
1 minute ago, Differentiation said:

It inevitably creates a new instance of UserListMutes every time the mod is loaded.

Yeah it has to do that...how much do you know about programming? Have you stepped through the code execution in the debugger?

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

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.