166 lines
5.0 KiB
Java
Raw Normal View History

2025-09-06 17:17:39 +04:00
package server;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.security.KeyStore;
import java.text.DecimalFormat;
import java.util.logging.Logger;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.filter.ssl.SslFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import server.database.DatabaseManager;
import server.database.MongoCopy;
import server.model.players.PlayerManager;
import server.networking.ConnectionHandler;
import server.util.ShutDownHook;
import server.util.SimpleTimer;
import server.util.SwConfig;
import server.SpecialWeaponConfig;
import server.model.players.Player;
import server.model.players.PlayerManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
public class Server {
public Server() {
debugPercentFormat = new DecimalFormat("0.0#%");
engineTimer = new SimpleTimer();
debugTimer = new SimpleTimer();
acceptor.setHandler(new ConnectionHandler());
}
public Server bind(int port) throws IOException {
acceptor.bind(new InetSocketAddress(port));
return this;
}
public static void main(String[] args) throws IOException {
SpecialWeaponConfig.loadConfig(); // Load JSON
startPeriodicCheck(); // Start timer
try {
if (args[0].contains("live")) {
Config.LIVE_SERVER = true;
}
} catch (Exception e) {
}
try {
new Server().bind(PORT).start();
} catch (Exception e) {
e.printStackTrace();
}
Thread savePlayers = new Thread(() -> gameEngine.destruct());
Runtime.getRuntime().addShutdownHook(savePlayers);
gameEngine = new GameEngine();
gameEngine.init();
System.out.println("Listening for connections on port " + Config.SERVER_PORT + "...");
try {
while (!shutdownServer) {
long startTime = System.currentTimeMillis();
engineTimer.reset();
if (updateTicks > 0)
updateTicks--;
if (updateTicks == 0) {
shutdownServer = true;
}
gameEngine.update();
cycleTime = engineTimer.elapsed();
sleepTime = Config.SERVER_TICK_RATE - cycleTime;
totalCycleTime += cycleTime;
cycles++;
debug();
long timeElapsed = System.currentTimeMillis() - startTime;
if (timeElapsed < 100) {
Thread.sleep(Config.SERVER_TICK_RATE - timeElapsed);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
gameEngine.destruct();
}
}
private static long cycleTime, cycles, totalCycleTime, sleepTime;
private static SimpleTimer engineTimer, debugTimer;
private static DecimalFormat debugPercentFormat;
private static void debug() {
if (debugTimer.elapsed() > 100*1000) {
long averageCycleTime = totalCycleTime / cycles;
System.out.println("Average Cycle Time: " + averageCycleTime + "ms");
double engineLoad = ((double) averageCycleTime / (double) Config.SERVER_TICK_RATE);
System.out.println("Players online: " + PlayerManager.getInstance().getPlayerCount()+ ", engine load: "+ debugPercentFormat.format(engineLoad));
totalCycleTime = 0;
cycles = 0;
System.gc();
debugTimer.reset();
}
}
public void start() {
logger.info("Starting server version "+Config.CLIENT_VERSION);
}
private static void startPeriodicCheck() {
new Thread(() -> {
while (true) {
try {
Thread.sleep(30000); // 30 seconds
for (Player player : PlayerManager.getInstance().players) {
if (player != null) {
player.currentWeaponBonus = SpecialWeaponConfig.getDamageMultiplier(
player.getEquipment().getPlayerWeapon(), player.skin);
// Cache for applyDamage
}
}
} catch (InterruptedException e) {
System.err.println("Periodic check error: " + e);
}
}
}).start();
}
//provide logging details
public static final Logger logger = Logger.getLogger(Server.class.getName());
//the port the server runs on
private static final int PORT = Config.SERVER_PORT;
//Socket acceptor
private final IoAcceptor acceptor = new NioSocketAcceptor();
//main gameengine instance
public static GameEngine gameEngine;
//count down for updating server
public static int updateTicks = -1;
//shut down when set to true
public static boolean shutdownServer = false;
}