Explorar o código

* Fixed TXT charserver doing periodic random-sized memory allocation (bugreport:312)
* Set 'Create Converter's produce success rate to 100% (bugreport:302)
* Added check that verifies weapon/ammo/state requirements also when casting finishes (might have unwanted side-effects tho'!) (bugreport:228)
* Fixed Firewall knocking back undead/fire element mobs (bug in r11578)
* Added dummy 'openmail' to txt server to fix a script error message

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

ultramage %!s(int64=17) %!d(string=hai) anos
pai
achega
2cb8a5838e
Modificáronse 6 ficheiros con 90 adicións e 108 borrados
  1. 6 0
      Changelog-Trunk.txt
  2. 32 31
      src/char/char.c
  3. 18 16
      src/char_sql/char.c
  4. 2 7
      src/map/script.c
  5. 31 53
      src/map/skill.c
  6. 1 1
      src/map/unit.c

+ 6 - 0
Changelog-Trunk.txt

@@ -4,6 +4,12 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 2007/10/27
+	* Fixed TXT charserver doing periodic random-sized alloc (bugreport:312)
+	* Set 'Create Converter's produce success rate to 100% (bugreport:302)
+	* Added check that verifies weapon/ammo/state requirements also when
+	  casting finishes (might have unwanted side-effects!) (bugreport:228)
+	* Fixed Firewall knocking back undead/fire element mobs (bug in r11578)
+	* Added dummy 'openmail' to txt server to fix a script error message
 	* Improvements/fixes to the mail system improvements :) [ultramage]
 	* Improvements to the mail system. Need Testing, [Zephyrus]
 2007/10/26

+ 32 - 31
src/char/char.c

@@ -1967,7 +1967,7 @@ int parse_fromlogin(int fd)
 
 	// only login-server can have an access to here.
 	// so, if it isn't the login-server, we disconnect the session.
