From 842984c9a12ca4d641314d3f1f5651c3a77d3f61 Mon Sep 17 00:00:00 2001 From: ultramage Date: Sat, 27 Oct 2007 11:59:35 +0000 Subject: * 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://rathena.svn.sourceforge.net/svnroot/rathena/trunk@11585 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/char/char.c | 63 ++++++++++++++++++++-------------------- src/char_sql/char.c | 34 ++++++++++++---------- src/map/script.c | 9 ++---- src/map/skill.c | 84 ++++++++++++++++++++--------------------------------- src/map/unit.c | 2 +- 5 files changed, 84 insertions(+), 108 deletions(-) (limited to 'src') diff --git a/src/char/char.c b/src/char/char.c index b37bded14..1c2dd5caf 100644 --- a/src/char/char.c +++ b/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; diff --git a/src/char_sql/char.c b/src/char_sql/char.c index 5d5f04653..c72b629c8 100644 --- a/src/char_sql/char.c +++ b/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; diff --git a/src/map/script.c b/src/map/script.c index d00d5f700..8b2464be4 100644 --- a/src/map/script.c +++ b/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 diff --git a/src/map/skill.c b/src/map/skill.c index a73a820e7..d9518d9bf 100644 --- a/src/map/skill.c +++ b/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 && diff --git a/src/map/unit.c b/src/map/unit.c index 709886e76..c43d1374e 100644 --- a/src/map/unit.c +++ b/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) { -- cgit v1.2.3-60-g2f50