Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package host.batt.daemon;
- import host.batt.daemon.ftp.*;
- import host.batt.daemon.console.commands.*;
- import host.batt.daemon.net.websocket.*;
- import host.batt.daemon.net.daemonsocket.*;
- import host.batt.daemon.tasks.*;
- import host.batt.daemon.migration.*;
- import org.apache.commons.io.FileUtils;
- import org.apache.commons.lang3.exception.*;
- import host.batt.daemon.console.*;
- import java.nio.charset.*;
- import host.batt.daemon.sql.*;
- import java.sql.*;
- import host.batt.daemon.adapter.*;
- import host.batt.daemon.processhooker.*;
- import java.io.*;
- import host.batt.daemon.config.*;
- import java.util.*;
- import java.util.Date;
- import java.util.concurrent.TimeUnit;
- import host.batt.daemon.system.*;
- public class MinecraftDaemon implements DaemonInfo, ManageableServer, ConsoleInput
- {
- public static String daemon_base_dir;
- public static String server_base_dir;
- public static String default_jars_dir;
- public static String process_hook_stream_dir;
- public static String update_dir;
- public static String migration_output_dir;
- public static String migration_input_dir;
- public static long version;
- public static String prefix;
- private boolean running;
- private boolean shuttingDown;
- private boolean outputServersConsole;
- private ConsoleBuffer consoleBuffer;
- private MysqlManager mysqlManager;
- private MysqlLogger mysqlLogger;
- private DaemonFtpServer ftpServer;
- private DaemonConfiguration daemonConfig;
- private CommandManager commandManager;
- private DaemonAdapter adapter;
- private ConsoleSocket consoleSocket;
- private DaemonSocket daemonSocket;
- public static ProcessWatcher processWatcher;
- private TaskManager taskManager;
- private MigrationManager migrationManager;
- private long startup;
- private long lastShutdownRequest;
- private Thread refreshThread;
- public List<MinecraftJavaServer> servers;
- private int lines = 1;
- public static MinecraftDaemon here;
- public MinecraftDaemon() {
- this.running = true;
- this.shuttingDown = false;
- this.outputServersConsole = false;
- this.consoleBuffer = new ConsoleBuffer(this);
- this.processWatcher = new UnixProcessWatcher();
- this.taskManager = new TaskManager(this);
- this.servers = new ArrayList<MinecraftJavaServer>();
- here = this;
- }
- public long getVersion() {
- return MinecraftDaemon.version;
- }
- public void log(final LogLevel level, final String line) {
- Date date = new Date();
- String info = date.getHours()+":"+date.getMinutes()+" - " + lines;
- switch (level) {
- case DAEMON_INFO: {
- this.consoleBuffer.outputLine("["+info+"] [INFO] " + line);
- break;
- }
- case DAEMON_ERROR: {
- this.consoleBuffer.outputLine("["+info+"] [Daemon Exception] " + line);
- break;
- }
- case CONSOLE_SOCKET: {
- this.consoleBuffer.outputLine("["+info+"] [Console Socket] " + line);
- break;
- }
- case DAEMON_SOCKET: {
- this.consoleBuffer.outputLine("["+info+"] [Daemon Socket] " + line);
- break;
- }
- case FTP: {
- this.consoleBuffer.outputLine("["+info+"] [FTP] ["+info+"] " + line);
- break;
- }
- case SQL: {
- this.consoleBuffer.outputLine("["+info+"] [SQL] ["+info+"] " + line);
- break;
- }
- case DOCKER_ERROR: {
- this.consoleBuffer.outputLine("["+info+"] [SQL] ["+info+"] " + line);
- break;
- }
- case SERVER: {
- if (this.outputServersConsole) {
- this.consoleBuffer.outputLine(line);
- break;
- }
- break;
- }
- case SERVER_ERROR: {
- this.consoleBuffer.outputLine(line);
- break;
- }
- }
- lines++;
- }
- public void printDaemonException(final Throwable throwable) {
- this.log(LogLevel.DAEMON_ERROR, ExceptionUtils.getStackTrace(throwable));
- }
- public static void sleep(final long millis) {
- try {
- Thread.sleep(millis);
- }
- catch (InterruptedException ex) {}
- }
- public static void main(final String[] args) throws InterruptedException {
- installDocker();
- final MinecraftDaemon instance = new MinecraftDaemon();
- instance.getConsoleBuffer().hook(new ConsoleHook() {
- @Override
- public void onOutput(final String line) {
- System.out.println(line);
- }
- });
- instance.init();
- startCommandServer(instance);
- final BufferedReader stdInput = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));
- try {
- while (instance.running) {
- final String l;
- if ((l = stdInput.readLine()) == null) {
- break;
- }
- instance.handleCommand(l);
- }
- }
- catch (Exception ex) {}
- }
- public static void startCommandServer(MinecraftDaemon i){
- //Vertx vertx = Vertx.vertx();
- //vertx.deployVerticle(new CmdServer(i));
- }
- public static File loadDefaultJar(final String fileName) {
- return new File(String.valueOf(MinecraftDaemon.default_jars_dir) + fileName);
- }
- public void init() {
- this.startup = System.currentTimeMillis();
- try {
- this.loadConfig();
- }
- catch (Exception e) {
- e.printStackTrace();
- this.shutdown();
- return;
- }
- new Thread(getSizeUpdater()).start();
- this.log(LogLevel.DAEMON_INFO, "Using MYSQL database: " + MysqlConfig.getDefault().getHost());
- this.mysqlLogger = new MysqlLogger(this.mysqlManager, this.adapter.getDaemonUUID());
- this.migrationManager = new MigrationManager(this);
- (this.commandManager = new CommandManager(this)).registerDefaults();
- this.loadServers();
- (this.ftpServer = new DaemonFtpServer(this)).start();
- (this.consoleSocket = new ConsoleSocket(this)).listen(this.daemonConfig.getWebSocketPort());
- (this.daemonSocket = new DaemonSocket(this)).listen(8029);
- Runtime.getRuntime().addShutdownHook(new Thread() {
- @Override
- public void run() {
- MinecraftDaemon.this.kill();
- }
- });
- this.refreshThread = new Thread(new Runnable() {
- @Override
- public void run() {
- while (MinecraftDaemon.this.running) {
- try {
- if (MinecraftDaemon.this.getTimeTillNextRestart() == 0) {
- MinecraftDaemon.this.restart();
- }
- MinecraftDaemon.sleep(15000L);
- MinecraftDaemon.this.taskManager.refresh();
- MinecraftDaemon.this.migrationManager.refresh();
- MinecraftDaemon.this.startAll();
- MinecraftDaemon.this.loadServers();
- }
- catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- });
- new Thread(new Runnable() {
- @Override
- public void run() {
- MinecraftDaemon.this.clearCache();
- }
- }).start();
- this.refreshThread.start();
- this.startAll();
- this.mysqlLogger.logAsync("Daemon inicializado com sucesso.");
- }
- @Override
- public void kill() {
- for (final MinecraftJavaServer server : this.servers) {
- System.out.println("[Shutdown Handler] Sending kill signal to server " + server.getId());
- server.kill();
- }
- this.ftpServer.kill();
- this.consoleSocket.stop();
- this.daemonSocket.stop();
- this.mysqlManager.cancelTasks();
- this.refreshThread.stop();
- this.running = false;
- }
- @Override
- public void restart() {
- this.shutdown(false);
- }
- @Override
- public void shutdown() {
- this.shutdown(true);
- }
- public int getTimeTillNextRestart() {
- return Math.max(0, 21600 - this.getOnlineTime());
- }
- public void shutdown(final boolean stopServers) {
- if (this.shuttingDown && System.currentTimeMillis() - this.lastShutdownRequest < 120000L) {
- this.log(LogLevel.DAEMON_INFO, "Daemon is already in a shut down process.");
- return;
- }
- this.lastShutdownRequest = System.currentTimeMillis();
- this.shuttingDown = true;
- try {
- this.mysqlLogger.log("Processo de desligamento iniciado");
- }
- catch (SQLException ex) {}
- if (!stopServers) {
- this.servers.clear();
- }
- else {
- for (final MinecraftJavaServer server : this.servers) {
- server.shutdown();
- }
- }
- this.ftpServer.stop();
- this.consoleSocket.stop();
- this.daemonSocket.stop();
- this.mysqlManager.cancelTasks();
- int secs = 0;
- if (stopServers) {
- this.log(LogLevel.DAEMON_INFO, "Now waiting for all servers to shut down.");
- while (this.getRunningServerCount() > 0) {
- if (secs >= 30) {
- this.log(LogLevel.DAEMON_INFO, "Servers did not shutdown in 30 seconds, they will now be killed immediately.");
- for (final MinecraftJavaServer server2 : this.servers) {
- server2.kill();
- }
- break;
- }
- try {
- Thread.sleep(1000L);
- }
- catch (InterruptedException ex2) {}
- ++secs;
- }
- }
- this.running = false;
- if (!stopServers) {
- Runtime.getRuntime().halt(1);
- }
- else {
- System.exit(0);
- }
- }
- private void loadConfig() throws Exception {
- final Properties pro = new Properties();
- pro.load(this.getClass().getResourceAsStream("/build.properties"));
- MinecraftDaemon.version = Long.valueOf(pro.getProperty("version").replaceAll("_", ""));
- this.daemonConfig = DaemonConfigurationLoader.loadConfig();
- this.mysqlManager = new MysqlManager(this.daemonConfig.getMysqlConfig());
- (this.adapter = new MysqlAdapter(this.mysqlManager, this)).loadConfig(this.daemonConfig);
- MinecraftDaemon.prefix = this.daemonConfig.getPrefix();
- MinecraftDaemon.daemon_base_dir = this.daemonConfig.getDaemonBaseDir();
- MinecraftDaemon.server_base_dir = String.valueOf(MinecraftDaemon.daemon_base_dir) + "servers" + File.separator;
- MinecraftDaemon.default_jars_dir = String.valueOf(MinecraftDaemon.daemon_base_dir) + "jars" + File.separator;
- MinecraftDaemon.process_hook_stream_dir = String.valueOf(MinecraftDaemon.daemon_base_dir) + "stream" + File.separator;
- MinecraftDaemon.update_dir = String.valueOf(MinecraftDaemon.daemon_base_dir) + "update" + File.separator;
- MinecraftDaemon.migration_output_dir = String.valueOf(MinecraftDaemon.daemon_base_dir) + "migration_out" + File.separator;
- MinecraftDaemon.migration_input_dir = String.valueOf(MinecraftDaemon.daemon_base_dir) + "migration_in" + File.separator;
- this.refreshHookperms();
- }
- public void refreshHookperms() {
- try {
- processWatcher.runAndPrint("chmod", "-R", "777", MinecraftDaemon.process_hook_stream_dir);
- processWatcher.runAndPrint("chmod", "755", String.valueOf(MinecraftDaemon.daemon_base_dir) + "ProcessHooker.jar");
- }
- catch (Exception e) {
- e.printStackTrace();
- }
- }
- public void clearCache() {
- try {
- this.log(LogLevel.DAEMON_INFO, "Limpando CACHE!");
- processWatcher.runAndPrint("echo", "3", ">", "/proc/sys/vm/drop_caches");
- processWatcher.runAndPrint("sysctl", "-w", "vm.drop_caches=3");
- }
- catch (Exception e) {
- e.printStackTrace();
- }
- }
- private void loadServers() {
- final String[] servers = this.adapter.loadServers();
- String[] array;
- for (int length = (array = servers).length, i = 0; i < length; ++i) {
- final String id = array[i];
- MinecraftJavaServer server;
- if ((server = this.getServer(id)) == null) {
- this.addServer(server = new MinecraftJavaServer(id, this));
- }
- else {
- server.validate();
- }
- }
- for (final MinecraftJavaServer server2 : new HashSet<MinecraftJavaServer>(this.servers)) {
- boolean remove = true;
- String[] array2;
- for (int length2 = (array2 = servers).length, j = 0; j < length2; ++j) {
- final String id2 = array2[j];
- if (id2.equalsIgnoreCase(server2.getId())) {
- remove = false;
- break;
- }
- }
- if (remove) {
- server2.kill();
- this.servers.remove(server2);
- }
- }
- File[] listFiles;
- for (int length3 = (listFiles = new File(MinecraftDaemon.process_hook_stream_dir).listFiles()).length, k = 0; k < length3; ++k) {
- final File f = listFiles[k];
- if (f.getName().endsWith("in")) {
- final String[] a = f.getName().split(".");
- if (a.length != 0) {
- final String sid = a[0];
- boolean remove2 = true;
- String[] array3;
- for (int length4 = (array3 = servers).length, l = 0; l < length4; ++l) {
- final String id3 = array3[l];
- if (id3.equalsIgnoreCase(sid)) {
- remove2 = false;
- break;
- }
- }
- if (remove2) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- final TailOutputStream out = new TailOutputStream(ProcessHooker.eof, new FileOutputStream(f));
- out.close();
- }
- catch (IOException ex) {}
- }
- }).start();
- }
- }
- }
- }
- File[] listFiles2;
- for (int length5 = (listFiles2 = new File(MinecraftDaemon.server_base_dir).listFiles()).length, n = 0; n < length5; ++n) {
- final File f = listFiles2[n];
- if (f.isDirectory() && f.exists()) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- final ServerConfiguration config = MinecraftDaemon.this.adapter.loadServerConfig(f.getName());
- if (config != null && !config.getDaemon().equalsIgnoreCase(MinecraftDaemon.this.getUUID())) {
- MinecraftDaemon.this.moveToTrash("Server " + config.getId(), f);
- MinecraftDaemon.this.mysqlLogger.logAsync("Arquivos do servidor ID=" + config.getId() + " enviados para a lixeira. Motivo: este servidor n\u00e3o pertence mais a este daemon.");
- }
- }
- }).start();
- }
- }
- }
- public MinecraftJavaServer getServer(final String serverID) {
- for (final MinecraftJavaServer server : this.servers) {
- if (server.getId().equalsIgnoreCase(serverID)) {
- return server;
- }
- }
- return null;
- }
- public void addServer(final MinecraftJavaServer server) {
- this.servers.add(server);
- }
- public void startAll() {
- for (final MinecraftJavaServer server : this.servers) {
- try {
- if (server.isRunning() || server.getShutdownRequested() != 0) {
- continue;
- }
- server.loadConfig();
- if (!server.getConfig().isAutoStart()) {
- continue;
- }
- this.startServer(server);
- }
- catch (Exception e) {
- this.log(LogLevel.DAEMON_ERROR, "ERROR WHILE AUTO-STARTING SERVER ID=" + server.getId());
- }
- }
- }
- public void startServer(final MinecraftJavaServer server) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- server.startServer();
- }
- }).start();
- }
- public boolean moveToTrash(final String prefix, final File file) {
- final File trashf = new File(String.valueOf(MinecraftDaemon.daemon_base_dir) + "trash" + File.separator);
- if (!trashf.exists()) {
- trashf.mkdirs();
- }
- return file.renameTo(new File(trashf, String.valueOf(getDateFileNameWithPrefix(prefix)) + "_" + file.getName()));
- }
- public static String getDateFileNameWithPrefix(final String prefix) {
- final GregorianCalendar c = new GregorianCalendar();
- return String.valueOf(prefix) + "_" + c.get(1) + "_" + (c.get(2) + 1) + "_" + c.get(5) + "_" + c.get(11) + "_" + c.get(12) + "_" + c.get(13);
- }
- @Override
- public boolean onConsoleInput(final String line) {
- final String[] spl = line.split(" ");
- return this.commandManager.handleCommand(spl[0], Arrays.copyOfRange(spl, 1, spl.length));
- }
- @Override
- public void handleCommand(final String line) {
- this.onConsoleInput(line);
- }
- @Override
- public void start() {
- }
- @Override
- public String getUUID() {
- return this.adapter.getDaemonUUID();
- }
- @Override
- public int getReservedRam() {
- return this.daemonConfig.getMemory();
- }
- @Override
- public int getAllocatedRam() {
- int r = 0;
- for (final MinecraftJavaServer s : this.servers) {
- r += s.getAllocatedRam();
- }
- return r;
- }
- @Override
- public int getPlayerCount() {
- int r = 0;
- for (final MinecraftJavaServer s : this.servers) {
- if (s.isOnline()) {
- r += s.getPlayerCount();
- }
- }
- return r;
- }
- @Override
- public int getServerCount() {
- return this.servers.size();
- }
- @Override
- public int getRunningServerCount() {
- int r = 0;
- for (final MinecraftJavaServer server : this.servers) {
- if (server.isRunning()) {
- ++r;
- }
- }
- return r;
- }
- @Override
- public int getOnlineServerCount() {
- int r = 0;
- for (final MinecraftJavaServer s : this.servers) {
- if (s.isOnline()) {
- ++r;
- }
- }
- return r;
- }
- public static void installDocker(){
- Runtime runtime = Runtime.getRuntime();
- try{
- runtime.exec("yum -y install docker-io");
- }catch (Exception e){
- here.log(LogLevel.DAEMON_ERROR, "Docker cannot be instaled: " + e.getLocalizedMessage());
- }
- }
- public class SizeUpdate implements Runnable {
- @Override
- public void run() {
- while (isRunning()){
- log(LogLevel.DAEMON_INFO, "Starting memory update and zip/unzip check");
- for (File sv : new File("/home/daemon/servers").listFiles()){
- update(sv);
- }
- try{TimeUnit.MINUTES.sleep(5);}catch (Exception e){}
- }
- }
- public void update(File b){
- double size = ((FileUtils.sizeOfDirectory(b)/1024.0)/ 1024.0);
- try {
- int id = Integer.parseInt(b.getName());
- log(LogLevel.DAEMON_INFO, "Updating server " + id + " STORAGE_USAGE");
- getMysqlManager().executeUpdate("UPDATE servers SET STORAGE_USAGE = ? WHERE ID = ?", size, id);
- }
- catch (SQLException e) {
- log(LogLevel.DAEMON_ERROR, e.getMessage());
- }
- }
- public void zipRequests(){
- }
- class zipRequest{
- }
- }
- public SizeUpdate getSizeUpdater(){
- return new SizeUpdate();
- }
- @Override
- public int getOnlineTime() {
- return (int)((System.currentTimeMillis() - this.startup) / 1000L);
- }
- public SystemInfo getSystemInfo() {
- return this.processWatcher;
- }
- public static String getPrefix() {
- return MinecraftDaemon.prefix;
- }
- public boolean isRunning() {
- return this.running;
- }
- public boolean isShuttingDown() {
- return this.shuttingDown;
- }
- public boolean isOutputServersConsole() {
- return this.outputServersConsole;
- }
- public void setOutputServersConsole(final boolean outputServersConsole) {
- this.outputServersConsole = outputServersConsole;
- }
- @Override
- public ConsoleBuffer getConsoleBuffer() {
- return this.consoleBuffer;
- }
- public MysqlManager getMysqlManager() {
- return this.mysqlManager;
- }
- public MysqlLogger getMysqlLogger() {
- return this.mysqlLogger;
- }
- public DaemonFtpServer getFtpServer() {
- return this.ftpServer;
- }
- public DaemonConfiguration getDaemonConfig() {
- return this.daemonConfig;
- }
- public CommandManager getCommandManager() {
- return this.commandManager;
- }
- public DaemonAdapter getAdapter() {
- return this.adapter;
- }
- public ConsoleSocket getConsoleSocket() {
- return this.consoleSocket;
- }
- public DaemonSocket getDaemonSocket() {
- return this.daemonSocket;
- }
- public ProcessWatcher getProcessWatcher() {
- return this.processWatcher;
- }
- public TaskManager getTaskManager() {
- return this.taskManager;
- }
- public MigrationManager getMigrationManager() {
- return this.migrationManager;
- }
- public long getStartup() {
- return this.startup;
- }
- public long getLastShutdownRequest() {
- return this.lastShutdownRequest;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement