summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-SVN.txt7
-rw-r--r--src/map/chrif.c42
-rw-r--r--src/map/mob.c2
-rw-r--r--src/map/npc.c60
-rw-r--r--src/map/skill.c3
-rw-r--r--src/map/status.c51
6 files changed, 138 insertions, 27 deletions
diff --git a/Changelog-SVN.txt b/Changelog-SVN.txt
index c22d8b353..ebdf84e3a 100644
--- a/Changelog-SVN.txt
+++ b/Changelog-SVN.txt
@@ -1,6 +1,11 @@
Date Added
03/08
+ * Reverted the reverted jA event change but this time without bugs (hopefully) [Shinomori]
+ * corrected status_change_timer as far as I understand the functionality
+ (better have a look at it, Celest), added a some security to prevent pending timers
+ * moved two variable declarations to scope start (mob.c and skill.c)
+
* Fixes Icewall can be directly cast on players and monsters -- also removes
the 'unsupported layout' message [celest]
* Added the new turbo_room and alde_tt to the maps config [celest]
@@ -40,6 +45,8 @@ Date Added
It also auto-ban hackers and broadcasts messages to all GMs. Good work, Yor!
* Misc fixes. [Lupus]
2Shino: BTW Some players can't re-connect to the server. Due to the updated session checks in chrif.c
+ actually impossible, because the checks handle the connection with the char server, not with users
+ anyway, I checked again and rearranged code but functionality is still the same and valid [Shinomori]
03/05
* Reversed drop_rate0item option, corrected MVP Drop rate (thanks to Freya) [Lupus]
03/04
diff --git a/src/map/chrif.c b/src/map/chrif.c
index a3a3e63f5..efe17fe29 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -100,7 +100,7 @@ int chrif_save(struct map_session_data *sd)
{
nullpo_retr(-1, sd);
- if (char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect())
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
return -1;
pc_makesavestatus(sd);
@@ -189,7 +189,7 @@ int chrif_changemapserver(struct map_session_data *sd, char *name, int x, int y,
nullpo_retr(-1, sd);
- if (!sd || char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
+ if( !sd || char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
return -1;
s_ip = 0;
@@ -299,7 +299,9 @@ int chrif_authreq(struct map_session_data *sd)
nullpo_retr(-1, sd);
- if (!sd || char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() || !sd->bl.id || !sd->login_id1)
+ if(!sd || !sd->bl.id || !sd->login_id1)
+ return -1;
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
return -1;
for(i = 0; i < fd_max; i++)
@@ -327,7 +329,9 @@ int chrif_charselectreq(struct map_session_data *sd)
nullpo_retr(-1, sd);
- if(!sd || char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() || !sd->bl.id || !sd->login_id1)
+ if( !sd || !sd->bl.id || !sd->login_id1 )
+ return -1;
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
return -1;
s_ip = 0;
@@ -353,7 +357,9 @@ int chrif_charselectreq(struct map_session_data *sd)
*/
int chrif_searchcharid(int char_id)
{
- if (!char_id || char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect())
+ if( !char_id )
+ return -1;
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
return -1;
WFIFOW(char_fd,0) = 0x2b08;
@@ -372,7 +378,7 @@ int chrif_changegm(int id, const char *pass, int len)
if (battle_config.etc_log)
printf("chrif_changegm: account: %d, password: '%s'.\n", id, pass);
- if (char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
return -1;
WFIFOW(char_fd,0) = 0x2b0a;
@@ -393,7 +399,7 @@ int chrif_changeemail(int id, const char *actual_email, const char *new_email)
if (battle_config.etc_log)
printf("chrif_changeemail: account: %d, actual_email: '%s', new_email: '%s'.\n", id, actual_email, new_email);
- if (char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
return -1;
WFIFOW(char_fd,0) = 0x2b0c;
@@ -418,7 +424,7 @@ int chrif_changeemail(int id, const char *actual_email, const char *new_email)
*/
int chrif_char_ask_name(int id, char * character_name, short operation_type, int year, int month, int day, int hour, int minute, int second)
{
- if (char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
return -1;
WFIFOW(char_fd, 0) = 0x2b0e;
@@ -444,7 +450,7 @@ int chrif_char_ask_name(int id, char * character_name, short operation_type, int
*------------------------------------------
*/
int chrif_changesex(int id, int sex) {
- if (char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
return -1;
WFIFOW(char_fd,0) = 0x2b11;
@@ -678,7 +684,7 @@ int chrif_saveaccountreg2(struct map_session_data *sd)
int p, j;
nullpo_retr(-1, sd);
- if (char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
return -1;
p = 8;
@@ -851,7 +857,7 @@ int chrif_chardisconnect(struct map_session_data *sd)
{
nullpo_retr(-1, sd);
- if(char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect())
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
return -1;
WFIFOW(char_fd,0)=0x2b18;
@@ -881,7 +887,7 @@ int chrif_recvgmaccounts(int fd)
*/
int chrif_reloadGMdb(void)
{
- if (char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
return -1;
WFIFOW(char_fd,0) = 0x2af7;
@@ -900,7 +906,7 @@ int chrif_reloadGMdb(void)
FILE *fp;
int i;
- if (char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
return -1;
WFIFOW(char_fd,0) = 0x2b16;
@@ -936,7 +942,7 @@ int chrif_reloadGMdb(void)
int chrif_char_offline(struct map_session_data *sd)
{
- if (char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect())
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
return -1;
WFIFOW(char_fd,0) = 0x2b17;
@@ -952,7 +958,7 @@ int chrif_char_offline(struct map_session_data *sd)
*-----------------------------------------
*/
int chrif_flush_fifo(void) {
- if (char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect())
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
return -1;
set_nonblocking(char_fd, 0);
@@ -967,7 +973,7 @@ int chrif_flush_fifo(void) {
*-----------------------------------------
*/
int chrif_char_reset_offline(void) {
- if (char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect())
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
return -1;
WFIFOW(char_fd,0) = 0x2b18;
@@ -983,7 +989,7 @@ int chrif_char_reset_offline(void) {
int chrif_char_online(struct map_session_data *sd)
{
- if (char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect())
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() )
return -1;
WFIFOW(char_fd,0) = 0x2b19;
@@ -1099,7 +1105,7 @@ int send_users_tochar(int tid, unsigned int tick, int id, int data) {
int users = 0, i;
struct map_session_data *sd;
- if (char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect()) // Thanks to Toster
+ if( char_fd < 1 || session[char_fd] == NULL || !chrif_isconnect() ) // Thanks to Toster
return 0;
WFIFOW(char_fd,0) = 0x2aff;
diff --git a/src/map/mob.c b/src/map/mob.c
index b313328c2..3fb7de38c 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -135,9 +135,9 @@ int mob_once_spawn(struct map_session_data *sd,char *mapname,
return 0;
if(class_<0){ // ランダムに召喚
+ int k;
i = 0;
j = -class_-1;
- int k;
if(j>=0 && j<MAX_RANDOMMONSTER){
do{
class_=rand()%1000+1001;
diff --git a/src/map/npc.c b/src/map/npc.c
index 21d863baf..6adbe7e9c 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -1664,7 +1664,15 @@ int npc_convertlabel_db(void *key,void *data,va_list ap)
lst=(struct npc_label_list *)aRealloc(lst,sizeof(struct npc_label_list)*(num+1));
*p='\0';
- strncpy(lst[num].name,lname,24);
+
+ // here we check if the label fit into the buffer
+ if (strlen(lname)>23) {
+ printf("npc_parse_script: label name longer than 23 chars! '%s'\n", lname);
+ exit(1);
+ }
+ memcpy(lst[num].name,lname,strlen(lname)+1); //including EOS
+
+
*p=':';
lst[num].pos=pos;
nd->u.scr.label_list=lst;
@@ -1873,11 +1881,16 @@ static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line
int pos=nd->u.scr.label_list[i].pos;
if ((lname[0]=='O' || lname[0]=='o')&&(lname[1]=='N' || lname[1]=='n')) {
+/*
+I rearrange the code so this is just for commenting; remove it if you have enough if it [Shinomori]
struct event_data *ev;
char *buf;
// エクスポートされる
ev=(struct event_data *)aCalloc(1,sizeof(struct event_data));
+why allocing 50 chars ?
buf=(char *)aCallocA(50,sizeof(char));
+why checking here?
+lname is identical to nd->u.scr.label_list[i].name which is only 24 chars so check for strlen should be 23
if (strlen(lname)>24) {
printf("npc_parse_script: label name error !\n");
exit(1);
@@ -1891,7 +1904,47 @@ static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line
// printf("npc_parse_script : duplicate event %s\n",buf);
// aFree(ev2);
//}
+you are sure reentering the same database key will overwrite the existing entry?
strdb_insert(ev_db,buf,ev);
+anyway instead of removing data from the db and inserting a new one
+wouldn't it be easier just not to insert the new duplicate event, it is a duplicate anyway?
+ }
+*/
+ // this check is useless here because the buffer is only 24 chars
+ // and already overwritten if this is here is reached
+ // I leave the check anyway but place it correctly to npc_convertlabel_db
+ if (strlen(lname)>23) {
+ printf("npc_parse_script: label name longer than 23 chars! '%s'\n", lname);
+ exit(1);
+ }else{
+ struct event_data *ev;
+ struct event_data *ev2;
+ char *buf;
+ // エクスポートされる
+
+ // 51 comes from: 24 for npc name + 24 for label + 2 for a "::" and 1 for EOS
+ //buf=(char *)aMalloc(51,sizeof(char));
+ // but to save some memory we alloc only the really necessary space
+ buf=(char *)aMalloc( (3+strlen(nd->exname)+strlen(lname))*sizeof(char));
+ sprintf(buf,"%s::%s",nd->exname,lname);
+
+ // search the label in ev_db;
+ // remember the label is max 50 chars + eos; see the strdb_init below
+ ev2 = (struct event_data *)strdb_search(ev_db,buf);
+ if(ev2 != NULL) {
+ printf("npc_parse_script : duplicate event %s\n",buf);
+
+ // just skip the label insertion and free the alloced buffer
+ aFree(buf);
+ }
+ else
+ { // generate the data and insert it
+ ev=(struct event_data *)aCalloc(1,sizeof(struct event_data));
+ ev->nd=nd;
+ ev->pos=pos;
+ strdb_insert(ev_db,buf,ev);
+ }
+
}
}
}
@@ -2362,7 +2415,10 @@ int do_init_npc(void)
npc_read_indoors();
//npc_read_weather();
- ev_db=strdb_init(24);
+ // comparing only the first 24 chars of labels that are 50 chars long isn't that nice
+ // will cause "duplicated" labels where actually no dup is...
+ //ev_db=strdb_init(24);
+ ev_db=strdb_init(51);
npcname_db=strdb_init(24);
ev_db->release = ev_release;
diff --git a/src/map/skill.c b/src/map/skill.c
index 3e657b0c5..d8ce713c6 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -6979,6 +6979,7 @@ int skill_use_id( struct map_session_data *sd, int target_id,
break;
case HP_BASILICA: /* バジリカ */
{
+ struct status_change *sc_data;
if (skill_check_unit_range(sd->bl.m,sd->bl.x,sd->bl.y,sd->skillid,sd->skilllv)) {
clif_skill_fail(sd,sd->skillid,0,0);
return 0;
@@ -6988,7 +6989,7 @@ int skill_use_id( struct map_session_data *sd, int target_id,
return 0;
}
// cancel Basilica if already in effect
- struct status_change *sc_data = status_get_sc_data(&sd->bl);
+ sc_data = status_get_sc_data(&sd->bl);
if(sc_data && sc_data[SC_BASILICA].timer != -1) {
struct skill_unit_group *sg = (struct skill_unit_group *)sc_data[SC_BASILICA].val4;
if (sg && sg->src_id == sd->bl.id) {
diff --git a/src/map/status.c b/src/map/status.c
index f13694145..53c59670f 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -4274,6 +4274,9 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
struct status_change *sc_data;
//short *sc_count; //使ってない?
+// security system to prevent forgetting timer removal
+ int temp_timerid;
+
nullpo_retr_f(0, bl=map_id2bl(id), "id=%d data=%d",id,data);
nullpo_retr(0, sc_data=status_get_sc_data(bl));
@@ -4288,6 +4291,11 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
return 0;
}
+ // security system to prevent forgetting timer removal
+ // you shouldn't be that careless inside the switch here
+ temp_timerid = sc_data[type].timer;
+ sc_data[type].timer = -1;
+
switch(type){ /* 特殊な?理になる場合 */
case SC_MAXIMIZEPOWER: /* マキシマイズパワ? */
case SC_CLOAKING:
@@ -4417,9 +4425,11 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
break;
skill_additional_effect(bl,bl,unit->group->skill_id,sc_data[type].val1,BF_LONG|BF_SKILL|BF_MISC,tick);
if (unit->group != 0)
+ {
sc_data[type].timer=add_timer(skill_get_time(unit->group->skill_id,unit->group->skill_lv)/10+tick,
status_change_timer, bl->id, data );
- return 0;
+ return 0;
+ }// dont forget the brackets
}
break;
@@ -4473,10 +4483,19 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
}
}
sc_data[type].timer=add_timer(1000+tick,status_change_timer, bl->id, data );
+ // hmm setting up a timer and breaking then to call status_change_end just right away?
+ // I think you're missing a:
+ return 0;
+
}
}
else
+ {
sc_data[type].timer=add_timer(1000+tick,status_change_timer, bl->id, data );
+ // hmm setting up a timer and breaking then to call status_change_end just right away?
+ // I think you're missing brackets and a:
+ return 0;
+ }
break;
case SC_DPOISON:
if (sc_data[SC_SLOWPOISON].timer == -1 && (--sc_data[type].val3) > 0) {
@@ -4496,7 +4515,12 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
}
}
if (sc_data[type].val3 > 0)
+ {
sc_data[type].timer=add_timer(1000+tick,status_change_timer, bl->id, data );
+ // hmm setting up a timer and breaking then to call status_change_end just right away?
+ // I think you're missing brackets and a:
+ return 0;
+ }
break;
case SC_TENSIONRELAX: /* テンションリラックス */
@@ -4512,7 +4536,13 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
return 0;
}
if(sd->status.max_hp <= sd->status.hp)
+ {
status_change_end(&sd->bl,SC_TENSIONRELAX,-1);
+ // calling status_change_end then break and call it again might not be that what is necessary
+ // or am I wrong?
+ // so I just add brackets and a:
+ return 0;
+ }
}
break;
case SC_BLEEDING: // [celest]
@@ -4538,6 +4568,9 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
}
sc_data[type].timer=add_timer(1000+tick,status_change_timer, bl->id, data );
+ // hmm setting up a timer and breaking then to call status_change_end just right away?
+ // I think you're missing a:
+ return 0;
}
break;
@@ -4554,8 +4587,7 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
case SC_BROKNWEAPON:
case SC_BROKNARMOR:
case SC_SACRIFICE:
-// if(sc_data[type].timer==tid)
- sc_data[type].timer=add_timer( 1000*600+tick,status_change_timer, bl->id, data );
+ sc_data[type].timer=add_timer( 1000*600+tick,status_change_timer, bl->id, data );
return 0;
case SC_DANCING: //ダンススキルの時間SP消費
@@ -4862,14 +4894,23 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
case SC_GUILDAURA:
{
struct block_list *tbl = map_id2bl(sc_data[type].val2);
- if (tbl && battle_check_range(bl, tbl, 2))
+
+ if (tbl && battle_check_range(bl, tbl, 2)){
sc_data[type].timer = add_timer(
1000 + tick, status_change_timer,
bl->id, data);
- return 0;
+ return 0;
+ }// ugh, don't forget the brackets
}
break;
}
+
+ // default for all non-handled control paths
+ // security system to prevent forgetting timer removal
+
+ // if we reach this point we need the timer for the next call,
+ // so restore it to have status_change_end handle a valid timer
+ sc_data[type].timer = temp_timerid;
return status_change_end( bl,type,tid );
}