Jump to content

[1.7.10] Loading External Files


Recommended Posts

I'm building a mod that relies on external XML files that define the content of the mod. I've managed to figure out how to load the files when the mod is being run on a dedicated server. Here's an example of how I'm loading files:


File file = FMLCommonHandler.instance().getMinecraftServerInstance().getFile("mods/empathymod/settings.xml");
// parse loaded file


However the game crashes when loading (before the title screen is reached) when running the mod on the CombinedClient because FMLCommonHandler.instance().getMinecraftServerInstance() returns null. What is the best way load these files that works for the Combined Client and Dedicated Server? Also, I'd ideally only want the server to be managing this content. In other words, the client shouldn't load any of the externals files but instead receive what the server has loaded from its external files. Is this possible? Are there any tutorials on the matter?



Link to comment
Share on other sites

You will have to write a dynamic registry then that can change (since of the course the client can connect to multiple servers in a row). Then when the server starts you read the data there and send it to every player that logs in (PlayerLoggedInEvent).

I have worded my question poorly. I already have the XML data being loaded and parsed, I'm just unsure of how to determine if the mod is running as the client vs the server. Then if the mod is running as the client, it needs to ask the server for the data it needs.


Also... why XML?

We have a team of designers writing the content and XML is the markup language that they are most familiar with.

Link to comment
Share on other sites

Right, but once the server has started and loaded the data, how would a client ask the server for the data?


Better yet, are there any mods that are doing something similar? I'm aware of what needs to be done, but I'm confused how to accomplish it within the Forge API.

Link to comment
Share on other sites

One of approaches:


In common code (main file / common proxy) make MyRegistry field.

In client code (client proxy) make additional MyRegistry field.


Use common MyRegistry as a place to load and hold stuff from XML, no matter what side.

Use client MyRegistry as holder for what client should use on current server.


More detailed:

1. Use init events to read XML files and place stuff loaded from them in common registry.

* For dedic it will be dedicated server data.

* For client it will be fallback single-player data (which can be used when you play SP).


2. Use PlayerLoggedInEvent (which is fired only on server thread) to gather common registry data and send it to client - which will save it to client registry.

* As you now see - no matter if you are on SP (integrated) or MP (dedicated/LAN) common registry is always present and no matter what you play - SP or MP - common one will be used on server thread (dedicated or integrated), and the other one (client's) will be use as display registry.

* What you choose to sync is entirely up to you.


3. Just to stress things out:

Your mod will have 2 registries - one for data holding, one for display, where display one will only exist on Client.jar.

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

Link to comment
Share on other sites

Okay this is starting to make sense! Just have some follow up questions:


As I mentioned above, I found that I was able to load the external files when via:

File file = FMLCommonHandler.instance().getMinecraftServerInstance().getFile("mods/empathymod/settings.xml");

While this works on the dedicated server it fails on the combined client because the MinecraftServerInstance is null. What is the proper method to load the data for the combined client (single player)?


How much data can I send over packets? Are there any problems with send large amounts of data? There's going to be quite a few large XML files, but I'd only need to send it to clients when either they first logged in or when the server reloaded the external files.

Link to comment
Share on other sites

Setup @SidedProxy, design choice:


abstract Common
    abstract File getDir();

Client extends Common
    File getDir() { return Minecraft.getMinecraft().mcDataDir; }

Server extends Common
    File getDir() { return FMLCommonHandler.instance().getMinecraftServerInstance(); }


Packet client->server are limited and if you need big data - you need to split them manually.

Packets server->client on the other hand are handled internally, so basically there is no limit as to what can written to buffer - it will be split into parts if too big. As to how much can be sent? Well - you can always throttle connection, but if operation happens per-login you are safe to send data in MB.

Big note - you should NOT send xml files!!! Waste of memory and requires client-side decoding. Once you decoded them on server you can encode data directly to buffer and read it back.

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

Link to comment
Share on other sites

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.

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.


  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • What MC version? What's the IP? Are any mods needed to be able to join?
    • Thank you for your answer ! Unfortunatly i have the same problem when i use setPos() public static int movingfunction(CommandContext<CommandSourceStack> context){ CommandSourceStack source = context.getSource(); if (!(source.getEntity() instanceof ServerPlayer)) { return 0; } ServerPlayer player = (ServerPlayer ) source.getEntity(); double moveSpeed = 0.5; for (int i =0; i<10000;i++) { LOGGER.info("running for the {} time", i); double x = player.getX() + player.getViewVector(1.0f).x * moveSpeed; double y = player.getY(); double z = player.getZ() + player.getViewVector(1.0f).z * moveSpeed ; Vec3 movementVec = new Vec3(x, y, z); LOGGER.info("x ={} y ={} z ={}", x, y, z); player.setPos( movementVec); } return 1; } With the logs i can see that x and z are increasing but once again my player is not moving. is there a function to use to sync the server and the client ? I also tried to use LocalPlayer instead of ServerPlayer but my code would stop when i got the object. Also i will change a bit the main topic but is there a way to similate key press ? i found KeyBinding.setKeyBindState on others post but it look like there is no more KeyBinding in 1.20   I found this code : KeyMapping.click(Minecraft.getInstance().options.keyUp.getKey()); But it doesn't seems to work   And i found this one : Minecraft.getInstance().options.keyUp.setDown(true); wich works but doesn't exactly do what i want , it doesn't release the key so for exemple i can't make him run. Minecraft.getInstance().options.keyUp.setDown(true); Minecraft.getInstance().options.keyUp.setDown(false); Minecraft.getInstance().options.keyUp.setDown(true); doesn't make him run
    • Add crash-reports with sites like https://paste.ee/ Maybe an issue with blur, essentials or cumulus_menus
    • Add the crash-report or latest.log (logs-folder) with sites like https://paste.ee/ and paste the link to it here  
  • Topics

  • Create New...

Important Information

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