Pārlūkot izejas kodu

-Add cli.c wich harmonize command input argument for all servers.
--enable login and char server to have alternative config file like map-server does.
--clean some hardcoded name conf.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@17152 54d463be-8e91-2dee-dedb-b68131a5f0ec

glighta 12 gadi atpakaļ
vecāks
revīzija
704a4f8108

+ 5 - 3
athena-start

@@ -43,9 +43,11 @@ case $1 in
     'start')
         print_start
         check_files
-
-        exec ./${L_SRV}&
-	echo $! > .${L_SRV}.pid
+	if [ -e .${L_SRV}.pid ] && [ -z $(cat .${L_SRV}.pid)] && [$(ps ax | grep $(cat .${L_SRV}.pid)) eq =~ /${L_SRV}/  ]; then
+	else
+	    exec ./${L_SRV}&
+	    echo $! > .${L_SRV}.pid
+	fi
         exec ./${C_SRV}&
 	echo $! > .${C_SRV}.pid
         exec ./${M_SRV}&

+ 30 - 11
src/char/char.c

@@ -12,6 +12,7 @@
 #include "../common/strlib.h"
 #include "../common/timer.h"
 #include "../common/utils.h"
+#include "../common/cli.h"
 #include "int_guild.h"
 #include "int_homun.h"
 #include "int_mercenary.h"
@@ -29,11 +30,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-// private declarations
-#define CHAR_CONF_NAME	"conf/char_athena.conf"
-#define LAN_CONF_NAME	"conf/subnet_athena.conf"
-#define SQL_CONF_NAME	"conf/inter_athena.conf"
-
 char char_db[256] = "char";
 char scdata_db[256] = "sc_data";
 char cart_db[256] = "cart_inventory";
@@ -835,7 +831,7 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit
 		for( j = 0; j < MAX_SLOTS; ++j )
 			StringBuf_Printf(&buf, ", '%d'", items[i].card[j]);
 		StringBuf_AppendStr(&buf, ")");
-		
+
 		updateLastUid(items[i].unique_id); // Unique Non Stackable Item ID
 	}
 	dbUpdateUid(sql_handle); // Unique Non Stackable Item ID
@@ -4015,11 +4011,11 @@ int parse_char(int fd)
 				char esc_name[NAME_LENGTH*2+1];
 				safestrncpy(name, (char *)RFIFOP(fd,6), NAME_LENGTH);
 				RFIFOSKIP(fd,30);
-				
+
 				ARR_FIND( 0, MAX_CHARS, i, sd->found_char[i] == cid );
 				if( i == MAX_CHARS )
 					break;
-				
+
 				normalize_name(name,TRIM_CHARS);
 				Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
 				if( !check_char_name(name,esc_name) ) {
@@ -4027,7 +4023,7 @@ int parse_char(int fd)
 					safestrncpy(sd->new_name, name, NAME_LENGTH);
 				} else
 					i = 0;
-				
+
 				WFIFOHEAD(fd, 4);
 				WFIFOW(fd,0) = 0x28e;
 				WFIFOW(fd,2) = i;
@@ -4761,8 +4757,14 @@ int do_init(int argc, char **argv)
 	mapindex_init();
 	start_point.map = mapindex_name2id("new_zone01");
 
-	char_config_read((argc < 2) ? CHAR_CONF_NAME : argv[1]);
-	char_lan_config_read((argc > 3) ? argv[3] : LAN_CONF_NAME);
+	CHAR_CONF_NAME = "conf/char_athena.conf";
+	LAN_CONF_NAME =	"conf/subnet_athena.conf";
+	SQL_CONF_NAME =	"conf/inter_athena.conf";
+
+	cli_get_options(argc,argv);
+
+	char_config_read(CHAR_CONF_NAME);
+	char_lan_config_read(LAN_CONF_NAME);
 	sql_config_read(SQL_CONF_NAME);
 
 	if (strcmp(userid, "s1")==0 && strcmp(passwd, "p1")==0) {
@@ -4846,3 +4848,20 @@ int do_init(int argc, char **argv)
 
 	return 0;
 }
