Jump to content

[1.7.10] Commenting on the JSON (for Configuration)


Recommended Posts

Posted

How can I add Comments on the JSON file for specific property?

 

I tried to do it using Gson, but I realized that It uses JsonWriter, which cannot print single sentence for commenting.

& I don't want to add new property for the comment.

 

Actually I have already solved this issue with refletion.. I got the Writer field from the JsonWriter which is private.

Is there any better way which I doesn't know? For I doesn't like using Reflection in this way..

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

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

Posted

Comments aren't possible in JSON.  The guy who designed it deliberately removed them to avoid folks misusing them for metadata.  The best you can do is descriptive property names I  think..

 

-TGG

Posted

Gson already suppports some comments(like /*, */, //) and ignore them while reading, so I thought writing comments would also be available.

 

So, is there no other way with Gson or anything?

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

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

Posted

Yes. I want to use it for my unified config system. (for Stellarium)

Since I'd use it not only for text configuration but also for packets & data saving, I prefer JSON forms.

And I just want to add some comments for text config.

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

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

Posted

JSON has nothing to do with packets, and to save data either use a normal config file or save it to NBT.

Yes, I know. But NBT is really bad for configuration, and I saw someone using JSON format to send object using packet.

It seems to be portable enough. (Of course I'd write the JSON in bytestream for sending packets)

 

and I said something wrong, the reason that I selected JSON is for the configuration.

Since my configuration have to be dynamic and hierarchical, I cannot use Forge Configuration.

 

Actually I tried to make my own config type, but I realized that it is hard work and It

And then I found that JSON is well suited for my objective.

 

and about hocon, is it accepted as a default library for Minecraft? If not, I think it would be difficult to use it..

Then I'd end up using my current way.

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

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

Posted

Send me a pm so that I can give you my custom database program as well add how to use it. I am not ready to release the code to the public yet though I will let you use it for this mod.

No. I think it will be much more complicated to use it.

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

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

Posted

If you want nested categories you can use "." to specify them when using the Forge Configuration class.

 

Categories:

String category1 = "topCategory.subCategory1";
String category2  "topCategory.subCategory2";

 

What the Forge config file might look like:

{
"topCategory": {
    "subCategory1": {
        # your options
    },
    "subCategory2": {
        " more options
    }
}
}

Don't make mods if you don't know Java.

Check out my website: http://shadowfacts.net

Developer of many mods

Posted

Again, what is wrong with the forge Configuration class?

What I mean by "dynamic", is that I have to find every existing category, and read information from each.

AFAIK Forge Configuration can be hierarchical, but not dynamic.

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

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

Posted

Maybe I am only remembering the old version of the Forge Configuration..

Anyway it is not hierarchical (only it can be shown as "hierarchical" using dots)

and it cannot be written on bytestream. (+without comments)

 

So it would take much more effort to change my system to use it.

I'd rather end up using reflection to JsonWriter.

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

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

Posted

No, it is actually not 'config'.

In fact, It is partially encoded basic information on planets.

 

On File Configuration part, it is encoded to be more readable.

On Bytestream part (for packet), it is encoded to be compressed.

 

+ It has to be sent by packet, since it will modify the world regardless of client configuration.

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

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

Posted

Can't you just include a readme file with the explanation on how to write the JSON that is what most people do, sounds to me your over complicating your life here. :P

I require Java, both the coffee and the code :)

Posted

Can't you just include a readme file with the explanation on how to write the JSON that is what most people do, sounds to me your over complicating your life here. :P

No, It would be a LOT harder to read. Then even I would not know what property means what, for it is very complicated config.

I'd need both readme file and comments, and they might not be enough!

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

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

Posted

Can't you just include a readme file with the explanation on how to write the JSON that is what most people do, sounds to me your over complicating your life here. :P

No, It would be a LOT harder to read. Then even I would not know what property means what, for it is very complicated config.

I'd need both readme file and comments, and they might not be enough!

 

Use an XMLSerializer then, XML supports comments <!-- -->

I require Java, both the coffee and the code :)

Posted

Does it support bytestream output, too?

 

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

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

Posted

Does it support bytestream output, too?

 

Yes you can technically transform anything to bytes, just deserialize it the way you serialized it, the only thing at stake is efficiency.

 

Now the only downside is that I'm not sure XML Serializers support comments when serializing, you'd have to test it out and if not find a LIB that does serialize comments too.

I require Java, both the coffee and the code :)

Posted

And the "Efficiency" is important. + Making XML bytestream writer would just double the effort.

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

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

Posted

Again: Why do you want to send a config via packets? That seems very strange. It is simple though: Just write whatever config file you chose into a String, like you would when writing to disk. Then send that string.

As I said, it is partially encoded basic information on planets, which can be sent from the Server.

Since server specifies the form of world on client, it has to be sent using packet.

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

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

Posted

Because I want to make the "configurable" system able to be changed either by GUI or Text.

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

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

Posted

Since it is deeply related with the world, it has to be sent by packet like world info.

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

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

Posted

I would just encode the data as a byte stream and send it, the configuration would just be that encoded data. Why would you need to send the config comments with your configuration? Will the clients be able to edit the config? In that case I would provide a nice gui for that.

I require Java, both the coffee and the code :)

Posted

What I meant was: How is the configuration format related to how you send it with a packet?

Because Forge Configuration always contains the comment, so i cant send it using a packet.

And any non built-in config platforms are really not preferable. (I don't want to import any external library)

 

To Belpois: It does not contains comment on packet. Please read the whole thread...

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

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

Posted

"Because Forge Configuration always contains the comment"

- Wrong, it doesn't (unless I misunderstood)

"i cant send it using a packet"

- You can send everything using packets, you are just looking for easy way.

 

Proper way of doing it would be:

1. Config loads

2. Sets some virtual data, example: (doesn't need that if)

if (conf.containsKey("Generics")) MyVirtualStorageClass.setGenerics(conf.get("Generics").getStringList());

3. And at this point you don't give a damn about config no more - everything is virtual.

4. In your packet you simply MyVirtualStorageClass.getGenerics  (which will return some String array) and write all strings to buffer.

5. On receiver side you read it and put in client-side vitrual storage class or actually anny other kind of storage (file cache).

 

I don't see why you want to send whole config so badly, it'd bebetter to send key info when you login on server and then on client use that info to e.g change sky behaviour (color and shit).

1.7.10 is no longer supported by forge, you are on your own.

Posted

Load all categories and send all of them as string? That doesn't make sense..

and Configuration#containsKey(String) or Configuration#get(String) doesn't seem to exist in forge 1.7.10.

 

Plus there was no method for getting Config String from Configuration class. (As it just uses the File class..)

 

I'd just use my current way with Json.

 

 

I think I got every help that I needed. There was no easier way with Json.

So I want to lock this thread.. how I can lock this thread? Or I cannot?

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

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

Guest
This topic is now closed to further replies.

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.