mirror of
https://github.com/Melledy/Nebula.git
synced 2025-12-13 21:04:36 +01:00
251 lines
7.8 KiB
Java
251 lines
7.8 KiB
Java
package emu.nebula;
|
|
|
|
import java.io.*;
|
|
import java.text.SimpleDateFormat;
|
|
import java.util.Date;
|
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import com.google.gson.Gson;
|
|
import com.google.gson.GsonBuilder;
|
|
|
|
import emu.nebula.command.CommandManager;
|
|
import emu.nebula.data.ResourceLoader;
|
|
import emu.nebula.database.DatabaseManager;
|
|
import emu.nebula.game.GameContext;
|
|
import emu.nebula.net.PacketHelper;
|
|
import emu.nebula.server.HttpServer;
|
|
import emu.nebula.util.Handbook;
|
|
import emu.nebula.util.JsonUtils;
|
|
import lombok.Getter;
|
|
|
|
public class Nebula {
|
|
private static final Logger log = LoggerFactory.getLogger(Nebula.class);
|
|
|
|
// Config
|
|
private static final File configFile = new File("./config.json");
|
|
@Getter private static Config config;
|
|
|
|
// Database
|
|
@Getter private static DatabaseManager accountDatabase;
|
|
@Getter private static DatabaseManager gameDatabase;
|
|
|
|
// Server
|
|
@Getter private static HttpServer httpServer;
|
|
@Getter private static HttpServer gameServer; // TODO
|
|
@Getter private static ServerType serverType = ServerType.BOTH;
|
|
|
|
@Getter private static GameContext gameContext;
|
|
@Getter private static CommandManager commandManager;
|
|
|
|
public static void main(String[] args) {
|
|
// Start Server
|
|
Nebula.getLogger().info("Starting Nebula " + getJarVersion());
|
|
Nebula.getLogger().info("Git hash: " + getGitHash());
|
|
Nebula.getLogger().info("Game version: " + GameConstants.VERSION);
|
|
|
|
boolean generateHandbook = true;
|
|
|
|
// Load config + commands
|
|
Nebula.loadConfig();
|
|
|
|
// Parse arguments
|
|
for (String arg : args) {
|
|
switch (arg) {
|
|
case "-login":
|
|
serverType = ServerType.LOGIN;
|
|
break;
|
|
case "-game":
|
|
serverType = ServerType.GAME;
|
|
break;
|
|
case "-nohandbook":
|
|
case "-skiphandbook":
|
|
generateHandbook = false;
|
|
break;
|
|
case "-database":
|
|
// Database only
|
|
DatabaseManager.startInternalMongoServer(Nebula.getConfig().getInternalMongoServer());
|
|
Nebula.getLogger().info("Running local Mongo server at " + DatabaseManager.getServer().getConnectionString());
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Skip these if we are only running the http server in dispatch mode
|
|
if (serverType.runGame()) {
|
|
// Load resources
|
|
ResourceLoader.loadAll();
|
|
// Generate handbook
|
|
if (generateHandbook) {
|
|
Handbook.generate();
|
|
}
|
|
// Cache proto methods
|
|
PacketHelper.cacheProtos();
|
|
}
|
|
|
|
try {
|
|
// Start Database(s)
|
|
Nebula.initDatabases();
|
|
} catch (Exception exception) {
|
|
Nebula.getLogger().error("Unable to start the database(s).", exception);
|
|
}
|
|
|
|
// Start game context
|
|
Nebula.gameContext = new GameContext();
|
|
Nebula.commandManager = new CommandManager();
|
|
|
|
// Start servers
|
|
try {
|
|
// Always run http server as it is needed by for dispatch and gateserver
|
|
httpServer = new HttpServer(serverType);
|
|
httpServer.start();
|
|
} catch (Exception exception) {
|
|
Nebula.getLogger().error("Unable to start the HTTP server.", exception);
|
|
}
|
|
|
|
// Start console
|
|
Nebula.startConsole();
|
|
}
|
|
|
|
public static Logger getLogger() {
|
|
return log;
|
|
}
|
|
|
|
// Database
|
|
|
|
private static void initDatabases() {
|
|
if (Nebula.getConfig().useSameDatabase) {
|
|
// Setup account and game database
|
|
accountDatabase = new DatabaseManager(Nebula.getConfig().getAccountDatabase(), serverType);
|
|
// Optimization: Dont run a 2nd database manager if we are not running a gameserver
|
|
if (serverType.runGame()) {
|
|
gameDatabase = accountDatabase;
|
|
}
|
|
} else {
|
|
// Run separate databases
|
|
accountDatabase = new DatabaseManager(Nebula.getConfig().getAccountDatabase(), ServerType.LOGIN);
|
|
// Optimization: Dont run a 2nd database manager if we are not running a gameserver
|
|
if (serverType.runGame()) {
|
|
gameDatabase = new DatabaseManager(Nebula.getConfig().getGameDatabase(), ServerType.GAME);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Config
|
|
|
|
public static void loadConfig() {
|
|
// Load from file
|
|
try (FileReader file = new FileReader(configFile)) {
|
|
Nebula.config = JsonUtils.loadToClass(file, Config.class);
|
|
} catch (Exception e) {
|
|
// Ignored
|
|
}
|
|
|
|
// Sanity check
|
|
if (Nebula.getConfig() == null) {
|
|
Nebula.config = new Config();
|
|
}
|
|
|
|
// Save config
|
|
Nebula.saveConfig();
|
|
}
|
|
|
|
public static void saveConfig() {
|
|
try (FileWriter file = new FileWriter(configFile)) {
|
|
Gson gson = new GsonBuilder()
|
|
.setDateFormat("dd-MM-yyyy hh:mm:ss")
|
|
.setPrettyPrinting()
|
|
.serializeNulls()
|
|
.create();
|
|
|
|
file.write(gson.toJson(config));
|
|
} catch (Exception e) {
|
|
getLogger().error("Config save error");
|
|
}
|
|
}
|
|
|
|
// Build Config
|
|
|
|
private static String getJarVersion() {
|
|
// Safely get the build config class without errors even if it hasnt been generated yet
|
|
try {
|
|
Class<?> buildConfig = Class.forName(Nebula.class.getPackageName() + ".BuildConfig");
|
|
return buildConfig.getField("VERSION").get(null).toString();
|
|
} catch (Exception e) {
|
|
// Ignored
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
public static String getGitHash() {
|
|
// Use a string builder in case one of the build config fields are missing
|
|
StringBuilder builder = new StringBuilder();
|
|
|
|
// Safely get the build config class without errors even if it hasnt been generated yet
|
|
try {
|
|
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
Class<?> buildConfig = Class.forName(Nebula.class.getPackageName() + ".BuildConfig");
|
|
|
|
String hash = buildConfig.getField("GIT_HASH").get(null).toString();
|
|
builder.append(hash);
|
|
|
|
String timestamp = buildConfig.getField("GIT_TIMESTAMP").get(null).toString();
|
|
long time = Long.parseLong(timestamp) * 1000;
|
|
builder.append(" (" + sf.format(new Date(time)) + ")");
|
|
} catch (Exception e) {
|
|
// Ignored
|
|
}
|
|
|
|
if (builder.isEmpty()) {
|
|
return "UNKNOWN";
|
|
} else {
|
|
return builder.toString();
|
|
}
|
|
}
|
|
|
|
// Utils
|
|
|
|
/**
|
|
* Returns the current server time in seconds
|
|
*/
|
|
public static long getCurrentTime() {
|
|
return System.currentTimeMillis() / 1000;
|
|
}
|
|
|
|
// Console
|
|
|
|
private static void startConsole() {
|
|
String input;
|
|
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
|
|
while ((input = br.readLine()) != null) {
|
|
Nebula.getCommandManager().invoke(null, input);
|
|
}
|
|
} catch (Exception e) {
|
|
Nebula.getLogger().error("Console error:", e);
|
|
}
|
|
}
|
|
|
|
// Server enums
|
|
|
|
public enum ServerType {
|
|
LOGIN (0x1),
|
|
GAME (0x2),
|
|
BOTH (0x3);
|
|
|
|
private final int flags;
|
|
|
|
ServerType(int flags) {
|
|
this.flags = flags;
|
|
}
|
|
|
|
public boolean runLogin() {
|
|
return (this.flags & 0x1) == 0x1;
|
|
}
|
|
|
|
public boolean runGame() {
|
|
return (this.flags & 0x2) == 0x2;
|
|
}
|
|
}
|
|
}
|