+/*======================================================
+ * Login-Server help option info
+ *------------------------------------------------------*/
+void display_helpscreen(bool do_exit)
+{
+	ShowInfo("Usage: %s [options]\n", SERVER_NAME);
+	ShowInfo("\n");
+	ShowInfo("Options:\n");
+	ShowInfo("  -?, -h [--help]\t\tDisplays this help screen.\n");
+	ShowInfo("  -v [--version]\t\tDisplays the server's version.\n");
+	ShowInfo("  --run-once\t\t\tCloses server after loading (testing).\n");
+	ShowInfo("  --char-config <file>\t\tAlternative char-server configuration.\n");
+	ShowInfo("  --lan-config <file>\t\tAlternative lag configuration.\n");
+	ShowInfo("  --inter-config <file>\t\tAlternative inter-server configuration.\n");
+	if( do_exit )
+		exit(EXIT_SUCCESS);
+}

+ 2 - 0
src/common/CMakeLists.txt

@@ -81,6 +81,7 @@ set( COMMON_BASE_HEADERS
 	"${COMMON_SOURCE_DIR}/mutex.h"
 	"${COMMON_SOURCE_DIR}/raconf.h"
 	"${COMMON_SOURCE_DIR}/mempool.h"
+	"${COMMON_SOURCE_DIR}/cli.h"
 	${LIBCONFIG_HEADERS} # needed by conf.h/showmsg.h
 	CACHE INTERNAL "common_base headers" )
 set( COMMON_BASE_SOURCES
@@ -104,6 +105,7 @@ set( COMMON_BASE_SOURCES
 	"${COMMON_SOURCE_DIR}/mutex.c"
 	"${COMMON_SOURCE_DIR}/mempool.c"
 	"${COMMON_SOURCE_DIR}/raconf.c"
+	"${COMMON_SOURCE_DIR}/cli.c"
 	${LIBCONFIG_SOURCES} # needed by conf.c/showmsg.c
 	CACHE INTERNAL "common_base sources" )
 set( COMMON_BASE_INCLUDE_DIRS

+ 3 - 2
src/common/Makefile.in

@@ -3,7 +3,8 @@ COMMON_OBJ = obj_all/core.o obj_all/socket.o obj_all/timer.o obj_all/db.o \
 	obj_all/nullpo.o obj_all/malloc.o obj_all/showmsg.o obj_all/strlib.o obj_all/utils.o \
 	obj_all/grfio.o obj_all/mapindex.o obj_all/ers.o obj_all/md5calc.o \
 	obj_all/minicore.o obj_all/minisocket.o obj_all/minimalloc.o obj_all/random.o obj_all/des.o \
-	obj_all/conf.o obj_all/thread.o obj_all/mutex.o obj_all/raconf.o obj_all/mempool.o
+	obj_all/conf.o obj_all/thread.o obj_all/mutex.o obj_all/raconf.o obj_all/mempool.o \
+	obj_all/cli.o
 
 COMMON_H = $(shell ls ../common/*.h)
 
@@ -70,7 +71,7 @@ obj_all/common.a: $(COMMON_OBJ)
 obj_sql/common_sql.a: $(COMMON_SQL_OBJ)
 	@echo "	AR	$@"
 	@@AR@ rcs obj_sql/common_sql.a $(COMMON_SQL_OBJ)
-                
+
 
 common: obj_all $(COMMON_OBJ) $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) obj_all/common.a
 

+ 136 - 0
src/common/cli.c

@@ -0,0 +1,136 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "cbasetypes.h"
+#include "showmsg.h"
+#include "core.h"
+#include "cli.h"
+
+char* MAP_CONF_NAME;
+char* INTER_CONF_NAME;
+char* LOG_CONF_NAME;
+char* BATTLE_CONF_FILENAME;
+char* ATCOMMAND_CONF_FILENAME;
+char* SCRIPT_CONF_NAME;
+char* GRF_PATH_FILENAME;
+//char
+char* CHAR_CONF_NAME;
+char* SQL_CONF_NAME;
+//login
+char* LOGIN_CONF_NAME;
+//common
+char* LAN_CONF_NAME; //char-login
+char* MSG_CONF_NAME; //all
+
+bool opt_has_next_value(const char* option, int i, int argc)
+{
+    if (i >= argc - 1) {
+	ShowWarning("Missing value for option '%s'.\n", option);
+	return false;
+    }
+
+    return true;
+}
+
+/*======================================================
+ * Servers Version Screen [MC Cameri]
+ *------------------------------------------------------*/
+void display_versionscreen(bool do_exit)
+{
+    ShowInfo(CL_WHITE"rAthena SVN version: %s" CL_RESET"\n", get_svn_revision());
+    ShowInfo(CL_GREEN"Website/Forum:"CL_RESET"\thttp://rathena.org/\n");
+    ShowInfo(CL_GREEN"IRC Channel:"CL_RESET"\tirc://irc.rathena.net/#rathena\n");
+    ShowInfo("Open "CL_WHITE"readme.txt"CL_RESET" for more information.\n");
+    if (do_exit)
+	exit(EXIT_SUCCESS);
+}
+
+int cli_get_options(int argc, char ** argv)
+{
+    int i = 0;
+    for (i = 1; i < argc; i++) {
+	const char* arg = argv[i];
+
+	if (arg[0] != '-' && (arg[0] != '/' || arg[1] == '-')) {// -, -- and /
+	    ShowError("Unknown option '%s'.\n", argv[i]);
+	    exit(EXIT_FAILURE);
+	} else if ((++arg)[0] == '-') {// long option
+	    arg++;
+
+	    if (strcmp(arg, "help") == 0) {
+		display_helpscreen(true);
+	    } else if (strcmp(arg, "version") == 0) {
+		display_versionscreen(true);
+	    } else if (strcmp(arg, "run-once") == 0) // close the map-server as soon as its done.. for testing [Celest]
+	    {
+		runflag = CORE_ST_STOP;
+	    } else if (SERVER_TYPE & (ATHENA_SERVER_LOGIN | ATHENA_SERVER_CHAR)) { //login or char
+		if (strcmp(arg, "lan-config") == 0) {
+		    if (opt_has_next_value(arg, i, argc))
+			LAN_CONF_NAME = argv[++i];
+		} else if (SERVER_TYPE == ATHENA_SERVER_LOGIN) { //login
+		    if (strcmp(arg, "login-config") == 0) {
+			if (opt_has_next_value(arg, i, argc))
+			    LOGIN_CONF_NAME = argv[++i];
+		    } else {
+			ShowError("Unknown option '%s'.\n", argv[i]);
+			exit(EXIT_FAILURE);
+		    }
+		} else if (SERVER_TYPE == ATHENA_SERVER_CHAR) { //char
+		    if (strcmp(arg, "char-config") == 0) {
+			if (opt_has_next_value(arg, i, argc))
+			    CHAR_CONF_NAME = argv[++i];
+		    } else if (strcmp(arg, "inter-config") == 0) {
+			if (opt_has_next_value(arg, i, argc))
+			    INTER_CONF_NAME = argv[++i];
+		    } else {
+			ShowError("Unknown option '%s'.\n", argv[i]);
+			exit(EXIT_FAILURE);
+		    }
+		}
+	    } else if (SERVER_TYPE == ATHENA_SERVER_MAP) { //map
+		if (strcmp(arg, "map-config") == 0) {
+		    if (opt_has_next_value(arg, i, argc))
+			MAP_CONF_NAME = argv[++i];
+		} else if (strcmp(arg, "battle-config") == 0) {
+		    if (opt_has_next_value(arg, i, argc))
+			BATTLE_CONF_FILENAME = argv[++i];
+		} else if (strcmp(arg, "atcommand-config") == 0) {
+		    if (opt_has_next_value(arg, i, argc))
+			ATCOMMAND_CONF_FILENAME = argv[++i];
+		} else if (strcmp(arg, "script-config") == 0) {
+		    if (opt_has_next_value(arg, i, argc))
+			SCRIPT_CONF_NAME = argv[++i];
+		} else if (strcmp(arg, "grf-path-file") == 0) {
+		    if (opt_has_next_value(arg, i, argc))
+			GRF_PATH_FILENAME = argv[++i];
+		} else if (strcmp(arg, "inter-config") == 0) {
+		    if (opt_has_next_value(arg, i, argc))
+			INTER_CONF_NAME = argv[++i];
+		} else if (strcmp(arg, "log-config") == 0) {
+		    if (opt_has_next_value(arg, i, argc))
+			LOG_CONF_NAME = argv[++i];
+		} else if (strcmp(arg, "msg-config") == 0) {
+		    if (opt_has_next_value(arg, i, argc))
+			MSG_CONF_NAME = argv[++i];
+		} else {
+		    ShowError("Unknown option '%s'.\n", argv[i]);
+		    exit(EXIT_FAILURE);
+		}
+	    }
+	} else switch (arg[0]) {// short option
+	    case '?':
+	    case 'h':
+		display_helpscreen(true);
+		break;
+	    case 'v':
+		display_versionscreen(true);
+		break;
+	    default:
+		ShowError("Unknown option '%s'.\n", argv[i]);
+		exit(EXIT_FAILURE);
+	    }
+    }
+    return 1;
+}

+ 40 - 0
src/common/cli.h

@@ -0,0 +1,40 @@
+/*
+ * File:   cli.h
+ * Author: lighta
+ *
+ * Created on February 21, 2013, 6:15 PM
+ */
+
+#ifndef CLI_H
+#define	CLI_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+//map
+ extern char* MAP_CONF_NAME;
+ extern char* INTER_CONF_NAME;
+ extern char* LOG_CONF_NAME;
+ extern char* BATTLE_CONF_FILENAME;
+ extern char* ATCOMMAND_CONF_FILENAME;
+ extern char* SCRIPT_CONF_NAME;
+ extern char* GRF_PATH_FILENAME;
+//char
+ extern char* CHAR_CONF_NAME;
+ extern char* SQL_CONF_NAME;
+//login
+ extern char* LOGIN_CONF_NAME;
+//common
+ extern char* LAN_CONF_NAME; //char-login
+ extern char* MSG_CONF_NAME; //all
+
+extern void display_helpscreen(bool exit);
+int cli_get_options(int argc, char ** argv);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* CLI_H */
+

+ 9 - 7
src/common/sql.c

@@ -15,6 +15,8 @@
 #include <string.h>// strlen/strnlen/memcpy/memset
 #include <stdlib.h>// strtoul
 
+#define SQL_CONF_NAME "conf/inter_athena.conf"
+
 void ra_mysql_error_handler(unsigned int ecode);
 
 int mysql_reconnect_type;
@@ -412,7 +414,7 @@ void Sql_ShowDebug_(Sql* self, const char* debug_file, const unsigned long debug
 
 
 /// Frees a Sql handle returned by Sql_Malloc.
-void Sql_Free(Sql* self) 
+void Sql_Free(Sql* self)
 {
 	if( self )
 	{
@@ -559,7 +561,7 @@ static void Sql_P_ShowDebugMysqlFieldInfo(const char* prefix, enum enum_field_ty
 	SHOW_DEBUG_OF(MYSQL_TYPE_NULL);
 #undef SHOW_DEBUG_TYPE_OF
 	}
-	ShowDebug("%stype=%s%s, length=%d%s\n", prefix, sign, type_string, length, length_postfix); 
+	ShowDebug("%stype=%s%s, length=%d%s\n", prefix, sign, type_string, length, length_postfix);
 }
 
 
@@ -980,7 +982,7 @@ void Sql_inter_server_read(const char* cfgName, bool first) {
 	int i;
 	char line[1024], w1[1024], w2[1024];
 	FILE* fp;
-	
+
 	fp = fopen(cfgName, "r");
 	if(fp == NULL) {
 		if( first ) {
@@ -990,12 +992,12 @@ void Sql_inter_server_read(const char* cfgName, bool first) {
 			ShowError("File not found: %s\n", cfgName);
 		return;
 	}
-	
+
 	while(fgets(line, sizeof(line), fp)) {
 		i = sscanf(line, "%[^:]: %[^\r\n]", w1, w2);
 		if(i != 2)
 			continue;
-		
+
 		if(!strcmpi(w1,"mysql_reconnect_type")) {
 			mysql_reconnect_type = atoi(w2);
 			switch( mysql_reconnect_type ) {
@@ -1015,10 +1017,10 @@ void Sql_inter_server_read(const char* cfgName, bool first) {
 			Sql_inter_server_read(w2,false);
 	}
 	fclose(fp);
-		
+
 	return;
 }
 
 void Sql_Init(void) {
-	Sql_inter_server_read("conf/inter_athena.conf",true);
+	Sql_inter_server_read(SQL_CONF_NAME,true);
 }

+ 33 - 10
src/login/login.c

@@ -10,6 +10,7 @@
 #include "../common/socket.h"
 #include "../common/strlib.h"
 #include "../common/timer.h"
+#include "../common/cli.h"
 #include "account.h"
 #include "ipban.h"
 #include "login.h"
@@ -184,7 +185,7 @@ static int online_data_cleanup(int tid, unsigned int tick, int id, intptr_t data
 {
 	online_db->foreach(online_db, online_data_cleanup_sub);
 	return 0;
-} 
+}
 
 
 //--------------------------------------------------------------------
@@ -282,7 +283,7 @@ bool check_password(const char* md5key, int passwdenc, const char* passwd, const
 	{
 		// password mode set to 1 -> md5(md5key, refpass) enable with <passwordencrypt></passwordencrypt>
 		// password mode set to 2 -> md5(refpass, md5key) enable with <passwordencrypt2></passwordencrypt2>
-		
+
 		return ((passwdenc&0x01) && check_encrypted(md5key, refpass, passwd)) ||
 		       ((passwdenc&0x02) && check_encrypted(refpass, md5key, passwd));
 	}
@@ -1022,7 +1023,7 @@ int mmo_auth(struct login_session_data* sd, bool isServer) {
 				return result;// Failed to make account. [Skotlex].
 		}
 	}
-	
+
 	if( !accounts->load_str(accounts, &acc, sd->userid) ) {
 		ShowNotice("Unknown account (account: %s, received pass: %s, ip: %s)\n", sd->userid, sd->passwd, ip);
 		return 0; // 0 = Unregistered ID
@@ -1049,7 +1050,7 @@ int mmo_auth(struct login_session_data* sd, bool isServer) {
 		ShowNotice("Connection refused (account: %s, pass: %s, state: %d, ip: %s)\n", sd->userid, sd->passwd, acc.state, ip);
 		return acc.state - 1;
 	}
-	
+
 	if( login_config.client_hash_check && !isServer ) {
 		struct client_hash_node *node = login_config.client_hash_nodes;
 		bool match = false;
@@ -1137,7 +1138,7 @@ void login_auth_ok(struct login_session_data* sd)
 		WFIFOW(fd,0) = 0x81;
 		WFIFOB(fd,2) = 1; // 01 = Server closed
 		WFIFOSET(fd,3);
-		return;		
+		return;
 	}
 
 	server_num = 0;
@@ -1758,7 +1759,7 @@ void do_final(void)
 	accounts = NULL; // destroyed in account_engines
 	online_db->destroy(online_db, NULL);
 	auth_db->destroy(auth_db, NULL);
-	
+
 	for( i = 0; i < ARRAYLENGTH(server); ++i )
 		chrif_server_destroy(i);
 
@@ -1815,11 +1816,17 @@ int do_init(int argc, char** argv)
 
 	// read login-server configuration
 	login_set_defaults();
-	login_config_read((argc > 1) ? argv[1] : LOGIN_CONF_NAME);
-	login_lan_config_read((argc > 2) ? argv[2] : LAN_CONF_NAME);
+
+	LOGIN_CONF_NAME = "conf/login_athena.conf";
+	LAN_CONF_NAME = "conf/subnet_athena.conf";
+
+	cli_get_options(argc,argv);
+
+	login_config_read(LOGIN_CONF_NAME);
+	login_lan_config_read(LAN_CONF_NAME);
 
 	rnd_init();
-	
+
 	for( i = 0; i < ARRAYLENGTH(server); ++i )
 		chrif_server_init(i);
 
@@ -1872,7 +1879,7 @@ int do_init(int argc, char** argv)
 		ShowFatalError("Failed to bind to port '"CL_WHITE"%d"CL_RESET"'\n",login_config.login_port);
 		exit(EXIT_FAILURE);
 	}
-	
+
 	if( runflag != CORE_ST_STOP ) {
 		shutdown_callback = do_shutdown;
 		runflag = LOGINSERVER_ST_RUNNING;
@@ -1883,3 +1890,19 @@ int do_init(int argc, char** argv)
 
 	return 0;
 }
+/*======================================================
+ * Login-Server help option info
+ *------------------------------------------------------*/
+void display_helpscreen(bool do_exit)
+{
+	ShowInfo("Usage: %s [options]\n", SERVER_NAME);
+	ShowInfo("\n");
+	ShowInfo("Options:\n");
+	ShowInfo("  -?, -h [--help]\t\tDisplays this help screen.\n");
+	ShowInfo("  -v [--version]\t\tDisplays the server's version.\n");
+	ShowInfo("  --run-once\t\t\tCloses server after loading (testing).\n");
+	ShowInfo("  --login-config <file>\t\tAlternative login-server configuration.\n");
+	ShowInfo("  --lan-config <file>\t\tAlternative lag configuration.\n");
+	if( do_exit )
+		exit(EXIT_SUCCESS);
+}

+ 0 - 3
src/login/login.h

@@ -14,9 +14,6 @@ enum E_LOGINSERVER_ST
 	LOGINSERVER_ST_LAST
 };
 
-#define LOGIN_CONF_NAME "conf/login_athena.conf"
-#define LAN_CONF_NAME "conf/subnet_athena.conf"
-
 // supported encryption types: 1- passwordencrypt, 2- passwordencrypt2, 3- both
 #define PASSWORDENC 3
 

+ 6 - 123
src/map/map.c

@@ -12,6 +12,7 @@
 #include "../common/random.h"
 #include "../common/strlib.h"
 #include "../common/utils.h"
+#include "../common/cli.h"
 
 #include "map.h"
 #include "path.h"
@@ -84,15 +85,6 @@ Sql* logmysql_handle;
 // messages like whispers to this nick. [LuzZza]
 char main_chat_nick[16] = "Main";
 
-char *INTER_CONF_NAME;
-char *LOG_CONF_NAME;
-char *MAP_CONF_NAME;
-char *BATTLE_CONF_FILENAME;
-char *ATCOMMAND_CONF_FILENAME;
-char *SCRIPT_CONF_NAME;
-char *MSG_CONF_NAME;
-char *GRF_PATH_FILENAME;
-
 // DBMap declaartion
 static DBMap* id_db=NULL; // int id -> struct block_list*
 static DBMap* pc_db=NULL; // int id -> struct map_session_data*
@@ -3629,7 +3621,7 @@ void do_final(void)
 	iwall_db->destroy(iwall_db, NULL);
 	regen_db->destroy(regen_db, NULL);
 
-    map_sql_close();
+	map_sql_close();
 
 	ShowStatus("Finished.\n");
 }
@@ -3666,9 +3658,9 @@ void do_abort(void)
 }
 
 /*======================================================
- * Map-Server Version Screen [MC Cameri]
+ * Map-Server help options screen
  *------------------------------------------------------*/
-static void map_helpscreen(bool do_exit)
+void display_helpscreen(bool do_exit)
 {
 	ShowInfo("Usage: %s [options]\n", SERVER_NAME);
 	ShowInfo("\n");
@@ -3688,19 +3680,6 @@ static void map_helpscreen(bool do_exit)
 		exit(EXIT_SUCCESS);
 }
 
-/*======================================================
- * Map-Server Version Screen [MC Cameri]
- *------------------------------------------------------*/
-static void map_versionscreen(bool do_exit)
-{
-	ShowInfo(CL_WHITE"rAthena SVN version: %s" CL_RESET"\n", get_svn_revision());
-	ShowInfo(CL_GREEN"Website/Forum:"CL_RESET"\thttp://rathena.org/\n");
-	ShowInfo(CL_GREEN"IRC Channel:"CL_RESET"\tirc://irc.rathena.net/#rathena\n");
-	ShowInfo("Open "CL_WHITE"readme.txt"CL_RESET" for more information.\n");
-	if( do_exit )
-		exit(EXIT_SUCCESS);
-}
-
 /*======================================================
  * Map-Server Init and Command-line Arguments [Valaris]
  *------------------------------------------------------*/
@@ -3729,17 +3708,6 @@ void do_shutdown(void)
 	}
 }
 
-static bool map_arg_next_value(const char* option, int i, int argc)
-{
-	if( i >= argc-1 )
-	{
-		ShowWarning("Missing value for option '%s'.\n", option);
-		return false;
-	}
-
-	return true;
-}
-
 int do_init(int argc, char *argv[])
 {
 	int i;
@@ -3757,94 +3725,9 @@ int do_init(int argc, char *argv[])
 	MSG_CONF_NAME = "conf/msg_athena.conf";
 	GRF_PATH_FILENAME = "conf/grf-files.txt";
 
-	rnd_init();
-
-	for( i = 1; i < argc ; i++ )
-	{
-		const char* arg = argv[i];
-
-		if( arg[0] != '-' && ( arg[0] != '/' || arg[1] == '-' ) )
-		{// -, -- and /
-			ShowError("Unknown option '%s'.\n", argv[i]);
-			exit(EXIT_FAILURE);
-		}
-		else if( (++arg)[0] == '-' )
-		{// long option
-			arg++;
-
-			if( strcmp(arg, "help") == 0 )
-			{
-				map_helpscreen(true);
-			}
-			else if( strcmp(arg, "version") == 0 )
-			{
-				map_versionscreen(true);
-			}
-			else if( strcmp(arg, "map-config") == 0 )
-			{
-				if( map_arg_next_value(arg, i, argc) )
-					MAP_CONF_NAME = argv[++i];
-			}
-			else if( strcmp(arg, "battle-config") == 0 )
-			{
-				if( map_arg_next_value(arg, i, argc) )
-					BATTLE_CONF_FILENAME = argv[++i];
-			}
-			else if( strcmp(arg, "atcommand-config") == 0 )
-			{
-				if( map_arg_next_value(arg, i, argc) )
-					ATCOMMAND_CONF_FILENAME = argv[++i];
-			}
-			else if( strcmp(arg, "script-config") == 0 )
-			{
-				if( map_arg_next_value(arg, i, argc) )
-					SCRIPT_CONF_NAME = argv[++i];
-			}
-			else if( strcmp(arg, "msg-config") == 0 )
-			{
-				if( map_arg_next_value(arg, i, argc) )
-					MSG_CONF_NAME = argv[++i];
-			}
-			else if( strcmp(arg, "grf-path-file") == 0 )
-			{
-				if( map_arg_next_value(arg, i, argc) )
-					GRF_PATH_FILENAME = argv[++i];
-			}
-			else if( strcmp(arg, "inter-config") == 0 )
-			{
-				if( map_arg_next_value(arg, i, argc) )
-					INTER_CONF_NAME = argv[++i];
-			}
-			else if( strcmp(arg, "log-config") == 0 )
-			{
-				if( map_arg_next_value(arg, i, argc) )
-					LOG_CONF_NAME = argv[++i];
-			}
-			else if( strcmp(arg, "run-once") == 0 ) // close the map-server as soon as its done.. for testing [Celest]
-			{
-				runflag = CORE_ST_STOP;
-			}
-			else
-			{
-				ShowError("Unknown option '%s'.\n", argv[i]);
-				exit(EXIT_FAILURE);
-			}
-		}
-		else switch( arg[0] )
-		{// short option
-			case '?':
-			case 'h':
-				map_helpscreen(true);
-				break;
-			case 'v':
-				map_versionscreen(true);
-				break;
-			default:
-				ShowError("Unknown option '%s'.\n", argv[i]);
-				exit(EXIT_FAILURE);
-		}
-	}
+	cli_get_options(argc,argv);
 
+	rnd_init();
 	map_config_read(MAP_CONF_NAME);
 	/* only temporary until sirius's datapack patch is complete  */
 

+ 2 - 0
vcproj-10/char-server_sql.vcxproj

@@ -156,6 +156,7 @@
     <ClInclude Include="..\src\common\thread.h" />
     <ClInclude Include="..\src\common\timer.h" />
     <ClInclude Include="..\src\common\utils.h" />
+    <ClInclude Include="..\src\common\cli.h" />
     <ClInclude Include="..\src\char\char.h" />
     <ClInclude Include="..\src\char\int_auction.h" />
     <ClInclude Include="..\src\char\int_elemental.h" />
@@ -194,6 +195,7 @@
     <ClCompile Include="..\src\common\thread.c" />
     <ClCompile Include="..\src\common\timer.c" />
     <ClCompile Include="..\src\common\utils.c" />
+    <ClCompile Include="..\src\common\cli.c" />
     <ClCompile Include="..\src\char\char.c" />
     <ClCompile Include="..\src\char\int_auction.c" />
     <ClCompile Include="..\src\char\int_elemental.c" />

+ 2 - 0
vcproj-10/login-server_sql.vcxproj

@@ -162,6 +162,7 @@
     <ClInclude Include="..\src\common\strlib.h" />
     <ClInclude Include="..\src\common\timer.h" />
     <ClInclude Include="..\src\common\utils.h" />
+    <ClInclude Include="..\src\common\cli.h" />
     <ClInclude Include="..\3rdparty\mt19937ar\mt19937ar.h" />
   </ItemGroup>
   <ItemGroup>
@@ -191,6 +192,7 @@
     <ClCompile Include="..\src\common\strlib.c" />
     <ClCompile Include="..\src\common\timer.c" />
     <ClCompile Include="..\src\common\utils.c" />
+    <ClCompile Include="..\src\common\cli.c" />
     <ClCompile Include="..\3rdparty\mt19937ar\mt19937ar.c" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

+ 2 - 0
vcproj-10/map-server_sql.vcxproj

@@ -158,6 +158,7 @@
     <ClInclude Include="..\src\common\timer.h" />
     <ClInclude Include="..\src\common\utils.h" />
     <ClInclude Include="..\src\common\winapi.h" />
+    <ClInclude Include="..\src\common\cli.h" />
     <ClInclude Include="..\src\map\atcommand.h" />
     <ClInclude Include="..\src\map\battle.h" />
     <ClInclude Include="..\src\map\battleground.h" />
@@ -228,6 +229,7 @@
     <ClCompile Include="..\src\common\thread.c" />
     <ClCompile Include="..\src\common\timer.c" />
     <ClCompile Include="..\src\common\utils.c" />
+    <ClCompile Include="..\src\common\cli.c" />
     <ClCompile Include="..\src\map\atcommand.c" />
     <ClCompile Include="..\src\map\battle.c" />
     <ClCompile Include="..\src\map\battleground.c" />

+ 2 - 0
vcproj-12/char-server_sql.vcxproj

@@ -159,6 +159,7 @@
     <ClInclude Include="..\src\common\thread.h" />
     <ClInclude Include="..\src\common\timer.h" />
     <ClInclude Include="..\src\common\utils.h" />
+    <ClInclude Include="..\src\common\cli.h" />
     <ClInclude Include="..\src\char\char.h" />
     <ClInclude Include="..\src\char\int_auction.h" />
     <ClInclude Include="..\src\char\int_elemental.h" />
@@ -197,6 +198,7 @@
     <ClCompile Include="..\src\common\thread.c" />
     <ClCompile Include="..\src\common\timer.c" />
     <ClCompile Include="..\src\common\utils.c" />
+    <ClCompile Include="..\src\common\cli.c" />
     <ClCompile Include="..\src\char\char.c" />
     <ClCompile Include="..\src\char\int_auction.c" />
     <ClCompile Include="..\src\char\int_elemental.c" />

+ 2 - 0
vcproj-12/login-server_sql.vcxproj

@@ -166,6 +166,7 @@
     <ClInclude Include="..\src\common\strlib.h" />
     <ClInclude Include="..\src\common\timer.h" />
     <ClInclude Include="..\src\common\utils.h" />
+    <ClInclude Include="..\src\common\cli.h" />
     <ClInclude Include="..\3rdparty\mt19937ar\mt19937ar.h" />
   </ItemGroup>
   <ItemGroup>
@@ -195,6 +196,7 @@
     <ClCompile Include="..\src\common\strlib.c" />
     <ClCompile Include="..\src\common\timer.c" />
     <ClCompile Include="..\src\common\utils.c" />
+    <ClCompile Include="..\src\common\cli.c" />
     <ClCompile Include="..\3rdparty\mt19937ar\mt19937ar.c" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

+ 2 - 0
vcproj-12/map-server_sql.vcxproj

@@ -162,6 +162,7 @@
     <ClInclude Include="..\src\common\timer.h" />
     <ClInclude Include="..\src\common\utils.h" />
     <ClInclude Include="..\src\common\winapi.h" />
+    <ClInclude Include="..\src\common\cli.h" />
     <ClInclude Include="..\src\map\atcommand.h" />
     <ClInclude Include="..\src\map\battle.h" />
     <ClInclude Include="..\src\map\battleground.h" />
@@ -232,6 +233,7 @@
     <ClCompile Include="..\src\common\thread.c" />
     <ClCompile Include="..\src\common\timer.c" />
     <ClCompile Include="..\src\common\utils.c" />
+    <ClCompile Include="..\src\common\cli.c" />
     <ClCompile Include="..\src\map\atcommand.c" />
     <ClCompile Include="..\src\map\battle.c" />
     <ClCompile Include="..\src\map\battleground.c" />

+ 8 - 0
vcproj-9/char-server_sql.vcproj

@@ -428,6 +428,14 @@
 				RelativePath="..\src\common\winapi.h"
 				>
 			</File>
+			<File
+				RelativePath="..\src\common\cli.h"
+				>
+			</File>	
+			<File
+				RelativePath="..\src\common\cli.c"
+				>
+			</File>						
 		</Filter>
 		<Filter
 			Name="char_sql"

+ 8 - 0
vcproj-9/login-server_sql.vcproj

@@ -398,6 +398,14 @@
 				RelativePath="..\src\common\winapi.h"
 				>
 			</File>
+			<File
+				RelativePath="..\src\common\cli.h"
+				>
+			</File>	
+			<File
+				RelativePath="..\src\common\cli.c"
+				>
+			</File>						
 		</Filter>
 		<Filter
 			Name="3rdparty"

+ 8 - 0
vcproj-9/map-server_sql.vcproj

@@ -451,6 +451,14 @@
 				RelativePath="..\src\common\winapi.h"
 				>
 			</File>
+			<File
+				RelativePath="..\src\common\cli.h"
+				>
+			</File>	
+			<File
+				RelativePath="..\src\common\cli.c"
+				>
+			</File>						
 		</Filter>
 		<Filter
 			Name="map_sql"