-	if (fd != login_fd)
+	if( fd != login_fd )
 		set_eof(fd);
 	if(session[fd]->eof) {
 		if (fd == login_fd) {
@@ -1980,20 +1980,24 @@ int parse_fromlogin(int fd)
 
 	sd = (struct char_session_data*)session[fd]->session_data;
 
-	while(RFIFOREST(fd) >= 2) {
-//		printf("parse_fromlogin: connection #%d, packet: 0x%x (with being read: %d bytes).\n", fd, RFIFOW(fd,0), RFIFOREST(fd));
+	while(RFIFOREST(fd) >= 2)
+	{
+		uint16 command = RFIFOW(fd,0);
 
-		switch(RFIFOW(fd,0)) {
+		switch( command )
+		{
+
+		// acknowledgement of connect-to-loginserver request
 		case 0x2711:
 			if (RFIFOREST(fd) < 3)
 				return 0;
+
 			if (RFIFOB(fd,2)) {
 				//printf("connect login server error : %d\n", RFIFOB(fd,2));
-				ShowError("Can not connect to the login-server.\n");
+				ShowError("Can not connect to login-server.\n");
 				ShowError("The server communication passwords (default s1/p1) are probably invalid.\n");
 				ShowInfo("Also, please make sure your accounts file (default: accounts.txt) has those values present.\n");
 				ShowInfo("The communication passwords can be changed in map_athena.conf and char_athena.conf\n");
-				//exit(EXIT_FAILURE); //fixed for server shutdown.
 			} else {
 				ShowStatus("Connected to login-server (connection #%d).\n", fd);
 				
@@ -2001,33 +2005,29 @@ int parse_fromlogin(int fd)
 				send_accounts_tologin(-1, gettick(), 0, 0);
 
 				// if no map-server already connected, display a message...
-				for(i = 0; i < MAX_MAP_SERVERS; i++)
-					if (server_fd[i] > 0 && server[i].map[0]) // if map-server online and at least 1 map
-						break;
-				if (i == MAX_MAP_SERVERS)
+				ARR_FIND( 0, MAX_MAP_SERVERS, i, server_fd[i] > 0 && server[i].map[0] );
+				if( i == MAX_MAP_SERVERS )
 					ShowStatus("Awaiting maps from map-server.\n");
 			}
 			RFIFOSKIP(fd,3);
 		break;
 
+		// acknowledgement of account authentication request
 		case 0x2713:
 			if (RFIFOREST(fd) < 51)
 				return 0;
 
-			for(i = 0; i < fd_max && !(
-				session[i] &&
-				(sd = (struct char_session_data*)session[i]->session_data) &&
-				sd->account_id == RFIFOL(fd,2))
-				; i++);
-
-			if (i < fd_max) {
-				if (RFIFOB(fd,6) != 0) {
+			// find the session with this account id
+			ARR_FIND( 0, fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->account_id == RFIFOL(fd,2) );
+			if( i < fd_max )
+			{
+				if( RFIFOB(fd,6) != 0 ) { // failure
 					WFIFOHEAD(i,3);
 					WFIFOW(i,0) = 0x6c;
 					WFIFOB(i,2) = 0x42;
 					WFIFOSET(i,3);
-				} else {
-					memcpy(sd->email, RFIFOP(fd, 7), 40);
+				} else { // success
+					memcpy(sd->email, RFIFOP(fd,7), 40);
 					if (e_mail_check(sd->email) == 0)
 						strncpy(sd->email, "a@a.com", 40); // default e-mail
 					sd->connect_until_time = (time_t)RFIFOL(fd,47);
@@ -3905,15 +3905,14 @@ int send_users_tologin(int tid, unsigned int tick, int id, int data)
 	return 0;
 }
 
+/// load this char's account id into the 'online accounts' packet
 static int send_accounts_tologin_sub(DBKey key, void* data, va_list ap)
 {
 	struct online_char_data* character = (struct online_char_data*)data;
-	int *i = va_arg(ap, int*);
-	int count = va_arg(ap, int);
-	if ((*i) >= count)
-		return 0; //This is an error that shouldn't happen....
-	if(character->server > -1) {
-		WFIFOHEAD(login_fd,8+count*4);
+	int* i = va_arg(ap, int*);
+
+	if(character->server > -1)
+	{
 		WFIFOL(login_fd,8+(*i)*4) = character->account_id;
 		(*i)++;
 		return 1;
@@ -3923,15 +3922,17 @@ static int send_accounts_tologin_sub(DBKey key, void* data, va_list ap)
 
 int send_accounts_tologin(int tid, unsigned int tick, int id, int data)
 {
-	int users = count_users(), i=0;
-
-	if (login_fd > 0 && session[login_fd]) {
+	if (login_fd > 0 && session[login_fd])
+	{
 		// send account list to login server
+		int users = online_char_db->size(online_char_db);
+		int i = 0;
+
 		WFIFOHEAD(login_fd,8+users*4);
 		WFIFOW(login_fd,0) = 0x272d;
-		WFIFOL(login_fd,4) = users;
-		online_char_db->foreach(online_char_db, send_accounts_tologin_sub, &i);
+		online_char_db->foreach(online_char_db, send_accounts_tologin_sub, &i, users);
 		WFIFOW(login_fd,2) = 8+ i*4;
+		WFIFOL(login_fd,4) = i;
 		WFIFOSET(login_fd,WFIFOW(login_fd,2));
 	}
 	return 0;

+ 18 - 16
src/char_sql/char.c

@@ -189,15 +189,15 @@ struct online_char_data {
 	int char_id;
 	int fd;
 	int waiting_disconnect;
-	short server;
+	short server; // -2: unknown server, -1: not connected, 0+: id of server
 };
 
-struct dbt *online_char_db; //Holds all online characters.
+struct dbt* online_char_db; //Holds all online characters.
 
-static void * create_online_char_data(DBKey key, va_list args)
+static void* create_online_char_data(DBKey key, va_list args)
 {
 	struct online_char_data* character;
-	character = aCalloc(1, sizeof(struct online_char_data));
+	CREATE(character, struct online_char_data, 1);
 	character->account_id = key.i;
 	character->char_id = -1;
   	character->server = -1;
@@ -1509,9 +1509,10 @@ int parse_fromlogin(int fd)
 {
 	int i;
 	struct char_session_data *sd;
+
 	// only login-server can have an access to here.
 	// so, if it isn't the login-server, we disconnect the session.
-	if(fd != login_fd)
+	if( fd != login_fd )
 		set_eof(fd);
 	if(session[fd]->eof) {
 		if (fd == login_fd) {
@@ -1571,7 +1572,7 @@ int parse_fromlogin(int fd)
 					WFIFOB(i,2) = 0x42;
 					WFIFOSET(i,3);
 				} else { // success
-					memcpy(sd->email, RFIFOP(fd, 7), 40);
+					memcpy(sd->email, RFIFOP(fd,7), 40);
 					sd->connect_until_time = (time_t)RFIFOL(fd,47);
 					char_auth_ok(i, sd);
 				}
@@ -3237,15 +3238,14 @@ int send_users_tologin(int tid, unsigned int tick, int id, int data)
 	return 0;
 }
 
+/// load this char's account id into the 'online accounts' packet
 static int send_accounts_tologin_sub(DBKey key, void* data, va_list ap)
 {
 	struct online_char_data* character = (struct online_char_data*)data;
-	int *i = va_arg(ap, int*);
-	int count = va_arg(ap, int);
-	if ((*i) >= count)
-		return 0; //This is an error that shouldn't happen....
-	if(character->server > -1) {
-		WFIFOHEAD(login_fd,8+count*4);
+	int* i = va_arg(ap, int*);
+
+	if(character->server > -1)
+	{
 		WFIFOL(login_fd,8+(*i)*4) = character->account_id;
 		(*i)++;
 		return 1;
@@ -3255,15 +3255,17 @@ static int send_accounts_tologin_sub(DBKey key, void* data, va_list ap)
 
 int send_accounts_tologin(int tid, unsigned int tick, int id, int data)
 {
-	int users = count_users(), i=0;
-
-	if (login_fd > 0 && session[login_fd]) {
+	if (login_fd > 0 && session[login_fd])
+	{
 		// send account list to login server
+		int users = online_char_db->size(online_char_db);
+		int i = 0;
+
 		WFIFOHEAD(login_fd,8+users*4);
 		WFIFOW(login_fd,0) = 0x272d;
-		WFIFOL(login_fd,4) = users;
 		online_char_db->foreach(online_char_db, send_accounts_tologin_sub, &i, users);
 		WFIFOW(login_fd,2) = 8+ i*4;
+		WFIFOL(login_fd,4) = i;
 		WFIFOSET(login_fd,WFIFOW(login_fd,2));
 	}
 	return 0;

+ 2 - 7
src/map/script.c

@@ -4052,10 +4052,7 @@ BUILDIN_FUNC(undisguise);
 BUILDIN_FUNC(getmonsterinfo); // [Lupus]
 BUILDIN_FUNC(checkvending); // check vending [Nab4]
 BUILDIN_FUNC(checkchatting); // check chatting [Marka]
-
-#ifndef TXT_ONLY
 BUILDIN_FUNC(openmail); // [Mail System]
-#endif
 
 #ifdef PCRE_SUPPORT
 BUILDIN_FUNC(defpattern); // MouseJstr
@@ -4395,9 +4392,7 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(roclass,"i*"),	//[Skotlex]
 	BUILDIN_DEF(checkvending,"*"),
 	BUILDIN_DEF(checkchatting,"*"),
-#ifndef TXT_ONLY
 	BUILDIN_DEF(openmail,""),
-#endif
 	{NULL,NULL,NULL},
 };
 
@@ -13455,10 +13450,10 @@ BUILDIN_FUNC(warpportal)
 	return 0;
 }
 
-#ifndef TXT_ONLY
 BUILDIN_FUNC(openmail)
 {
+#ifndef TXT_ONLY
 	mail_openmail(script_rid2sd(st));
+#endif
 	return 0;
 }
-#endif

+ 31 - 53
src/map/skill.c

@@ -7328,16 +7328,19 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
 		{
 			int count=0;
 			const int x = bl->x, y = bl->y;
-			//Take into account these hit more times than the timer interval
-			//can handle.
+			const bool noknockback = ( tstatus->def_ele == ELE_FIRE || battle_check_undead(tstatus->race, tstatus->def_ele) );
+
+			//Take into account these hit more times than the timer interval can handle.
 			do
-				skill_attack(BF_MAGIC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick+count*sg->interval,0);
+				skill_attack(BF_MAGIC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick+count*sg->interval,noknockback);
 			while(--src->val2 && x == bl->x && y == bl->y &&
 				++count < SKILLUNITTIMER_INTERVAL/sg->interval && !status_isdead(bl));
+
 			if (src->val2<=0)
 				skill_delunit(src);
-			break;
 		}
+		break;
+
 		case UNT_SANCTUARY:
 			if (battle_check_undead(tstatus->race, tstatus->def_ele) || tstatus->race==RC_DEMON)
 			{	//Only damage enemies with offensive Sanctuary. [Skotlex]
@@ -7392,24 +7395,25 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
 				case SG_SUN_WARM: //SG skills [Komurka]
 				case SG_MOON_WARM:
 				case SG_STAR_WARM:
+				{
+					int count = 0;
+					const int x = bl->x, y = bl->y;
+
+					//If target isn't knocked back it should hit every 20ms [Playtester]
+					do
 					{
-						int count=0;
-						const int x = bl->x, y = bl->y;
-						//If target isn't knocked back it should hit every 20ms [Playtester]
-						do
-						{
-							if( bl->type == BL_PC )
-								status_zap(bl, 0, 15); //Only damage SP [Skotlex]
-							else // mobs
-							if( status_charge(ss, 0, 2) ) // costs 2 SP per hit
-								skill_attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick+count*sg->interval,0);
-							else { //should end when out of sp.
-								sg->limit = DIFF_TICK(tick,sg->tick);
-								break;
-							}
-						} while( x == bl->x && y == bl->y &&
-							++count < SKILLUNITTIMER_INTERVAL/sg->interval && !status_isdead(bl) );
-					}
+						if( bl->type == BL_PC )
+							status_zap(bl, 0, 15); // sp damage to players
+						else // mobs
+						if( status_charge(ss, 0, 2) ) // costs 2 SP per hit
+							skill_attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick+count*sg->interval,0);
+						else { //should end when out of sp.
+							sg->limit = DIFF_TICK(tick,sg->tick);
+							break;
+						}
+					} while( x == bl->x && y == bl->y &&
+						++count < SKILLUNITTIMER_INTERVAL/sg->interval && !status_isdead(bl) );
+				}
 				break;
 				case WZ_STORMGUST:
 					if (tsc && tsc->data[SC_FREEZE].val4 != sg->group_id)
@@ -8177,13 +8181,10 @@ int skill_check_condition(struct map_session_data* sd, short skill, short lv, in
 	sp_rate = skill_db[j].sp_rate[lv-1];
 	zeny = skill_db[j].zeny[lv-1];
 
-	if (!type) { //These should only be checked on begin casting.
-		weapon = skill_db[j].weapon;
-		ammo = skill_db[j].ammo;
-		ammo_qty = skill_db[j].ammo_qty[lv-1];
-		state = skill_db[j].state;
-	} else
-		weapon = ammo = ammo_qty = state = 0;
+	weapon = skill_db[j].weapon;
+	ammo = skill_db[j].ammo;
+	ammo_qty = skill_db[j].ammo_qty[lv-1];
+	state = skill_db[j].state;
 
 	spiritball = skill_db[j].spiritball[lv-1];
 	mhp = skill_db[j].mhp[lv-1];
@@ -10783,31 +10784,8 @@ int skill_produce_mix (struct map_session_data *sd, int skill_id, int nameid, in
 				if(battle_config.pp_rate != 100)
 					make_per = make_per * battle_config.pp_rate / 100;
 				break;
-			case SA_CREATECON: // Elemental Converter Creation - skill bonuses are from kRO [DracoRPG]
-				make_per = pc_checkskill(sd, SA_ADVANCEDBOOK)*100 + //TODO: Advanced Book bonus is custom! [Skotlex]
-					sd->status.job_level*20 + status->int_*10 + status->dex*10;
-				switch(nameid){
-					case 12114:
-						flag = pc_checkskill(sd,SA_FLAMELAUNCHER);
-						if (flag > 0)
-							make_per += 1000*flag-500;
-						break;
-					case 12115:
-						flag = pc_checkskill(sd,SA_FROSTWEAPON);
-						if (flag > 0)
-							make_per += 1000*flag-500;
-						break;
-					case 12116:
-						flag = pc_checkskill(sd,SA_SEISMICWEAPON);
-						if (flag > 0)
-							make_per += 1000*flag-500;
-						break;
-					case 12117:
-						flag = pc_checkskill(sd,SA_LIGHTNINGLOADER);
-						if (flag > 0)
-							make_per += 1000*flag-500;
-						break;
-				}
+			case SA_CREATECON: // Elemental Converter Creation
+				make_per = 100000; // should be 100% success rate
 				break;
 			default:
 				if (sd->menuskill_id ==	AM_PHARMACY &&

+ 1 - 1
src/map/unit.c

@@ -911,7 +911,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
 			break;
 		}
 		if (!skill_check_condition(sd, skill_num, skill_lv, 0))
-			return 0;	
+			return 0;
 	}
 	//TODO: Add type-independant skill_check_condition function.
 	if (src->type == BL_MOB) {