summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/char/char.c188
-rw-r--r--src/char_sql/char.c74
-rw-r--r--src/char_sql/int_auction.c2
-rw-r--r--src/common/core.h2
-rw-r--r--src/common/db.c4
-rw-r--r--src/common/grfio.c134
-rw-r--r--src/common/plugins.c2
-rw-r--r--src/common/socket.c5
-rw-r--r--src/common/socket.h7
-rw-r--r--src/common/strlib.c10
-rw-r--r--src/ladmin/Makefile.in45
-rw-r--r--src/ladmin/ladmin.c3074
-rw-r--r--src/ladmin/ladmin.h9
-rw-r--r--src/login/Makefile.in2
-rw-r--r--src/login/account.h3
-rw-r--r--src/login/account_sql.c9
-rw-r--r--src/login/account_txt.c31
-rw-r--r--src/login/admin.c857
-rw-r--r--src/login/login.c136
-rw-r--r--src/login/login.h4
-rw-r--r--src/map/atcommand.c72
-rw-r--r--src/map/battle.c38
-rw-r--r--src/map/chrif.c37
-rw-r--r--src/map/clif.c125
-rw-r--r--src/map/clif.h2
-rw-r--r--src/map/guild.c113
-rw-r--r--src/map/homunculus.c355
-rw-r--r--src/map/itemdb.c211
-rw-r--r--src/map/itemdb.h2
-rw-r--r--src/map/map.c176
-rw-r--r--src/map/mercenary.c216
-rw-r--r--src/map/mob.c26
-rw-r--r--src/map/npc.c30
-rw-r--r--src/map/party.c4
-rw-r--r--src/map/pc.c92
-rw-r--r--src/map/pc.h3
-rw-r--r--src/map/pet.c32
-rw-r--r--src/map/script.c127
-rw-r--r--src/map/skill.c225
-rw-r--r--src/map/status.c224
-rw-r--r--src/map/storage.c3
-rw-r--r--src/map/trade.c3
-rw-r--r--src/map/unit.c135
-rw-r--r--src/map/vending.c33
-rw-r--r--src/map/vending.h2
-rw-r--r--src/plugins/Makefile.in10
-rw-r--r--src/plugins/console.c7
-rw-r--r--src/plugins/gui.c107
-rw-r--r--src/plugins/gui.txt15
-rw-r--r--src/plugins/pid.def (renamed from src/plugins/plugin.def)3
-rw-r--r--src/plugins/sample.def11
-rw-r--r--src/tool/Makefile.in38
-rw-r--r--src/tool/adduser.c103
-rw-r--r--src/tool/grfio.c844
-rw-r--r--src/tool/grfio.h20
-rw-r--r--src/tool/mapcache.c58
56 files changed, 1367 insertions, 6733 deletions
diff --git a/src/char/char.c b/src/char/char.c
index 6dd131976..6523decf7 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -184,7 +184,7 @@ static void* create_online_char_data(DBKey key, va_list args)
character->char_id = -1;
character->server = -1;
character->fd = -1;
- character->waiting_disconnect = -1;
+ character->waiting_disconnect = INVALID_TIMER;
return character;
}
@@ -201,9 +201,9 @@ void set_char_charselect(int account_id)
character->char_id = -1;
character->server = -1;
- if(character->waiting_disconnect != -1) {
+ if(character->waiting_disconnect != INVALID_TIMER) {
delete_timer(character->waiting_disconnect, chardb_waiting_disconnect);
- character->waiting_disconnect = -1;
+ character->waiting_disconnect = INVALID_TIMER;
}
if (login_fd > 0 && !session[login_fd]->flag.eof)
@@ -237,9 +237,9 @@ void set_char_online(int map_id, int char_id, int account_id)
server[character->server].users++;
//Get rid of disconnect timer
- if(character->waiting_disconnect != -1) {
+ if(character->waiting_disconnect != INVALID_TIMER) {
delete_timer(character->waiting_disconnect, chardb_waiting_disconnect);
- character->waiting_disconnect = -1;
+ character->waiting_disconnect = INVALID_TIMER;
}
//Notify login server
@@ -262,9 +262,9 @@ void set_char_offline(int char_id, int account_id)
if( server[character->server].users > 0 ) // Prevent this value from going negative.
server[character->server].users--;
- if(character->waiting_disconnect != -1){
+ if(character->waiting_disconnect != INVALID_TIMER){
delete_timer(character->waiting_disconnect, chardb_waiting_disconnect);
- character->waiting_disconnect = -1;
+ character->waiting_disconnect = INVALID_TIMER;
}
if(character->char_id == char_id)
@@ -293,9 +293,9 @@ static int char_db_setoffline(DBKey key, void* data, va_list ap)
if (server == -1) {
character->char_id = -1;
character->server = -1;
- if(character->waiting_disconnect != -1){
+ if(character->waiting_disconnect != INVALID_TIMER){
delete_timer(character->waiting_disconnect, chardb_waiting_disconnect);
- character->waiting_disconnect = -1;
+ character->waiting_disconnect = INVALID_TIMER;
}
} else if (character->server == server)
character->server = -2; //In some map server that we aren't connected to.
@@ -313,7 +313,7 @@ static int char_db_kickoffline(DBKey key, void* data, va_list ap)
//Kick out any connected characters, and set them offline as appropiate.
if (character->server > -1)
mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 1);
- else if (character->waiting_disconnect == -1)
+ else if (character->waiting_disconnect == INVALID_TIMER)
set_char_offline(character->char_id, character->account_id);
else
return 0; // fail
@@ -1937,7 +1937,7 @@ static void char_auth_ok(int fd, struct char_session_data *sd)
if (character->server > -1)
{ //Character already online. KICK KICK KICK
mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2);
- if (character->waiting_disconnect == -1)
+ if (character->waiting_disconnect == INVALID_TIMER)
character->waiting_disconnect = add_timer(gettick()+20000, chardb_waiting_disconnect, character->account_id, 0);
WFIFOW(fd,0) = 0x81;
WFIFOB(fd,2) = 8;
@@ -2016,7 +2016,7 @@ int parse_fromlogin(int fd)
ShowStatus("Connected to login-server (connection #%d).\n", fd);
//Send online accounts to login server.
- send_accounts_tologin(-1, gettick(), 0, 0);
+ send_accounts_tologin(INVALID_TIMER, gettick(), 0, 0);
// if no map-server already connected, display a message...
ARR_FIND( 0, MAX_MAP_SERVERS, i, server[i].fd > 0 && server[i].map[0] );
@@ -2176,72 +2176,6 @@ int parse_fromlogin(int fd)
}
break;
- case 0x2726: // Request to send a broadcast message (no answer)
- if (RFIFOREST(fd) < 8 || RFIFOREST(fd) < (8 + RFIFOL(fd,4)))
- return 0;
- if (RFIFOL(fd,4) < 1)
- char_log("Receiving a message for broadcast, but message is void.\n");
- else
- {
- // at least 1 map-server
- ARR_FIND( 0, MAX_MAP_SERVERS, i, server[i].fd >= 0 );
- if (i == MAX_MAP_SERVERS)
- char_log("'ladmin': Receiving a message for broadcast, but no map-server is online.\n");
- else {
- unsigned char buf[128];
- char message[4096]; // +1 to add a null terminated if not exist in the packet
- int lp;
- char *p;
- memset(message, '\0', sizeof(message));
- memcpy(message, RFIFOP(fd,8), RFIFOL(fd,4));
- message[sizeof(message)-1] = '\0';
- remove_control_chars(message);
- // remove all first spaces
- p = message;
- while(p[0] == ' ')
- p++;
- // if message is only composed of spaces
- if (p[0] == '\0')
- char_log("Receiving a message for broadcast, but message is only a lot of spaces.\n");
- // else send message to all map-servers
- else {
- if (RFIFOW(fd,2) == 0) {
- char_log("'ladmin': Receiving a message for broadcast (message (in yellow): %s)\n",
- message);
- lp = 4;
- } else {
- char_log("'ladmin': Receiving a message for broadcast (message (in blue): %s)\n",
- message);
- lp = 8;
- }
- // split message to max 80 char
- while(p[0] != '\0') { // if not finish
- if (p[0] == ' ') // jump if first char is a space
- p++;
- else {
- char split[80];
- char* last_space;
- sscanf(p, "%79[^\t]", split); // max 79 char, any char (\t is control char and control char was removed before)
- split[sizeof(split)-1] = '\0'; // last char always \0
- if ((last_space = strrchr(split, ' ')) != NULL) { // searching space from end of the string
- last_space[0] = '\0'; // replace it by NULL to have correct length of split
- p++; // to jump the new NULL
- }
- p += strlen(split);
- // send broadcast to all map-servers
- WBUFW(buf,0) = 0x3800;
- WBUFW(buf,2) = lp + strlen(split) + 1;
- WBUFL(buf,4) = 0x65756c62; // only write if in blue (lp = 8)
- memcpy(WBUFP(buf,lp), split, strlen(split) + 1);
- mapif_sendall(buf, WBUFW(buf,2));
- }
- }
- }
- }
- }
- RFIFOSKIP(fd,8 + RFIFOL(fd,4));
- break;
-
// reply to an account_reg2 registry request
case 0x2729:
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
@@ -2256,54 +2190,6 @@ int parse_fromlogin(int fd)
}
break;
- // Account deletion notification (from login-server)
- case 0x2730:
- if (RFIFOREST(fd) < 6)
- return 0;
- // Deletion of all characters of the account
- for(i = 0; i < char_num; i++) {
- if (char_dat[i].status.account_id == RFIFOL(fd,2)) {
- char_delete(&char_dat[i].status);
- if (i < char_num - 1) {
- memcpy(&char_dat[i], &char_dat[char_num-1], sizeof(struct character_data));
- // if moved character owns to deleted account, check again it's character
- if (char_dat[i].status.account_id == RFIFOL(fd,2)) {
- i--;
- // Correct moved character reference in the character's owner by [Yor]
- } else {
- int j, k;
- struct char_session_data *sd2;
- for (j = 0; j < fd_max; j++) {
- if (session[j] && (sd2 = (struct char_session_data*)session[j]->session_data) &&
- sd2->account_id == char_dat[char_num-1].status.account_id) {
- for (k = 0; k < MAX_CHARS; k++) {
- if (sd2->found_char[k] == char_num-1) {
- sd2->found_char[k] = i;
- break;
- }
- }
- break;
- }
- }
- }
- }
- char_num--;
- }
- }
- // Deletion of the storage
- inter_storage_delete(RFIFOL(fd,2));
- // send to all map-servers to disconnect the player
- {
- unsigned char buf[6];
- WBUFW(buf,0) = 0x2b13;
- WBUFL(buf,2) = RFIFOL(fd,2);
- mapif_sendall(buf, 6);
- }
- // disconnect player if online on char-server
- disconnect_player(RFIFOL(fd,2));
- RFIFOSKIP(fd,6);
- break;
-
// State change of account/ban notification (from login-server)
case 0x2731:
if (RFIFOREST(fd) < 11)
@@ -2336,7 +2222,7 @@ int parse_fromlogin(int fd)
if( character->server > -1 )
{ //Kick it from the map server it is on.
mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2);
- if (character->waiting_disconnect == -1)
+ if (character->waiting_disconnect == INVALID_TIMER)
character->waiting_disconnect = add_timer(gettick()+AUTH_TIMEOUT, chardb_waiting_disconnect, character->account_id, 0);
}
else
@@ -3550,7 +3436,7 @@ int parse_char(int fd)
ShowInfo(CL_RED"Request Char Deletion: "CL_GREEN"%d (%d)"CL_RESET"\n", sd->account_id, cid);
memcpy(email, RFIFOP(fd,6), 40);
- RFIFOSKIP(fd,RFIFOREST(fd)); // hack to make the other deletion packet work
+ RFIFOSKIP(fd,( cmd == 0x68 ) ? 46 : 56);
if (e_mail_check(email) == 0)
safestrncpy(email, "a@a.com", sizeof(email)); // default e-mail
@@ -3750,22 +3636,6 @@ int parse_char(int fd)
}
return 0; // avoid processing of followup packets here
- // Athena info get
- case 0x7530:
- WFIFOHEAD(fd,10);
- WFIFOW(fd,0) = 0x7531;
- WFIFOB(fd,2) = ATHENA_MAJOR_VERSION;
- WFIFOB(fd,3) = ATHENA_MINOR_VERSION;
- WFIFOB(fd,4) = ATHENA_REVISION;
- WFIFOB(fd,5) = ATHENA_RELEASE_FLAG;
- WFIFOB(fd,6) = ATHENA_OFFICIAL_FLAG;
- WFIFOB(fd,7) = ATHENA_SERVER_INTER | ATHENA_SERVER_CHAR;
- WFIFOW(fd,8) = ATHENA_MOD_VERSION;
- WFIFOSET(fd,10);
-
- RFIFOSKIP(fd,2);
- break;
-
// unknown packet received
default:
ShowError("parse_char: Received unknown packet "CL_WHITE"0x%x"CL_RESET" from ip '"CL_WHITE"%s"CL_RESET"'! Disconnecting!\n", RFIFOW(fd,0), ip2str(ipl, NULL));
@@ -3779,29 +3649,19 @@ int parse_char(int fd)
}
// Console Command Parser [Wizputer]
-int parse_console(char* buf)
+int parse_console(const char* command)
{
- char command[256];
+ ShowNotice("Console command: %s\n", command);
- memset(command, 0, sizeof(command));
-
- sscanf(buf, "%[^\n]", command);
-
- //login_log("Console command :%s\n", command);
-
- if( strcmpi("shutdown", command) == 0 ||
- strcmpi("exit", command) == 0 ||
- strcmpi("quit", command) == 0 ||
- strcmpi("end", command) == 0 )
+ if( strcmpi("shutdown", command) == 0 || strcmpi("exit", command) == 0 || strcmpi("quit", command) == 0 || strcmpi("end", command) == 0 )
runflag = 0;
- else if( strcmpi("alive", command) == 0 ||
- strcmpi("status", command) == 0 )
+ else if( strcmpi("alive", command) == 0 || strcmpi("status", command) == 0 )
ShowInfo(CL_CYAN"Console: "CL_BOLD"I'm Alive."CL_RESET"\n");
- else if( strcmpi("help", command) == 0 ){
- ShowInfo(CL_BOLD"Help of commands:"CL_RESET"\n");
- ShowInfo(" To shutdown the server:\n");
- ShowInfo(" 'shutdown|exit|qui|end'\n");
- ShowInfo(" To know if server is alive:\n");
+ else if( strcmpi("help", command) == 0 )
+ {
+ ShowInfo("To shutdown the server:\n");
+ ShowInfo(" 'shutdown|exit|quit|end'\n");
+ ShowInfo("To know if server is alive:\n");
ShowInfo(" 'alive|status'\n");
}
@@ -3978,7 +3838,7 @@ static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr
struct online_char_data* character;
if ((character = (struct online_char_data*)idb_get(online_char_db, id)) != NULL && character->waiting_disconnect == tid)
{ //Mark it offline due to timeout.
- character->waiting_disconnect = -1;
+ character->waiting_disconnect = INVALID_TIMER;
set_char_offline(character->char_id, character->account_id);
}
return 0;
diff --git a/src/char_sql/char.c b/src/char_sql/char.c
index 46b645ce6..262f585d2 100644
--- a/src/char_sql/char.c
+++ b/src/char_sql/char.c
@@ -202,7 +202,7 @@ static void* create_online_char_data(DBKey key, va_list args)
character->char_id = -1;
character->server = -1;
character->fd = -1;
- character->waiting_disconnect = -1;
+ character->waiting_disconnect = INVALID_TIMER;
return character;
}
@@ -219,9 +219,9 @@ void set_char_charselect(int account_id)
character->char_id = -1;
character->server = -1;
- if(character->waiting_disconnect != -1) {
+ if(character->waiting_disconnect != INVALID_TIMER) {
delete_timer(character->waiting_disconnect, chardb_waiting_disconnect);
- character->waiting_disconnect = -1;
+ character->waiting_disconnect = INVALID_TIMER;
}
if (login_fd > 0 && !session[login_fd]->flag.eof)
@@ -260,9 +260,9 @@ void set_char_online(int map_id, int char_id, int account_id)
server[character->server].users++;
//Get rid of disconnect timer
- if(character->waiting_disconnect != -1) {
+ if(character->waiting_disconnect != INVALID_TIMER) {
delete_timer(character->waiting_disconnect, chardb_waiting_disconnect);
- character->waiting_disconnect = -1;
+ character->waiting_disconnect = INVALID_TIMER;
}
//Set char online in guild cache. If char is in memory, use the guild id on it, otherwise seek it.
@@ -305,9 +305,9 @@ void set_char_offline(int char_id, int account_id)
if( server[character->server].users > 0 ) // Prevent this value from going negative.
server[character->server].users--;
- if(character->waiting_disconnect != -1){
+ if(character->waiting_disconnect != INVALID_TIMER){
delete_timer(character->waiting_disconnect, chardb_waiting_disconnect);
- character->waiting_disconnect = -1;
+ character->waiting_disconnect = INVALID_TIMER;
}
if(character->char_id == char_id)
@@ -336,9 +336,9 @@ static int char_db_setoffline(DBKey key, void* data, va_list ap)
if (server == -1) {
character->char_id = -1;
character->server = -1;
- if(character->waiting_disconnect != -1){
+ if(character->waiting_disconnect != INVALID_TIMER){
delete_timer(character->waiting_disconnect, chardb_waiting_disconnect);
- character->waiting_disconnect = -1;
+ character->waiting_disconnect = INVALID_TIMER;
}
} else if (character->server == server)
character->server = -2; //In some map server that we aren't connected to.
@@ -356,7 +356,7 @@ static int char_db_kickoffline(DBKey key, void* data, va_list ap)
//Kick out any connected characters, and set them offline as appropiate.
if (character->server > -1)
mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 1);
- else if (character->waiting_disconnect == -1)
+ else if (character->waiting_disconnect == INVALID_TIMER)
set_char_offline(character->char_id, character->account_id);
else
return 0; // fail
@@ -1722,7 +1722,7 @@ static void char_auth_ok(int fd, struct char_session_data *sd)
if (character->server > -1)
{ //Character already online. KICK KICK KICK
mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2);
- if (character->waiting_disconnect == -1)
+ if (character->waiting_disconnect == INVALID_TIMER)
character->waiting_disconnect = add_timer(gettick()+20000, chardb_waiting_disconnect, character->account_id, 0);
WFIFOW(fd,0) = 0x81;
WFIFOB(fd,2) = 8;
@@ -1801,7 +1801,7 @@ int parse_fromlogin(int fd)
ShowStatus("Connected to login-server (connection #%d).\n", fd);
//Send online accounts to login server.
- send_accounts_tologin(-1, gettick(), 0, 0);
+ send_accounts_tologin(INVALID_TIMER, gettick(), 0, 0);
// if no map-server already connected, display a message...
ARR_FIND( 0, MAX_MAP_SERVERS, i, server[i].fd > 0 && server[i].map[0] );
@@ -2008,7 +2008,7 @@ int parse_fromlogin(int fd)
if( character->server > -1 )
{ //Kick it from the map server it is on.
mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2);
- if (character->waiting_disconnect == -1)
+ if (character->waiting_disconnect == INVALID_TIMER)
character->waiting_disconnect = add_timer(gettick()+AUTH_TIMEOUT, chardb_waiting_disconnect, character->account_id, 0);
}
else
@@ -3256,7 +3256,7 @@ int parse_char(int fd)
ShowInfo(CL_RED"Request Char Deletion: "CL_GREEN"%d (%d)"CL_RESET"\n", sd->account_id, cid);
memcpy(email, RFIFOP(fd,6), 40);
- RFIFOSKIP(fd,RFIFOREST(fd)); // hack to make the other deletion packet work
+ RFIFOSKIP(fd,( cmd == 0x68) ? 46 : 56);
// Check if e-mail is correct
if(strcmpi(email, sd->email) && //email does not matches and
@@ -3429,22 +3429,6 @@ int parse_char(int fd)
}
return 0; // avoid processing of followup packets here
- // Athena info get
- case 0x7530:
- WFIFOHEAD(fd,10);
- WFIFOW(fd,0) = 0x7531;
- WFIFOB(fd,2) = ATHENA_MAJOR_VERSION;
- WFIFOB(fd,3) = ATHENA_MINOR_VERSION;
- WFIFOB(fd,4) = ATHENA_REVISION;
- WFIFOB(fd,5) = ATHENA_RELEASE_FLAG;
- WFIFOB(fd,6) = ATHENA_OFFICIAL_FLAG;
- WFIFOB(fd,7) = ATHENA_SERVER_INTER | ATHENA_SERVER_CHAR;
- WFIFOW(fd,8) = ATHENA_MOD_VERSION;
- WFIFOSET(fd,10);
-
- RFIFOSKIP(fd,2);
- break;
-
// unknown packet received
default:
ShowError("parse_char: Received unknown packet "CL_WHITE"0x%x"CL_RESET" from ip '"CL_WHITE"%s"CL_RESET"'! Disconnecting!\n", RFIFOW(fd,0), ip2str(ipl, NULL));
@@ -3458,29 +3442,19 @@ int parse_char(int fd)
}
// Console Command Parser [Wizputer]
-int parse_console(char* buf)
+int parse_console(const char* command)
{
- char command[256];
+ ShowNotice("Console command: %s\n", command);
- memset(command, 0, sizeof(command));
-
- sscanf(buf, "%[^\n]", command);
-
- //login_log("Console command :%s\n", command);
-
- if( strcmpi("shutdown", command) == 0 ||
- strcmpi("exit", command) == 0 ||
- strcmpi("quit", command) == 0 ||
- strcmpi("end", command) == 0 )
+ if( strcmpi("shutdown", command) == 0 || strcmpi("exit", command) == 0 || strcmpi("quit", command) == 0 || strcmpi("end", command) == 0 )
runflag = 0;
- else if( strcmpi("alive", command) == 0 ||
- strcmpi("status", command) == 0 )
+ else if( strcmpi("alive", command) == 0 || strcmpi("status", command) == 0 )
ShowInfo(CL_CYAN"Console: "CL_BOLD"I'm Alive."CL_RESET"\n");
- else if( strcmpi("help", command) == 0 ){
- ShowInfo(CL_BOLD"Help of commands:"CL_RESET"\n");
- ShowInfo(" To shutdown the server:\n");
- ShowInfo(" 'shutdown|exit|qui|end'\n");
- ShowInfo(" To know if server is alive:\n");
+ else if( strcmpi("help", command) == 0 )
+ {
+ ShowInfo("To shutdown the server:\n");
+ ShowInfo(" 'shutdown|exit|quit|end'\n");
+ ShowInfo("To know if server is alive:\n");
ShowInfo(" 'alive|status'\n");
}
@@ -3654,7 +3628,7 @@ static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr
struct online_char_data* character;
if ((character = (struct online_char_data*)idb_get(online_char_db, id)) != NULL && character->waiting_disconnect == tid)
{ //Mark it offline due to timeout.
- character->waiting_disconnect = -1;
+ character->waiting_disconnect = INVALID_TIMER;
set_char_offline(character->char_id, character->account_id);
}
return 0;
diff --git a/src/char_sql/int_auction.c b/src/char_sql/int_auction.c
index a51361789..bba693256 100644
--- a/src/char_sql/int_auction.c
+++ b/src/char_sql/int_auction.c
@@ -166,7 +166,7 @@ void auction_delete(struct auction_data *auction)
if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `auction_id` = '%d'", auction_db, auction_id) )
Sql_ShowDebug(sql_handle);
- if( auction->auction_end_timer != -1 )
+ if( auction->auction_end_timer != INVALID_TIMER )
delete_timer(auction->auction_end_timer, auction_end_timer);
idb_remove(auction_db_, auction_id);
diff --git a/src/common/core.h b/src/common/core.h
index 68325505a..fc4af3e3e 100644
--- a/src/common/core.h
+++ b/src/common/core.h
@@ -11,7 +11,7 @@ extern int runflag;
extern char *SERVER_NAME;
extern char SERVER_TYPE;
-extern int parse_console(char* buf);
+extern int parse_console(const char* buf);
extern const char *get_svn_revision(void);
extern int do_init(int,char**);
extern void set_server_type(void);
diff --git a/src/common/db.c b/src/common/db.c
index 4dcf1d0b0..595ed241d 100644
--- a/src/common/db.c
+++ b/src/common/db.c
@@ -697,7 +697,7 @@ static void db_free_add(DBMap_impl* db, DBNode node, DBNode *root)
db->alloc_file, db->alloc_line);
exit(EXIT_FAILURE);
}
- if (!(db->options&DB_OPT_DUP_KEY)) { // Make shure we have a key until the node is freed
+ if (!(db->options&DB_OPT_DUP_KEY)) { // Make sure we have a key until the node is freed
old_key = node->key;
node->key = db_dup_key(db, node->key);
db->release(old_key, node->data, DB_RELEASE_KEY);
@@ -1976,13 +1976,13 @@ static int db_obj_vclear(DBMap* self, DBApply func, va_list args)
node->deleted = 1;
}
DB_COUNTSTAT(db_node_free);
- ers_free(db->nodes, node);
if (parent) {
if (parent->left == node)
parent->left = NULL;
else
parent->right = NULL;
}
+ ers_free(db->nodes, node);
node = parent;
}
db->ht[i] = NULL;
diff --git a/src/common/grfio.c b/src/common/grfio.c
index fe94e0803..3c0960f30 100644
--- a/src/common/grfio.c
+++ b/src/common/grfio.c
@@ -12,6 +12,8 @@
#include "../common/cbasetypes.h"
#include "../common/showmsg.h"
#include "../common/malloc.h"
+#include "../common/strlib.h"
+#include "../common/utils.h"
//----------------------------
@@ -381,6 +383,35 @@ static void filelist_adjust(void)
}
}
+
+/// Combines are resource path with the data folder location to
+/// create local resource path.
+static void grfio_localpath_create(char* buffer, size_t size, const char* filename)
+{
+ unsigned int i;
+ size_t len;
+
+ len = strlen(data_dir);
+
+ if( data_dir[0] == 0 || data_dir[len-1] == '/' || data_dir[len-1] == '\\' )
+ {
+ safesnprintf(buffer, size, "%s%s", data_dir, filename);
+ }
+ else
+ {
+ safesnprintf(buffer, size, "%s/%s", data_dir, filename);
+ }
+
+ for( i = 0; buffer[i]; i++ )
+ {// normalize path
+ if( buffer[i] == '\\' )
+ {
+ buffer[i] = '/';
+ }
+ }
+}
+
+
/***********************************************************
*** Grfio Sobroutines ***
***********************************************************/
@@ -398,13 +429,10 @@ int grfio_size(char* fname)
FILELIST lentry;
struct stat st;
- sprintf(lfname, "%s%s", data_dir, fname);
-
- for (p = &lfname[0]; *p != 0; p++)
- if (*p=='\\') *p = '/';
+ grfio_localpath_create(lfname, sizeof(lfname), fname);
if (stat(lfname, &st) == 0) {
- strncpy(lentry.fn, fname, sizeof(lentry.fn) - 1);
+ safestrncpy(lentry.fn, fname, sizeof(lentry.fn));
lentry.fnd = NULL;
lentry.declen = st.st_size;
lentry.gentry = 0; // 0:LocalFile
@@ -428,35 +456,28 @@ void* grfio_reads(char* fname, int* size)
entry = filelist_find(fname);
if (entry == NULL || entry->gentry <= 0) { // LocalFileCheck
- char lfname[256], *p;
- FILELIST lentry;
+ char lfname[256];
+ int declen;
- sprintf(lfname, "%s%s", data_dir, fname);
-
- for (p = &lfname[0]; *p != 0; p++)
- if (*p == '\\') *p = '/';
+ grfio_localpath_create(lfname, sizeof(lfname), ( entry && entry->fnd ) ? entry->fnd : fname);
in = fopen(lfname, "rb");
if (in != NULL) {
- if (entry != NULL && entry->gentry == 0) {
- lentry.declen = entry->declen;
- } else {
- fseek(in,0,SEEK_END);
- lentry.declen = ftell(in);
- }
+ fseek(in,0,SEEK_END);
+ declen = ftell(in);
fseek(in,0,SEEK_SET);
- buf2 = (unsigned char *)aMallocA(lentry.declen + 1024);
- fread(buf2, 1, lentry.declen, in);
+ buf2 = (unsigned char *)aMallocA(declen+1); // +1 for resnametable zero-termination
+ fread(buf2, 1, declen, in);
fclose(in);
- strncpy(lentry.fn, fname, sizeof(lentry.fn) - 1);
- lentry.fnd = NULL;
- lentry.gentry = 0; // 0:LocalFile
- entry = filelist_modify(&lentry);
+ if( size )
+ {
+ size[0] = declen;
+ }
} else {
if (entry != NULL && entry->gentry < 0) {
entry->gentry = -entry->gentry; // local file checked
} else {
- ShowError("%s not found (grfio_reads - local file %s)\n", fname, lfname);
+ ShowError("grfio_reads: %s not found (local file: %s)\n", fname, lfname);
return NULL;
}
}
@@ -465,11 +486,11 @@ void* grfio_reads(char* fname, int* size)
char* grfname = gentry_table[entry->gentry - 1];
in = fopen(grfname, "rb");
if(in != NULL) {
- unsigned char *buf = (unsigned char *)aMallocA(entry->srclen_aligned + 1024);
+ unsigned char *buf = (unsigned char *)aMallocA(entry->srclen_aligned);
fseek(in, entry->srcpos, 0);
fread(buf, 1, entry->srclen_aligned, in);
fclose(in);
- buf2 = (unsigned char *)aMallocA(entry->declen + 1024);
+ buf2 = (unsigned char *)aMallocA(entry->declen+1); // +1 for resnametable zero-termination
if (entry->type == 1 || entry->type == 3 || entry->type == 5) {
uLongf len;
if (entry->cycle >= 0)
@@ -485,14 +506,16 @@ void* grfio_reads(char* fname, int* size)
} else {
memcpy(buf2, buf, entry->declen);
}
+ if( size )
+ {
+ size[0] = entry->declen;
+ }
aFree(buf);
} else {
- ShowError("%s not found (grfio_reads - GRF file %s)\n", fname, grfname);
+ ShowError("grfio_reads: %s not found (GRF file: %s)\n", fname, grfname);
return NULL;
}
}
- if (size != NULL && entry != NULL)
- *size = entry->declen;
return buf2;
}
@@ -590,7 +613,7 @@ static int grfio_entryread(char* grfname, int gentry)
aentry.srcpos = getlong(grf_filelist+ofs2+13)+0x2e;
aentry.cycle = srccount;
aentry.type = type;
- strncpy(aentry.fn, fname,sizeof(aentry.fn)-1);
+ safestrncpy(aentry.fn, fname, sizeof(aentry.fn));
aentry.fnd = NULL;
#ifdef GRFIO_LOCAL
aentry.gentry = -(gentry+1); // As Flag for making it a negative number carrying out the first time LocalFileCheck
@@ -657,7 +680,7 @@ static int grfio_entryread(char* grfname, int gentry)
aentry.srcpos = getlong(grf_filelist+ofs2+13)+0x2e;
aentry.cycle = srccount;
aentry.type = type;
- strncpy(aentry.fn,fname,sizeof(aentry.fn)-1);
+ safestrncpy(aentry.fn, fname, sizeof(aentry.fn));
aentry.fnd = NULL;
#ifdef GRFIO_LOCAL
aentry.gentry = -(gentry+1); // As Flag for making it a negative number carrying out the first time LocalFileCheck
@@ -686,17 +709,16 @@ static int grfio_entryread(char* grfname, int gentry)
*------------------------------------------*/
static void grfio_resourcecheck(void)
{
- char w1[256], w2[256], src[256], dst[256], restable[256], line[256];
+ char w1[256], w2[256], src[256], dst[256], restable[256], line[256], local[256];
char *ptr, *buf;
FILELIST* entry;
+ FILELIST fentry;
int size;
FILE* fp;
int i = 0;
// read resnametable from data directory and return if successful
- sprintf(restable, "%sdata\\resnametable.txt", data_dir);
- for (ptr = &restable[0]; *ptr != 0; ptr++)
- if (*ptr == '\\') *ptr = '/';
+ grfio_localpath_create(restable, sizeof(restable), "data\\resnametable.txt");
fp = fopen(restable, "rb");
if (fp) {
@@ -710,14 +732,28 @@ static void grfio_resourcecheck(void)
sprintf(dst, "data\\%s", w2);
entry = filelist_find(dst);
// create new entries reusing the original's info
- if (entry != NULL) {
- FILELIST fentry;
+ if (entry != NULL)
+ {// alias for GRF resource
memcpy(&fentry, entry, sizeof(FILELIST));
- strncpy(fentry.fn, src, sizeof(fentry.fn) - 1);
+ safestrncpy(fentry.fn, src, sizeof(fentry.fn));
fentry.fnd = aStrdup(dst);
filelist_modify(&fentry);
i++;
}
+ else
+ {
+ grfio_localpath_create(local, sizeof(local), dst);
+
+ if( exists(local) )
+ {// alias for local resource
+ memset(&fentry, 0, sizeof(fentry));
+ //fentry.gentry = 0;
+ safestrncpy(fentry.fn, src, sizeof(fentry.fn));
+ fentry.fnd = aStrdup(dst);
+ filelist_modify(&fentry);
+ i++;
+ }
+ }
}
}
fclose(fp);
@@ -738,14 +774,28 @@ static void grfio_resourcecheck(void)
sprintf(src, "data\\%s", w1);
sprintf(dst, "data\\%s", w2);
entry = filelist_find(dst);
- if (entry != NULL) {
- FILELIST fentry;
+ if (entry != NULL)
+ {// alias for GRF resource
memcpy(&fentry, entry, sizeof(FILELIST));
- strncpy(fentry.fn, src, sizeof(fentry.fn) - 1);
+ safestrncpy(fentry.fn, src, sizeof(fentry.fn));
fentry.fnd = aStrdup(dst);
filelist_modify(&fentry);
i++;
}
+ else
+ {
+ grfio_localpath_create(local, sizeof(local), dst);
+
+ if( exists(local) )
+ {// alias for local resource
+ memset(&fentry, 0, sizeof(fentry));
+ //fentry.gentry = 0;
+ safestrncpy(fentry.fn, src, sizeof(fentry.fn));
+ fentry.fnd = aStrdup(dst);
+ filelist_modify(&fentry);
+ i++;
+ }
+ }
}
ptr = strchr(ptr, '\n'); // Next line
if (!ptr) break;
@@ -824,7 +874,7 @@ void grfio_init(char* fname)
if(strcmp(w1, "grf") == 0) // GRF file
grf_num += (grfio_add(w2) == 0);
else if(strcmp(w1,"data_dir") == 0) { // Data directory
- strcpy(data_dir, w2);
+ safestrncpy(data_dir, w2, sizeof(data_dir));
}
}
fclose(data_conf);
diff --git a/src/common/plugins.c b/src/common/plugins.c
index 2d81548a1..2d50fc9e8 100644
--- a/src/common/plugins.c
+++ b/src/common/plugins.c
@@ -251,6 +251,8 @@ Plugin* plugin_open(const char* filename)
func = (Plugin_Event_Func*)DLL_SYM(plugin->dll, events[i].func_name);
if (func)
register_plugin_event(func, events[i].event_name);
+ else
+ ShowError("Failed to locate function '%s' in '%s'.\n", events[i].func_name, filename);
}
i++;
}
diff --git a/src/common/socket.c b/src/common/socket.c
index 89c605c9d..ff667cf2e 100644
--- a/src/common/socket.c
+++ b/src/common/socket.c
@@ -996,10 +996,10 @@ int access_ipmask(const char* str, AccessControl* acc)
(n == 5 && m[0] > 32) ){ // invalid bit mask
return 0;
}
- ip = (uint32)(a[0] | (a[1] << 8) | (a[2] << 16) | (a[3] << 24));
+ ip = MAKEIP(a[0],a[1],a[2],a[3]);
if( n == 8 )
{// standard mask
- mask = (uint32)(a[0] | (a[1] << 8) | (a[2] << 16) | (a[3] << 24));
+ mask = MAKEIP(m[0],m[1],m[2],m[3]);
} else if( n == 5 )
{// bit mask
mask = 0;
@@ -1007,7 +1007,6 @@ int access_ipmask(const char* str, AccessControl* acc)
mask = (mask >> 1) | 0x80000000;
--m[0];
}
- mask = ntohl(mask);
} else
{// just this ip
mask = 0xFFFFFFFF;
diff --git a/src/common/socket.h b/src/common/socket.h
index f7309f6d3..0a740a63f 100644
--- a/src/common/socket.h
+++ b/src/common/socket.h
@@ -135,6 +135,7 @@ uint32 host2ip(const char* hostname);
const char* ip2str(uint32 ip, char ip_str[16]);
uint32 str2ip(const char* ip_str);
#define CONVIP(ip) ((ip)>>24)&0xFF,((ip)>>16)&0xFF,((ip)>>8)&0xFF,((ip)>>0)&0xFF
+#define MAKEIP(a,b,c,d) (uint32)( ( ( (a)&0xFF ) << 24 ) | ( ( (b)&0xFF ) << 16 ) | ( ( (c)&0xFF ) << 8 ) | ( ( (d)&0xFF ) << 0 ) )
uint16 ntows(uint16 netshort);
int socket_getips(uint32* ips, int max);
@@ -152,12 +153,6 @@ void set_eof(int fd);
#define SEND_SHORTLIST
#ifdef SEND_SHORTLIST
-struct send_shortlist_node {
- struct send_shortlist_node *next; // Next node in the linked list
- struct send_shortlist_node *prev; // Previous node in the linked list
- int fd; // FD that needs sending.
-};
-
// Add a fd to the shortlist so that it'll be recognized as a fd that needs
// sending done on it.
void send_shortlist_add_fd(int fd);
diff --git a/src/common/strlib.c b/src/common/strlib.c
index 019e2d629..a0cba906c 100644
--- a/src/common/strlib.c
+++ b/src/common/strlib.c
@@ -925,6 +925,7 @@ bool sv_readdb(const char* directory, const char* filename, char delim, int minc
char** fields; // buffer for fields ([0] is reserved)
int columns, fields_length;
char path[1024], line[1024];
+ char* match;
snprintf(path, sizeof(path), "%s/%s", directory, filename);
@@ -944,9 +945,12 @@ bool sv_readdb(const char* directory, const char* filename, char delim, int minc
while( fgets(line, sizeof(line), fp) )
{
lines++;
- if( line[0] == '/' && line[1] == '/' )
- continue;
- //TODO: strip trailing // comment
+
+ if( ( match = strstr(line, "//") ) != NULL )
+ {// strip comments
+ match[0] = 0;
+ }
+
//TODO: strip trailing whitespace
if( line[0] == '\0' || line[0] == '\n' || line[0] == '\r')
continue;
diff --git a/src/ladmin/Makefile.in b/src/ladmin/Makefile.in
deleted file mode 100644
index 4703dded1..000000000
--- a/src/ladmin/Makefile.in
+++ /dev/null
@@ -1,45 +0,0 @@
-
-COMMON_OBJ = ../common/obj_all/minicore.o ../common/obj_all/minisocket.o ../common/obj_all/timer.o \
- ../common/obj_all/malloc.o ../common/obj_all/showmsg.o ../common/obj_all/strlib.o \
- ../common/obj_all/utils.o ../common/obj_all/md5calc.o
-COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h \
- ../common/version.h ../common/malloc.h ../common/showmsg.h ../common/strlib.h \
- ../common/utils.h ../common/md5calc.h ../common/cbasetypes.h
-
-LADMIN_OBJ = obj_all/ladmin.o
-LADMIN_H = ladmin.h
-
-@SET_MAKE@
-
-#####################################################################
-.PHONY : all ladmin clean help
-
-all: ladmin
-
-ladmin: obj_all $(LADMIN_OBJ) $(COMMON_OBJ)
- @CC@ @LDFLAGS@ -o ../../ladmin@EXEEXT@ $(LADMIN_OBJ) $(COMMON_OBJ) @LIBS@
-
-clean:
- rm -rf *.o obj_all ../../ladmin@EXEEXT@
-
-help:
- @echo "possible targets are 'ladmin' 'all' 'clean' 'help'"
- @echo "'ladmin' - remote administration tool"
- @echo "'all' - builds all above targets"
- @echo "'clean' - cleans builds and objects"
- @echo "'help' - outputs this message"
-
-#####################################################################
-
-obj_all:
- -mkdir obj_all
-
-obj_all/%.o: %.c $(LADMIN_H) $(COMMON_H)
- @CC@ @CFLAGS@ @LDFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
-
-# missing common object files
-../common/obj_all/%.o:
- @$(MAKE) -C ../common txt
-
-../common/obj_all/mini%.o:
- @$(MAKE) -C ../common txt
diff --git a/src/ladmin/ladmin.c b/src/ladmin/ladmin.c
deleted file mode 100644
index d7a78c119..000000000
--- a/src/ladmin/ladmin.c
+++ /dev/null
@@ -1,3074 +0,0 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
-
-///////////////////////////////////////////////////////////////////////////
-// EAthena login-server remote administration tool
-///////////////////////////////////////////////////////////////////////////
-
-#include "../common/cbasetypes.h"
-#include "../common/core.h"
-#include "../common/strlib.h"
-#include "../common/socket.h"
-#include "../common/timer.h"
-#include "../common/version.h"
-#include "../common/mmo.h"
-#include "../common/md5calc.h"
-#include "../common/showmsg.h"
-#include "ladmin.h"
-
-#include <sys/types.h>
-#include <time.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <string.h> // str*
-#include <stdarg.h> // valist
-
-
-//-------------------------------INSTRUCTIONS------------------------------
-// Set the variables below:
-// IP of the login server.
-// Port where the login-server listens incoming packets.
-// Password of administration (same of config_athena.conf).
-// IMPORTANT:
-// Be sure that you authorize remote administration in login-server
-// (see login_athena.conf, 'admin_state' parameter)
-//-------------------------------------------------------------------------
-char loginserverip[16] = "127.0.0.1"; // IP of login-server
-int loginserverport = 6900; // Port of login-server
-char loginserveradminpassword[24] = "admin"; // Administration password
-int passenc = 0; // Encoding type of the password
-char ladmin_log_filename[1024] = "log/ladmin.log";
-char date_format[32] = "%Y-%m-%d %H:%M:%S";
-
-//-------------------------------------------------------------------------
-// LIST of COMMANDs that you can type at the prompt:
-// To use these commands you can only type only the first letters.
-// You must type a minimum of letters (you can not type 'a',
-// because ladmin doesn't know if it's for 'aide' or for 'add')
-// <Example> q <= quit, li <= list, pass <= passwd, etc.
-//
-// Note: every time you must give a account_name, you can use "" or '' (spaces can be included)
-//
-// aide/help/?
-// Display the description of the commands
-// aide/help/? [command]
-// Display the description of the specified command
-//
-// add <account_name> <sex> <password>
-// Create an account with the default email (a@a.com).
-// Concerning the sex, only the first letter is used (F or M).
-// The e-mail is set to a@a.com (default e-mail). It's like to have no e-mail.
-// When the password is omitted, the input is done without displaying of the pressed keys.
-// <example> add testname Male testpass
-//
-// ban/banish yyyy/mm/dd hh:mm:ss <account name>
-// Changes the final date of a banishment of an account.
-// Like banset, but <account name> is at end.
-//
-// banadd <account_name> <modifier>
-// Adds or substracts time from the final date of a banishment of an account.
-// Modifier is done as follows:
-// Adjustment value (-1, 1, +1, etc...)
-// Modified element:
-// a or y: year
-// m: month
-// j or d: day
-// h: hour
-// mn: minute
-// s: second
-// <example> banadd testname +1m-2mn1s-6y
-// this example adds 1 month and 1 second, and substracts 2 minutes and 6 years at the same time.
-// NOTE: If you modify the final date of a non-banished account,
-// you fix the final date to (actual time +- adjustments)
-//
-// banset <account_name> yyyy/mm/dd [hh:mm:ss]
-// Changes the final date of a banishment of an account.
-// Default time [hh:mm:ss]: 23:59:59.
-// banset <account_name> 0
-// Set a non-banished account (0 = unbanished).
-//
-// block <account name>
-// Set state 5 (You have been blocked by the GM Team) to an account.
-// Like state <account name> 5.
-//
-// check <account_name> <password>
-// Check the validity of a password for an account
-// NOTE: Server will never send back a password.
-// It's the only method you have to know if a password is correct.
-// The other method is to have a ('physical') access to the accounts file.
-//
-// create <account_name> <sex> <email> <password>
-// Like the 'add' command, but with e-mail moreover.
-// <example> create testname Male my@mail.com testpass
-//
-// del <account name>
-// Remove an account.
-// This order requires confirmation. After confirmation, the account is deleted.
-//
-// email <account_name> <email>
-// Modify the e-mail of an account.
-//
-// getcount
-// Give the number of players online on all char-servers.
-//
-// gm <account_name> [GM_level]
-// Modify the GM level of an account.
-// Default value remove GM level (GM level = 0).
-// <example> gm testname 80
-//
-// id <account name>
-// Give the id of an account.
-//
-// info <account_id>
-// Display complete information of an account.
-//
-// kami <message>
-// Sends a broadcast message on all map-server (in yellow).
-// kamib <message>
-// Sends a broadcast message on all map-server (in blue).
-//
-// list/ls [start_id [end_id]]
-// Display a list of accounts.
-// 'start_id', 'end_id': indicate end and start identifiers.
-// Research by name is not possible with this command.
-// <example> list 10 9999999
-//
-// listBan/lsBan [start_id [end_id]]
-// Like list/ls, but only for accounts with state or banished
-//
-// listGM/lsGM [start_id [end_id]]
-// Like list/ls, but only for GM accounts
-//
-// listOK/lsOK [start_id [end_id]]
-// Like list/ls, but only for accounts without state and not banished
-//
-// memo <account_name> <memo>
-// Modify the memo of an account.
-// 'memo': it can have until 253 characters (with spaces or not).
-//
-// name <account_id>
-// Give the name of an account.
-//
-// passwd <account_name> <new_password>
-// Change the password of an account.
-// When new password is omitted, the input is done without displaying of the pressed keys.
-//
-// quit/end/exit
-// End of the program of administration
-//
-// reloadGM
-// Reload GM configuration file
-//
-// search <expression>
-// Seek accounts.
-// Displays the accounts whose names correspond.
-// search -r/-e/--expr/--regex <expression>
-// Seek accounts by regular expression.
-// Displays the accounts whose names correspond.
-//
-// sex <account_name> <sex>
-// Modify the sex of an account.
-// <example> sex testname Male
-//
-// state <account_name> <new_state> <error_message_#7>
-// Change the state of an account.
-// 'new_state': state is the state of the packet 0x006a + 1. The possibilities are:
-// 0 = Account ok 6 = Your Game's EXE file is not the latest version
-// 1 = Unregistered ID 7 = You are Prohibited to log in until %s
-// 2 = Incorrect Password 8 = Server is jammed due to over populated
-// 3 = This ID is expired 9 = No MSG
-// 4 = Rejected from Server 100 = This ID has been totally erased
-// 5 = You have been blocked by the GM Team
-// all other values are 'No MSG', then use state 9 please.
-// 'error_message_#7': message of the code error 6 = Your are Prohibited to log in until %s (packet 0x006a)
-//
-// timeadd <account_name> <modifier>
-// Adds or substracts time from the validity limit of an account.
-// Modifier is done as follows:
-// Adjustment value (-1, 1, +1, etc...)
-// Modified element:
-// a or y: year
-// m: month
-// j or d: day
-// h: hour
-// mn: minute
-// s: second
-// <example> timeadd testname +1m-2mn1s-6y
-// this example adds 1 month and 1 second, and substracts 2 minutes and 6 years at the same time.
-// NOTE: You can not modify a unlimited validity limit.
-// If you want modify it, you want probably create a limited validity limit.
-// So, at first, you must set the validity limit to a date/time.
-//
-// timeset <account_name> yyyy/mm/dd [hh:mm:ss]
-// Changes the validity limit of an account.
-// Default time [hh:mm:ss]: 23:59:59.
-// timeset <account_name> 0
-// Gives an unlimited validity limit (0 = unlimited).
-//
-// unban/unbanish <account name>
-// Unban an account.
-// Like banset <account name> 0.
-//
-// unblock <account name>
-// Set state 0 (Account ok) to an account.
-// Like state <account name> 0.
-//
-// version
-// Display the version of the login-server.
-//
-// who <account name>
-// Displays complete information of an account.
-//
-//-------------------------------------------------------------------------
-
-int login_fd;
-int login_ip;
-int bytes_to_read = 0; // flag to know if we waiting bytes from login-server
-char command[1024];
-char parameters[1024];
-int list_first, list_last, list_type, list_count; // parameter to display a list of accounts
-int already_exit_function = 0; // sometimes, the exit function is called twice... so, don't log twice the message
-
-//------------------------------
-// Writing function of logs file
-//------------------------------
-int ladmin_log(char *fmt, ...)
-{
- FILE *logfp;
- va_list ap;
- time_t t;
- char tmpstr[2048];
-
- va_start(ap, fmt);
-
- logfp = fopen(ladmin_log_filename, "a");
- if (logfp) {
- if (fmt[0] == '\0') // jump a line if no message
- fprintf(logfp, "\n");
- else {
- t = time(NULL);
- strftime(tmpstr, 24, date_format, localtime(&t));
- sprintf(tmpstr + strlen(tmpstr), ": %s", fmt);
- vfprintf(logfp, tmpstr, ap);
- }
- fclose(logfp);
- }
-
- va_end(ap);
- return 0;
-}
-
-//---------------------------------------------
-// Function to return ordinal text of a number.
-//---------------------------------------------
-char* makeordinal(int number)
-{
- if ((number % 10) < 4 && (number % 10) != 0 && (number < 10 || number > 20)) {
- if ((number % 10) == 1)
- return "st";
- else if ((number % 10) == 2)
- return "nd";
- else
- return "rd";
- } else {
- return "th";
- }
-}
-
-//-----------------------------------------------------------------------------------------
-// Function to test of the validity of an account name (return 0 if incorrect, and 1 if ok)
-//-----------------------------------------------------------------------------------------
-int verify_accountname(char* account_name)
-{
- int i;
-
- for(i = 0; account_name[i]; i++) {
- if (account_name[i] < 32) {
- ShowMessage("Illegal character found in the account name (%d%s character).\n", i+1, makeordinal(i+1));
- ladmin_log("Illegal character found in the account name (%d%s character).\n", i+1, makeordinal(i+1));
- return 0;
- }
- }
-
- if (strlen(account_name) < 4) {
- ShowMessage("Account name is too short. Please input an account name of 4-23 bytes.\n");
- ladmin_log("Account name is too short. Please input an account name of 4-23 bytes.\n");
- return 0;
- }
-
- if (strlen(account_name) > 23) {
- ShowMessage("Account name is too long. Please input an account name of 4-23 bytes.\n");
- ladmin_log("Account name is too long. Please input an account name of 4-23 bytes.\n");
- return 0;
- }
-
- return 1;
-}
-
-//----------------------------------
-// Sub-function: Input of a password
-//----------------------------------
-int typepasswd(char * password)
-{
- char password1[1023], password2[1023];
- int letter;
- int i;
-
- ladmin_log("No password was given. Request to obtain a password.\n");
-
- memset(password1, '\0', sizeof(password1));
- memset(password2, '\0', sizeof(password2));
-
- ShowMessage("\033[1;36m Type the password > \033[0;32;42m");
-
- i = 0;
- while ((letter = getchar()) != '\n')
- password1[i++] = letter;
-
- ShowMessage("\033[0m\033[1;36m Verify the password > \033[0;32;42m");
-
- i = 0;
- while ((letter = getchar()) != '\n')
- password2[i++] = letter;
-
- ShowMessage("\033[0m");
- fflush(stdout);
- fflush(stdin);
-
- if (strcmp(password1, password2) != 0) {
- ShowMessage("Password verification failed. Please input same password.\n");
- ladmin_log("Password verification failed. Please input same password.\n");
- ladmin_log(" First password: %s, second password: %s.\n", password1, password2);
- return 0;
- }
- ladmin_log("Typed password: %s.\n", password1);
- strcpy(password, password1);
- return 1;
-}
-
-//------------------------------------------------------------------------------------
-// Sub-function: Test of the validity of password (return 0 if incorrect, and 1 if ok)
-//------------------------------------------------------------------------------------
-int verify_password(char * password)
-{
- int i;
-
- for(i = 0; password[i]; i++) {
- if (password[i] < 32) {
- ShowMessage("Illegal character found in the password (%d%s character).\n", i+1, makeordinal(i+1));
- ladmin_log("Illegal character found in the password (%d%s character).\n", i+1, makeordinal(i+1));
- return 0;
- }
- }
-
- if (strlen(password) < 4) {
- ShowMessage("Account name is too short. Please input an account name of 4-23 bytes.\n");
- ladmin_log("Account name is too short. Please input an account name of 4-23 bytes.\n");
- return 0;
- }
-
- if (strlen(password) > 23) {
- ShowMessage("Password is too long. Please input a password of 4-23 bytes.\n");
- ladmin_log("Password is too long. Please input a password of 4-23 bytes.\n");
- return 0;
- }
-
- return 1;
-}
-
-//------------------------------------------------------------------
-// Sub-function: Check the name of a command (return complete name)
-//-----------------------------------------------------------------
-int check_command(char * command)
-{
-// help
- if (strncmp(command, "help", 1) == 0 && strncmp(command, "help", strlen(command)) == 0)
- strcpy(command, "help");
-// general commands
- else if (strncmp(command, "add", 2) == 0 && strncmp(command, "add", strlen(command)) == 0) // not 1 letter command: 'aide' or 'add'?
- strcpy(command, "add");
- else if ((strncmp(command, "ban", 3) == 0 && strncmp(command, "ban", strlen(command)) == 0) ||
- (strncmp(command, "banish", 4) == 0 && strncmp(command, "banish", strlen(command)) == 0))
- strcpy(command, "ban");
- else if ((strncmp(command, "banadd", 4) == 0 && strncmp(command, "banadd", strlen(command)) == 0) || // not 1 letter command: 'ba' or 'bs'? 'banadd' or 'banset' ?
- strcmp(command, "ba") == 0)
- strcpy(command, "banadd");
- else if ((strncmp(command, "banset", 4) == 0 && strncmp(command, "banset", strlen(command)) == 0) || // not 1 letter command: 'ba' or 'bs'? 'banadd' or 'banset' ?
- strcmp(command, "bs") == 0)
- strcpy(command, "banset");
- else if (strncmp(command, "block", 2) == 0 && strncmp(command, "block", strlen(command)) == 0)
- strcpy(command, "block");
- else if (strncmp(command, "check", 2) == 0 && strncmp(command, "check", strlen(command)) == 0) // not 1 letter command: 'check' or 'create'?
- strcpy(command, "check");
- else if (strncmp(command, "create", 2) == 0 && strncmp(command, "create", strlen(command)) == 0) // not 1 letter command: 'check' or 'create'?
- strcpy(command, "create");
- else if (strncmp(command, "delete", 1) == 0 && strncmp(command, "delete", strlen(command)) == 0)
- strcpy(command, "delete");
- else if ((strncmp(command, "email", 2) == 0 && strncmp(command, "email", strlen(command)) == 0) || // not 1 letter command: 'email', 'end' or 'exit'?
- (strncmp(command, "e-mail", 2) == 0 && strncmp(command, "e-mail", strlen(command)) == 0))
- strcpy(command, "email");
- else if (strncmp(command, "getcount", 2) == 0 && strncmp(command, "getcount", strlen(command)) == 0) // not 1 letter command: 'getcount' or 'gm'?
- strcpy(command, "getcount");
-// else if (strncmp(command, "gm", 2) == 0 && strncmp(command, "gm", strlen(command)) == 0) // not 1 letter command: 'getcount' or 'gm'?
-// strcpy(command, "gm");
-// else if (strncmp(command, "id", 2) == 0 && strncmp(command, "id", strlen(command)) == 0) // not 1 letter command: 'id' or 'info'?
-// strcpy(command, "id");
- else if (strncmp(command, "info", 2) == 0 && strncmp(command, "info", strlen(command)) == 0) // not 1 letter command: 'id' or 'info'?
- strcpy(command, "info");
-// else if (strncmp(command, "kami", 4) == 0 && strncmp(command, "kami", strlen(command)) == 0) // only all letters command: 'kami' or 'kamib'?
-// strcpy(command, "kami");
-// else if (strncmp(command, "kamib", 5) == 0 && strncmp(command, "kamib", strlen(command)) == 0) // only all letters command: 'kami' or 'kamib'?
-// strcpy(command, "kamib");
- else if ((strncmp(command, "list", 2) == 0 && strncmp(command, "list", strlen(command)) == 0) || // 'list' is default list command // not 1 letter command: 'list'?
- strcmp(command, "ls") == 0)
- strcpy(command, "list");
- else if ((strncmp(command, "listban", 5) == 0 && strncmp(command, "listban", strlen(command)) == 0) ||
- (strncmp(command, "lsban", 3) == 0 && strncmp(command, "lsban", strlen(command)) == 0) ||
- strcmp(command, "lb") == 0)
- strcpy(command, "listban");
- else if ((strncmp(command, "listgm", 5) == 0 && strncmp(command, "listgm", strlen(command)) == 0) ||
- (strncmp(command, "lsgm", 3) == 0 && strncmp(command, "lsgm", strlen(command)) == 0) ||
- strcmp(command, "lg") == 0)
- strcpy(command, "listgm");
- else if ((strncmp(command, "listok", 5) == 0 && strncmp(command, "listok", strlen(command)) == 0) ||
- (strncmp(command, "lsok", 3) == 0 && strncmp(command, "lsok", strlen(command)) == 0) ||
- strcmp(command, "lo") == 0)
- strcpy(command, "listok");
- else if (strncmp(command, "memo", 1) == 0 && strncmp(command, "memo", strlen(command)) == 0)
- strcpy(command, "memo");
- else if (strncmp(command, "name", 1) == 0 && strncmp(command, "name", strlen(command)) == 0)
- strcpy(command, "name");
- else if ((strncmp(command, "password", 1) == 0 && strncmp(command, "password", strlen(command)) == 0) ||
- strcmp(command, "passwd") == 0)
- strcpy(command, "password");
- else if (strncmp(command, "reloadgm", 1) == 0 && strncmp(command, "reloadgm", strlen(command)) == 0)
- strcpy(command, "reloadgm");
- else if (strncmp(command, "search", 3) == 0 && strncmp(command, "search", strlen(command)) == 0) // not 1 letter command: 'search', 'state' or 'sex'?
- strcpy(command, "search"); // not 2 letters command: 'search' or 'sex'?
-// else if (strncmp(command, "sex", 3) == 0 && strncmp(command, "sex", strlen(command)) == 0) // not 1 letter command: 'search', 'state' or 'sex'?
-// strcpy(command, "sex"); // not 2 letters command: 'search' or 'sex'?
- else if (strncmp(command, "state", 2) == 0 && strncmp(command, "state", strlen(command)) == 0) // not 1 letter command: 'search', 'state' or 'sex'?
- strcpy(command, "state");
- else if ((strncmp(command, "timeadd", 5) == 0 && strncmp(command, "timeadd", strlen(command)) == 0) || // not 1 letter command: 'ta' or 'ts'? 'timeadd' or 'timeset'?
- strcmp(command, "ta") == 0)
- strcpy(command, "timeadd");
- else if ((strncmp(command, "timeset", 5) == 0 && strncmp(command, "timeset", strlen(command)) == 0) || // not 1 letter command: 'ta' or 'ts'? 'timeadd' or 'timeset'?
- strcmp(command, "ts") == 0)
- strcpy(command, "timeset");
- else if ((strncmp(command, "unban", 5) == 0 && strncmp(command, "unban", strlen(command)) == 0) ||
- (strncmp(command, "unbanish", 4) == 0 && strncmp(command, "unbanish", strlen(command)) == 0))
- strcpy(command, "unban");
- else if (strncmp(command, "unblock", 4) == 0 && strncmp(command, "unblock", strlen(command)) == 0)
- strcpy(command, "unblock");
- else if (strncmp(command, "version", 1) == 0 && strncmp(command, "version", strlen(command)) == 0)
- strcpy(command, "version");
- else if (strncmp(command, "who", 1) == 0 && strncmp(command, "who", strlen(command)) == 0)
- strcpy(command, "who");
-// quit
- else if (strncmp(command, "quit", 1) == 0 && strncmp(command, "quit", strlen(command)) == 0)
- strcpy(command, "quit");
- else if (strncmp(command, "exit", 2) == 0 && strncmp(command, "exit", strlen(command)) == 0) // not 1 letter command: 'email', 'end' or 'exit'?
- strcpy(command, "exit");
- else if (strncmp(command, "end", 2) == 0 && strncmp(command, "end", strlen(command)) == 0) // not 1 letter command: 'email', 'end' or 'exit'?
- strcpy(command, "end");
-
- return 0;
-}
-
-//-----------------------------------------
-// Sub-function: Display commands of ladmin
-//-----------------------------------------
-void display_help(char* param)
-{
- char command[1023];
- int i;
-
- memset(command, '\0', sizeof(command));
-
- if (sscanf(param, "%s ", command) < 1 || strlen(command) == 0)
- strcpy(command, ""); // any value that is not a command
-
- if (command[0] == '?')
- strcpy(command, "help");
-
- // lowercase for command
- for (i = 0; command[i]; i++)
- command[i] = TOLOWER(command[i]);
-
- // Analyse of the command
- check_command(command); // give complete name to the command
-
- ladmin_log("Displaying of the commands or a command.\n");
-
- if (strcmp(command, "help") == 0 ) {
- ShowMessage("aide/help/?\n");
- ShowMessage(" Display the description of the commands\n");
- ShowMessage("aide/help/? [command]\n");
- ShowMessage(" Display the description of the specified command\n");
-// general commands
- } else if (strcmp(command, "add") == 0) {
- ShowMessage("add <account_name> <sex> <password>\n");
- ShowMessage(" Create an account with the default email (a@a.com).\n");
- ShowMessage(" Concerning the sex, only the first letter is used (F or M).\n");
- ShowMessage(" The e-mail is set to a@a.com (default e-mail). It's like to have no e-mail.\n");
- ShowMessage(" When the password is omitted,\n");
- ShowMessage(" the input is done without displaying of the pressed keys.\n");
- ShowMessage(" <example> add testname Male testpass\n");
- } else if (strcmp(command, "ban") == 0) {
- ShowMessage("ban/banish yyyy/mm/dd hh:mm:ss <account name>\n");
- ShowMessage(" Changes the final date of a banishment of an account.\n");
- ShowMessage(" Like banset, but <account name> is at end.\n");
- } else if (strcmp(command, "banadd") == 0) {
- ShowMessage("banadd <account_name> <modifier>\n");
- ShowMessage(" Adds or substracts time from the final date of a banishment of an account.\n");
- ShowMessage(" Modifier is done as follows:\n");
- ShowMessage(" Adjustment value (-1, 1, +1, etc...)\n");
- ShowMessage(" Modified element:\n");
- ShowMessage(" a or y: year\n");
- ShowMessage(" m: month\n");
- ShowMessage(" j or d: day\n");
- ShowMessage(" h: hour\n");
- ShowMessage(" mn: minute\n");
- ShowMessage(" s: second\n");
- ShowMessage(" <example> banadd testname +1m-2mn1s-6y\n");
- ShowMessage(" this example adds 1 month and 1 second, and substracts 2 minutes\n");
- ShowMessage(" and 6 years at the same time.\n");
- ShowMessage("NOTE: If you modify the final date of a non-banished account,\n");
- ShowMessage(" you fix the final date to (actual time +- adjustments)\n");
- } else if (strcmp(command, "banset") == 0) {
- ShowMessage("banset <account_name> yyyy/mm/dd [hh:mm:ss]\n");
- ShowMessage(" Changes the final date of a banishment of an account.\n");
- ShowMessage(" Default time [hh:mm:ss]: 23:59:59.\n");
- ShowMessage("banset <account_name> 0\n");
- ShowMessage(" Set a non-banished account (0 = unbanished).\n");
- } else if (strcmp(command, "block") == 0) {
- ShowMessage("block <account name>\n");
- ShowMessage(" Set state 5 (You have been blocked by the GM Team) to an account.\n");
- ShowMessage(" This command works like state <account_name> 5.\n");
- } else if (strcmp(command, "check") == 0) {
- ShowMessage("check <account_name> <password>\n");
- ShowMessage(" Check the validity of a password for an account.\n");
- ShowMessage(" NOTE: Server will never send back a password.\n");
- ShowMessage(" It's the only method you have to know if a password is correct.\n");
- ShowMessage(" The other method is to have a ('physical') access to the accounts file.\n");
- } else if (strcmp(command, "create") == 0) {
- ShowMessage("create <account_name> <sex> <email> <password>\n");
- ShowMessage(" Like the 'add' command, but with e-mail moreover.\n");
- ShowMessage(" <example> create testname Male my@mail.com testpass\n");
- } else if (strcmp(command, "delete") == 0) {
- ShowMessage("del <account name>\n");
- ShowMessage(" Remove an account.\n");
- ShowMessage(" This order requires confirmation. After confirmation, the account is deleted.\n");
- } else if (strcmp(command, "email") == 0) {
- ShowMessage("email <account_name> <email>\n");
- ShowMessage(" Modify the e-mail of an account.\n");
- } else if (strcmp(command, "getcount") == 0) {
- ShowMessage("getcount\n");
- ShowMessage(" Give the number of players online on all char-servers.\n");
- } else if (strcmp(command, "gm") == 0) {
- ShowMessage("gm <account_name> [GM_level]\n");
- ShowMessage(" Modify the GM level of an account.\n");
- ShowMessage(" Default value remove GM level (GM level = 0).\n");
- ShowMessage(" <example> gm testname 80\n");
- } else if (strcmp(command, "id") == 0) {
- ShowMessage("id <account name>\n");
- ShowMessage(" Give the id of an account.\n");
- } else if (strcmp(command, "info") == 0) {
- ShowMessage("info <account_id>\n");
- ShowMessage(" Display complete information of an account.\n");
- } else if (strcmp(command, "kami") == 0) {
- ShowMessage("kami <message>\n");
- ShowMessage(" Sends a broadcast message on all map-server (in yellow).\n");
- } else if (strcmp(command, "kamib") == 0) {
- ShowMessage("kamib <message>\n");
- ShowMessage(" Sends a broadcast message on all map-server (in blue).\n");
- } else if (strcmp(command, "list") == 0) {
- ShowMessage("list/ls [start_id [end_id]]\n");
- ShowMessage(" Display a list of accounts.\n");
- ShowMessage(" 'start_id', 'end_id': indicate end and start identifiers.\n");
- ShowMessage(" Research by name is not possible with this command.\n");
- ShowMessage(" <example> list 10 9999999\n");
- } else if (strcmp(command, "listban") == 0) {
- ShowMessage("listBan/lsBan [start_id [end_id]]\n");
- ShowMessage(" Like list/ls, but only for accounts with state or banished.\n");
- } else if (strcmp(command, "listgm") == 0) {
- ShowMessage("listGM/lsGM [start_id [end_id]]\n");
- ShowMessage(" Like list/ls, but only for GM accounts.\n");
- } else if (strcmp(command, "listok") == 0) {
- ShowMessage("listOK/lsOK [start_id [end_id]]\n");
- ShowMessage(" Like list/ls, but only for accounts without state and not banished.\n");
- } else if (strcmp(command, "memo") == 0) {
- ShowMessage("memo <account_name> <memo>\n");
- ShowMessage(" Modify the memo of an account.\n");
- ShowMessage(" 'memo': it can have until 253 characters (with spaces or not).\n");
- } else if (strcmp(command, "name") == 0) {
- ShowMessage("name <account_id>\n");
- ShowMessage(" Give the name of an account.\n");
- } else if (strcmp(command, "password") == 0) {
- ShowMessage("passwd <account_name> <new_password>\n");
- ShowMessage(" Change the password of an account.\n");
- ShowMessage(" When new password is omitted,\n");
- ShowMessage(" the input is done without displaying of the pressed keys.\n");
- } else if (strcmp(command, "reloadgm") == 0) {
- ShowMessage("reloadGM\n");
- ShowMessage(" Reload GM configuration file\n");
- } else if (strcmp(command, "search") == 0) {
- ShowMessage("search <expression>\n");
- ShowMessage(" Seek accounts.\n");
- ShowMessage(" Displays the accounts whose names correspond.\n");
-// ShowMessage("search -r/-e/--expr/--regex <expression>\n");
-// ShowMessage(" Seek accounts by regular expression.\n");
-// ShowMessage(" Displays the accounts whose names correspond.\n");
- } else if (strcmp(command, "sex") == 0) {
- ShowMessage("sex <account_name> <sex>\n");
- ShowMessage(" Modify the sex of an account.\n");
- ShowMessage(" <example> sex testname Male\n");
- } else if (strcmp(command, "state") == 0) {
- ShowMessage("state <account_name> <new_state> <error_message_#7>\n");
- ShowMessage(" Change the state of an account.\n");
- ShowMessage(" 'new_state': state is the state of the packet 0x006a + 1.\n");
- ShowMessage(" The possibilities are:\n");
- ShowMessage(" 0 = Account ok\n");
- ShowMessage(" 1 = Unregistered ID\n");
- ShowMessage(" 2 = Incorrect Password\n");
- ShowMessage(" 3 = This ID is expired\n");
- ShowMessage(" 4 = Rejected from Server\n");
- ShowMessage(" 5 = You have been blocked by the GM Team\n");
- ShowMessage(" 6 = Your Game's EXE file is not the latest version\n");
- ShowMessage(" 7 = You are Prohibited to log in until...\n");
- ShowMessage(" 8 = Server is jammed due to over populated\n");
- ShowMessage(" 9 = No MSG\n");
- ShowMessage(" 100 = This ID has been totally erased\n");
- ShowMessage(" all other values are 'No MSG', then use state 9 please.\n");
- ShowMessage(" 'error_message_#7': message of the code error 6\n");
- ShowMessage(" = Your are Prohibited to log in until... (packet 0x006a)\n");
- } else if (strcmp(command, "timeadd") == 0) {
- ShowMessage("timeadd <account_name> <modifier>\n");
- ShowMessage(" Adds or substracts time from the validity limit of an account.\n");
- ShowMessage(" Modifier is done as follows:\n");
- ShowMessage(" Adjustment value (-1, 1, +1, etc...)\n");
- ShowMessage(" Modified element:\n");
- ShowMessage(" a or y: year\n");
- ShowMessage(" m: month\n");
- ShowMessage(" j or d: day\n");
- ShowMessage(" h: hour\n");
- ShowMessage(" mn: minute\n");
- ShowMessage(" s: second\n");
- ShowMessage(" <example> timeadd testname +1m-2mn1s-6y\n");
- ShowMessage(" this example adds 1 month and 1 second, and substracts 2 minutes\n");
- ShowMessage(" and 6 years at the same time.\n");
- ShowMessage("NOTE: You can not modify a unlimited validity limit.\n");
- ShowMessage(" If you want modify it, you want probably create a limited validity limit.\n");
- ShowMessage(" So, at first, you must set the validity limit to a date/time.\n");
- } else if (strcmp(command, "timeadd") == 0) {
- ShowMessage("timeset <account_name> yyyy/mm/dd [hh:mm:ss]\n");
- ShowMessage(" Changes the validity limit of an account.\n");
- ShowMessage(" Default time [hh:mm:ss]: 23:59:59.\n");
- ShowMessage("timeset <account_name> 0\n");
- ShowMessage(" Gives an unlimited validity limit (0 = unlimited).\n");
- } else if (strcmp(command, "unban") == 0) {
- ShowMessage("unban/unbanish <account name>\n");
- ShowMessage(" Remove the banishment of an account.\n");
- ShowMessage(" This command works like banset <account_name> 0.\n");
- } else if (strcmp(command, "unblock") == 0) {
- ShowMessage("unblock <account name>\n");
- ShowMessage(" Set state 0 (Account ok) to an account.\n");
- ShowMessage(" This command works like state <account_name> 0.\n");
- } else if (strcmp(command, "version") == 0) {
- ShowMessage("version\n");
- ShowMessage(" Display the version of the login-server.\n");
- } else if (strcmp(command, "who") == 0) {
- ShowMessage("who <account name>\n");
- ShowMessage(" Displays complete information of an account.\n");
-// quit
- } else if (strcmp(command, "quit") == 0 ||
- strcmp(command, "exit") == 0 ||
- strcmp(command, "end") == 0) {
- ShowMessage("quit/end/exit\n");
- ShowMessage(" End of the program of administration.\n");
-// unknown command
- } else {
- if (strlen(command) > 0)
- ShowMessage("Unknown command [%s] for help. Displaying of all commands.\n", command);
- ShowMessage(" aide/help/? -- Display this help\n");
- ShowMessage(" aide/help/? [command] -- Display the help of the command\n");
- ShowMessage(" add <account_name> <sex> <password> -- Create an account with default email\n");
- ShowMessage(" ban/banish yyyy/mm/dd hh:mm:ss <account name> -- Change final date of a ban\n");
- ShowMessage(" banadd/ba <account_name> <modifier> -- Add or substract time from the final\n");
- ShowMessage(" example: ba apple +1m-2mn1s-2y date of a banishment of an account\n");
- ShowMessage(" banset/bs <account_name> yyyy/mm/dd [hh:mm:ss] -- Change final date of a ban\n");
- ShowMessage(" banset/bs <account_name> 0 -- Un-banish an account\n");
- ShowMessage(" block <account name> -- Set state 5 (blocked by the GM Team) to an account\n");
- ShowMessage(" check <account_name> <password> -- Check the validity of a password\n");
- ShowMessage(" create <account_name> <sex> <email> <passwrd> -- Create an account with email\n");
- ShowMessage(" del <account name> -- Remove an account\n");
- ShowMessage(" email <account_name> <email> -- Modify an email of an account\n");
- ShowMessage(" getcount -- Give the number of players online\n");
- ShowMessage(" gm <account_name> [GM_level] -- Modify the GM level of an account\n");
- ShowMessage(" id <account name> -- Give the id of an account\n");
- ShowMessage(" info <account_id> -- Display all information of an account\n");
- ShowMessage(" kami <message> -- Sends a broadcast message (in yellow)\n");
- ShowMessage(" kamib <message> -- Sends a broadcast message (in blue)\n");
- ShowMessage(" list/ls [First_id [Last_id]] -- Display a list of accounts\n");
- ShowMessage(" listBan/lsBan [First_id [Last_id] ] -- Display a list of accounts\n");
- ShowMessage(" with state or banished\n");
- ShowMessage(" listGM/lsGM [First_id [Last_id]] -- Display a list of GM accounts\n");
- ShowMessage(" listOK/lsOK [First_id [Last_id] ] -- Display a list of accounts\n");
- ShowMessage(" without state and not banished\n");
- ShowMessage(" memo <account_name> <memo> -- Modify the memo of an account\n");
- ShowMessage(" name <account_id> -- Give the name of an account\n");
- ShowMessage(" passwd <account_name> <new_password> -- Change the password of an account\n");
- ShowMessage(" quit/end/exit -- End of the program of administation\n");
- ShowMessage(" reloadGM -- Reload GM configuration file\n");
- ShowMessage(" search <expression> -- Seek accounts\n");
-// ShowMessage(" search -e/-r/--expr/--regex <expressn> -- Seek accounts by regular-expression\n");
- ShowMessage(" sex <nomcompte> <sexe> -- Modify the sex of an account\n");
- ShowMessage(" state <account_name> <new_state> <error_message_#7> -- Change the state\n");
- ShowMessage(" timeadd/ta <account_name> <modifier> -- Add or substract time from the\n");
- ShowMessage(" example: ta apple +1m-2mn1s-2y validity limit of an account\n");
- ShowMessage(" timeset/ts <account_name> yyyy/mm/dd [hh:mm:ss] -- Change the validify limit\n");
- ShowMessage(" timeset/ts <account_name> 0 -- Give a unlimited validity limit\n");
- ShowMessage(" unban/unbanish <account name> -- Remove the banishment of an account\n");
- ShowMessage(" unblock <account name> -- Set state 0 (Account ok) to an account\n");
- ShowMessage(" version -- Gives the version of the login-server\n");
- ShowMessage(" who <account name> -- Display all information of an account\n");
- ShowMessage(" who <account name> -- Display all information of an account\n");
- ShowMessage(" Note: To use spaces in an account name, type \"<account name>\" (or ').\n");
- }
-}
-
-//-----------------------------
-// Sub-function: add an account
-//-----------------------------
-int addaccount(char* param, int emailflag)
-{
- char name[1023], sex[1023], email[1023], password[1023];
-// int i;
- WFIFOHEAD(login_fd,91);
-
- memset(name, '\0', sizeof(name));
- memset(sex, '\0', sizeof(sex));
- memset(email, '\0', sizeof(email));
- memset(password, '\0', sizeof(password));
-
- if (emailflag == 0) { // add command
- if (sscanf(param, "\"%[^\"]\" %s %[^\r\n]", name, sex, password) < 2 && // password can be void
- sscanf(param, "'%[^']' %s %[^\r\n]", name, sex, password) < 2 && // password can be void
- sscanf(param, "%s %s %[^\r\n]", name, sex, password) < 2) { // password can be void
- ShowMessage("Please input an account name, a sex and a password.\n");
- ShowMessage("<example> add testname Male testpass\n");
- ladmin_log("Incomplete parameters to create an account ('add' command).\n");
- return 136;
- }
- strcpy(email, "a@a.com"); // default email
- } else { // 1: create command
- if (sscanf(param, "\"%[^\"]\" %s %s %[^\r\n]", name, sex, email, password) < 3 && // password can be void
- sscanf(param, "'%[^']' %s %s %[^\r\n]", name, sex, email, password) < 3 && // password can be void
- sscanf(param, "%s %s %s %[^\r\n]", name, sex, email, password) < 3) { // password can be void
- ShowMessage("Please input an account name, a sex and a password.\n");
- ShowMessage("<example> create testname Male my@mail.com testpass\n");
- ladmin_log("Incomplete parameters to create an account ('create' command).\n");
- return 136;
- }
- }
- if (verify_accountname(name) == 0) {
- return 102;
- }
-
- sex[0] = TOUPPER(sex[0]);
- if (strchr("MF", sex[0]) == NULL) {
- ShowMessage("Illegal gender [%s]. Please input M or F.\n", sex);
- ladmin_log("Illegal gender [%s]. Please input M or F.\n", sex);
- return 103;
- }
-
- if (strlen(email) < 3) {
- ShowMessage("Email is too short [%s]. Please input a valid e-mail.\n", email);
- ladmin_log("Email is too short [%s]. Please input a valid e-mail.\n", email);
- return 109;
- }
- if (strlen(email) > 39) {
- ShowMessage("Email is too long [%s]. Please input an e-mail with 39 bytes at the most.\n", email);
- ladmin_log("Email is too long [%s]. Please input an e-mail with 39 bytes at the most.\n", email);
- return 109;
- }
- if (e_mail_check(email) == 0) {
- ShowMessage("Invalid email [%s]. Please input a valid e-mail.\n", email);
- ladmin_log("Invalid email [%s]. Please input a valid e-mail.\n", email);
- return 109;
- }
-
- if (strlen(password) == 0) {
- if (typepasswd(password) == 0)
- return 108;
- }
- if (verify_password(password) == 0)
- return 104;
-
- ladmin_log("Request to login-server to create an account.\n");
-
- WFIFOW(login_fd,0) = 0x7930;
- memcpy(WFIFOP(login_fd,2), name, 24);
- memcpy(WFIFOP(login_fd,26), password, 24);
- WFIFOB(login_fd,50) = sex[0];
- memcpy(WFIFOP(login_fd,51), email, 40);
- WFIFOSET(login_fd,91);
- bytes_to_read = 1;
-
- return 0;
-}
-
-//---------------------------------------------------------------------------------
-// Sub-function: Add/substract time to the final date of a banishment of an account
-//---------------------------------------------------------------------------------
-int banaddaccount(char* param)
-{
- char name[1023], modif[1023];
- int year, month, day, hour, minute, second;
- char * p_modif;
- int value, i;
- WFIFOHEAD(login_fd,38);
-
- memset(name, '\0', sizeof(name));
- memset(modif, '\0', sizeof(modif));
- year = month = day = hour = minute = second = 0;
-
- if (sscanf(param, "\"%[^\"]\" %[^\r\n]", name, modif) < 2 &&
- sscanf(param, "'%[^']' %[^\r\n]", name, modif) < 2 &&
- sscanf(param, "%s %[^\r\n]", name, modif) < 2) {
- ShowMessage("Please input an account name and a modifier.\n");
- ShowMessage(" <example>: banadd testname +1m-2mn1s-6y\n");
- ShowMessage(" this example adds 1 month and 1 second, and substracts 2 minutes\n");
- ShowMessage(" and 6 years at the same time.\n");
- ladmin_log("Incomplete parameters to modify the ban date/time of an account ('banadd' command).\n");
- return 136;
- }
- if (verify_accountname(name) == 0) {
- return 102;
- }
-
- // lowercase for modif
- for (i = 0; modif[i]; i++)
- modif[i] = TOLOWER(modif[i]);
- p_modif = modif;
- while (strlen(p_modif) > 0) {
- value = atoi(p_modif);
- if (value == 0) {
- p_modif++;
- } else {
- if (p_modif[0] == '-' || p_modif[0] == '+')
- p_modif++;
- while (strlen(p_modif) > 0 && p_modif[0] >= '0' && p_modif[0] <= '9') {
- p_modif++;
- }
- if (p_modif[0] == 's') {
- second = value;
- p_modif++;
- } else if (p_modif[0] == 'm' && p_modif[1] == 'n') {
- minute = value;
- p_modif += 2;
- } else if (p_modif[0] == 'h') {
- hour = value;
- p_modif++;
- } else if (p_modif[0] == 'd' || p_modif[0] == 'j') {
- day = value;
- p_modif += 2;
- } else if (p_modif[0] == 'm') {
- month = value;
- p_modif++;
- } else if (p_modif[0] == 'y' || p_modif[0] == 'a') {
- year = value;
- p_modif++;
- } else {
- p_modif++;
- }
- }
- }
-
- ShowMessage(" year: %d\n", year);
- ShowMessage(" month: %d\n", month);
- ShowMessage(" day: %d\n", day);
- ShowMessage(" hour: %d\n", hour);
- ShowMessage(" minute: %d\n", minute);
- ShowMessage(" second: %d\n", second);
-
- if (year == 0 && month == 0 && day == 0 && hour == 0 && minute == 0 && second == 0) {
- ShowMessage("Please give an adjustment with this command:\n");
- ShowMessage(" Adjustment value (-1, 1, +1, etc...)\n");
- ShowMessage(" Modified element:\n");
- ShowMessage(" a or y: year\n");
- ShowMessage(" m: month\n");
- ShowMessage(" j or d: day\n");
- ShowMessage(" h: hour\n");
- ShowMessage(" mn: minute\n");
- ShowMessage(" s: second\n");
- ShowMessage(" <example> banadd testname +1m-2mn1s-6y\n");
- ShowMessage(" this example adds 1 month and 1 second, and substracts 2 minutes\n");
- ShowMessage(" and 6 years at the same time.\n");
- ladmin_log("No adjustment isn't an adjustment ('banadd' command).\n");
- return 137;
- }
- if (year > 127 || year < -127) {
- ShowMessage("Please give a correct adjustment for the years (from -127 to 127).\n");
- ladmin_log("Abnormal adjustment for the year ('banadd' command).\n");
- return 137;
- }
- if (month > 255 || month < -255) {
- ShowMessage("Please give a correct adjustment for the months (from -255 to 255).\n");
- ladmin_log("Abnormal adjustment for the month ('banadd' command).\n");
- return 137;
- }
- if (day > 32767 || day < -32767) {
- ShowMessage("Please give a correct adjustment for the days (from -32767 to 32767).\n");
- ladmin_log("Abnormal adjustment for the days ('banadd' command).\n");
- return 137;
- }
- if (hour > 32767 || hour < -32767) {
- ShowMessage("Please give a correct adjustment for the hours (from -32767 to 32767).\n");
- ladmin_log("Abnormal adjustment for the hours ('banadd' command).\n");
- return 137;
- }
- if (minute > 32767 || minute < -32767) {
- ShowMessage("Please give a correct adjustment for the minutes (from -32767 to 32767).\n");
- ladmin_log("Abnormal adjustment for the minutes ('banadd' command).\n");
- return 137;
- }
- if (second > 32767 || second < -32767) {
- ShowMessage("Please give a correct adjustment for the seconds (from -32767 to 32767).\n");
- ladmin_log("Abnormal adjustment for the seconds ('banadd' command).\n");
- return 137;
- }
-
- ladmin_log("Request to login-server to modify a ban date/time.\n");
-
- WFIFOW(login_fd,0) = 0x794c;
- memcpy(WFIFOP(login_fd,2), name, 24);
- WFIFOW(login_fd,26) = (short)year;
- WFIFOW(login_fd,28) = (short)month;
- WFIFOW(login_fd,30) = (short)day;
- WFIFOW(login_fd,32) = (short)hour;
- WFIFOW(login_fd,34) = (short)minute;
- WFIFOW(login_fd,36) = (short)second;
- WFIFOSET(login_fd,38);
- bytes_to_read = 1;
-
- return 0;
-}
-
-//-----------------------------------------------------------------------
-// Sub-function of sub-function banaccount, unbanaccount or bansetaccount
-// Set the final date of a banishment of an account
-//-----------------------------------------------------------------------
-int bansetaccountsub(char* name, char* date, char* time)
-{
- int year, month, day, hour, minute, second;
- time_t unban_time; // # of seconds 1/1/1970 (timestamp): ban time limit of the account (0 = no ban)
- struct tm *tmtime;
- WFIFOHEAD(login_fd,30);
-
- year = month = day = hour = minute = second = 0;
- unban_time = 0;
- tmtime = localtime(&unban_time); // initialize
-
- if (verify_accountname(name) == 0) {
- return 102;
- }
-
- if (atoi(date) != 0 &&
- ((sscanf(date, "%d/%d/%d", &year, &month, &day) < 3 &&
- sscanf(date, "%d-%d-%d", &year, &month, &day) < 3 &&
- sscanf(date, "%d.%d.%d", &year, &month, &day) < 3) ||
- sscanf(time, "%d:%d:%d", &hour, &minute, &second) < 3))
- {
- ShowMessage("Please input a date and a time (format: yyyy/mm/dd hh:mm:ss).\n");
- ShowMessage("You can imput 0 instead of if you use 'banset' command.\n");
- ladmin_log("Invalid format for the date/time ('banset' or 'ban' command).\n");
- return 102;
- }
-
- if (atoi(date) == 0) {
- unban_time = 0;
- } else {
- if (year < 70) {
- year = year + 100;
- }
- if (year >= 1900) {
- year = year - 1900;
- }
- if (month < 1 || month > 12) {
- ShowMessage("Please give a correct value for the month (from 1 to 12).\n");
- ladmin_log("Invalid month for the date ('banset' or 'ban' command).\n");
- return 102;
- }
- month = month - 1;
- if (day < 1 || day > 31) {
- ShowMessage("Please give a correct value for the day (from 1 to 31).\n");
- ladmin_log("Invalid day for the date ('banset' or 'ban' command).\n");
- return 102;
- }
- if (((month == 3 || month == 5 || month == 8 || month == 10) && day > 30) ||
- (month == 1 && day > 29)) {
- ShowMessage("Please give a correct value for a day of this month (%d).\n", month);
- ladmin_log("Invalid day for this month ('banset' or 'ban' command).\n");
- return 102;
- }
- if (hour < 0 || hour > 23) {
- ShowMessage("Please give a correct value for the hour (from 0 to 23).\n");
- ladmin_log("Invalid hour for the time ('banset' or 'ban' command).\n");
- return 102;
- }
- if (minute < 0 || minute > 59) {
- ShowMessage("Please give a correct value for the minutes (from 0 to 59).\n");
- ladmin_log("Invalid minute for the time ('banset' or 'ban' command).\n");
- return 102;
- }
- if (second < 0 || second > 59) {
- ShowMessage("Please give a correct value for the seconds (from 0 to 59).\n");
- ladmin_log("Invalid second for the time ('banset' or 'ban' command).\n");
- return 102;
- }
- tmtime->tm_year = year;
- tmtime->tm_mon = month;
- tmtime->tm_mday = day;
- tmtime->tm_hour = hour;
- tmtime->tm_min = minute;
- tmtime->tm_sec = second;
- tmtime->tm_isdst = -1; // -1: no winter/summer time modification
- unban_time = mktime(tmtime);
- if (unban_time == -1) {
- ShowMessage("Invalid date.\n");
- ShowMessage("Please input a date and a time (format: yyyy/mm/dd hh:mm:ss).\n");
- ShowMessage("You can imput 0 instead of if you use 'banset' command.\n");
- ladmin_log("Invalid date. ('banset' or 'ban' command).\n");
- return 102;
- }
- }
-
- ladmin_log("Request to login-server to set a ban.\n");
-
- WFIFOW(login_fd,0) = 0x794a;
- memcpy(WFIFOP(login_fd,2), name, 24);
- WFIFOL(login_fd,26) = (int)unban_time;
- WFIFOSET(login_fd,30);
- bytes_to_read = 1;
-
- return 0;
-}
-
-//---------------------------------------------------------------------
-// Sub-function: Set the final date of a banishment of an account (ban)
-//---------------------------------------------------------------------
-int banaccount(char* param)
-{
- char name[1023], date[1023], time[1023];
-
- memset(name, '\0', sizeof(name));
- memset(date, '\0', sizeof(date));
- memset(time, '\0', sizeof(time));
-
- if (sscanf(param, "%s %s \"%[^\"]\"", date, time, name) < 3 &&
- sscanf(param, "%s %s '%[^']'", date, time, name) < 3 &&
- sscanf(param, "%s %s %[^\r\n]", date, time, name) < 3) {
- ShowMessage("Please input an account name, a date and a hour.\n");
- ShowMessage("<example>: banset <account_name> yyyy/mm/dd [hh:mm:ss]\n");
- ShowMessage(" banset <account_name> 0 (0 = un-banished)\n");
- ShowMessage(" ban/banish yyyy/mm/dd hh:mm:ss <account name>\n");
- ShowMessage(" unban/unbanish <account name>\n");
- ShowMessage(" Default time [hh:mm:ss]: 23:59:59.\n");
- ladmin_log("Incomplete parameters to set a ban ('banset' or 'ban' command).\n");
- return 136;
- }
-
- return bansetaccountsub(name, date, time);
-}
-
-//------------------------------------------------------------------------
-// Sub-function: Set the final date of a banishment of an account (banset)
-//------------------------------------------------------------------------
-int bansetaccount(char* param)
-{
- char name[1023], date[1023], time[1023];
-
- memset(name, '\0', sizeof(name));
- memset(date, '\0', sizeof(date));
- memset(time, '\0', sizeof(time));
-
- if (sscanf(param, "\"%[^\"]\" %s %[^\r\n]", name, date, time) < 2 && // if date = 0, time can be void
- sscanf(param, "'%[^']' %s %[^\r\n]", name, date, time) < 2 && // if date = 0, time can be void
- sscanf(param, "%s %s %[^\r\n]", name, date, time) < 2) { // if date = 0, time can be void
- ShowMessage("Please input an account name, a date and a hour.\n");
- ShowMessage("<example>: banset <account_name> yyyy/mm/dd [hh:mm:ss]\n");
- ShowMessage(" banset <account_name> 0 (0 = un-banished)\n");
- ShowMessage(" ban/banish yyyy/mm/dd hh:mm:ss <account name>\n");
- ShowMessage(" unban/unbanish <account name>\n");
- ShowMessage(" Default time [hh:mm:ss]: 23:59:59.\n");
- ladmin_log("Incomplete parameters to set a ban ('banset' or 'ban' command).\n");
- return 136;
- }
-
- if (time[0] == '\0')
- strcpy(time, "23:59:59");
-
- return bansetaccountsub(name, date, time);
-}
-
-//-------------------------------------------------
-// Sub-function: unbanishment of an account (unban)
-//-------------------------------------------------
-int unbanaccount(char* param)
-{
- char name[1023];
-
- memset(name, '\0', sizeof(name));
-
- if (strlen(param) == 0 ||
- (sscanf(param, "\"%[^\"]\"", name) < 1 &&
- sscanf(param, "'%[^']'", name) < 1 &&
- sscanf(param, "%[^\r\n]", name) < 1) ||
- strlen(name) == 0)
- {
- ShowMessage("Please input an account name.\n");
- ShowMessage("<example>: banset <account_name> yyyy/mm/dd [hh:mm:ss]\n");
- ShowMessage(" banset <account_name> 0 (0 = un-banished)\n");
- ShowMessage(" ban/banish yyyy/mm/dd hh:mm:ss <account name>\n");
- ShowMessage(" unban/unbanish <account name>\n");
- ShowMessage(" Default time [hh:mm:ss]: 23:59:59.\n");
- ladmin_log("Incomplete parameters to set a ban ('unban' command).\n");
- return 136;
- }
-
- return bansetaccountsub(name, "0", "");
-}
-
-//---------------------------------------------------------
-// Sub-function: Asking to check the validity of a password
-// (Note: never send back a password with login-server!! security of passwords)
-//---------------------------------------------------------
-int checkaccount(char* param)
-{
- char name[1023], password[1023];
- WFIFOHEAD(login_fd,50);
-
- memset(name, '\0', sizeof(name));
- memset(password, '\0', sizeof(password));
-
- if (sscanf(param, "\"%[^\"]\" %[^\r\n]", name, password) < 1 && // password can be void
- sscanf(param, "'%[^']' %[^\r\n]", name, password) < 1 && // password can be void
- sscanf(param, "%s %[^\r\n]", name, password) < 1) { // password can be void
- ShowMessage("Please input an account name.\n");
- ShowMessage("<example> check testname password\n");
- ladmin_log("Incomplete parameters to check the password of an account ('check' command).\n");
- return 136;
- }
-
- if (verify_accountname(name) == 0) {
- return 102;
- }
-
- if (strlen(password) == 0) {
- if (typepasswd(password) == 0)
- return 134;
- }
- if (verify_password(password) == 0)
- return 131;
-
- ladmin_log("Request to login-server to check a password.\n");
-
- WFIFOW(login_fd,0) = 0x793a;
- memcpy(WFIFOP(login_fd,2), name, 24);
- memcpy(WFIFOP(login_fd,26), password, 24);
- WFIFOSET(login_fd,50);
- bytes_to_read = 1;
-
- return 0;
-}
-
-//------------------------------------------------
-// Sub-function: Asking for deletion of an account
-//------------------------------------------------
-int delaccount(char* param)
-{
- char name[1023];
- char letter;
- char confirm[1023];
- int i;
- WFIFOHEAD(login_fd,26);
-
- memset(name, '\0', sizeof(name));
-
- if (strlen(param) == 0 ||
- (sscanf(param, "\"%[^\"]\"", name) < 1 &&
- sscanf(param, "'%[^']'", name) < 1 &&
- sscanf(param, "%[^\r\n]", name) < 1) ||
- strlen(name) == 0)
- {
- ShowMessage("Please input an account name.\n");
- ShowMessage("<example> del testnametodelete\n");
- ladmin_log("No name given to delete an account ('delete' command).\n");
- return 136;
- }
-
- if (verify_accountname(name) == 0) {
- return 102;
- }
-
- memset(confirm, '\0', sizeof(confirm));
- while (confirm[0] != 'n' && confirm[0] != 'y')
- {
- ShowMessage("\033[1;36m ** Are you really sure to DELETE account [$userid]? (y/n) > \033[0m");
- fflush(stdout);
- memset(confirm, '\0', sizeof(confirm));
- i = 0;
- while ((letter = getchar()) != '\n')
- confirm[i++] = letter;
- }
-
- if (confirm[0] == 'n') {
- ShowMessage("Deletion canceled.\n");
- ladmin_log("Deletion canceled by user ('delete' command).\n");
- return 121;
- }
-
- ladmin_log("Request to login-server to delete an acount.\n");
-
- WFIFOW(login_fd,0) = 0x7932;
- memcpy(WFIFOP(login_fd,2), name, 24);
- WFIFOSET(login_fd,26);
- bytes_to_read = 1;
-
- return 0;
-}
-
-//----------------------------------------------------------
-// Sub-function: Asking to modification of an account e-mail
-//----------------------------------------------------------
-int changeemail(char* param)
-{
- char name[1023], email[1023];
- WFIFOHEAD(login_fd,66);
-
- memset(name, '\0', sizeof(name));
- memset(email, '\0', sizeof(email));
-
- if (sscanf(param, "\"%[^\"]\" %[^\r\n]", name, email) < 2 &&
- sscanf(param, "'%[^']' %[^\r\n]", name, email) < 2 &&
- sscanf(param, "%s %[^\r\n]", name, email) < 2) {
- ShowMessage("Please input an account name and an email.\n");
- ShowMessage("<example> email testname newemail\n");
- ladmin_log("Incomplete parameters to change the email of an account ('email' command).\n");
- return 136;
- }
-
- if (verify_accountname(name) == 0) {
- return 102;
- }
-
- if (strlen(email) < 3) {
- ShowMessage("Email is too short [%s]. Please input a valid e-mail.\n", email);
- ladmin_log("Email is too short [%s]. Please input a valid e-mail.\n", email);
- return 109;
- }
- if (strlen(email) > 39) {
- ShowMessage("Email is too long [%s]. Please input an e-mail with 39 bytes at the most.\n", email);
- ladmin_log("Email is too long [%s]. Please input an e-mail with 39 bytes at the most.\n", email);
- return 109;
- }
- if (e_mail_check(email) == 0) {
- ShowMessage("Invalid email [%s]. Please input a valid e-mail.\n", email);
- ladmin_log("Invalid email [%s]. Please input a valid e-mail.\n", email);
- return 109;
- }
-
- ladmin_log("Request to login-server to change an email.\n");
-
- WFIFOW(login_fd,0) = 0x7940;
- memcpy(WFIFOP(login_fd,2), name, 24);
- memcpy(WFIFOP(login_fd,26), email, 40);
- WFIFOSET(login_fd,66);
- bytes_to_read = 1;
-
- return 0;
-}
-
-//-----------------------------------------------------
-// Sub-function: Asking of the number of online players
-//-----------------------------------------------------
-int getlogincount(void)
-{
- WFIFOHEAD(login_fd,2);
- ladmin_log("Request to login-server to obtain the # of online players.\n");
-
- WFIFOW(login_fd,0) = 0x7938;
- WFIFOSET(login_fd,2);
- bytes_to_read = 1;
-
- return 0;
-}
-
-//----------------------------------------------------------
-// Sub-function: Asking to modify the GM level of an account
-//----------------------------------------------------------
-int changegmlevel(char* param)
-{
- char name[1023];
- int GM_level;
- WFIFOHEAD(login_fd,27);
-
- memset(name, '\0', sizeof(name));
- GM_level = 0;
-
- if (sscanf(param, "\"%[^\"]\" %d", name, &GM_level) < 1 &&
- sscanf(param, "'%[^']' %d", name, &GM_level) < 1 &&
- sscanf(param, "%s %d", name, &GM_level) < 1) {
- ShowMessage("Please input an account name and a GM level.\n");
- ShowMessage("<example> gm testname 80\n");
- ladmin_log("Incomplete parameters to change the GM level of an account ('gm' command).\n");
- return 136;
- }
-
- if (verify_accountname(name) == 0) {
- return 102;
- }
-
- if (GM_level < 0 || GM_level > 99) {
- ShowMessage("Illegal GM level [%d]. Please input a value from 0 to 99.\n", GM_level);
- ladmin_log("Illegal GM level [%d]. The value can be from 0 to 99.\n", GM_level);
- return 103;
- }
-
- ladmin_log("Request to login-server to change a GM level.\n");
-
- WFIFOW(login_fd,0) = 0x793e;
- memcpy(WFIFOP(login_fd,2), name, 24);
- WFIFOB(login_fd,26) = GM_level;
- WFIFOSET(login_fd,27);
- bytes_to_read = 1;
-
- return 0;
-}
-
-//---------------------------------------------
-// Sub-function: Asking to obtain an account id
-//---------------------------------------------
-int idaccount(char* param)
-{
- char name[1023];
- WFIFOHEAD(login_fd,26);
-
- memset(name, '\0', sizeof(name));
-
- if (strlen(param) == 0 ||
- (sscanf(param, "\"%[^\"]\"", name) < 1 &&
- sscanf(param, "'%[^']'", name) < 1 &&
- sscanf(param, "%[^\r\n]", name) < 1) ||
- strlen(name) == 0)
- {
- ShowMessage("Please input an account name.\n");
- ShowMessage("<example> id testname\n");
- ladmin_log("No name given to search an account id ('id' command).\n");
- return 136;
- }
-
- if (verify_accountname(name) == 0) {
- return 102;
- }
-
- ladmin_log("Request to login-server to know an account id.\n");
-
- WFIFOW(login_fd,0) = 0x7944;
- memcpy(WFIFOP(login_fd,2), name, 24);
- WFIFOSET(login_fd,26);
- bytes_to_read = 1;
-
- return 0;
-}
-
-//----------------------------------------------------------------------------
-// Sub-function: Asking to displaying information about an account (by its id)
-//----------------------------------------------------------------------------
-int infoaccount(int account_id)
-{
- WFIFOHEAD(login_fd,6);
- if (account_id < 0) {
- ShowMessage("Please input a positive value for the id.\n");
- ladmin_log("Negative value was given to found the account.\n");
- return 136;
- }
-
- ladmin_log("Request to login-server to obtain information about an account (by its id).\n");
-
- WFIFOW(login_fd,0) = 0x7954;
- WFIFOL(login_fd,2) = account_id;
- WFIFOSET(login_fd,6);
- bytes_to_read = 1;
-
- return 0;
-}
-
-//---------------------------------------
-// Sub-function: Send a broadcast message
-//---------------------------------------
-int sendbroadcast(short type, char* message)
-{
- int len = strlen(message);
- WFIFOHEAD(login_fd,9+len);
- if (len == 0) {
- ShowMessage("Please input a message.\n");
- if (type == 0) {
- ShowMessage("<example> kami a message\n");
- } else {
- ShowMessage("<example> kamib a message\n");
- }
- ladmin_log("The message is void ('kami(b)' command).\n");
- return 136;
- }
- len++; //+'\0'
- WFIFOW(login_fd,0) = 0x794e;
- WFIFOW(login_fd,2) = type;
- WFIFOL(login_fd,4) = len;
- memcpy(WFIFOP(login_fd,8), message, len);
- WFIFOSET(login_fd,8+len);
- bytes_to_read = 1;
-
- return 0;
-}
-
-//--------------------------------------------------------
-// Sub-function: Asking to Displaying of the accounts list
-//--------------------------------------------------------
-int listaccount(char* param, int type)
-{
-//int list_first, list_last, list_type; // parameter to display a list of accounts
- int i;
- WFIFOHEAD(login_fd,10);
-
- list_type = type;
-
- // set default values
- list_first = 0;
- list_last = 0;
-
- if (list_type == 1) { // if listgm
- // get all accounts = use default
- } else if (list_type == 2) { // if search
- for (i = 0; param[i]; i++)
- param[i] = TOLOWER(param[i]);
- // get all accounts = use default
- } else if (list_type == 3) { // if listban
- // get all accounts = use default
- } else if (list_type == 4) { // if listok
- // get all accounts = use default
- } else { // if list (list_type == 0)
- switch(sscanf(param, "%d %d", &list_first, &list_last)) {
- case 0:
- // get all accounts = use default
- break;
- case 1:
- list_last = 0;
- // use tests of the following value
- default:
- if (list_first < 0)
- list_first = 0;
- if (list_last < list_first || list_last < 0)
- list_last = 0;
- break;
- }
- }
-
- ladmin_log("Request to login-server to obtain the list of accounts from %d to %d.\n", list_first, list_last);
-
- WFIFOW(login_fd,0) = 0x7920;
- WFIFOL(login_fd,2) = list_first;
- WFIFOL(login_fd,6) = list_last;
- WFIFOSET(login_fd,10);
- bytes_to_read = 1;
-
- // 0123456789 01 01234567890123456789012301234 012345 0123456789012345678901234567
- ShowMessage("account_id GM user_name sex count state\n");
- ShowMessage("-------------------------------------------------------------------------------\n");
- list_count = 0;
-
- return 0;
-}
-
-//--------------------------------------------
-// Sub-function: Asking to modify a memo field
-//--------------------------------------------
-int changememo(char* param)
-{
- char name[1023], memo[1023];
- WFIFOHEAD(login_fd,28+255);
-
- memset(name, '\0', sizeof(name));
- memset(memo, '\0', sizeof(memo));
-
- if (sscanf(param, "\"%[^\"]\" %[^\r\n]", name, memo) < 1 && // memo can be void
- sscanf(param, "'%[^']' %[^\r\n]", name, memo) < 1 && // memo can be void
- sscanf(param, "%s %[^\r\n]", name, memo) < 1) { // memo can be void
- ShowMessage("Please input an account name and a memo.\n");
- ShowMessage("<example> memo testname new memo\n");
- ladmin_log("Incomplete parameters to change the memo of an account ('email' command).\n");
- return 136;
- }
-
- if (verify_accountname(name) == 0) {
- return 102;
- }
-
- if (strlen(memo) > 254) {
- ShowMessage("Memo is too long (%lu characters).\n", (unsigned long)strlen(memo));
- ShowMessage("Please input a memo of 254 bytes at the maximum.\n");
- ladmin_log("Email is too long (%d characters). Please input a memo of 254 bytes at the maximum.\n", strlen(memo));
- return 102;
- }
-
- ladmin_log("Request to login-server to change a memo.\n");
-
- WFIFOW(login_fd,0) = 0x7942;
- memcpy(WFIFOP(login_fd,2), name, 24);
- WFIFOW(login_fd,26) = strlen(memo);
- if (strlen(memo) > 0)
- memcpy(WFIFOP(login_fd,28), memo, strlen(memo));
- WFIFOSET(login_fd,28+strlen(memo));
- bytes_to_read = 1;
-
- return 0;
-}
-
-//-----------------------------------------------
-// Sub-function: Asking to obtain an account name
-//-----------------------------------------------
-int nameaccount(int id)
-{
- WFIFOHEAD(login_fd,6);
- if (id < 0) {
- ShowMessage("Please input a positive value for the id.\n");
- ladmin_log("Negativ id given to search an account name ('name' command).\n");
- return 136;
- }
-
- ladmin_log("Request to login-server to know an account name.\n");
-
- WFIFOW(login_fd,0) = 0x7946;
- WFIFOL(login_fd,2) = id;
- WFIFOSET(login_fd,6);
- bytes_to_read = 1;
-
- return 0;
-}
-
-//------------------------------------------
-// Sub-function: Asking to modify a password
-// (Note: never send back a password with login-server!! security of passwords)
-//------------------------------------------
-int changepasswd(char* param)
-{
- char name[1023], password[1023];
- WFIFOHEAD(login_fd,50);
-
- memset(name, '\0', sizeof(name));
- memset(password, '\0', sizeof(password));
-
- if (sscanf(param, "\"%[^\"]\" %[^\r\n]", name, password) < 1 &&
- sscanf(param, "'%[^']' %[^\r\n]", name, password) < 1 &&
- sscanf(param, "%s %[^\r\n]", name, password) < 1) {
- ShowMessage("Please input an account name.\n");
- ShowMessage("<example> passwd testname newpassword\n");
- ladmin_log("Incomplete parameters to change the password of an account ('password' command).\n");
- return 136;
- }
-
- if (verify_accountname(name) == 0) {
- return 102;
- }
-
- if (strlen(password) == 0) {
- if (typepasswd(password) == 0)
- return 134;
- }
- if (verify_password(password) == 0)
- return 131;
-
- ladmin_log("Request to login-server to change a password.\n");
-
- WFIFOW(login_fd,0) = 0x7934;
- memcpy(WFIFOP(login_fd,2), name, 24);
- memcpy(WFIFOP(login_fd,26), password, 24);
- WFIFOSET(login_fd,50);
- bytes_to_read = 1;
-
- return 0;
-}
-
-//----------------------------------------------------------------------
-// Sub-function: Request to login-server to reload GM configuration file
-// this function have no answer
-//----------------------------------------------------------------------
-int reloadGM(void)
-{
- WFIFOHEAD(login_fd,2);
- WFIFOW(login_fd,0) = 0x7955;
- WFIFOSET(login_fd,2);
- bytes_to_read = 0;
-
- ladmin_log("Request to reload the GM configuration file sended.\n");
- ShowMessage("Request to reload the GM configuration file sended.\n");
- ShowMessage("Check the actual GM accounts (after reloading):\n");
- listaccount(parameters, 1); // 1: to list only GM
-
- return 180;
-}
-
-//-----------------------------------------------------
-// Sub-function: Asking to modify the sex of an account
-//-----------------------------------------------------
-int changesex(char* param)
-{
- char name[1023], sex[1023];
- WFIFOHEAD(login_fd,27);
-
- memset(name, '\0', sizeof(name));
- memset(sex, '\0', sizeof(sex));
-
- if (sscanf(param, "\"%[^\"]\" %[^\r\n]", name, sex) < 2 &&
- sscanf(param, "'%[^']' %[^\r\n]", name, sex) < 2 &&
- sscanf(param, "%s %[^\r\n]", name, sex) < 2) {
- ShowMessage("Please input an account name and a sex.\n");
- ShowMessage("<example> sex testname Male\n");
- ladmin_log("Incomplete parameters to change the sex of an account ('sex' command).\n");
- return 136;
- }
-
- if (verify_accountname(name) == 0) {
- return 102;
- }
-
- sex[0] = TOUPPER(sex[0]);
- if (strchr("MF", sex[0]) == NULL) {
- ShowMessage("Illegal gender [%s]. Please input M or F.\n", sex);
- ladmin_log("Illegal gender [%s]. Please input M or F.\n", sex);
- return 103;
- }
-
- ladmin_log("Request to login-server to change a sex.\n");
-
- WFIFOW(login_fd,0) = 0x793c;
- memcpy(WFIFOP(login_fd,2), name, 24);
- WFIFOB(login_fd,26) = sex[0];
- WFIFOSET(login_fd,27);
- bytes_to_read = 1;
-
- return 0;
-}
-
-//-------------------------------------------------------------------------
-// Sub-function of sub-function changestate, blockaccount or unblockaccount
-// Asking to modify the state of an account
-//-------------------------------------------------------------------------
-int changestatesub(char* name, int state, char* error_message7)
-{
- char error_message[1023]; // need to use, because we can modify error_message7
- WFIFOHEAD(login_fd,50);
-
- memset(error_message, '\0', sizeof(error_message));
- strncpy(error_message, error_message7, sizeof(error_message)-1);
-
- if ((state < 0 || state > 9) && state != 100) { // Valid values: 0: ok, or value of the 0x006a packet + 1
- ShowMessage("Please input one of these states:\n");
- ShowMessage(" 0 = Account ok 6 = Your Game's EXE file is not the latest version\n");
- ShowMessage(" 1 = Unregistered ID 7 = You are Prohibited to log in until + message\n");
- ShowMessage(" 2 = Incorrect Password 8 = Server is jammed due to over populated\n");
- ShowMessage(" 3 = This ID is expired 9 = No MSG\n");
- ShowMessage(" 4 = Rejected from Server 100 = This ID has been totally erased\n");
- ShowMessage(" 5 = You have been blocked by the GM Team\n");
- ShowMessage("<examples> state testname 5\n");
- ShowMessage(" state testname 7 end of your ban\n");
- ShowMessage(" block <account name>\n");
- ShowMessage(" unblock <account name>\n");
- ladmin_log("Invalid value for the state of an account ('state', 'block' or 'unblock' command).\n");
- return 151;
- }
-
- if (verify_accountname(name) == 0) {
- return 102;
- }
-
- if (state != 7) {
- strcpy(error_message, "-");
- } else {
- if (strlen(error_message) < 1) {
- ShowMessage("Error message is too short. Please input a message of 1-19 bytes.\n");
- ladmin_log("Error message is too short. Please input a message of 1-19 bytes.\n");
- return 102;
- }
- if (strlen(error_message) > 19) {
- ShowMessage("Error message is too long. Please input a message of 1-19 bytes.\n");
- ladmin_log("Error message is too long. Please input a message of 1-19 bytes.\n");
- return 102;
- }
- }
-
- ladmin_log("Request to login-server to change a state.\n");
-
- WFIFOW(login_fd,0) = 0x7936;
- memcpy(WFIFOP(login_fd,2), name, 24);
- WFIFOL(login_fd,26) = state;
- memcpy(WFIFOP(login_fd,30), error_message, 20);
- WFIFOSET(login_fd,50);
- bytes_to_read = 1;
-
- return 0;
-}
-
-//-------------------------------------------------------
-// Sub-function: Asking to modify the state of an account
-//-------------------------------------------------------
-int changestate(char* param)
-{
- char name[1023], error_message[1023];
- int state;
-
- memset(name, '\0', sizeof(name));
- memset(error_message, '\0', sizeof(error_message));
-
- if (sscanf(param, "\"%[^\"]\" %d %[^\r\n]", name, &state, error_message) < 2 &&
- sscanf(param, "'%[^']' %d %[^\r\n]", name, &state, error_message) < 2 &&
- sscanf(param, "%s %d %[^\r\n]", name, &state, error_message) < 2) {
- ShowMessage("Please input an account name and a state.\n");
- ShowMessage("<examples> state testname 5\n");
- ShowMessage(" state testname 7 end of your ban\n");
- ShowMessage(" block <account name>\n");
- ShowMessage(" unblock <account name>\n");
- ladmin_log("Incomplete parameters to change the state of an account ('state' command).\n");
- return 136;
- }
-
- return changestatesub(name, state, error_message);
-}
-
-//-------------------------------------------
-// Sub-function: Asking to unblock an account
-//-------------------------------------------
-int unblockaccount(char* param)
-{
- char name[1023];
-
- memset(name, '\0', sizeof(name));
-
- if (strlen(param) == 0 ||
- (sscanf(param, "\"%[^\"]\"", name) < 1 &&
- sscanf(param, "'%[^']'", name) < 1 &&
- sscanf(param, "%[^\r\n]", name) < 1) ||
- strlen(name) == 0)
- {
- ShowMessage("Please input an account name.\n");
- ShowMessage("<examples> state testname 5\n");
- ShowMessage(" state testname 7 end of your ban\n");
- ShowMessage(" block <account name>\n");
- ShowMessage(" unblock <account name>\n");
- ladmin_log("Incomplete parameters to change the state of an account ('unblock' command).\n");
- return 136;
- }
-
- return changestatesub(name, 0, "-"); // state 0, no error message
-}
-
-//-------------------------------------------
-// Sub-function: Asking to unblock an account
-//-------------------------------------------
-int blockaccount(char* param)
-{
- char name[1023];
-
- memset(name, '\0', sizeof(name));
-
- if (strlen(param) == 0 ||
- (sscanf(param, "\"%[^\"]\"", name) < 1 &&
- sscanf(param, "'%[^']'", name) < 1 &&
- sscanf(param, "%[^\r\n]", name) < 1) ||
- strlen(name) == 0)
- {
- ShowMessage("Please input an account name.\n");
- ShowMessage("<examples> state testname 5\n");
- ShowMessage(" state testname 7 end of your ban\n");
- ShowMessage(" block <account name>\n");
- ShowMessage(" unblock <account name>\n");
- ladmin_log("Incomplete parameters to change the state of an account ('block' command).\n");
- return 136;
- }
-
- return changestatesub(name, 5, "-"); // state 5, no error message
-}
-
-//---------------------------------------------------------------------
-// Sub-function: Add/substract time to the validity limit of an account
-//---------------------------------------------------------------------
-int timeaddaccount(char* param)
-{
- char name[1023], modif[1023];
- int year, month, day, hour, minute, second;
- char * p_modif;
- int value, i;
- WFIFOHEAD(login_fd,38);
-
- memset(name, '\0', sizeof(name));
- memset(modif, '\0', sizeof(modif));
- year = month = day = hour = minute = second = 0;
-
- if (sscanf(param, "\"%[^\"]\" %[^\r\n]", name, modif) < 2 &&
- sscanf(param, "'%[^']' %[^\r\n]", name, modif) < 2 &&
- sscanf(param, "%s %[^\r\n]", name, modif) < 2)
- {
- ShowMessage("Please input an account name and a modifier.\n");
- ShowMessage(" <example>: timeadd testname +1m-2mn1s-6y\n");
- ShowMessage(" this example adds 1 month and 1 second, and substracts 2 minutes\n");
- ShowMessage(" and 6 years at the same time.\n");
- ladmin_log("Incomplete parameters to modify a limit time ('timeadd' command).\n");
- return 136;
- }
- if (verify_accountname(name) == 0) {
- return 102;
- }
-
- // lowercase for modif
- for (i = 0; modif[i]; i++)
- modif[i] = TOLOWER(modif[i]);
- p_modif = modif;
- while (strlen(p_modif) > 0) {
- value = atoi(p_modif);
- if (value == 0) {
- p_modif++;
- } else {
- if (p_modif[0] == '-' || p_modif[0] == '+')
- p_modif++;
- while (strlen(p_modif) > 0 && p_modif[0] >= '0' && p_modif[0] <= '9') {
- p_modif++;
- }
- if (p_modif[0] == 's') {
- second = value;
- p_modif++;
- } else if (p_modif[0] == 'm' && p_modif[1] == 'n') {
- minute = value;
- p_modif += 2;
- } else if (p_modif[0] == 'h') {
- hour = value;
- p_modif++;
- } else if (p_modif[0] == 'd' || p_modif[0] == 'j') {
- day = value;
- p_modif += 2;
- } else if (p_modif[0] == 'm') {
- month = value;
- p_modif++;
- } else if (p_modif[0] == 'y' || p_modif[0] == 'a') {
- year = value;
- p_modif++;
- } else {
- p_modif++;
- }
- }
- }
-
- ShowMessage(" year: %d\n", year);
- ShowMessage(" month: %d\n", month);
- ShowMessage(" day: %d\n", day);
- ShowMessage(" hour: %d\n", hour);
- ShowMessage(" minute: %d\n", minute);
- ShowMessage(" second: %d\n", second);
-
- if (year == 0 && month == 0 && day == 0 && hour == 0 && minute == 0 && second == 0) {
- ShowMessage("Please give an adjustment with this command:\n");
- ShowMessage(" Adjustment value (-1, 1, +1, etc...)\n");
- ShowMessage(" Modified element:\n");
- ShowMessage(" a or y: year\n");
- ShowMessage(" m: month\n");
- ShowMessage(" j or d: day\n");
- ShowMessage(" h: hour\n");
- ShowMessage(" mn: minute\n");
- ShowMessage(" s: second\n");
- ShowMessage(" <example> timeadd testname +1m-2mn1s-6y\n");
- ShowMessage(" this example adds 1 month and 1 second, and substracts 2 minutes\n");
- ShowMessage(" and 6 years at the same time.\n");
- ladmin_log("No adjustment isn't an adjustment ('timeadd' command).\n");
- return 137;
- }
- if (year > 127 || year < -127) {
- ShowMessage("Please give a correct adjustment for the years (from -127 to 127).\n");
- ladmin_log("Abnormal adjustment for the year ('timeadd' command).\n");
- return 137;
- }
- if (month > 255 || month < -255) {
- ShowMessage("Please give a correct adjustment for the months (from -255 to 255).\n");
- ladmin_log("Abnormal adjustment for the month ('timeadd' command).\n");
- return 137;
- }
- if (day > 32767 || day < -32767) {
- ShowMessage("Please give a correct adjustment for the days (from -32767 to 32767).\n");
- ladmin_log("Abnormal adjustment for the days ('timeadd' command).\n");
- return 137;
- }
- if (hour > 32767 || hour < -32767) {
- ShowMessage("Please give a correct adjustment for the hours (from -32767 to 32767).\n");
- ladmin_log("Abnormal adjustment for the hours ('timeadd' command).\n");
- return 137;
- }
- if (minute > 32767 || minute < -32767) {
- ShowMessage("Please give a correct adjustment for the minutes (from -32767 to 32767).\n");
- ladmin_log("Abnormal adjustment for the minutes ('timeadd' command).\n");
- return 137;
- }
- if (second > 32767 || second < -32767) {
- ShowMessage("Please give a correct adjustment for the seconds (from -32767 to 32767).\n");
- ladmin_log("Abnormal adjustment for the seconds ('timeadd' command).\n");
- return 137;
- }
-
- ladmin_log("Request to login-server to modify a time limit.\n");
-
- WFIFOW(login_fd,0) = 0x7950;
- memcpy(WFIFOP(login_fd,2), name, 24);
- WFIFOW(login_fd,26) = (short)year;
- WFIFOW(login_fd,28) = (short)month;
- WFIFOW(login_fd,30) = (short)day;
- WFIFOW(login_fd,32) = (short)hour;
- WFIFOW(login_fd,34) = (short)minute;
- WFIFOW(login_fd,36) = (short)second;
- WFIFOSET(login_fd,38);
- bytes_to_read = 1;
-
- return 0;
-}
-
-//-------------------------------------------------
-// Sub-function: Set a validity limit of an account
-//-------------------------------------------------
-int timesetaccount(char* param)
-{
- char name[1023], date[1023], time[1023];
- int year, month, day, hour, minute, second;
- time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
- struct tm *tmtime;
- WFIFOHEAD(login_fd,30);
-
- memset(name, '\0', sizeof(name));
- memset(date, '\0', sizeof(date));
- memset(time, '\0', sizeof(time));
- year = month = day = hour = minute = second = 0;
- expiration_time = 0;
- tmtime = localtime(&expiration_time); // initialize
-
- if (sscanf(param, "\"%[^\"]\" %s %[^\r\n]", name, date, time) < 2 && // if date = 0, time can be void
- sscanf(param, "'%[^']' %s %[^\r\n]", name, date, time) < 2 && // if date = 0, time can be void
- sscanf(param, "%s %s %[^\r\n]", name, date, time) < 2) { // if date = 0, time can be void
- ShowMessage("Please input an account name, a date and a hour.\n");
- ShowMessage("<example>: timeset <account_name> yyyy/mm/dd [hh:mm:ss]\n");
- ShowMessage(" timeset <account_name> 0 (0 = unlimited)\n");
- ShowMessage(" Default time [hh:mm:ss]: 23:59:59.\n");
- ladmin_log("Incomplete parameters to set a limit time ('timeset' command).\n");
- return 136;
- }
- if (verify_accountname(name) == 0) {
- return 102;
- }
-
- if (time[0] == '\0')
- strcpy(time, "23:59:59");
-
- if (atoi(date) != 0 &&
- ((sscanf(date, "%d/%d/%d", &year, &month, &day) < 3 &&
- sscanf(date, "%d-%d-%d", &year, &month, &day) < 3 &&
- sscanf(date, "%d.%d.%d", &year, &month, &day) < 3 &&
- sscanf(date, "%d'%d'%d", &year, &month, &day) < 3) ||
- sscanf(time, "%d:%d:%d", &hour, &minute, &second) < 3))
- {
- ShowMessage("Please input 0 or a date and a time (format: 0 or yyyy/mm/dd hh:mm:ss).\n");
- ladmin_log("Invalid format for the date/time ('timeset' command).\n");
- return 102;
- }
-
- if (atoi(date) == 0) {
- expiration_time = 0;
- } else {
- if (year < 70) {
- year = year + 100;
- }
- if (year >= 1900) {
- year = year - 1900;
- }
- if (month < 1 || month > 12) {
- ShowMessage("Please give a correct value for the month (from 1 to 12).\n");
- ladmin_log("Invalid month for the date ('timeset' command).\n");
- return 102;
- }
- month = month - 1;
- if (day < 1 || day > 31) {
- ShowMessage("Please give a correct value for the day (from 1 to 31).\n");
- ladmin_log("Invalid day for the date ('timeset' command).\n");
- return 102;
- }
- if (((month == 3 || month == 5 || month == 8 || month == 10) && day > 30) ||
- (month == 1 && day > 29)) {
- ShowMessage("Please give a correct value for a day of this month (%d).\n", month);
- ladmin_log("Invalid day for this month ('timeset' command).\n");
- return 102;
- }
- if (hour < 0 || hour > 23) {
- ShowMessage("Please give a correct value for the hour (from 0 to 23).\n");
- ladmin_log("Invalid hour for the time ('timeset' command).\n");
- return 102;
- }
- if (minute < 0 || minute > 59) {
- ShowMessage("Please give a correct value for the minutes (from 0 to 59).\n");
- ladmin_log("Invalid minute for the time ('timeset' command).\n");
- return 102;
- }
- if (second < 0 || second > 59) {
- ShowMessage("Please give a correct value for the seconds (from 0 to 59).\n");
- ladmin_log("Invalid second for the time ('timeset' command).\n");
- return 102;
- }
- tmtime->tm_year = year;
- tmtime->tm_mon = month;
- tmtime->tm_mday = day;
- tmtime->tm_hour = hour;
- tmtime->tm_min = minute;
- tmtime->tm_sec = second;
- tmtime->tm_isdst = -1; // -1: no winter/summer time modification
- expiration_time = mktime(tmtime);
- if (expiration_time == -1) {
- ShowMessage("Invalid date.\n");
- ShowMessage("Please add 0 or a date and a time (format: 0 or yyyy/mm/dd hh:mm:ss).\n");
- ladmin_log("Invalid date. ('timeset' command).\n");
- return 102;
- }
- }
-
- ladmin_log("Request to login-server to set a time limit.\n");
-
- WFIFOW(login_fd,0) = 0x7948;
- memcpy(WFIFOP(login_fd,2), name, 24);
- WFIFOL(login_fd,26) = (int)expiration_time;
- WFIFOSET(login_fd,30);
- bytes_to_read = 1;
-
- return 0;
-}
-
-//------------------------------------------------------------------------------
-// Sub-function: Asking to displaying information about an account (by its name)
-//------------------------------------------------------------------------------
-int whoaccount(char* param)
-{
- char name[1023];
- WFIFOHEAD(login_fd,26);
-
- memset(name, '\0', sizeof(name));
-
- if (strlen(param) == 0 ||
- (sscanf(param, "\"%[^\"]\"", name) < 1 &&
- sscanf(param, "'%[^']'", name) < 1 &&
- sscanf(param, "%[^\r\n]", name) < 1) ||
- strlen(name) == 0)
- {
- ShowMessage("Please input an account name.\n");
- ShowMessage("<example> who testname\n");
- ladmin_log("No name was given to found the account.\n");
- return 136;
- }
- if (verify_accountname(name) == 0) {
- return 102;
- }
-
- ladmin_log("Request to login-server to obtain information about an account (by its name).\n");
-
- WFIFOW(login_fd,0) = 0x7952;
- memcpy(WFIFOP(login_fd,2), name, 24);
- WFIFOSET(login_fd,26);
- bytes_to_read = 1;
-
- return 0;
-}
-
-//--------------------------------------------------------
-// Sub-function: Asking of the version of the login-server
-//--------------------------------------------------------
-int checkloginversion(void)
-{
- WFIFOHEAD(login_fd,2);
- ladmin_log("Request to login-server to obtain its version.\n");
-
- WFIFOW(login_fd,0) = 0x7530;
- WFIFOSET(login_fd,2);
- bytes_to_read = 1;
-
- return 0;
-}
-
-//---------------------------------------------
-// Prompt function
-// this function wait until user type a command
-// and analyse the command.
-//---------------------------------------------
-int prompt(void)
-{
- int i, j;
- char buf[1024];
- char *p;
-
- // while we don't wait new packets
- while (bytes_to_read == 0) {
- // for help with the console colors look here:
- // http://www.edoceo.com/liberum/?doc=printf-with-color
- // some code explanation (used here):
- // \033[2J : clear screen and go up/left (0, 0 position)
- // \033[K : clear line from actual position to end of the line
- // \033[0m : reset color parameter
- // \033[1m : use bold for font
- ShowMessage("\n");
- ShowMessage("\033[32mTo list the commands, type 'enter'.\033[0m\n");
- ShowMessage("\033[0;36mLadmin-> \033[0m");
- ShowMessage("\033[1m");
- fflush(stdout);
-
- // get command and parameter
- memset(buf, '\0', sizeof(buf));
- fflush(stdin);
- fgets(buf, sizeof(buf), stdin);
-
- ShowMessage("\033[0m");
- fflush(stdout);
-
- // remove final \n
- if((p = strrchr(buf, '\n')) != NULL)
- p[0] = '\0';
- // remove all control char
- for (i = 0; buf[i]; i++)
- if (buf[i] < 32) {
- // remove cursor control.
- if (buf[i] == 27 && buf[i+1] == '[' &&
- (buf[i+2] == 'H' || // home position (cursor)
- buf[i+2] == 'J' || // clear screen
- buf[i+2] == 'A' || // up 1 line
- buf[i+2] == 'B' || // down 1 line
- buf[i+2] == 'C' || // right 1 position
- buf[i+2] == 'D' || // left 1 position
- buf[i+2] == 'G')) { // center cursor (windows)
- for (j = i; buf[j]; j++)
- buf[j] = buf[j+3];
- } else if (buf[i] == 27 && buf[i+1] == '[' && buf[i+2] == '2' && buf[i+3] == 'J') { // clear screen
- for (j = i; buf[j]; j++)
- buf[j] = buf[j+4];
- } else if (buf[i] == 27 && buf[i+1] == '[' && buf[i+3] == '~' &&
- (buf[i+2] == '1' || // home (windows)
- buf[i+2] == '2' || // insert (windows)
- buf[i+2] == '3' || // del (windows)
- buf[i+2] == '4' || // end (windows)
- buf[i+2] == '5' || // pgup (windows)
- buf[i+2] == '6')) { // pgdown (windows)
- for (j = i; buf[j]; j++)
- buf[j] = buf[j+4];
- } else {
- // remove other control char.
- for (j = i; buf[j]; j++)
- buf[j] = buf[j+1];
- }
- i--;
- }
-
- // extract command name and parameters
- memset(command, '\0', sizeof(command));
- memset(parameters, '\0', sizeof(parameters));
- sscanf(buf, "%1023s %[^\n]", command, parameters);
- command[1023] = '\0';
- parameters[1023] = '\0';
-
- // lowercase for command line
- for (i = 0; command[i]; i++)
- command[i] = TOLOWER(command[i]);
-
- if (command[0] == '?' || strlen(command) == 0) {
- strcpy(buf, "help");
- strcpy(command, "help");
- }
-
- // Analyse of the command
- check_command(command); // give complete name to the command
-
- if (strlen(parameters) == 0) {
- ladmin_log("Command: '%s' (without parameters)\n", command, parameters);
- } else {
- ladmin_log("Command: '%s', parameters: '%s'\n", command, parameters);
- }
-
- // Analyse of the command
-// help
- if (strcmp(command, "help") == 0 ) {
- display_help(parameters);
-// general commands
- } else if (strcmp(command, "add") == 0) {
- addaccount(parameters, 0); // 0: no email
- } else if (strcmp(command, "ban") == 0) {
- banaccount(parameters);
- } else if (strcmp(command, "banadd") == 0) {
- banaddaccount(parameters);
- } else if (strcmp(command, "banset") == 0) {
- bansetaccount(parameters);
- } else if (strcmp(command, "block") == 0) {
- blockaccount(parameters);
- } else if (strcmp(command, "check") == 0) {
- checkaccount(parameters);
- } else if (strcmp(command, "create") == 0) {
- addaccount(parameters, 1); // 1: with email
- } else if (strcmp(command, "delete") == 0) {
- delaccount(parameters);
- } else if (strcmp(command, "email") == 0) {
- changeemail(parameters);
- } else if (strcmp(command, "getcount") == 0) {
- getlogincount();
- } else if (strcmp(command, "gm") == 0) {
- changegmlevel(parameters);
- } else if (strcmp(command, "id") == 0) {
- idaccount(parameters);
- } else if (strcmp(command, "info") == 0) {
- infoaccount(atoi(parameters));
- } else if (strcmp(command, "kami") == 0) {
- sendbroadcast(0, parameters); // flag for normal
- } else if (strcmp(command, "kamib") == 0) {
- sendbroadcast(0x10, parameters); // flag for blue
- } else if (strcmp(command, "list") == 0) {
- listaccount(parameters, 0); // 0: to list all
- } else if (strcmp(command, "listban") == 0) {
- listaccount(parameters, 3); // 3: to list only accounts with state or bannished
- } else if (strcmp(command, "listgm") == 0) {
- listaccount(parameters, 1); // 1: to list only GM
- } else if (strcmp(command, "listok") == 0) {
- listaccount(parameters, 4); // 4: to list only accounts without state and not bannished
- } else if (strcmp(command, "memo") == 0) {
- changememo(parameters);
- } else if (strcmp(command, "name") == 0) {
- nameaccount(atoi(parameters));
- } else if (strcmp(command, "password") == 0) {
- changepasswd(parameters);
- } else if (strcmp(command, "reloadgm") == 0) {
- reloadGM();
- } else if (strcmp(command, "search") == 0) { // no regex in C version
- listaccount(parameters, 2); // 2: to list with pattern
- } else if (strcmp(command, "sex") == 0) {
- changesex(parameters);
- } else if (strcmp(command, "state") == 0) {
- changestate(parameters);
- } else if (strcmp(command, "timeadd") == 0) {
- timeaddaccount(parameters);
- } else if (strcmp(command, "timeset") == 0) {
- timesetaccount(parameters);
- } else if (strcmp(command, "unban") == 0) {
- unbanaccount(parameters);
- } else if (strcmp(command, "unblock") == 0) {
- unblockaccount(parameters);
- } else if (strcmp(command, "version") == 0) {
- checkloginversion();
- } else if (strcmp(command, "who") == 0) {
- whoaccount(parameters);
-// quit
- } else if (strcmp(command, "quit") == 0 ||
- strcmp(command, "exit") == 0 ||
- strcmp(command, "end") == 0) {
- ShowMessage("Bye.\n");
- exit(EXIT_SUCCESS);
-// unknown command
- } else {
- ShowMessage("Unknown command [%s].\n", buf);
- ladmin_log("Unknown command [%s].\n", buf);
- }
- }
-
- return 0;
-}
-
-//-------------------------------------------------------------
-// Function: Parse receiving informations from the login-server
-//-------------------------------------------------------------
-int parse_fromlogin(int fd)
-{
- struct char_session_data *sd;
- int id;
- RFIFOHEAD(fd);
- if (session[fd]->flag.eof) {
- ShowMessage("Impossible to have a connection with the login-server [%s:%d] !\n", loginserverip, loginserverport);
- ladmin_log("Impossible to have a connection with the login-server [%s:%d] !\n", loginserverip, loginserverport);
- do_close(fd);
- exit(EXIT_FAILURE);
- }
-
-// ShowMessage("parse_fromlogin : %d %d %d\n", fd, RFIFOREST(fd), RFIFOW(fd,0));
- sd = (struct char_session_data*)session[fd]->session_data;
-
- while(RFIFOREST(fd) >= 2) {
- switch(RFIFOW(fd,0)) {
- case 0x7919: // answer of a connection request
- if (RFIFOREST(fd) < 3)
- return 0;
- if (RFIFOB(fd,2) != 0) {
- ShowMessage("Error at login:\n");
- ShowMessage(" - incorrect password,\n");
- ShowMessage(" - administration system not activated, or\n");
- ShowMessage(" - unauthorised IP.\n");
- ladmin_log("Error at login: incorrect password, administration system not activated, or unauthorised IP.\n");
- set_eof(fd);
- //bytes_to_read = 1; // not stop at prompt
- return 0;
- } else {
- ShowMessage("Established connection.\n");
- ladmin_log("Established connection.\n");
- ShowMessage("Reading of the version of the login-server...\n");
- ladmin_log("Reading of the version of the login-server...\n");
- //bytes_to_read = 1; // unchanged
- checkloginversion();
- }
- RFIFOSKIP(fd,3);
- break;
-
- case 0x01dc: // answer of a coding key request
- if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
- return 0;
- {
- char md5str[64] = "", md5bin[32];
- WFIFOHEAD(login_fd, 20);
- if (passenc == 1) {
- strncpy(md5str, (const char*)RFIFOP(fd,4), RFIFOW(fd,2) - 4);
- strcat(md5str, loginserveradminpassword);
- } else if (passenc == 2) {
- strncpy(md5str, loginserveradminpassword, sizeof(loginserveradminpassword));
- strcat(md5str, (const char*)RFIFOP(fd,4));
- }
- MD5_Binary(md5str, md5bin);
- WFIFOW(login_fd,0) = 0x7918; // Request for administation login (encrypted password)
- WFIFOW(login_fd,2) = passenc; // Encrypted type
- memcpy(WFIFOP(login_fd,4), md5bin, 16);
- WFIFOSET(login_fd,20);
- ShowMessage("Receiving of the MD5 key.\n");
- ladmin_log("Receiving of the MD5 key.\n");
- ShowMessage("Sending of the encrypted password...\n");
- ladmin_log("Sending of the encrypted password...\n");
- }
- bytes_to_read = 1;
- RFIFOSKIP(fd,RFIFOW(fd,2));
- break;
-
- case 0x7531: // Displaying of the version of the login-server
- if (RFIFOREST(fd) < 10)
- return 0;
- ShowMessage(" Login-Server [%s:%d]\n", loginserverip, loginserverport);
- if (((int)RFIFOB(login_fd,5)) == 0) {
- ShowMessage(" eAthena version stable-%d.%d", (int)RFIFOB(login_fd,2), (int)RFIFOB(login_fd,3));
- } else {
- ShowMessage(" eAthena version dev-%d.%d", (int)RFIFOB(login_fd,2), (int)RFIFOB(login_fd,3));
- }
- if (((int)RFIFOB(login_fd,4)) == 0)
- ShowMessage(" revision %d", (int)RFIFOB(login_fd,4));
- if (((int)RFIFOB(login_fd,6)) == 0)
- ShowMessage("%d.\n", RFIFOW(login_fd,8));
- else
- ShowMessage("-mod%d.\n", RFIFOW(login_fd,8));
- bytes_to_read = 0;
- RFIFOSKIP(fd,10);
- break;
-
- case 0x7921: // Displaying of the list of accounts
- if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
- return 0;
- if (RFIFOW(fd,2) < 5) {
- ladmin_log(" Receiving of a void accounts list.\n");
- if (list_count == 0)
- ShowMessage("No account found.\n");
- else if (list_count == 1)
- ShowMessage("1 account found.\n");
- else
- ShowMessage("%d accounts found.\n", list_count);
- bytes_to_read = 0;
- } else {
- int i;
- WFIFOHEAD(login_fd,10);
- ladmin_log(" Receiving of a accounts list.\n");
- for(i = 4; i < RFIFOW(fd,2); i += 38) {
- int j;
- char userid[24];
- char lower_userid[24];
- memcpy(userid, RFIFOP(fd,i + 5), sizeof(userid));
- userid[sizeof(userid)-1] = '\0';
- memset(lower_userid, '\0', sizeof(lower_userid));
- for (j = 0; userid[j]; j++)
- lower_userid[j] = TOLOWER(userid[j]);
- list_first = RFIFOL(fd,i) + 1;
- // here are checks...
- if (list_type == 0 ||
- (list_type == 1 && RFIFOB(fd,i+4) > 0) ||
- (list_type == 2 && strstr(lower_userid, parameters) != NULL) ||
- (list_type == 3 && RFIFOL(fd,i+34) != 0) ||
- (list_type == 4 && RFIFOL(fd,i+34) == 0)) {
- ShowMessage("%10d ", (int)RFIFOL(fd,i));
- if (RFIFOB(fd,i+4) == 0)
- ShowMessage(" ");
- else
- ShowMessage("%2d ", (int)RFIFOB(fd,i+4));
- ShowMessage("%-24s", userid);
- if (RFIFOB(fd,i+29) == 0)
- ShowMessage("%-5s ", "Femal");
- else if (RFIFOB(fd,i+29) == 1)
- ShowMessage("%-5s ", "Male");
- else
- ShowMessage("%-5s ", "Servr");
- ShowMessage("%6d ", (int)RFIFOL(fd,i+30));
- switch(RFIFOL(fd,i+34)) {
- case 0:
- ShowMessage("%-27s\n", "Account OK");
- break;
- case 1:
- ShowMessage("%-27s\n", "Unregistered ID");
- break;
- case 2:
- ShowMessage("%-27s\n", "Incorrect Password");
- break;
- case 3:
- ShowMessage("%-27s\n", "This ID is expired");
- break;
- case 4:
- ShowMessage("%-27s\n", "Rejected from Server");
- break;
- case 5:
- ShowMessage("%-27s\n", "Blocked by the GM Team"); // You have been blocked by the GM Team
- break;
- case 6:
- ShowMessage("%-27s\n", "Your EXE file is too old"); // Your Game's EXE file is not the latest version
- break;
- case 7:
- ShowMessage("%-27s\n", "Banishement or");
- ShowMessage(" Prohibited to login until...\n"); // You are Prohibited to log in until %s
- break;
- case 8:
- ShowMessage("%-27s\n", "Server is over populated");
- break;
- case 9:
- ShowMessage("%-27s\n", "No MSG");
- break;
- default: // 100
- ShowMessage("%-27s\n", "This ID is totally erased"); // This ID has been totally erased
- break;
- }
- list_count++;
- }
- }
- // asking of the following acounts
- ladmin_log("Request to login-server to obtain the list of accounts from %d to %d (complement).\n", list_first, list_last);
- WFIFOW(login_fd,0) = 0x7920;
- WFIFOL(login_fd,2) = list_first;
- WFIFOL(login_fd,6) = list_last;
- WFIFOSET(login_fd,10);
- bytes_to_read = 1;
- }
- RFIFOSKIP(fd,RFIFOW(fd,2));
- break;
-
- case 0x7931: // Answer of login-server about an account creation
- if (RFIFOREST(fd) < 30)
- return 0;
- id = RFIFOL(fd,2);
- if (id != -1) {
- ShowMessage("Account [%s] creation failed. Return code %d.\n", RFIFOP(fd,6), id);
- ladmin_log("Account [%s] creation failed. Return code %d.\n", RFIFOP(fd,6), id);
- } else {
- ShowMessage("Account [%s] is successfully created.\n", RFIFOP(fd,6));
- ladmin_log("Account [%s] is successfully created.\n", RFIFOP(fd,6));
- }
- bytes_to_read = 0;
- RFIFOSKIP(fd,30);
- break;
-
- case 0x7933: // Answer of login-server about an account deletion
- if (RFIFOREST(fd) < 30)
- return 0;
- if (RFIFOL(fd,2) == -1) {
- ShowMessage("Account [%s] deletion failed. Account doesn't exist.\n", RFIFOP(fd,6));
- ladmin_log("Account [%s] deletion failed. Account doesn't exist.\n", RFIFOP(fd,6));
- } else {
- ShowMessage("Account [%s][id: %d] is successfully DELETED.\n", RFIFOP(fd,6), (int)RFIFOL(fd,2));
- ladmin_log("Account [%s][id: %d] is successfully DELETED.\n", RFIFOP(fd,6), RFIFOL(fd,2));
- }
- bytes_to_read = 0;
- RFIFOSKIP(fd,30);
- break;
-
- case 0x7935: // answer of the change of an account password
- if (RFIFOREST(fd) < 30)
- return 0;
- if (RFIFOL(fd,2) == -1) {
- ShowMessage("Account [%s] password changing failed.\n", RFIFOP(fd,6));
- ShowMessage("Account [%s] doesn't exist.\n", RFIFOP(fd,6));
- ladmin_log("Account password changing failed. The compte [%s] doesn't exist.\n", RFIFOP(fd,6));
- } else {
- ShowMessage("Account [%s][id: %d] password successfully changed.\n", RFIFOP(fd,6), (int)RFIFOL(fd,2));
- ladmin_log("Account [%s][id: %d] password successfully changed.\n", RFIFOP(fd,6), (int)RFIFOL(fd,2));
- }
- bytes_to_read = 0;
- RFIFOSKIP(fd,30);
- break;
-
- case 0x7937: // answer of the change of an account state
- if (RFIFOREST(fd) < 34)
- return 0;
- if (RFIFOL(fd,2) == -1) {
- ShowMessage("Account [%s] state changing failed. Account doesn't exist.\n", RFIFOP(fd,6));
- ladmin_log("Account [%s] state changing failed. Account doesn't exist.\n", RFIFOP(fd,6));
- } else {
- char tmpstr[256];
- sprintf(tmpstr, "Account [%s] state successfully changed in [", RFIFOP(fd,6));
- switch(RFIFOL(fd,30)) {
- case 0:
- strcat(tmpstr, "0: Account OK");
- case 1:
- strcat(tmpstr, "1: Unregistered ID");
- break;
- case 2:
- strcat(tmpstr, "2: Incorrect Password");
- break;
- case 3:
- strcat(tmpstr, "3: This ID is expired");
- break;
- case 4:
- strcat(tmpstr, "4: Rejected from Server");
- break;
- case 5:
- strcat(tmpstr, "5: You have been blocked by the GM Team");
- break;
- case 6:
- strcat(tmpstr, "6: [Your Game's EXE file is not the latest version");
- break;
- case 7:
- strcat(tmpstr, "7: You are Prohibited to log in until...");
- break;
- case 8:
- strcat(tmpstr, "8: Server is jammed due to over populated");
- break;
- case 9:
- strcat(tmpstr, "9: No MSG");
- break;
- default: // 100
- strcat(tmpstr, "100: This ID is totally erased");
- break;
- }
- strcat(tmpstr, "]");
- ShowMessage("%s\n", tmpstr);
- ladmin_log("%s\n", tmpstr);
- }
- bytes_to_read = 0;
- RFIFOSKIP(fd,34);
- break;
-
- case 0x7939: // answer of the number of online players
- if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
- return 0;
- {
- // Get length of the received packet
- int i;
- char name[20];
- ladmin_log(" Receiving of the number of online players.\n");
- // Read information of the servers
- if (RFIFOW(fd,2) < 5) {
- ShowMessage(" No server is connected to the login-server.\n");
- } else {
- ShowMessage(" Number of online players (server: number).\n");
- // Displaying of result
- for(i = 4; i < RFIFOW(fd,2); i += 32) {
- memcpy(name, RFIFOP(fd,i+6), sizeof(name));
- name[sizeof(name) - 1] = '\0';
- ShowMessage(" %-20s : %5d\n", name, RFIFOW(fd,i+26));
- }
- }
- }
- bytes_to_read = 0;
- RFIFOSKIP(fd,RFIFOW(fd,2));
- break;
-
- case 0x793b: // answer of the check of a password
- if (RFIFOREST(fd) < 30)
- return 0;
- id = RFIFOL(fd,2);
- if (id == -1) {
- ShowMessage("The account [%s] doesn't exist or the password is incorrect.\n", RFIFOP(fd,6));
- ladmin_log("The account [%s] doesn't exist or the password is incorrect.\n", RFIFOP(fd,6));
- } else {
- ShowMessage("The proposed password is correct for the account [%s][id: %d].\n", RFIFOP(fd,6), id);
- ladmin_log("The proposed password is correct for the account [%s][id: %d].\n", RFIFOP(fd,6), id);
- }
- bytes_to_read = 0;
- RFIFOSKIP(fd,30);
- break;
-
- case 0x793d: // answer of the change of an account sex
- if (RFIFOREST(fd) < 30)
- return 0;
- id = RFIFOL(fd,2);
- if (id == -1) {
- ShowMessage("Account [%s] sex changing failed.\n", RFIFOP(fd,6));
- ShowMessage("Account [%s] doesn't exist or the sex is already the good sex.\n", RFIFOP(fd,6));
- ladmin_log("Account sex changing failed. The compte [%s] doesn't exist or the sex is already the good sex.\n", RFIFOP(fd,6));
- } else {
- ShowMessage("Account [%s][id: %d] sex successfully changed.\n", RFIFOP(fd,6), id);
- ladmin_log("Account [%s][id: %d] sex successfully changed.\n", RFIFOP(fd,6), id);
- }
- bytes_to_read = 0;
- RFIFOSKIP(fd,30);
- break;
-
- case 0x793f: // answer of the change of an account GM level
- if (RFIFOREST(fd) < 30)
- return 0;
- id = RFIFOL(fd,2);
- if (id == -1) {
- ShowMessage("Account [%s] GM level changing failed.\n", RFIFOP(fd,6));
- ShowMessage("Account [%s] doesn't exist, the GM level is already the good GM level\n", RFIFOP(fd,6));
- ShowMessage("or it's impossible to modify the GM accounts file.\n");
- ladmin_log("Account GM level changing failed. The compte [%s] doesn't exist, the GM level is already the good sex or it's impossible to modify the GM accounts file.\n", RFIFOP(fd,6));
- } else {
- ShowMessage("Account [%s][id: %d] GM level successfully changed.\n", RFIFOP(fd,6), id);
- ladmin_log("Account [%s][id: %d] GM level successfully changed.\n", RFIFOP(fd,6), id);
- }
- bytes_to_read = 0;
- RFIFOSKIP(fd,30);
- break;
-
- case 0x7941: // answer of the change of an account email
- if (RFIFOREST(fd) < 30)
- return 0;
- id = RFIFOL(fd,2);
- if (id == -1) {
- ShowMessage("Account [%s] e-mail changing failed.\n", RFIFOP(fd,6));
- ShowMessage("Account [%s] doesn't exist.\n", RFIFOP(fd,6));
- ladmin_log("Account e-mail changing failed. The compte [%s] doesn't exist.\n", RFIFOP(fd,6));
- } else {
- ShowMessage("Account [%s][id: %d] e-mail successfully changed.\n", RFIFOP(fd,6), id);
- ladmin_log("Account [%s][id: %d] e-mail successfully changed.\n", RFIFOP(fd,6), id);
- }
- bytes_to_read = 0;
- RFIFOSKIP(fd,30);
- break;
-
- case 0x7943: // answer of the change of an account memo
- if (RFIFOREST(fd) < 30)
- return 0;
- id = RFIFOL(fd,2);
- if (id == -1) {
- ShowMessage("Account [%s] memo changing failed. Account doesn't exist.\n", RFIFOP(fd,6));
- ladmin_log("Account [%s] memo changing failed. Account doesn't exist.\n", RFIFOP(fd,6));
- } else {
- ShowMessage("Account [%s][id: %d] memo successfully changed.\n", RFIFOP(fd,6), id);
- ladmin_log("Account [%s][id: %d] memo successfully changed.\n", RFIFOP(fd,6), id);
- }
- bytes_to_read = 0;
- RFIFOSKIP(fd,30);
- break;
-
- case 0x7945: // answer of an account id search
- if (RFIFOREST(fd) < 30)
- return 0;
- id = RFIFOL(fd,2);
- if (id == -1) {
- ShowMessage("Unable to find the account [%s] id. Account doesn't exist.\n", RFIFOP(fd,6));
- ladmin_log("Unable to find the account [%s] id. Account doesn't exist.\n", RFIFOP(fd,6));
- } else {
- ShowMessage("The account [%s] have the id: %d.\n", RFIFOP(fd,6), id);
- ladmin_log("The account [%s] have the id: %d.\n", RFIFOP(fd,6), id);
- }
- bytes_to_read = 0;
- RFIFOSKIP(fd,30);
- break;
-
- case 0x7947: // answer of an account name search
- if (RFIFOREST(fd) < 30)
- return 0;
- id = RFIFOL(fd,2);
- if (strcmp((const char*)RFIFOP(fd,6), "") == 0) {
- ShowMessage("Unable to find the account [%d] name. Account doesn't exist.\n", id);
- ladmin_log("Unable to find the account [%d] name. Account doesn't exist.\n", id);
- } else {
- ShowMessage("The account [id: %d] have the name: %s.\n", id, RFIFOP(fd,6));
- ladmin_log("The account [id: %d] have the name: %s.\n", id, RFIFOP(fd,6));
- }
- bytes_to_read = 0;
- RFIFOSKIP(fd,30);
- break;
-
- case 0x7949: // answer of an account validity limit set
- if (RFIFOREST(fd) < 34)
- return 0;
- id = RFIFOL(fd,2);
- if (id == -1) {
- ShowMessage("Account [%s] validity limit changing failed. Account doesn't exist.\n", RFIFOP(fd,6));
- ladmin_log("Account [%s] validity limit changing failed. Account doesn't exist.\n", RFIFOP(fd,6));
- } else {
- time_t timestamp = RFIFOL(fd,30);
- if (timestamp == 0) {
- ShowMessage("Validity Limit of the account [%s][id: %d] successfully changed to [unlimited].\n", RFIFOP(fd,6), id);
- ladmin_log("Validity Limit of the account [%s][id: %d] successfully changed to [unlimited].\n", RFIFOP(fd,6), id);
- } else {
- char tmpstr[128];
- strftime(tmpstr, 24, date_format, localtime(&timestamp));
- ShowMessage("Validity Limit of the account [%s][id: %d] successfully changed to be until %s.\n", RFIFOP(fd,6), id, tmpstr);
- ladmin_log("Validity Limit of the account [%s][id: %d] successfully changed to be until %s.\n", RFIFOP(fd,6), id, tmpstr);
- }
- }
- bytes_to_read = 0;
- RFIFOSKIP(fd,34);
- break;
-
- case 0x794b: // answer of an account ban set
- if (RFIFOREST(fd) < 34)
- return 0;
- id = RFIFOL(fd,2);
- if (id == -1) {
- ShowMessage("Account [%s] final date of banishment changing failed. Account doesn't exist.\n", RFIFOP(fd,6));
- ladmin_log("Account [%s] final date of banishment changing failed. Account doesn't exist.\n", RFIFOP(fd,6));
- } else {
- time_t timestamp = RFIFOL(fd,30);
- if (timestamp == 0) {
- ShowMessage("Final date of banishment of the account [%s][id: %d] successfully changed to [unbanished].\n", RFIFOP(fd,6), id);
- ladmin_log("Final date of banishment of the account [%s][id: %d] successfully changed to [unbanished].\n", RFIFOP(fd,6), id);
- } else {
- char tmpstr[128];
- strftime(tmpstr, 24, date_format, localtime(&timestamp));
- ShowMessage("Final date of banishment of the account [%s][id: %d] successfully changed to be until %s.\n", RFIFOP(fd,6), id, tmpstr);
- ladmin_log("Final date of banishment of the account [%s][id: %d] successfully changed to be until %s.\n", RFIFOP(fd,6), id, tmpstr);
- }
- }
- bytes_to_read = 0;
- RFIFOSKIP(fd,34);
- break;
-
- case 0x794d: // answer of an account ban date/time changing
- if (RFIFOREST(fd) < 34)
- return 0;
- id = RFIFOL(fd,2);
- if (id == -1) {
- ShowMessage("Account [%s] final date of banishment changing failed. Account doesn't exist.\n", RFIFOP(fd,6));
- ladmin_log("Account [%s] final date of banishment changing failed. Account doesn't exist.\n", RFIFOP(fd,6));
- } else {
- time_t timestamp = RFIFOL(fd,30);
- if (timestamp == 0) {
- ShowMessage("Final date of banishment of the account [%s][id: %d] successfully changed to [unbanished].\n", RFIFOP(fd,6), id);
- ladmin_log("Final date of banishment of the account [%s][id: %d] successfully changed to [unbanished].\n", RFIFOP(fd,6), id);
- } else {
- char tmpstr[128];
- strftime(tmpstr, 24, date_format, localtime(&timestamp));
- ShowMessage("Final date of banishment of the account [%s][id: %d] successfully changed to be until %s.\n", RFIFOP(fd,6), id, tmpstr);
- ladmin_log("Final date of banishment of the account [%s][id: %d] successfully changed to be until %s.\n", RFIFOP(fd,6), id, tmpstr);
- }
- }
- bytes_to_read = 0;
- RFIFOSKIP(fd,34);
- break;
-
- case 0x794f: // answer of a broadcast
- if (RFIFOREST(fd) < 4)
- return 0;
- if (RFIFOW(fd,2) == (unsigned short)-1) {
- ShowMessage("Message sending failed. No online char-server.\n");
- ladmin_log("Message sending failed. No online char-server.\n");
- } else {
- ShowMessage("Message successfully sended to login-server.\n");
- ladmin_log("Message successfully sended to login-server.\n");
- }
- bytes_to_read = 0;
- RFIFOSKIP(fd,4);
- break;
-
- case 0x7951: // answer of an account validity limit changing
- if (RFIFOREST(fd) < 34)
- return 0;
- id = RFIFOL(fd,2);
- if (id == -1) {
- ShowMessage("Account [%s] validity limit changing failed. Account doesn't exist.\n", RFIFOP(fd,6));
- ladmin_log("Account [%s] validity limit changing failed. Account doesn't exist.\n", RFIFOP(fd,6));
- } else {
- time_t timestamp = RFIFOL(fd,30);
- if (timestamp == 0) {
- ShowMessage("Validity limit of the account [%s][id: %d] unchanged.\n", RFIFOP(fd,6), id);
- ShowMessage("The account have an unlimited validity limit or\n");
- ShowMessage("the changing is impossible with the proposed adjustments.\n");
- ladmin_log("Validity limit of the account [%s][id: %d] unchanged. The account have an unlimited validity limit or the changing is impossible with the proposed adjustments.\n", RFIFOP(fd,6), id);
- } else {
- char tmpstr[128];
- strftime(tmpstr, 24, date_format, localtime(&timestamp));
- ShowMessage("Validity limit of the account [%s][id: %d] successfully changed to be until %s.\n", RFIFOP(fd,6), id, tmpstr);
- ladmin_log("Validity limit of the account [%s][id: %d] successfully changed to be until %s.\n", RFIFOP(fd,6), id, tmpstr);
- }
- }
- bytes_to_read = 0;
- RFIFOSKIP(fd,34);
- break;
-
- case 0x7953: // answer of a request about informations of an account (by account name/id)
- if (RFIFOREST(fd) < 150 || RFIFOREST(fd) < (size_t)(150 + RFIFOW(fd,148)))
- return 0;
- {
- char userid[24], error_message[20], lastlogin[24], last_ip[16], email[40], memo[255];
- time_t unban_time; // # of seconds 1/1/1970 (timestamp): ban time limit of the account (0 = no ban)
- time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
- safestrncpy(userid, (char*)RFIFOP(fd,7), sizeof(userid));
- safestrncpy(error_message, (char*)RFIFOP(fd,40), sizeof(error_message));
- safestrncpy(lastlogin, (char*)RFIFOP(fd,60), sizeof(lastlogin));
- safestrncpy(last_ip, (char*)RFIFOP(fd,84), sizeof(last_ip));
- safestrncpy(email, (char*)RFIFOP(fd,100), sizeof(email));
- expiration_time = (time_t)RFIFOL(fd,140);
- unban_time = (time_t)RFIFOL(fd,144);
- memset(memo, '\0', sizeof(memo));
- safestrncpy(memo, (const char*)RFIFOP(fd,150), RFIFOW(fd,148));
- id = RFIFOL(fd,2);
- if (id == -1) {
- ShowMessage("Unabled to find the account [%s]. Account doesn't exist.\n", parameters);
- ladmin_log("Unabled to find the account [%s]. Account doesn't exist.\n", parameters);
- } else if (strlen(userid) == 0) {
- ShowMessage("Unabled to find the account [id: %s]. Account doesn't exist.\n", parameters);
- ladmin_log("Unabled to find the account [id: %s]. Account doesn't exist.\n", parameters);
- } else {
- ladmin_log("Receiving information about an account.\n");
- ShowMessage("The account is set with:\n");
- if (RFIFOB(fd,6) == 0) {
- ShowMessage(" Id: %d (non-GM)\n", id);
- } else {
- ShowMessage(" Id: %d (GM level %d)\n", id, (int)RFIFOB(fd,6));
- }
- ShowMessage(" Name: '%s'\n", userid);
- if (RFIFOB(fd,31) == 0)
- ShowMessage(" Sex: Female\n");
- else if (RFIFOB(fd,31) == 1)
- ShowMessage(" Sex: Male\n");
- else
- ShowMessage(" Sex: Server\n");
- ShowMessage(" E-mail: %s\n", email);
- switch(RFIFOL(fd,36)) {
- case 0: ShowMessage(" State: 0 [Account OK]\n"); break;
- case 1: ShowMessage(" State: 1 [Unregistered ID]\n"); break;
- case 2: ShowMessage(" State: 2 [Incorrect Password]\n"); break;
- case 3: ShowMessage(" State: 3 [This ID is expired]\n"); break;
- case 4: ShowMessage(" State: 4 [Rejected from Server]\n"); break;
- case 5: ShowMessage(" State: 5 [You have been blocked by the GM Team]\n"); break;
- case 6: ShowMessage(" State: 6 [Your Game's EXE file is not the latest version]\n"); break;
- case 7: ShowMessage(" State: 7 [You are Prohibited to log in until %s]\n", error_message); break;
- case 8: ShowMessage(" State: 8 [Server is jammed due to over populated]\n"); break;
- case 9: ShowMessage(" State: 9 [No MSG]\n"); break;
- default: // 100
- ShowMessage(" State: %d [This ID is totally erased]\n", (int)RFIFOL(fd,36));
- break;
- }
- if (unban_time == 0) {
- ShowMessage(" Banishment: not banished.\n");
- } else {
- char tmpstr[128];
- strftime(tmpstr, 24, date_format, localtime(&unban_time));
- ShowMessage(" Banishment: until %s.\n", tmpstr);
- }
- if (RFIFOL(fd,32) > 1)
- ShowMessage(" Count: %d connections.\n", (int)RFIFOL(fd,32));
- else
- ShowMessage(" Count: %d connection.\n", (int)RFIFOL(fd,32));
- ShowMessage(" Last connection at: %s (ip: %s)\n", lastlogin, last_ip);
- if (expiration_time == 0) {
- ShowMessage(" Validity limit: unlimited.\n");
- } else {
- char tmpstr[128];
- strftime(tmpstr, 24, date_format, localtime(&expiration_time));
- ShowMessage(" Validity limit: until %s.\n", tmpstr);
- }
- ShowMessage(" Memo: '%s'\n", memo);
- }
- }
- bytes_to_read = 0;
- RFIFOSKIP(fd,150 + RFIFOW(fd,148));
- break;
-
- default:
- ShowMessage("Remote administration has been disconnected (unknown packet).\n");
- ladmin_log("'End of connection, unknown packet.\n");
- set_eof(fd);
- return 0;
- }
- }
-
- // if we don't wait new packets, do the prompt
- prompt();
-
- return 0;
-}
-
-//------------------------------------
-// Function to connect to login-server
-//------------------------------------
-int Connect_login_server(void)
-{
- ShowMessage("Attempt to connect to login-server...\n");
- ladmin_log("Attempt to connect to login-server...\n");
-
- login_fd = make_connection(login_ip, loginserverport);
- if (login_fd == -1)
- { //Might not be the most elegant way to handle this, but I've never used ladmin so I dunno what else you could do. [Skotlex]
- ShowMessage("Error: Failed to connect to Login Server\n");
- exit(EXIT_FAILURE);
- }
- session[login_fd]->flag.server = 1;
- if (passenc == 0) {
- WFIFOHEAD(login_fd,28);
- WFIFOW(login_fd,0) = 0x7918; // Request for administation login
- WFIFOW(login_fd,2) = 0; // no encrypted
- memcpy(WFIFOP(login_fd,4), loginserveradminpassword, 24);
- WFIFOSET(login_fd,28);
- bytes_to_read = 1;
- ShowMessage("Sending of the password...\n");
- ladmin_log("Sending of the password...\n");
- } else {
- WFIFOHEAD(login_fd,2);
- WFIFOW(login_fd,0) = 0x791a; // Sending request about the coding key
- WFIFOSET(login_fd,2);
- bytes_to_read = 1;
- ShowMessage("Request about the MD5 key...\n");
- ladmin_log("Request about the MD5 key...\n");
- }
-
- return 0;
-}
-
-// sends a ping packet to login server (will receive pong 0x2718)
-int ping_login_server(int tid, unsigned int tick, int id, intptr data)
-{
- if (login_fd > 0 && session[login_fd] != NULL)
- {
- WFIFOHEAD(login_fd,2);
- WFIFOW(login_fd,0) = 0x2719;
- WFIFOSET(login_fd,2);
- }
- return 0;
-}
-
-//-----------------------------------
-// Reading general configuration file
-//-----------------------------------
-int ladmin_config_read(const char *cfgName)
-{
- char line[1024], w1[1024], w2[1024];
- FILE *fp;
-
- fp = fopen(cfgName, "r");
- if (fp == NULL) {
- ShowMessage("\033[0mConfiguration file (%s) not found.\n", cfgName);
- return 1;
- }
-
- ShowMessage("\033[0m---Start reading of Ladmin configuration file (%s)\n", cfgName);
- while(fgets(line, sizeof(line), fp))
- {
- if (line[0] == '/' && line[1] == '/')
- continue;
-
- if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) == 2) {
- remove_control_chars(w1);
- remove_control_chars(w2);
-
- if(strcmpi(w1,"login_ip")==0) {
- uint32 ipl = host2ip(w2);
- if (ipl != 0) {
- ip2str(ipl, loginserverip);
- ShowMessage("Login server IP address: %s -> %s\n", w2, loginserverip);
- } else
- memcpy(loginserverip, w2, 16);
- } else if (strcmpi(w1, "login_port") == 0) {
- loginserverport = atoi(w2);
- } else if (strcmpi(w1, "admin_pass") == 0) {
- strncpy(loginserveradminpassword, w2, sizeof(loginserveradminpassword));
- loginserveradminpassword[sizeof(loginserveradminpassword)-1] = '\0';
- } else if (strcmpi(w1, "passenc") == 0) {
- passenc = atoi(w2);
- if (passenc < 0 || passenc > 2)
- passenc = 0;
- } else if (strcmpi(w1, "ladmin_log_filename") == 0) {
- strncpy(ladmin_log_filename, w2, sizeof(ladmin_log_filename));
- ladmin_log_filename[sizeof(ladmin_log_filename)-1] = '\0';
- } else if (strcmpi(w1, "date_format") == 0) {
- strncpy(date_format, w2, sizeof(date_format));
- } else if(strcmpi(w1,"stdout_with_ansisequence") == 0) {
- stdout_with_ansisequence = config_switch(w2);
- } else if (strcmpi(w1, "import") == 0) {
- ladmin_config_read(w2);
- }
- }
- }
- fclose(fp);
-
- login_ip = str2ip(loginserverip);
-
- ShowMessage("---End reading of Ladmin configuration file.\n");
-
- return 0;
-}
-
-//------------------------------
-// Function called when the server
-// has received a crash signal.
-//------------------------------
-void do_abort(void)
-{
-}
-
-//--------------------------------------
-// Function called at exit of the server
-//--------------------------------------
-void do_final(void)
-{
- if (already_exit_function == 0) {
-
- ShowMessage("\033[0m----End of Ladmin (normal end with closing of all files).\n");
- ladmin_log("----End of Ladmin (normal end with closing of all files).\n");
-
- already_exit_function = 1;
- do_close(login_fd);
- }
-}
-
-//------------------------
-// Main function of ladmin
-//------------------------
-int do_init(int argc, char **argv)
-{
- int next;
- socket_init();
-
- // read ladmin configuration
- ladmin_config_read((argc > 1) ? argv[1] : LADMIN_CONF_NAME);
-
- ladmin_log("");
- ladmin_log("Configuration file readed.\n");
-
- srand(time(NULL));
-
- set_defaultparse(parse_fromlogin);
-
- ShowMessage("EAthena login-server administration tool.\n");
- ShowMessage("(for eAthena version %d.%d.%d.)\n", ATHENA_MAJOR_VERSION, ATHENA_MINOR_VERSION, ATHENA_REVISION);
-
- ladmin_log("Ladmin is ready.\n");
- ShowMessage("Ladmin is \033[1;32mready\033[0m.\n\n");
-
- Connect_login_server();
-
- // keep the char-login connection alive
- add_timer_func_list(ping_login_server, "ping_login_server");
- add_timer_interval(gettick() + 1000, ping_login_server, 0, 0, ((int)stall_time-2) * 1000);
-
- // minimalist core doesn't have sockets parsing,
- // so we have to do this ourselves
- while (runflag) {
- next = do_timer(gettick_nocache());
- do_sockets(next);
- }
-
- return 0;
-}
diff --git a/src/ladmin/ladmin.h b/src/ladmin/ladmin.h
deleted file mode 100644
index 824407af7..000000000
--- a/src/ladmin/ladmin.h
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
-
-#ifndef _LADMIN_H_
-#define _LADMIN_H_
-
-#define LADMIN_CONF_NAME "conf/ladmin_athena.conf"
-
-#endif /* _LADMIN_H_ */
diff --git a/src/login/Makefile.in b/src/login/Makefile.in
index 611ca385b..c153d95b3 100644
--- a/src/login/Makefile.in
+++ b/src/login/Makefile.in
@@ -13,7 +13,7 @@ COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h
COMMON_SQL_OBJ = ../common/obj_sql/sql.o
COMMON_SQL_H = ../common/sql.h
-LOGIN_OBJ = login.o admin.o
+LOGIN_OBJ = login.o
LOGIN_TXT_OBJ = $(LOGIN_OBJ:%=obj_txt/%) \
obj_txt/account_txt.o obj_txt/ipban_txt.o obj_txt/loginlog_txt.o
LOGIN_SQL_OBJ = $(LOGIN_OBJ:%=obj_sql/%) \
diff --git a/src/login/account.h b/src/login/account.h
index 4cc9b353b..650f2c661 100644
--- a/src/login/account.h
+++ b/src/login/account.h
@@ -41,7 +41,7 @@ AccountDB* ACCOUNTDB_CONSTRUCTOR(ACCOUNTDB_ENGINE_4)(void);
struct mmo_account
{
int account_id;
- char userid[24];
+ char userid[NAME_LENGTH];
char pass[32+1]; // 23+1 for plaintext, 32+1 for md5-ed passwords
char sex; // gender (M/F/S)
char email[40]; // e-mail (by default: a@a.com)
@@ -52,6 +52,7 @@ struct mmo_account
unsigned int logincount;// number of successful auth attempts
char lastlogin[24]; // date+time of last successful login
char last_ip[16]; // save of last IP of connection
+ char birthdate[10+1]; // assigned birth date (format: YYYY-MM-DD, default: 0000-00-00)
int account_reg2_num;
struct global_reg account_reg2[ACCOUNT_REG2_NUM]; // account script variables (stored on login server)
};
diff --git a/src/login/account_sql.c b/src/login/account_sql.c
index c2f4a9965..e3e725efa 100644
--- a/src/login/account_sql.c
+++ b/src/login/account_sql.c
@@ -522,7 +522,7 @@ static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int acc
// retrieve login entry for the specified account
if( SQL_ERROR == Sql_Query(sql_handle,
- "SELECT `account_id`,`userid`,`user_pass`,`sex`,`email`,`level`,`state`,`unban_time`,`expiration_time`,`logincount`,`lastlogin`,`last_ip` FROM `%s` WHERE `account_id` = %d",
+ "SELECT `account_id`,`userid`,`user_pass`,`sex`,`email`,`level`,`state`,`unban_time`,`expiration_time`,`logincount`,`lastlogin`,`last_ip`,`birthdate` FROM `%s` WHERE `account_id` = %d",
db->account_db, account_id )
) {
Sql_ShowDebug(sql_handle);
@@ -547,6 +547,7 @@ static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int acc
Sql_GetData(sql_handle, 9, &data, NULL); acc->logincount = strtoul(data, NULL, 10);
Sql_GetData(sql_handle, 10, &data, NULL); safestrncpy(acc->lastlogin, data, sizeof(acc->lastlogin));
Sql_GetData(sql_handle, 11, &data, NULL); safestrncpy(acc->last_ip, data, sizeof(acc->last_ip));
+ Sql_GetData(sql_handle, 12, &data, NULL); safestrncpy(acc->birthdate, data, sizeof(acc->birthdate));
Sql_FreeResult(sql_handle);
@@ -595,7 +596,7 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
if( is_new )
{// insert into account table
if( SQL_SUCCESS != SqlStmt_Prepare(stmt,
- "INSERT INTO `%s` (`account_id`, `userid`, `user_pass`, `sex`, `email`, `level`, `state`, `unban_time`, `expiration_time`, `logincount`, `lastlogin`, `last_ip`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ "INSERT INTO `%s` (`account_id`, `userid`, `user_pass`, `sex`, `email`, `level`, `state`, `unban_time`, `expiration_time`, `logincount`, `lastlogin`, `last_ip`, `birthdate`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
db->account_db)
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_INT, (void*)&acc->account_id, sizeof(acc->account_id))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (void*)acc->userid, strlen(acc->userid))
@@ -609,6 +610,7 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 9, SQLDT_UINT, (void*)&acc->logincount, sizeof(acc->logincount))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 10, SQLDT_STRING, (void*)&acc->lastlogin, strlen(acc->lastlogin))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 11, SQLDT_STRING, (void*)&acc->last_ip, strlen(acc->last_ip))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 12, SQLDT_STRING, (void*)&acc->birthdate, strlen(acc->birthdate))
|| SQL_SUCCESS != SqlStmt_Execute(stmt)
) {
SqlStmt_ShowDebug(stmt);
@@ -617,7 +619,7 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
}
else
{// update account table
- if( SQL_SUCCESS != SqlStmt_Prepare(stmt, "UPDATE `%s` SET `userid`=?,`user_pass`=?,`sex`=?,`email`=?,`level`=?,`state`=?,`unban_time`=?,`expiration_time`=?,`logincount`=?,`lastlogin`=?,`last_ip`=? WHERE `account_id` = '%d'", db->account_db, acc->account_id)
+ if( SQL_SUCCESS != SqlStmt_Prepare(stmt, "UPDATE `%s` SET `userid`=?,`user_pass`=?,`sex`=?,`email`=?,`level`=?,`state`=?,`unban_time`=?,`expiration_time`=?,`logincount`=?,`lastlogin`=?,`last_ip`=?,`birthdate`=? WHERE `account_id` = '%d'", db->account_db, acc->account_id)
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, (void*)acc->userid, strlen(acc->userid))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (void*)acc->pass, strlen(acc->pass))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_ENUM, (void*)&acc->sex, sizeof(acc->sex))
@@ -629,6 +631,7 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 8, SQLDT_UINT, (void*)&acc->logincount, sizeof(acc->logincount))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 9, SQLDT_STRING, (void*)&acc->lastlogin, strlen(acc->lastlogin))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 10, SQLDT_STRING, (void*)&acc->last_ip, strlen(acc->last_ip))
+ || SQL_SUCCESS != SqlStmt_BindParam(stmt, 11, SQLDT_STRING, (void*)&acc->birthdate, strlen(acc->birthdate))
|| SQL_SUCCESS != SqlStmt_Execute(stmt)
) {
SqlStmt_ShowDebug(stmt);
diff --git a/src/login/account_txt.c b/src/login/account_txt.c
index ba3388c57..758a2c24e 100644
--- a/src/login/account_txt.c
+++ b/src/login/account_txt.c
@@ -14,7 +14,7 @@
#include <string.h>
/// global defines
-#define ACCOUNT_TXT_DB_VERSION 20080409
+#define ACCOUNT_TXT_DB_VERSION 20110114
#define AUTHS_BEFORE_SAVE 10 // flush every 10 saves
#define AUTH_SAVING_INTERVAL 60000 // flush every 10 minutes
@@ -452,10 +452,31 @@ static bool mmo_auth_fromstr(struct mmo_account* a, char* str, unsigned int vers
// zero out the destination first
memset(a, 0x00, sizeof(struct mmo_account));
+ // defaults for older format versions
+ safestrncpy(a->birthdate, "0000-00-00", sizeof(a->birthdate));
+
// extract tab-separated columns from line
count = sv_split(str, strlen(str), 0, '\t', fields, ARRAYLENGTH(fields), (e_svopt)(SV_TERMINATE_LF|SV_TERMINATE_CRLF));
- if( version == ACCOUNT_TXT_DB_VERSION && count == 13 )
+ if( version == ACCOUNT_TXT_DB_VERSION && count == 14 )
+ {
+ a->account_id = strtol(fields[1], NULL, 10);
+ safestrncpy(a->userid, fields[2], sizeof(a->userid));
+ safestrncpy(a->pass, fields[3], sizeof(a->pass));
+ a->sex = fields[4][0];
+ safestrncpy(a->email, fields[5], sizeof(a->email));
+ a->level = strtoul(fields[6], NULL, 10);
+ a->state = strtoul(fields[7], NULL, 10);
+ a->unban_time = strtol(fields[8], NULL, 10);
+ a->expiration_time = strtol(fields[9], NULL, 10);
+ a->logincount = strtoul(fields[10], NULL, 10);
+ safestrncpy(a->lastlogin, fields[11], sizeof(a->lastlogin));
+ safestrncpy(a->last_ip, fields[12], sizeof(a->last_ip));
+ safestrncpy(a->birthdate, fields[13], sizeof(a->birthdate));
+ regs = fields[14];
+ }
+ else
+ if( version == 20080409 && count == 13 )
{
a->account_id = strtol(fields[1], NULL, 10);
safestrncpy(a->userid, fields[2], sizeof(a->userid));
@@ -558,10 +579,10 @@ static bool mmo_auth_tostr(const struct mmo_account* a, char* str)
int i;
char* str_p = str;
- str_p += sprintf(str_p, "%d\t%s\t%s\t%c\t%s\t%u\t%u\t%ld\t%ld\t%u\t%s\t%s\t",
+ str_p += sprintf(str_p, "%d\t%s\t%s\t%c\t%s\t%u\t%u\t%ld\t%ld\t%u\t%s\t%s\t%s\t",
a->account_id, a->userid, a->pass, a->sex, a->email, a->level,
a->state, (long)a->unban_time, (long)a->expiration_time,
- a->logincount, a->lastlogin, a->last_ip);
+ a->logincount, a->lastlogin, a->last_ip, a->birthdate);
for( i = 0; i < a->account_reg2_num; ++i )
if( a->account_reg2[i].str[0] )
@@ -587,7 +608,7 @@ static void mmo_auth_sync(AccountDB_TXT* db)
fprintf(fp, "%d\n", ACCOUNT_TXT_DB_VERSION); // savefile version
fprintf(fp, "// Accounts file: here are saved all information about the accounts.\n");
- fprintf(fp, "// Structure: account ID, username, password, sex, email, level, state, unban time, expiration time, # of logins, last login time, last (accepted) login ip, repeated(register key, register value)\n");
+ fprintf(fp, "// Structure: account ID, username, password, sex, email, level, state, unban time, expiration time, # of logins, last login time, last (accepted) login ip, birth date, repeated(register key, register value)\n");
fprintf(fp, "// where:\n");
fprintf(fp, "// sex : M or F for normal accounts, S for server accounts\n");
fprintf(fp, "// level : this account's gm level\n");
diff --git a/src/login/admin.c b/src/login/admin.c
deleted file mode 100644
index d5175dca5..000000000
--- a/src/login/admin.c
+++ /dev/null
@@ -1,857 +0,0 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
-
-#include "../common/cbasetypes.h"
-#include "../common/mmo.h"
-#include "../common/core.h"
-#include "../common/socket.h"
-#include "../common/db.h"
-#include "../common/timer.h"
-#include "../common/malloc.h"
-#include "../common/strlib.h"
-#include "../common/showmsg.h"
-#include "../common/version.h"
-#include "../common/md5calc.h"
-#include "../common/lock.h"
-#include "account.h"
-#include "login.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h> // for stat/lstat/fstat
-
-extern AccountDB* accounts;
-
-int charif_sendallwos(int sfd, unsigned char *buf, unsigned int len);
-bool check_password(const char* md5key, int passwdenc, const char* passwd, const char* refpass);
-int mmo_auth_new(const char* userid, const char* pass, const char sex, const char* last_ip);
-int parse_admin(int fd);
-
-
-bool ladmin_auth(struct login_session_data* sd, const char* ip)
-{
- bool result = false;
-
- if( str2ip(ip) != host2ip(login_config.admin_allowed_host) )
- ShowNotice("'ladmin'-login: Connection in administration mode REFUSED - IP isn't authorised (ip: %s).\n", ip);
- else
- if( !login_config.admin_state )
- ShowNotice("'ladmin'-login: Connection in administration mode REFUSED - remote administration is disabled (ip: %s)\n", ip);
- else
- if( !check_password(sd->md5key, sd->passwdenc, sd->passwd, login_config.admin_pass) )
- ShowNotice("'ladmin'-login: Connection in administration mode REFUSED - invalid password (ip: %s)\n", ip);
- else
- {
- ShowNotice("'ladmin'-login: Connection in administration mode accepted (ip: %s)\n", ip);
- session[sd->fd]->func_parse = parse_admin;
- result = true;
- }
-
- return result;
-}
-
-//---------------------------------------
-// Packet parsing for administation login
-//
-// List of supported operations:
-// 0x7530 - request server version (response: 0x7531)
-// 0x7938 - request server list (response: 0x7939)
-// 0x7920 - request entire list of accounts (response: 0x7921)
-// 0x794e - request message broadcast (response: 0x794f + 0x2726)
-
-// 0x7930 - request account creation (response: 0x7931)
-// 0x7932 - request account deletion (response: 0x7933 + 0x2730)
-
-// 0x7934 - request account password modification (response: 0x7935)
-// 0x7936 - request account state modification (response: 0x7937 + 0x2731)
-// 0x793a - request password check (response: 0x793b)
-// 0x793c - request account sex modification (response: 0x793d + 0x2723)
-// 0x793e - request account gm-level modification (response: 0x793f)
-// 0x7940 - request account email modification (response: 0x7941)
-// 0x7942 - request account memo modification (response: 0x7943)
-// 0x7948 - request account expiration-time modification - absolute (response: 0x7949)
-// 0x7950 - request account expiration-time modification - relative (response: 0x7951)
-// 0x794a - request account unban-time modification - absolute (response: 0x794b + 0x2731)
-// 0x794c - request account unban-time modification - relative (response: 0x794d + 0x2731)
-
-// 0x7944 - request account id lookup by name (response: 0x7945)
-// 0x7946 - request account name lookup by id (response: 0x7947)
-// 0x7952 - request account information lookup by name (response: 0x7953)
-// 0x7954 - request account information lookup by id (response: 0x7953)
-//---------------------------------------
-int parse_admin(int fd)
-{
- char* account_name;
-
- uint32 ipl = session[fd]->client_addr;
- char ip[16];
- ip2str(ipl, ip);
-
- if( session[fd]->flag.eof )
- {
- do_close(fd);
- ShowInfo("Remote administration has disconnected (session #%d).\n", fd);
- return 0;
- }
-
- while( RFIFOREST(fd) >= 2 )
- {
- uint16 command = RFIFOW(fd,0);
-
- switch( command )
- {
-
- case 0x7530: // Request of the server version
- ShowStatus("'ladmin': Sending of the server version (ip: %s)\n", ip);
- WFIFOHEAD(fd,10);
- WFIFOW(fd,0) = 0x7531;
- WFIFOB(fd,2) = ATHENA_MAJOR_VERSION;
- WFIFOB(fd,3) = ATHENA_MINOR_VERSION;
- WFIFOB(fd,4) = ATHENA_REVISION;
- WFIFOB(fd,5) = ATHENA_RELEASE_FLAG;
- WFIFOB(fd,6) = ATHENA_OFFICIAL_FLAG;
- WFIFOB(fd,7) = ATHENA_SERVER_LOGIN;
- WFIFOW(fd,8) = ATHENA_MOD_VERSION;
- WFIFOSET(fd,10);
- RFIFOSKIP(fd,2);
- break;
-/*
- case 0x7920: // Request of an accounts list
- if (RFIFOREST(fd) < 10)
- return 0;
- {
- int st, ed;
- uint16 len;
- CREATE_BUFFER(id, int, auth_num);
- st = RFIFOL(fd,2);
- ed = RFIFOL(fd,6);
- RFIFOSKIP(fd,10);
- WFIFOW(fd,0) = 0x7921;
- if (st < 0)
- st = 0;
- if (ed > END_ACCOUNT_NUM || ed < st || ed <= 0)
- ed = END_ACCOUNT_NUM;
- ShowStatus("'ladmin': Sending an accounts list (ask: from %d to %d, ip: %s)\n", st, ed, ip);
- // Sort before send
- for(i = 0; i < auth_num; i++) {
- unsigned int k;
- id[i] = i;
- for(j = 0; j < i; j++) {
- if (auth_dat[id[i]].account_id < auth_dat[id[j]].account_id) {
- for(k = i; k > j; k--) {
- id[k] = id[k-1];
- }
- id[j] = i; // id[i]
- break;
- }
- }
- }
- // Sending accounts information
- len = 4;
- for(i = 0; i < auth_num && len < 30000; i++) {
- int account_id = auth_dat[id[i]].account_id; // use sorted index
- if (account_id >= st && account_id <= ed) {
- j = id[i];
- WFIFOL(fd,len) = account_id;
- WFIFOB(fd,len+4) = (unsigned char)isGM(account_id);
- memcpy(WFIFOP(fd,len+5), auth_dat[j].userid, 24);
- WFIFOB(fd,len+29) = auth_dat[j].sex;
- WFIFOL(fd,len+30) = auth_dat[j].logincount;
- if (auth_dat[j].state == 0 && auth_dat[j].unban_time != 0) // if no state and banished
- WFIFOL(fd,len+34) = 7; // 6 = Your are Prohibited to log in until %s
- else
- WFIFOL(fd,len+34) = auth_dat[j].state;
- len += 38;
- }
- }
- WFIFOW(fd,2) = len;
- WFIFOSET(fd,len);
- //if (id) free(id);
- DELETE_BUFFER(id);
- }
- break;
-*/
- case 0x7930: // Request for an account creation
- if (RFIFOREST(fd) < 91)
- return 0;
- {
- struct mmo_account ma;
- safestrncpy(ma.userid, (char*)RFIFOP(fd, 2), sizeof(ma.userid));
- safestrncpy(ma.pass, (char*)RFIFOP(fd,26), sizeof(ma.pass));
- ma.sex = RFIFOB(fd,50);
- safestrncpy(ma.email, (char*)RFIFOP(fd,51), sizeof(ma.email));
- safestrncpy(ma.lastlogin, "-", sizeof(ma.lastlogin));
-
- ShowNotice("'ladmin': Account creation request (account: %s pass: %s, sex: %c, email: %s, ip: %s)\n", ma.userid, ma.pass, ma.sex, ma.email, ip);
-
- WFIFOW(fd,0) = 0x7931;
- WFIFOL(fd,2) = mmo_auth_new(ma.userid, ma.pass, ma.sex, ip);
- safestrncpy((char*)WFIFOP(fd,6), ma.userid, 24);
- WFIFOSET(fd,30);
- }
- RFIFOSKIP(fd,91);
- break;
-/*
- case 0x7932: // Request for an account deletion
- if (RFIFOREST(fd) < 26)
- return 0;
- {
- struct mmo_account acc;
-
- char* account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
-
- WFIFOW(fd,0) = 0x7933;
-
- if( accounts->load_str(accounts, &acc, account_name) )
- {
- // Char-server is notified of deletion (for characters deletion).
- unsigned char buf[65535];
- WBUFW(buf,0) = 0x2730;
- WBUFL(buf,2) = acc.account_id;
- charif_sendallwos(-1, buf, 6);
-
- // send answer
- memcpy(WFIFOP(fd,6), acc.userid, 24);
- WFIFOL(fd,2) = acc.account_id;
-
- // delete account
- memset(acc.userid, '\0', sizeof(acc.userid));
- auth_dat[i].account_id = -1;
- mmo_auth_sync();
- } else {
- WFIFOL(fd,2) = -1;
- memcpy(WFIFOP(fd,6), account_name, 24);
- ShowNotice("'ladmin': Attempt to delete an unknown account (account: %s, ip: %s)\n", account_name, ip);
- }
- WFIFOSET(fd,30);
- }
- RFIFOSKIP(fd,26);
- break;
-*/
- case 0x7934: // Request to change a password
- if (RFIFOREST(fd) < 50)
- return 0;
- {
- struct mmo_account acc;
-
- char* account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
-
- WFIFOW(fd,0) = 0x7935;
-
- if( accounts->load_str(accounts, &acc, account_name) )
- {
- WFIFOL(fd,2) = acc.account_id;
- safestrncpy((char*)WFIFOP(fd,6), acc.userid, 24);
- safestrncpy(acc.pass, (char*)RFIFOP(fd,26), 24);
- ShowNotice("'ladmin': Modification of a password (account: %s, new password: %s, ip: %s)\n", acc.userid, acc.pass, ip);
-
- accounts->save(accounts, &acc);
- }
- else
- {
- WFIFOL(fd,2) = -1;
- safestrncpy((char*)WFIFOP(fd,6), account_name, 24);
- ShowNotice("'ladmin': Attempt to modify the password of an unknown account (account: %s, ip: %s)\n", account_name, ip);
- }
-
- WFIFOSET(fd,30);
- }
- RFIFOSKIP(fd,50);
- break;
-
- case 0x7936: // Request to modify a state
- if (RFIFOREST(fd) < 50)
- return 0;
- {
- struct mmo_account acc;
-
- char* account_name = (char*)RFIFOP(fd,2);
- uint32 state = RFIFOL(fd,26);
- account_name[23] = '\0';
-
- WFIFOW(fd,0) = 0x7937;
-
- if( accounts->load_str(accounts, &acc, account_name) )
- {
- memcpy(WFIFOP(fd,6), acc.userid, 24);
- WFIFOL(fd,2) = acc.account_id;
-
- if (acc.state == state)
- ShowNotice("'ladmin': Modification of a state, but the state of the account already has this value (account: %s, received state: %d, ip: %s)\n", account_name, state, ip);
- else
- {
- ShowNotice("'ladmin': Modification of a state (account: %s, new state: %d, ip: %s)\n", acc.userid, state, ip);
-
- if (acc.state == 0) {
- unsigned char buf[16];
- WBUFW(buf,0) = 0x2731;
- WBUFL(buf,2) = acc.account_id;
- WBUFB(buf,6) = 0; // 0: change of statut, 1: ban
- WBUFL(buf,7) = state; // status or final date of a banishment
- charif_sendallwos(-1, buf, 11);
- }
- acc.state = state;
- accounts->save(accounts, &acc);
- }
- }
- else
- {
- ShowNotice("'ladmin': Attempt to modify the state of an unknown account (account: %s, received state: %d, ip: %s)\n", account_name, state, ip);
- WFIFOL(fd,2) = -1;
- memcpy(WFIFOP(fd,6), account_name, 24);
- }
-
- WFIFOL(fd,30) = state;
- WFIFOSET(fd,34);
- }
- RFIFOSKIP(fd,50);
- break;
-/*
- case 0x7938: // Request for servers list and # of online players
- {
- uint8 server_num = 0;
- ShowStatus("'ladmin': Sending of servers list (ip: %s)\n", ip);
- for(i = 0; i < MAX_SERVERS; i++) {
- if (server[i].fd >= 0) {
- WFIFOL(fd,4+server_num*32) = htonl(server[i].ip);
- WFIFOW(fd,4+server_num*32+4) = htons(server[i].port);
- memcpy(WFIFOP(fd,4+server_num*32+6), server[i].name, 20);
- WFIFOW(fd,4+server_num*32+26) = server[i].users;
- WFIFOW(fd,4+server_num*32+28) = server[i].maintenance;
- WFIFOW(fd,4+server_num*32+30) = server[i].new_;
- server_num++;
- }
- }
- WFIFOW(fd,0) = 0x7939;
- WFIFOW(fd,2) = 4 + 32 * server_num;
- WFIFOSET(fd,4+32*server_num);
- RFIFOSKIP(fd,2);
- break;
- }
-
- case 0x793a: // Request to password check
- if (RFIFOREST(fd) < 50)
- return 0;
- WFIFOW(fd,0) = 0x793b;
- WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- if( accounts->load_str(accounts, &acc, account_name) )
- {
- char pass[25];
- memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
- memcpy(pass, RFIFOP(fd,26), 24);
- pass[24] = '\0';
- remove_control_chars(pass);
- if (strcmp(acc.pass, pass) == 0) {
- WFIFOL(fd,2) = acc.account_id;
- ShowNotice("'ladmin': Check of password OK (account: %s, password: %s, ip: %s)\n", acc.userid, acc.pass, ip);
- } else {
- ShowNotice("'ladmin': Failure of password check (account: %s, proposed pass: %s, ip: %s)\n", acc.userid, pass, ip);
- }
- } else {
- memcpy(WFIFOP(fd,6), account_name, 24);
- ShowNotice("'ladmin': Attempt to check the password of an unknown account (account: %s, ip: %s)\n", account_name, ip);
- }
- WFIFOSET(fd,30);
- RFIFOSKIP(fd,50);
- break;
-
- case 0x793c: // Request to modify sex
- if (RFIFOREST(fd) < 27)
- return 0;
- WFIFOW(fd,0) = 0x793d;
- WFIFOL(fd,2) = 0xFFFFFFFF; // -1
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- memcpy(WFIFOP(fd,6), account_name, 24);
- {
- char sex;
- sex = RFIFOB(fd,26);
- if (sex != 'F' && sex != 'M') {
- if (sex > 31)
- ShowNotice("'ladmin': Attempt to give an invalid sex (account: %s, received sex: %c, ip: %s)\n", account_name, sex, ip);
- else
- ShowNotice("'ladmin': Attempt to give an invalid sex (account: %s, received sex: 'control char', ip: %s)\n", account_name, ip);
- } else {
- if( accounts->load_str(accounts, &acc, account_name) )
- {
- memcpy(WFIFOP(fd,6), acc.userid, 24);
- if (acc.sex != sex)
- {
- unsigned char buf[16];
- ShowNotice("'ladmin': Modification of a sex (account: %s, new sex: %c, ip: %s)\n", acc.userid, sex, ip);
-
- WFIFOL(fd,2) = acc.account_id;
- acc.sex = sex;
- accounts->save(accounts, &acc);
-
- // send to all char-server the change
- WBUFW(buf,0) = 0x2723;
- WBUFL(buf,2) = acc.account_id;
- WBUFB(buf,6) = acc.sex;
- charif_sendallwos(-1, buf, 7);
- } else {
- ShowNotice("'ladmin': Modification of a sex, but the sex is already the good sex (account: %s, sex: %c, ip: %s)\n", acc.userid, sex, ip);
- }
- } else {
- ShowNotice("'ladmin': Attempt to modify the sex of an unknown account (account: %s, received sex: %c, ip: %s)\n", account_name, sex, ip);
- }
- }
- }
- WFIFOSET(fd,30);
- RFIFOSKIP(fd,27);
- break;
-
- case 0x793e: // Request to modify GM level
- if (RFIFOREST(fd) < 27)
- return 0;
- WFIFOW(fd,0) = 0x793f;
- WFIFOL(fd,2) = 0xFFFFFFFF; // -1
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- memcpy(WFIFOP(fd,6), account_name, 24);
- {
- char new_gm_level;
- new_gm_level = RFIFOB(fd,26);
- if( new_gm_level < 0 || new_gm_level > 99 )
- ShowNotice("'ladmin': Attempt to give an invalid GM level (account: %s, received GM level: %d, ip: %s)\n", account_name, (int)new_gm_level, ip);
- else
- if( !accounts->load_str(accounts, &acc, account_name) )
- ShowNotice("'ladmin': Attempt to modify the GM level of an unknown account (account: %s, received GM level: %d, ip: %s)\n", account_name, (int)new_gm_level, ip);
- else
- {
- memcpy(WFIFOP(fd,6), acc.userid, 24);
-
- if (isGM(acc.account_id) == new_gm_level)
- ShowNotice("'ladmin': Attempt to modify of a GM level, but the GM level is already the good GM level (account: %s (%d), GM level: %d, ip: %s)\n", acc.userid, acc.account_id, (int)new_gm_level, ip);
- else
- {
- //TODO: change level
- }
- }
- }
- WFIFOSET(fd,30);
- RFIFOSKIP(fd,27);
- break;
-
- case 0x7940: // Request to modify e-mail
- if (RFIFOREST(fd) < 66)
- return 0;
- WFIFOW(fd,0) = 0x7941;
- WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- memcpy(WFIFOP(fd,6), account_name, 24);
- {
- char email[40];
- memcpy(email, RFIFOP(fd,26), 40);
- if (e_mail_check(email) == 0) {
- ShowNotice("'ladmin': Attempt to give an invalid e-mail (account: %s, ip: %s)\n", account_name, ip);
- } else {
- remove_control_chars(email);
- i = search_account_index(account_name);
- if (i != -1) {
- memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
- memcpy(auth_dat[i].email, email, 40);
- WFIFOL(fd,2) = auth_dat[i].account_id;
- ShowNotice("'ladmin': Modification of an email (account: %s, new e-mail: %s, ip: %s)\n", auth_dat[i].userid, email, ip);
- mmo_auth_sync();
- } else {
- ShowNotice("'ladmin': Attempt to modify the e-mail of an unknown account (account: %s, received e-mail: %s, ip: %s)\n", account_name, email, ip);
- }
- }
- }
- WFIFOSET(fd,30);
- RFIFOSKIP(fd,66);
- break;
-
- case 0x7942: // Request to modify memo field
- if ((int)RFIFOREST(fd) < 28 || (int)RFIFOREST(fd) < (28 + RFIFOW(fd,26)))
- return 0;
- WFIFOW(fd,0) = 0x7943;
- WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- i = search_account_index(account_name);
- if (i != -1) {
- int size_of_memo = sizeof(auth_dat[i].memo);
- memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
- memset(auth_dat[i].memo, '\0', size_of_memo);
- if (RFIFOW(fd,26) == 0) {
- strncpy(auth_dat[i].memo, "-", size_of_memo);
- } else if (RFIFOW(fd,26) > size_of_memo - 1) {
- memcpy(auth_dat[i].memo, RFIFOP(fd,28), size_of_memo - 1);
- } else {
- memcpy(auth_dat[i].memo, RFIFOP(fd,28), RFIFOW(fd,26));
- }
- auth_dat[i].memo[size_of_memo - 1] = '\0';
- remove_control_chars(auth_dat[i].memo);
- WFIFOL(fd,2) = auth_dat[i].account_id;
- ShowNotice("'ladmin': Modification of a memo field (account: %s, new memo: %s, ip: %s)\n", auth_dat[i].userid, auth_dat[i].memo, ip);
- mmo_auth_sync();
- } else {
- memcpy(WFIFOP(fd,6), account_name, 24);
- ShowNotice("'ladmin': Attempt to modify the memo field of an unknown account (account: %s, ip: %s)\n", account_name, ip);
- }
- WFIFOSET(fd,30);
- RFIFOSKIP(fd,28 + RFIFOW(fd,26));
- break;
-
- case 0x7944: // Request to found an account id
- if (RFIFOREST(fd) < 26)
- return 0;
- WFIFOW(fd,0) = 0x7945;
- WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- i = search_account_index(account_name);
- if (i != -1) {
- memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
- WFIFOL(fd,2) = auth_dat[i].account_id;
- ShowNotice("'ladmin': Request (by the name) of an account id (account: %s, id: %d, ip: %s)\n", auth_dat[i].userid, auth_dat[i].account_id, ip);
- } else {
- memcpy(WFIFOP(fd,6), account_name, 24);
- ShowNotice("'ladmin': ID request (by the name) of an unknown account (account: %s, ip: %s)\n", account_name, ip);
- }
- WFIFOSET(fd,30);
- RFIFOSKIP(fd,26);
- break;
-
- case 0x7946: // Request to found an account name
- if (RFIFOREST(fd) < 6)
- return 0;
- WFIFOW(fd,0) = 0x7947;
- WFIFOL(fd,2) = RFIFOL(fd,2);
- memset(WFIFOP(fd,6), '\0', 24);
- for(i = 0; i < auth_num; i++) {
- if (auth_dat[i].account_id == (int)RFIFOL(fd,2)) {
- strncpy((char*)WFIFOP(fd,6), auth_dat[i].userid, 24);
- ShowNotice("'ladmin': Request (by id) of an account name (account: %s, id: %d, ip: %s)\n", auth_dat[i].userid, RFIFOL(fd,2), ip);
- break;
- }
- }
- if (i == auth_num) {
- ShowNotice("'ladmin': Name request (by id) of an unknown account (id: %d, ip: %s)\n", RFIFOL(fd,2), ip);
- strncpy((char*)WFIFOP(fd,6), "", 24);
- }
- WFIFOSET(fd,30);
- RFIFOSKIP(fd,6);
- break;
-
- case 0x7948: // Request to change the validity limit (timestamp) (absolute value)
- if (RFIFOREST(fd) < 30)
- return 0;
- {
- time_t timestamp;
- char tmpstr[2048];
- WFIFOW(fd,0) = 0x7949;
- WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- timestamp = (time_t)RFIFOL(fd,26);
- strftime(tmpstr, 24, login_config.date_format, localtime(&timestamp));
- i = search_account_index(account_name);
- if (i != -1) {
- memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
- ShowNotice("'ladmin': Change of a validity limit (account: %s, new validity: %d (%s), ip: %s)\n", auth_dat[i].userid, timestamp, (timestamp == 0 ? "unlimited" : tmpstr), ip);
- auth_dat[i].expiration_time = timestamp;
- WFIFOL(fd,2) = auth_dat[i].account_id;
- mmo_auth_sync();
- } else {
- memcpy(WFIFOP(fd,6), account_name, 24);
- ShowNotice("'ladmin': Attempt to change the validity limit of an unknown account (account: %s, received validity: %d (%s), ip: %s)\n", account_name, timestamp, (timestamp == 0 ? "unlimited" : tmpstr), ip);
- }
- WFIFOL(fd,30) = (unsigned int)timestamp;
- }
- WFIFOSET(fd,34);
- RFIFOSKIP(fd,30);
- break;
-
- case 0x794a: // Request to change the final date of a banishment (timestamp) (absolute value)
- if (RFIFOREST(fd) < 30)
- return 0;
- {
- time_t timestamp;
- char tmpstr[2048];
- WFIFOW(fd,0) = 0x794b;
- WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- timestamp = (time_t)RFIFOL(fd,26);
- if (timestamp <= time(NULL))
- timestamp = 0;
- strftime(tmpstr, 24, login_config.date_format, localtime(&timestamp));
- i = search_account_index(account_name);
- if (i != -1) {
- memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
- WFIFOL(fd,2) = auth_dat[i].account_id;
- ShowNotice("'ladmin': Change of the final date of a banishment (account: %s, new final date of banishment: %d (%s), ip: %s)\n", auth_dat[i].userid, timestamp, (timestamp == 0 ? "no banishment" : tmpstr), ip);
- if (auth_dat[i].unban_time != timestamp) {
- if (timestamp != 0) {
- unsigned char buf[16];
- WBUFW(buf,0) = 0x2731;
- WBUFL(buf,2) = auth_dat[i].account_id;
- WBUFB(buf,6) = 1; // 0: change of statut, 1: ban
- WBUFL(buf,7) = (unsigned int)timestamp; // status or final date of a banishment
- charif_sendallwos(-1, buf, 11);
- }
- auth_dat[i].unban_time = timestamp;
- mmo_auth_sync();
- }
- } else {
- memcpy(WFIFOP(fd,6), account_name, 24);
- ShowNotice("'ladmin': Attempt to change the final date of a banishment of an unknown account (account: %s, received final date of banishment: %d (%s), ip: %s)\n", account_name, timestamp, (timestamp == 0 ? "no banishment" : tmpstr), ip);
- }
- WFIFOL(fd,30) = (unsigned int)timestamp;
- }
- WFIFOSET(fd,34);
- RFIFOSKIP(fd,30);
- break;
-
- case 0x794c: // Request to change the final date of a banishment (timestamp) (relative change)
- if (RFIFOREST(fd) < 38)
- return 0;
- {
- time_t timestamp;
- struct tm *tmtime;
- char tmpstr[2048];
- WFIFOW(fd,0) = 0x794d;
- WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- i = search_account_index(account_name);
- if (i != -1) {
- WFIFOL(fd,2) = auth_dat[i].account_id;
- memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
- if (auth_dat[i].unban_time == 0 || auth_dat[i].unban_time < time(NULL))
- timestamp = time(NULL);
- else
- timestamp = auth_dat[i].unban_time;
- tmtime = localtime(&timestamp);
- tmtime->tm_year = tmtime->tm_year + (short)RFIFOW(fd,26);
- tmtime->tm_mon = tmtime->tm_mon + (short)RFIFOW(fd,28);
- tmtime->tm_mday = tmtime->tm_mday + (short)RFIFOW(fd,30);
- tmtime->tm_hour = tmtime->tm_hour + (short)RFIFOW(fd,32);
- tmtime->tm_min = tmtime->tm_min + (short)RFIFOW(fd,34);
- tmtime->tm_sec = tmtime->tm_sec + (short)RFIFOW(fd,36);
- timestamp = mktime(tmtime);
- if (timestamp != -1) {
- if (timestamp <= time(NULL))
- timestamp = 0;
- strftime(tmpstr, 24, login_config.date_format, localtime(&timestamp));
- ShowNotice("'ladmin': Adjustment of a final date of a banishment (account: %s, (%+d y %+d m %+d d %+d h %+d mn %+d s) -> new validity: %d (%s), ip: %s)\n", auth_dat[i].userid, (short)RFIFOW(fd,26), (short)RFIFOW(fd,28), (short)RFIFOW(fd,30), (short)RFIFOW(fd,32), (short)RFIFOW(fd,34), (short)RFIFOW(fd,36), timestamp, (timestamp == 0 ? "no banishment" : tmpstr), ip);
- if (auth_dat[i].unban_time != timestamp) {
- if (timestamp != 0) {
- unsigned char buf[16];
- WBUFW(buf,0) = 0x2731;
- WBUFL(buf,2) = auth_dat[i].account_id;
- WBUFB(buf,6) = 1; // 0: change of statut, 1: ban
- WBUFL(buf,7) = (unsigned int)timestamp; // status or final date of a banishment
- charif_sendallwos(-1, buf, 11);
- }
- auth_dat[i].unban_time = timestamp;
- mmo_auth_sync();
- }
- } else {
- strftime(tmpstr, 24, login_config.date_format, localtime(&auth_dat[i].unban_time));
- ShowNotice("'ladmin': Impossible to adjust the final date of a banishment (account: %s, %d (%s) + (%+d y %+d m %+d d %+d h %+d mn %+d s) -> ???, ip: %s)\n", auth_dat[i].userid, auth_dat[i].unban_time, (auth_dat[i].unban_time == 0 ? "no banishment" : tmpstr), (short)RFIFOW(fd,26), (short)RFIFOW(fd,28), (short)RFIFOW(fd,30), (short)RFIFOW(fd,32), (short)RFIFOW(fd,34), (short)RFIFOW(fd,36), ip);
- }
- WFIFOL(fd,30) = (unsigned long)auth_dat[i].unban_time;
- } else {
- memcpy(WFIFOP(fd,6), account_name, 24);
- ShowNotice("'ladmin': Attempt to adjust the final date of a banishment of an unknown account (account: %s, ip: %s)\n", account_name, ip);
- WFIFOL(fd,30) = 0;
- }
- }
- WFIFOSET(fd,34);
- RFIFOSKIP(fd,38);
- break;
-
- case 0x794e: // Request to send a broadcast message
- if (RFIFOREST(fd) < 8 || RFIFOREST(fd) < (8 + RFIFOL(fd,4)))
- return 0;
- WFIFOW(fd,0) = 0x794f;
- WFIFOW(fd,2) = 0xFFFF; // WTF???
- if (RFIFOL(fd,4) < 1) {
- ShowNotice("'ladmin': Receiving a message for broadcast, but message is void (ip: %s)\n", ip);
- } else {
- // at least 1 char-server
- for(i = 0; i < MAX_SERVERS; i++)
- if (server[i].fd >= 0)
- break;
- if (i == MAX_SERVERS) {
- ShowNotice("'ladmin': Receiving a message for broadcast, but no char-server is online (ip: %s)\n", ip);
- } else {
- unsigned char buf[32000];
- char message[32000];
- WFIFOW(fd,2) = 0;
- memset(message, '\0', sizeof(message));
- memcpy(message, RFIFOP(fd,8), RFIFOL(fd,4));
- message[sizeof(message)-1] = '\0';
- remove_control_chars(message);
- if (RFIFOW(fd,2) == 0)
- ShowNotice("'ladmin': Receiving a message for broadcast (message (in yellow): %s, ip: %s)\n", message, ip);
- else
- ShowNotice("'ladmin': Receiving a message for broadcast (message (in blue): %s, ip: %s)\n", message, ip);
- // send same message to all char-servers (no answer)
- memcpy(WBUFP(buf,0), RFIFOP(fd,0), 8 + RFIFOL(fd,4));
- WBUFW(buf,0) = 0x2726;
- charif_sendallwos(-1, buf, 8 + RFIFOL(fd,4));
- }
- }
- WFIFOSET(fd,4);
- RFIFOSKIP(fd,8 + RFIFOL(fd,4));
- break;
-
- case 0x7950: // Request to change the validity limite (timestamp) (relative change)
- if (RFIFOREST(fd) < 38)
- return 0;
- {
- time_t timestamp;
- struct tm *tmtime;
- char tmpstr[2048];
- char tmpstr2[2048];
- WFIFOW(fd,0) = 0x7951;
- WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- i = search_account_index(account_name);
- if (i != -1) {
- WFIFOL(fd,2) = auth_dat[i].account_id;
- memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
- timestamp = auth_dat[i].expiration_time;
- if (timestamp == 0 || timestamp < time(NULL))
- timestamp = time(NULL);
- tmtime = localtime(&timestamp);
- tmtime->tm_year = tmtime->tm_year + (short)RFIFOW(fd,26);
- tmtime->tm_mon = tmtime->tm_mon + (short)RFIFOW(fd,28);
- tmtime->tm_mday = tmtime->tm_mday + (short)RFIFOW(fd,30);
- tmtime->tm_hour = tmtime->tm_hour + (short)RFIFOW(fd,32);
- tmtime->tm_min = tmtime->tm_min + (short)RFIFOW(fd,34);
- tmtime->tm_sec = tmtime->tm_sec + (short)RFIFOW(fd,36);
- timestamp = mktime(tmtime);
- if (timestamp != -1) {
- strftime(tmpstr, 24, login_config.date_format, localtime(&auth_dat[i].expiration_time));
- strftime(tmpstr2, 24, login_config.date_format, localtime(&timestamp));
- ShowNotice("'ladmin': Adjustment of a validity limit (account: %s, %d (%s) + (%+d y %+d m %+d d %+d h %+d mn %+d s) -> new validity: %d (%s), ip: %s)\n", auth_dat[i].userid, auth_dat[i].expiration_time, (auth_dat[i].expiration_time == 0 ? "unlimited" : tmpstr), (short)RFIFOW(fd,26), (short)RFIFOW(fd,28), (short)RFIFOW(fd,30), (short)RFIFOW(fd,32), (short)RFIFOW(fd,34), (short)RFIFOW(fd,36), timestamp, (timestamp == 0 ? "unlimited" : tmpstr2), ip);
- auth_dat[i].expiration_time = timestamp;
- mmo_auth_sync();
- WFIFOL(fd,30) = (unsigned long)auth_dat[i].expiration_time;
- } else {
- strftime(tmpstr, 24, login_config.date_format, localtime(&auth_dat[i].expiration_time));
- ShowNotice("'ladmin': Impossible to adjust a validity limit (account: %s, %d (%s) + (%+d y %+d m %+d d %+d h %+d mn %+d s) -> ???, ip: %s)\n", auth_dat[i].userid, auth_dat[i].expiration_time, (auth_dat[i].expiration_time == 0 ? "unlimited" : tmpstr), (short)RFIFOW(fd,26), (short)RFIFOW(fd,28), (short)RFIFOW(fd,30), (short)RFIFOW(fd,32), (short)RFIFOW(fd,34), (short)RFIFOW(fd,36), ip);
- WFIFOL(fd,30) = 0;
- }
- } else {
- memcpy(WFIFOP(fd,6), account_name, 24);
- ShowNotice("'ladmin': Attempt to adjust the validity limit of an unknown account (account: %s, ip: %s)\n", account_name, ip);
- WFIFOL(fd,30) = 0;
- }
-
- WFIFOSET(fd,34);
- }
- RFIFOSKIP(fd,38);
- break;
-*/
- case 0x7952: // Request about informations of an account (by account name)
- if (RFIFOREST(fd) < 26)
- return 0;
- {
- struct mmo_account acc;
-
- WFIFOW(fd,0) = 0x7953;
-
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
-
- if( accounts->load_str(accounts, &acc, account_name) )
- {
- ShowNotice("'ladmin': Sending information of an account (request by the name; account: %s, id: %d, ip: %s)\n", acc.userid, acc.account_id, ip);
- WFIFOL(fd,2) = acc.account_id;
- WFIFOB(fd,6) = acc.level;
- safestrncpy((char*)WFIFOP(fd,7), acc.userid, 24);
- WFIFOB(fd,31) = acc.sex;
- WFIFOL(fd,32) = acc.logincount;
- WFIFOL(fd,36) = acc.state;
- safestrncpy((char*)WFIFOP(fd,40), "-", 20); // error message (removed)
- safestrncpy((char*)WFIFOP(fd,60), acc.lastlogin, 24);
- safestrncpy((char*)WFIFOP(fd,84), acc.last_ip, 16);
- safestrncpy((char*)WFIFOP(fd,100), acc.email, 40);
- WFIFOL(fd,140) = (unsigned long)acc.expiration_time;
- WFIFOL(fd,144) = (unsigned long)acc.unban_time;
- WFIFOW(fd,148) = 0; // previously, this was strlen(memo), and memo went afterwards
- }
- else
- {
- ShowNotice("'ladmin': Attempt to obtain information (by the name) of an unknown account (account: %s, ip: %s)\n", account_name, ip);
- WFIFOL(fd,2) = -1;
- safestrncpy((char*)WFIFOP(fd,7), account_name, 24); // not found
- }
-
- WFIFOSET(fd,150);
- }
- RFIFOSKIP(fd,26);
- break;
-
- case 0x7954: // Request about information of an account (by account id)
- if (RFIFOREST(fd) < 6)
- return 0;
- {
- struct mmo_account acc;
-
- int account_id = RFIFOL(fd,2);
-
- WFIFOHEAD(fd,150);
- WFIFOW(fd,0) = 0x7953;
- WFIFOL(fd,2) = account_id;
-
- if( accounts->load_num(accounts, &acc, account_id) )
- {
- ShowNotice("'ladmin': Sending information of an account (request by the id; account: %s, id: %d, ip: %s)\n", acc.userid, account_id, ip);
- WFIFOB(fd,6) = acc.level;
- safestrncpy((char*)WFIFOP(fd,7), acc.userid, 24);
- WFIFOB(fd,31) = acc.sex;
- WFIFOL(fd,32) = acc.logincount;
- WFIFOL(fd,36) = acc.state;
- safestrncpy((char*)WFIFOP(fd,40), "-", 20); // error message (removed)
- safestrncpy((char*)WFIFOP(fd,60), acc.lastlogin, 24);
- safestrncpy((char*)WFIFOP(fd,84), acc.last_ip, 16);
- safestrncpy((char*)WFIFOP(fd,100), acc.email, 40);
- WFIFOL(fd,140) = (unsigned long)acc.expiration_time;
- WFIFOL(fd,144) = (unsigned long)acc.unban_time;
- WFIFOW(fd,148) = 0; // previously, this was strlen(memo), and memo went afterwards
- }
- else
- {
- ShowNotice("'ladmin': Attempt to obtain information (by the id) of an unknown account (id: %d, ip: %s)\n", account_id, ip);
- safestrncpy((char*)WFIFOP(fd,7), "", 24); // not found
- }
-
- WFIFOSET(fd,150);
- }
- RFIFOSKIP(fd,6);
- break;
-
- default:
- ShowStatus("'ladmin': End of connection, unknown packet (ip: %s)\n", ip);
- set_eof(fd);
- return 0;
- }
- }
- RFIFOSKIP(fd,RFIFOREST(fd));
- return 0;
-}
diff --git a/src/login/login.c b/src/login/login.c
index 6b3a1bcaf..6a8525930 100644
--- a/src/login/login.c
+++ b/src/login/login.c
@@ -19,7 +19,6 @@
#include <stdlib.h>
#include <string.h>
-bool ladmin_auth(struct login_session_data* sd, const char* ip);
struct Login_Config login_config;
int login_fd; // login server socket
@@ -70,6 +69,7 @@ struct s_subnet {
int subnet_count = 0;
+int mmo_auth_new(const char* userid, const char* pass, const char sex, const char* last_ip);
//-----------------------------------------------------
// Auth database
@@ -109,7 +109,7 @@ static void* create_online_user(DBKey key, va_list args)
CREATE(p, struct online_login_data, 1);
p->account_id = key.i;
p->char_server = -1;
- p->waiting_disconnect = -1;
+ p->waiting_disconnect = INVALID_TIMER;
return p;
}
@@ -118,10 +118,10 @@ struct online_login_data* add_online_user(int char_server, int account_id)
struct online_login_data* p;
p = (struct online_login_data*)idb_ensure(online_db, account_id, create_online_user);
p->char_server = char_server;
- if( p->waiting_disconnect != -1 )
+ if( p->waiting_disconnect != INVALID_TIMER )
{
delete_timer(p->waiting_disconnect, waiting_disconnect_timer);
- p->waiting_disconnect = -1;
+ p->waiting_disconnect = INVALID_TIMER;
}
return p;
}
@@ -132,7 +132,7 @@ void remove_online_user(int account_id)
p = (struct online_login_data*)idb_get(online_db, account_id);
if( p == NULL )
return;
- if( p->waiting_disconnect != -1 )
+ if( p->waiting_disconnect != INVALID_TIMER )
delete_timer(p->waiting_disconnect, waiting_disconnect_timer);
idb_remove(online_db, account_id);
@@ -143,7 +143,7 @@ static int waiting_disconnect_timer(int tid, unsigned int tick, int id, intptr d
struct online_login_data* p = (struct online_login_data*)idb_get(online_db, id);
if( p != NULL && p->waiting_disconnect == tid && p->account_id == id )
{
- p->waiting_disconnect = -1;
+ p->waiting_disconnect = INVALID_TIMER;
remove_online_user(id);
idb_remove(auth_db, id);
}
@@ -157,10 +157,10 @@ static int online_db_setoffline(DBKey key, void* data, va_list ap)
if( server == -1 )
{
p->char_server = -1;
- if( p->waiting_disconnect != -1 )
+ if( p->waiting_disconnect != INVALID_TIMER )
{
delete_timer(p->waiting_disconnect, waiting_disconnect_timer);
- p->waiting_disconnect = -1;
+ p->waiting_disconnect = INVALID_TIMER;
}
}
else if( p->char_server == server )
@@ -323,32 +323,49 @@ int login_lan_config_read(const char *lancfgName)
//-----------------------
// Console Command Parser [Wizputer]
//-----------------------
-int parse_console(char* buf)
+int parse_console(const char* command)
{
- char command[256];
+ ShowNotice("Console command: %s\n", command);
- memset(command, 0, sizeof(command));
-
- sscanf(buf, "%[^\n]", command);
-
- ShowInfo("Console command :%s", command);
-
- if( strcmpi("shutdown", command) == 0 ||
- strcmpi("exit", command) == 0 ||
- strcmpi("quit", command) == 0 ||
- strcmpi("end", command) == 0 )
+ if( strcmpi("shutdown", command) == 0 || strcmpi("exit", command) == 0 || strcmpi("quit", command) == 0 || strcmpi("end", command) == 0 )
runflag = 0;
- else
- if( strcmpi("alive", command) == 0 ||
- strcmpi("status", command) == 0 )
+ else if( strcmpi("alive", command) == 0 || strcmpi("status", command) == 0 )
ShowInfo(CL_CYAN"Console: "CL_BOLD"I'm Alive."CL_RESET"\n");
- else
- if( strcmpi("help", command) == 0 ) {
- ShowInfo(CL_BOLD"Help of commands:"CL_RESET"\n");
- ShowInfo(" To shutdown the server:\n");
+ else if( strcmpi("help", command) == 0 )
+ {
+ ShowInfo("To shutdown the server:\n");
ShowInfo(" 'shutdown|exit|quit|end'\n");
- ShowInfo(" To know if server is alive:\n");
+ ShowInfo("To know if server is alive:\n");
ShowInfo(" 'alive|status'\n");
+ ShowInfo("To create a new account:\n");
+ ShowInfo(" 'create'\n");
+ }
+ else
+ {// commands with parameters
+ char cmd[128], params[256];
+
+ if( sscanf(command, "%127s %255[^\r\n]", cmd, params) < 2 )
+ {
+ return 0;
+ }
+
+ if( strcmpi(cmd, "create") == 0 )
+ {
+ char username[NAME_LENGTH], password[NAME_LENGTH], sex;
+
+ if( sscanf(params, "%23s %23s %c", username, password, &sex) < 3 || strnlen(username, sizeof(username)) < 4 || strnlen(password, sizeof(password)) < 1 )
+ {
+ ShowWarning("Console: Invalid parameters for '%s'. Usage: %s <username> <password> <sex:F/M>\n", cmd, cmd);
+ return 0;
+ }
+
+ if( mmo_auth_new(username, password, TOUPPER(sex), "0.0.0.0") != -1 )
+ {
+ ShowError("Console: Account creation failed.\n");
+ return 0;
+ }
+ ShowStatus("Console: Account '%s' created successfully.\n", username);
+ }
}
return 0;
@@ -524,8 +541,6 @@ int parse_fromchar(int fd)
break;
case 0x2719: // ping request from charserver
- if( RFIFOREST(fd) < 2 )
- return 0;
RFIFOSKIP(fd,2);
WFIFOHEAD(fd,2);
@@ -733,8 +748,8 @@ int parse_fromchar(int fd)
// Sending information towards the other char-servers.
RFIFOW(fd,0) = 0x2729;// reusing read buffer
charif_sendallwos(fd, RFIFOP(fd,0), RFIFOW(fd,2));
- RFIFOSKIP(fd,RFIFOW(fd,2));
}
+ RFIFOSKIP(fd,RFIFOW(fd,2));
}
break;
@@ -788,10 +803,10 @@ int parse_fromchar(int fd)
aid = RFIFOL(fd,6+i*4);
p = (struct online_login_data*)idb_ensure(online_db, aid, create_online_user);
p->char_server = id;
- if (p->waiting_disconnect != -1)
+ if (p->waiting_disconnect != INVALID_TIMER)
{
delete_timer(p->waiting_disconnect, waiting_disconnect_timer);
- p->waiting_disconnect = -1;
+ p->waiting_disconnect = INVALID_TIMER;
}
}
}
@@ -854,7 +869,6 @@ int parse_fromchar(int fd)
} // switch
} // while
- RFIFOSKIP(fd,RFIFOREST(fd));
return 0;
}
@@ -898,6 +912,7 @@ int mmo_auth_new(const char* userid, const char* pass, const char sex, const cha
acc.expiration_time = ( login_config.start_limited_time != -1 ) ? time(NULL) + login_config.start_limited_time : 0;
safestrncpy(acc.lastlogin, "0000-00-00 00:00:00", sizeof(acc.lastlogin));
safestrncpy(acc.last_ip, last_ip, sizeof(acc.last_ip));
+ safestrncpy(acc.birthdate, "0000-00-00", sizeof(acc.birthdate));
if( !accounts->create(accounts, &acc) )
return 0;
@@ -1077,7 +1092,7 @@ void login_auth_ok(struct login_session_data* sd)
WBUFW(buf,0) = 0x2734;
WBUFL(buf,2) = sd->account_id;
charif_sendallwos(-1, buf, 6);
- if( data->waiting_disconnect == -1 )
+ if( data->waiting_disconnect == INVALID_TIMER )
data->waiting_disconnect = add_timer(gettick()+AUTH_TIMEOUT, waiting_disconnect_timer, sd->account_id, 0);
WFIFOHEAD(fd,3);
@@ -1209,7 +1224,7 @@ void login_auth_failed(struct login_session_data* sd, int result)
//----------------------------------------------------------------------------------------
-// Default packet parsing (normal players or administation/char-server connection requests)
+// Default packet parsing (normal players or char-server connection requests)
//----------------------------------------------------------------------------------------
int parse_login(int fd)
{
@@ -1343,7 +1358,6 @@ int parse_login(int fd)
break;
case 0x01db: // Sending request of the coding key
- case 0x791a: // Sending request of the coding key (administration packet)
RFIFOSKIP(fd,2);
{
memset(sd->md5key, '\0', sizeof(sd->md5key));
@@ -1419,45 +1433,6 @@ int parse_login(int fd)
}
return 0; // processing will continue elsewhere
- case 0x7530: // Server version information request
- ShowStatus("Sending server version information to ip: %s\n", ip);
- RFIFOSKIP(fd,2);
- WFIFOHEAD(fd,10);
- WFIFOW(fd,0) = 0x7531;
- WFIFOB(fd,2) = ATHENA_MAJOR_VERSION;
- WFIFOB(fd,3) = ATHENA_MINOR_VERSION;
- WFIFOB(fd,4) = ATHENA_REVISION;
- WFIFOB(fd,5) = ATHENA_RELEASE_FLAG;
- WFIFOB(fd,6) = ATHENA_OFFICIAL_FLAG;
- WFIFOB(fd,7) = ATHENA_SERVER_LOGIN;
- WFIFOW(fd,8) = ATHENA_MOD_VERSION;
- WFIFOSET(fd,10);
- break;
-
- case 0x7918: // Request for administation login
- if ((int)RFIFOREST(fd) < 4 || (int)RFIFOREST(fd) < ((RFIFOW(fd,2) == 0) ? 28 : 20))
- return 0;
- {
- int passwdenc = (int)RFIFOW(fd,2);
- const char* passwd = (char*)RFIFOP(fd,4);
-
- if( passwdenc == 0 ) { // non encrypted password
- safestrncpy(sd->passwd, passwd, NAME_LENGTH);
- sd->passwdenc = 0;
- } else { // encrypted password
- memcpy(sd->passwd, passwd, 16); sd->passwd[16] = '\0'; // raw binary data here!
- sd->passwdenc = passwdenc;
- }
-
- RFIFOSKIP(fd, (passwdenc == 0) ? 28 : 20);
-
- WFIFOHEAD(fd,3);
- WFIFOW(fd,0) = 0x7919;
- WFIFOB(fd,2) = ladmin_auth(sd, ip) ? 0 : 1;
- WFIFOSET(fd,3);
- }
- break;
-
default:
ShowNotice("Abnormal end of connection (ip: %s): Unknown packet 0x%x\n", ip, command);
set_eof(fd);
@@ -1465,7 +1440,6 @@ int parse_login(int fd)
}
}
- RFIFOSKIP(fd,RFIFOREST(fd));
return 0;
}
@@ -1564,14 +1538,6 @@ int login_config_read(const char* cfgName)
login_config.ipban_cleanup_interval = (unsigned int)atoi(w2);
else if(!strcmpi(w1, "ip_sync_interval"))
login_config.ip_sync_interval = (unsigned int)1000*60*atoi(w2); //w2 comes in minutes.
-
- else if(!strcmpi(w1, "admin_state"))
- login_config.admin_state = (bool)config_switch(w2);
- else if(!strcmpi(w1, "admin_pass"))
- safestrncpy(login_config.admin_pass, w2, sizeof(login_config.admin_pass));
- else if(!strcmpi(w1, "admin_allowed_host"))
- safestrncpy(login_config.admin_allowed_host, w2, sizeof(login_config.admin_pass));
-
else if(!strcmpi(w1, "import"))
login_config_read(w2);
else
diff --git a/src/login/login.h b/src/login/login.h
index 807caaed6..f338a09e1 100644
--- a/src/login/login.h
+++ b/src/login/login.h
@@ -60,10 +60,6 @@ struct Login_Config {
bool check_client_version; // check the clientversion set in the clientinfo ?
uint32 client_version_to_connect; // the client version needed to connect (if checking is enabled)
- bool admin_state; // is ladmin support enabled?
- char admin_pass[24]; // security password for ladmin
- char admin_allowed_host[32]; // host/ip that is allowed to connect as ladmin
-
bool ipban; // perform IP blocking (via contents of `ipbanlist`) ?
bool dynamic_pass_failure_ban; // automatic IP blocking due to failed login attemps ?
unsigned int dynamic_pass_failure_ban_interval; // how far to scan the loginlog for password failures
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 95b3dc33e..cebd881ce 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -1937,7 +1937,7 @@ static int atcommand_pvpoff_sub(struct block_list *bl,va_list ap)
{
TBL_PC* sd = (TBL_PC*)bl;
clif_pvpset(sd, 0, 0, 2);
- if (sd->pvp_timer != -1) {
+ if (sd->pvp_timer != INVALID_TIMER) {
delete_timer(sd->pvp_timer, pc_calc_pvprank_timer);
sd->pvp_timer = INVALID_TIMER;
}
@@ -1969,7 +1969,7 @@ ACMD_FUNC(pvpoff)
static int atcommand_pvpon_sub(struct block_list *bl,va_list ap)
{
TBL_PC* sd = (TBL_PC*)bl;
- if (sd->pvp_timer == -1) {
+ if (sd->pvp_timer == INVALID_TIMER) {
sd->pvp_timer = add_timer(gettick() + 200, pc_calc_pvprank_timer, sd->bl.id, 0);
sd->pvp_rank = 0;
sd->pvp_lastusers = 0;
@@ -6095,7 +6095,7 @@ ACMD_FUNC(autoloot)
}
/*==========================================
- * @autolootitem
+ * @alootid
*------------------------------------------*/
ACMD_FUNC(autolootitem)
{
@@ -6104,9 +6104,9 @@ ACMD_FUNC(autolootitem)
if (!message || !*message) {
if (sd->state.autolootid) {
sd->state.autolootid = 0;
- clif_displaymessage(fd, "Autolootitem have been turned OFF.");
+ clif_displaymessage(fd, "Autolootitem has been turned OFF.");
} else
- clif_displaymessage(fd, "Please, enter Item name or its ID (usage: @autolootitem <item_name_or_ID>).");
+ clif_displaymessage(fd, "Please, enter item name or it's ID (usage: @alootid <item_name_or_ID>).");
return -1;
}
@@ -6122,7 +6122,7 @@ ACMD_FUNC(autolootitem)
sd->state.autolootid = item_data->nameid; // Autoloot Activated
- sprintf(atcmd_output, "Autolooting Item: '%s'/'%s' {%d}",
+ sprintf(atcmd_output, "Autolooting item: '%s'/'%s' (%d)",
item_data->name, item_data->jname, item_data->nameid);
clif_displaymessage(fd, atcmd_output);
@@ -6741,7 +6741,7 @@ ACMD_FUNC(unmute)
}
pl_sd->status.manner = 0;
- status_change_end(&pl_sd->bl,SC_NOCHAT,-1);
+ status_change_end(&pl_sd->bl, SC_NOCHAT, INVALID_TIMER);
clif_displaymessage(sd->fd,"Player unmuted");
return 0;
@@ -6815,7 +6815,7 @@ ACMD_FUNC(mute)
sc_start(&pl_sd->bl,SC_NOCHAT,100,0,0);
} else {
pl_sd->status.manner = 0;
- status_change_end(&pl_sd->bl,SC_NOCHAT,-1);
+ status_change_end(&pl_sd->bl, SC_NOCHAT, INVALID_TIMER);
}
clif_GM_silence(sd, pl_sd, (manner > 0 ? 1 : 0));
@@ -6986,7 +6986,7 @@ ACMD_FUNC(mobinfo)
strcpy(atcmd_output, " ");
j = 0;
for (i = 0; i < MAX_MOB_DROP; i++) {
- if (mob->dropitem[i].nameid <= 0 || mob->dropitem[i].p < 1 || (item_data = itemdb_search(mob->dropitem[i].nameid)) == NULL)
+ if (mob->dropitem[i].nameid <= 0 || mob->dropitem[i].p < 1 || (item_data = itemdb_exists(mob->dropitem[i].nameid)) == NULL)
continue;
if (item_data->slot)
sprintf(atcmd_output2, " - %s[%d] %02.02f%%", item_data->jname, item_data->slot, (float)mob->dropitem[i].p / 100);
@@ -7009,7 +7009,7 @@ ACMD_FUNC(mobinfo)
strcpy(atcmd_output, " MVP Items:");
j = 0;
for (i = 0; i < 3; i++) {
- if (mob->mvpitem[i].nameid <= 0 || (item_data = itemdb_search(mob->mvpitem[i].nameid)) == NULL)
+ if (mob->mvpitem[i].nameid <= 0 || (item_data = itemdb_exists(mob->mvpitem[i].nameid)) == NULL)
continue;
if (mob->mvpitem[i].p > 0) {
j++;
@@ -7115,19 +7115,18 @@ ACMD_FUNC(homlevel)
nullpo_retr(-1, sd);
- if (!message || !*message) {
- clif_displaymessage(fd, "Please, enter a level adjustment: (usage: @homlevel <+/- # of levels>.");
+ if ( !message || !*message || ( level = atoi(message) ) < 1 ) {
+ clif_displaymessage(fd, "Please, enter a level adjustment: (usage: @homlevel <# of levels to level up>.");
return -1;
}
-
+
if ( !merc_is_hom_active(sd->hd) ) {
clif_displaymessage(fd, "You do not have a homunculus.");
return -1;
}
- level = atoi(message);
hd = sd->hd;
-
+
for (i = 1; i <= level && hd->exp_next; i++){
hd->homunculus.exp += hd->exp_next;
merc_hom_levelup(hd);
@@ -7616,8 +7615,8 @@ static int atcommand_mutearea_sub(struct block_list *bl,va_list ap)
pl_sd->status.manner -= time;
if (pl_sd->status.manner < 0)
sc_start(&pl_sd->bl,SC_NOCHAT,100,0,0);
- else if (pl_sd->sc.data[SC_NOCHAT])
- status_change_end(&pl_sd->bl, SC_NOCHAT, -1);
+ else
+ status_change_end(&pl_sd->bl, SC_NOCHAT, INVALID_TIMER);
}
return 0;
}
@@ -7964,6 +7963,13 @@ ACMD_FUNC(accept)
return 0;
}
+ if( duel_list[sd->duel_invite].max_players_limit > 0 && duel_list[sd->duel_invite].members_count >= duel_list[sd->duel_invite].max_players_limit )
+ {
+ // "Duel: Limit of players is reached."
+ clif_displaymessage(fd, msg_txt(351));
+ return 0;
+ }
+
duel_accept(sd->duel_invite, sd);
// "Duel: Invitation has been accepted."
clif_displaymessage(fd, msg_txt(361));
@@ -8015,30 +8021,6 @@ ACMD_FUNC(cash)
return 0;
}
-/*===================================
- * Away message (@away, @aw) [LuzZza]
- *-----------------------------------*/
-ACMD_FUNC(away)
-{
- if(strlen(message) > 0) {
- if(strlen(message) > 128)
- return -1;
- strcpy(sd->away_message, message);
- //"Away automessage has been activated."
- clif_displaymessage(fd, msg_txt(546));
- } else {
- if(strlen(sd->away_message) > 0) {
- sd->away_message[0] = 0;
- //"Away automessage has been disabled."
- clif_displaymessage(fd, msg_txt(547));
- return 0;
- }
- //"Usage: @away,@aw <message>. Enter empty message for disable it."
- clif_displaymessage(fd, msg_txt(548));
- }
- return 0;
-}
-
// @clone/@slaveclone/@evilclone <playername> [Valaris]
ACMD_FUNC(clone)
{
@@ -8323,7 +8305,7 @@ ACMD_FUNC(itemlist)
const struct item* it = &items[i];
struct item_data* itd;
- if( it->nameid == 0 || (itd = itemdb_search(it->nameid)) == NULL )
+ if( it->nameid == 0 || (itd = itemdb_exists(it->nameid)) == NULL )
continue;
counter += it->amount;
@@ -8406,7 +8388,7 @@ ACMD_FUNC(itemlist)
{
struct item_data* card;
- if( it->card[j] == 0 || (card = itemdb_search(it->card[j])) == NULL )
+ if( it->card[j] == 0 || (card = itemdb_exists(it->card[j])) == NULL )
continue;
counter2++;
@@ -8872,8 +8854,6 @@ AtCommandInfo atcommand_info[] = {
{ "leave", 1,1, atcommand_leave },
{ "accept", 1,1, atcommand_accept },
{ "reject", 1,1, atcommand_reject },
- { "away", 1,1, atcommand_away },
- { "aw", 1,1, atcommand_away },
{ "main", 1,1, atcommand_main },
{ "clone", 50,50, atcommand_clone },
{ "slaveclone", 50,50, atcommand_clone },
@@ -9118,8 +9098,8 @@ int atcommand_config_read(const char* cfgName)
}
else {
p->level2 = atoi(w3);
- p->level2 = cap_value(p->level2, 0, 100);
}
+ p->level2 = cap_value(p->level2, 0, 100);
}
else
if( strcmpi(w1, "import") == 0 )
diff --git a/src/map/battle.c b/src/map/battle.c
index 32def23f3..3e58c1209 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -160,7 +160,7 @@ int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr data)
struct block_list *target = map_id2bl(dat->target);
if (target && dat && map_id2bl(id) == dat->src && target->prev != NULL && !status_isdead(target) &&
target->m == dat->src->m &&
- (target->type != BL_PC || ((TBL_PC*)target)->invincible_timer == -1) &&
+ (target->type != BL_PC || ((TBL_PC*)target)->invincible_timer == INVALID_TIMER) &&
check_distance_bl(dat->src, target, dat->distance)) //Check to see if you haven't teleported. [Skotlex]
{
map_freeblock_lock();
@@ -263,7 +263,7 @@ int battle_attr_fix(struct block_list *src, struct block_list *target, int damag
if( tsc->data[SC_SPIDERWEB]->val2-- > 0 )
damage <<= 1; // double damage
if( tsc->data[SC_SPIDERWEB]->val2 == 0 )
- status_change_end(target,SC_SPIDERWEB,-1);
+ status_change_end(target, SC_SPIDERWEB, INVALID_TIMER);
}
return damage*ratio/100;
}
@@ -326,7 +326,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
d->dmg_lv = ATK_BLOCK;
return 0;
}
- status_change_end(bl,SC_SAFETYWALL,-1);
+ status_change_end(bl, SC_SAFETYWALL, INVALID_TIMER);
}
if( sc->data[SC_PNEUMA] && (flag&(BF_MAGIC|BF_LONG)) == BF_LONG )
@@ -381,7 +381,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
//Shouldn't end until Breaker's non-weapon part connects.
if (skill_num != ASC_BREAKER || !(flag&BF_WEAPON))
if (--(sce->val3) <= 0) //We make it work like Safety Wall, even though it only blocks 1 time.
- status_change_end(bl, SC_KAUPE, -1);
+ status_change_end(bl, SC_KAUPE, INVALID_TIMER);
return 0;
}
@@ -395,9 +395,9 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
}
//Both need to be consumed if they are active.
if (sce && --(sce->val2) <= 0)
- status_change_end(bl, SC_UTSUSEMI, -1);
+ status_change_end(bl, SC_UTSUSEMI, INVALID_TIMER);
if ((sce=sc->data[SC_BUNSINJYUTSU]) && --(sce->val2) <= 0)
- status_change_end(bl, SC_BUNSINJYUTSU, -1);
+ status_change_end(bl, SC_BUNSINJYUTSU, INVALID_TIMER);
return 0;
}
@@ -408,7 +408,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
damage <<= 1; // Lex Aeterna only doubles damage of regular attacks from mercenaries
if( skill_num != ASC_BREAKER || !(flag&BF_WEAPON) )
- status_change_end( bl,SC_AETERNA,-1 ); //Shouldn't end until Breaker's non-weapon part connects.
+ status_change_end(bl, SC_AETERNA, INVALID_TIMER); //Shouldn't end until Breaker's non-weapon part connects.
}
//Finally damage reductions....
@@ -464,7 +464,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
per /=20; //Uses 20% SP intervals.
//SP Cost: 1% + 0.5% per every 20% SP
if (!status_charge(bl, 0, (10+5*per)*status->max_sp/1000))
- status_change_end( bl,SC_ENERGYCOAT,-1 );
+ status_change_end(bl, SC_ENERGYCOAT, INVALID_TIMER);
//Reduction: 6% + 6% every 20%
damage -= damage * 6 * (1+per) / 100;
}
@@ -484,7 +484,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
status_fix_damage(bl,src,damage,clif_damage(bl,src,gettick(),0,0,damage,0,0,0));
clif_skill_nodamage(bl,bl,ST_REJECTSWORD,sce->val1,1);
if(--(sce->val3)<=0)
- status_change_end(bl, SC_REJECTSWORD, -1);
+ status_change_end(bl, SC_REJECTSWORD, INVALID_TIMER);
}
//Finally Kyrie because it may, or not, reduce damage to 0.
@@ -497,7 +497,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
damage=-sce->val2;
}
if((--sce->val3)<=0 || (sce->val2<=0) || skill_num == AL_HOLYLIGHT)
- status_change_end(bl, SC_KYRIE, -1);
+ status_change_end(bl, SC_KYRIE, INVALID_TIMER);
}
if (!damage) return 0;
@@ -3090,7 +3090,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
}
if (sc && sc->data[SC_CLOAKING] && !(sc->data[SC_CLOAKING]->val4&2))
- status_change_end(src,SC_CLOAKING,-1);
+ status_change_end(src, SC_CLOAKING, INVALID_TIMER);
if( tsc && tsc->data[SC_AUTOCOUNTER] && status_check_skilluse(target, src, KN_AUTOCOUNTER, 1) )
{
@@ -3102,7 +3102,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
int skilllv = tsc->data[SC_AUTOCOUNTER]->val1;
clif_skillcastcancel(target); //Remove the casting bar. [Skotlex]
clif_damage(src, target, tick, sstatus->amotion, 1, 0, 1, 0, 0); //Display MISS.
- status_change_end(target,SC_AUTOCOUNTER,-1);
+ status_change_end(target, SC_AUTOCOUNTER, INVALID_TIMER);
skill_attack(BF_WEAPON,target,target,src,KN_AUTOCOUNTER,skilllv,tick,0);
return ATK_NONE;
}
@@ -3112,7 +3112,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
{
int skilllv = tsc->data[SC_BLADESTOP_WAIT]->val1;
int duration = skill_get_time2(MO_BLADESTOP,skilllv);
- status_change_end(target, SC_BLADESTOP_WAIT, -1);
+ status_change_end(target, SC_BLADESTOP_WAIT, INVALID_TIMER);
if(sc_start4(src, SC_BLADESTOP, 100, sd?pc_checkskill(sd, MO_BLADESTOP):5, 0, 0, target->id, duration))
{ //Target locked.
clif_damage(src, target, tick, sstatus->amotion, 1, 0, 1, 0, 0); //Display MISS.
@@ -3128,7 +3128,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
if (sc && sc->data[SC_SKILLRATE_UP] && sc->data[SC_SKILLRATE_UP]->val1 == MO_TRIPLEATTACK)
{
triple_rate+= triple_rate*(sc->data[SC_SKILLRATE_UP]->val2)/100;
- status_change_end(src,SC_SKILLRATE_UP,-1);
+ status_change_end(src, SC_SKILLRATE_UP, INVALID_TIMER);
}
if (rand()%100 < triple_rate)
//FIXME: invalid return type!
@@ -3142,7 +3142,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
int skilllv = sc->data[SC_SACRIFICE]->val1;
if( --sc->data[SC_SACRIFICE]->val2 <= 0 )
- status_change_end(src, SC_SACRIFICE,-1);
+ status_change_end(src, SC_SACRIFICE, INVALID_TIMER);
status_zap(src, sstatus->max_hp*9/100, 0);//Damage to self is always 9%
@@ -3154,7 +3154,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
return (damage_lv)skill_attack(BF_MAGIC,src,src,target,NPC_MAGICALATTACK,sc->data[SC_MAGICALATTACK]->val1,tick,0);
}
- if(tsc && tsc->data[SC_KAAHI] && tsc->data[SC_KAAHI]->val4 == -1 && tstatus->hp < tstatus->max_hp)
+ if(tsc && tsc->data[SC_KAAHI] && tsc->data[SC_KAAHI]->val4 == INVALID_TIMER && tstatus->hp < tstatus->max_hp)
tsc->data[SC_KAAHI]->val4 = add_timer(tick + skill_get_time2(SL_KAAHI,tsc->data[SC_KAAHI]->val1), kaahi_heal_timer, target->id, SC_KAAHI); //Activate heal.
wd = battle_calc_attack(BF_WEAPON, src, target, 0, 0, flag);
@@ -3197,7 +3197,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
status_fix_damage(NULL, d_bl, damage, 0);
}
else
- status_change_end(target, SC_DEVOTION, -1);
+ status_change_end(target, SC_DEVOTION, INVALID_TIMER);
}
if (sc && sc->data[SC_AUTOSPELL] && rand()%100 < sc->data[SC_AUTOSPELL]->val4) {
@@ -3256,7 +3256,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
--sce->val2;
}
if (sce->val2 <= 0)
- status_change_end(target, SC_POISONREACT, -1);
+ status_change_end(target, SC_POISONREACT, INVALID_TIMER);
}
}
map_freeblock_unlock();
@@ -3344,7 +3344,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
switch( target->type )
{ // Checks on actual target
case BL_PC:
- if (((TBL_PC*)target)->invincible_timer != -1 || pc_isinvisible((TBL_PC*)target))
+ if (((TBL_PC*)target)->invincible_timer != INVALID_TIMER || pc_isinvisible((TBL_PC*)target))
return -1; //Cannot be targeted yet.
break;
case BL_MOB:
diff --git a/src/map/chrif.c b/src/map/chrif.c
index a9634d2c2..c4eeea3d9 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -36,9 +36,9 @@ static DBMap* auth_db; // int id -> struct auth_node*
static const int packet_len_table[0x3d] = { // U - used, F - free
60, 3,-1,27,10,-1, 6,-1, // 2af8-2aff: U->2af8, U->2af9, U->2afa, U->2afb, U->2afc, U->2afd, U->2afe, U->2aff
- 6,-1,18, 7,-1,35,30,-1, // 2b00-2b07: U->2b00, U->2b01, U->2b02, U->2b03, U->2b04, U->2b05, U->2b06, F->2b07
- 6,30,-1,-1,86, 7,44,34, // 2b08-2b0f: U->2b08, U->2b09, F->2b0a, F->2b0b, U->2b0c, U->2b0d, U->2b0e, U->2b0f
- 11,10,10, 6,11,-1,266,10, // 2b10-2b17: U->2b10, U->2b11, U->2b12, U->2b13, U->2b14, F->2b15, U->2b16, U->2b17
+ 6,-1,18, 7,-1,35,30, 0, // 2b00-2b07: U->2b00, U->2b01, U->2b02, U->2b03, U->2b04, U->2b05, U->2b06, F->2b07
+ 6,30, 0, 0,86, 7,44,34, // 2b08-2b0f: U->2b08, U->2b09, F->2b0a, F->2b0b, U->2b0c, U->2b0d, U->2b0e, U->2b0f
+ 11,10,10, 0,11, 0,266,10, // 2b10-2b17: U->2b10, U->2b11, U->2b12, F->2b13, U->2b14, F->2b15, U->2b16, U->2b17
2,10, 2,-1,-1,-1, 2, 7, // 2b18-2b1f: U->2b18, U->2b19, U->2b1a, U->2b1b, U->2b1c, U->2b1d, U->2b1e, U->2b1f
-1,10, 8, 2, 2,14,19,19, // 2b20-2b27: U->2b20, U->2b21, U->2b22, U->2b23, U->2b24, U->2b25, U->2b26, U->2b27
};
@@ -71,7 +71,7 @@ static const int packet_len_table[0x3d] = { // U - used, F - free
//2b10: Outgoing, chrif_updatefamelist -> 'Update the fame ranking lists and send them'
//2b11: Outgoing, chrif_divorce -> 'tell the charserver to do divorce'
//2b12: Incoming, chrif_divorceack -> 'divorce chars
-//2b13: Incoming, chrif_accountdeletion -> 'Delete acc XX, if the player is on, kick ....'
+//2b13: FREE
//2b14: Incoming, chrif_accountban -> 'not sure: kick the player with message XY'
//2b15: FREE
//2b16: Outgoing, chrif_ragsrvinfo -> 'sends base / job / drop rates ....'
@@ -942,32 +942,6 @@ int chrif_deadopt(int father_id, int mother_id, int child_id)
return 0;
}
-/*==========================================
- * Disconnection of a player (account has been deleted in login-server) by [Yor]
- *------------------------------------------*/
-int chrif_accountdeletion(int fd)
-{
- int acc;
- struct map_session_data *sd;
-
- acc = RFIFOL(fd,2);
- if (battle_config.etc_log)
- ShowNotice("chrif_accountdeletion %d.\n", acc);
- sd = map_id2sd(acc);
- if (acc > 0) {
- if (sd != NULL) {
- sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters
- clif_displaymessage(sd->fd, "Your account has been deleted (disconnection)...");
- set_eof(sd->fd); // forced to disconnect for the change
- map_quit(sd); // Remove leftovers (e.g. autotrading) [Paradox924X]
- }
- } else {
- if (sd != NULL)
- ShowError("chrif_accountdeletion failed - player not online.\n");
- }
-
- return 0;
-}
/*==========================================
* Disconnection of a player (account has been banned of has a status, from login-server) by [Yor]
@@ -1169,7 +1143,7 @@ int chrif_save_scdata(struct map_session_data *sd)
{
if (!sc->data[i])
continue;
- if (sc->data[i]->timer != -1)
+ if (sc->data[i]->timer != INVALID_TIMER)
{
timer = get_timer(sc->data[i]->timer);
if (timer == NULL || timer->func != status_change_timer || DIFF_TICK(timer->tick,tick) < 0)
@@ -1426,7 +1400,6 @@ int chrif_parse(int fd)
case 0x2b0d: chrif_changedsex(fd); break;
case 0x2b0f: chrif_char_ask_name_answer(RFIFOL(fd,2), (char*)RFIFOP(fd,6), RFIFOW(fd,30), RFIFOW(fd,32)); break;
case 0x2b12: chrif_divorceack(RFIFOL(fd,2), RFIFOL(fd,6)); break;
- case 0x2b13: chrif_accountdeletion(fd); break;
case 0x2b14: chrif_accountban(fd); break;
case 0x2b1b: chrif_recvfamelist(fd); break;
case 0x2b1d: chrif_load_scdata(fd); break;
diff --git a/src/map/clif.c b/src/map/clif.c
index c5796555a..b724ddbab 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -5599,9 +5599,9 @@ void clif_closevendingboard(struct block_list* bl, int fd)
}
/*==========================================
- * Sends a list of items in a shop
+ * Sends a list of items in a shop (ZC_PC_PURCHASE_ITEMLIST_FROMMC/ZC_PC_PURCHASE_ITEMLIST_FROMMC2)
* R 0133 <len>.w <ID>.l {<value>.l <amount>.w <index>.w <type>.B <item ID>.w <identify flag>.B <attribute?>.B <refine>.B <card>.4w}.22B
- * R 0800 <len>.w <ID>.l <ID?>.l {<value>.l <amount>.w <index>.w <type>.B <item ID>.w <identify flag>.B <attribute?>.B <refine>.B <card>.4w}.22B
+ * R 0800 <len>.w <ID>.l <UniqueID>.l {<value>.l <amount>.w <index>.w <type>.B <item ID>.w <identify flag>.B <attribute?>.B <refine>.B <card>.4w}.22B
*------------------------------------------*/
void clif_vendinglist(struct map_session_data* sd, int id, struct s_vending* vending)
{
@@ -5628,7 +5628,7 @@ void clif_vendinglist(struct map_session_data* sd, int id, struct s_vending* ven
WFIFOW(fd,2) = offset+count*22;
WFIFOL(fd,4) = id;
#if PACKETVER >= 20100105
- WFIFOL(fd,8) = vsd->status.char_id;
+ WFIFOL(fd,8) = vsd->vender_id;
#endif
for( i = 0; i < count; i++ )
@@ -5649,12 +5649,14 @@ void clif_vendinglist(struct map_session_data* sd, int id, struct s_vending* ven
}
/*==========================================
- * Shop purchase failure
+ * Shop purchase failure (ZC_PC_PURCHASE_RESULT_FROMMC)
* R 0135 <index>.w <amount>.w <fail>.B
* fail=1 - not enough zeny
* fail=2 - overweight
* fail=4 - out of stock
* fail=5 - "cannot use an npc shop while in a trade"
+ * fail=6 - Because the store information was incorrect the item was not purchased.
+ * fail=7 - No sales information.
*------------------------------------------*/
void clif_buyvending(struct map_session_data* sd, int index, int amount, int fail)
{
@@ -8398,8 +8400,8 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
clif_refreshlook(&sd->bl,sd->bl.id,LOOK_CLOTHES_COLOR,sd->vd.cloth_color,SELF);
// item
+ clif_inventorylist(sd); // inventory list first, otherwise deleted items in pc_checkitem show up as 'unknown item'
pc_checkitem(sd);
- clif_inventorylist(sd);
// cart
if(pc_iscarton(sd)) {
@@ -8724,11 +8726,13 @@ void clif_progressbar_abort(struct map_session_data * sd)
void clif_parse_progressbar(int fd, struct map_session_data * sd)
{
+ int npc_id = sd->progressbar.npc_id;
+
if( gettick() < sd->progressbar.timeout && sd->st )
sd->st->state = END;
- npc_scriptcont(sd, sd->progressbar.npc_id);
sd->progressbar.npc_id = sd->progressbar.timeout = 0;
+ npc_scriptcont(sd, npc_id);
}
/*==========================================
@@ -9075,7 +9079,7 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type,
return;
}
- if (sd->ud.skilltimer != -1 || sd->sc.opt1)
+ if (sd->ud.skilltimer != INVALID_TIMER || sd->sc.opt1)
break;
if (sd->sc.count && (
@@ -9279,19 +9283,6 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd)
// notify sender of success
clif_wis_end(fd, 0); // 0: success to send wisper
- // if player has an auto-away message
- if(dstsd->away_message[0] != '\0')
- {
- char output[256];
- sprintf(output, "%s %s", message, msg_txt(543)); // "(Automessage has been sent)"
- clif_wis_message(dstsd->fd, sd->status.name, output, strlen(output) + 1);
- if(dstsd->state.autotrade)
- sprintf(output, msg_txt(544), dstsd->away_message); // "Away [AT] - "%s""
- else
- sprintf(output, msg_txt(545), dstsd->away_message); // "Away - "%s""
- clif_wis_message(fd, dstsd->status.name, output, strlen(output) + 1);
- return;
- }
// Normal message
clif_wis_message(dstsd->fd, sd->status.name, message, messagelen);
return;
@@ -9562,9 +9553,11 @@ void clif_parse_NpcBuyListSend(int fd, struct map_session_data* sd)
WFIFOSET(fd,packet_len(0xca));
}
-/*==========================================
- *
- *------------------------------------------*/
+/// Request to sell chosen items to npc shop
+/// R 00c9 <packet len>.W {<index>.W <amount>.W}.4B*
+/// S 00cb <result>.B
+/// result = 00 -> "The deal has successfully completed."
+/// result = 01 -> "The deal has failed."
void clif_parse_NpcSellListSend(int fd,struct map_session_data *sd)
{
int fail=0,n;
@@ -9848,7 +9841,7 @@ static void clif_parse_UseSkillToId_homun(struct homun_data *hd, struct map_sess
return;
if( hd->bl.id != target_id && skill_get_inf(skillnum)&INF_SELF_SKILL )
target_id = hd->bl.id;
- if( hd->ud.skilltimer != -1 )
+ if( hd->ud.skilltimer != INVALID_TIMER )
{
if( skillnum != SA_CASTCANCEL ) return;
}
@@ -9958,7 +9951,7 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
if( target_id < 0 && -target_id == sd->bl.id ) // for disguises [Valaris]
target_id = sd->bl.id;
- if( sd->ud.skilltimer != -1 )
+ if( sd->ud.skilltimer != INVALID_TIMER )
{
if( skillnum != SA_CASTCANCEL )
return;
@@ -10050,7 +10043,7 @@ void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, short skil
safestrncpy(sd->message, (char*)RFIFOP(fd,skillmoreinfo), MESSAGE_SIZE);
}
- if( sd->ud.skilltimer != -1 )
+ if( sd->ud.skilltimer != INVALID_TIMER )
return;
if( DIFF_TICK(tick, sd->ud.canact_tick) < 0 )
@@ -10880,7 +10873,7 @@ void clif_parse_VendingListReq(int fd, struct map_session_data* sd)
}
/*==========================================
- * Shop item(s) purchase request
+ * Shop item(s) purchase request (CZ_PC_PURCHASE_ITEMLIST_FROMMC)
* S 0134 <len>.w <ID>.l {<amount>.w <index>.w}.4B*
*------------------------------------------*/
void clif_parse_PurchaseReq(int fd, struct map_session_data* sd)
@@ -10889,21 +10882,27 @@ void clif_parse_PurchaseReq(int fd, struct map_session_data* sd)
int id = (int)RFIFOL(fd,4);
const uint8* data = (uint8*)RFIFOP(fd,8);
- vending_purchasereq(sd, id, -1, data, len/4);
+ vending_purchasereq(sd, id, sd->vended_id, data, len/4);
+
+ // whether it fails or not, the buy window is closed
+ sd->vended_id = 0;
}
/*==========================================
- * Shop item(s) purchase request
- * S 0134/0801 <len>.w <AID>.l <CID>.l {<amount>.w <index>.w}.4B*
+ * Shop item(s) purchase request (CZ_PC_PURCHASE_ITEMLIST_FROMMC2)
+ * S 0801 <len>.w <AID>.l <UniqueID>.l {<amount>.w <index>.w}.4B*
*------------------------------------------*/
void clif_parse_PurchaseReq2(int fd, struct map_session_data* sd)
{
int len = (int)RFIFOW(fd,2) - 12;
int aid = (int)RFIFOL(fd,4);
- int cid = (int)RFIFOL(fd,8);
+ int uid = (int)RFIFOL(fd,8);
const uint8* data = (uint8*)RFIFOP(fd,12);
- vending_purchasereq(sd, aid, cid, data, len/4);
+ vending_purchasereq(sd, aid, uid, data, len/4);
+
+ // whether it fails or not, the buy window is closed
+ sd->vended_id = 0;
}
/*==========================================
@@ -11615,7 +11614,7 @@ void clif_parse_GMReqNoChat(int fd,struct map_session_data *sd)
sc_start(&dstsd->bl,SC_NOCHAT,100,0,0);
} else {
dstsd->status.manner = 0;
- status_change_end(&dstsd->bl,SC_NOCHAT,-1);
+ status_change_end(&dstsd->bl, SC_NOCHAT, INVALID_TIMER);
}
if( type != 2 )
@@ -11674,7 +11673,7 @@ void clif_parse_GMReqAccountName(int fd, struct map_session_data *sd)
* S 0198 <x>.W <y>.W <gat>.W
*------------------------------------------*/
void clif_parse_GMChangeMapType(int fd, struct map_session_data *sd)
-{// FIXME: type sent by client is 0 or 1 (even if you enter 2+); that suggests, that it is walkable gat attribute
+{
int x,y,type;
if( battle_config.atc_gmonly && !pc_isGM(sd) )
@@ -12013,7 +12012,6 @@ void clif_parse_FriendsListReply(int fd, struct map_session_data *sd)
account_id = RFIFOL(fd,2);
char_id = RFIFOL(fd,6);
reply = RFIFOB(fd,10);
- //printf ("reply: %d %d %d\n", char_id, id, reply);
f_sd = map_id2sd(account_id); //The account id is the same as the bl.id of players.
if (f_sd == NULL)
@@ -12096,20 +12094,20 @@ void clif_parse_FriendsListRemove(int fd, struct map_session_data *sd)
}
/*==========================================
- * /pvpinfo
+ * /pvpinfo (CZ_REQ_PVPPOINT & ZC_ACK_PVPPOINT)
+ * R 020f <char id>.L <account id>.L
+ * S 0210 <char id>.L <account id>.L <win point>.L <lose point>.L <point>.L
*------------------------------------------*/
void clif_parse_PVPInfo(int fd,struct map_session_data *sd)
{
WFIFOHEAD(fd,packet_len(0x210));
WFIFOW(fd,0) = 0x210;
- //WFIFOL(fd,2) = 0; // not sure what for yet
- //WFIFOL(fd,6) = 0;
+ WFIFOL(fd,2) = sd->status.char_id;
+ WFIFOL(fd,6) = sd->status.account_id;
WFIFOL(fd,10) = sd->pvp_won; // times won
WFIFOL(fd,14) = sd->pvp_lost; // times lost
WFIFOL(fd,18) = sd->pvp_point;
WFIFOSET(fd, packet_len(0x210));
-
- return;
}
/*==========================================
@@ -12584,7 +12582,7 @@ void clif_Mail_read(struct map_session_data *sd, int mail_id)
WFIFOL(fd,72) = 0;
WFIFOL(fd,76) = msg->zeny;
- if( item->nameid && (data = itemdb_search(item->nameid)) != NULL )
+ if( item->nameid && (data = itemdb_exists(item->nameid)) != NULL )
{
WFIFOL(fd,80) = item->amount;
WFIFOW(fd,84) = (data->view_id)?data->view_id:item->nameid;
@@ -12650,7 +12648,7 @@ void clif_parse_Mail_getattach(int fd, struct map_session_data *sd)
struct item_data *data;
unsigned int weight;
- if ((data = itemdb_search(sd->mail.inbox.msg[i].item.nameid)) == NULL)
+ if ((data = itemdb_exists(sd->mail.inbox.msg[i].item.nameid)) == NULL)
return;
switch( pc_checkadditem(sd, data->nameid, sd->mail.inbox.msg[i].item.amount) )
@@ -12863,7 +12861,7 @@ void clif_Auction_results(struct map_session_data *sd, short count, short pages,
WFIFOL(fd,k) = auction.auction_id;
safestrncpy((char*)WFIFOP(fd,4+k), auction.seller_name, NAME_LENGTH);
- if( (item = itemdb_search(auction.item.nameid)) != NULL && item->view_id > 0 )
+ if( (item = itemdb_exists(auction.item.nameid)) != NULL && item->view_id > 0 )
WFIFOW(fd,28+k) = item->view_id;
else
WFIFOW(fd,28+k) = auction.item.nameid;
@@ -12924,7 +12922,7 @@ void clif_parse_Auction_setitem(int fd, struct map_session_data *sd)
return;
}
- if( (item = itemdb_search(sd->status.inventory[idx].nameid)) != NULL && !(item->type == IT_ARMOR || item->type == IT_PETARMOR || item->type == IT_WEAPON || item->type == IT_CARD || item->type == IT_ETC) )
+ if( (item = itemdb_exists(sd->status.inventory[idx].nameid)) != NULL && !(item->type == IT_ARMOR || item->type == IT_PETARMOR || item->type == IT_WEAPON || item->type == IT_CARD || item->type == IT_ETC) )
{ // Consumible or pets are not allowed
clif_Auction_setitem(sd->fd, idx, true);
return;
@@ -13025,7 +13023,7 @@ void clif_parse_Auction_register(int fd, struct map_session_data *sd)
return;
}
- if( (item = itemdb_search(sd->status.inventory[sd->auction.index].nameid)) == NULL )
+ if( (item = itemdb_exists(sd->status.inventory[sd->auction.index].nameid)) == NULL )
{ // Just in case
clif_Auction_message(fd, 2); // The auction has been canceled
return;
@@ -13139,6 +13137,31 @@ void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd)
WFIFOSET(fd,WFIFOW(fd,2));
}
+/// Cashshop Buy Ack (ZC_PC_CASH_POINT_UPDATE)
+/// S 0289 <cash point>.L <kafra point>.L <error>.W
+///
+/// @param error
+/// 0: The deal has successfully completed. (ERROR_TYPE_NONE)
+/// 1: The Purchase has failed because the NPC does not exist. (ERROR_TYPE_NPC)
+/// 2: The Purchase has failed because the Kafra Shop System is not working correctly. (ERROR_TYPE_SYSTEM)
+/// 3: You are over your Weight Limit. (ERROR_TYPE_INVENTORY_WEIGHT)
+/// 4: You cannot purchase items while you are in a trade. (ERROR_TYPE_EXCHANGE)
+/// 5: The Purchase has failed because the Item Information was incorrect. (ERROR_TYPE_ITEM_ID)
+/// 6: You do not have enough Kafra Credit Points. (ERROR_TYPE_MONEY)
+/// 7: You can purchase up to 10 items.
+/// 8: Some items could not be purchased.
+void clif_cashshop_ack(struct map_session_data* sd, int error)
+{
+ int fd = sd->fd;
+
+ WFIFOHEAD(fd, packet_len(0x289));
+ WFIFOW(fd,0) = 0x289;
+ WFIFOL(fd,2) = sd->cashPoints;
+ WFIFOL(fd,6) = sd->kafraPoints;
+ WFIFOW(fd,10) = TOW(error);
+ WFIFOSET(fd, packet_len(0x289));
+}
+
void clif_parse_cashshop_buy(int fd, struct map_session_data *sd)
{
int fail = 0, amount, points;
@@ -13154,12 +13177,7 @@ void clif_parse_cashshop_buy(int fd, struct map_session_data *sd)
else
fail = npc_cashshop_buy(sd, nameid, amount, points);
- WFIFOHEAD(fd,12);
- WFIFOW(fd,0) = 0x289;
- WFIFOL(fd,2) = sd->cashPoints;
- WFIFOL(fd,6) = sd->kafraPoints;
- WFIFOW(fd,10) = fail;
- WFIFOSET(fd,12);
+ clif_cashshop_ack(sd, fail);
}
/*==========================================
@@ -13248,7 +13266,7 @@ void clif_bossmapinfo(int fd, struct mob_data *md, short flag)
else
WFIFOB(fd,2) = 2; // First Time
}
- else if (md->spawn_timer != -1)
+ else if (md->spawn_timer != INVALID_TIMER)
{ // Boss is Dead
const struct TimerData * timer_data = get_timer(md->spawn_timer);
unsigned int seconds;
@@ -14268,7 +14286,7 @@ static int packetdb_readdb(void)
6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
//#0x0280
- 0, 0, 0, 6, 0, 0, 0, 0, 0, 8, 18, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 0, 0, 0, 0, 0, 12, 18, 0, 0, 0, 0, 0,
0, 4, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
85, -1, -1,107, 6, -1, 7, 7, 22,191, 0, 0, 0, 0, 0, 0,
@@ -14579,6 +14597,7 @@ static int packetdb_readdb(void)
{clif_parse_PartyBookingUpdateReq,"bookingupdatereq"},
{clif_parse_PartyBookingDeleteReq,"bookingdelreq"},
#endif
+ {clif_parse_PVPInfo,"pvpinfo"},
{NULL,NULL}
};
diff --git a/src/map/clif.h b/src/map/clif.h
index ded8ece30..8e9f2be7a 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -461,8 +461,6 @@ int clif_friendslist_toggle_sub(struct map_session_data *sd,va_list ap);
void clif_friendslist_send(struct map_session_data *sd);
void clif_friendslist_reqack(struct map_session_data *sd, struct map_session_data *f_sd, int type);
-// [Valaris]
-int clif_mob_hp(struct mob_data *md);
void clif_weather(int m); // [Valaris]
int clif_specialeffect(struct block_list* bl, int type, enum send_target target); // special effects [Valaris]
void clif_specialeffect_single(struct block_list* bl, int type, int fd);
diff --git a/src/map/guild.c b/src/map/guild.c
index f90fc8946..7b20808d6 100644
--- a/src/map/guild.c
+++ b/src/map/guild.c
@@ -103,46 +103,34 @@ int guild_checkskill(struct guild *g,int id)
/*==========================================
* guild_skill_tree.txt reading - from jA [Komurka]
*------------------------------------------*/
-int guild_read_guildskill_tree_db(void)
-{
- int i,k,id=0,ln=0;
- FILE *fp;
- char line[1024],*p;
+static bool guild_read_guildskill_tree_db(char* split[], int columns, int current)
+{// <skill id>,<max lv>,<req id1>,<req lv1>,<req id2>,<req lv2>,<req id3>,<req lv3>,<req id4>,<req lv4>,<req id5>,<req lv5>
+ int k, id, skillid;
- memset(guild_skill_tree,0,sizeof(guild_skill_tree));
- sprintf(line, "%s/guild_skill_tree.txt", db_path);
- if( (fp=fopen(line,"r"))==NULL){
- ShowError("can't read %s\n", line);
- return -1;
+ skillid = atoi(split[0]);
+ id = skillid - GD_SKILLBASE;
+
+ if( id < 0 || id >= MAX_GUILDSKILL )
+ {
+ ShowWarning("guild_read_guildskill_tree_db: Invalid skill id %d.\n", skillid);
+ return false;
+ }
+
+ guild_skill_tree[id].id = skillid;
+ guild_skill_tree[id].max = atoi(split[1]);
+
+ if( guild_skill_tree[id].id == GD_GLORYGUILD && battle_config.require_glory_guild && guild_skill_tree[id].max == 0 )
+ {// enable guild's glory when required for emblems
+ guild_skill_tree[id].max = 1;
}
- while(fgets(line, sizeof(line), fp))
+
+ for( k = 0; k < 5; k++ )
{
- char *split[50];
- if(line[0]=='/' && line[1]=='/')
- continue;
- for(i=0,p=line;i<12 && p;i++){
- split[i]=p;
- p=strchr(p,',');
- if(p) *p++=0;
- }
- if(i<12)
- continue;
- id = atoi(split[0]) - GD_SKILLBASE;
- if(id<0 || id>=MAX_GUILDSKILL)
- continue;
- guild_skill_tree[id].id=atoi(split[0]);
- guild_skill_tree[id].max=atoi(split[1]);
- if (guild_skill_tree[id].id==GD_GLORYGUILD && battle_config.require_glory_guild && guild_skill_tree[id].max==0) guild_skill_tree[id].max=1;
- for(k=0;k<5;k++){
- guild_skill_tree[id].need[k].id=atoi(split[k*2+2]);
- guild_skill_tree[id].need[k].lv=atoi(split[k*2+3]);
- }
- ln++;
+ guild_skill_tree[id].need[k].id = atoi(split[k*2+2]);
+ guild_skill_tree[id].need[k].lv = atoi(split[k*2+3]);
}
- fclose(fp);
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,"guild_skill_tree.txt");
- return 0;
+ return true;
}
/*==========================================
@@ -168,51 +156,21 @@ int guild_check_skill_require(struct guild *g,int id)
return 1;
}
-static int guild_read_castledb(void)
-{
- FILE *fp;
- char line[1024];
- int j,ln=0;
- char *str[32],*p;
+static bool guild_read_castledb(char* str[], int columns, int current)
+{// <castle id>,<map name>,<castle name>,<castle event>[,<reserved/unused switch flag>]
struct guild_castle *gc;
- sprintf(line, "%s/castle_db.txt", db_path);
- if( (fp=fopen(line,"r"))==NULL){
- ShowError("can't read %s\n", line);
- return -1;
- }
-
- while(fgets(line, sizeof(line), fp))
- {
- if(line[0]=='/' && line[1]=='/')
- continue;
- memset(str,0,sizeof(str));
- for(j=0,p=line;j<6 && p;j++){
- str[j]=p;
- p=strchr(p,',');
- if(p) *p++=0;
- }
- if (j < 4) //Insufficient data for castle. [Skotlex]
- {
- ShowError("castle_db.txt: invalid line '%s'\n", line);
- continue;
- }
-
- gc=(struct guild_castle *)aCalloc(1,sizeof(struct guild_castle));
- gc->castle_id=atoi(str[0]);
- gc->mapindex = mapindex_name2id(str[1]);
- safestrncpy(gc->castle_name,str[2],NAME_LENGTH);
- safestrncpy(gc->castle_event,str[3],NAME_LENGTH);
+ CREATE(gc, struct guild_castle, 1);
+ gc->castle_id = atoi(str[0]);
+ gc->mapindex = mapindex_name2id(str[1]);
+ safestrncpy(gc->castle_name, str[2], sizeof(gc->castle_name));
+ safestrncpy(gc->castle_event, str[3], sizeof(gc->castle_event));
- idb_put(castle_db,gc->castle_id,gc);
+ idb_put(castle_db,gc->castle_id,gc);
- //intif_guild_castle_info(gc->castle_id);
+ //intif_guild_castle_info(gc->castle_id);
- ln++;
- }
- fclose(fp);
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,"castle_db.txt");
- return 0;
+ return true;
}
/// lookup: guild id -> guild*
@@ -1969,9 +1927,10 @@ void do_init_guild(void)
expcache_ers = ers_new(sizeof(struct guild_expcache));
guild_castleinfoevent_db=idb_alloc(DB_OPT_BASE);
- guild_read_castledb();
+ sv_readdb(db_path, "castle_db.txt", ',', 4, 5, -1, &guild_read_castledb);
- guild_read_guildskill_tree_db(); //guild skill tree [Komurka]
+ memset(guild_skill_tree,0,sizeof(guild_skill_tree));
+ sv_readdb(db_path, "guild_skill_tree.txt", ',', 12, 12, -1, &guild_read_guildskill_tree_db); //guild skill tree [Komurka]
add_timer_func_list(guild_payexp_timer,"guild_payexp_timer");
add_timer_func_list(guild_send_xy_timer, "guild_send_xy_timer");
diff --git a/src/map/homunculus.c b/src/map/homunculus.c
index 0fbd7cbff..7bfb6081d 100644
--- a/src/map/homunculus.c
+++ b/src/map/homunculus.c
@@ -8,6 +8,7 @@
#include "../common/nullpo.h"
#include "../common/mmo.h"
#include "../common/showmsg.h"
+#include "../common/strlib.h"
#include "../common/utils.h"
#include "log.h"
@@ -523,7 +524,7 @@ static int merc_hom_hungry(int tid, unsigned int tick, int id, intptr data)
int merc_hom_hungry_timer_delete(struct homun_data *hd)
{
nullpo_ret(hd);
- if(hd->hungry_timer != -1) {
+ if(hd->hungry_timer != INVALID_TIMER) {
delete_timer(hd->hungry_timer,merc_hom_hungry);
hd->hungry_timer = INVALID_TIMER;
}
@@ -637,7 +638,7 @@ int merc_hom_alloc(struct map_session_data *sd, struct s_homunculus *hom)
void merc_hom_init_timers(struct homun_data * hd)
{
- if (hd->hungry_timer == -1)
+ if (hd->hungry_timer == INVALID_TIMER)
hd->hungry_timer = add_timer(gettick()+hd->homunculusDB->hungryDelay,merc_hom_hungry,hd->master->bl.id,0);
hd->regen.state.block = 0; //Restore HP/SP block.
}
@@ -876,226 +877,190 @@ int merc_hom_shuffle(struct homun_data *hd)
return 1;
}
+static bool read_homunculusdb_sub(char* str[], int columns, int current)
+{
+ int classid;
+ struct s_homunculus_db *db;
+
+ //Base Class,Evo Class
+ classid = atoi(str[0]);
+ if (classid < HM_CLASS_BASE || classid > HM_CLASS_MAX)
+ {
+ ShowError("read_homunculusdb : Invalid class %d\n", classid);
+ return false;
+ }
+ db = &homunculus_db[current];
+ db->base_class = classid;
+ classid = atoi(str[1]);
+ if (classid < HM_CLASS_BASE || classid > HM_CLASS_MAX)
+ {
+ db->base_class = 0;
+ ShowError("read_homunculusdb : Invalid class %d\n", classid);
+ return false;
+ }
+ db->evo_class = classid;
+ //Name, Food, Hungry Delay, Base Size, Evo Size, Race, Element, ASPD
+ strncpy(db->name,str[2],NAME_LENGTH-1);
+ db->foodID = atoi(str[3]);
+ db->hungryDelay = atoi(str[4]);
+ db->base_size = atoi(str[5]);
+ db->evo_size = atoi(str[6]);
+ db->race = atoi(str[7]);
+ db->element = atoi(str[8]);
+ db->baseASPD = atoi(str[9]);
+ //base HP, SP, str, agi, vit, int, dex, luk
+ db->base.HP = atoi(str[10]);
+ db->base.SP = atoi(str[11]);
+ db->base.str = atoi(str[12]);
+ db->base.agi = atoi(str[13]);
+ db->base.vit = atoi(str[14]);
+ db->base.int_= atoi(str[15]);
+ db->base.dex = atoi(str[16]);
+ db->base.luk = atoi(str[17]);
+ //Growth Min/Max HP, SP, str, agi, vit, int, dex, luk
+ db->gmin.HP = atoi(str[18]);
+ db->gmax.HP = atoi(str[19]);
+ db->gmin.SP = atoi(str[20]);
+ db->gmax.SP = atoi(str[21]);
+ db->gmin.str = atoi(str[22]);
+ db->gmax.str = atoi(str[23]);
+ db->gmin.agi = atoi(str[24]);
+ db->gmax.agi = atoi(str[25]);
+ db->gmin.vit = atoi(str[26]);
+ db->gmax.vit = atoi(str[27]);
+ db->gmin.int_= atoi(str[28]);
+ db->gmax.int_= atoi(str[29]);
+ db->gmin.dex = atoi(str[30]);
+ db->gmax.dex = atoi(str[31]);
+ db->gmin.luk = atoi(str[32]);
+ db->gmax.luk = atoi(str[33]);
+ //Evolution Min/Max HP, SP, str, agi, vit, int, dex, luk
+ db->emin.HP = atoi(str[34]);
+ db->emax.HP = atoi(str[35]);
+ db->emin.SP = atoi(str[36]);
+ db->emax.SP = atoi(str[37]);
+ db->emin.str = atoi(str[38]);
+ db->emax.str = atoi(str[39]);
+ db->emin.agi = atoi(str[40]);
+ db->emax.agi = atoi(str[41]);
+ db->emin.vit = atoi(str[42]);
+ db->emax.vit = atoi(str[43]);
+ db->emin.int_= atoi(str[44]);
+ db->emax.int_= atoi(str[45]);
+ db->emin.dex = atoi(str[46]);
+ db->emax.dex = atoi(str[47]);
+ db->emin.luk = atoi(str[48]);
+ db->emax.luk = atoi(str[49]);
+
+ //Check that the min/max values really are below the other one.
+ if(db->gmin.HP > db->gmax.HP)
+ db->gmin.HP = db->gmax.HP;
+ if(db->gmin.SP > db->gmax.SP)
+ db->gmin.SP = db->gmax.SP;
+ if(db->gmin.str > db->gmax.str)
+ db->gmin.str = db->gmax.str;
+ if(db->gmin.agi > db->gmax.agi)
+ db->gmin.agi = db->gmax.agi;
+ if(db->gmin.vit > db->gmax.vit)
+ db->gmin.vit = db->gmax.vit;
+ if(db->gmin.int_> db->gmax.int_)
+ db->gmin.int_= db->gmax.int_;
+ if(db->gmin.dex > db->gmax.dex)
+ db->gmin.dex = db->gmax.dex;
+ if(db->gmin.luk > db->gmax.luk)
+ db->gmin.luk = db->gmax.luk;
+
+ if(db->emin.HP > db->emax.HP)
+ db->emin.HP = db->emax.HP;
+ if(db->emin.SP > db->emax.SP)
+ db->emin.SP = db->emax.SP;
+ if(db->emin.str > db->emax.str)
+ db->emin.str = db->emax.str;
+ if(db->emin.agi > db->emax.agi)
+ db->emin.agi = db->emax.agi;
+ if(db->emin.vit > db->emax.vit)
+ db->emin.vit = db->emax.vit;
+ if(db->emin.int_> db->emax.int_)
+ db->emin.int_= db->emax.int_;
+ if(db->emin.dex > db->emax.dex)
+ db->emin.dex = db->emax.dex;
+ if(db->emin.luk > db->emax.luk)
+ db->emin.luk = db->emax.luk;
+
+ return true;
+}
+
int read_homunculusdb(void)
{
- FILE *fp;
- char line[1024], *p;
- int i, k, classid;
- int j = 0;
+ int i;
const char *filename[]={"homunculus_db.txt","homunculus_db2.txt"};
- char *str[50];
- struct s_homunculus_db *db;
memset(homunculus_db,0,sizeof(homunculus_db));
- for(i = 0; i<2; i++)
+ for(i = 0; i<ARRAYLENGTH(filename); i++)
{
- sprintf(line, "%s/%s", db_path, filename[i]);
- fp = fopen(line,"r");
- if(!fp){
- if(i != 0)
- continue;
- ShowError("read_homunculusdb : can't read %s\n", line);
- return -1;
- }
+ char path[256];
- while(fgets(line, sizeof(line), fp) && j < MAX_HOMUNCULUS_CLASS)
+ if( i > 0 )
{
- if(line[0] == '/' && line[1] == '/')
- continue;
+ sprintf(path, "%s/%s", db_path, filename[i]);
- k = 0;
- p = strtok (line,",");
- while (p != NULL && k < 50)
- {
- str[k++] = p;
- p = strtok (NULL, ",");
- }
- if (k < 50 )
- {
- ShowError("read_homunculusdb : Incorrect number of columns at %s, homunculus %d. Read %d columns, 50 are needed.\n", filename[i], j+1, k);
- continue;
- }
-
- //Base Class,Evo Class
- classid = atoi(str[0]);
- if (classid < HM_CLASS_BASE || classid > HM_CLASS_MAX)
- {
- ShowError("read_homunculusdb : Invalid class %d (%s)\n", classid, filename[i]);
- continue;
- }
- db = &homunculus_db[j];
- db->base_class = classid;
- classid = atoi(str[1]);
- if (classid < HM_CLASS_BASE || classid > HM_CLASS_MAX)
+ if( !exists(path) )
{
- db->base_class = 0;
- ShowError("read_homunculusdb : Invalid class %d (%s)\n", classid, filename[i]);
continue;
}
- db->evo_class = classid;
- //Name, Food, Hungry Delay, Base Size, Evo Size, Race, Element, ASPD
- strncpy(db->name,str[2],NAME_LENGTH-1);
- db->foodID = atoi(str[3]);
- db->hungryDelay = atoi(str[4]);
- db->base_size = atoi(str[5]);
- db->evo_size = atoi(str[6]);
- db->race = atoi(str[7]);
- db->element = atoi(str[8]);
- db->baseASPD = atoi(str[9]);
- //base HP, SP, str, agi, vit, int, dex, luk
- db->base.HP = atoi(str[10]);
- db->base.SP = atoi(str[11]);
- db->base.str = atoi(str[12]);
- db->base.agi = atoi(str[13]);
- db->base.vit = atoi(str[14]);
- db->base.int_= atoi(str[15]);
- db->base.dex = atoi(str[16]);
- db->base.luk = atoi(str[17]);
- //Growth Min/Max HP, SP, str, agi, vit, int, dex, luk
- db->gmin.HP = atoi(str[18]);
- db->gmax.HP = atoi(str[19]);
- db->gmin.SP = atoi(str[20]);
- db->gmax.SP = atoi(str[21]);
- db->gmin.str = atoi(str[22]);
- db->gmax.str = atoi(str[23]);
- db->gmin.agi = atoi(str[24]);
- db->gmax.agi = atoi(str[25]);
- db->gmin.vit = atoi(str[26]);
- db->gmax.vit = atoi(str[27]);
- db->gmin.int_= atoi(str[28]);
- db->gmax.int_= atoi(str[29]);
- db->gmin.dex = atoi(str[30]);
- db->gmax.dex = atoi(str[31]);
- db->gmin.luk = atoi(str[32]);
- db->gmax.luk = atoi(str[33]);
- //Evolution Min/Max HP, SP, str, agi, vit, int, dex, luk
- db->emin.HP = atoi(str[34]);
- db->emax.HP = atoi(str[35]);
- db->emin.SP = atoi(str[36]);
- db->emax.SP = atoi(str[37]);
- db->emin.str = atoi(str[38]);
- db->emax.str = atoi(str[39]);
- db->emin.agi = atoi(str[40]);
- db->emax.agi = atoi(str[41]);
- db->emin.vit = atoi(str[42]);
- db->emax.vit = atoi(str[43]);
- db->emin.int_= atoi(str[44]);
- db->emax.int_= atoi(str[45]);
- db->emin.dex = atoi(str[46]);
- db->emax.dex = atoi(str[47]);
- db->emin.luk = atoi(str[48]);
- db->emax.luk = atoi(str[49]);
-
- //Check that the min/max values really are below the other one.
- if(db->gmin.HP > db->gmax.HP)
- db->gmin.HP = db->gmax.HP;
- if(db->gmin.SP > db->gmax.SP)
- db->gmin.SP = db->gmax.SP;
- if(db->gmin.str > db->gmax.str)
- db->gmin.str = db->gmax.str;
- if(db->gmin.agi > db->gmax.agi)
- db->gmin.agi = db->gmax.agi;
- if(db->gmin.vit > db->gmax.vit)
- db->gmin.vit = db->gmax.vit;
- if(db->gmin.int_> db->gmax.int_)
- db->gmin.int_= db->gmax.int_;
- if(db->gmin.dex > db->gmax.dex)
- db->gmin.dex = db->gmax.dex;
- if(db->gmin.luk > db->gmax.luk)
- db->gmin.luk = db->gmax.luk;
-
- if(db->emin.HP > db->emax.HP)
- db->emin.HP = db->emax.HP;
- if(db->emin.SP > db->emax.SP)
- db->emin.SP = db->emax.SP;
- if(db->emin.str > db->emax.str)
- db->emin.str = db->emax.str;
- if(db->emin.agi > db->emax.agi)
- db->emin.agi = db->emax.agi;
- if(db->emin.vit > db->emax.vit)
- db->emin.vit = db->emax.vit;
- if(db->emin.int_> db->emax.int_)
- db->emin.int_= db->emax.int_;
- if(db->emin.dex > db->emax.dex)
- db->emin.dex = db->emax.dex;
- if(db->emin.luk > db->emax.luk)
- db->emin.luk = db->emax.luk;
-
- j++;
}
- if (j > MAX_HOMUNCULUS_CLASS)
- ShowWarning("read_homunculusdb: Reached max number of homunculus [%d]. Remaining homunculus were not read.\n ", MAX_HOMUNCULUS_CLASS);
- fclose(fp);
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' homunculus in '"CL_WHITE"db/%s"CL_RESET"'.\n",j,filename[i]);
+
+ sv_readdb(db_path, filename[i], ',', 50, 50, MAX_HOMUNCULUS_CLASS, &read_homunculusdb_sub);
}
+
return 0;
}
-int read_homunculus_skilldb(void)
-{
- FILE *fp;
- char line[1024], *p;
+static bool read_homunculus_skilldb_sub(char* split[], int columns, int current)
+{// <hom class>,<skill id>,<max level>[,<job level>],<req id1>,<req lv1>,<req id2>,<req lv2>,<req id3>,<req lv3>,<req id4>,<req lv4>,<req id5>,<req lv5>
int k, classid;
- int j = 0;
- char *split[15];
+ int j;
+ int minJobLevelPresent = 0;
- memset(hskill_tree,0,sizeof(hskill_tree));
- sprintf(line, "%s/homun_skill_tree.txt", db_path);
- fp=fopen(line,"r");
- if(fp==NULL){
- ShowError("can't read %s\n", line);
- return 1;
- }
+ if( columns == 14 )
+ minJobLevelPresent = 1; // MinJobLvl has been added
- while(fgets(line, sizeof(line), fp))
+ // check for bounds [celest]
+ classid = atoi(split[0]) - HM_CLASS_BASE;
+ if ( classid >= MAX_HOMUNCULUS_CLASS )
{
- int minJobLevelPresent = 0;
-
- if(line[0]=='/' && line[1]=='/')
- continue;
-
- k = 0;
- p = strtok(line,",");
- while (p != NULL && k < 15)
- {
- split[k++] = p;
- p = strtok(NULL, ",");
- }
-
- if(k < 13)
- continue;
-
- if (k == 14)
- minJobLevelPresent = 1; // MinJobLvl has been added
+ ShowWarning("read_homunculus_skilldb: Invalud homunculus class %d.\n", atoi(split[0]));
+ return false;
+ }
- // check for bounds [celest]
- classid = atoi(split[0]) - HM_CLASS_BASE;
- if ( classid >= MAX_HOMUNCULUS_CLASS )
- continue;
+ k = atoi(split[1]); //This is to avoid adding two lines for the same skill. [Skotlex]
+ // Search an empty line or a line with the same skill_id (stored in j)
+ ARR_FIND( 0, MAX_SKILL_TREE, j, !hskill_tree[classid][j].id || hskill_tree[classid][j].id == k );
+ if (j == MAX_SKILL_TREE)
+ {
+ ShowWarning("Unable to load skill %d into homunculus %d's tree. Maximum number of skills per class has been reached.\n", k, classid);
+ return false;
+ }
- k = atoi(split[1]); //This is to avoid adding two lines for the same skill. [Skotlex]
- // Search an empty line or a line with the same skill_id (stored in j)
- for(j = 0; j < MAX_SKILL_TREE && hskill_tree[classid][j].id && hskill_tree[classid][j].id != k; j++);
+ hskill_tree[classid][j].id = k;
+ hskill_tree[classid][j].max = atoi(split[2]);
+ if (minJobLevelPresent)
+ hskill_tree[classid][j].joblv = atoi(split[3]);
- if (j == MAX_SKILL_TREE)
- {
- ShowWarning("Unable to load skill %d into homunculus %d's tree. Maximum number of skills per class has been reached.\n", k, classid);
- continue;
- }
+ for( k = 0; k < MAX_PC_SKILL_REQUIRE; k++ )
+ {
+ hskill_tree[classid][j].need[k].id = atoi(split[3+k*2+minJobLevelPresent]);
+ hskill_tree[classid][j].need[k].lv = atoi(split[3+k*2+minJobLevelPresent+1]);
+ }
- hskill_tree[classid][j].id=k;
- hskill_tree[classid][j].max=atoi(split[2]);
- if (minJobLevelPresent)
- hskill_tree[classid][j].joblv=atoi(split[3]);
+ return true;
+}
- for(k=0;k<MAX_PC_SKILL_REQUIRE;k++){
- hskill_tree[classid][j].need[k].id=atoi(split[3+k*2+minJobLevelPresent]);
- hskill_tree[classid][j].need[k].lv=atoi(split[3+k*2+minJobLevelPresent+1]);
- }
- }
+int read_homunculus_skilldb(void)
+{
+ memset(hskill_tree,0,sizeof(hskill_tree));
+ sv_readdb(db_path, "homun_skill_tree.txt", ',', 13, 14, -1, &read_homunculus_skilldb_sub);
- fclose(fp);
- ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n","homun_skill_tree.txt");
return 0;
}
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index 6455d10b6..bf801fefd 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -471,46 +471,32 @@ int itemdb_isidentified(int nameid)
/*==========================================
* ƒAƒCƒeƒ€Žg—p‰Â”\ƒtƒ‰ƒO‚̃I[ƒo[ƒ‰ƒCƒh
*------------------------------------------*/
-static int itemdb_read_itemavail (void)
-{
- FILE *fp;
- int nameid, j, k, ln = 0;
- char line[1024], *str[10], *p;
+static bool itemdb_read_itemavail(char* str[], int columns, int current)
+{// <nameid>,<sprite>
+ int nameid, sprite;
struct item_data *id;
- sprintf(line, "%s/item_avail.txt", db_path);
- if ((fp = fopen(line,"r")) == NULL) {
- ShowError("can't read %s\n", line);
- return -1;
- }
+ nameid = atoi(str[0]);
- while(fgets(line, sizeof(line), fp))
+ if( ( id = itemdb_exists(nameid) ) == NULL )
{
- if (line[0] == '/' && line[1] == '/')
- continue;
- memset(str, 0, sizeof(str));
- for (j = 0, p = line; j < 2 && p; j++) {
- str[j] = p;
- p = strchr(p, ',');
- if(p) *p++ = 0;
- }
+ ShowWarning("itemdb_read_itemavail: Invalid item id %d.\n", nameid);
+ return false;
+ }
- if (j < 2 || str[0] == NULL ||
- (nameid = atoi(str[0])) < 0 || !(id = itemdb_exists(nameid)))
- continue;
+ sprite = atoi(str[1]);
- k = atoi(str[1]);
- if (k > 0) {
- id->flag.available = 1;
- id->view_id = k;
- } else
- id->flag.available = 0;
- ln++;
+ if( sprite > 0 )
+ {
+ id->flag.available = 1;
+ id->view_id = sprite;
+ }
+ else
+ {
+ id->flag.available = 0;
}
- fclose(fp);
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", ln, "item_avail.txt");
- return 0;
+ return true;
}
/*==========================================
@@ -591,137 +577,90 @@ static void itemdb_read_itemgroup(void)
/*==========================================
* ‘•”õ§ŒÀƒtƒ@ƒCƒ‹“Ç‚Ýo‚µ
*------------------------------------------*/
-static int itemdb_read_noequip(void)
-{
- FILE *fp;
- char line[1024];
- int ln=0;
- int nameid,j;
- char *str[32],*p;
+static bool itemdb_read_noequip(char* str[], int columns, int current)
+{// <nameid>,<mode>
+ int nameid;
struct item_data *id;
- sprintf(line, "%s/item_noequip.txt", db_path);
- if( (fp=fopen(line,"r"))==NULL ){
- ShowError("can't read %s\n", line);
- return -1;
- }
- while(fgets(line, sizeof(line), fp))
- {
- if(line[0]=='/' && line[1]=='/')
- continue;
- memset(str,0,sizeof(str));
- for(j=0,p=line;j<2 && p;j++){
- str[j]=p;
- p=strchr(p,',');
- if(p) *p++=0;
- }
- if(str[0]==NULL)
- continue;
-
- nameid=atoi(str[0]);
- if(nameid<=0 || !(id=itemdb_exists(nameid)))
- continue;
+ nameid = atoi(str[0]);
- id->flag.no_equip |= atoi(str[1]);
+ if( ( id = itemdb_exists(nameid) ) == NULL )
+ {
+ ShowWarning("itemdb_read_noequip: Invalid item id %d.\n", nameid);
+ return false;
+ }
- ln++;
+ id->flag.no_equip |= atoi(str[1]);
- }
- fclose(fp);
- if (ln > 0) {
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,"item_noequip.txt");
- }
- return 0;
+ return true;
}
/*==========================================
* Reads item trade restrictions [Skotlex]
*------------------------------------------*/
-static int itemdb_read_itemtrade(void)
-{
- FILE *fp;
- int nameid, j, flag, gmlv, ln = 0;
- char line[1024], *str[10], *p;
+static bool itemdb_read_itemtrade(char* str[], int columns, int current)
+{// <nameid>,<mask>,<gm level>
+ int nameid, flag, gmlv;
struct item_data *id;
- sprintf(line, "%s/item_trade.txt", db_path);
- if ((fp = fopen(line,"r")) == NULL) {
- ShowError("can't read %s\n", line);
- return -1;
- }
+ nameid = atoi(str[0]);
- while(fgets(line, sizeof(line), fp))
+ if( ( id = itemdb_exists(nameid) ) == NULL )
{
- if (line[0] == '/' && line[1] == '/')
- continue;
- memset(str, 0, sizeof(str));
- for (j = 0, p = line; j < 3 && p; j++) {
- str[j] = p;
- p = strchr(p, ',');
- if(p) *p++ = 0;
- }
+ //ShowWarning("itemdb_read_itemtrade: Invalid item id %d.\n", nameid);
+ //return false;
+ // FIXME: item_trade.txt contains items, which are commented in item database.
+ return true;
+ }
- if (j < 3 || str[0] == NULL ||
- (nameid = atoi(str[0])) < 0 || !(id = itemdb_exists(nameid)))
- continue;
+ flag = atoi(str[1]);
+ gmlv = atoi(str[2]);
- flag = atoi(str[1]);
- gmlv = atoi(str[2]);
-
- if (flag > 0 && flag < 128 && gmlv > 0) { //Check range
- id->flag.trade_restriction = flag;
- id->gm_lv_trade_override = gmlv;
- ln++;
- }
+ if( flag < 0 || flag >= 128 )
+ {//Check range
+ ShowWarning("itemdb_read_itemtrade: Invalid trading mask %d for item id %d.\n", flag, nameid);
+ return false;
}
- fclose(fp);
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", ln, "item_trade.txt");
- return 0;
+ if( gmlv < 1 )
+ {
+ ShowWarning("itemdb_read_itemtrade: Invalid override GM level %d for item id %d.\n", gmlv, nameid);
+ return false;
+ }
+
+ id->flag.trade_restriction = flag;
+ id->gm_lv_trade_override = gmlv;
+
+ return true;
}
/*==========================================
* Reads item delay amounts [Paradox924X]
*------------------------------------------*/
-static int itemdb_read_itemdelay(void)
-{
- FILE *fp;
- int nameid, j, item_delays = 0;
- char line[1024], *str[10], *p;
+static bool itemdb_read_itemdelay(char* str[], int columns, int current)
+{// <nameid>,<delay>
+ int nameid, delay;
struct item_data *id;
- sprintf(line, "%s/item_delay.txt", db_path);
- if ((fp = fopen(line,"r")) == NULL) {
- ShowError("can't read %s\n", line);
- return -1;
- }
+ nameid = atoi(str[0]);
- while(fgets(line, sizeof(line), fp))
+ if( ( id = itemdb_exists(nameid) ) == NULL )
{
- if (line[0] == '/' && line[1] == '/')
- continue;
- if (item_delays == MAX_ITEMDELAYS) {
- ShowError("itemdb_read_itemdelay: Too many entries specified in %s/item_delay.txt! Increase MAX_ITEMDELAYS in itemdb.h!\n", db_path);
- break;
- }
- memset(str, 0, sizeof(str));
- for (j = 0, p = line; j < 2 && p; j++) {
- str[j] = p;
- p = strchr(p, ',');
- if(p) *p++ = 0;
- }
+ ShowWarning("itemdb_read_itemdelay: Invalid item id %d.\n", nameid);
+ return false;
+ }
- if (j < 2 || str[0] == NULL ||
- (nameid = atoi(str[0])) < 0 || !(id = itemdb_exists(nameid)))
- continue;
+ delay = atoi(str[1]);
- id->delay = atoi(str[1]);
- item_delays++;
+ if( delay < 0 )
+ {
+ ShowWarning("itemdb_read_itemdelay: Invalid delay %d for item id %d.\n", id->delay, nameid);
+ return false;
}
- fclose(fp);
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", item_delays, "item_delay.txt");
- return 0;
+ id->delay = delay;
+
+ return true;
}
/*==================================================================
@@ -1076,10 +1015,10 @@ static void itemdb_read(void)
itemdb_readdb();
itemdb_read_itemgroup();
- itemdb_read_itemavail();
- itemdb_read_noequip();
- itemdb_read_itemtrade();
- itemdb_read_itemdelay();
+ sv_readdb(db_path, "item_avail.txt", ',', 2, 2, -1, &itemdb_read_itemavail);
+ sv_readdb(db_path, "item_noequip.txt", ',', 2, 2, -1, &itemdb_read_noequip);
+ sv_readdb(db_path, "item_trade.txt", ',', 3, 3, -1, &itemdb_read_itemtrade);
+ sv_readdb(db_path, "item_delay.txt", ',', 2, 2, MAX_ITEMDELAYS, &itemdb_read_itemdelay);
sv_readdb(db_path, "item_stack.txt", ',', 3, 3, -1, &itemdb_read_stack);
}
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index bc1d5b3b0..1b8917277 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -111,7 +111,7 @@ struct item_data* itemdb_exists(int nameid);
#define itemdb_wlv(n) itemdb_search(n)->wlv
#define itemdb_range(n) itemdb_search(n)->range
#define itemdb_slot(n) itemdb_search(n)->slot
-#define itemdb_available(n) (itemdb_exists(n) && itemdb_search(n)->flag.available)
+#define itemdb_available(n) (itemdb_search(n)->flag.available)
#define itemdb_viewid(n) (itemdb_search(n)->view_id)
#define itemdb_autoequip(n) (itemdb_search(n)->flag.autoequip)
const char* itemdb_typename(int type);
diff --git a/src/map/map.c b/src/map/map.c
index b052cd7bc..e3cada963 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -393,19 +393,11 @@ int map_moveblock(struct block_list *bl, int x1, int y1, unsigned int tick)
//TODO: Perhaps some outs of bounds checking should be placed here?
if (bl->type&BL_CHAR) {
skill_unit_move(bl,tick,2);
- sc = status_get_sc(bl);
- if (sc && sc->count) {
- if (sc->data[SC_CLOSECONFINE])
- status_change_end(bl, SC_CLOSECONFINE, -1);
- if (sc->data[SC_CLOSECONFINE2])
- status_change_end(bl, SC_CLOSECONFINE2, -1);
-// if (sc->data[SC_BLADESTOP]) //Won't stop when you are knocked away, go figure...
-// status_change_end(bl, SC_BLADESTOP, -1);
- if (sc->data[SC_TATAMIGAESHI])
- status_change_end(bl, SC_TATAMIGAESHI, -1);
- if (sc->data[SC_MAGICROD])
- status_change_end(bl, SC_MAGICROD, -1);
- }
+ status_change_end(bl, SC_CLOSECONFINE, INVALID_TIMER);
+ status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER);
+// status_change_end(bl, SC_BLADESTOP, INVALID_TIMER); //Won't stop when you are knocked away, go figure...
+ status_change_end(bl, SC_TATAMIGAESHI, INVALID_TIMER);
+ status_change_end(bl, SC_MAGICROD, INVALID_TIMER);
} else
if (bl->type == BL_NPC)
npc_unsetcells((TBL_NPC*)bl);
@@ -423,6 +415,7 @@ int map_moveblock(struct block_list *bl, int x1, int y1, unsigned int tick)
if (bl->type&BL_CHAR) {
skill_unit_move(bl,tick,3);
+ sc = status_get_sc(bl);
if (sc) {
if (sc->count) {
if (sc->data[SC_CLOAKING])
@@ -1566,7 +1559,7 @@ int map_quit(struct map_session_data *sd)
return 0;
}
- if (sd->npc_timer_id != -1) //Cancel the event timer.
+ if (sd->npc_timer_id != INVALID_TIMER) //Cancel the event timer.
npc_timerevent_quit(sd);
if (sd->npc_id)
@@ -1580,64 +1573,40 @@ int map_quit(struct map_session_data *sd)
if( sd->sc.count )
{
//Status that are not saved...
- if(sd->sc.data[SC_BOSSMAPINFO])
- status_change_end(&sd->bl,SC_BOSSMAPINFO,-1);
- if(sd->sc.data[SC_AUTOTRADE])
- status_change_end(&sd->bl,SC_AUTOTRADE,-1);
- if(sd->sc.data[SC_SPURT])
- status_change_end(&sd->bl,SC_SPURT,-1);
- if(sd->sc.data[SC_BERSERK])
- status_change_end(&sd->bl,SC_BERSERK,-1);
- if(sd->sc.data[SC_TRICKDEAD])
- status_change_end(&sd->bl,SC_TRICKDEAD,-1);
- if(sd->sc.data[SC_GUILDAURA])
- status_change_end(&sd->bl,SC_GUILDAURA,-1);
+ status_change_end(&sd->bl, SC_BOSSMAPINFO, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_AUTOTRADE, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_SPURT, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_BERSERK, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_TRICKDEAD, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_GUILDAURA, INVALID_TIMER);
if(sd->sc.data[SC_ENDURE] && sd->sc.data[SC_ENDURE]->val4)
- status_change_end(&sd->bl,SC_ENDURE,-1); //No need to save infinite endure.
- if(sd->sc.data[SC_WEIGHT50])
- status_change_end(&sd->bl,SC_WEIGHT50,-1);
- if(sd->sc.data[SC_WEIGHT90])
- status_change_end(&sd->bl,SC_WEIGHT90,-1);
+ status_change_end(&sd->bl, SC_ENDURE, INVALID_TIMER); //No need to save infinite endure.
+ status_change_end(&sd->bl, SC_WEIGHT50, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_WEIGHT90, INVALID_TIMER);
if (battle_config.debuff_on_logout&1) {
- if(sd->sc.data[SC_ORCISH])
- status_change_end(&sd->bl,SC_ORCISH,-1);
- if(sd->sc.data[SC_STRIPWEAPON])
- status_change_end(&sd->bl,SC_STRIPWEAPON,-1);
- if(sd->sc.data[SC_STRIPARMOR])
- status_change_end(&sd->bl,SC_STRIPARMOR,-1);
- if(sd->sc.data[SC_STRIPSHIELD])
- status_change_end(&sd->bl,SC_STRIPSHIELD,-1);
- if(sd->sc.data[SC_STRIPHELM])
- status_change_end(&sd->bl,SC_STRIPHELM,-1);
- if(sd->sc.data[SC_EXTREMITYFIST])
- status_change_end(&sd->bl,SC_EXTREMITYFIST,-1);
- if(sd->sc.data[SC_EXPLOSIONSPIRITS])
- status_change_end(&sd->bl,SC_EXPLOSIONSPIRITS,-1);
+ status_change_end(&sd->bl, SC_ORCISH, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_STRIPWEAPON, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_STRIPARMOR, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_STRIPSHIELD, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_STRIPHELM, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_EXTREMITYFIST, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_EXPLOSIONSPIRITS, INVALID_TIMER);
if(sd->sc.data[SC_REGENERATION] && sd->sc.data[SC_REGENERATION]->val4)
- status_change_end(&sd->bl,SC_REGENERATION,-1);
+ status_change_end(&sd->bl, SC_REGENERATION, INVALID_TIMER);
//TO-DO Probably there are way more NPC_type negative status that are removed
- if(sd->sc.data[SC_CHANGEUNDEAD])
- status_change_end(&sd->bl,SC_CHANGEUNDEAD,-1);
+ status_change_end(&sd->bl, SC_CHANGEUNDEAD, INVALID_TIMER);
// Both these statuses are removed on logout. [L0ne_W0lf]
- if(sd->sc.data[SC_SLOWCAST])
- status_change_end(&sd->bl,SC_SLOWCAST,-1);
- if(sd->sc.data[SC_CRITICALWOUND])
- status_change_end(&sd->bl,SC_CRITICALWOUND,-1);
+ status_change_end(&sd->bl, SC_SLOWCAST, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_CRITICALWOUND, INVALID_TIMER);
}
if (battle_config.debuff_on_logout&2)
{
- if(sd->sc.data[SC_MAXIMIZEPOWER])
- status_change_end(&sd->bl,SC_MAXIMIZEPOWER,-1);
- if(sd->sc.data[SC_MAXOVERTHRUST])
- status_change_end(&sd->bl,SC_MAXOVERTHRUST,-1);
- if(sd->sc.data[SC_STEELBODY])
- status_change_end(&sd->bl,SC_STEELBODY,-1);
- if(sd->sc.data[SC_PRESERVE])
- status_change_end(&sd->bl,SC_PRESERVE,-1);
- if(sd->sc.data[SC_KAAHI])
- status_change_end(&sd->bl,SC_KAAHI,-1);
- if(sd->sc.data[SC_SPIRIT])
- status_change_end(&sd->bl,SC_SPIRIT,-1);
+ status_change_end(&sd->bl, SC_MAXIMIZEPOWER, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_MAXOVERTHRUST, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_STEELBODY, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_PRESERVE, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_KAAHI, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_SPIRIT, INVALID_TIMER);
}
}
@@ -2109,7 +2078,7 @@ int map_addmobtolist(unsigned short m, struct spawn_data *spawn)
void map_spawnmobs(int m)
{
int i, k=0;
- if (map[m].mob_delete_timer != -1)
+ if (map[m].mob_delete_timer != INVALID_TIMER)
{ //Mobs have not been removed yet [Skotlex]
delete_timer(map[m].mob_delete_timer, map_removemobs_timer);
map[m].mob_delete_timer = INVALID_TIMER;
@@ -2184,7 +2153,7 @@ int map_removemobs_timer(int tid, unsigned int tick, int id, intptr data)
void map_removemobs(int m)
{
- if (map[m].mob_delete_timer != -1) // should never happen
+ if (map[m].mob_delete_timer != INVALID_TIMER) // should never happen
return; //Mobs are already scheduled for removal
map[m].mob_delete_timer = add_timer(gettick()+battle_config.mob_remove_delay, map_removemobs_timer, m, 0);
@@ -2804,8 +2773,16 @@ void map_flags_init(void)
for( i = 0; i < map_num; i++ )
{
+ // mapflags
memset(&map[i].flag, 0, sizeof(map[i].flag));
+ // additional mapflag data
+ map[i].zone = 0; // restricted mapflag zone
+ map[i].nocommand = 0; // nocommand mapflag level
+ map[i].bexp = 100; // per map base exp multiplicator
+ map[i].jexp = 100; // per map job exp multiplicator
+
+ // adjustments
if( battle_config.pk_mode )
map[i].flag.pvp = 1; // make all maps pvp for pk_mode [Valaris]
}
@@ -2975,11 +2952,7 @@ int map_readallmaps (void)
map[i].bxs = (map[i].xs + BLOCK_SIZE - 1) / BLOCK_SIZE;
map[i].bys = (map[i].ys + BLOCK_SIZE - 1) / BLOCK_SIZE;
-
- // default experience multiplicators
- map[i].jexp = 100;
- map[i].bexp = 100;
-
+
size = map[i].bxs * map[i].bys * sizeof(struct block_list*);
map[i].block = (struct block_list**)aCalloc(size, 1);
map[i].block_mob = (struct block_list**)aCalloc(size, 1);
@@ -3012,7 +2985,7 @@ static int char_ip_set = 0;
/*==========================================
* Console Command Parser [Wizputer]
*------------------------------------------*/
-int parse_console(char* buf)
+int parse_console(const char* buf)
{
char type[64];
char command[64];
@@ -3026,14 +2999,20 @@ int parse_console(char* buf)
memset(&sd, 0, sizeof(struct map_session_data));
strcpy(sd.status.name, "console");
- if( (n=sscanf(buf, "%[^:]:%[^:]:%99s %d %d[^\n]",type,command,map,&x,&y)) < 5 )
- if( (n=sscanf(buf, "%[^:]:%[^\n]",type,command)) < 2 )
- n = sscanf(buf,"%[^\n]",type);
+ if( ( n = sscanf(buf, "%63[^:]:%63[^:]:%63s %d %d[^\n]", type, command, map, &x, &y) ) < 5 )
+ {
+ if( ( n = sscanf(buf, "%63[^:]:%63[^\n]", type, command) ) < 2 )
+ {
+ n = sscanf(buf, "%63[^\n]", type);
+ }
+ }
- if( n == 5 ) {
+ if( n == 5 )
+ {
m = map_mapname2mapid(map);
- if( m < 0 ){
- ShowWarning("Console: Unknown map\n");
+ if( m < 0 )
+ {
+ ShowWarning("Console: Unknown map.\n");
return 0;
}
sd.bl.m = m;
@@ -3042,32 +3021,40 @@ int parse_console(char* buf)
sd.bl.x = x;
if( y > 0 )
sd.bl.y = y;
- } else {
+ }
+ else
+ {
map[0] = '\0';
- if( n < 2 ) command[0] = '\0';
- if( n < 1 ) type[0] = '\0';
+ if( n < 2 )
+ command[0] = '\0';
+ if( n < 1 )
+ type[0] = '\0';
}
- ShowInfo("Type of command: '%s' || Command: '%s' || Map: '%s' Coords: %d %d\n", type, command, map, x, y);
+ ShowNotice("Type of command: '%s' || Command: '%s' || Map: '%s' Coords: %d %d\n", type, command, map, x, y);
- if( n == 5 && strcmpi("admin",type) == 0 ){
- if( !is_atcommand(sd.fd,&sd,command,0) )
+ if( n == 5 && strcmpi("admin",type) == 0 )
+ {
+ if( !is_atcommand(sd.fd, &sd, command, 0) )
ShowInfo("Console: not atcommand\n");
- } else if( n == 2 && strcmpi("server",type) == 0 ){
- if( strcmpi("shutdown",command) == 0 ||
- strcmpi("exit",command) == 0 ||
- strcmpi("quit",command) == 0 ){
+ }
+ else if( n == 2 && strcmpi("server", type) == 0 )
+ {
+ if( strcmpi("shutdown", command) == 0 || strcmpi("exit", command) == 0 || strcmpi("quit", command) == 0 )
+ {
runflag = 0;
}
- } else if( strcmpi("help",type) == 0 ){
- ShowNotice("To use GM commands:\n");
- ShowInfo("admin:<gm command>:<map of \"gm\"> <x> <y>\n");
+ }
+ else if( strcmpi("help", type) == 0 )
+ {
+ ShowInfo("To use GM commands:\n");
+ ShowInfo(" admin:<gm command>:<map of \"gm\"> <x> <y>\n");
ShowInfo("You can use any GM command that doesn't require the GM.\n");
ShowInfo("No using @item or @warp however you can use @charwarp\n");
ShowInfo("The <map of \"gm\"> <x> <y> is for commands that need coords of the GM\n");
ShowInfo("IE: @spawn\n");
ShowInfo("To shutdown the server:\n");
- ShowInfo("server:shutdown\n");
+ ShowInfo(" server:shutdown\n");
}
return 0;
@@ -3412,9 +3399,14 @@ void do_final(void)
ShowStatus("Terminating...\n");
+ // remove all objects on maps
for (i = 0; i < map_num; i++)
+ {
+ ShowStatus("Cleaning up maps [%d/%d]: %s..."CL_CLL"\r", i+1, map_num, map[i].name);
if (map[i].m >= 0)
map_foreachinmap(cleanup_sub, i, BL_ALL);
+ }
+ ShowStatus("Cleaned up %d maps."CL_CLL"\n", map_num);
//Scan any remaining players (between maps?) to kick them out. [Skotlex]
iter = mapit_getallusers();
diff --git a/src/map/mercenary.c b/src/map/mercenary.c
index 79bec2da6..8300628d5 100644
--- a/src/map/mercenary.c
+++ b/src/map/mercenary.c
@@ -8,6 +8,7 @@
#include "../common/nullpo.h"
#include "../common/mmo.h"
#include "../common/showmsg.h"
+#include "../common/strlib.h"
#include "../common/utils.h"
#include "log.h"
@@ -249,7 +250,7 @@ int merc_delete(struct mercenary_data *md, int reply)
if( md->devotion_flag )
{
md->devotion_flag = 0;
- status_change_end(&sd->bl, SC_DEVOTION, -1);
+ status_change_end(&sd->bl, SC_DEVOTION, INVALID_TIMER);
}
switch( reply )
@@ -402,162 +403,105 @@ int mercenary_checkskill(struct mercenary_data *md, int skill_id)
return 0;
}
-int read_mercenarydb(void)
+static bool read_mercenarydb_sub(char* str[], int columns, int current)
{
- FILE *fp;
- char line[1024], *p;
- char *str[26];
- int i, j = 0, k = 0, ele;
+ int ele;
struct s_mercenary_db *db;
struct status_data *status;
- sprintf(line, "%s/%s", db_path, "mercenary_db.txt");
- memset(mercenary_db,0,sizeof(mercenary_db));
-
- fp = fopen(line, "r");
- if( !fp )
+ db = &mercenary_db[current];
+ db->class_ = atoi(str[0]);
+ strncpy(db->sprite, str[1], NAME_LENGTH);
+ strncpy(db->name, str[2], NAME_LENGTH);
+ db->lv = atoi(str[3]);
+
+ status = &db->status;
+ db->vd.class_ = db->class_;
+
+ status->max_hp = atoi(str[4]);
+ status->max_sp = atoi(str[5]);
+ status->rhw.range = atoi(str[6]);
+ status->rhw.atk = atoi(str[7]);
+ status->rhw.atk2 = status->rhw.atk + atoi(str[8]);
+ status->def = atoi(str[9]);
+ status->mdef = atoi(str[10]);
+ status->str = atoi(str[11]);
+ status->agi = atoi(str[12]);
+ status->vit = atoi(str[13]);
+ status->int_ = atoi(str[14]);
+ status->dex = atoi(str[15]);
+ status->luk = atoi(str[16]);
+ db->range2 = atoi(str[17]);
+ db->range3 = atoi(str[18]);
+ status->size = atoi(str[19]);
+ status->race = atoi(str[20]);
+
+ ele = atoi(str[21]);
+ status->def_ele = ele%10;
+ status->ele_lv = ele/20;
+ if( status->def_ele >= ELE_MAX )
{
- ShowError("read_mercenarydb : can't read mercenary_db.txt\n");
- return -1;
+ ShowWarning("Mercenary %d has invalid element type %d (max element is %d)\n", db->class_, status->def_ele, ELE_MAX - 1);
+ status->def_ele = ELE_NEUTRAL;
}
-
- while( fgets(line, sizeof(line), fp) && j < MAX_MERCENARY_CLASS )
+ if( status->ele_lv < 1 || status->ele_lv > 4 )
{
- k++;
- if( line[0] == '/' && line[1] == '/' )
- continue;
-
- i = 0;
- p = strtok(line, ",");
- while( p != NULL && i < 26 )
- {
- str[i++] = p;
- p = strtok(NULL, ",");
- }
- if( i < 26 )
- {
- ShowError("read_mercenarydb : Incorrect number of columns at mercenary_db.txt line %d.\n", k);
- continue;
- }
-
- db = &mercenary_db[j];
- db->class_ = atoi(str[0]);
- strncpy(db->sprite, str[1], NAME_LENGTH);
- strncpy(db->name, str[2], NAME_LENGTH);
- db->lv = atoi(str[3]);
-
- status = &db->status;
- db->vd.class_ = db->class_;
-
- status->max_hp = atoi(str[4]);
- status->max_sp = atoi(str[5]);
- status->rhw.range = atoi(str[6]);
- status->rhw.atk = atoi(str[7]);
- status->rhw.atk2 = status->rhw.atk + atoi(str[8]);
- status->def = atoi(str[9]);
- status->mdef = atoi(str[10]);
- status->str = atoi(str[11]);
- status->agi = atoi(str[12]);
- status->vit = atoi(str[13]);
- status->int_ = atoi(str[14]);
- status->dex = atoi(str[15]);
- status->luk = atoi(str[16]);
- db->range2 = atoi(str[17]);
- db->range3 = atoi(str[18]);
- status->size = atoi(str[19]);
- status->race = atoi(str[20]);
-
- ele = atoi(str[21]);
- status->def_ele = ele%10;
- status->ele_lv = ele/20;
- if( status->def_ele >= ELE_MAX )
- {
- ShowWarning("Mercenary %d has invalid element type %d (max element is %d)\n", db->class_, status->def_ele, ELE_MAX - 1);
- status->def_ele = ELE_NEUTRAL;
- }
- if( status->ele_lv < 1 || status->ele_lv > 4 )
- {
- ShowWarning("Mercenary %d has invalid element level %d (max is 4)\n", db->class_, status->ele_lv);
- status->ele_lv = 1;
- }
-
- status->aspd_rate = 1000;
- status->speed = atoi(str[22]);
- status->adelay = atoi(str[23]);
- status->amotion = atoi(str[24]);
- status->dmotion = atoi(str[25]);
-
- j++;
+ ShowWarning("Mercenary %d has invalid element level %d (max is 4)\n", db->class_, status->ele_lv);
+ status->ele_lv = 1;
}
- fclose(fp);
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' mercenaries in '"CL_WHITE"db/mercenary_db.txt"CL_RESET"'.\n",j);
+ status->aspd_rate = 1000;
+ status->speed = atoi(str[22]);
+ status->adelay = atoi(str[23]);
+ status->amotion = atoi(str[24]);
+ status->dmotion = atoi(str[25]);
- return 0;
+ return true;
}
-int read_mercenary_skilldb(void)
+int read_mercenarydb(void)
{
- FILE *fp;
- char line[1024], *p;
- char *str[3];
+ memset(mercenary_db,0,sizeof(mercenary_db));
+ sv_readdb(db_path, "mercenary_db.txt", ',', 26, 26, MAX_MERCENARY_CLASS, &read_mercenarydb_sub);
+
+ return 0;
+}
+
+static bool read_mercenary_skilldb_sub(char* str[], int columns, int current)
+{// <merc id>,<skill id>,<skill level>
struct s_mercenary_db *db;
- int i, j = 0, k = 0, class_;
+ int i, class_;
int skillid, skilllv;
- sprintf(line, "%s/%s", db_path, "mercenary_skill_db.txt");
- fp = fopen(line, "r");
- if( !fp )
+ class_ = atoi(str[0]);
+ ARR_FIND(0, MAX_MERCENARY_CLASS, i, class_ == mercenary_db[i].class_);
+ if( i == MAX_MERCENARY_CLASS )
{
- ShowError("read_mercenary_skilldb : can't read mercenary_skill_db.txt\n");
- return -1;
+ ShowError("read_mercenary_skilldb : Class %d not found in mercenary_db for skill entry.\n", class_);
+ return false;
}
-
- while( fgets(line, sizeof(line), fp) )
+
+ skillid = atoi(str[1]);
+ if( skillid < MC_SKILLBASE || skillid >= MC_SKILLBASE + MAX_MERCSKILL )
{
- k++;
- if( line[0] == '/' && line[1] == '/' )
- continue;
-
- i = 0;
- p = strtok(line, ",");
- while( p != NULL && i < 3 )
- {
- str[i++] = p;
- p = strtok(NULL, ",");
- }
- if( i < 3 )
- {
- ShowError("read_mercenary_skilldb : Incorrect number of columns at mercenary_skill_db.txt line %d.\n", k);
- continue;
- }
-
- class_ = atoi(str[0]);
- ARR_FIND(0, MAX_MERCENARY_CLASS, i, class_ == mercenary_db[i].class_);
- if( i == MAX_MERCENARY_CLASS )
- {
- ShowError("read_mercenary_skilldb : Class not found in mercenary_db for skill entry, line %d.\n", k);
- continue;
- }
-
- skillid = atoi(str[1]);
- if( skillid < MC_SKILLBASE || skillid >= MC_SKILLBASE + MAX_MERCSKILL )
- {
- ShowError("read_mercenary_skilldb : Skill out of range, line %d.\n", k);
- continue;
- }
-
- db = &mercenary_db[i];
- skilllv = atoi(str[2]);
-
- i = skillid - MC_SKILLBASE;
- db->skill[i].id = skillid;
- db->skill[i].lv = skilllv;
- j++;
+ ShowError("read_mercenary_skilldb : Skill %d out of range.\n", skillid);
+ return false;
}
- fclose(fp);
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"db/mercenary_skill_db.txt"CL_RESET"'.\n",j);
+ db = &mercenary_db[i];
+ skilllv = atoi(str[2]);
+
+ i = skillid - MC_SKILLBASE;
+ db->skill[i].id = skillid;
+ db->skill[i].lv = skilllv;
+
+ return true;
+}
+
+int read_mercenary_skilldb(void)
+{
+ sv_readdb(db_path, "mercenary_skill_db.txt", ',', 3, 3, -1, &read_mercenary_skilldb_sub);
+
return 0;
}
diff --git a/src/map/mob.c b/src/map/mob.c
index d67b470af..6135850b6 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -1183,7 +1183,7 @@ int mob_unlocktarget(struct mob_data *md, unsigned int tick)
switch (md->state.skillstate) {
case MSS_WALK:
- if (md->ud.walktimer != -1)
+ if (md->ud.walktimer != INVALID_TIMER)
break;
//Because it is not unset when the mob finishes walking.
md->state.skillstate = MSS_IDLE;
@@ -1274,7 +1274,7 @@ int mob_warpchase(struct mob_data *md, struct block_list *target)
if (target->m == md->bl.m && check_distance_bl(&md->bl, target, AREA_SIZE))
return 0; //No need to do a warp chase.
- if (md->ud.walktimer != -1 &&
+ if (md->ud.walktimer != INVALID_TIMER &&
map_getcell(md->bl.m,md->ud.to_x,md->ud.to_y,CELL_CHKNPC))
return 1; //Already walking to a warp.
@@ -1306,10 +1306,10 @@ static bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick)
md->last_thinktime = tick;
- if (md->ud.skilltimer != -1)
+ if (md->ud.skilltimer != INVALID_TIMER)
return false;
- if(md->ud.walktimer != -1 && md->ud.walkpath.path_pos <= 3)
+ if(md->ud.walktimer != INVALID_TIMER && md->ud.walkpath.path_pos <= 3)
return false;
// Abnormalities
@@ -1331,8 +1331,8 @@ static bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick)
{ //Check validity of current target. [Skotlex]
tbl = map_id2bl(md->target_id);
if (!tbl || tbl->m != md->bl.m ||
- (md->ud.attacktimer == -1 && !status_check_skilluse(&md->bl, tbl, 0, 0)) ||
- (md->ud.walktimer != -1 && !(battle_config.mob_ai&0x1) && !check_distance_bl(&md->bl, tbl, md->min_chase)) ||
+ (md->ud.attacktimer == INVALID_TIMER && !status_check_skilluse(&md->bl, tbl, 0, 0)) ||
+ (md->ud.walktimer != INVALID_TIMER && !(battle_config.mob_ai&0x1) && !check_distance_bl(&md->bl, tbl, md->min_chase)) ||
(
tbl->type == BL_PC &&
((((TBL_PC*)tbl)->state.gangsterparadise && !(mode&MD_BOSS)) ||
@@ -1447,7 +1447,7 @@ static bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick)
if (tbl->type == BL_ITEM)
{ //Loot time.
struct flooritem_data *fitem;
- if (md->ud.target == tbl->id && md->ud.walktimer != -1)
+ if (md->ud.target == tbl->id && md->ud.walktimer != INVALID_TIMER)
return true; //Already locked.
if (md->lootitem == NULL)
{ //Can't loot...
@@ -1469,7 +1469,7 @@ static bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick)
return true;
}
//Within looting range.
- if (md->ud.attacktimer != -1)
+ if (md->ud.attacktimer != INVALID_TIMER)
return true; //Busy attacking?
fitem = (struct flooritem_data *)tbl;
@@ -1497,7 +1497,7 @@ static bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick)
}
//Attempt to attack.
//At this point we know the target is attackable, we just gotta check if the range matches.
- if (md->ud.target == tbl->id && md->ud.attacktimer != -1) //Already locked.
+ if (md->ud.target == tbl->id && md->ud.attacktimer != INVALID_TIMER) //Already locked.
return true;
if (battle_check_range (&md->bl, tbl, md->status.rhw.range))
@@ -1526,7 +1526,7 @@ static bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick)
return true;
}
- if (md->ud.walktimer != -1 && md->ud.target == tbl->id &&
+ if (md->ud.walktimer != INVALID_TIMER && md->ud.target == tbl->id &&
(
!(battle_config.mob_ai&0x1) ||
check_distance_blxy(tbl, md->ud.to_x, md->ud.to_y, md->status.rhw.range)
@@ -2432,7 +2432,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
md->status.hp = 1;
}
- if(md->deletetimer!=-1) {
+ if(md->deletetimer != INVALID_TIMER) {
delete_timer(md->deletetimer,mob_timer_delete);
md->deletetimer = INVALID_TIMER;
}
@@ -2900,7 +2900,7 @@ int mobskill_use(struct mob_data *md, unsigned int tick, int event)
nullpo_ret(md);
nullpo_ret(ms = md->db->skill);
- if (!battle_config.mob_skill_rate || md->ud.skilltimer != -1 || !md->db->maxskill)
+ if (!battle_config.mob_skill_rate || md->ud.skilltimer != INVALID_TIMER || !md->db->maxskill)
return 0;
if (event == -1 && DIFF_TICK(md->ud.canact_tick, tick) > 0)
@@ -4123,7 +4123,7 @@ static bool mob_parse_row_mobskilldb(char** str, int columns, int current)
ms->target = MST_TARGET;
}
} else if (ms->target > MST_MASTER) {
- ShowWarning("mob_parse_row_mobskilldb: Wrong mob skill target 'around' for non-ground skill %d (%s) for %s\n.",
+ ShowWarning("mob_parse_row_mobskilldb: Wrong mob skill target 'around' for non-ground skill %d (%s) for %s.\n",
ms->skill_id, skill_get_name(ms->skill_id),
mob_id < 0?"all mobs":mob_db_data[mob_id]->sprite);
ms->target = MST_TARGET;
diff --git a/src/map/npc.c b/src/map/npc.c
index 4b188c177..1bf5bd312 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -493,10 +493,10 @@ int npc_timerevent(int tid, unsigned int tick, int id, intptr data)
else
{
if( sd )
- sd->npc_timer_id = -1;
+ sd->npc_timer_id = INVALID_TIMER;
else
{
- nd->u.scr.timerid = -1;
+ nd->u.scr.timerid = INVALID_TIMER;
nd->u.scr.timertick = 0; // NPC timer stopped
}
ers_free(timer_event_ers, ted);
@@ -544,10 +544,10 @@ int npc_timerevent_start(struct npc_data* nd, int rid)
// Check if timer is already started.
if( sd )
{
- if( sd->npc_timer_id != -1 )
+ if( sd->npc_timer_id != INVALID_TIMER )
return 0;
}
- else if( nd->u.scr.timerid != -1 )
+ else if( nd->u.scr.timerid != INVALID_TIMER )
return 0;
// Arrange for the next event
@@ -587,7 +587,7 @@ int npc_timerevent_stop(struct npc_data* nd)
}
tid = sd?&sd->npc_timer_id:&nd->u.scr.timerid;
- if( *tid == -1 ) // Nothing to stop
+ if( *tid == INVALID_TIMER ) // Nothing to stop
return 0;
// Delete timer
@@ -595,7 +595,7 @@ int npc_timerevent_stop(struct npc_data* nd)
if( td && td->data )
ers_free(timer_event_ers, (void*)td->data);
delete_timer(*tid,npc_timerevent);
- *tid = -1;
+ *tid = INVALID_TIMER;
if( !sd )
{
@@ -615,11 +615,11 @@ void npc_timerevent_quit(struct map_session_data* sd)
struct timer_event_data *ted;
// Check timer existance
- if( sd->npc_timer_id == -1 )
+ if( sd->npc_timer_id == INVALID_TIMER )
return;
if( !(td = get_timer(sd->npc_timer_id)) )
{
- sd->npc_timer_id = -1;
+ sd->npc_timer_id = INVALID_TIMER;
return;
}
@@ -627,7 +627,7 @@ void npc_timerevent_quit(struct map_session_data* sd)
nd = (struct npc_data *)map_id2bl(td->id);
ted = (struct timer_event_data*)td->data;
delete_timer(sd->npc_timer_id, npc_timerevent);
- sd->npc_timer_id = -1;
+ sd->npc_timer_id = INVALID_TIMER;
// Execute OnTimerQuit
if( nd && nd->bl.type == BL_NPC )
@@ -873,7 +873,7 @@ int npc_touch_areanpc(struct map_session_data* sd, int m, int x, int y)
{ // failed to run OnTouch event, so just click the npc
struct unit_data *ud = unit_bl2ud(&sd->bl);
if( ud && ud->walkpath.path_pos < ud->walkpath.path_len )
- { // Since walktimer always == -1 at this time, we stop walking manually. [Inkfish]
+ { // Since walktimer always == INVALID_TIMER at this time, we stop walking manually. [Inkfish]
clif_fixpos(&sd->bl);
ud->walkpath.path_pos = ud->walkpath.path_len;
}
@@ -1183,7 +1183,7 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po
if( sd->state.trading )
return 4;
- if( (item = itemdb_search(nameid)) == NULL )
+ if( (item = itemdb_exists(nameid)) == NULL )
return 5; // Invalid Item
ARR_FIND(0, nd->u.shop.count, i, nd->u.shop.shop_item[i].nameid == nameid);
@@ -1600,7 +1600,7 @@ int npc_unload(struct npc_data* nd)
}
mapit_free(iter);
- if (nd->u.scr.timerid != -1) {
+ if (nd->u.scr.timerid != INVALID_TIMER) {
const struct TimerData *td = NULL;
td = get_timer(nd->u.scr.timerid);
if (td && td->data)
@@ -2245,7 +2245,7 @@ static const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, cons
nd->u.scr.timeramount++;
}
}
- nd->u.scr.timerid = -1;
+ nd->u.scr.timerid = INVALID_TIMER;
return end;
}
@@ -2428,7 +2428,7 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
nd->u.scr.timeramount++;
}
}
- nd->u.scr.timerid = -1;
+ nd->u.scr.timerid = INVALID_TIMER;
return end;
}
@@ -3536,7 +3536,7 @@ int do_init_npc(void)
fake_nd->subtype = SCRIPT;
strdb_put(npcname_db, fake_nd->exname, fake_nd);
- fake_nd->u.scr.timerid = -1;
+ fake_nd->u.scr.timerid = INVALID_TIMER;
map_addiddb(&fake_nd->bl);
// End of initialization
diff --git a/src/map/party.c b/src/map/party.c
index 407221cde..9c55a05f2 100644
--- a/src/map/party.c
+++ b/src/map/party.c
@@ -298,11 +298,11 @@ int party_recv_info(struct party *sp)
int party_invite(struct map_session_data *sd,struct map_session_data *tsd)
{
- struct party_data *p=party_search(sd->status.party_id);
+ struct party_data *p;
int i,flag=0;
nullpo_ret(sd);
- if( p == NULL )
+ if( ( p = party_search(sd->status.party_id) ) == NULL )
return 0;
if( tsd == NULL) { //TODO: Find the correct reply packet.
clif_displaymessage(sd->fd, msg_txt(3));
diff --git a/src/map/pc.c b/src/map/pc.c
index e7ef23ce9..7525ff63c 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -170,7 +170,7 @@ int pc_addspiritball(struct map_session_data *sd,int interval,int max)
if( sd->spiritball && sd->spiritball >= max )
{
- if(sd->spirit_timer[0] != -1)
+ if(sd->spirit_timer[0] != INVALID_TIMER)
delete_timer(sd->spirit_timer[0],pc_spiritball_timer);
sd->spiritball--;
if( sd->spiritball != 0 )
@@ -209,14 +209,14 @@ int pc_delspiritball(struct map_session_data *sd,int count,int type)
count = MAX_SKILL_LEVEL;
for(i=0;i<count;i++) {
- if(sd->spirit_timer[i] != -1) {
+ if(sd->spirit_timer[i] != INVALID_TIMER) {
delete_timer(sd->spirit_timer[i],pc_spiritball_timer);
- sd->spirit_timer[i] = -1;
+ sd->spirit_timer[i] = INVALID_TIMER;
}
}
for(i=count;i<MAX_SKILL_LEVEL;i++) {
sd->spirit_timer[i-count] = sd->spirit_timer[i];
- sd->spirit_timer[i] = -1;
+ sd->spirit_timer[i] = INVALID_TIMER;
}
if(!type)
@@ -317,7 +317,7 @@ int pc_inventory_rental_clear(struct map_session_data *sd)
if( sd->rental_timer != INVALID_TIMER )
{
delete_timer(sd->rental_timer, pc_inventory_rental_end);
- sd->rental_timer = -1;
+ sd->rental_timer = INVALID_TIMER;
}
return 1;
@@ -892,9 +892,7 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
if (!(battle_config.display_skill_fail&2))
sd->state.showdelay = 1;
- // ƒAƒCƒeƒ€ƒ`ƒFƒbƒN
pc_setinventorydata(sd);
- pc_checkitem(sd);
status_change_init(&sd->bl);
if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) && (pc_isGM(sd) >= get_atcommand_level(atcommand_hide)))
@@ -912,7 +910,7 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
// Event Timers
for( i = 0; i < MAX_EVENTTIMER; i++ )
- sd->eventtimer[i] = -1;
+ sd->eventtimer[i] = INVALID_TIMER;
// Rental Timer
sd->rental_timer = INVALID_TIMER;
@@ -1418,9 +1416,9 @@ int pc_updateweightstatus(struct map_session_data *sd)
// stop old status change
if( old_overweight == 1 )
- status_change_end(&sd->bl, SC_WEIGHT50, -1);
+ status_change_end(&sd->bl, SC_WEIGHT50, INVALID_TIMER);
else if( old_overweight == 2 )
- status_change_end(&sd->bl, SC_WEIGHT90, -1);
+ status_change_end(&sd->bl, SC_WEIGHT90, INVALID_TIMER);
// start new status change
if( new_overweight == 1 )
@@ -3718,7 +3716,7 @@ int pc_useitem(struct map_session_data *sd,int n)
//perform a skill-use check before going through. [Skotlex]
//resurrection was picked as testing skill, as a non-offensive, generic skill, it will do.
//FIXME: Is this really needed here? It'll be checked in unit.c after all and this prevents skill items using when silenced [Inkfish]
- if( sd->inventory_data[n]->flag.delay_consume && ( sd->ud.skilltimer != -1 /*|| !status_check_skilluse(&sd->bl, &sd->bl, ALL_RESURRECTION, 0)*/ ) )
+ if( sd->inventory_data[n]->flag.delay_consume && ( sd->ud.skilltimer != INVALID_TIMER /*|| !status_check_skilluse(&sd->bl, &sd->bl, ALL_RESURRECTION, 0)*/ ) )
return 0;
if( sd->inventory_data[n]->delay > 0 ) { // Check if there is a delay on this item [Paradox924X]
@@ -4118,21 +4116,15 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y
{ // Cancel some map related stuff.
if (sd->sc.data[SC_JAILED])
return 1; //You may not get out!
- if (sd->sc.data[SC_BOSSMAPINFO])
- status_change_end(&sd->bl,SC_BOSSMAPINFO,-1);
- if (sd->sc.data[SC_WARM])
- status_change_end(&sd->bl,SC_WARM,-1);
- if (sd->sc.data[SC_SUN_COMFORT])
- status_change_end(&sd->bl,SC_SUN_COMFORT,-1);
- if (sd->sc.data[SC_MOON_COMFORT])
- status_change_end(&sd->bl,SC_MOON_COMFORT,-1);
- if (sd->sc.data[SC_STAR_COMFORT])
- status_change_end(&sd->bl,SC_STAR_COMFORT,-1);
- if (sd->sc.data[SC_MIRACLE])
- status_change_end(&sd->bl,SC_MIRACLE,-1);
+ status_change_end(&sd->bl, SC_BOSSMAPINFO, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_WARM, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_SUN_COMFORT, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_MOON_COMFORT, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_STAR_COMFORT, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_MIRACLE, INVALID_TIMER);
if (sd->sc.data[SC_KNOWLEDGE]) {
struct status_change_entry *sce = sd->sc.data[SC_KNOWLEDGE];
- if (sce->timer != -1)
+ if (sce->timer != INVALID_TIMER)
delete_timer(sce->timer, status_change_timer);
sce->timer = add_timer(gettick() + skill_get_time(SG_KNOWLEDGE, sce->val1), status_change_timer, sd->bl.id, SC_KNOWLEDGE);
}
@@ -4404,17 +4396,17 @@ int pc_checkallowskill(struct map_session_data *sd)
{ // Skills requiring specific weapon types
if(sd->sc.data[scw_list[i]] &&
!pc_check_weapontype(sd,skill_get_weapontype(status_sc2skill(scw_list[i]))))
- status_change_end(&sd->bl,scw_list[i],-1);
+ status_change_end(&sd->bl, scw_list[i], INVALID_TIMER);
}
if(sd->sc.data[SC_SPURT] && sd->status.weapon)
// Spurt requires bare hands (feet, in fact xD)
- status_change_end(&sd->bl,SC_SPURT,-1);
+ status_change_end(&sd->bl, SC_SPURT, INVALID_TIMER);
if(sd->status.shield <= 0) { // Skills requiring a shield
for (i = 0; i < ARRAYLENGTH(scs_list); i++)
if(sd->sc.data[scs_list[i]])
- status_change_end(&sd->bl,scs_list[i],-1);
+ status_change_end(&sd->bl, scs_list[i], INVALID_TIMER);
}
return 0;
}
@@ -4776,7 +4768,7 @@ int pc_follow_timer(int tid, unsigned int tick, int id, intptr data)
// either player or target is currently detached from map blocks (could be teleporting),
// but still connected to this map, so we'll just increment the timer and check back later
if (sd->bl.prev != NULL && tbl->prev != NULL &&
- sd->ud.skilltimer == -1 && sd->ud.attacktimer == -1 && sd->ud.walktimer == -1)
+ sd->ud.skilltimer == INVALID_TIMER && sd->ud.attacktimer == INVALID_TIMER && sd->ud.walktimer == INVALID_TIMER)
{
if((sd->bl.m == tbl->m) && unit_can_reach_bl(&sd->bl,tbl, AREA_SIZE, 0, NULL, NULL)) {
if (!check_distance_bl(&sd->bl, tbl, 5))
@@ -4808,11 +4800,11 @@ int pc_follow(struct map_session_data *sd,int target_id)
struct block_list *bl = map_id2bl(target_id);
if (bl == NULL /*|| bl->type != BL_PC*/)
return 1;
- if (sd->followtimer != -1)
+ if (sd->followtimer != INVALID_TIMER)
pc_stop_following(sd);
sd->followtarget = target_id;
- pc_follow_timer(-1,gettick(),sd->bl.id,0);
+ pc_follow_timer(INVALID_TIMER, gettick(), sd->bl.id, 0);
return 0;
}
@@ -5705,7 +5697,8 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
for(k = 0; k < 5; k++)
if (sd->devotion[k]){
struct map_session_data *devsd = map_id2sd(sd->devotion[k]);
- if (devsd) status_change_end(&devsd->bl,SC_DEVOTION,-1);
+ if (devsd)
+ status_change_end(&devsd->bl, SC_DEVOTION, INVALID_TIMER);
sd->devotion[k] = 0;
}
@@ -5774,6 +5767,11 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
md->level++;
status_calc_mob(md, 0);
status_percent_heal(src,10,0);
+
+ if( battle_config.show_mob_info&4 )
+ {// update name with new level
+ clif_charnameack(0, &md->bl);
+ }
}
src = battle_get_master(src); // Maybe Player Summon
}
@@ -5854,7 +5852,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
pc_setinvincibletimer(sd, battle_config.pc_invincible_time);
sc_start(&sd->bl,status_skill2sc(MO_STEELBODY),100,1,skill_get_time(MO_STEELBODY,1));
if(map_flag_gvg(sd->bl.m))
- pc_respawn_timer(-1, gettick(), sd->bl.id, 0);
+ pc_respawn_timer(INVALID_TIMER, gettick(), sd->bl.id, 0);
return 0;
}
}
@@ -6352,7 +6350,7 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper)
//Remove status specific to your current tree skills.
enum sc_type sc = status_skill2sc(id);
if (sc > SC_COMMON_MAX && sd->sc.data[sc])
- status_change_end(&sd->bl, sc, -1);
+ status_change_end(&sd->bl, sc, INVALID_TIMER);
}
}
@@ -6998,7 +6996,7 @@ static int pc_eventtimer(int tid, unsigned int tick, int id, intptr data)
ARR_FIND( 0, MAX_EVENTTIMER, i, sd->eventtimer[i] == tid );
if( i < MAX_EVENTTIMER )
{
- sd->eventtimer[i] = -1;
+ sd->eventtimer[i] = INVALID_TIMER;
sd->eventcount--;
npc_event(sd,p,0);
}
@@ -7017,7 +7015,7 @@ int pc_addeventtimer(struct map_session_data *sd,int tick,const char *name)
int i;
nullpo_ret(sd);
- ARR_FIND( 0, MAX_EVENTTIMER, i, sd->eventtimer[i] == -1 );
+ ARR_FIND( 0, MAX_EVENTTIMER, i, sd->eventtimer[i] == INVALID_TIMER );
if( i == MAX_EVENTTIMER )
return 0;
@@ -7042,7 +7040,7 @@ int pc_deleventtimer(struct map_session_data *sd,const char *name)
// find the named event timer
ARR_FIND( 0, MAX_EVENTTIMER, i,
- sd->eventtimer[i] != -1 &&
+ sd->eventtimer[i] != INVALID_TIMER &&
(p = (char *)(get_timer(sd->eventtimer[i])->data)) != NULL &&
strcmp(p, name) == 0
);
@@ -7050,7 +7048,7 @@ int pc_deleventtimer(struct map_session_data *sd,const char *name)
return 0; // not found
delete_timer(sd->eventtimer[i],pc_eventtimer);
- sd->eventtimer[i]=-1;
+ sd->eventtimer[i] = INVALID_TIMER;
sd->eventcount--;
aFree(p);
@@ -7067,7 +7065,7 @@ int pc_addeventtimercount(struct map_session_data *sd,const char *name,int tick)
nullpo_ret(sd);
for(i=0;i<MAX_EVENTTIMER;i++)
- if( sd->eventtimer[i]!=-1 && strcmp(
+ if( sd->eventtimer[i] != INVALID_TIMER && strcmp(
(char *)(get_timer(sd->eventtimer[i])->data), name)==0 ){
addtick_timer(sd->eventtimer[i],tick);
break;
@@ -7089,10 +7087,10 @@ int pc_cleareventtimer(struct map_session_data *sd)
return 0;
for(i=0;i<MAX_EVENTTIMER;i++)
- if( sd->eventtimer[i]!=-1 ){
+ if( sd->eventtimer[i] != INVALID_TIMER ){
char *p = (char *)(get_timer(sd->eventtimer[i])->data);
delete_timer(sd->eventtimer[i],pc_eventtimer);
- sd->eventtimer[i]=-1;
+ sd->eventtimer[i] = INVALID_TIMER;
sd->eventcount--;
if (p) aFree(p);
}
@@ -7299,8 +7297,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag)
sd->status.weapon = sd->weapontype2;
pc_calcweapontype(sd);
clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
- if(sd->sc.data[SC_DANCING]) //When unequipping, stop dancing. [Skotlex]
- status_change_end(&sd->bl, SC_DANCING, -1);
+ status_change_end(&sd->bl, SC_DANCING, INVALID_TIMER); //When unequipping, stop dancing. [Skotlex]
}
if(sd->status.inventory[n].equip & EQP_HAND_L) {
sd->status.shield = sd->weapontype2 = 0;
@@ -7330,10 +7327,8 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag)
if(sd->status.inventory[n].equip & EQP_ARMOR) {
// On Armor Change...
- if( sd->sc.data[SC_BENEDICTIO] )
- status_change_end(&sd->bl, SC_BENEDICTIO, -1);
- if( sd->sc.data[SC_ARMOR_RESIST] )
- status_change_end(&sd->bl, SC_ARMOR_RESIST, -1);
+ status_change_end(&sd->bl, SC_BENEDICTIO, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_ARMOR_RESIST, INVALID_TIMER);
}
if( sd->state.autobonus&sd->status.inventory[n].equip )
@@ -7347,7 +7342,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag)
}
if(sd->sc.data[SC_SIGNUMCRUCIS] && !battle_check_undead(sd->battle_status.race,sd->battle_status.def_ele))
- status_change_end(&sd->bl,SC_SIGNUMCRUCIS,-1);
+ status_change_end(&sd->bl, SC_SIGNUMCRUCIS, INVALID_TIMER);
//OnUnEquip script [Skotlex]
if (sd->inventory_data[n]) {
@@ -7793,8 +7788,7 @@ int map_night_timer(int tid, unsigned int tick, int id, intptr data)
void pc_setstand(struct map_session_data *sd){
nullpo_retv(sd);
- if(sd->sc.data[SC_TENSIONRELAX])
- status_change_end(&sd->bl,SC_TENSIONRELAX,-1);
+ status_change_end(&sd->bl, SC_TENSIONRELAX, INVALID_TIMER);
//Reset sitting tick.
sd->ssregen.tick.hp = sd->ssregen.tick.sp = 0;
diff --git a/src/map/pc.h b/src/map/pc.h
index 2921b4527..c48defbf5 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -350,6 +350,7 @@ struct map_session_data {
int guildspy; // [Syrus22]
int partyspy; // [Syrus22]
+ int vended_id;
int vender_id;
int vend_num;
char message[MESSAGE_SIZE];
@@ -383,8 +384,6 @@ struct map_session_data {
int killerrid, killedrid;
- char away_message[128]; // [LuzZza]
-
int cashPoints, kafraPoints;
int rental_timer;
diff --git a/src/map/pet.c b/src/map/pet.c
index 843f1cc11..6b16fe888 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -180,7 +180,7 @@ int pet_sc_check(struct map_session_data *sd, int type)
if( pd == NULL
|| (battle_config.pet_equip_required && pd->pet.equip == 0)
|| pd->recovery == NULL
- || pd->recovery->timer != -1
+ || pd->recovery->timer != INVALID_TIMER
|| pd->recovery->type != type )
return 1;
@@ -263,7 +263,7 @@ int search_petDB_index(int key,int type)
int pet_hungry_timer_delete(struct pet_data *pd)
{
nullpo_ret(pd);
- if(pd->pet_hungry_timer != -1) {
+ if(pd->pet_hungry_timer != INVALID_TIMER) {
delete_timer(pd->pet_hungry_timer,pet_hungry);
pd->pet_hungry_timer = INVALID_TIMER;
}
@@ -666,14 +666,14 @@ int pet_equipitem(struct map_session_data *sd,int index)
if (battle_config.pet_equip_required)
{ //Skotlex: start support timers if need
unsigned int tick = gettick();
- if (pd->s_skill && pd->s_skill->timer == -1)
+ if (pd->s_skill && pd->s_skill->timer == INVALID_TIMER)
{
if (pd->s_skill->id)
pd->s_skill->timer=add_timer(tick+pd->s_skill->delay*1000, pet_skill_support_timer, sd->bl.id, 0);
else
pd->s_skill->timer=add_timer(tick+pd->s_skill->delay*1000, pet_heal_timer, sd->bl.id, 0);
}
- if (pd->bonus && pd->bonus->timer == -1)
+ if (pd->bonus && pd->bonus->timer == INVALID_TIMER)
pd->bonus->timer=add_timer(tick+pd->bonus->delay*1000, pet_skill_bonus_timer, sd->bl.id, 0);
}
@@ -706,7 +706,7 @@ static int pet_unequipitem(struct map_session_data *sd, struct pet_data *pd)
pd->state.skillbonus = 0;
status_calc_pc(sd,0);
}
- if( pd->s_skill && pd->s_skill->timer != -1 )
+ if( pd->s_skill && pd->s_skill->timer != INVALID_TIMER )
{
if( pd->s_skill->id )
delete_timer(pd->s_skill->timer, pet_skill_support_timer);
@@ -714,7 +714,7 @@ static int pet_unequipitem(struct map_session_data *sd, struct pet_data *pd)
delete_timer(pd->s_skill->timer, pet_heal_timer);
pd->s_skill->timer = INVALID_TIMER;
}
- if( pd->bonus && pd->bonus->timer != -1 )
+ if( pd->bonus && pd->bonus->timer != INVALID_TIMER )
{
delete_timer(pd->bonus->timer, pet_skill_bonus_timer);
pd->bonus->timer = INVALID_TIMER;
@@ -825,10 +825,10 @@ static int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, uns
return 0;
pd->last_thinktime=tick;
- if(pd->ud.attacktimer != -1 || pd->ud.skilltimer != -1 || pd->bl.m != sd->bl.m)
+ if(pd->ud.attacktimer != INVALID_TIMER || pd->ud.skilltimer != INVALID_TIMER || pd->bl.m != sd->bl.m)
return 0;
- if(pd->ud.walktimer != -1 && pd->ud.walkpath.path_pos <= 2)
+ if(pd->ud.walktimer != INVALID_TIMER && pd->ud.walkpath.path_pos <= 2)
return 0; //No thinking when you just started to walk.
if(pd->pet.intimate <= 0) {
@@ -841,7 +841,7 @@ static int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, uns
//Master too far, chase.
if(pd->target_id)
pet_unlocktarget(pd);
- if(pd->ud.walktimer != -1 && pd->ud.target == sd->bl.id)
+ if(pd->ud.walktimer != INVALID_TIMER && pd->ud.target == sd->bl.id)
return 0; //Already walking to him
if (DIFF_TICK(tick, pd->ud.canmove_tick) < 0)
return 0; //Can't move yet.
@@ -855,7 +855,7 @@ static int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, uns
//Return speed to normal.
if (pd->status.speed != pd->petDB->speed) {
- if (pd->ud.walktimer != -1)
+ if (pd->ud.walktimer != INVALID_TIMER)
return 0; //Wait until the pet finishes walking back to master.
pd->status.speed = pd->petDB->speed;
}
@@ -881,7 +881,7 @@ static int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, uns
if (check_distance_bl(&sd->bl, &pd->bl, 3))
return 0; //Already next to master.
- if(pd->ud.walktimer != -1 && check_distance_blxy(&sd->bl, pd->ud.to_x,pd->ud.to_y, 3))
+ if(pd->ud.walktimer != INVALID_TIMER && check_distance_blxy(&sd->bl, pd->ud.to_x,pd->ud.to_y, 3))
return 0; //Already walking to him
unit_calc_pos(&pd->bl, sd->bl.x, sd->bl.y, sd->ud.dir);
@@ -892,7 +892,7 @@ static int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, uns
}
if(pd->ud.target == target->id &&
- (pd->ud.attacktimer != -1 || pd->ud.walktimer != -1))
+ (pd->ud.attacktimer != INVALID_TIMER || pd->ud.walktimer != INVALID_TIMER))
return 0; //Target already locked.
if (target->type != BL_ITEM)
@@ -915,7 +915,7 @@ static int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, uns
struct flooritem_data *fitem = (struct flooritem_data *)target;
if(pd->loot->count < pd->loot->max){
memcpy(&pd->loot->item[pd->loot->count++],&fitem->item_data,sizeof(pd->loot->item[0]));
- pd->loot->weight += itemdb_search(fitem->item_data.nameid)->weight*fitem->item_data.amount;
+ pd->loot->weight += itemdb_weight(fitem->item_data.nameid)*fitem->item_data.amount;
map_clearflooritem(target->id);
}
//Target is unlocked regardless of whether it was picked or not.
@@ -1099,7 +1099,7 @@ int pet_recovery_timer(int tid, unsigned int tick, int id, intptr data)
{ //Display a heal animation?
//Detoxify is chosen for now.
clif_skill_nodamage(&pd->bl,&sd->bl,TF_DETOXIFY,1,1);
- status_change_end(&sd->bl,pd->recovery->type,-1);
+ status_change_end(&sd->bl, pd->recovery->type, INVALID_TIMER);
clif_emotion(&pd->bl, E_OK);
}
@@ -1130,7 +1130,7 @@ int pet_heal_timer(int tid, unsigned int tick, int id, intptr data)
if(pc_isdead(sd) ||
(rate = get_percentage(status->sp, status->max_sp)) > pd->s_skill->sp ||
(rate = get_percentage(status->hp, status->max_hp)) > pd->s_skill->hp ||
- (rate = (pd->ud.skilltimer != -1)) //Another skill is in effect
+ (rate = (pd->ud.skilltimer != INVALID_TIMER)) //Another skill is in effect
) { //Wait (how long? 1 sec for every 10% of remaining)
pd->s_skill->timer=add_timer(gettick()+(rate>10?rate:10)*100,pet_heal_timer,sd->bl.id,0);
return 0;
@@ -1173,7 +1173,7 @@ int pet_skill_support_timer(int tid, unsigned int tick, int id, intptr data)
if(pc_isdead(sd) ||
(rate = get_percentage(status->sp, status->max_sp)) > pd->s_skill->sp ||
(rate = get_percentage(status->hp, status->max_hp)) > pd->s_skill->hp ||
- (rate = (pd->ud.skilltimer != -1)) //Another skill is in effect
+ (rate = (pd->ud.skilltimer != INVALID_TIMER)) //Another skill is in effect
) { //Wait (how long? 1 sec for every 10% of remaining)
pd->s_skill->timer=add_timer(tick+(rate>10?rate:10)*100,pet_skill_support_timer,sd->bl.id,0);
return 0;
diff --git a/src/map/script.c b/src/map/script.c
index 59a9b5448..f842b614a 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -70,6 +70,7 @@
// - remove dynamic allocation in add_word()
// - remove GETVALUE / SETVALUE
// - clean up the set_reg / set_val / setd_sub mess
+// - detect invalid label references at parse-time
//
// struct script_state* st;
@@ -977,6 +978,23 @@ const char* parse_callfunc(const char* p, int require_paren)
return p;
}
+/// Processes end of logical script line.
+/// @param first When true, only fix up scheduling data is initialized
+/// @param p Script position for error reporting in set_label
+static void parse_nextline(bool first, const char* p)
+{
+ if( !first )
+ {
+ add_scriptc(C_EOL); // mark end of line for stack cleanup
+ set_label(LABEL_NEXTLINE, script_pos, p); // fix up '-' labels
+ }
+
+ // initialize data for new '-' label fix up scheduling
+ str_data[LABEL_NEXTLINE].type = C_NOP;
+ str_data[LABEL_NEXTLINE].backpatch = -1;
+ str_data[LABEL_NEXTLINE].label = -1;
+}
+
/*==========================================
* €‚̉ðÍ
*------------------------------------------*/
@@ -1541,12 +1559,17 @@ const char* parse_syntax(const char* p)
// function declaration - just register the name
int l;
l = add_word(func_name);
- if( str_data[l].type == C_NOP )// set type only if the name did not exist before
+ if( str_data[l].type == C_NOP )// register only, if the name was not used by something else
str_data[l].type = C_USERFUNC;
+ else if( str_data[l].type == C_USERFUNC )
+ ; // already registered
+ else
+ disp_error_message("parse_syntax:function: function name is invalid", func_name);
// if, for , while ‚̕‚¶”»’è
p = parse_syntax_close(p2 + 1);
- return p; }
+ return p;
+ }
else if(*p2 == '{')
{// function <name> <line/block of code>
char label[256];
@@ -1567,11 +1590,16 @@ const char* parse_syntax(const char* p)
// Set the position of the function (label)
l=add_word(func_name);
- if( str_data[l].type == C_NOP )// set type only if the name did not exist before
+ if( str_data[l].type == C_NOP || str_data[l].type == C_USERFUNC )// register only, if the name was not used by something else
+ {
str_data[l].type = C_USERFUNC;
- set_label(l, script_pos, p);
- if( parse_options&SCRIPT_USE_LABEL_DB )
- strdb_put(scriptlabel_db, get_str(l), (void*)script_pos);
+ set_label(l, script_pos, p);
+ if( parse_options&SCRIPT_USE_LABEL_DB )
+ strdb_put(scriptlabel_db, get_str(l), (void*)script_pos);
+ }
+ else
+ disp_error_message("parse_syntax:function: function name is invalid", func_name);
+
return skip_space(p);
}
else
@@ -1691,6 +1719,10 @@ const char* parse_syntax_close_sub(const char* p,int* flag)
} else if(syntax.curly[pos].type == TYPE_IF) {
const char *bp = p;
const char *p2;
+
+ // if-block and else-block end is a new line
+ parse_nextline(false, p);
+
// if ÅIꊂ֔ò‚΂·
sprintf(label,"goto __IF%x_FIN;",syntax.curly[pos].index);
syntax.curly[syntax.curly_count++].type = TYPE_NULL;
@@ -1766,6 +1798,10 @@ const char* parse_syntax_close_sub(const char* p,int* flag)
if(*p != '(') {
disp_error_message("need '('",p);
}
+
+ // do-block end is a new line
+ parse_nextline(false, p);
+
sprintf(label,"__DO%x_FIN",syntax.curly[pos].index);
add_scriptl(add_str("jump_zero"));
add_scriptc(C_ARG);
@@ -1793,6 +1829,9 @@ const char* parse_syntax_close_sub(const char* p,int* flag)
syntax.curly_count--;
return p;
} else if(syntax.curly[pos].type == TYPE_FOR) {
+ // for-block end is a new line
+ parse_nextline(false, p);
+
// ŽŸ‚̃‹[ƒv‚É”ò‚΂·
sprintf(label,"goto __FR%x_NXT;",syntax.curly[pos].index);
syntax.curly[syntax.curly_count++].type = TYPE_NULL;
@@ -1806,6 +1845,9 @@ const char* parse_syntax_close_sub(const char* p,int* flag)
syntax.curly_count--;
return p;
} else if(syntax.curly[pos].type == TYPE_WHILE) {
+ // while-block end is a new line
+ parse_nextline(false, p);
+
// while ðŒ”»’f‚Ö”ò‚΂·
sprintf(label,"goto __WL%x_NXT;",syntax.curly[pos].index);
syntax.curly[syntax.curly_count++].type = TYPE_NULL;
@@ -1974,6 +2016,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
struct script_code* code = NULL;
static int first=1;
char end;
+ bool unresolved_names = false;
if( src == NULL )
return NULL;// empty script
@@ -1988,9 +2031,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
script_buf=(unsigned char *)aMalloc(SCRIPT_BLOCK_SIZE*sizeof(unsigned char));
script_pos=0;
script_size=SCRIPT_BLOCK_SIZE;
- str_data[LABEL_NEXTLINE].type=C_NOP;
- str_data[LABEL_NEXTLINE].backpatch=-1;
- str_data[LABEL_NEXTLINE].label=-1;
+ parse_nextline(true, NULL);
// who called parse_script is responsible for clearing the database after using it, but just in case... lets clear it here
if( options&SCRIPT_USE_LABEL_DB )
@@ -2077,12 +2118,8 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
// ‘¼‚Í‘S•”ˆê‚­‚½
p=parse_line(p);
p=skip_space(p);
- add_scriptc(C_EOL);
- set_label(LABEL_NEXTLINE,script_pos,p);
- str_data[LABEL_NEXTLINE].type=C_NOP;
- str_data[LABEL_NEXTLINE].backpatch=-1;
- str_data[LABEL_NEXTLINE].label=-1;
+ parse_nextline(false, p);
}
add_scriptc(C_NOP);
@@ -2103,13 +2140,23 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
j=next;
}
}
+ else if( str_data[i].type == C_USERFUNC )
+ {// 'function name;' without follow-up code
+ ShowError("parse_script: function '%s' declared but not defined.\n", str_buf+str_data[i].str);
+ unresolved_names = true;
+ }
+ }
+
+ if( unresolved_names )
+ {
+ disp_error_message("parse_script: unresolved function references", p);
}
#ifdef DEBUG_DISP
for(i=0;i<script_pos;i++){
- if((i&15)==0) printf("%04x : ",i);
+ if((i&15)==0) ShowMessage("%04x : ",i);
ShowMessage("%02x ",script_buf[i]);
- if((i&15)==15) printf("\n");
+ if((i&15)==15) ShowMessage("\n");
}
ShowMessage("\n");
#endif
@@ -3235,7 +3282,7 @@ int run_script_timer(int tid, unsigned int tick, int id, intptr data)
st->rid = 0;
st->state = END;
}
- while( node && st->sleep.timer != -1 ) {
+ while( node && st->sleep.timer != INVALID_TIMER ) {
if( (int)node->key == st->oid && ((struct script_state *)node->data)->sleep.timer == st->sleep.timer ) {
script_erase_sleepdb(node);
st->sleep.timer = INVALID_TIMER;
@@ -4882,8 +4929,8 @@ BUILDIN_FUNC(setarray)
}
end = start + script_lastdata(st) - 2;
- if( end >= SCRIPT_MAX_ARRAYSIZE )
- end = SCRIPT_MAX_ARRAYSIZE-1;
+ if( end > SCRIPT_MAX_ARRAYSIZE )
+ end = SCRIPT_MAX_ARRAYSIZE;
if( is_string_variable(name) )
{// string array
@@ -4945,10 +4992,10 @@ BUILDIN_FUNC(cleararray)
v = (void*)script_getnum(st, 3);
end = start + script_getnum(st, 4);
- if( end >= SCRIPT_MAX_ARRAYSIZE )
- end = SCRIPT_MAX_ARRAYSIZE-1;
+ if( end > SCRIPT_MAX_ARRAYSIZE )
+ end = SCRIPT_MAX_ARRAYSIZE;
- for( ; start <= end; ++start )
+ for( ; start < end; ++start )
set_reg(st, sd, reference_uid(id, start), name, v, script_getref(st,2));
return 0;
}
@@ -5015,8 +5062,8 @@ BUILDIN_FUNC(copyarray)
}
count = script_getnum(st, 4);
- if( count >= SCRIPT_MAX_ARRAYSIZE - idx1 )
- count = (SCRIPT_MAX_ARRAYSIZE-1) - idx1;
+ if( count > SCRIPT_MAX_ARRAYSIZE - idx1 )
+ count = SCRIPT_MAX_ARRAYSIZE - idx1;
if( count <= 0 || (id1 == id2 && idx1 == idx2) )
return 0;// nothing to copy
@@ -5121,7 +5168,8 @@ BUILDIN_FUNC(deletearray)
return 0;// no player attached
}
- end = getarraysize(st, id, start, is_string_variable(name), reference_getref(data));
+ end = SCRIPT_MAX_ARRAYSIZE;
+
if( start >= end )
return 0;// nothing to free
@@ -6191,7 +6239,7 @@ BUILDIN_FUNC(readparam)
if( script_hasdata(st,3) )
sd=map_nick2sd(script_getstr(st,3));
else
- sd=script_rid2sd(st);
+ sd=script_rid2sd(st);
if(sd==NULL){
script_pushint(st,-1);
@@ -8321,10 +8369,10 @@ BUILDIN_FUNC(getnpctimer)
ShowError("buildin_getnpctimer: Attached player not found!\n");
break;
}
- val = (sd->npc_timer_id != -1);
+ val = (sd->npc_timer_id != INVALID_TIMER);
}
else
- val = (nd->u.scr.timerid !=-1);
+ val = (nd->u.scr.timerid != INVALID_TIMER);
break;
case 2: val = nd->u.scr.timeramount; break;
}
@@ -9705,7 +9753,7 @@ BUILDIN_FUNC(pvpon)
iter = mapit_getallusers();
for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
{
- if( sd->bl.m != m || sd->pvp_timer != -1 )
+ if( sd->bl.m != m || sd->pvp_timer != INVALID_TIMER )
continue; // not applicable
sd->pvp_timer = add_timer(gettick()+200,pc_calc_pvprank_timer,sd->bl.id,0);
@@ -9724,7 +9772,7 @@ static int buildin_pvpoff_sub(struct block_list *bl,va_list ap)
{
TBL_PC* sd = (TBL_PC*)bl;
clif_pvpset(sd, 0, 0, 2);
- if (sd->pvp_timer != -1) {
+ if (sd->pvp_timer != INVALID_TIMER) {
delete_timer(sd->pvp_timer, pc_calc_pvprank_timer);
sd->pvp_timer = INVALID_TIMER;
}
@@ -10809,7 +10857,7 @@ BUILDIN_FUNC(petskillbonus)
pd=sd->pd;
if (pd->bonus)
{ //Clear previous bonus
- if (pd->bonus->timer != -1)
+ if (pd->bonus->timer != INVALID_TIMER)
delete_timer(pd->bonus->timer, pet_skill_bonus_timer);
} else //init
pd->bonus = (struct pet_bonus *) aMalloc(sizeof(struct pet_bonus));
@@ -11162,7 +11210,7 @@ BUILDIN_FUNC(petrecovery)
if (pd->recovery)
{ //Halt previous bonus
- if (pd->recovery->timer != -1)
+ if (pd->recovery->timer != INVALID_TIMER)
delete_timer(pd->recovery->timer, pet_recovery_timer);
} else //Init
pd->recovery = (struct pet_recovery *)aMalloc(sizeof(struct pet_recovery));
@@ -11188,7 +11236,7 @@ BUILDIN_FUNC(petheal)
pd=sd->pd;
if (pd->s_skill)
{ //Clear previous skill
- if (pd->s_skill->timer != -1)
+ if (pd->s_skill->timer != INVALID_TIMER)
{
if (pd->s_skill->id)
delete_timer(pd->s_skill->timer, pet_skill_support_timer);
@@ -11282,7 +11330,7 @@ BUILDIN_FUNC(petskillsupport)
pd=sd->pd;
if (pd->s_skill)
{ //Clear previous skill
- if (pd->s_skill->timer != -1)
+ if (pd->s_skill->timer != INVALID_TIMER)
{
if (pd->s_skill->id)
delete_timer(pd->s_skill->timer, pet_skill_support_timer);
@@ -11636,9 +11684,6 @@ BUILDIN_FUNC(jump_zero)
pos=script_getnum(st,3);
st->pos=pos;
st->state=GOTO;
- // printf("script: jump_zero: jumpto : %d\n",pos);
- } else {
- // printf("script: jump_zero: fail\n");
}
return 0;
}
@@ -12312,7 +12357,7 @@ BUILDIN_FUNC(autoequip)
struct item_data *item_data;
nameid=script_getnum(st,2);
flag=script_getnum(st,3);
- if(nameid>=500 && (item_data = itemdb_search(nameid)) != NULL){
+ if(nameid>=500 && (item_data = itemdb_exists(nameid)) != NULL){
item_data->flag.autoequip = flag>0?1:0;
}
return 0;
@@ -12362,7 +12407,7 @@ BUILDIN_FUNC(charisalpha)
const char *str=script_getstr(st,2);
int pos=script_getnum(st,3);
- int val = ( str && pos >= 0 && (unsigned int)pos < strlen(str) ) ? ISALPHA( str[pos] ) : 0;
+ int val = ( str && pos >= 0 && (unsigned int)pos < strlen(str) ) ? ISALPHA( str[pos] ) != 0 : 0;
script_pushint(st,val);
return 0;
@@ -13557,7 +13602,7 @@ BUILDIN_FUNC(awake)
struct script_state* tst = (struct script_state*)node->data;
TBL_PC* sd = map_id2sd(tst->rid);
- if( tst->sleep.timer == -1 )
+ if( tst->sleep.timer == INVALID_TIMER )
{// already awake ???
node = node->next;
continue;
@@ -14590,7 +14635,7 @@ static int buildin_mobuseskill_sub(struct block_list *bl,va_list ap)
if( md->class_ != mobid )
return 0;
- if( md->ud.skilltimer != -1 ) // Cancel the casting skill.
+ if( md->ud.skilltimer != INVALID_TIMER ) // Cancel the casting skill.
unit_skillcastcancel(bl,0);
// 0:self, 1:target, 2:master, default:random
diff --git a/src/map/skill.c b/src/map/skill.c
index 6b63c2b83..cd9115df4 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -611,7 +611,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
rate = 20;
if (sc->data[SC_SKILLRATE_UP] && sc->data[SC_SKILLRATE_UP]->val1 == TK_COUNTER) {
rate += rate*sc->data[SC_SKILLRATE_UP]->val2/100;
- status_change_end(src,SC_SKILLRATE_UP,-1);
+ status_change_end(src, SC_SKILLRATE_UP, INVALID_TIMER);
}
sc_start4(src,SC_COMBO, rate, TK_COUNTER, bl->id,0,0,
(2000 - 4*sstatus->agi - 2*sstatus->dex));
@@ -883,12 +883,12 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
case TK_JUMPKICK:
if( dstsd && dstsd->class_ != MAPID_SOUL_LINKER && !tsc->data[SC_PRESERVE] )
{// debuff the following statuses
- status_change_end(bl, SC_SPIRIT, -1);
- status_change_end(bl, SC_ADRENALINE2, -1);
- status_change_end(bl, SC_KAITE, -1);
- status_change_end(bl, SC_KAAHI, -1);
- status_change_end(bl, SC_ONEHAND, -1);
- status_change_end(bl, SC_ASPDPOTION2, -1);
+ status_change_end(bl, SC_SPIRIT, INVALID_TIMER);
+ status_change_end(bl, SC_ADRENALINE2, INVALID_TIMER);
+ status_change_end(bl, SC_KAITE, INVALID_TIMER);
+ status_change_end(bl, SC_KAAHI, INVALID_TIMER);
+ status_change_end(bl, SC_ONEHAND, INVALID_TIMER);
+ status_change_end(bl, SC_ASPDPOTION2, INVALID_TIMER);
}
break;
case TK_TURNKICK:
@@ -1544,7 +1544,7 @@ static int skill_magic_reflect(struct block_list* src, struct block_list* bl, in
{// Kaite only works against non-players if they are low-level.
clif_specialeffect(bl, 438, AREA);
if( --sc->data[SC_KAITE]->val2 <= 0 )
- status_change_end(bl, SC_KAITE, -1);
+ status_change_end(bl, SC_KAITE, INVALID_TIMER);
return 2;
}
@@ -1719,7 +1719,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
break;
default:
if( src == dsrc ) // Ground skills are exceptions. [Inkfish]
- status_change_end(src,SC_COMBO,-1);
+ status_change_end(src, SC_COMBO, INVALID_TIMER);
}
}
switch(skillid)
@@ -1904,7 +1904,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
status_fix_damage(NULL, d_bl, damage, 0);
}
else
- status_change_end(bl, SC_DEVOTION, -1);
+ status_change_end(bl, SC_DEVOTION, INVALID_TIMER);
}
if(skillid == RG_INTIMIDATE && damage > 0 && !(tstatus->mode&MD_BOSS)) {
@@ -2338,8 +2338,7 @@ static int skill_timerskill(int tid, unsigned int tick, int id, intptr data)
} else {
struct status_change *sc = status_get_sc(src);
if(sc) {
- if(sc->data[SC_MAGICPOWER])
- status_change_end(src,SC_MAGICPOWER,-1);
+ status_change_end(src, SC_MAGICPOWER, INVALID_TIMER);
if(sc->data[SC_SPIRIT] &&
sc->data[SC_SPIRIT]->val2 == SL_WIZARD &&
sc->data[SC_SPIRIT]->val3 == skl->skill_id)
@@ -2469,7 +2468,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
{ //GTB makes all targetted magic display miss with a single bolt.
sc_type sct = status_skill2sc(skillid);
if(sct != SC_NONE)
- status_change_end(bl, sct, -1);
+ status_change_end(bl, sct, INVALID_TIMER);
clif_skill_damage(src, bl, tick, status_get_amotion(src), status_get_dmotion(bl), 0, 1, skillid, skilllv, skill_get_hit(skillid));
return 1;
}
@@ -2662,16 +2661,14 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
case MO_INVESTIGATE:
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- if (sc && sc->data[SC_BLADESTOP])
- status_change_end(src,SC_BLADESTOP,-1);
+ status_change_end(src, SC_BLADESTOP, INVALID_TIMER);
break;
case RG_BACKSTAP:
{
int dir = map_calc_dir(src, bl->x, bl->y), t_dir = unit_getdir(bl);
if ((!check_distance_bl(src, bl, 0) && !map_check_dir(dir, t_dir)) || bl->type == BL_SKILL) {
- if (sc && sc->data[SC_HIDING])
- status_change_end(src, SC_HIDING, -1);
+ status_change_end(src, SC_HIDING, INVALID_TIMER);
skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag);
dir = dir < 4 ? dir+4 : dir-4; // change direction [Celest]
unit_setdir(bl,dir);
@@ -2688,25 +2685,23 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
for (i = 1; i < sd->spiritball_old; i++)
skill_addtimerskill(src, tick + i * 200, bl->id, 0, 0, skillid, skilllv, BF_WEAPON, flag);
}
- if (sc && sc->data[SC_BLADESTOP])
- status_change_end(src,SC_BLADESTOP,-1);
+ status_change_end(src, SC_BLADESTOP, INVALID_TIMER);
break;
case MO_CHAINCOMBO:
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- if (sc && sc->data[SC_BLADESTOP])
- status_change_end(src,SC_BLADESTOP,-1);
+ status_change_end(src, SC_BLADESTOP, INVALID_TIMER);
break;
case NJ_ISSEN:
- status_change_end(src,SC_NEN,-1);
- status_change_end(src,SC_HIDING,-1);
+ status_change_end(src, SC_NEN, INVALID_TIMER);
+ status_change_end(src, SC_HIDING, INVALID_TIMER);
// fall through
case MO_EXTREMITYFIST:
if( skillid == MO_EXTREMITYFIST )
{
- status_change_end(src,SC_EXPLOSIONSPIRITS,-1);
- status_change_end(src,SC_BLADESTOP,-1);
+ status_change_end(src, SC_EXPLOSIONSPIRITS, INVALID_TIMER);
+ status_change_end(src, SC_BLADESTOP, INVALID_TIMER);
}
//Client expects you to move to target regardless of distance
{
@@ -2991,8 +2986,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
break;
case SL_SMA:
- if (sc && sc->data[SC_SMA])
- status_change_end(src,SC_SMA,-1);
+ status_change_end(src, SC_SMA, INVALID_TIMER);
case SL_STIN:
case SL_STUN:
if (sd && !battle_config.allow_es_magic_pc && bl->type != BL_MOB) {
@@ -3065,8 +3059,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
if (unit_movepos(src, x, y, 0, 0))
clif_slide(src,src->x,src->y);
}
- if (sc && sc->data[SC_HIDING])
- status_change_end(src, SC_HIDING, -1);
+ status_change_end(src, SC_HIDING, INVALID_TIMER);
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
break;
case 0:
@@ -3208,7 +3201,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
if( tsc->data[SC_KAITE] && !(sstatus->mode&MD_BOSS) )
{ //Bounce back heal
if (--tsc->data[SC_KAITE]->val2 <= 0)
- status_change_end(bl, SC_KAITE, -1);
+ status_change_end(bl, SC_KAITE, INVALID_TIMER);
if (src == bl)
heal=0; //When you try to heal yourself under Kaite, the heal is voided.
else {
@@ -3327,7 +3320,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case PR_LEXDIVINA:
case MER_LEXDIVINA:
if( tsce )
- status_change_end(bl,type, -1);
+ status_change_end(bl,type, INVALID_TIMER);
else
sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
clif_skill_nodamage (src, bl, skillid, skilllv, 1);
@@ -3441,9 +3434,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
{
const enum sc_type scs[] = { SC_QUAGMIRE, SC_PROVOKE, SC_ROKISWEIL, SC_GRAVITATION, SC_SUITON, SC_STRIPWEAPON, SC_STRIPSHIELD, SC_STRIPARMOR, SC_STRIPHELM, SC_BLADESTOP };
for (i = SC_COMMON_MIN; i <= SC_COMMON_MAX; i++)
- if (tsc->data[i]) status_change_end(bl, (sc_type)i, -1);
+ if (tsc->data[i]) status_change_end(bl, (sc_type)i, INVALID_TIMER);
for (i = 0; i < ARRAYLENGTH(scs); i++)
- if (tsc->data[scs[i]]) status_change_end(bl, scs[i], -1);
+ if (tsc->data[scs[i]]) status_change_end(bl, scs[i], INVALID_TIMER);
}
}
break;
@@ -3508,8 +3501,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
if( sc->data[SC_MARIONETTE ] && sc->data[SC_MARIONETTE ]->val1 == bl->id &&
tsc->data[SC_MARIONETTE2] && tsc->data[SC_MARIONETTE2]->val1 == src->id )
{
- status_change_end(src, SC_MARIONETTE, -1);
- status_change_end(bl, SC_MARIONETTE2, -1);
+ status_change_end(src, SC_MARIONETTE, INVALID_TIMER);
+ status_change_end(bl, SC_MARIONETTE2, INVALID_TIMER);
}
else
{
@@ -3698,8 +3691,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case NJ_BUNSINJYUTSU:
clif_skill_nodamage(src,bl,skillid,skilllv,
sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- if (tsc && tsc->data[SC_NEN])
- status_change_end(bl,SC_NEN,-1);
+ status_change_end(bl, SC_NEN, INVALID_TIMER);
break;
/* Was modified to only affect targetted char. [Skotlex]
case HP_ASSUMPTIO:
@@ -3804,12 +3796,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
if( tsc && tsc->count )
{
- if( tsc->data[SC_FREEZE] )
- status_change_end(bl,SC_FREEZE,-1);
+ status_change_end(bl, SC_FREEZE, INVALID_TIMER);
if( tsc->data[SC_STONE] && tsc->opt1 == OPT1_STONE )
- status_change_end(bl,SC_STONE,-1);
- if( tsc->data[SC_SLEEP] )
- status_change_end(bl,SC_SLEEP,-1);
+ status_change_end(bl, SC_STONE, INVALID_TIMER);
+ status_change_end(bl, SC_SLEEP, INVALID_TIMER);
}
if( dstmd )
@@ -3947,7 +3937,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
skill_get_splash(skillid, skilllv), splash_target(src),
src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
skill_castend_damage_id);
- status_change_end(src, SC_HIDING, -1);
+ status_change_end(src, SC_HIDING, INVALID_TIMER);
break;
case ASC_METEORASSAULT:
@@ -4016,7 +4006,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case WZ_SIGHTRASHER:
//Passive side of the attack.
- status_change_end(src,SC_SIGHT,-1);
+ status_change_end(src, SC_SIGHT, INVALID_TIMER);
clif_skill_nodamage(src,bl,skillid,skilllv,1);
map_foreachinrange(skill_area_sub,src,
skill_get_splash(skillid, skilllv),BL_CHAR|BL_SKILL,
@@ -4104,7 +4094,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case GS_GATLINGFEVER:
if( tsce )
{
- clif_skill_nodamage(src,bl,skillid,skilllv,status_change_end(bl, type, -1));
+ clif_skill_nodamage(src,bl,skillid,skilllv,status_change_end(bl, type, INVALID_TIMER));
map_freeblock_unlock();
return 0;
}
@@ -4133,7 +4123,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case SM_AUTOBERSERK:
case MER_AUTOBERSERK:
if( tsce )
- i = status_change_end(bl, type, -1);
+ i = status_change_end(bl, type, INVALID_TIMER);
else
i = sc_start(bl,type,100,skilllv,60000);
clif_skill_nodamage(src,bl,skillid,skilllv,i);
@@ -4142,7 +4132,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case ST_CHASEWALK:
if (tsce)
{
- clif_skill_nodamage(src,bl,skillid,-1,status_change_end(bl, type, -1)); //Hide skill-scream animation.
+ clif_skill_nodamage(src,bl,skillid,-1,status_change_end(bl, type, INVALID_TIMER)); //Hide skill-scream animation.
map_freeblock_unlock();
return 0;
}
@@ -4151,7 +4141,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case TK_RUN:
if (tsce)
{
- clif_skill_nodamage(src,bl,skillid,skilllv,status_change_end(bl, type, -1));
+ clif_skill_nodamage(src,bl,skillid,skilllv,status_change_end(bl, type, INVALID_TIMER));
map_freeblock_unlock();
return 0;
}
@@ -4162,7 +4152,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case AS_CLOAKING:
if (tsce)
{
- i = status_change_end(bl, type, -1);
+ i = status_change_end(bl, type, INVALID_TIMER);
if( i )
clif_skill_nodamage(src,bl,skillid,-1,i);
else if( sd )
@@ -4180,7 +4170,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case BD_ADAPTATION:
if(tsc && tsc->data[SC_DANCING]){
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- status_change_end(bl, SC_DANCING, -1);
+ status_change_end(bl, SC_DANCING, INVALID_TIMER);
}
break;
@@ -4253,7 +4243,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
break;
if (tsc->data[SC_STONE]) {
- status_change_end(bl,SC_STONE,-1);
+ status_change_end(bl, SC_STONE, INVALID_TIMER);
if (sd) clif_skill_fail(sd,skillid,0,0);
break;
}
@@ -4283,16 +4273,16 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
clif_skill_nodamage(src,bl,skillid,skilllv,0);
break;
}
- status_change_end(bl, SC_SILENCE , -1 );
- status_change_end(bl, SC_BLIND , -1 );
- status_change_end(bl, SC_CONFUSION, -1 );
+ status_change_end(bl, SC_SILENCE, INVALID_TIMER);
+ status_change_end(bl, SC_BLIND, INVALID_TIMER);
+ status_change_end(bl, SC_CONFUSION, INVALID_TIMER);
clif_skill_nodamage(src,bl,skillid,skilllv,1);
break;
case TF_DETOXIFY:
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- status_change_end(bl, SC_POISON , -1 );
- status_change_end(bl, SC_DPOISON , -1 );
+ status_change_end(bl, SC_POISON, INVALID_TIMER);
+ status_change_end(bl, SC_DPOISON, INVALID_TIMER);
break;
case PR_STRECOVERY:
@@ -4301,10 +4291,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
break;
}
if (tsc && tsc->opt1) {
- status_change_end(bl, SC_FREEZE, -1 );
- status_change_end(bl, SC_STONE, -1 );
- status_change_end(bl, SC_SLEEP, -1 );
- status_change_end(bl, SC_STUN, -1 );
+ status_change_end(bl, SC_FREEZE, INVALID_TIMER);
+ status_change_end(bl, SC_STONE, INVALID_TIMER);
+ status_change_end(bl, SC_SLEEP, INVALID_TIMER);
+ status_change_end(bl, SC_STUN, INVALID_TIMER);
}
//Is this equation really right? It looks so... special.
if(battle_check_undead(tstatus->race,tstatus->def_ele))
@@ -4321,31 +4311,31 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
// Mercenary Supportive Skills
case MER_BENEDICTION:
- status_change_end(bl, SC_CURSE, -1);
- status_change_end(bl, SC_BLIND, -1);
+ status_change_end(bl, SC_CURSE, INVALID_TIMER);
+ status_change_end(bl, SC_BLIND, INVALID_TIMER);
clif_skill_nodamage(src,bl,skillid,skilllv,1);
break;
case MER_COMPRESS:
- status_change_end(bl, SC_BLEEDING, -1);
+ status_change_end(bl, SC_BLEEDING, INVALID_TIMER);
clif_skill_nodamage(src,bl,skillid,skilllv,1);
break;
case MER_MENTALCURE:
- status_change_end(bl, SC_CONFUSION, -1);
+ status_change_end(bl, SC_CONFUSION, INVALID_TIMER);
clif_skill_nodamage(src,bl,skillid,skilllv,1);
break;
case MER_RECUPERATE:
- status_change_end(bl, SC_POISON, -1);
- status_change_end(bl, SC_SILENCE, -1);
+ status_change_end(bl, SC_POISON, INVALID_TIMER);
+ status_change_end(bl, SC_SILENCE, INVALID_TIMER);
clif_skill_nodamage(src,bl,skillid,skilllv,1);
break;
case MER_REGAIN:
- status_change_end(bl, SC_SLEEP, -1);
- status_change_end(bl, SC_STUN, -1);
+ status_change_end(bl, SC_SLEEP, INVALID_TIMER);
+ status_change_end(bl, SC_STUN, INVALID_TIMER);
clif_skill_nodamage(src,bl,skillid,skilllv,1);
break;
case MER_TENDER:
- status_change_end(bl, SC_FREEZE, -1);
- status_change_end(bl, SC_STONE, -1);
+ status_change_end(bl, SC_FREEZE, INVALID_TIMER);
+ status_change_end(bl, SC_STONE, INVALID_TIMER);
clif_skill_nodamage(src,bl,skillid,skilllv,1);
break;
@@ -4642,8 +4632,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case AM_CP_HELM:
{
enum sc_type scid = (sc_type)(SC_STRIPWEAPON + (skillid - AM_CP_WEAPON));
- if(tsc && tsc->data[scid])
- status_change_end(bl, scid, -1 );
+ status_change_end(bl, scid, INVALID_TIMER);
clif_skill_nodamage(src,bl,skillid,skilllv,
sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
}
@@ -4735,7 +4724,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
break;
}
if(i==SC_BERSERK) tsc->data[i]->val2=0; //Mark a dispelled berserk to avoid setting hp to 100 by setting hp penalty to 0.
- status_change_end(bl,(sc_type)i,-1);
+ status_change_end(bl, (sc_type)i, INVALID_TIMER);
}
break;
}
@@ -4796,7 +4785,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
} else {
struct unit_data *ud = unit_bl2ud(bl);
int bl_skillid=0,bl_skilllv=0,hp = 0;
- if (!ud || ud->skilltimer == -1) break; //Nothing to cancel.
+ if (!ud || ud->skilltimer == INVALID_TIMER)
+ break; //Nothing to cancel.
bl_skillid = ud->skillid;
bl_skilllv = ud->skilllv;
if (tstatus->mode & MD_BOSS)
@@ -5021,7 +5011,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
{
clif_emotion(bl, md->db->skill[md->skillidx].val[0]);
if(md->db->skill[md->skillidx].val[4] && tsce)
- status_change_end(bl, type, -1);
+ status_change_end(bl, type, INVALID_TIMER);
if(md->db->skill[md->skillidx].val[1] || md->db->skill[md->skillidx].val[2])
sc_start4(src, type, 100, skilllv,
@@ -5225,12 +5215,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
unit_skillcastcancel(bl,0);
if(tsc && tsc->count){
- if(tsc->data[SC_FREEZE])
- status_change_end(bl,SC_FREEZE,-1);
+ status_change_end(bl, SC_FREEZE, INVALID_TIMER);
if(tsc->data[SC_STONE] && tsc->opt1 == OPT1_STONE)
- status_change_end(bl,SC_STONE,-1);
- if(tsc->data[SC_SLEEP])
- status_change_end(bl,SC_SLEEP,-1);
+ status_change_end(bl, SC_STONE, INVALID_TIMER);
+ status_change_end(bl, SC_SLEEP, INVALID_TIMER);
}
if(dstmd)
@@ -5297,8 +5285,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
break;
}
for (i=0; i<4; i++) {
- if(tsc->data[SC_STRIPWEAPON + i])
- status_change_end(bl, (sc_type)(SC_STRIPWEAPON + i), -1 );
+ status_change_end(bl, (sc_type)(SC_STRIPWEAPON + i), INVALID_TIMER);
sc_start(bl,(sc_type)(SC_CP_WEAPON + i),100,skilllv,skilltime);
}
clif_skill_nodamage(src,bl,skillid,skilllv,1);
@@ -5771,7 +5758,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr data)
return 0;
}
- if( sd && ud->skilltimer != -1 && pc_checkskill(sd,SA_FREECAST) > 0 )
+ if( sd && ud->skilltimer != INVALID_TIMER && pc_checkskill(sd,SA_FREECAST) > 0 )
{// restore original walk speed
ud->skilltimer = INVALID_TIMER;
status_calc_bl(&sd->bl, SCB_SPEED);
@@ -5875,7 +5862,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr data)
}
//Avoid doing double checks for instant-cast skills.
- if (tid != -1 && !status_check_skilluse(src, target, ud->skillid, 1))
+ if (tid != INVALID_TIMER && !status_check_skilluse(src, target, ud->skillid, 1))
break;
if(md) {
@@ -5909,7 +5896,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr data)
if (ud->state.running && ud->skillid == TK_JUMPKICK)
flag = 1;
- if (ud->walktimer != -1 && ud->skillid != TK_RUN)
+ if (ud->walktimer != INVALID_TIMER && ud->skillid != TK_RUN)
unit_stop_walking(src,1);
if( !sd || sd->skillitem != ud->skillid || skill_get_delay(ud->skillid,ud->skilllv) )
@@ -5952,7 +5939,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr data)
if(sc && sc->count) {
if(sc->data[SC_MAGICPOWER] &&
ud->skillid != HW_MAGICPOWER && ud->skillid != WZ_WATERBALL)
- status_change_end(src,SC_MAGICPOWER,-1);
+ status_change_end(src, SC_MAGICPOWER, INVALID_TIMER);
if(sc->data[SC_SPIRIT] &&
sc->data[SC_SPIRIT]->val2 == SL_WIZARD &&
sc->data[SC_SPIRIT]->val3 == ud->skillid &&
@@ -5966,7 +5953,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr data)
if( sd && ud->skillid != SA_ABRACADABRA ) // Hocus-Pocus has just set the data so leave it as it is.[Inkfish]
sd->skillitem = sd->skillitemlv = 0;
- if (ud->skilltimer == -1) {
+ if (ud->skilltimer == INVALID_TIMER) {
if(md) md->skillidx = -1;
else ud->skillid = 0; //mobs can't clear this one as it is used for skill condition 'afterskill'
ud->skilllv = ud->skilltarget = 0;
@@ -5984,10 +5971,8 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr data)
sc = &sd->sc;
if (sc->count)
{ //End states
- if (sc->data[SC_EXPLOSIONSPIRITS])
- status_change_end(src, SC_EXPLOSIONSPIRITS, -1);
- if (sc->data[SC_BLADESTOP])
- status_change_end(src,SC_BLADESTOP,-1);
+ status_change_end(src, SC_EXPLOSIONSPIRITS, INVALID_TIMER);
+ status_change_end(src, SC_BLADESTOP, INVALID_TIMER);
}
if (target && target->m == src->m)
{ //Move character to target anyway.
@@ -6049,7 +6034,7 @@ int skill_castend_pos(int tid, unsigned int tick, int id, intptr data)
return 0;
}
- if( sd && ud->skilltimer != -1 && pc_checkskill(sd,SA_FREECAST) > 0 )
+ if( sd && ud->skilltimer != INVALID_TIMER && pc_checkskill(sd,SA_FREECAST) > 0 )
{// restore original walk speed
ud->skilltimer = INVALID_TIMER;
status_calc_bl(&sd->bl, SCB_SPEED);
@@ -6091,7 +6076,7 @@ int skill_castend_pos(int tid, unsigned int tick, int id, intptr data)
}
}
- if(tid != -1)
+ if(tid != INVALID_TIMER)
{ //Avoid double checks on instant cast skills. [Skotlex]
if (!status_check_skilluse(src, NULL, ud->skillid, 1))
break;
@@ -6124,7 +6109,7 @@ int skill_castend_pos(int tid, unsigned int tick, int id, intptr data)
ShowInfo("Type %d, ID %d skill castend pos [id =%d, lv=%d, (%d,%d)]\n",
src->type, src->id, ud->skillid, ud->skilllv, ud->skillx, ud->skilly);
- if (ud->walktimer != -1)
+ if (ud->walktimer != INVALID_TIMER)
unit_stop_walking(src,1);
if( !sd || sd->skillitem != ud->skillid || skill_get_delay(ud->skillid,ud->skilllv) )
@@ -6148,7 +6133,7 @@ int skill_castend_pos(int tid, unsigned int tick, int id, intptr data)
if( sd && sd->skillitem != AL_WARP ) // Warp-Portal thru items will clear data in skill_castend_map. [Inkfish]
sd->skillitem = sd->skillitemlv = 0;
- if (ud->skilltimer == -1) {
+ if (ud->skilltimer == INVALID_TIMER) {
if (md) md->skillidx = -1;
else ud->skillid = 0; //Non mobs can't clear this one as it is used for skill condition 'afterskill'
ud->skilllv = ud->skillx = ud->skilly = 0;
@@ -6335,7 +6320,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
break;
case HP_BASILICA:
if( sc->data[SC_BASILICA] )
- status_change_end(src, SC_BASILICA, -1); // Cancel Basilica
+ status_change_end(src, SC_BASILICA, INVALID_TIMER); // Cancel Basilica
else
{ // Create Basilica. Start SC on caster. Unit timer start SC on others.
skill_clear_unitgroup(src);
@@ -6408,8 +6393,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
unit_movepos(src, x, y, 1, 0);
clif_slide(src,x,y);
}
- if (sc && sc->data[SC_HIDING])
- status_change_end(src, SC_HIDING, -1);
+ status_change_end(src, SC_HIDING, INVALID_TIMER);
break;
case AM_SPHEREMINE:
case AM_CANNIBALIZE:
@@ -6544,7 +6528,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
case PA_GOSPEL:
if (sce && sce->val4 == BCT_SELF)
{
- status_change_end(src,SC_GOSPEL,-1);
+ status_change_end(src, SC_GOSPEL, INVALID_TIMER);
return 0;
}
else
@@ -6552,7 +6536,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
sg = skill_unitsetting(src,skillid,skilllv,src->x,src->y,0);
if (!sg) break;
if (sce)
- status_change_end(src,type,-1); //Was under someone else's Gospel. [Skotlex]
+ status_change_end(src, type, INVALID_TIMER); //Was under someone else's Gospel. [Skotlex]
sc_start4(src,type,100,skilllv,0,sg->group_id,BCT_SELF,skill_get_time(skillid,skilllv));
clif_skill_poseffect(src, skillid, skilllv, 0, 0, tick); // PA_GOSPEL music packet
}
@@ -6578,8 +6562,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
return 1;
}
- if (sc && sc->data[SC_MAGICPOWER])
- status_change_end(src,SC_MAGICPOWER,-1);
+ status_change_end(src, SC_MAGICPOWER, INVALID_TIMER);
if( sd )
{
@@ -7807,17 +7790,17 @@ int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned in
case UNT_SAFETYWALL:
case UNT_PNEUMA:
if (sce)
- status_change_end(bl,type,-1);
+ status_change_end(bl, type, INVALID_TIMER);
break;
case UNT_BASILICA:
if( sce && sce->val4 == src->bl.id )
- status_change_end(bl,type,-1);
+ status_change_end(bl, type, INVALID_TIMER);
break;
case UNT_HERMODE: //Clear Hermode if the owner moved.
if (sce && sce->val3 == BCT_SELF && sce->val4 == sg->group_id)
- status_change_end(bl,type,-1);
+ status_change_end(bl, type, INVALID_TIMER);
break;
case UNT_SPIDERWEB:
@@ -7826,7 +7809,7 @@ int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned in
if (target && target==bl)
{
if (sce && sce->val3 == sg->group_id)
- status_change_end(bl,type,-1);
+ status_change_end(bl, type, INVALID_TIMER);
sg->limit = DIFF_TICK(tick,sg->tick)+1000;
}
break;
@@ -7857,7 +7840,7 @@ static int skill_unit_onleft (int skill_id, struct block_list *bl, unsigned int
if (bl->type==BL_MOB)
break;
if (sce)
- status_change_end(bl, type, -1);
+ status_change_end(bl, type, INVALID_TIMER);
break;
case BD_LULLABY:
@@ -7875,7 +7858,7 @@ static int skill_unit_onleft (int skill_id, struct block_list *bl, unsigned int
//it only checks if you are doing the same ensemble. So if there's two chars doing an ensemble
//which overlaps, by stepping outside of the other parther's ensemble will cause you to cancel
//your own. Let's pray that scenario is pretty unlikely and noone will complain too much about it.
- status_change_end(bl, SC_DANCING, -1);
+ status_change_end(bl, SC_DANCING, INVALID_TIMER);
}
case MG_SAFETYWALL:
case AL_PNEUMA:
@@ -7886,7 +7869,7 @@ static int skill_unit_onleft (int skill_id, struct block_list *bl, unsigned int
case HW_GRAVITATION:
case NJ_SUITON:
if (sce)
- status_change_end(bl, type, -1);
+ status_change_end(bl, type, INVALID_TIMER);
break;
case BA_POEMBRAGI:
@@ -7909,11 +7892,11 @@ static int skill_unit_onleft (int skill_id, struct block_list *bl, unsigned int
case PF_FOGWALL:
if (sce)
{
- status_change_end(bl,type,-1);
+ status_change_end(bl, type, INVALID_TIMER);
if ((sce=sc->data[SC_BLIND]))
{
if (bl->type == BL_PC) //Players get blind ended inmediately, others have it still for 30 secs. [Skotlex]
- status_change_end(bl, SC_BLIND, -1);
+ status_change_end(bl, SC_BLIND, INVALID_TIMER);
else {
delete_timer(sce->timer, status_change_timer);
sce->timer = add_timer(30000+tick, status_change_timer, bl->id, SC_BLIND);
@@ -8252,7 +8235,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, short skill, sh
switch( skill )
{
case SA_CASTCANCEL:
- if(sd->ud.skilltimer == -1) {
+ if(sd->ud.skilltimer == INVALID_TIMER) {
clif_skill_fail(sd,skill,0,0);
return 0;
}
@@ -8352,7 +8335,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, short skill, sh
if (pc_famerank(sd->status.char_id,MAPID_TAEKWON))
{ //Unlimited Combo
if (skill == sd->skillid_old) {
- status_change_end(&sd->bl, SC_COMBO, -1);
+ status_change_end(&sd->bl, SC_COMBO, INVALID_TIMER);
sd->skillid_old = sd->skilllv_old = 0;
return 0; //Can't repeat previous combo skill.
}
@@ -9046,12 +9029,12 @@ int skill_castfix_sc (struct block_list *bl, int time)
time += time * sc->data[SC_SLOWCAST]->val2 / 100;
if (sc->data[SC_SUFFRAGIUM]) {
time -= time * sc->data[SC_SUFFRAGIUM]->val2 / 100;
- status_change_end(bl, SC_SUFFRAGIUM, -1);
+ status_change_end(bl, SC_SUFFRAGIUM, INVALID_TIMER);
}
if (sc->data[SC_MEMORIZE]) {
time>>=1;
if ((--sc->data[SC_MEMORIZE]->val2) <= 0)
- status_change_end(bl, SC_MEMORIZE, -1);
+ status_change_end(bl, SC_MEMORIZE, INVALID_TIMER);
}
if (sc->data[SC_POEMBRAGI])
time -= time * sc->data[SC_POEMBRAGI]->val2 / 100;
@@ -9915,7 +9898,7 @@ int skill_enchant_elemental_end (struct block_list *bl, int type)
for (i = 0; i < ARRAYLENGTH(scs); i++)
if (type != scs[i] && sc->data[scs[i]])
- status_change_end(bl, scs[i], -1);
+ status_change_end(bl, scs[i], INVALID_TIMER);
return 0;
}
@@ -9940,7 +9923,7 @@ bool skill_check_cloaking(struct block_list *bl, struct status_change_entry *sce
if( !wall )
{
if( sce->val1 < 3 ) //End cloaking.
- status_change_end(bl, SC_CLOAKING, -1);
+ status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
else
if( sce->val4&1 )
{ //Remove wall bonus
@@ -10039,7 +10022,7 @@ int skill_delunit (struct skill_unit* unit)
{
struct block_list* target = map_id2bl(group->val2);
if( target )
- status_change_end(target,SC_ANKLE,-1);
+ status_change_end(target, SC_ANKLE, INVALID_TIMER);
}
break;
case WZ_ICEWALL:
@@ -10185,7 +10168,7 @@ int skill_delunitgroup_(struct skill_unit_group *group, const char* file, int li
if (sc && sc->data[SC_DANCING])
{
sc->data[SC_DANCING]->val2 = 0 ; //This prevents status_change_end attempting to redelete the group. [Skotlex]
- status_change_end(src,SC_DANCING,-1);
+ status_change_end(src, SC_DANCING, INVALID_TIMER);
}
}
@@ -10195,7 +10178,7 @@ int skill_delunitgroup_(struct skill_unit_group *group, const char* file, int li
struct status_change *sc = status_get_sc(src);
if(sc && sc->data[SC_GOSPEL]) {
sc->data[SC_GOSPEL]->val3 = 0; //Remove reference to this group. [Skotlex]
- status_change_end(src,SC_GOSPEL,-1);
+ status_change_end(src, SC_GOSPEL, INVALID_TIMER);
}
}
@@ -10205,7 +10188,7 @@ int skill_delunitgroup_(struct skill_unit_group *group, const char* file, int li
struct status_change *sc = status_get_sc(src);
if(sc && sc->data[SC_WARM]) {
sc->data[SC_WARM]->val4 = 0;
- status_change_end(src,SC_WARM,-1);
+ status_change_end(src, SC_WARM, INVALID_TIMER);
}
}
diff --git a/src/map/status.c b/src/map/status.c
index 449ea8f56..45fe3a4cf 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -698,20 +698,20 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
if( sc ) {
struct status_change_entry *sce;
if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
- status_change_end(target,SC_STONE,-1);
- status_change_end(target,SC_FREEZE,-1);
- status_change_end(target,SC_SLEEP,-1);
- status_change_end(target,SC_WINKCHARM,-1);
- status_change_end(target,SC_CONFUSION,-1);
- status_change_end(target,SC_TRICKDEAD,-1);
- status_change_end(target,SC_HIDING,-1);
- status_change_end(target,SC_CLOAKING,-1);
- status_change_end(target,SC_CHASEWALK,-1);
+ status_change_end(target, SC_STONE, INVALID_TIMER);
+ status_change_end(target, SC_FREEZE, INVALID_TIMER);
+ status_change_end(target, SC_SLEEP, INVALID_TIMER);
+ status_change_end(target, SC_WINKCHARM, INVALID_TIMER);
+ status_change_end(target, SC_CONFUSION, INVALID_TIMER);
+ status_change_end(target, SC_TRICKDEAD, INVALID_TIMER);
+ status_change_end(target, SC_HIDING, INVALID_TIMER);
+ status_change_end(target, SC_CLOAKING, INVALID_TIMER);
+ status_change_end(target, SC_CHASEWALK, INVALID_TIMER);
if ((sce=sc->data[SC_ENDURE]) && !sce->val4) {
//Endure count is only reduced by non-players on non-gvg maps.
//val4 signals infinite endure. [Skotlex]
if (src && src->type != BL_PC && !map_flag_gvg(target->m) && !map[target->m].flag.battleground && --(sce->val2) < 0)
- status_change_end(target, SC_ENDURE, -1);
+ status_change_end(target, SC_ENDURE, INVALID_TIMER);
}
if ((sce=sc->data[SC_GRAVITATION]) && sce->val3 == BCT_SELF)
{
@@ -719,11 +719,11 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
if (sg) {
skill_delunitgroup(sg);
sce->val4 = 0;
- status_change_end(target, SC_GRAVITATION, -1);
+ status_change_end(target, SC_GRAVITATION, INVALID_TIMER);
}
}
if(sc->data[SC_DANCING] && (unsigned int)hp > status->max_hp>>2)
- status_change_end(target, SC_DANCING, -1);
+ status_change_end(target, SC_DANCING, INVALID_TIMER);
}
unit_skillcastcancel(target, 2);
}
@@ -747,7 +747,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
status->hp < status->max_hp>>2)
sc_start4(target,SC_PROVOKE,100,10,1,0,0,0);
if (sc->data[SC_BERSERK] && status->hp <= 100)
- status_change_end(target, SC_BERSERK, -1);
+ status_change_end(target, SC_BERSERK, INVALID_TIMER);
}
switch (target->type)
@@ -899,7 +899,7 @@ int status_heal(struct block_list *bl,int hp,int sp, int flag)
sc->data[SC_PROVOKE]->val2==1 &&
status->hp>=status->max_hp>>2
) //End auto berserk.
- status_change_end(bl,SC_PROVOKE,-1);
+ status_change_end(bl, SC_PROVOKE, INVALID_TIMER);
// send hp update to client
switch(bl->type) {
@@ -2869,9 +2869,9 @@ void status_calc_bl_main(struct block_list *bl, enum scb_flag flag)
struct unit_data *ud = unit_bl2ud(bl);
status->speed = status_calc_speed(bl, sc, b_status->speed);
- //Re-walk to adjust speed (we do not check if walktimer != -1
+ //Re-walk to adjust speed (we do not check if walktimer != INVALID_TIMER
//because if you step on something while walking, the moment this
- //piece of code triggers the walk-timer is set on -1) [Skotlex]
+ //piece of code triggers the walk-timer is set on INVALID_TIMER) [Skotlex]
if (ud)
ud->state.change_walk_target = ud->state.speed_changed = 1;
@@ -3757,7 +3757,7 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
if( sc == NULL )
return cap_value(speed,10,USHRT_MAX);
- if( sd && sd->ud.skilltimer != -1 && pc_checkskill(sd,SA_FREECAST) > 0 )
+ if( sd && sd->ud.skilltimer != INVALID_TIMER && pc_checkskill(sd,SA_FREECAST) > 0 )
{
speed_rate = 175 - 5 * pc_checkskill(sd,SA_FREECAST);
}
@@ -4213,7 +4213,7 @@ signed char status_get_def(struct block_list *bl)
struct status_data *status = status_get_status_data(bl);
int def = status?status->def:0;
ud = unit_bl2ud(bl);
- if (ud && ud->skilltimer != -1)
+ if (ud && ud->skilltimer != INVALID_TIMER)
def -= def * skill_get_castdef(ud->skillid)/100;
return cap_value(def, CHAR_MIN, CHAR_MAX);
}
@@ -4846,7 +4846,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if (val3) mode|= val3; //Add mode
if (mode == bstatus->mode) { //No change.
if (sc->data[type]) //Abort previous status
- return status_change_end(bl, type, -1);
+ return status_change_end(bl, type, INVALID_TIMER);
return 0;
}
}
@@ -5001,133 +5001,132 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
//TO-DO Blessing and Agi up should do 1 damage against players on Undead Status, even on PvM
//but cannot be plagiarized (this requires aegis investigation on packets and official behavior) [Brainstorm]
if ((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC) {
- if (sc->data[SC_CURSE])
- status_change_end(bl,SC_CURSE,-1);
+ status_change_end(bl, SC_CURSE, INVALID_TIMER);
if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
- status_change_end(bl,SC_STONE,-1);
+ status_change_end(bl, SC_STONE, INVALID_TIMER);
}
break;
case SC_INCREASEAGI:
- status_change_end(bl,SC_DECREASEAGI,-1);
+ status_change_end(bl, SC_DECREASEAGI, INVALID_TIMER);
break;
case SC_QUAGMIRE:
- status_change_end(bl,SC_CONCENTRATE,-1);
- status_change_end(bl,SC_TRUESIGHT,-1);
- status_change_end(bl,SC_WINDWALK,-1);
+ status_change_end(bl, SC_CONCENTRATE, INVALID_TIMER);
+ status_change_end(bl, SC_TRUESIGHT, INVALID_TIMER);
+ status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
//Also blocks the ones below...
case SC_DECREASEAGI:
- status_change_end(bl,SC_CARTBOOST,-1);
+ status_change_end(bl, SC_CARTBOOST, INVALID_TIMER);
//Also blocks the ones below...
case SC_DONTFORGETME:
- status_change_end(bl,SC_INCREASEAGI,-1);
- status_change_end(bl,SC_ADRENALINE,-1);
- status_change_end(bl,SC_ADRENALINE2,-1);
- status_change_end(bl,SC_SPEARQUICKEN,-1);
- status_change_end(bl,SC_TWOHANDQUICKEN,-1);
- status_change_end(bl,SC_ONEHAND,-1);
- status_change_end(bl,SC_MERC_QUICKEN,-1);
+ status_change_end(bl, SC_INCREASEAGI, INVALID_TIMER);
+ status_change_end(bl, SC_ADRENALINE, INVALID_TIMER);
+ status_change_end(bl, SC_ADRENALINE2, INVALID_TIMER);
+ status_change_end(bl, SC_SPEARQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_ONEHAND, INVALID_TIMER);
+ status_change_end(bl, SC_MERC_QUICKEN, INVALID_TIMER);
break;
case SC_ONEHAND:
//Removes the Aspd potion effect, as reported by Vicious. [Skotlex]
- status_change_end(bl,SC_ASPDPOTION0,-1);
- status_change_end(bl,SC_ASPDPOTION1,-1);
- status_change_end(bl,SC_ASPDPOTION2,-1);
- status_change_end(bl,SC_ASPDPOTION3,-1);
+ status_change_end(bl, SC_ASPDPOTION0, INVALID_TIMER);
+ status_change_end(bl, SC_ASPDPOTION1, INVALID_TIMER);
+ status_change_end(bl, SC_ASPDPOTION2, INVALID_TIMER);
+ status_change_end(bl, SC_ASPDPOTION3, INVALID_TIMER);
break;
case SC_MAXOVERTHRUST:
//Cancels Normal Overthrust. [Skotlex]
- status_change_end(bl, SC_OVERTHRUST, -1);
+ status_change_end(bl, SC_OVERTHRUST, INVALID_TIMER);
break;
case SC_KYRIE:
//Cancels Assumptio
- status_change_end(bl,SC_ASSUMPTIO,-1);
+ status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
break;
case SC_DELUGE:
if (sc->data[SC_FOGWALL] && sc->data[SC_BLIND])
- status_change_end(bl,SC_BLIND,-1);
+ status_change_end(bl, SC_BLIND, INVALID_TIMER);
break;
case SC_SILENCE:
if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF)
- status_change_end(bl,SC_GOSPEL,-1);
+ status_change_end(bl, SC_GOSPEL, INVALID_TIMER);
break;
case SC_HIDING:
- status_change_end(bl, SC_CLOSECONFINE, -1);
- status_change_end(bl, SC_CLOSECONFINE2, -1);
+ status_change_end(bl, SC_CLOSECONFINE, INVALID_TIMER);
+ status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER);
break;
case SC_BERSERK:
if(battle_config.berserk_cancels_buffs)
{
- status_change_end(bl,SC_ONEHAND,-1);
- status_change_end(bl,SC_TWOHANDQUICKEN,-1);
- status_change_end(bl,SC_CONCENTRATION,-1);
- status_change_end(bl,SC_PARRYING,-1);
- status_change_end(bl,SC_AURABLADE,-1);
- status_change_end(bl,SC_MERC_QUICKEN,-1);
+ status_change_end(bl, SC_ONEHAND, INVALID_TIMER);
+ status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_CONCENTRATION, INVALID_TIMER);
+ status_change_end(bl, SC_PARRYING, INVALID_TIMER);
+ status_change_end(bl, SC_AURABLADE, INVALID_TIMER);
+ status_change_end(bl, SC_MERC_QUICKEN, INVALID_TIMER);
}
break;
case SC_ASSUMPTIO:
- status_change_end(bl,SC_KYRIE,-1);
- status_change_end(bl,SC_KAITE,-1);
+ status_change_end(bl, SC_KYRIE, INVALID_TIMER);
+ status_change_end(bl, SC_KAITE, INVALID_TIMER);
break;
case SC_KAITE:
- status_change_end(bl,SC_ASSUMPTIO,-1);
+ status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
break;
case SC_CARTBOOST:
if(sc->data[SC_DECREASEAGI])
{ //Cancel Decrease Agi, but take no further effect [Skotlex]
- status_change_end(bl,SC_DECREASEAGI,-1);
+ status_change_end(bl, SC_DECREASEAGI, INVALID_TIMER);
return 0;
}
break;
case SC_FUSION:
- status_change_end(bl,SC_SPIRIT,-1);
+ status_change_end(bl, SC_SPIRIT, INVALID_TIMER);
break;
case SC_ADJUSTMENT:
- status_change_end(bl,SC_MADNESSCANCEL,-1);
+ status_change_end(bl, SC_MADNESSCANCEL, INVALID_TIMER);
break;
case SC_MADNESSCANCEL:
- status_change_end(bl,SC_ADJUSTMENT,-1);
+ status_change_end(bl, SC_ADJUSTMENT, INVALID_TIMER);
break;
//NPC_CHANGEUNDEAD will debuff Blessing and Agi Up
case SC_CHANGEUNDEAD:
- status_change_end(bl,SC_BLESSING,-1);
- status_change_end(bl,SC_INCREASEAGI,-1);
+ status_change_end(bl, SC_BLESSING, INVALID_TIMER);
+ status_change_end(bl, SC_INCREASEAGI, INVALID_TIMER);
break;
case SC_STRFOOD:
- status_change_end(bl,SC_FOOD_STR_CASH,-1);
+ status_change_end(bl, SC_FOOD_STR_CASH, INVALID_TIMER);
break;
case SC_AGIFOOD:
- status_change_end(bl,SC_FOOD_AGI_CASH,-1);
+ status_change_end(bl, SC_FOOD_AGI_CASH, INVALID_TIMER);
break;
case SC_VITFOOD:
- status_change_end(bl,SC_FOOD_VIT_CASH,-1);
+ status_change_end(bl, SC_FOOD_VIT_CASH, INVALID_TIMER);
break;
case SC_INTFOOD:
- status_change_end(bl,SC_FOOD_INT_CASH,-1);
+ status_change_end(bl, SC_FOOD_INT_CASH, INVALID_TIMER);
break;
case SC_DEXFOOD:
- status_change_end(bl,SC_FOOD_DEX_CASH,-1);
+ status_change_end(bl, SC_FOOD_DEX_CASH, INVALID_TIMER);
break;
case SC_LUKFOOD:
- status_change_end(bl,SC_FOOD_LUK_CASH,-1);
+ status_change_end(bl, SC_FOOD_LUK_CASH, INVALID_TIMER);
break;
case SC_FOOD_STR_CASH:
- status_change_end(bl,SC_STRFOOD,-1);
+ status_change_end(bl, SC_STRFOOD, INVALID_TIMER);
break;
case SC_FOOD_AGI_CASH:
- status_change_end(bl,SC_AGIFOOD,-1);
+ status_change_end(bl, SC_AGIFOOD, INVALID_TIMER);
break;
case SC_FOOD_VIT_CASH:
- status_change_end(bl,SC_VITFOOD,-1);
+ status_change_end(bl, SC_VITFOOD, INVALID_TIMER);
break;
case SC_FOOD_INT_CASH:
- status_change_end(bl,SC_INTFOOD,-1);
+ status_change_end(bl, SC_INTFOOD, INVALID_TIMER);
break;
case SC_FOOD_DEX_CASH:
- status_change_end(bl,SC_DEXFOOD,-1);
+ status_change_end(bl, SC_DEXFOOD, INVALID_TIMER);
break;
case SC_FOOD_LUK_CASH:
- status_change_end(bl,SC_LUKFOOD,-1);
+ status_change_end(bl, SC_LUKFOOD, INVALID_TIMER);
break;
}
@@ -5198,9 +5197,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_KAAHI:
//Kaahi overwrites previous level regardless of existing level.
//Delete timer if it exists.
- if (sce->val4 != -1) {
+ if (sce->val4 != INVALID_TIMER) {
delete_timer(sce->val4,kaahi_heal_timer);
- sce->val4=-1;
+ sce->val4 = INVALID_TIMER;
}
break;
case SC_JAILED:
@@ -5821,7 +5820,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_KAAHI:
val2 = 200*val1; //HP heal
val3 = 5*val1; //SP cost
- val4 = -1; //Kaahi Timer.
+ val4 = INVALID_TIMER; //Kaahi Timer.
break;
case SC_BLESSING:
if ((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC)
@@ -6087,7 +6086,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
clif_changelook(bl,LOOK_CLOTHES_COLOR,val4);
break;
case SC_KAAHI:
- val4 = -1;
+ val4 = INVALID_TIMER;
break;
}
@@ -6102,7 +6101,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
pc_setstand(sd);
case SC_TRICKDEAD:
unit_stop_attack(bl);
- status_change_end(bl, SC_DANCING, -1);
+ status_change_end(bl, SC_DANCING, INVALID_TIMER);
// Cancel cast when get status [LuzZza]
if (battle_config.sc_castcancel&bl->type)
unit_skillcastcancel(bl, 0);
@@ -6448,14 +6447,14 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
sd = BL_CAST(BL_PC,bl);
- if (sce->timer != tid && tid != -1)
+ if (sce->timer != tid && tid != INVALID_TIMER)
return 0;
- if (tid == -1) {
+ if (tid == INVALID_TIMER) {
if (type == SC_ENDURE && sce->val4)
//Do not end infinite endure.
return 0;
- if (sce->timer != -1) //Could be a SC with infinite duration
+ if (sce->timer != INVALID_TIMER) //Could be a SC with infinite duration
delete_timer(sce->timer,status_change_timer);
if (sc->opt1)
switch (type) {
@@ -6514,7 +6513,7 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
if(!ud->state.running)
begin_spurt = false;
ud->state.running = 0;
- if (ud->walktimer != -1)
+ if (ud->walktimer != INVALID_TIMER)
unit_stop_walking(bl,1);
}
if (begin_spurt && sce->val1 >= 7 &&
@@ -6526,7 +6525,7 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
break;
case SC_AUTOBERSERK:
if (sc->data[SC_PROVOKE] && sc->data[SC_PROVOKE]->val2 == 1)
- status_change_end(bl,SC_PROVOKE,-1);
+ status_change_end(bl, SC_PROVOKE, INVALID_TIMER);
break;
case SC_ENDURE:
@@ -6541,14 +6540,14 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
for( i = 0; i < 5; i++ )
{
if( sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])) && tsd->sc.data[type] )
- status_change_end(&tsd->bl, type, -1);
+ status_change_end(&tsd->bl, type, INVALID_TIMER);
}
}
else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag )
{ // Clear Status from Master
tsd = ((TBL_MER*)bl)->master;
if( tsd && tsd->sc.data[type] )
- status_change_end(&tsd->bl, type, -1);
+ status_change_end(&tsd->bl, type, INVALID_TIMER);
}
}
break;
@@ -6564,10 +6563,10 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
clif_devotion(d_bl, NULL);
}
- status_change_end(bl,SC_AUTOGUARD,-1);
- status_change_end(bl,SC_DEFENDER,-1);
- status_change_end(bl,SC_REFLECTSHIELD,-1);
- status_change_end(bl,SC_ENDURE,-1);
+ status_change_end(bl, SC_AUTOGUARD, INVALID_TIMER);
+ status_change_end(bl, SC_DEFENDER, INVALID_TIMER);
+ status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER);
+ status_change_end(bl, SC_ENDURE, INVALID_TIMER);
}
break;
@@ -6581,7 +6580,7 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
if(tbl && tsc && tsc->data[SC_BLADESTOP])
{
tsc->data[SC_BLADESTOP]->val4 = 0;
- status_change_end(tbl,SC_BLADESTOP,-1);
+ status_change_end(tbl, SC_BLADESTOP, INVALID_TIMER);
}
clif_bladestop(bl, tid, 0);
}
@@ -6598,7 +6597,7 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
if(dsc)
{ //This will prevent recursive loops.
dsc->val2 = dsc->val4 = 0;
- status_change_end(&dsd->bl, SC_DANCING, -1);
+ status_change_end(&dsd->bl, SC_DANCING, INVALID_TIMER);
}
}
@@ -6621,11 +6620,11 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
if((sce->val1&0xFFFF) == CG_MOONLIT)
clif_status_change(bl,SI_MOONLIT,0,0);
- status_change_end(bl,SC_LONGING,-1);
+ status_change_end(bl, SC_LONGING, INVALID_TIMER);
}
break;
case SC_NOCHAT:
- if (sd && sd->status.manner < 0 && tid != -1)
+ if (sd && sd->status.manner < 0 && tid != INVALID_TIMER)
sd->status.manner = 0;
if (sd)
{
@@ -6636,7 +6635,7 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
case SC_SPLASHER:
{
struct block_list *src=map_id2bl(sce->val3);
- if(src && tid!=-1)
+ if(src && tid != INVALID_TIMER)
skill_castend_damage_id(src, bl, sce->val2, sce->val1, gettick(), SD_LEVEL );
}
break;
@@ -6648,7 +6647,7 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
//If status was already ended, do nothing.
//Decrease count
if (--(sc2->data[SC_CLOSECONFINE]->val1) <= 0) //No more holds, free him up.
- status_change_end(src, SC_CLOSECONFINE, -1);
+ status_change_end(src, SC_CLOSECONFINE, INVALID_TIMER);
}
}
case SC_CLOSECONFINE:
@@ -6685,7 +6684,7 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
if (sc2 && sc2->data[type2])
{
sc2->data[type2]->val1 = 0;
- status_change_end(pbl, type2, -1);
+ status_change_end(pbl, type2, INVALID_TIMER);
}
}
break;
@@ -6697,7 +6696,7 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
if(sc->data[SC_ENDURE] && sc->data[SC_ENDURE]->val4 == 2)
{
sc->data[SC_ENDURE]->val4 = 0;
- status_change_end(bl, SC_ENDURE, -1);
+ status_change_end(bl, SC_ENDURE, INVALID_TIMER);
}
sc_start4(bl, SC_REGENERATION, 100, 10,0,0,(RGN_HP|RGN_SP), skill_get_time(LK_BERSERK, sce->val1));
break;
@@ -6727,25 +6726,25 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
break;
case SC_KAAHI:
//Delete timer if it exists.
- if (sce->val4 != -1)
+ if (sce->val4 != INVALID_TIMER)
delete_timer(sce->val4,kaahi_heal_timer);
break;
case SC_JAILED:
- if(tid == -1)
+ if(tid == INVALID_TIMER)
break;
//natural expiration.
if(sd && sd->mapindex == sce->val2)
pc_setpos(sd,(unsigned short)sce->val3,sce->val4&0xFFFF, sce->val4>>16, CLR_TELEPORT);
break; //guess hes not in jail :P
case SC_CHANGE:
- if (tid == -1)
+ if (tid == INVALID_TIMER)
break;
// "lose almost all their HP and SP" on natural expiration.
status_set_hp(bl, 10, 0);
status_set_sp(bl, 10, 0);
break;
case SC_AUTOTRADE:
- if (tid == -1)
+ if (tid == INVALID_TIMER)
break;
vending_closevending(sd);
map_quit(sd);
@@ -6759,7 +6758,7 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
struct block_list* tbl = map_id2bl(sce->val2);
sce->val2 = 0;
if( tbl && (sc = status_get_sc(tbl)) && sc->data[SC_STOP] && sc->data[SC_STOP]->val2 == bl->id )
- status_change_end(tbl, SC_STOP, -1);
+ status_change_end(tbl, SC_STOP, INVALID_TIMER);
}
break;
}
@@ -6956,13 +6955,13 @@ int kaahi_heal_timer(int tid, unsigned int tick, int id, intptr data)
if(sce->val4 != tid) {
ShowError("kaahi_heal_timer: Timer mismatch: %d != %d\n", tid, sce->val4);
- sce->val4=-1;
+ sce->val4 = INVALID_TIMER;
return 0;
}
status=status_get_status_data(bl);
if(!status_charge(bl, 0, sce->val3)) {
- sce->val4=-1;
+ sce->val4 = INVALID_TIMER;
return 0;
}
@@ -6971,7 +6970,7 @@ int kaahi_heal_timer(int tid, unsigned int tick, int id, intptr data)
hp = sce->val2;
if (hp)
status_heal(bl, hp, 0, 2);
- sce->val4=-1;
+ sce->val4 = INVALID_TIMER;
return 1;
}
@@ -7350,13 +7349,13 @@ int status_change_timer_sub(struct block_list* bl, va_list ap)
{
case SC_SIGHT: /* ƒTƒCƒg */
case SC_CONCENTRATE:
- status_change_end(bl, SC_HIDING, -1);
- status_change_end(bl, SC_CLOAKING, -1);
+ status_change_end(bl, SC_HIDING, INVALID_TIMER);
+ status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
break;
case SC_RUWACH: /* ƒ‹ƒAƒt */
if (tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING])) {
- status_change_end(bl, SC_HIDING, -1);
- status_change_end(bl, SC_CLOAKING, -1);
+ status_change_end(bl, SC_HIDING, INVALID_TIMER);
+ status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
if(battle_check_target( src, bl, BCT_ENEMY ) > 0)
skill_attack(BF_MAGIC,src,src,bl,AL_RUWACH,1,tick,0);
}
@@ -7373,7 +7372,7 @@ int status_change_timer_sub(struct block_list* bl, va_list ap)
//Lock char has released the hold on everyone...
if (tsc && tsc->data[SC_CLOSECONFINE2] && tsc->data[SC_CLOSECONFINE2]->val2 == src->id) {
tsc->data[SC_CLOSECONFINE2]->val2 = 0;
- status_change_end(bl, SC_CLOSECONFINE2, -1);
+ status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER);
}
break;
}
@@ -7395,8 +7394,7 @@ int status_change_clear_buffs (struct block_list* bl, int type)
if (type&2) //Debuffs
for( i = SC_COMMON_MIN; i <= SC_COMMON_MAX; i++ )
{
- if(sc->data[i])
- status_change_end(bl,(sc_type)i,-1);
+ status_change_end(bl, (sc_type)i, INVALID_TIMER);
}
for( i = SC_COMMON_MAX+1; i < SC_MAX; i++ )
@@ -7469,7 +7467,7 @@ int status_change_clear_buffs (struct block_list* bl, int type)
continue;
break;
}
- status_change_end(bl,(sc_type)i,-1);
+ status_change_end(bl, (sc_type)i, INVALID_TIMER);
}
return 0;
}
@@ -7557,7 +7555,7 @@ static int status_natural_heal(struct block_list* bl, va_list args)
ud = unit_bl2ud(bl);
- if (flag&(RGN_HP|RGN_SHP|RGN_SSP) && ud && ud->walktimer != -1)
+ if (flag&(RGN_HP|RGN_SHP|RGN_SSP) && ud && ud->walktimer != INVALID_TIMER)
{
flag&=~(RGN_SHP|RGN_SSP);
if(!regen->state.walk)
@@ -7580,7 +7578,7 @@ static int status_natural_heal(struct block_list* bl, va_list args)
if (flag&RGN_HP)
{
rate = natural_heal_diff_tick*(regen->rate.hp+bonus);
- if (ud && ud->walktimer != -1)
+ if (ud && ud->walktimer != INVALID_TIMER)
rate/=2;
// Homun HP regen fix (they should regen as if they were sitting (twice as fast)
if(bl->type==BL_HOM) rate *=2;
diff --git a/src/map/storage.c b/src/map/storage.c
index 9aa34d3e0..116ba18c9 100644
--- a/src/map/storage.c
+++ b/src/map/storage.c
@@ -398,11 +398,12 @@ int guild_storage_additem(struct map_session_data* sd, struct guild_storage* sto
nullpo_retr(1, sd);
nullpo_retr(1, stor);
nullpo_retr(1, item_data);
- nullpo_retr(1, data = itemdb_search(item_data->nameid));
if(item_data->nameid <= 0 || amount <= 0)
return 1;
+ data = itemdb_search(item_data->nameid);
+
if( data->stack.guildstorage && amount > data->stack.amount )
{// item stack limitation
return 1;
diff --git a/src/map/trade.c b/src/map/trade.c
index 32c84b508..ba01826f2 100644
--- a/src/map/trade.c
+++ b/src/map/trade.c
@@ -56,7 +56,7 @@ void trade_traderequest(struct map_session_data *sd, struct map_session_data *ta
}
}
- if ((target_sd->trade_partner != 0) || (sd->trade_partner != 0)) {
+ if (target_sd->trade_partner != 0) {
clif_tradestart(sd, 2); // person is in another trade
return;
}
@@ -110,6 +110,7 @@ void trade_tradeack(struct map_session_data *sd, int type)
if (tsd->state.trading || tsd->trade_partner != sd->bl.id)
{
clif_tradestart(sd, 2);
+ sd->trade_partner=0;
return; //Already trading or wrong partner.
}
diff --git a/src/map/unit.c b/src/map/unit.c
index df4efef8e..7abfde12b 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -157,7 +157,7 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr data)
map_moveblock(bl, x, y, tick);
ud->walk_count++; //walked cell counter, to be used for walk-triggered skills. [Skotlex]
- if (bl->x != x || bl->y != y || ud->walktimer != -1)
+ if (bl->x != x || bl->y != y || ud->walktimer != INVALID_TIMER)
return 0; //map_moveblock has altered the object beyond what we expected (moved/warped it)
ud->walktimer = -2; // arbitrary non-INVALID_TIMER value to make the clif code send walking packets
@@ -197,11 +197,11 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr data)
if (md->min_chase > md->db->range3) md->min_chase--;
//Walk skills are triggered regardless of target due to the idle-walk mob state.
//But avoid triggering on stop-walk calls.
- if(tid != -1 &&
+ if(tid != INVALID_TIMER &&
!(ud->walk_count%WALK_SKILL_INTERVAL) &&
mobskill_use(md, tick, -1))
{
- if (!(ud->skillid == NPC_SELFDESTRUCTION && ud->skilltimer != -1))
+ if (!(ud->skillid == NPC_SELFDESTRUCTION && ud->skilltimer != INVALID_TIMER))
{ //Skill used, abort walking
clif_fixpos(bl); //Fix position as walk has been cancelled.
return 0;
@@ -211,7 +211,7 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr data)
}
}
- if(tid == -1) //A directly invoked timer is from battle_stop_walking, therefore the rest is irrelevant.
+ if(tid == INVALID_TIMER) //A directly invoked timer is from battle_stop_walking, therefore the rest is irrelevant.
return 0;
if(ud->state.change_walk_target)
@@ -306,14 +306,14 @@ int unit_walktoxy( struct block_list *bl, short x, short y, int flag)
if (sc && sc->data[SC_CONFUSION]) //Randomize the target position
map_random_dir(bl, &ud->to_x, &ud->to_y);
- if(ud->walktimer != -1) {
+ if(ud->walktimer != INVALID_TIMER) {
// Œ»Ý•à‚¢‚Ä‚¢‚éÅ’†‚Ì–Ú“I’n•ÏX‚Ȃ̂Ń}ƒX–Ú‚Ì’†S‚É—ˆ‚½Žž‚É
// timerŠÖ”‚©‚çunit_walktoxy_sub‚ðŒÄ‚Ԃ悤‚É‚·‚é
ud->state.change_walk_target = 1;
return 1;
}
- if(ud->attacktimer != -1) {
+ if(ud->attacktimer != INVALID_TIMER) {
delete_timer( ud->attacktimer, unit_attack_timer );
ud->attacktimer = INVALID_TIMER;
}
@@ -331,7 +331,7 @@ static int unit_walktobl_sub(int tid, unsigned int tick, int id, intptr data)
struct block_list *bl = map_id2bl(id);
struct unit_data *ud = bl?unit_bl2ud(bl):NULL;
- if (ud && ud->walktimer == -1 && ud->target == data)
+ if (ud && ud->walktimer == INVALID_TIMER && ud->target == data)
{
if (DIFF_TICK(ud->canmove_tick, tick) > 0) //Keep waiting?
add_timer(ud->canmove_tick+1, unit_walktobl_sub, id, data);
@@ -374,7 +374,7 @@ int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, int
if (sc && sc->data[SC_CONFUSION]) //Randomize the target position
map_random_dir(bl, &ud->to_x, &ud->to_y);
- if(ud->walktimer != -1) {
+ if(ud->walktimer != INVALID_TIMER) {
ud->state.change_walk_target = 1;
set_mobstate(bl, flag&2);
return 1;
@@ -389,7 +389,7 @@ int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, int
if(!unit_can_move(bl))
return 0;
- if(ud->attacktimer != -1) {
+ if(ud->attacktimer != INVALID_TIMER) {
delete_timer( ud->attacktimer, unit_attack_timer );
ud->attacktimer = INVALID_TIMER;
}
@@ -413,7 +413,7 @@ int unit_run(struct block_list *bl)
return 0;
if (!unit_can_move(bl)) {
- status_change_end(bl,SC_RUN,-1);
+ status_change_end(bl, SC_RUN, INVALID_TIMER);
return 0;
}
@@ -443,7 +443,7 @@ int unit_run(struct block_list *bl)
//Set running to 0 beforehand so status_change_end knows not to enable spurt [Kevin]
unit_bl2ud(bl)->state.running = 0;
- status_change_end(bl,SC_RUN,-1);
+ status_change_end(bl, SC_RUN, INVALID_TIMER);
skill_blown(bl,bl,skill_get_blewcount(TK_RUN,lv),unit_getdir(bl),0);
clif_fixpos(bl); //Why is a clif_slide (skill_blown) AND a fixpos needed? Ask Aegis.
@@ -463,7 +463,7 @@ int unit_run(struct block_list *bl)
//Set running to 0 beforehand so status_change_end knows not to enable spurt [Kevin]
unit_bl2ud(bl)->state.running = 0;
- status_change_end(bl,SC_RUN,-1);
+ status_change_end(bl, SC_RUN, INVALID_TIMER);
skill_blown(bl,bl,skill_get_blewcount(TK_RUN,lv),unit_getdir(bl),0);
clif_fixpos(bl);
@@ -725,7 +725,7 @@ int unit_stop_walking(struct block_list *bl,int type)
nullpo_ret(bl);
ud = unit_bl2ud(bl);
- if(!ud || ud->walktimer == -1)
+ if(!ud || ud->walktimer == INVALID_TIMER)
return 0;
//NOTE: We are using timer data after deleting it because we know the
//delete_timer function does not messes with it. If the function's
@@ -739,7 +739,7 @@ int unit_stop_walking(struct block_list *bl,int type)
|| (type&0x04 && td && DIFF_TICK(td->tick, tick) <= td->data/2) //Enough time has passed to cover half-cell
) {
ud->walkpath.path_len = ud->walkpath.path_pos+1;
- unit_walktoxy_timer(-1, tick, bl->id, ud->walkpath.path_pos);
+ unit_walktoxy_timer(INVALID_TIMER, tick, bl->id, ud->walkpath.path_pos);
}
if(type&0x01)
@@ -754,7 +754,7 @@ int unit_stop_walking(struct block_list *bl,int type)
//Readded, the check in unit_set_walkdelay means dmg during running won't fall through to this place in code [Kevin]
if (ud->state.running)
- status_change_end(bl, SC_RUN, -1);
+ status_change_end(bl, SC_RUN, INVALID_TIMER);
return 1;
}
@@ -774,7 +774,7 @@ int unit_is_walking(struct block_list *bl)
struct unit_data *ud = unit_bl2ud(bl);
nullpo_ret(bl);
if(!ud) return 0;
- return (ud->walktimer != -1);
+ return (ud->walktimer != INVALID_TIMER);
}
/*==========================================
@@ -794,7 +794,7 @@ int unit_can_move(struct block_list *bl)
if (!ud)
return 0;
- if (ud->skilltimer != -1 && (!sd || !pc_checkskill(sd, SA_FREECAST) || skill_get_inf2(ud->skillid)&INF2_GUILD_SKILL))
+ if (ud->skilltimer != INVALID_TIMER && (!sd || !pc_checkskill(sd, SA_FREECAST) || skill_get_inf2(ud->skillid)&INF2_GUILD_SKILL))
return 0; // prevent moving while casting
if (DIFF_TICK(ud->canmove_tick, gettick()) > 0)
@@ -880,7 +880,7 @@ int unit_set_walkdelay(struct block_list *bl, unsigned int tick, int delay, int
return 0;
}
ud->canmove_tick = tick + delay;
- if (ud->walktimer != -1)
+ if (ud->walktimer != INVALID_TIMER)
{ //Stop walking, if chasing, readjust timers.
if (delay == 1)
{ //Minimal delay (walk-delay) disabled. Just stop walking.
@@ -939,8 +939,6 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
if(skillnotok(skill_num, sd)) // [MouseJstr]
return 0;
- mob_ksprotected(src, map_id2bl(target_id));
-
switch(skill_num)
{ //Check for skills that auto-select target
case MO_CHAINCOMBO:
@@ -987,8 +985,11 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
if( !target || src->m != target->m || !src->prev || !target->prev )
return 0;
+ if( mob_ksprotected(src, target) )
+ return 0;
+
//Normally not needed because clif.c checks for it, but the at/char/script commands don't! [Skotlex]
- if(ud->skilltimer != -1 && skill_num != SA_CASTCANCEL)
+ if(ud->skilltimer != INVALID_TIMER && skill_num != SA_CASTCANCEL)
return 0;
if(skill_get_inf2(skill_num)&INF2_NO_TARGET_SELF && src->id == target_id)
@@ -1047,7 +1048,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
//Check range when not using skill on yourself or is a combo-skill during attack
//(these are supposed to always have the same range as your attack)
- if( src->id != target_id && (!temp || ud->attacktimer == -1) )
+ if( src->id != target_id && (!temp || ud->attacktimer == INVALID_TIMER) )
{
if( skill_get_state(ud->skillid) == ST_MOVE_ENABLE )
{
@@ -1065,7 +1066,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
if (!temp) //Stop attack on non-combo skills [Skotlex]
unit_stop_attack(src);
- else if(ud->attacktimer != -1) //Elsewise, delay current attack sequence
+ else if(ud->attacktimer != INVALID_TIMER) //Elsewise, delay current attack sequence
ud->attackabletime = tick + status_get_adelay(src);
ud->state.skillcastcancel = castcancel;
@@ -1180,7 +1181,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
if( sc && sc->data[SC_CLOAKING] && !(sc->data[SC_CLOAKING]->val4&4) && skill_num != AS_CLOAKING )
{
- status_change_end(src,SC_CLOAKING,-1);
+ status_change_end(src, SC_CLOAKING, INVALID_TIMER);
if (!src->prev) return 0; //Warped away!
}
@@ -1224,7 +1225,7 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, sh
ud = unit_bl2ud(src);
if(ud == NULL) return 0;
- if(ud->skilltimer != -1) //Normally not needed since clif.c checks for it, but at/char/script commands don't! [Skotlex]
+ if(ud->skilltimer != INVALID_TIMER) //Normally not needed since clif.c checks for it, but at/char/script commands don't! [Skotlex]
return 0;
sc = status_get_sc(src);
@@ -1285,7 +1286,7 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, sh
if (sc && sc->data[SC_CLOAKING] && !(sc->data[SC_CLOAKING]->val4&4))
{
- status_change_end(src,SC_CLOAKING,-1);
+ status_change_end(src, SC_CLOAKING, INVALID_TIMER);
if (!src->prev) return 0; //Warped away!
}
@@ -1310,7 +1311,7 @@ int unit_stop_attack(struct block_list *bl)
struct unit_data *ud = unit_bl2ud(bl);
nullpo_ret(bl);
- if(!ud || ud->attacktimer == -1)
+ if(!ud || ud->attacktimer == INVALID_TIMER)
return 0;
delete_timer( ud->attacktimer, unit_attack_timer );
@@ -1380,7 +1381,7 @@ int unit_attack(struct block_list *src,int target_id,int continuous)
ud->chaserange = status_get_range(src);
//Just change target/type. [Skotlex]
- if(ud->attacktimer != -1)
+ if(ud->attacktimer != INVALID_TIMER)
return 0;
//Set Mob's ANGRY/BERSERK states.
@@ -1391,7 +1392,7 @@ int unit_attack(struct block_list *src,int target_id,int continuous)
//Do attack next time it is possible. [Skotlex]
ud->attacktimer=add_timer(ud->attackabletime,unit_attack_timer,src->id,0);
else //Attack NOW.
- unit_attack_timer(-1,gettick(),src->id,0);
+ unit_attack_timer(INVALID_TIMER, gettick(), src->id, 0);
return 0;
}
@@ -1402,7 +1403,7 @@ int unit_cancel_combo(struct block_list *bl)
{
struct unit_data *ud;
- if (!status_change_end(bl, SC_COMBO, -1))
+ if (!status_change_end(bl, SC_COMBO, INVALID_TIMER))
return 0; //Combo wasn't active.
ud = unit_bl2ud(bl);
@@ -1410,7 +1411,7 @@ int unit_cancel_combo(struct block_list *bl)
ud->attackabletime = gettick() + status_get_amotion(bl);
- if (ud->attacktimer == -1)
+ if (ud->attacktimer == INVALID_TIMER)
return 1; //Nothing more to do.
delete_timer(ud->attacktimer, unit_attack_timer);
@@ -1563,12 +1564,12 @@ static int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int t
return 0;
}
- if( ud->skilltimer != -1 && !(sd && pc_checkskill(sd,SA_FREECAST) > 0) )
+ if( ud->skilltimer != INVALID_TIMER && !(sd && pc_checkskill(sd,SA_FREECAST) > 0) )
return 0; // can't attack while casting
if( !battle_config.sdelay_attack_enable && DIFF_TICK(ud->canact_tick,tick) > 0 && !(sd && pc_checkskill(sd,SA_FREECAST) > 0) )
{ // attacking when under cast delay has restrictions:
- if( tid == -1 )
+ if( tid == INVALID_TIMER )
{ //requested attack.
if(sd) clif_skill_fail(sd,1,4,0);
return 0;
@@ -1612,14 +1613,14 @@ static int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int t
//Sync packet only for players.
//Non-players use the sync packet on the walk timer. [Skotlex]
- if (tid == -1 && sd) clif_fixpos(src);
+ if (tid == INVALID_TIMER && sd) clif_fixpos(src);
if( DIFF_TICK(ud->attackabletime,tick) <= 0 )
{
if (battle_config.attack_direction_change && (src->type&battle_config.attack_direction_change)) {
ud->dir = map_calc_dir(src, target->x,target->y );
}
- if(ud->walktimer != -1)
+ if(ud->walktimer != INVALID_TIMER)
unit_stop_walking(src,1);
if(md) {
if (mobskill_use(md,tick,-1))
@@ -1674,7 +1675,7 @@ int unit_skillcastcancel(struct block_list *bl,int type)
int ret=0, skill;
nullpo_ret(bl);
- if (!ud || ud->skilltimer==-1)
+ if (!ud || ud->skilltimer == INVALID_TIMER)
return 0; //Nothing to cancel.
sd = BL_CAST(BL_PC, bl);
@@ -1732,9 +1733,9 @@ void unit_dataset(struct block_list *bl)
memset( ud, 0, sizeof( struct unit_data) );
ud->bl = bl;
- ud->walktimer = -1;
- ud->skilltimer = -1;
- ud->attacktimer = -1;
+ ud->walktimer = INVALID_TIMER;
+ ud->skilltimer = INVALID_TIMER;
+ ud->attacktimer = INVALID_TIMER;
ud->attackabletime =
ud->canact_tick =
ud->canmove_tick = gettick();
@@ -1754,7 +1755,7 @@ static int unit_counttargeted_sub(struct block_list* bl, va_list ap)
ud = unit_bl2ud(bl);
- if (ud && ud->target == id && ud->attacktimer != -1 && ud->attacktarget_lv >= target_lv)
+ if (ud && ud->target == id && ud->attacktimer != INVALID_TIMER && ud->attacktarget_lv >= target_lv)
return 1;
return 0;
@@ -1821,36 +1822,36 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file,
map_freeblock_lock();
ud->target = 0; //Unlock walk/attack target.
- if (ud->walktimer != -1)
+ if (ud->walktimer != INVALID_TIMER)
unit_stop_walking(bl,0);
- if (ud->attacktimer != -1)
+ if (ud->attacktimer != INVALID_TIMER)
unit_stop_attack(bl);
- if (ud->skilltimer != -1)
+ if (ud->skilltimer != INVALID_TIMER)
unit_skillcastcancel(bl,0);
// Do not reset can-act delay. [Skotlex]
ud->attackabletime = ud->canmove_tick /*= ud->canact_tick*/ = gettick();
if(sc && sc->count ) { //map-change/warp dispells.
- status_change_end(bl,SC_BLADESTOP,-1);
- status_change_end(bl,SC_BASILICA,-1);
- status_change_end(bl,SC_ANKLE,-1);
- status_change_end(bl,SC_TRICKDEAD,-1);
- status_change_end(bl,SC_BLADESTOP_WAIT,-1);
- status_change_end(bl,SC_RUN,-1);
- status_change_end(bl,SC_DANCING,-1);
- status_change_end(bl,SC_WARM,-1);
- status_change_end(bl,SC_DEVOTION,-1);
- status_change_end(bl,SC_MARIONETTE,-1);
- status_change_end(bl,SC_MARIONETTE2,-1);
- status_change_end(bl,SC_CLOSECONFINE,-1);
- status_change_end(bl,SC_CLOSECONFINE2,-1);
- status_change_end(bl,SC_HIDING,-1);
- status_change_end(bl,SC_CLOAKING,-1);
- status_change_end(bl,SC_CHASEWALK,-1);
+ status_change_end(bl, SC_BLADESTOP, INVALID_TIMER);
+ status_change_end(bl, SC_BASILICA, INVALID_TIMER);
+ status_change_end(bl, SC_ANKLE, INVALID_TIMER);
+ status_change_end(bl, SC_TRICKDEAD, INVALID_TIMER);
+ status_change_end(bl, SC_BLADESTOP_WAIT, INVALID_TIMER);
+ status_change_end(bl, SC_RUN, INVALID_TIMER);
+ status_change_end(bl, SC_DANCING, INVALID_TIMER);
+ status_change_end(bl, SC_WARM, INVALID_TIMER);
+ status_change_end(bl, SC_DEVOTION, INVALID_TIMER);
+ status_change_end(bl, SC_MARIONETTE, INVALID_TIMER);
+ status_change_end(bl, SC_MARIONETTE2, INVALID_TIMER);
+ status_change_end(bl, SC_CLOSECONFINE, INVALID_TIMER);
+ status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER);
+ status_change_end(bl, SC_HIDING, INVALID_TIMER);
+ status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
+ status_change_end(bl, SC_CHASEWALK, INVALID_TIMER);
if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF)
- status_change_end(bl,SC_GOSPEL,-1);
- status_change_end(bl,SC_CHANGE,-1);
- status_change_end(bl,SC_STOP,-1);
+ status_change_end(bl, SC_GOSPEL, INVALID_TIMER);
+ status_change_end(bl, SC_CHANGE, INVALID_TIMER);
+ status_change_end(bl, SC_STOP, INVALID_TIMER);
}
if (bl->type&BL_CHAR) {
@@ -1890,7 +1891,7 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file,
sd->npc_shopid = 0;
sd->adopt_invite = 0;
- if(sd->pvp_timer!=-1) {
+ if(sd->pvp_timer != INVALID_TIMER) {
delete_timer(sd->pvp_timer,pc_calc_pvprank_timer);
sd->pvp_timer = INVALID_TIMER;
sd->pvp_rank = 0;
@@ -2052,7 +2053,7 @@ int unit_free(struct block_list *bl, clr_type clrtype)
pc_delautobonus(sd,sd->autobonus2,ARRAYLENGTH(sd->autobonus2),false);
pc_delautobonus(sd,sd->autobonus3,ARRAYLENGTH(sd->autobonus3),false);
- if( sd->followtimer != -1 )
+ if( sd->followtimer != INVALID_TIMER )
pc_stop_following(sd);
if( sd->duel_invite > 0 )
@@ -2103,7 +2104,7 @@ int unit_free(struct block_list *bl, clr_type clrtype)
}
if( pd->s_skill )
{
- if (pd->s_skill->timer != -1) {
+ if (pd->s_skill->timer != INVALID_TIMER) {
if (pd->s_skill->id)
delete_timer(pd->s_skill->timer, pet_skill_support_timer);
else
@@ -2114,14 +2115,14 @@ int unit_free(struct block_list *bl, clr_type clrtype)
}
if( pd->recovery )
{
- if(pd->recovery->timer != -1)
+ if(pd->recovery->timer != INVALID_TIMER)
delete_timer(pd->recovery->timer, pet_recovery_timer);
aFree(pd->recovery);
pd->recovery = NULL;
}
if( pd->bonus )
{
- if (pd->bonus->timer != -1)
+ if (pd->bonus->timer != INVALID_TIMER)
delete_timer(pd->bonus->timer, pet_skill_bonus_timer);
aFree(pd->bonus);
pd->bonus = NULL;
diff --git a/src/map/vending.c b/src/map/vending.c
index 90bff7399..a47be9057 100644
--- a/src/map/vending.c
+++ b/src/map/vending.c
@@ -19,6 +19,18 @@
#include <stdio.h>
#include <string.h>
+static int vending_nextid = 1;
+
+/// Returns an unique vending shop id.
+static int vending_getuid(void)
+{
+ if(!vending_nextid)
+ {// wrapped around, 0 is reserved for "not vending" state on eathena
+ vending_nextid = 1;
+ }
+
+ return vending_nextid++;
+}
/*==========================================
* Close shop
@@ -50,13 +62,15 @@ void vending_vendinglistreq(struct map_session_data* sd, int id)
return;
}
+ sd->vended_id = vsd->vender_id; // register vending uid
+
clif_vendinglist(sd, id, vsd->vending);
}
/*==========================================
* Purchase item(s) from a shop
*------------------------------------------*/
-void vending_purchasereq(struct map_session_data* sd, int aid, int cid, const uint8* data, int count)
+void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const uint8* data, int count)
{
int i, j, cursor, w, new_ = 0, blank, vend_list[MAX_VENDING];
double z;
@@ -64,12 +78,15 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int cid, const ui
struct map_session_data* vsd = map_id2sd(aid);
nullpo_retv(sd);
- if( vsd == NULL || vsd->vender_id == 0 || vsd->vender_id == sd->bl.id )
+ if( vsd == NULL || vsd->vender_id == 0 || vsd->bl.id == sd->bl.id )
return; // invalid shop
-#if PACKETVER >= 20100105
- if( vsd->status.char_id != cid )
- return; //Char-ID check
-#endif
+
+ if( vsd->vender_id != uid )
+ {// shop has changed
+ clif_buyvending(sd, 0, 0, 6); // store information was incorrect
+ return;
+ }
+
if( sd->bl.m != vsd->bl.m || !check_distance_bl(&sd->bl, &vsd->bl, AREA_SIZE) )
return; // shop too far away
if( count < 1 || count > MAX_VENDING || count > vsd->vend_num )
@@ -289,11 +306,11 @@ void vending_openvending(struct map_session_data* sd, const char* message, bool
return;
}
- sd->vender_id = sd->bl.id;
+ sd->vender_id = vending_getuid();
sd->vend_num = i;
safestrncpy(sd->message, message, MESSAGE_SIZE);
pc_stop_walking(sd,1);
- clif_openvending(sd,sd->vender_id,sd->vending);
+ clif_openvending(sd,sd->bl.id,sd->vending);
clif_showvendingboard(&sd->bl,message,0);
}
diff --git a/src/map/vending.h b/src/map/vending.h
index 9748b675a..3c483a38c 100644
--- a/src/map/vending.h
+++ b/src/map/vending.h
@@ -17,6 +17,6 @@ struct s_vending {
void vending_closevending(struct map_session_data* sd);
void vending_openvending(struct map_session_data* sd, const char* message, bool flag, const uint8* data, int count);
void vending_vendinglistreq(struct map_session_data* sd, int id);
-void vending_purchasereq(struct map_session_data* sd, int aid, int cid, const uint8* data, int count);
+void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const uint8* data, int count);
#endif /* _VENDING_H_ */
diff --git a/src/plugins/Makefile.in b/src/plugins/Makefile.in
index a16083981..fa74ff90d 100644
--- a/src/plugins/Makefile.in
+++ b/src/plugins/Makefile.in
@@ -5,7 +5,7 @@ COMMON_H = ../common/plugin.h ../common/cbasetypes.h \
../common/showmsg.h ../common/utils.h ../common/strlib.h \
../common/malloc.h
-PLUGINS = sample sig pid gui console
+PLUGINS = sample sig pid console
@SET_MAKE@
@@ -20,8 +20,6 @@ sig: sig@DLLEXT@
pid: pid@DLLEXT@
-gui: gui@DLLEXT@
-
console: console@DLLEXT@
clean:
@@ -32,7 +30,6 @@ help:
@echo "'sample' - sample plugin"
@echo "'sig' - signal handler plugin"
@echo "'pid' - process id plugin"
- @echo "'gui' - gui plugin"
@echo "'console' - console plugin"
@echo "'all' - builds all above targets"
@echo "'clean' - cleans builds and objects"
@@ -43,14 +40,9 @@ help:
%@DLLEXT@: %.c
@CC@ @CFLAGS@ @CPPFLAGS@ @LDFLAGS@ -shared -o ../../plugins/$@ $<
-gui@DLLEXT@: ../../plugins/gui.conf
-
sig@DLLEXT@: sig.c $(COMMON_OBJ)
@CC@ @CFLAGS@ @CPPFLAGS@ @LDFLAGS@ -shared -o ../../plugins/$@ $< $(COMMON_OBJ)
-../../plugins/%.conf: %.txt
- cp -r $< $@
-
# missing common object files
../common/obj_all/%.o: ../common/%.c $(COMMON_H)
@$(MAKE) -C ../common txt
diff --git a/src/plugins/console.c b/src/plugins/console.c
index 5056eafdc..b1307f863 100644
--- a/src/plugins/console.c
+++ b/src/plugins/console.c
@@ -32,7 +32,8 @@
#define WORKER_FUNC_END(name) } ExitThread(0); return 0; }
#define WORKER_EXECUTE(name,errvar) \
do{ \
- buf.worker = CreateThread(NULL, 0, worker_ ## name, NULL, CREATE_SUSPENDED, NULL); \
+ DWORD dwThreadId; \
+ buf.worker = CreateThread(NULL, 0, worker_ ## name, NULL, CREATE_SUSPENDED, &dwThreadId); \
if( errvar ) \
*errvar = ( buf.worker == NULL ); \
}while(0)
@@ -132,10 +133,10 @@ int (*add_timer_func_list)(TimerFunc func, char* name);
int (*add_timer_interval)(unsigned int tick, TimerFunc func, int id, intptr data, int interval);
int (*delete_timer)(int tid, TimerFunc func);
unsigned int (*gettick)(void);
-int (*parse_console)(char* buf);
+int (*parse_console)(const char* buf);
// Locals
-int tid; // timer id
+int tid = -1; // timer id
BUFFER buf; // input buffer
WORKER_FUNC_DECLARE(getinput); // worker for the input buffer
diff --git a/src/plugins/gui.c b/src/plugins/gui.c
deleted file mode 100644
index f45345341..000000000
--- a/src/plugins/gui.c
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "../common/plugin.h"
-//Needed for strcmpi
-#include "../common/mmo.h"
-
-// "I'm Alive" and "Flush stdout" Originally by Mugendai
-// Ported to plugin by Celest
-
-PLUGIN_INFO = {
- "AthenaGUI",
- PLUGIN_CORE,
- "1.0",
- PLUGIN_VERSION,
- "Core plugin for Athena GUI functions"
-};
-
-PLUGIN_EVENTS_TABLE = {
- { "gui_init", "Plugin_Init" },
- { NULL, NULL }
-};
-
-typedef int (*TimerFunc)(int tid, unsigned int tick, int id, intptr data);
-unsigned int (*gettick)();
-int (*add_timer_func_list)(TimerFunc func, char* name);
-int (*add_timer_interval)(unsigned int tick, TimerFunc func, int id, intptr data, int interval);
-
-//-----------------------------------------------------
-//I'm Alive Alert
-//Used to output 'I'm Alive' every few seconds
-//Intended to let frontends know if the app froze
-//-----------------------------------------------------
-int imalive_timer(int tid, unsigned int tick, int id, intptr data)
-{
- printf("I'm Alive\n");
- return 0;
-}
-
-//-----------------------------------------------------
-//Flush stdout
-//stdout buffer needs flushed to be seen in GUI
-//-----------------------------------------------------
-int flush_timer(int tid, unsigned int tick, int id, intptr data)
-{
- fflush(stdout);
- return 0;
-}
-
-void gui_init ()
-{
- char line[1024], w1[1024], w2[1024];
- int flush_on = 0;
- int flush_time = 100;
- int imalive_on = 0;
- int imalive_time = 30;
- char **argv;
- int *argc;
- FILE *fp;
- int i;
-
- IMPORT_SYMBOL(argc, 2);
- IMPORT_SYMBOL(argv, 3);
- IMPORT_SYMBOL(gettick, 5);
- IMPORT_SYMBOL(add_timer_interval, 8);
- IMPORT_SYMBOL(add_timer_func_list, 9);
-
- do {
- fp = fopen("plugins/gui.conf","r");
- if (fp == NULL)
- break;
-
- while(fgets(line, sizeof(line), fp))
- {
- if (line[0] == '/' && line[1] == '/')
- continue;
- if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) == 2) {
- if(strcmpi(w1,"imalive_on")==0){
- imalive_on = atoi(w2);
- } else if(strcmpi(w1,"imalive_time")==0){
- imalive_time = atoi(w2);
- } else if(strcmpi(w1,"flush_on")==0){
- flush_on = atoi(w2);
- } else if(strcmpi(w1,"flush_time")==0){
- flush_time = atoi(w2);
- }
- }
- }
- fclose(fp);
- } while (0);
-
- for (i = 1; i < *argc ; i++)
- if (strcmp(argv[i], "--gui") == 0)
- flush_on = imalive_on = 1;
-
- if (flush_on) {
- add_timer_func_list(flush_timer, "flush_timer");
- add_timer_interval(gettick()+1000,flush_timer,0,0,flush_time);
- }
- if (imalive_on) {
- add_timer_func_list(imalive_timer, "imalive_timer");
- add_timer_interval(gettick()+10, imalive_timer,0,0,imalive_time*1000);
- }
-}
diff --git a/src/plugins/gui.txt b/src/plugins/gui.txt
deleted file mode 100644
index c71b684b6..000000000
--- a/src/plugins/gui.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// GUI Plugin Configuration
-//
-
-// Enable I'm Alive?
-imalive_on: 0
-
-// How often to display I'm Alive (in seconds)
-imalive_time: 30
-
-// Enable GUI flushing for Mugendai's GUI?
-flush_on: 0
-
-// How often to flush the buffer on-screen (in seconds)
-flush_time: 60
diff --git a/src/plugins/plugin.def b/src/plugins/pid.def
index 6117bedc6..a70cf8127 100644
--- a/src/plugins/plugin.def
+++ b/src/plugins/pid.def
@@ -2,3 +2,6 @@ EXPORTS
plugin_info DATA
plugin_event_table DATA
plugin_call_table DATA
+
+ pid_create
+ pid_delete
diff --git a/src/plugins/sample.def b/src/plugins/sample.def
new file mode 100644
index 000000000..f5c4af652
--- /dev/null
+++ b/src/plugins/sample.def
@@ -0,0 +1,11 @@
+EXPORTS
+ ; common exports
+ plugin_info DATA
+ plugin_event_table DATA
+ plugin_call_table DATA
+
+ ; plugin-specific exports
+ test_me
+ do_init
+ do_final
+ some_function
diff --git a/src/tool/Makefile.in b/src/tool/Makefile.in
index 78300a68c..06813f843 100644
--- a/src/tool/Makefile.in
+++ b/src/tool/Makefile.in
@@ -1,26 +1,44 @@
+COMMON_OBJ = ../common/obj_all/minicore.o ../common/obj_all/malloc.o \
+ ../common/obj_all/showmsg.o ../common/obj_all/strlib.o \
+ ../common/obj_all/utils.o ../common/obj_all/grfio.o
+COMMON_H = ../common/core.h ../common/mmo.h ../common/version.h \
+ ../common/malloc.h ../common/showmsg.h ../common/strlib.h \
+ ../common/utils.h ../common/cbasetypes.h ../common/grfio.h
+
+MAPCACHE_OBJ = obj_all/mapcache.o
+
@SET_MAKE@
#####################################################################
-.PHONY : all adduser mapcache clean help
+.PHONY : all mapcache clean help
-all: adduser mapcache
+all: mapcache
-adduser:
- @CC@ -o ../../tools/adduser@EXEEXT@ adduser.c
-
-mapcache:
- @CC@ -o ../../mapcache@EXEEXT@ mapcache.c grfio.c -lz
+mapcache: obj_all $(MAPCACHE_OBJ) $(COMMON_OBJ)
+ @CC@ @LDFLAGS@ -o ../../mapcache@EXEEXT@ $(MAPCACHE_OBJ) $(COMMON_OBJ) @LIBS@
clean:
- rm -rf *.o ../../tools/adduser@EXEEXT@ ../../mapcache@EXEEXT@
+ rm -rf obj_all/*.o ../../mapcache@EXEEXT@
help:
- @echo "possible targets are 'adduser' 'mapcache' 'all' 'clean' 'help'"
- @echo "'adduser' - ???"
+ @echo "possible targets are 'mapcache' 'all' 'clean' 'help'"
@echo "'mapcache' - mapcache generator"
@echo "'all' - builds all above targets"
@echo "'clean' - cleans builds and objects"
@echo "'help' - outputs this message"
#####################################################################
+
+obj_all:
+ -mkdir obj_all
+
+obj_all/%.o: %.c $(COMMON_H)
+ @CC@ @CFLAGS@ @LDFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
+
+# missing common object files
+../common/obj_all/%.o:
+ @$(MAKE) -C ../common txt
+
+../common/obj_all/mini%.o:
+ @$(MAKE) -C ../common txt
diff --git a/src/tool/adduser.c b/src/tool/adduser.c
deleted file mode 100644
index 5f4dfb6a5..000000000
--- a/src/tool/adduser.c
+++ /dev/null
@@ -1,103 +0,0 @@
-// (c) eAthena Dev Team - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
-
-/*
- This program adds an user to account.txt
- Don't usr it When login-sever is working.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-char *account_txt = "../save/account.txt";
-
-//-----------------------------------------------------
-// Function to suppress control characters in a string.
-//-----------------------------------------------------
-int remove_control_chars(char* str)
-{
- int i;
- int change = 0;
-
- for(i = 0; str[i]; i++) {
- if (iscntrl((unsigned char)(str[i]))) {
- str[i] = '_';
- change = 1;
- }
- }
-
- return change;
-}
-
-int main(int argc, char *argv[])
-{
- char username[24];
- char password[24];
- char sex[2];
-
- int next_id, id;
- char line[1024];
- FILE *FPaccin,*FPaccout;
-
- // Check to see if account.txt exists.
- printf("Checking if '%s' file exists...\n", account_txt);
- FPaccin = fopen(account_txt, "r");
- if (FPaccin == NULL) {
- printf("'%s' file not found!\n", account_txt);
- printf("Run the setup wizard please.\n");
- exit(EXIT_SUCCESS);
- }
-
- next_id = 2000000;
- while(fgets(line, sizeof(line), FPaccin))
- {
- if (line[0] == '/' && line[1] == '/') { continue; }
- if (sscanf(line, "%d\t%%newid%%\n", &id) == 1) {
- if (next_id < id) {
- next_id = id;
- }
- } else {
- sscanf(line,"%i%[^ ]", &id);
- if (next_id <= id) {
- next_id = id +1;
- }
- }
- }
- fclose(FPaccin);
- printf("File exists.\n");
-
- printf("Don't create an account if the login-server is online!!!\n");
- printf("If the login-server is online, press ctrl+C now to stop this software.\n");
- printf("\n");
-
- strcpy(username, "");
- while (strlen(username) < 4 || strlen(username) > 23) {
- printf("Enter an username (4-23 characters): ");
- scanf("%s", username);
- username[23] = 0;
- remove_control_chars(username);
- }
-
- strcpy(password, "");
- while (strlen(password) < 4 || strlen(password) > 23) {
- printf("Enter a password (4-23 characters): ");
- scanf("%s", password);
- password[23] = 0;
- remove_control_chars(password);
- }
-
- strcpy(sex, "");
- while (strcmp(sex, "F") != 0 && strcmp(sex, "M") != 0) {
- printf("Enter a gender (M for male, F for female): ");
- scanf("%s", sex);
- }
-
- FPaccout = fopen(account_txt, "r+");
- fseek(FPaccout, 0, SEEK_END);
- fprintf(FPaccout, "%i %s %s - %s -\r\n", next_id, username, password, sex);
- fclose(FPaccout);
-
- printf("Account added.\n");
-}
diff --git a/src/tool/grfio.c b/src/tool/grfio.c
deleted file mode 100644
index 26cfb636f..000000000
--- a/src/tool/grfio.c
+++ /dev/null
@@ -1,844 +0,0 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <ctype.h> // tolower()
-
-#include "grfio.h"
-#include <zlib.h>
-
-
-#ifndef __WIN32
- #define strcmpi strcasecmp
-#endif
-
-
-//----------------------------
-// file entry table struct
-//----------------------------
-typedef struct _FILELIST {
- int srclen; // compressed size
- int srclen_aligned;
- int declen; // original size
- int srcpos; // position of entry in grf
- int next; // index of next filelist entry with same hash (-1: end of entry chain)
- int cycle;
- char type;
- char fn[128-4*5]; // file name
- char* fnd; // if the file was cloned, contains name of original file
- char gentry; // read grf file select
-} FILELIST;
-
-//gentry ... > 0 : data read from a grf file (gentry_table[gentry-1])
-//gentry ... 0 : data read from a local file (data directory)
-//gentry ... < 0 : entry "-(gentry)" is marked for a local file check
-// - if local file exists, gentry will be set to 0 (thus using the local file)
-// - if local file doesn't exist, sign is inverted (thus using the original file inside a grf)
-// (NOTE: this case is only used once (during startup) and only if GRFIO_LOCAL is enabled)
-// (NOTE: probably meant to be used to override grf contents by files in the data directory)
-//#define GRFIO_LOCAL
-
-// stores info about every loaded file
-FILELIST* filelist = NULL;
-int filelist_entrys = 0;
-int filelist_maxentry = 0;
-
-// stores grf file names
-char** gentry_table = NULL;
-int gentry_entrys = 0;
-int gentry_maxentry = 0;
-
-// the path to the data directory
-char data_dir[1024] = "";
-
-//----------------------------
-// file list hash table
-//----------------------------
-int filelist_hash[256];
-
-//----------------------------
-// grf decode data table
-//----------------------------
-static unsigned char BitMaskTable[8] = {
- 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
-};
-
-static char BitSwapTable1[64] = {
- 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
- 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
- 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
- 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
-};
-static char BitSwapTable2[64] = {
- 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
- 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
- 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
- 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25
-};
-static char BitSwapTable3[32] = {
- 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
- 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
-};
-
-static unsigned char NibbleData[4][64]={
- {
- 0xef, 0x03, 0x41, 0xfd, 0xd8, 0x74, 0x1e, 0x47, 0x26, 0xef, 0xfb, 0x22, 0xb3, 0xd8, 0x84, 0x1e,
- 0x39, 0xac, 0xa7, 0x60, 0x62, 0xc1, 0xcd, 0xba, 0x5c, 0x96, 0x90, 0x59, 0x05, 0x3b, 0x7a, 0x85,
- 0x40, 0xfd, 0x1e, 0xc8, 0xe7, 0x8a, 0x8b, 0x21, 0xda, 0x43, 0x64, 0x9f, 0x2d, 0x14, 0xb1, 0x72,
- 0xf5, 0x5b, 0xc8, 0xb6, 0x9c, 0x37, 0x76, 0xec, 0x39, 0xa0, 0xa3, 0x05, 0x52, 0x6e, 0x0f, 0xd9,
- }, {
- 0xa7, 0xdd, 0x0d, 0x78, 0x9e, 0x0b, 0xe3, 0x95, 0x60, 0x36, 0x36, 0x4f, 0xf9, 0x60, 0x5a, 0xa3,
- 0x11, 0x24, 0xd2, 0x87, 0xc8, 0x52, 0x75, 0xec, 0xbb, 0xc1, 0x4c, 0xba, 0x24, 0xfe, 0x8f, 0x19,
- 0xda, 0x13, 0x66, 0xaf, 0x49, 0xd0, 0x90, 0x06, 0x8c, 0x6a, 0xfb, 0x91, 0x37, 0x8d, 0x0d, 0x78,
- 0xbf, 0x49, 0x11, 0xf4, 0x23, 0xe5, 0xce, 0x3b, 0x55, 0xbc, 0xa2, 0x57, 0xe8, 0x22, 0x74, 0xce,
- }, {
- 0x2c, 0xea, 0xc1, 0xbf, 0x4a, 0x24, 0x1f, 0xc2, 0x79, 0x47, 0xa2, 0x7c, 0xb6, 0xd9, 0x68, 0x15,
- 0x80, 0x56, 0x5d, 0x01, 0x33, 0xfd, 0xf4, 0xae, 0xde, 0x30, 0x07, 0x9b, 0xe5, 0x83, 0x9b, 0x68,
- 0x49, 0xb4, 0x2e, 0x83, 0x1f, 0xc2, 0xb5, 0x7c, 0xa2, 0x19, 0xd8, 0xe5, 0x7c, 0x2f, 0x83, 0xda,
- 0xf7, 0x6b, 0x90, 0xfe, 0xc4, 0x01, 0x5a, 0x97, 0x61, 0xa6, 0x3d, 0x40, 0x0b, 0x58, 0xe6, 0x3d,
- }, {
- 0x4d, 0xd1, 0xb2, 0x0f, 0x28, 0xbd, 0xe4, 0x78, 0xf6, 0x4a, 0x0f, 0x93, 0x8b, 0x17, 0xd1, 0xa4,
- 0x3a, 0xec, 0xc9, 0x35, 0x93, 0x56, 0x7e, 0xcb, 0x55, 0x20, 0xa0, 0xfe, 0x6c, 0x89, 0x17, 0x62,
- 0x17, 0x62, 0x4b, 0xb1, 0xb4, 0xde, 0xd1, 0x87, 0xc9, 0x14, 0x3c, 0x4a, 0x7e, 0xa8, 0xe2, 0x7d,
- 0xa0, 0x9f, 0xf6, 0x5c, 0x6a, 0x09, 0x8d, 0xf0, 0x0f, 0xe3, 0x53, 0x25, 0x95, 0x36, 0x28, 0xcb,
- }
-};
-
-// little endian char array to uint conversion
-static unsigned int getlong(unsigned char* p)
-{
- return (p[0] | p[1] << 0x08 | p[2] << 0x10 | p[3] << 0x18);
-}
-
-/*==========================================
- * Grf data decode : Subs
- *------------------------------------------*/
-static void NibbleSwap(unsigned char* Src, int len)
-{
- for(;0<len;len--,Src++) {
- *Src = (*Src>>4) | (*Src<<4);
- }
-}
-
-static void BitConvert(unsigned char* Src, char* BitSwapTable)
-{
- int lop,prm;
- unsigned char tmp[8];
- memset(tmp,0,8);
- for(lop=0;lop!=64;lop++) {
- prm = BitSwapTable[lop]-1;
- if (Src[(prm >> 3) & 7] & BitMaskTable[prm & 7]) {
- tmp[(lop >> 3) & 7] |= BitMaskTable[lop & 7];
- }
- }
- memcpy(Src,tmp,8);
-}
-
-static void BitConvert4(unsigned char* Src)
-{
- int lop,prm;
- unsigned char tmp[8];
- tmp[0] = ((Src[7]<<5) | (Src[4]>>3)) & 0x3f; // ..0 vutsr
- tmp[1] = ((Src[4]<<1) | (Src[5]>>7)) & 0x3f; // ..srqpo n
- tmp[2] = ((Src[4]<<5) | (Src[5]>>3)) & 0x3f; // ..o nmlkj
- tmp[3] = ((Src[5]<<1) | (Src[6]>>7)) & 0x3f; // ..kjihg f
- tmp[4] = ((Src[5]<<5) | (Src[6]>>3)) & 0x3f; // ..g fedcb
- tmp[5] = ((Src[6]<<1) | (Src[7]>>7)) & 0x3f; // ..cba98 7
- tmp[6] = ((Src[6]<<5) | (Src[7]>>3)) & 0x3f; // ..8 76543
- tmp[7] = ((Src[7]<<1) | (Src[4]>>7)) & 0x3f; // ..43210 v
-
- for(lop=0;lop!=4;lop++) {
- tmp[lop] = (NibbleData[lop][tmp[lop*2]] & 0xf0)
- | (NibbleData[lop][tmp[lop*2+1]] & 0x0f);
- }
-
- memset(tmp+4,0,4);
- for(lop=0;lop!=32;lop++) {
- prm = BitSwapTable3[lop]-1;
- if (tmp[prm >> 3] & BitMaskTable[prm & 7]) {
- tmp[(lop >> 3) + 4] |= BitMaskTable[lop & 7];
- }
- }
- Src[0] ^= tmp[4];
- Src[1] ^= tmp[5];
- Src[2] ^= tmp[6];
- Src[3] ^= tmp[7];
-}
-
-static void decode_des_etc(unsigned char* buf, size_t len, int type, int cycle)
-{
- size_t lop,cnt=0;
- if(cycle<3) cycle=3;
- else if(cycle<5) cycle++;
- else if(cycle<7) cycle+=9;
- else cycle+=15;
-
- for(lop=0; lop*8<len; lop++, buf+=8)
- {
- if(lop<20 || (type==0 && lop%cycle==0)) { // des
- BitConvert(buf,BitSwapTable1);
- BitConvert4(buf);
- BitConvert(buf,BitSwapTable2);
- } else {
- if(cnt==7 && type==0) {
- unsigned char a;
- unsigned char tmp[8];
- memcpy(tmp,buf,8);
- cnt=0;
- buf[0]=tmp[3];
- buf[1]=tmp[4];
- buf[2]=tmp[6];
- buf[3]=tmp[0];
- buf[4]=tmp[1];
- buf[5]=tmp[2];
- buf[6]=tmp[5];
- a=tmp[7];
- if(a==0x00) a=0x2b;
- else if(a==0x2b) a=0x00;
- else if(a==0x01) a=0x68;
- else if(a==0x68) a=0x01;
- else if(a==0x48) a=0x77;
- else if(a==0x77) a=0x48;
- else if(a==0x60) a=0xff;
- else if(a==0xff) a=0x60;
- else if(a==0x6c) a=0x80;
- else if(a==0x80) a=0x6c;
- else if(a==0xb9) a=0xc0;
- else if(a==0xc0) a=0xb9;
- else if(a==0xeb) a=0xfe;
- else if(a==0xfe) a=0xeb;
- buf[7]=a;
- }
- cnt++;
- }
- }
-}
-/*==========================================
- * Grf data decode sub : zip
- *------------------------------------------*/
-int decode_zip(unsigned char* dest, unsigned long* destLen, const unsigned char* source, unsigned long sourceLen)
-{
- z_stream stream;
- int err;
-
- stream.next_in = (Bytef*)source;
- stream.avail_in = (uInt)sourceLen;
- /* Check for source > 64K on 16-bit machine: */
- if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
-
- stream.next_out = (Bytef*) dest;
- stream.avail_out = (uInt)*destLen;
- if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
-
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
-
- err = inflateInit(&stream);
- if (err != Z_OK) return err;
-
- err = inflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- inflateEnd(&stream);
- return err == Z_OK ? Z_BUF_ERROR : err;
- }
- *destLen = stream.total_out;
-
- err = inflateEnd(&stream);
- return err;
-}
-
-int encode_zip(unsigned char* dest, unsigned long* destLen, const unsigned char* source, unsigned long sourceLen)
-{
- z_stream stream;
- int err;
- memset(&stream, 0, sizeof(stream));
- stream.next_in = (Bytef*)source;
- stream.avail_in = (uInt)sourceLen;
- /* Check for source > 64K on 16-bit machine: */
- if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
-
- stream.next_out = (Bytef*) dest;
- stream.avail_out = (uInt)*destLen;
- if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
-
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
-
- err = deflateInit(&stream,Z_DEFAULT_COMPRESSION);
- if (err != Z_OK) return err;
-
- err = deflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- inflateEnd(&stream);
- return err == Z_OK ? Z_BUF_ERROR : err;
- }
- *destLen = stream.total_out;
-
- err = deflateEnd(&stream);
- return err;
-}
-
-unsigned long grfio_crc32 (const unsigned char* buf, unsigned int len)
-{
- return crc32(crc32(0L, Z_NULL, 0), buf, len);
-}
-
-/***********************************************************
- *** File List Subroutines ***
- ***********************************************************/
-
-// initializes the table that holds the first elements of all hash chains
-static void hashinit(void)
-{
- int i;
- for (i = 0; i < 256; i++)
- filelist_hash[i] = -1;
-}
-
-// hashes a filename string into a number from {0..255}
-static int filehash(char* fname)
-{
- unsigned int hash = 0;
- while(*fname) {
- hash = ((hash<<1) + (hash>>7)*9 + (unsigned int)tolower((unsigned char)(*fname)));
- fname++;
- }
- return hash & 255;
-}
-
-// finds a FILELIST entry with the specified file name
-static FILELIST* filelist_find(char* fname)
-{
- int hash, index;
-
- if (!filelist)
- return NULL;
-
- hash = filelist_hash[filehash(fname)];
- for (index = hash; index != -1; index = filelist[index].next)
- if(!strcmpi(filelist[index].fn, fname))
- break;
-
- return (index >= 0) ? &filelist[index] : NULL;
-}
-
-// returns the original file name
-/*
-char* grfio_find_file(char* fname)
-{
- FILELIST *filelist = filelist_find(fname);
- if (!filelist) return NULL;
- return (!filelist->fnd ? filelist->fn : filelist->fnd);
-}
-*/
-
-// adds a FILELIST entry into the list of loaded files
-static FILELIST* filelist_add(FILELIST* entry)
-{
- int hash;
-
- #define FILELIST_ADDS 1024 // number increment of file lists `
-
- if (filelist_entrys >= filelist_maxentry) {
- filelist = (FILELIST *)realloc(filelist, (filelist_maxentry + FILELIST_ADDS) * sizeof(FILELIST));
- memset(filelist + filelist_maxentry, '\0', FILELIST_ADDS * sizeof(FILELIST));
- filelist_maxentry += FILELIST_ADDS;
- }
-
- memcpy (&filelist[filelist_entrys], entry, sizeof(FILELIST));
-
- hash = filehash(entry->fn);
- filelist[filelist_entrys].next = filelist_hash[hash];
- filelist_hash[hash] = filelist_entrys;
-
- filelist_entrys++;
-
- return &filelist[filelist_entrys - 1];
-}
-
-// adds a new FILELIST entry or overwrites an existing one
-static FILELIST* filelist_modify(FILELIST* entry)
-{
- FILELIST* fentry = filelist_find(entry->fn);
- if (fentry != NULL) {
- int tmp = fentry->next;
- memcpy(fentry, entry, sizeof(FILELIST));
- fentry->next = tmp;
- } else {
- fentry = filelist_add(entry);
- }
- return fentry;
-}
-
-// shrinks the file list array if too long
-static void filelist_adjust(void)
-{
- if (filelist == NULL)
- return;
-
- if (filelist_entrys < filelist_maxentry) {
- filelist = (FILELIST *)realloc(filelist, filelist_entrys * sizeof(FILELIST));
- filelist_maxentry = filelist_entrys;
- }
-}
-
-/***********************************************************
- *** Grfio Sobroutines ***
- ***********************************************************/
-
-// returns a file's size
-/*
-int grfio_size(char* fname)
-{
- FILELIST* entry;
-
- entry = filelist_find(fname);
-
- if (entry == NULL || entry->gentry < 0) { // LocalFileCheck
- char lfname[256], *p;
- FILELIST lentry;
- struct stat st;
-
- sprintf(lfname, "%s%s", data_dir, fname);
-
- for (p = &lfname[0]; *p != 0; p++)
- if (*p=='\\') *p = '/';
-
- if (stat(lfname, &st) == 0) {
- strncpy(lentry.fn, fname, sizeof(lentry.fn) - 1);
- lentry.fnd = NULL;
- lentry.declen = st.st_size;
- lentry.gentry = 0; // 0:LocalFile
- entry = filelist_modify(&lentry);
- } else if (entry == NULL) {
- printf("%s not found (grfio_size)\n", fname);
- return -1;
- }
- }
- return entry->declen;
-}
-*/
-
-// reads a file into a newly allocated buffer (from grf or data directory)
-void* grfio_reads(char* fname, int* size)
-{
- FILE* in;
- FILELIST* entry;
- unsigned char* buf2 = NULL;
-
- entry = filelist_find(fname);
-
- if (entry == NULL || entry->gentry <= 0) { // LocalFileCheck
- char lfname[256], *p;
- FILELIST lentry;
-
- sprintf(lfname, "%s%s", data_dir, fname);
-
- for (p = &lfname[0]; *p != 0; p++)
- if (*p == '\\') *p = '/';
-
- in = fopen(lfname, "rb");
- if (in != NULL) {
- if (entry != NULL && entry->gentry == 0) {
- lentry.declen = entry->declen;
- } else {
- fseek(in,0,SEEK_END);
- lentry.declen = ftell(in);
- }
- fseek(in,0,SEEK_SET);
- buf2 = (unsigned char *)malloc(lentry.declen + 1024);
- fread(buf2, 1, lentry.declen, in);
- fclose(in);
- strncpy(lentry.fn, fname, sizeof(lentry.fn) - 1);
- lentry.fnd = NULL;
- lentry.gentry = 0; // 0:LocalFile
- entry = filelist_modify(&lentry);
- } else {
- if (entry != NULL && entry->gentry < 0) {
- entry->gentry = -entry->gentry; // local file checked
- } else {
- printf("%s not found (grfio_reads - local file %s)\n", fname, lfname);
- return NULL;
- }
- }
- }
- if (entry != NULL && entry->gentry > 0) { // Archive[GRF] File Read
- char* grfname = gentry_table[entry->gentry - 1];
- in = fopen(grfname, "rb");
- if(in != NULL) {
- unsigned char *buf = (unsigned char *)malloc(entry->srclen_aligned + 1024);
- fseek(in, entry->srcpos, 0);
- fread(buf, 1, entry->srclen_aligned, in);
- fclose(in);
- buf2 = (unsigned char *)malloc(entry->declen + 1024);
- if (entry->type == 1 || entry->type == 3 || entry->type == 5) {
- uLongf len;
- if (entry->cycle >= 0)
- decode_des_etc(buf, entry->srclen_aligned, entry->cycle == 0, entry->cycle);
- len = entry->declen;
- decode_zip(buf2, &len, buf, entry->srclen);
- if (len != (uLong)entry->declen) {
- printf("decode_zip size mismatch err: %d != %d\n", (int)len, entry->declen);
- free(buf);
- free(buf2);
- return NULL;
- }
- } else {
- memcpy(buf2, buf, entry->declen);
- }
- free(buf);
- } else {
- printf("%s not found (grfio_reads - GRF file %s)\n", fname, grfname);
- return NULL;
- }
- }
- if (size != NULL && entry != NULL)
- *size = entry->declen;
-
- return buf2;
-}
-
-/*==========================================
- * Resource filename decode
- *------------------------------------------*/
-static char* decode_filename(unsigned char* buf, int len)
-{
- int lop;
- for(lop=0;lop<len;lop+=8) {
- NibbleSwap(&buf[lop],8);
- BitConvert(&buf[lop],BitSwapTable1);
- BitConvert4(&buf[lop]);
- BitConvert(&buf[lop],BitSwapTable2);
- }
- return (char*)buf;
-}
-
-// loads all entries in the specified grf file into the filelist
-// gentry - index of the grf file name in the gentry_table
-static int grfio_entryread(char* grfname, int gentry)
-{
- FILE* fp;
- long grf_size,list_size;
- unsigned char grf_header[0x2e];
- int lop,entry,entrys,ofs,grf_version;
- char *fname;
- unsigned char *grf_filelist;
-
- fp = fopen(grfname, "rb");
- if (fp == NULL) {
- printf("GRF data file not found: '%s'\n",grfname);
- return 1; // 1:not found error
- } else
- printf("GRF data file found: '%s'\n",grfname);
-
- fseek(fp,0,SEEK_END);
- grf_size = ftell(fp);
- fseek(fp,0,SEEK_SET);
- fread(grf_header,1,0x2e,fp);
- if (strcmp((const char *) grf_header,"Master of Magic") ||
- fseek(fp,getlong(grf_header+0x1e),SEEK_CUR))
- {
- fclose(fp);
- printf("GRF %s read error\n", grfname);
- return 2; // 2:file format error
- }
-
- grf_version = getlong(grf_header+0x2a) >> 8;
-
- if (grf_version == 0x01) { //****** Grf version 01xx ******
- list_size = grf_size - ftell(fp);
- grf_filelist = (unsigned char *) malloc(list_size);
- fread(grf_filelist,1,list_size,fp);
- fclose(fp);
-
- entrys = getlong(grf_header+0x26) - getlong(grf_header+0x22) - 7;
-
- // Get an entry
- for (entry = 0,ofs = 0; entry < entrys; entry++) {
- int ofs2, srclen, srccount;
- unsigned char type;
- char* period_ptr;
- FILELIST aentry;
-
- ofs2 = ofs+getlong(grf_filelist+ofs)+4;
- type = grf_filelist[ofs2+12];
- if (type != 0) { // Directory Index ... skip
- fname = decode_filename(grf_filelist+ofs+6, grf_filelist[ofs]-6);
- if (strlen(fname) > sizeof(aentry.fn) - 1) {
- printf("GRF file name %s is too long\n", fname);
- free(grf_filelist);
- exit(EXIT_FAILURE);
- }
- srclen = 0;
- if ((period_ptr = strrchr(fname, '.')) != NULL) {
- for(lop = 0; lop < 4; lop++) {
- if (strcmpi(period_ptr, ".gnd\0.gat\0.act\0.str"+lop*5) == 0)
- break;
- }
- srclen = getlong(grf_filelist+ofs2) - getlong(grf_filelist+ofs2+8) - 715;
- if(lop == 4) {
- for(lop = 10, srccount = 1; srclen >= lop; lop = lop * 10, srccount++);
- } else {
- srccount = 0;
- }
- } else {
- srccount = 0;
- }
-
- aentry.srclen = srclen;
- aentry.srclen_aligned = getlong(grf_filelist+ofs2+4)-37579;
- aentry.declen = getlong(grf_filelist+ofs2+8);
- aentry.srcpos = getlong(grf_filelist+ofs2+13)+0x2e;
- aentry.cycle = srccount;
- aentry.type = type;
- strncpy(aentry.fn, fname,sizeof(aentry.fn)-1);
- aentry.fnd = NULL;
-#ifdef GRFIO_LOCAL
- aentry.gentry = -(gentry+1); // As Flag for making it a negative number carrying out the first time LocalFileCheck
-#else
- aentry.gentry = gentry+1; // With no first time LocalFileCheck
-#endif
- filelist_modify(&aentry);
- }
- ofs = ofs2 + 17;
- }
- free(grf_filelist);
-
- } else if (grf_version == 0x02) { //****** Grf version 02xx ******
- unsigned char eheader[8];
- unsigned char *rBuf;
- uLongf rSize, eSize;
-
- fread(eheader,1,8,fp);
- rSize = getlong(eheader); // Read Size
- eSize = getlong(eheader+4); // Extend Size
-
- if ((long)rSize > grf_size-ftell(fp)) {
- fclose(fp);
- printf("Illegal data format: GRF compress entry size\n");
- return 4;
- }
-
- rBuf = (unsigned char *)malloc(rSize); // Get a Read Size
- grf_filelist = (unsigned char *)malloc(eSize); // Get a Extend Size
- fread(rBuf,1,rSize,fp);
- fclose(fp);
- decode_zip(grf_filelist, &eSize, rBuf, rSize); // Decode function
- list_size = eSize;
- free(rBuf);
-
- entrys = getlong(grf_header+0x26) - 7;
-
- // Get an entry
- for(entry = 0, ofs = 0; entry < entrys; entry++) {
- int ofs2, srclen, srccount, type;
- FILELIST aentry;
-
- fname = (char*)(grf_filelist+ofs);
- if (strlen(fname) > sizeof(aentry.fn)-1) {
- printf("GRF file name %s is too long\n", fname);
- free(grf_filelist);
- exit(EXIT_FAILURE);
- }
- ofs2 = ofs + (int)strlen(fname)+1;
- type = grf_filelist[ofs2+12];
- if (type == 1 || type == 3 || type == 5) {
- srclen = getlong(grf_filelist+ofs2);
- if (grf_filelist[ofs2+12] == 3) {
- for (lop = 10, srccount = 1; srclen >= lop; lop = lop * 10, srccount++);
- } else if (grf_filelist[ofs2+12] == 5) {
- srccount = 0;
- } else { // if (grf_filelist[ofs2+12]==1) {
- srccount = -1;
- }
-
- aentry.srclen = srclen;
- aentry.srclen_aligned = getlong(grf_filelist+ofs2+4);
- aentry.declen = getlong(grf_filelist+ofs2+8);
- aentry.srcpos = getlong(grf_filelist+ofs2+13)+0x2e;
- aentry.cycle = srccount;
- aentry.type = type;
- strncpy(aentry.fn,fname,sizeof(aentry.fn)-1);
- aentry.fnd = NULL;
-#ifdef GRFIO_LOCAL
- aentry.gentry = -(gentry+1); // As Flag for making it a negative number carrying out the first time LocalFileCheck
-#else
- aentry.gentry = gentry+1; // With no first time LocalFileCheck
-#endif
- filelist_modify(&aentry);
- }
- ofs = ofs2 + 17;
- }
- free(grf_filelist);
-
- } else { //****** Grf Other version ******
- fclose(fp);
- printf("GRF version %04x not supported\n",getlong(grf_header+0x2a));
- return 4;
- }
-
- filelist_adjust(); // Unnecessary area release of filelist
-
- return 0; // 0:no error
-}
-
-/*==========================================
- * Grfio : Resource file check
- *------------------------------------------*/
-static void grfio_resourcecheck(void)
-{
- char w1[256], w2[256], src[256], dst[256], restable[256], line[256];
- char *ptr, *buf;
- FILELIST* entry;
- int size;
- FILE* fp;
-
- // read resnametable from data directory and return if successful
- sprintf(restable, "%sdata\\resnametable.txt", data_dir);
- for (ptr = &restable[0]; *ptr != 0; ptr++)
- if (*ptr == '\\') *ptr = '/';
-
- fp = fopen(restable, "rb");
- if (fp) {
- while(fgets(line, sizeof(line), fp))
- {
- if (sscanf(line, "%[^#]#%[^#]#", w1, w2) == 2 &&
- // we only need the maps' GAT and RSW files
- (strstr(w2, ".gat") || strstr(w2, ".rsw")))
- {
- sprintf(src, "data\\%s", w1);
- sprintf(dst, "data\\%s", w2);
- entry = filelist_find(dst);
- // create new entries reusing the original's info
- if (entry != NULL) {
- FILELIST fentry;
- memcpy(&fentry, entry, sizeof(FILELIST));
- strncpy(fentry.fn, src, sizeof(fentry.fn) - 1);
- fentry.fnd = strdup(dst);
- filelist_modify(&fentry);
- }
- }
- }
- fclose(fp);
- return; // we're done here!
- }
-
- // read resnametable from loaded GRF's, only if it cannot be loaded from the data directory
- buf = (char *)grfio_reads("data\\resnametable.txt", &size);
- if (buf) {
- buf[size] = 0;
-
- ptr = buf;
- while (ptr - buf < size) {
- if (sscanf(ptr, "%[^#]#%[^#]#", w1, w2) == 2 &&
- (strstr(w2, ".gat") || strstr(w2, ".rsw")))
- {
- sprintf(src, "data\\%s", w1);
- sprintf(dst, "data\\%s", w2);
- entry = filelist_find(dst);
- if (entry != NULL) {
- FILELIST fentry;
- memcpy(&fentry, entry, sizeof(FILELIST));
- strncpy(fentry.fn, src, sizeof(fentry.fn) - 1);
- fentry.fnd = strdup(dst);
- filelist_modify(&fentry);
- }
- }
- ptr = strchr(ptr, '\n'); // Next line
- if (!ptr) break;
- ptr++;
- }
- free(buf);
- return;
- }
-
-}
-
-// reads a grf file and adds it to the list
-static int grfio_add(char* fname)
-{
- #define GENTRY_ADDS 4 // The number increment of gentry_table entries
-
- if (gentry_entrys >= gentry_maxentry) {
- gentry_maxentry += GENTRY_ADDS;
- gentry_table = (char**)realloc(gentry_table, gentry_maxentry * sizeof(char*));
- memset(gentry_table + (gentry_maxentry - GENTRY_ADDS), 0, sizeof(char*) * GENTRY_ADDS);
- }
-
- gentry_table[gentry_entrys++] = strdup(fname);
-
- return grfio_entryread(fname, gentry_entrys - 1);
-}
-
-// removes all entries
-void grfio_final(void)
-{
- if (filelist != NULL) {
- int i;
- for (i = 0; i < filelist_entrys; i++)
- if (filelist[i].fnd != NULL)
- free(filelist[i].fnd);
-
- free(filelist);
- filelist = NULL;
- }
- filelist_entrys = filelist_maxentry = 0;
-
- if (gentry_table != NULL) {
- int i;
- for (i = 0; i < gentry_entrys; i++)
- if (gentry_table[i] != NULL)
- free(gentry_table[i]);
-
- free(gentry_table);
- gentry_table = NULL;
- }
- gentry_entrys = gentry_maxentry = 0;
-}
-
-/*==========================================
- * Grfio : Initialize
- *------------------------------------------*/
-void grfio_init(char* fname)
-{
- FILE* data_conf;
- char line[1024], w1[1024], w2[1024];
- int grf_num = 0;
-
- hashinit(); // hash table initialization
-
- data_conf = fopen(fname, "r");
- // It will read, if there is grf-files.txt.
- if (data_conf) {
- while(fgets(line, sizeof(line), data_conf))
- {
- if (line[0] == '/' && line[1] == '/')
- continue;
- if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) != 2)
- continue;
- // Entry table reading
- if(strcmp(w1, "grf") == 0) // GRF file
- grf_num += (grfio_add(w2) == 0);
- else if(strcmp(w1,"data_dir") == 0) { // Data directory
- strcpy(data_dir, w2);
- printf("Use data directory %s\n", w2);
- }
- }
- fclose(data_conf);
- } // end of reading grf-files.txt
-
- if (grf_num == 0) {
- printf("No GRF loaded, using default data directory\n");
- }
-
- // Unneccessary area release of filelist
- filelist_adjust();
-
- // Resource check
- grfio_resourcecheck();
-
- return;
-}
diff --git a/src/tool/grfio.h b/src/tool/grfio.h
deleted file mode 100644
index 57439b16d..000000000
--- a/src/tool/grfio.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
-
-#ifndef _GRFIO_H_
-#define _GRFIO_H_
-
-void grfio_init(char*); // GRFIO Initialize
-void grfio_final(void); // GRFIO Finalize
-void* grfio_reads(char*,int*); // GRFIO data file read & size get
-char *grfio_find_file(char *fname);
-
-#define grfio_read(fn) grfio_reads(fn, NULL)
-
-int grfio_size(char*); // GRFIO data file size get
-unsigned long grfio_crc32(const unsigned char *buf, unsigned int len);
-
-int decode_zip(unsigned char *dest, unsigned long* destLen, const unsigned char* source, unsigned long sourceLen);
-int encode_zip(unsigned char *dest, unsigned long* destLen, const unsigned char* source, unsigned long sourceLen);
-
-#endif /* _GRFIO_H_ */
diff --git a/src/tool/mapcache.c b/src/tool/mapcache.c
index 49e1826ab..f782331ca 100644
--- a/src/tool/mapcache.c
+++ b/src/tool/mapcache.c
@@ -1,6 +1,12 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
+#include "../common/cbasetypes.h"
+#include "../common/grfio.h"
+#include "../common/malloc.h"
+#include "../common/mmo.h"
+#include "../common/showmsg.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -9,11 +15,6 @@
#include <unistd.h>
#endif
-#include "../common/cbasetypes.h"
-#include "grfio.h"
-
-#define MAP_NAME_LENGTH 12
-#define MAP_NAME_LENGTH_EXT 16
#define NO_WATER 1000000
char grf_list_file[256] = "conf/grf-files.txt";
@@ -124,7 +125,7 @@ int read_map(char *name, struct map_data *m)
// Read water height
if (rsw) {
water_height = (int)GetFloat(rsw+166);
- free(rsw);
+ aFree(rsw);
} else
water_height = NO_WATER;
@@ -132,11 +133,11 @@ int read_map(char *name, struct map_data *m)
m->xs = (int16)GetULong(gat+6);
m->ys = (int16)GetULong(gat+10);
if (m->xs <= 0 || m->ys <= 0) {
- free(gat);
+ aFree(gat);
return 0;
}
num_cells = (size_t)m->xs*(size_t)m->ys;
- m->cells = (unsigned char *)malloc(num_cells);
+ m->cells = (unsigned char *)aMalloc(num_cells);
// Set cell properties
off = 14;
@@ -154,7 +155,7 @@ int read_map(char *name, struct map_data *m)
m->cells[xy] = (unsigned char)type;
}
- free(gat);
+ aFree(gat);
return 1;
}
@@ -168,7 +169,7 @@ void cache_map(char *name, struct map_data *m)
// Create an output buffer twice as big as the uncompressed map... this way we're sure it fits
len = (unsigned long)m->xs*(unsigned long)m->ys*2;
- write_buf = (unsigned char *)malloc(len);
+ write_buf = (unsigned char *)aMalloc(len);
// Compress the cells and get the compressed length
encode_zip(write_buf, &len, m->cells, m->xs*m->ys);
@@ -185,8 +186,8 @@ void cache_map(char *name, struct map_data *m)
header.file_size += sizeof(struct map_info) + len;
header.map_count++;
- free(write_buf);
- free(m->cells);
+ aFree(write_buf);
+ aFree(m->cells);
return;
}
@@ -245,7 +246,7 @@ void process_args(int argc, char *argv[])
}
-int main(int argc, char *argv[])
+int do_init(int argc, char *argv[])
{
FILE *list;
char line[1024];
@@ -255,15 +256,15 @@ int main(int argc, char *argv[])
// Process the command-line arguments
process_args(argc, argv);
- printf("Initializing grfio with %s\n", grf_list_file);
+ ShowStatus("Initializing grfio with %s\n", grf_list_file);
grfio_init(grf_list_file);
// Attempt to open the map cache file and force rebuild if not found
- printf("Opening map cache: %s\n", map_cache_file);
+ ShowStatus("Opening map cache: %s\n", map_cache_file);
if(!rebuild) {
map_cache_fp = fopen(map_cache_file, "rb");
if(map_cache_fp == NULL) {
- printf("Existing map cache not found, forcing rebuild mode\n");
+ ShowNotice("Existing map cache not found, forcing rebuild mode\n");
rebuild = 1;
} else
fclose(map_cache_fp);
@@ -273,15 +274,15 @@ int main(int argc, char *argv[])
else
map_cache_fp = fopen(map_cache_file, "r+b");
if(map_cache_fp == NULL) {
- printf("Failure when opening map cache file %s\n", map_cache_file);
+ ShowError("Failure when opening map cache file %s\n", map_cache_file);
exit(EXIT_FAILURE);
}
// Open the map list
- printf("Opening map list: %s\n", map_list_file);
+ ShowStatus("Opening map list: %s\n", map_list_file);
list = fopen(map_list_file, "r");
if(list == NULL) {
- printf("Failure when opening maps list file %s\n", map_list_file);
+ ShowError("Failure when opening maps list file %s\n", map_list_file);
exit(EXIT_FAILURE);
}
@@ -309,30 +310,33 @@ int main(int argc, char *argv[])
name[MAP_NAME_LENGTH_EXT-1] = '\0';
remove_extension(name);
- printf("%s", name);
if(find_map(name))
- printf(" already in cache!\n");
+ ShowInfo("Map '"CL_WHITE"%s"CL_RESET"' already in cache.\n", name);
else if(read_map(name, &map)) {
cache_map(name, &map);
- printf(" successfully cached\n");
+ ShowInfo("Map '"CL_WHITE"%s"CL_RESET"' successfully cached.\n", name);
} else
- printf(" not found in GRF!\n");
+ ShowError("Map '"CL_WHITE"%s"CL_RESET"' not found!\n", name);
}
- printf("Closing map list: %s\n", map_list_file);
+ ShowStatus("Closing map list: %s\n", map_list_file);
fclose(list);
// Write the main header and close the map cache
- printf("Closing map cache: %s\n", map_cache_file);
+ ShowStatus("Closing map cache: %s\n", map_cache_file);
fseek(map_cache_fp, 0, SEEK_SET);
fwrite(&header, sizeof(struct main_header), 1, map_cache_fp);
fclose(map_cache_fp);
- printf("Finalizing grfio\n");
+ ShowStatus("Finalizing grfio\n");
grfio_final();
- printf("%d maps now in cache\n", header.map_count);
+ ShowInfo("%d maps now in cache\n", header.map_count);
return 0;
}
+
+void do_final(void)
+{
+}