Lower-bracket equip levelup & Channel/World capacity patch

Rebalanced the low level section of the equipment level up system.
Fixed EQUIP_EXP_RATE not acting as expected to be.
Changed chscroll system, now using a new flag instead of the SCROLL_CHANCE_RATE.
Optimized PlayerStorage, now using a proper name map when searching for a character name.
Tweaked some aspects of the BalrogPQ.
Improved the channel capacity bar and world server capacity checks throughout the source.
This commit is contained in:
ronancpl
2018-04-25 12:01:24 -03:00
parent b7a259e2c4
commit 7d448cce4f
31 changed files with 446 additions and 90 deletions

View File

@@ -37,11 +37,13 @@ public class PlayerStorage {
private final ReadLock rlock = locks.readLock();
private final WriteLock wlock = locks.writeLock();
private final Map<Integer, MapleCharacter> storage = new LinkedHashMap<>();
private final Map<String, MapleCharacter> nameStorage = new LinkedHashMap<>();
public void addPlayer(MapleCharacter chr) {
wlock.lock();
try {
storage.put(chr.getId(), chr);
nameStorage.put(chr.getName().toLowerCase(), chr);
} finally {
wlock.unlock();
}
@@ -50,7 +52,10 @@ public class PlayerStorage {
public MapleCharacter removePlayer(int chr) {
wlock.lock();
try {
return storage.remove(chr);
MapleCharacter mc = storage.remove(chr);
if(mc != null) nameStorage.remove(mc.getName().toLowerCase());
return mc;
} finally {
wlock.unlock();
}
@@ -59,11 +64,7 @@ public class PlayerStorage {
public MapleCharacter getCharacterByName(String name) {
rlock.lock();
try {
for (MapleCharacter chr : storage.values()) {
if (chr.getName().toLowerCase().equals(name.toLowerCase()))
return chr;
}
return null;
return nameStorage.get(name.toLowerCase());
} finally {
rlock.unlock();
}

View File

@@ -77,7 +77,7 @@ import server.quest.MapleQuest;
import tools.locks.MonitoredLockType;
import tools.AutoJCE;
public class Server implements Runnable {
public class Server {
private static final Set<Integer> activeFly = new HashSet<>();
private static final Map<Integer, Integer> couponRates = new HashMap<>(30);
private static final List<Integer> activeCoupons = new LinkedList<>();
@@ -262,8 +262,7 @@ public class Server implements Runnable {
}
}
@Override
public void run() {
public void init() {
Properties p = new Properties();
try {
p.load(new FileInputStream("world.ini"));
@@ -388,7 +387,7 @@ public class Server implements Runnable {
System.setProperty("wzpath", "wz");
Security.setProperty("crypto.policy", "unlimited");
AutoJCE.removeCryptographyRestrictions();
Server.getInstance().run();
Server.getInstance().init();
}
public Properties getSubnetInfo() {
@@ -973,7 +972,7 @@ public class Server implements Runnable {
}
instance = null;
System.gc();
getInstance().run();//DID I DO EVERYTHING?! D:
getInstance().init();//DID I DO EVERYTHING?! D:
}
} finally {
srvLock.unlock();

View File

@@ -194,9 +194,9 @@ public final class Channel {
public void removePlayer(MapleCharacter chr) {
players.removePlayer(chr.getId());
}
public int getConnectedClients() {
return players.getAllCharacters().size();
public int getChannelCapacity() {
return (int)(Math.ceil(((float) players.getAllCharacters().size() / ServerConstants.CHANNEL_LOAD) * 800));
}
public void broadcastPacket(final byte[] data) {

View File

@@ -98,16 +98,22 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
boolean allowLogin = true;
Channel cserv = c.getChannelServer();
/* is this check really necessary?
if (state == MapleClient.LOGIN_SERVER_TRANSITION || state == MapleClient.LOGIN_NOTLOGGEDIN) {
for (String charName : c.loadCharacterNames(c.getWorld())) {
for (Channel ch : c.getWorldServer().getChannels()) {
if (ch.isConnected(charName)) {
allowLogin = false;
}
List<String> charNames = c.loadCharacterNames(c.getWorld());
if(!newcomer) {
charNames.remove(player.getName());
}
for (String charName : charNames) {
if(c.getWorldServer().getPlayerStorage().getCharacterByName(charName) != null) {
allowLogin = false;
break;
}
break;
}
}
*/
if (state != MapleClient.LOGIN_SERVER_TRANSITION || !allowLogin) {
c.setPlayer(null);
c.announce(MaplePacketCreator.getAfterLoginError(7));

View File

@@ -51,6 +51,11 @@ public final class CharSelectedHandler extends AbstractMaplePacketHandler {
return;
}
if(c.getWorldServer().isWorldCapacityFull()) {
c.announce(MaplePacketCreator.getAfterLoginError(10));
return;
}
server.unregisterLoginState(c);
c.updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION);
server.setCharacteridInTransition((InetSocketAddress) c.getSession().getRemoteAddress(), charId);

View File

@@ -33,6 +33,11 @@ public class CharSelectedWithPicHandler extends AbstractMaplePacketHandler {
}
if (c.checkPic(pic)) {
if(c.getWorldServer().isWorldCapacityFull()) {
c.announce(MaplePacketCreator.getAfterLoginError(10));
return;
}
server.unregisterLoginState(c);
c.updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION);
server.setCharacteridInTransition((InetSocketAddress) c.getSession().getRemoteAddress(), charId);

View File

@@ -23,6 +23,8 @@ package net.server.handlers.login;
import client.MapleClient;
import net.AbstractMaplePacketHandler;
import net.server.Server;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
public final class CharlistRequestHandler extends AbstractMaplePacketHandler {
@@ -32,6 +34,12 @@ public final class CharlistRequestHandler extends AbstractMaplePacketHandler {
slea.readByte();
int world = slea.readByte();
c.setWorld(world);
if(Server.getInstance().getWorld(world).isWorldCapacityFull()) {
c.announce(MaplePacketCreator.getServerStatus(2));
return;
}
c.setChannel(slea.readByte() + 1);
c.sendCharList(world);
}

View File

@@ -22,10 +22,9 @@
package net.server.handlers.login;
import client.MapleClient;
import constants.ServerConstants;
import net.AbstractMaplePacketHandler;
import net.server.world.World;
import net.server.Server;
import net.server.channel.Channel;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
@@ -34,18 +33,9 @@ public final class ServerStatusRequestHandler extends AbstractMaplePacketHandler
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
byte world = (byte) slea.readShort();//Wuuu? ):
int status;
int num = 0;
for (Channel ch : Server.getInstance().getWorld(world).getChannels()) {
num += ch.getConnectedClients();
}
if (num >= ServerConstants.CHANNEL_LOAD) {
status = 2;
} else if (num >= ServerConstants.CHANNEL_LOAD * .8) { // More than 80 percent o___o
status = 1;
} else {
status = 0;
}
World wserv = Server.getInstance().getWorld(world);
int status = wserv.getWorldCapacityStatus();
c.announce(MaplePacketCreator.getServerStatus(status));
}
}

View File

@@ -264,6 +264,26 @@ public class World {
return g;
}
public boolean isWorldCapacityFull() {
return getWorldCapacityStatus() == 2;
}
public int getWorldCapacityStatus() {
int worldCap = channels.size() * ServerConstants.CHANNEL_LOAD;
int num = players.getSize();
int status;
if (num >= worldCap) {
status = 2;
} else if (num >= worldCap * .8) { // More than 80 percent o___o
status = 1;
} else {
status = 0;
}
return status;
}
public MapleGuildSummary getGuildSummary(int gid, int wid) {
if (gsStore.containsKey(gid)) {
return gsStore.get(gid);