Server/Management-Server/src/main/java/ms/world/WorldDatabase.java
2021-07-26 07:33:07 -05:00

275 lines
No EOL
7 KiB
Java

package ms.world;
import java.nio.ByteBuffer;
import ms.ServerConstants;
import ms.net.IoSession;
import ms.net.packet.IoBuffer;
import ms.world.info.CountryFlag;
import ms.world.info.WorldInfo;
import ms09.MSLogger;
/**
* Holds all the world servers.
* @author Emperor
*
*/
public class WorldDatabase {
/**
* The game servers.
*/
private static final GameServer[] DATABASE = new GameServer[ServerConstants.WORLD_LIMIT];
/**
* The update time stamp.
*/
private static long updateStamp = System.currentTimeMillis();
/**
* Used to prevent {@code WorldDatabase} from getting instantiated.
*/
private WorldDatabase() {
/*
* empty.
*/
}
/**
* Gets the packet to update the world list in the lobby.
* @param player The player.
* @param worldConfiguration If the configuration should be added.
* @param worldStatus If the status should be added.
* @return The {@code OutgoingPacket} to write.
*/
public static void sendUpdate(IoSession session, int updateStamp) {
ByteBuffer buf = ByteBuffer.allocate(1024);
buf.put((byte) 0);
buf.putShort((short) 0);
buf.put((byte) 1);
IoBuffer buffer = new IoBuffer();
if (updateStamp == (int) WorldDatabase.updateStamp) {
buf.put((byte) 0);
} else {
buf.put((byte) 1); // Indicates an update occured.
putWorldListinfo(buffer);
}
putPlayerInfo(buffer);
if (buffer.toByteBuffer().position() > 0) {
buf.put((ByteBuffer) buffer.toByteBuffer().flip());
}
buf.putShort(1, (short) (buf.position() - 3));
session.queue((ByteBuffer) buf.flip());
}
/**
* Adds the world status on the packet.
* @param buffer The current packet.
*/
private static void putPlayerInfo(IoBuffer buffer) {
for (GameServer server : DATABASE) {
if (server != null) {
WorldInfo w = server.getInfo();
buffer.putSmart(w.getWorldId());
buffer.putShort(server.isActive() ? server.getPlayerAmount() : -1);
}
}
}
/**
* Sets the countries for each world.
* @param buffer The current packet.
*/
private static void putCountryInfo(IoBuffer buffer) {
for (CountryFlag country : CountryFlag.values()) {
buffer.putSmart(country.getId());
buffer.putJagString(capitalize(country.name().toLowerCase()));
}
}
/**
* Converts a string to a capitalized string
* @param name
* @return
*/
private static String capitalize(String name) {
if (name == null || name.length() == 0) {
return name;
} else {
char[] chars = name.toCharArray();
chars[0] = Character.toUpperCase(chars[0]);
return new String(chars);
}
}
/**
* Adds the world configuration on the packet.
* @param buffer The current packet.
*/
private static void putWorldListinfo(IoBuffer buffer) {
buffer.putSmart(CountryFlag.values().length);
putCountryInfo(buffer);
buffer.putSmart(0);
buffer.putSmart(DATABASE.length);
buffer.putSmart(getRegisteredAmount());
for (GameServer server : DATABASE) {
if (server != null) {
WorldInfo w = server.getInfo();
buffer.putSmart(w.getWorldId());
buffer.put(w.getCountry().ordinal());
buffer.putInt(w.getSettings());
buffer.putJagString(w.getActivity());
buffer.putJagString(w.getAddress());
}
}
buffer.putInt((int) updateStamp);
}
/**
* Gets the amount of worlds registered.
* @return The amount of worlds registered.
*/
public static int getRegisteredAmount() {
int count = 0;
for (GameServer server : DATABASE) {
if (server != null) {
count++;
}
}
return count;
}
/**
* Registers a game server.
* @param info The game world info.
*/
public static GameServer register(WorldInfo info) {
GameServer server = DATABASE[info.getWorldId()];
if (server != null && server.getSession().isActive() && !server.getSession().getAddress().equals(info.getAddress())) {
throw new IllegalStateException("World " + info.getWorldId() + " is already registered!");
}
flagUpdate();
MSLogger.logInfo("Registered world - [id=" + info.getWorldId() + ", ip=" + info.getAddress() + ", country=" + info.getCountry().name().toLowerCase() + ", revision=" + info.getRevision() + "]!");
return DATABASE[info.getWorldId()] = new GameServer(info);
}
public static void unRegister(GameServer server){
int index = -1;
for(int i = 0; i < DATABASE.length; i++){
GameServer s = DATABASE[i];
if(s == server){
index = i;
break;
}
}
if(index != -1){
DATABASE[index] = null;
WorldInfo info = server.getInfo();
MSLogger.logInfo("Unregistered world - [id=" + info.getWorldId() + ", ip=" + info.getAddress() + ", country=" + info.getCountry().name().toLowerCase() + ", revision=" + info.getRevision() + "]!");
}
}
/**
* Gets the world id of the player.
* @param username The username of the player.
* @return The world id.
*/
public static int getWorldId(String username) {
return getWorldId(getPlayer(username));
}
/**
* Gets the world id of the player.
* @param player The player.
* @return The world id.
*/
public static int getWorldId(PlayerSession player) {
if (player == null || !player.isActive()) {
return 0;
}
return player.getWorldId();
}
/**
* Checks if the game world is active.
* @param worldId The world id.
* @return {@code True} if so.
*/
public static boolean isActive(int worldId) {
GameServer server = get(worldId);
return server != null && server.isActive();
}
/**
* Checks if the player session for the given name is active.
* @param username The player's username.
* @return {@code True} if so.
*/
public static boolean isActivePlayer(String username) {
PlayerSession session = getPlayer(username);
return session != null && session.isActive();
}
/**
* Gets the player session for the given name.
* @param username The player's username.
* @return The player session.
*/
public static PlayerSession getPlayer(String username) {
return getPlayer(username, false);
}
/**
* Gets the player session for the given name.
* @param username The player's username.
* @param load If we load the users data.
* @return The player session.
*/
public static PlayerSession getPlayer(String username, boolean load) {
for (GameServer server : DATABASE) {
if (server != null && server.isActive()) {
PlayerSession player = server.getPlayers().get(username);
if (player != null) {
return player;
}
}
}
if (load) {
return PlayerSession.get(username);
}
return null;
}
/**
* Gets the game server for the given world id.
* @param worldId The world id.
* @return The game server.
*/
public static GameServer get(int worldId) {
return DATABASE[worldId];
}
/**
* Gets all the game servers.
* @return The list of game servers.
*/
public static GameServer[] getWorlds() {
return DATABASE;
}
/**
* Gets the updateStamp.
* @return the updateStamp
*/
public static long getUpdateStamp() {
return updateStamp;
}
/**
* Sets the updateStamp.
* @param updateStamp the updateStamp to set.
*/
public static void flagUpdate() {
WorldDatabase.updateStamp = System.currentTimeMillis();
}
}