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 ;
2020-01-22 00:35:33 +01:00
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
2020-01-22 00:35:33 +01:00
public final static int MAJOR = 2 ;
2020-01-19 23:56:14 +01:00
public final static int MINOR = 3 ;
public final static int BUILD = 0 ;
2020-01-22 00:35:33 +01:00
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 " ;
2018-07-06 15:30:00 +02:00
2018-07-08 23:32:00 +02:00
2020-01-23 20:55:53 +01:00
public final static String PREVIEW = " RC-2 " ;
2019-05-12 19:33:16 +02:00
2019-05-26 20:14:53 +02:00
public static final String version = " Arcturus Morningstar " + " " + MAJOR + " . " + MINOR + " . " + BUILD + " " + PREVIEW ;
private static final String logo =
2020-01-22 00:35:33 +01:00
" \ 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 ;
2020-01-23 20:55:53 +01:00
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 {
2020-01-23 20:55:53 +01:00
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 ( ) ;
2020-01-22 00:35:33 +01:00
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 ( ) ;
2020-01-14 20:45:11 +01:00
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 ( ) {
2020-01-22 00:35:33 +01:00
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 ;
2020-01-23 20:55:53 +01:00
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 )
2020-01-22 00:35:33 +01:00
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 ( ) ;
}
}