فهرست منبع

Improved 'client_hash_check' config. (Hercules e4a1ca2)
- Added option to disable hash check by GM group_id (specify 'disabled' as hash for a certain group_id to let them log in with any client, even if 'client_hash_check' is enabled.
- Updated and reworded related documentation for the feature.

Improvements on script command 'axtoi'; added 'strtol'. (Hercules 1cf7c1e)
- Added script command 'strtol' (conforming to the ISO C90 function).
- Modified script command 'axtoi' to internally use 'strtol' instead of an unnecessary separate implementation.

Cleaned up many sections of script documentation, and modernized syntax in examples.
Added documentation for 'rentitem2' and 'makeitem2'. (follow-up 339c0a8)

Added 'true' (1) and 'false' (2) as script constants.

'freeloop' argument is now optional, and will only return the value of freeloop if no argument is given. (tid:92470)
http://rathena.org/board/topic/92470-freeloop-optional-argument/

Added a missing mapflag to custom 'devil_square' script. (bugreport:8611)
http://rathena.org/board/tracker/issue-8611-devil-square-bug/

Signed-off-by: Euphy <euphy.raliel@rathena.org>

Euphy 11 سال پیش
والد
کامیت
de46393592
8فایلهای تغییر یافته به همراه385 افزوده شده و 376 حذف شده
  1. 10 4
      conf/login_athena.conf
  2. 3 0
      db/const.txt
  3. 10 10
      doc/item_group.txt
  4. 27 11
      doc/md5_hashcheck.txt
  5. 263 284
      doc/script_commands.txt
  6. 1 0
      npc/custom/events/devil_square.txt
  7. 29 17
      src/login/login.c
  8. 42 50
      src/map/script.c

+ 10 - 4
conf/login_athena.conf

@@ -165,14 +165,20 @@ account.engine: auto
 // Client MD5 hash check
 // If turned on, the login server will check if the client's hash matches
 // the value below, and will not connect tampered clients.
-// Note: see doc\md5_hashcheck.txt for more details.
+// Note: see 'doc/md5_hashcheck.txt' for more details.
 client_hash_check: off
 
 // Client MD5 hashes
-// A player can login with a client hash at or below the account group_id.
+// The client with the specified hash can be used to log in by players with
+// a group_id equal to or greater than the given value.
+// If you specify 'disabled' as hash, players with a group_id greater than or
+// equal to the given value will be able to log in regardless of hash (and even
+// if their client does not send a hash at all.)
 // Format: group_id, hash
-client_hash: 0, 113e195e6c051bb1cfb12a644bb084c5
-client_hash: 99, cb1ea78023d337c38e8ba5124e2338ae
+// Note: see 'doc/md5_hashcheck.txt' for more details.
+//client_hash: 0, 113e195e6c051bb1cfb12a644bb084c5
+//client_hash: 10, cb1ea78023d337c38e8ba5124e2338ae
+//client_hash: 99, disabled
 
 import: conf/inter_athena.conf
 import: conf/import/login_conf.txt

+ 3 - 0
db/const.txt

@@ -4559,3 +4559,6 @@ VAR_MAX_GUILD_STORAGE	8
 VAR_MAX_BG_MEMBERS	9
 VAR_VIP_SCRIPT	10
 VAR_MIN_STORAGE	11
+
+false	0
+true	1

+ 10 - 10
doc/item_group.txt

@@ -13,25 +13,25 @@ and 'getgroupitem' script commands. The table below explains which fields are
 accessed in each.
 
 +===============+====================+================+
-| Field			| 'getrandgroupitem' | 'getgroupitem' |
+| Field         | 'getrandgroupitem' | 'getgroupitem' |
 +===============+====================+================+
-| GroupID		|		YES			 |		YES		  |
+| GroupID       |       YES          |      YES       |
 +===============+====================+================+
-| ItemID		|		YES			 |		YES		  |
+| ItemID        |       YES          |      YES       |
 +===============+====================+================+
-| Rate			|		YES			 |		YES		  |
+| Rate          |       YES          |      YES       |
 +===============+====================+================+
-| Amount		|		no			 |		YES		  |
+| Amount        |       no           |      YES       |
 +===============+====================+================+
-| Random		|		no			 |		YES		  |
+| Random        |       no           |      YES       |
 +===============+====================+================+
-| isAnnounced	|		no			 |		YES		  |
+| isAnnounced   |       no           |      YES       |
 +===============+====================+================+
-| Duration		|		no			 |		YES		  |
+| Duration      |       no           |      YES       |
 +===============+====================+================+
-| isNamed		|		no			 |		YES		  |
+| isNamed       |       no           |      YES       |
 +===============+====================+================+
-| isBound		|		no			 |		YES		  |
+| isBound       |       no           |      YES       |
 +===============+====================+================+
 
 ---------------------------------------

+ 27 - 11
doc/md5_hashcheck.txt

@@ -3,7 +3,7 @@
 //===== By: ==================================================
 //= rAthena Dev Team
 //===== Last Updated: ========================================
-//= 20120921
+//= 20140208
 //===== Description: =========================================
 //= This file outlines the login server's MD5 hash check.
 //============================================================
@@ -14,25 +14,41 @@ the client is the one specific to your server.
 
 The client can only send the correct MD5 hash to the server on certain
 server types, so a client diff is required to ensure the hash is sent.
-A link containing the required WeeDiffGen plugin can be found at:
+Please refer to your client diff tool manual for the appropriate patch,
+called "Force Send Client Hash Packet" or a similar name. A link
+containing the WeeDiffGen plugin can be found at:
 http://rathena.org/board/topic/70841-r16771-client-md5-hash-check/
 
-The settings for the hash check are located in conf\login_athena.conf:
+The server-side settings for the hash check are located in
+'conf\login_athena.conf':
 
 // Client MD5 hash check
 // If turned on, the login server will check if the client's hash matches
 // the value below, and will not connect tampered clients.
-// Note: see doc\md5_hashcheck.txt for more details.
+// Note: see 'doc/md5_hashcheck.txt' for more details.
 client_hash_check: off
 
 // Client MD5 hashes
-// A player can login with a client hash at or below the account group_id.
+// The client with the specified hash can be used to log in by players with
+// a group_id equal to or greater than the given value.
+// If you specify 'disabled' as hash, players with a group_id greater than or
+// equal to the given value will be able to log in regardless of hash (and even
+// if their client does not send a hash at all.)
 // Format: group_id, hash
+// Note: see 'doc/md5_hashcheck.txt' for more details.
 client_hash: 0, 113e195e6c051bb1cfb12a644bb084c5
-client_hash: 99, cb1ea78023d337c38e8ba5124e2338ae
+client_hash: 10, cb1ea78023d337c38e8ba5124e2338ae
+client_hash: 99, disabled
 
-To enable MD5 hash checks, set 'client_hash_check' to 'on'.
-The 'client_hash' group_id can be any of the groups in conf\groups.conf,
-and is particularly useful if you wanted to allow GMs a different client
-than normal players; for example, a GM client could be hexed differently
-with dual-clienting enabled and chat flood disabled.
+To enable MD5 hash checks, set 'client_hash_check' to 'on' and add one
+'client_hash' entry for each client you want to use.
+The group_id can be any of the groups in 'conf/groups.conf', and it is
+useful in case if you want to allow GMs to use a different client
+than normal players; for example, a GM client could be hexed
+differently, perhaps with dual-clienting enabled and chat flood
+disabled.
+You will need to replace the example MD5 hashes with the actual hash of
+your client. You can use any MD5 hash tools to generate it, e.g.:
+- md5sum (command line) on linux
+- WinMD5 on Windows
+- md5 (command line) on Mac OS X

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 263 - 284
doc/script_commands.txt


+ 1 - 0
npc/custom/events/devil_square.txt

@@ -227,6 +227,7 @@ ordeal_1-1,246,245,7	script	Devil Square Guardian#2	406,{
 ordeal_1-1	mapflag	nowarp
 ordeal_1-1	mapflag	nowarpto
 ordeal_1-1	mapflag	noteleport
+ordeal_1-1	mapflag	monster_noteleport
 ordeal_1-1	mapflag	nosave	SavePoint
 ordeal_1-1	mapflag	nomemo
 ordeal_1-1	mapflag	nobranch

+ 29 - 17
src/login/login.c

@@ -1208,27 +1208,29 @@ int mmo_auth(struct login_session_data* sd, bool isServer) {
 	}
 
 	if( login_config.client_hash_check && !isServer ) {
-		struct client_hash_node *node = login_config.client_hash_nodes;
+		struct client_hash_node *node = NULL;
 		bool match = false;
 
-		if( !sd->has_client_hash ) {
-			ShowNotice("Client doesn't sent client hash (account: %s, pass: %s, ip: %s)\n", sd->userid, sd->passwd, acc.state, ip);
-			return 5;
-		}
-
-		while( node ) {
-			if( node->group_id <= acc.group_id && memcmp(node->hash, sd->client_hash, 16) == 0 ) {
+		for( node = login_config.client_hash_nodes; node; node = node->next ) {
+			if( acc.group_id < node->group_id )
+				continue;
+			if( *node->hash == '\0' // Allowed to login without hash
+			 || (sd->has_client_hash && memcmp(node->hash, sd->client_hash, 16) == 0 ) // Correct hash
+			) {
 				match = true;
 				break;
 			}
-
-			node = node->next;
 		}
 
 		if( !match ) {
 			char smd5[33];
 			int i;
 
+			if( !sd->has_client_hash ) {
+				ShowNotice("Client didn't send client hash (account: %s, pass: %s, ip: %s)\n", sd->userid, sd->passwd, acc.state, ip);
+				return 5;
+			}
+
 			for( i = 0; i < 16; i++ )
 				sprintf(&smd5[i * 2], "%02x", sd->client_hash[i]);
 
@@ -1832,20 +1834,30 @@ int login_config_read(const char* cfgName)
 		else if(!strcmpi(w1, "client_hash")) {
 			int group = 0;
 			char md5[33];
+
 			if (sscanf(w2, "%3d, %32s", &group, md5) == 2) {
 				struct client_hash_node *nnode;
 				int i;
 				CREATE(nnode, struct client_hash_node, 1);
-				for (i = 0; i < 32; i += 2) {
-					char buf[3];
-					unsigned int byte;
-					memcpy(buf, &md5[i], 2);
-					buf[2] = 0;
-					sscanf(buf, "%2x", &byte);
-					nnode->hash[i / 2] = (uint8)(byte & 0xFF);
+
+				if (strcmpi(md5, "disabled") == 0) {
+					nnode->hash[0] = '\0';
+				} else {
+					for (i = 0; i < 32; i += 2) {
+						char buf[3];
+						unsigned int byte;
+
+						memcpy(buf, &md5[i], 2);
+						buf[2] = 0;
+
+						sscanf(buf, "%2x", &byte);
+						nnode->hash[i / 2] = (uint8)(byte & 0xFF);
+					}
 				}
+
 				nnode->group_id = group;
 				nnode->next = login_config.client_hash_nodes;
+
 				login_config.client_hash_nodes = nnode;
 			}
 		} else if(strcmpi(w1, "chars_per_account") == 0) { //maxchars per account [Sirius]

+ 42 - 50
src/map/script.c

@@ -14579,6 +14579,16 @@ BUILDIN_FUNC(sscanf){
 	argc = script_lastdata(st)-3;
 
 	len = strlen(format);
+
+
+	if (len != 0 && strlen(str) == 0) {
+		// If the source string is empty but the format string is not, we return -1
+		// according to the C specs. (if the format string is also empty, we shall
+		// continue and return 0: 0 conversions took place out of the 0 attempted.)
+		script_pushint(st, -1);
+		return SCRIPT_CMD_SUCCESS;
+	}
+
 	CREATE(buf, char, len*2+1);
 
 	// Issue sscanf for each parameter
@@ -14649,10 +14659,7 @@ BUILDIN_FUNC(sscanf){
 		*(buf_p-len+1) = '*';
 	}
 
-	if( !strcmp(str, "") )
-		script_pushint(st, -1);
-	else
-		script_pushint(st, arg);
+	script_pushint(st, arg);
 	if(buf) aFree(buf);
 	if(ref_str) aFree(ref_str);
 
@@ -14923,6 +14930,29 @@ BUILDIN_FUNC(atoi)
 	return SCRIPT_CMD_SUCCESS;
 }
 
+BUILDIN_FUNC(axtoi)
+{
+	const char *hex = script_getstr(st,2);
+	long value = strtol(hex, NULL, 16);
+#if LONG_MAX > INT_MAX || LONG_MIN < INT_MIN
+	value = cap_value(value, INT_MIN, INT_MAX);
+#endif
+	script_pushint(st, (int)value);
+	return SCRIPT_CMD_SUCCESS;
+}
+
+BUILDIN_FUNC(strtol)
+{
+	const char *string = script_getstr(st, 2);
+	int base = script_getnum(st, 3);
+	long value = strtol(string, NULL, base);
+#if LONG_MAX > INT_MAX || LONG_MIN < INT_MIN
+	value = cap_value(value, INT_MIN, INT_MAX);
+#endif
+	script_pushint(st, (int)value);
+	return SCRIPT_CMD_SUCCESS;
+}
+
 // case-insensitive substring search [lordalfa]
 BUILDIN_FUNC(compare)
 {
@@ -15656,47 +15686,6 @@ BUILDIN_FUNC(searchitem)
 	return SCRIPT_CMD_SUCCESS;
 }
 
-int axtoi(const char *hexStg)
-{
-	int n = 0;         // position in string
-	int16 m = 0;         // position in digit[] to shift
-	int count;         // loop index
-	int intValue = 0;  // integer value of hex string
-	int digit[11];      // hold values to convert
-	while (n < 10) {
-		if (hexStg[n]=='\0')
-			break;
-		if (hexStg[n] > 0x29 && hexStg[n] < 0x40 ) //if 0 to 9
-			digit[n] = hexStg[n] & 0x0f;            //convert to int
-		else if (hexStg[n] >='a' && hexStg[n] <= 'f') //if a to f
-			digit[n] = (hexStg[n] & 0x0f) + 9;      //convert to int
-		else if (hexStg[n] >='A' && hexStg[n] <= 'F') //if A to F
-			digit[n] = (hexStg[n] & 0x0f) + 9;      //convert to int
-		else break;
-		n++;
-	}
-	count = n;
-	m = n - 1;
-	n = 0;
-	while(n < count) {
-		// digit[n] is value of hex digit at position n
-		// (m << 2) is the number of positions to shift
-		// OR the bits into return value
-		intValue = intValue | (digit[n] << (m << 2));
-		m--;   // adjust the position to set
-		n++;   // next digit to process
-	}
-	return (intValue);
-}
-
-// [Lance] Hex string to integer converter
-BUILDIN_FUNC(axtoi)
-{
-	const char *hex = script_getstr(st,2);
-	script_pushint(st,axtoi(hex));
-	return SCRIPT_CMD_SUCCESS;
-}
-
 // [zBuffer] List of player cont commands --->
 BUILDIN_FUNC(rid2name)
 {
@@ -17556,10 +17545,12 @@ BUILDIN_FUNC(get_githash) {
  **/
 BUILDIN_FUNC(freeloop) {
 
-	if( script_getnum(st,2) )
-		st->freeloop = 1;
-	else
-		st->freeloop = 0;
+	if( script_hasdata(st,2) ) {
+		if( script_getnum(st,2) )
+			st->freeloop = 1;
+		else
+			st->freeloop = 0;
+	}
 
 	script_pushint(st, st->freeloop);
 	return SCRIPT_CMD_SUCCESS;
@@ -18893,6 +18884,7 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(query_logsql,"s*"),
 	BUILDIN_DEF(escape_sql,"v"),
 	BUILDIN_DEF(atoi,"s"),
+	BUILDIN_DEF(strtol,"si"),
 	// [zBuffer] List of player cont commands --->
 	BUILDIN_DEF(rid2name,"i"),
 	BUILDIN_DEF(pcfollow,"ii"),
@@ -18992,7 +18984,7 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(is_function,"s"),
 	BUILDIN_DEF(get_revision,""),
 	BUILDIN_DEF(get_githash,""),
-	BUILDIN_DEF(freeloop,"i"),
+	BUILDIN_DEF(freeloop,"?"),
 	BUILDIN_DEF(getrandgroupitem,"ii?"),
 	BUILDIN_DEF(cleanmap,"s"),
 	BUILDIN_DEF2(cleanmap,"cleanarea","siiii"),

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است