It's been a while since I've released something, so here's something small. It's been coded on MapleCrystal, which is based off EliteMS, which is based off FuckMS, which is based off Lithium. But you'll be able to get it on any source on any version if you're capable of more than just copy-pasting text.
Map Disposal
At its simplest, this release removes unused maps after 30 minutes. That's all.
Instructions
Step 1:
Under MapleMap.java, add:
Step 2:Code:private long lastPlayerLeft = System.currentTimeMillis(); public boolean canDelete() { return (System.currentTimeMillis() - lastPlayerLeft > (30 * 60 * 1000L)) && (getCharactersSize() == 0); }
Still under MapleMap.java, look for the removePlayer() function, which should look something like:
Add this line at the top of the function, like so:Code:public final void removePlayer(final MapleCharacter chr) { ... ... ... }
Step 3:Code:public final void removePlayer(final MapleCharacter chr) { lastPlayerLeft = System.currentTimeMillis(); ... ... ... }
Go to World.java, and look for handleMap function:
Again, add the following code at the top of the function:Code:public static void handleMap(final MapleMap map, final int numTimes, final int size, final long now) { ... ... ... }
And that's it.Code:public static void handleMap(final MapleMap map, final int numTimes, final int size, final long now) { if (map.canDelete()) { map.resetFully(false); MapleMapFactory mmf = ChannelServer.getInstance(map.getChannel()).getMapFactory(); if (mmf.isMapLoaded(map.getId())) { if (mmf.getMap(map.getId()) == map) { // Ensure we are deleting the right map mmf.removeMap(map.getId()); } } return; } ... ... ... }
How it works is, every time a player leaves a map, the time is stored as "lastPlayerLeft". When canDelete() is called, if there are no players on the map and the last time a player left the map was more than 30 minutes ago, then the map is taken off the channel's MapleMapFactory. An extra check is added so that if maps are instanced (for instance, player houses), it will not wrongly delete the original map from the channel.
Whether or not this might cause memory leaks depends on whether or not map.resetFully(false), followed by deleting of the map causes memory leaks. If it does, then don't use this. Or clean up the leaks like any self-respecting programmer would.
Why use this?
One of the reasons why servers require quite a fair bit of RAM is because of maps (as well as the drops, mobs, reactors, whatever) taking up space. For smaller servers this might not be a problem. However, for bigger servers with more channels, having 10 instances of explored maps for 10 different channels can become quite the burden to the RAM, considering most maps are simply passed through, or explored for only a few moments before it's empty for the rest of the server's uptime.
While honestly I don't know how much RAM maps consume on servers in general, I think it is still good to remove unused maps after long periods of time.
Feel free to discuss the usefulness of this, because I still have doubts if it'll actually solve some memory problems, and if it does, why has it not been implemented in most, if not all public sources.



Reply With Quote


