Arcturus-Community/src/main/java/com/eu/habbo/Emulator.java

401 lines
16 KiB
Java
Raw Normal View History

2018-07-06 15:30:00 +02:00
package com.eu.habbo;
2018-09-28 21:25:00 +02:00
import com.eu.habbo.core.CleanerThread;
import com.eu.habbo.core.ConfigurationManager;
import com.eu.habbo.core.Logging;
import com.eu.habbo.core.TextsManager;
2018-07-06 15:30:00 +02:00
import com.eu.habbo.core.consolecommands.ConsoleCommand;
import com.eu.habbo.database.Database;
import com.eu.habbo.habbohotel.GameEnvironment;
import com.eu.habbo.networking.camera.CameraClient;
import com.eu.habbo.networking.gameserver.GameServer;
import com.eu.habbo.networking.rconserver.RCONServer;
import com.eu.habbo.plugin.PluginManager;
import com.eu.habbo.plugin.events.emulator.EmulatorConfigUpdatedEvent;
import com.eu.habbo.plugin.events.emulator.EmulatorLoadedEvent;
import com.eu.habbo.plugin.events.emulator.EmulatorStartShutdownEvent;
import com.eu.habbo.plugin.events.emulator.EmulatorStoppedEvent;
import com.eu.habbo.threading.ThreadPooling;
import com.eu.habbo.util.imager.badges.BadgeImager;
import org.fusesource.jansi.AnsiConsole;
2018-07-06 15:30:00 +02:00
2019-07-24 14:59:20 +02:00
import java.io.*;
2019-05-12 22:31:59 +02:00
import java.security.MessageDigest;
2018-07-06 15:30:00 +02:00
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
2019-05-17 11:21:55 +02:00
import java.util.Locale;
2018-07-06 15:30:00 +02:00
import java.util.Random;
2019-05-26 20:14:53 +02:00
public final class Emulator {
2018-07-08 23:32:00 +02:00
public final static int MAJOR = 2;
2020-04-03 17:40:48 +02:00
public final static int MINOR = 4;
public final static int BUILD = 0;
public static final String ANSI_RED = "\u001B[31m";
public static final String ANSI_BLUE = "\u001B[34m";
public static final String ANSI_PURPLE = "\u001B[35m";
public static final String ANSI_WHITE = "\u001B[37m";
public static final String ANSI_YELLOW = "\u001B[33m";
2020-04-03 17:40:48 +02:00
// This Build of 2.4.0 will not be released anytime soon. :)
2018-07-06 15:30:00 +02:00
2020-04-03 17:40:48 +02:00
public final static String PREVIEW = "RC-1";
2018-07-08 23:32:00 +02:00
2020-04-03 17:40:48 +02:00
public static final String version = "Arcturus Morningstar" + " " + MAJOR + "." + MINOR + "." + BUILD + "-" + PREVIEW;
2019-05-26 20:14:53 +02:00
private static final String logo =
"\n" +
"███╗ ███╗ ██████╗ ██████╗ ███╗ ██╗██╗███╗ ██╗ ██████╗ ███████╗████████╗ █████╗ ██████╗ \n" +
"████╗ ████║██╔═══██╗██╔══██╗████╗ ██║██║████╗ ██║██╔════╝ ██╔════╝╚══██╔══╝██╔══██╗██╔══██╗\n" +
"██╔████╔██║██║ ██║██████╔╝██╔██╗ ██║██║██╔██╗ ██║██║ ███╗███████╗ ██║ ███████║██████╔╝\n" +
"██║╚██╔╝██║██║ ██║██╔══██╗██║╚██╗██║██║██║╚██╗██║██║ ██║╚════██║ ██║ ██╔══██║██╔══██╗\n" +
"██║ ╚═╝ ██║╚██████╔╝██║ ██║██║ ╚████║██║██║ ╚████║╚██████╔╝███████║ ██║ ██║ ██║██║ ██║\n" +
"╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝\n" +
" ";
2018-07-06 15:30:00 +02:00
2019-05-12 22:31:59 +02:00
public static String build = "";
2018-07-06 15:30:00 +02:00
public static boolean isReady = false;
public static boolean isShuttingDown = false;
public static boolean stopped = false;
public static boolean debugging = false;
private static String classPath = System.getProperty("java.class.path");
private static String osName = System.getProperty("os.name");
2019-05-26 20:14:53 +02:00
private static int timeStarted = 0;
private static Runtime runtime;
private static ConfigurationManager config;
private static TextsManager texts;
private static GameServer gameServer;
private static RCONServer rconServer;
private static CameraClient cameraClient;
private static Database database;
private static Logging logging;
private static ThreadPooling threading;
private static GameEnvironment gameEnvironment;
private static PluginManager pluginManager;
private static Random random;
private static BadgeImager badgeImager;
static {
Thread hook = new Thread(new Runnable() {
public synchronized void run() {
2018-07-06 15:30:00 +02:00
Emulator.dispose();
}
});
hook.setPriority(10);
Runtime.getRuntime().addShutdownHook(hook);
}
2019-05-26 20:14:53 +02:00
public static void main(String[] args) throws Exception {
try {
if (osName.startsWith("Windows") && (!classPath.contains("idea_rt.jar"))) {
AnsiConsole.systemInstall();
}
2019-05-17 11:21:55 +02:00
Locale.setDefault(new Locale("en"));
2019-05-12 22:31:59 +02:00
setBuild();
2018-07-06 15:30:00 +02:00
Emulator.stopped = false;
ConsoleCommand.load();
Emulator.logging = new Logging();
System.out.println(ANSI_PURPLE + logo );
System.out.println(ANSI_WHITE + "This project is for educational purposes only. This Emulator is an open-source fork of Arcturus created by TheGeneral.");
System.out.println(ANSI_BLUE + "[VERSION] " + ANSI_WHITE + version);
System.out.println(ANSI_RED + "[BUILD] " + ANSI_WHITE + build + "\n");
System.out.println(ANSI_YELLOW + "[KREWS] " + ANSI_WHITE + "Remember to sign up your hotel to join our toplist beta at https://bit.ly/2NN0rxq" );
System.out.println(ANSI_YELLOW + "[KREWS] " + ANSI_WHITE + "Join our discord at https://discord.gg/syuqgN" + "\n");
2018-07-06 15:30:00 +02:00
random = new Random();
long startTime = System.nanoTime();
Emulator.runtime = Runtime.getRuntime();
Emulator.config = new ConfigurationManager("config.ini");
Emulator.database = new Database(Emulator.getConfig());
Emulator.config.loaded = true;
Emulator.config.loadFromDatabase();
Emulator.threading = new ThreadPooling(Emulator.getConfig().getInt("runtime.threads"));
Emulator.getDatabase().getDataSource().setMaximumPoolSize(Emulator.getConfig().getInt("runtime.threads") * 2);
Emulator.getDatabase().getDataSource().setMinimumIdle(10);
Emulator.pluginManager = new PluginManager();
Emulator.pluginManager.reload();
Emulator.getPluginManager().fireEvent(new EmulatorConfigUpdatedEvent());
Emulator.texts = new TextsManager();
new CleanerThread();
Emulator.gameServer = new GameServer(getConfig().getValue("game.host", "127.0.0.1"), getConfig().getInt("game.port", 30000));
2020-01-27 23:12:47 +01:00
Emulator.rconServer = new RCONServer(getConfig().getValue("rcon.host", "127.0.0.1"), getConfig().getInt("rcon.port", 30001));
2018-07-06 15:30:00 +02:00
Emulator.gameEnvironment = new GameEnvironment();
Emulator.gameEnvironment.load();
2018-10-07 00:28:00 +02:00
Emulator.gameServer.initializePipeline();
2018-07-06 15:30:00 +02:00
Emulator.gameServer.connect();
2020-01-27 23:12:47 +01:00
Emulator.rconServer.initializePipeline();
Emulator.rconServer.connect();
2018-07-06 15:30:00 +02:00
Emulator.badgeImager = new BadgeImager();
Emulator.getLogging().logStart("Arcturus Morningstar has succesfully loaded. You're running: " + Emulator.version);
2018-07-06 15:30:00 +02:00
Emulator.getLogging().logStart("System launched in: " + (System.nanoTime() - startTime) / 1e6 + "ms. Using: " + (Runtime.getRuntime().availableProcessors() * 2) + " threads!");
Emulator.getLogging().logStart("Memory: " + (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024) + "/" + (runtime.freeMemory()) / (1024 * 1024) + "MB");
Emulator.debugging = Emulator.getConfig().getBoolean("debug.mode");
2019-05-26 20:14:53 +02:00
if (debugging) {
2018-07-06 15:30:00 +02:00
Emulator.getLogging().logDebugLine("Debugging Enabled!");
}
Emulator.getPluginManager().fireEvent(new EmulatorLoadedEvent());
Emulator.isReady = true;
Emulator.timeStarted = getIntUnixTimestamp();
2019-05-26 20:14:53 +02:00
if (Emulator.getConfig().getInt("runtime.threads") < (Runtime.getRuntime().availableProcessors() * 2)) {
2018-07-06 15:30:00 +02:00
Emulator.getLogging().logStart("Emulator settings runtime.threads (" + Emulator.getConfig().getInt("runtime.threads") + ") can be increased to " + (Runtime.getRuntime().availableProcessors() * 2) + " to possibly increase performance.");
}
2019-07-17 02:33:19 +02:00
Emulator.getThreading().run(() -> {
2019-07-24 13:12:53 +02:00
}, 1500);
2018-09-12 18:45:00 +02:00
2018-07-06 15:30:00 +02:00
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
2019-07-24 13:12:53 +02:00
while (!isShuttingDown && isReady) {
2019-05-26 20:14:53 +02:00
try {
2018-12-22 11:39:00 +01:00
2018-07-06 15:30:00 +02:00
String line = reader.readLine();
2019-05-26 20:14:53 +02:00
if (line != null) {
2018-07-06 15:30:00 +02:00
ConsoleCommand.handle(line);
}
2018-12-22 11:39:00 +01:00
System.out.println("Waiting for command: ");
2019-05-26 20:14:53 +02:00
} catch (Exception e) {
2019-07-24 14:59:20 +02:00
if (!(e instanceof IOException && e.getMessage().equals("Bad file descriptor"))) {
Emulator.getLogging().logErrorLine(e);
}
2018-07-06 15:30:00 +02:00
}
}
2019-05-26 20:14:53 +02:00
} catch (Exception e) {
2018-07-06 15:30:00 +02:00
e.printStackTrace();
}
}
2019-05-12 22:31:59 +02:00
private static void setBuild() {
2019-09-10 22:37:06 +02:00
if (Emulator.class.getProtectionDomain().getCodeSource() == null) {
build = "UNKNOWN";
return;
}
2019-05-12 22:31:59 +02:00
StringBuilder sb = new StringBuilder();
2019-05-26 20:14:53 +02:00
try {
2019-09-10 22:37:06 +02:00
String filepath = new File(Emulator.class.getProtectionDomain().getCodeSource().getLocation().getPath()).getAbsolutePath();
2019-05-12 22:31:59 +02:00
MessageDigest md = MessageDigest.getInstance("MD5");// MD5
2019-09-10 22:37:06 +02:00
FileInputStream fis = new FileInputStream(filepath);
2019-05-12 22:31:59 +02:00
byte[] dataBytes = new byte[1024];
int nread = 0;
2019-09-10 22:37:06 +02:00
while ((nread = fis.read(dataBytes)) != -1)
2019-05-12 22:31:59 +02:00
md.update(dataBytes, 0, nread);
byte[] mdbytes = md.digest();
2019-05-26 20:14:53 +02:00
for (int i = 0; i < mdbytes.length; i++)
sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
} catch (Exception e) {
2019-05-12 22:31:59 +02:00
build = "UNKNOWN";
return;
}
build = sb.toString();
}
2019-05-26 20:14:53 +02:00
private static void dispose() {
2019-04-22 01:42:00 +02:00
Emulator.getThreading().setCanAdd(false);
2018-07-06 15:30:00 +02:00
Emulator.isShuttingDown = true;
Emulator.isReady = false;
Emulator.getLogging().logShutdownLine("Stopping Arcturus Emulator " + version + "...");
2019-05-26 20:14:53 +02:00
try {
2018-07-06 15:30:00 +02:00
if (Emulator.getPluginManager() != null)
Emulator.getPluginManager().fireEvent(new EmulatorStartShutdownEvent());
2019-05-26 20:14:53 +02:00
} catch (Exception e) {
2018-07-06 15:30:00 +02:00
}
2019-05-26 20:14:53 +02:00
try {
2018-07-06 15:30:00 +02:00
if (Emulator.cameraClient != null)
Emulator.cameraClient.disconnect();
2019-05-26 20:14:53 +02:00
} catch (Exception e) {
2018-07-06 15:30:00 +02:00
}
2019-05-26 20:14:53 +02:00
try {
2018-07-06 15:30:00 +02:00
if (Emulator.rconServer != null)
Emulator.rconServer.stop();
2019-05-26 20:14:53 +02:00
} catch (Exception e) {
2018-07-06 15:30:00 +02:00
}
2019-05-26 20:14:53 +02:00
try {
2018-07-06 15:30:00 +02:00
if (Emulator.gameEnvironment != null)
Emulator.gameEnvironment.dispose();
2019-05-26 20:14:53 +02:00
} catch (Exception e) {
2018-07-06 15:30:00 +02:00
}
2019-05-26 20:14:53 +02:00
try {
2018-07-06 15:30:00 +02:00
if (Emulator.getPluginManager() != null)
Emulator.getPluginManager().fireEvent(new EmulatorStoppedEvent());
2019-05-26 20:14:53 +02:00
} catch (Exception e) {
2018-07-06 15:30:00 +02:00
}
2019-05-26 20:14:53 +02:00
try {
2018-07-06 15:30:00 +02:00
if (Emulator.pluginManager != null)
Emulator.pluginManager.dispose();
2019-05-26 20:14:53 +02:00
} catch (Exception e) {
2018-07-06 15:30:00 +02:00
}
Emulator.getLogging().saveLogs();
2019-05-26 20:14:53 +02:00
try {
if (Emulator.config != null) {
2018-07-06 15:30:00 +02:00
Emulator.config.saveToDatabase();
}
2019-05-26 20:14:53 +02:00
} catch (Exception e) {
2018-07-06 15:30:00 +02:00
}
2019-05-26 20:14:53 +02:00
try {
2018-07-06 15:30:00 +02:00
if (Emulator.gameServer != null)
Emulator.gameServer.stop();
2019-05-26 20:14:53 +02:00
} catch (Exception e) {
2018-07-06 15:30:00 +02:00
}
Emulator.getLogging().logShutdownLine("Stopped Arcturus Emulator " + version + "...");
2019-05-26 20:14:53 +02:00
if (Emulator.database != null) {
2018-07-06 15:30:00 +02:00
Emulator.getDatabase().dispose();
}
Emulator.stopped = true;
if (osName.startsWith("Windows") && (!classPath.contains("idea_rt.jar"))) {
AnsiConsole.systemUninstall();
}
2019-05-26 20:14:53 +02:00
try {
2018-07-06 15:30:00 +02:00
if (Emulator.threading != null)
2018-07-06 15:30:00 +02:00
Emulator.threading.shutDown();
2019-05-26 20:14:53 +02:00
} catch (Exception e) {
2018-07-06 15:30:00 +02:00
}
}
2019-05-26 20:14:53 +02:00
public static ConfigurationManager getConfig() {
2018-07-06 15:30:00 +02:00
return config;
}
2019-05-26 20:14:53 +02:00
public static TextsManager getTexts() {
2018-07-06 15:30:00 +02:00
return texts;
}
2019-05-26 20:14:53 +02:00
public static Database getDatabase() {
2018-07-06 15:30:00 +02:00
return database;
}
2019-05-26 20:14:53 +02:00
public static Runtime getRuntime() {
2018-07-06 15:30:00 +02:00
return runtime;
}
2019-05-26 20:14:53 +02:00
public static GameServer getGameServer() {
2018-07-06 15:30:00 +02:00
return gameServer;
}
2019-05-26 20:14:53 +02:00
public static RCONServer getRconServer() {
2018-07-06 15:30:00 +02:00
return rconServer;
}
2019-05-26 20:14:53 +02:00
public static Logging getLogging() {
2018-07-06 15:30:00 +02:00
return logging;
}
2019-05-26 20:14:53 +02:00
public static ThreadPooling getThreading() {
2018-07-06 15:30:00 +02:00
return threading;
}
2019-05-26 20:14:53 +02:00
public static GameEnvironment getGameEnvironment() {
2018-07-06 15:30:00 +02:00
return gameEnvironment;
}
2019-05-26 20:14:53 +02:00
public static PluginManager getPluginManager() {
2018-07-06 15:30:00 +02:00
return pluginManager;
}
2019-05-26 20:14:53 +02:00
public static Random getRandom() {
2018-07-06 15:30:00 +02:00
return random;
}
2019-05-26 20:14:53 +02:00
public static BadgeImager getBadgeImager() {
2018-07-06 15:30:00 +02:00
return badgeImager;
}
2019-05-26 20:14:53 +02:00
public static CameraClient getCameraClient() {
2018-07-06 15:30:00 +02:00
return cameraClient;
}
2019-05-26 20:14:53 +02:00
public static synchronized void setCameraClient(CameraClient client) {
2018-07-06 15:30:00 +02:00
cameraClient = client;
}
2018-12-22 11:39:00 +01:00
2019-05-26 20:14:53 +02:00
public static int getTimeStarted() {
2018-07-06 15:30:00 +02:00
return timeStarted;
}
2018-12-22 11:39:00 +01:00
2019-05-26 20:14:53 +02:00
public static int getOnlineTime() {
2019-04-22 01:42:00 +02:00
return getIntUnixTimestamp() - timeStarted;
}
2019-05-26 20:14:53 +02:00
public static void prepareShutdown() {
2018-07-06 15:30:00 +02:00
System.exit(0);
}
2019-05-26 20:14:53 +02:00
private static String dateToUnixTimestamp(Date date) {
2018-07-06 15:30:00 +02:00
String res = "";
Date aux = stringToDate("1970-01-01 00:00:00");
Timestamp aux1 = dateToTimeStamp(aux);
Timestamp aux2 = dateToTimeStamp(date);
long difference = aux2.getTime() - aux1.getTime();
long seconds = difference / 1000L;
return res + seconds;
}
2019-05-26 20:14:53 +02:00
private static Date stringToDate(String date) {
2018-07-06 15:30:00 +02:00
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date res = null;
2019-05-26 20:14:53 +02:00
try {
2018-07-06 15:30:00 +02:00
res = format.parse(date);
2019-05-26 20:14:53 +02:00
} catch (Exception e) {
2018-07-06 15:30:00 +02:00
Emulator.getLogging().logErrorLine(e);
}
return res;
}
2018-12-22 11:39:00 +01:00
2019-05-26 20:14:53 +02:00
public static Timestamp dateToTimeStamp(Date date) {
2018-07-06 15:30:00 +02:00
return new Timestamp(date.getTime());
}
2019-05-26 20:14:53 +02:00
public static Date getDate() {
2018-07-06 15:30:00 +02:00
return new Date(System.currentTimeMillis());
}
2019-05-26 20:14:53 +02:00
public static String getUnixTimestamp() {
2018-07-06 15:30:00 +02:00
return dateToUnixTimestamp(getDate());
}
2018-12-22 11:39:00 +01:00
2019-05-26 20:14:53 +02:00
public static int getIntUnixTimestamp() {
2018-07-06 15:30:00 +02:00
return (int) (System.currentTimeMillis() / 1000);
}
2018-12-22 11:39:00 +01:00
2018-07-06 15:30:00 +02:00
public static boolean isNumeric(String string)
2019-05-26 20:14:53 +02:00
throws IllegalArgumentException {
2018-07-06 15:30:00 +02:00
boolean isnumeric = false;
2019-05-26 20:14:53 +02:00
if ((string != null) && (!string.equals(""))) {
2018-07-06 15:30:00 +02:00
isnumeric = true;
char[] chars = string.toCharArray();
2019-05-26 20:14:53 +02:00
for (char aChar : chars) {
2018-07-06 15:30:00 +02:00
isnumeric = Character.isDigit(aChar);
2019-05-26 20:14:53 +02:00
if (!isnumeric) {
2018-07-06 15:30:00 +02:00
break;
}
}
}
return isnumeric;
}
2019-05-26 20:14:53 +02:00
public int getUserCount() {
2018-07-06 15:30:00 +02:00
return gameEnvironment.getHabboManager().getOnlineCount();
}
2019-05-26 20:14:53 +02:00
public int getRoomCount() {
2018-07-06 15:30:00 +02:00
return gameEnvironment.getRoomManager().getActiveRooms().size();
}
}