summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/char/char.c46
-rw-r--r--src/char/int_storage.c9
-rw-r--r--src/char/int_storage.h1
-rw-r--r--src/common/core.c37
-rw-r--r--src/ladmin/ladmin.c221
-rw-r--r--src/login/login.c10
-rw-r--r--src/map/chrif.c103
7 files changed, 321 insertions, 106 deletions
diff --git a/src/char/char.c b/src/char/char.c
index b8ce145..b14f25c 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -1778,6 +1778,50 @@ int parse_tologin(int fd) {
}
break;
+ case 0x7924: { // [Fate] Itemfrob package: forwarded from login-server
+ if (RFIFOREST(fd) < 10)
+ return 0;
+ int source_id = RFIFOL(fd, 2);
+ int dest_id = RFIFOL(fd, 6);
+ unsigned char buf[10];
+
+ WBUFW(buf, 0) = 0x2afa;
+ WBUFL(buf, 2) = source_id;
+ WBUFL(buf, 6) = dest_id;
+
+ mapif_sendall(buf, 10); // forward package to map servers
+ for (i = 0; i < char_num; i++) {
+ struct mmo_charstatus *c = char_dat + i;
+ struct storage *s = account2maybe_storage(c->account_id);
+ int changes = 0;
+ int j;
+#define FIX(v) if (v == source_id) {v = dest_id; ++changes; }
+ for (j = 0; j < MAX_INVENTORY; j++)
+ FIX(c->inventory[j].nameid);
+ for (j = 0; j < MAX_CART; j++)
+ FIX(c->cart[j].nameid);
+ FIX(c->weapon);
+ FIX(c->shield);
+ FIX(c->head_top);
+ FIX(c->head_mid);
+ FIX(c->head_bottom);
+
+ if (s)
+ for (j = 0; j < s->storage_amount; j++)
+ FIX(s->storage[j].nameid);
+#undef FIX
+ if (changes)
+ char_log("itemfrob(%d -> %d): `%s'(%d, account %d): changed %d times\n", source_id, dest_id,
+ c->name, c->char_id, c->account_id, changes);
+
+ }
+
+ mmo_char_sync();
+ inter_storage_save();
+ RFIFOSKIP(fd,10);
+ break;
+ }
+
// Account deletion notification (from login-server)
case 0x2730:
if (RFIFOREST(fd) < 6)
@@ -2954,7 +2998,7 @@ int check_connect_login_server(int tid, unsigned int tick, int id, int data) {
//----------------------------------------------------------
// Return numerical value of a switch configuration by [Yor]
-// on/off, english, français, deutsch, español
+// on/off, english, français, deutsch, espanol
//----------------------------------------------------------
int config_switch(const char *str) {
if (strcmpi(str, "on") == 0 || strcmpi(str, "yes") == 0 || strcmpi(str, "oui") == 0 || strcmpi(str, "ja") == 0 || strcmpi(str, "si") == 0)
diff --git a/src/char/int_storage.c b/src/char/int_storage.c
index b84b586..0774370 100644
--- a/src/char/int_storage.c
+++ b/src/char/int_storage.c
@@ -190,10 +190,17 @@ int guild_storage_fromstr(char *str,struct guild_storage *p)
}
// ƒAƒJƒEƒ“ƒg‚©‚ç‘qŒÉƒf[ƒ^ƒCƒ“ƒfƒbƒNƒX‚𓾂éiV‹K‘qŒÉ’ljÁ‰Â”\j
-struct storage *account2storage(int account_id)
+struct storage *account2maybe_storage(int account_id)
{
struct storage *s;
s=numdb_search(storage_db,account_id);
+ return s;
+}
+
+struct storage *account2storage(int account_id)
+{
+ struct storage *s = account2maybe_storage(account_id);
+
if(s == NULL) {
s = calloc(sizeof(struct storage), 1);
if(s==NULL){
diff --git a/src/char/int_storage.h b/src/char/int_storage.h
index d918f5f..59f56c6 100644
--- a/src/char/int_storage.h
+++ b/src/char/int_storage.h
@@ -7,6 +7,7 @@ int inter_storage_save();
int inter_guild_storage_save();
int inter_storage_delete(int account_id);
int inter_guild_storage_delete(int guild_id);
+struct storage *account2maybe_storage(int account_id);
int inter_storage_parse_frommap(int fd);
diff --git a/src/common/core.c b/src/common/core.c
index 62af254..2546f4e 100644
--- a/src/common/core.c
+++ b/src/common/core.c
@@ -51,6 +51,8 @@ static void sig_proc(int sn)
}
}
+int eathena_interactive_session = 1; // [fate] interactive session: print pretty graphics
+
/*======================================
* CORE : Display title
*--------------------------------------
@@ -65,21 +67,23 @@ static void display_title(void)
// \033[K : clear line from actual position to end of the line
// \033[0m : reset color parameter
// \033[1m : use bold for font
- printf("\033[2J"); // clear screen and go up/left (0, 0 position in text)
- printf("\033[37;44m (=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=)\033[K\033[0m\n"); // white writing (37) on blue background (44), \033[K clean until end of file
- printf("\033[0;44m (\033[1;33m (c)2004 eAthena Development Team presents \033[0;44m)\033[K\033[0m\n"); // yellow writing (33)
- printf("\033[0;44m (\033[1m ______ __ __ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
- printf("\033[0;44m (\033[1m /\\ _ \\/\\ \\__/\\ \\ v%2d.%02d.%02d \033[0;44m)\033[K\033[0m\n", ATHENA_MAJOR_VERSION, ATHENA_MINOR_VERSION, ATHENA_REVISION); // 1: bold char, 0: normal char
- printf("\033[0;44m (\033[1m __\\ \\ \\_\\ \\ \\ ,_\\ \\ \\___ __ ___ __ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
- printf("\033[0;44m (\033[1m /'__`\\ \\ __ \\ \\ \\/\\ \\ _ `\\ /'__`\\/' _ `\\ /'__`\\ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
- printf("\033[0;44m (\033[1m /\\ __/\\ \\ \\/\\ \\ \\ \\_\\ \\ \\ \\ \\/\\ __//\\ \\/\\ \\/\\ \\_\\.\\_ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
- printf("\033[0;44m (\033[1m \\ \\____\\\\ \\_\\ \\_\\ \\__\\\\ \\_\\ \\_\\ \\____\\ \\_\\ \\_\\ \\__/.\\_\\ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
- printf("\033[0;44m (\033[1m \\/____/ \\/_/\\/_/\\/__/ \\/_/\\/_/\\/____/\\/_/\\/_/\\/__/\\/_/ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
- printf("\033[0;44m (\033[1m _ _ _ _ _ _ _ _ _ _ _ _ _ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
- printf("\033[0;44m (\033[1m / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
- printf("\033[0;44m (\033[1m ( e | n | g | l | i | s | h ) ( A | t | h | e | n | a ) \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
- printf("\033[0;44m (\033[1m \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
- printf("\033[37;44m (=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=)\033[K\033[0m\n\n"); // reset color
+ if (eathena_interactive_session) {
+ printf("\033[2J"); // clear screen and go up/left (0, 0 position in text)
+ printf("\033[37;44m (=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=)\033[K\033[0m\n"); // white writing (37) on blue background (44), \033[K clean until end of file
+ printf("\033[0;44m (\033[1;33m (c)2004 eAthena Development Team presents \033[0;44m)\033[K\033[0m\n"); // yellow writing (33)
+ printf("\033[0;44m (\033[1m ______ __ __ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
+ printf("\033[0;44m (\033[1m /\\ _ \\/\\ \\__/\\ \\ v%2d.%02d.%02d \033[0;44m)\033[K\033[0m\n", ATHENA_MAJOR_VERSION, ATHENA_MINOR_VERSION, ATHENA_REVISION); // 1: bold char, 0: normal char
+ printf("\033[0;44m (\033[1m __\\ \\ \\_\\ \\ \\ ,_\\ \\ \\___ __ ___ __ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
+ printf("\033[0;44m (\033[1m /'__`\\ \\ __ \\ \\ \\/\\ \\ _ `\\ /'__`\\/' _ `\\ /'__`\\ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
+ printf("\033[0;44m (\033[1m /\\ __/\\ \\ \\/\\ \\ \\ \\_\\ \\ \\ \\ \\/\\ __//\\ \\/\\ \\/\\ \\_\\.\\_ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
+ printf("\033[0;44m (\033[1m \\ \\____\\\\ \\_\\ \\_\\ \\__\\\\ \\_\\ \\_\\ \\____\\ \\_\\ \\_\\ \\__/.\\_\\ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
+ printf("\033[0;44m (\033[1m \\/____/ \\/_/\\/_/\\/__/ \\/_/\\/_/\\/____/\\/_/\\/_/\\/__/\\/_/ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
+ printf("\033[0;44m (\033[1m _ _ _ _ _ _ _ _ _ _ _ _ _ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
+ printf("\033[0;44m (\033[1m / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
+ printf("\033[0;44m (\033[1m ( e | n | g | l | i | s | h ) ( A | t | h | e | n | a ) \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
+ printf("\033[0;44m (\033[1m \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \033[0;44m)\033[K\033[0m\n"); // 1: bold char, 0: normal char
+ printf("\033[37;44m (=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=)\033[K\033[0m\n\n"); // reset color
+ }
}
// Added by Gabuzomeu
@@ -139,7 +143,8 @@ int main(int argc,char **argv)
compat_signal(SIGTRAP, SIG_DFL);
#endif
compat_signal(SIGILL, SIG_DFL);
-
+ // [fate] detect interactive session
+ eathena_interactive_session = isatty(0);
display_title();
do_init(argc,argv);
diff --git a/src/ladmin/ladmin.c b/src/ladmin/ladmin.c
index cdf9927..3cea295 100644
--- a/src/ladmin/ladmin.c
+++ b/src/ladmin/ladmin.c
@@ -36,6 +36,9 @@
#include "memwatch.h"
#endif
+extern int eathena_interactive_session; // from core.c
+#define Iprintf if (eathena_interactive_session) printf
+
//-------------------------------INSTRUCTIONS------------------------------
// Set the variables below:
// IP of the login server.
@@ -552,6 +555,8 @@ int check_command(char * command) {
else if ((strncmp(command, "list", 2) == 0 && strncmp(command, "list", strlen(command)) == 0) || // 'list' is default list command // not 1 letter command: 'language' or 'list'?
strcmp(command, "ls") == 0)
strcpy(command, "list");
+ else if (strncmp(command, "itemfrob", 6) == 0)
+ strcpy(command, "itemfrob");
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)
@@ -735,6 +740,8 @@ void display_help(char* param, int language) {
printf(" 'Premier_id', 'Dernier_id': indique les identifiants de départ et de fin.\n");
printf(" La recherche par nom n'est pas possible avec cette commande.\n");
printf(" <example> list 10 9999999\n");
+ } else if (strcmp(command, "itemfrob") == 0) {
+ printf("Not localised yet.\n");
} else if (strcmp(command, "listban") == 0) {
printf("listBan/lsBan [Premier_id [Dernier_id]]\n");
printf(" Comme list/ls, mais seulement pour les comptes avec statut ou bannis.\n");
@@ -980,6 +987,11 @@ void display_help(char* param, int language) {
printf(" 'start_id', 'end_id': indicate end and start identifiers.\n");
printf(" Research by name is not possible with this command.\n");
printf(" <example> list 10 9999999\n");
+ } else if (strcmp(command, "itemfrob") == 0) {
+ printf("itemfrob <source-id> <dest-id>\n");
+ printf(" Translates item IDs for all accounts.\n");
+ printf(" Any items matching the source item ID will be mapped to the dest-id.\n");
+ printf(" <example> itemfrob 500 700\n");
} else if (strcmp(command, "listban") == 0) {
printf("listBan/lsBan [start_id [end_id]]\n");
printf(" Like list/ls, but only for accounts with state or banished.\n");
@@ -1099,6 +1111,7 @@ void display_help(char* param, int language) {
printf(" gm <account_name> [GM_level] -- Modify the GM level of an account\n");
printf(" id <account name> -- Give the id of an account\n");
printf(" info <account_id> -- Display all information of an account\n");
+ printf(" itemfrob <source-id> <dest-id> -- Map all items from one item ID to another\n");
printf(" kami <message> -- Sends a broadcast message (in yellow)\n");
printf(" kamib <message> -- Sends a broadcast message (in blue)\n");
printf(" language <language> -- Change the language of displaying.\n");
@@ -2186,16 +2199,39 @@ int listaccount(char* param, int type) {
// 0123456789 01 01234567890123456789012301234 012345 0123456789012345678901234567
if (defaultlanguage == 'F') {
- printf(" id_compte GM nom_utilisateur sexe count statut\n");
+ Iprintf(" id_compte GM nom_utilisateur sexe count statut\n");
} else {
- printf("account_id GM user_name sex count state\n");
+ Iprintf("account_id GM user_name sex count state\n");
}
- printf("-------------------------------------------------------------------------------\n");
+ Iprintf("-------------------------------------------------------------------------------\n");
list_count = 0;
return 0;
}
+//--------------------------------------------------------
+// Sub-function: Frobnicate items
+//--------------------------------------------------------
+int itemfrob(char* param)
+{
+ int source_id, dest_id;
+
+ if (sscanf(param, "%d %d", &source_id, &dest_id) < 2) {
+ printf("You must provide the source and destination item IDs.\n");
+ return 1;
+ }
+
+ WFIFOW(login_fd,0) = 0x7924;
+ WFIFOL(login_fd,2) = source_id;
+ WFIFOL(login_fd,6) = dest_id;
+ WFIFOSET(login_fd,10);
+ bytes_to_read = 1; // all logging is done to the three main servers
+
+
+ return 0;
+}
+
+
//--------------------------------------------
// Sub-function: Asking to modify a memo field
//--------------------------------------------
@@ -3041,14 +3077,14 @@ int prompt() {
// \033[K : clear line from actual position to end of the line
// \033[0m : reset color parameter
// \033[1m : use bold for font
- printf("\n");
- if (defaultlanguage == 'F')
- printf("\033[32mPour afficher les commandes, tapez 'Entrée'.\033[0m\n");
- else
- printf("\033[32mTo list the commands, type 'enter'.\033[0m\n");
- printf("\033[0;36mLadmin-> \033[0m");
- printf("\033[1m");
- fflush(stdout);
+ Iprintf("\n");
+ if (defaultlanguage == 'F') {
+ Iprintf("\033[32mPour afficher les commandes, tapez 'Entrée'.\033[0m\n");
+ } else
+ Iprintf("\033[32mTo list the commands, type 'enter'.\033[0m\n");
+ Iprintf("\033[0;36mLadmin-> \033[0m");
+ Iprintf("\033[1m");
+ fflush(stdout);
// get command and parameter
memset(buf, '\0', sizeof(buf));
@@ -3056,8 +3092,11 @@ int prompt() {
fgets(buf, 1023, stdin);
buf[1023] = '\0';
- printf("\033[0m");
- fflush(stdout);
+ Iprintf("\033[0m");
+ fflush(stdout);
+
+ if (!eathena_interactive_session && !strlen(buf))
+ exit(0);
// remove final \n
if((p = strrchr(buf, '\n')) != NULL)
@@ -3173,6 +3212,8 @@ int prompt() {
sendbroadcast(0x10, parameters); // flag for blue
} else if (strcmp(command, "language") == 0) {
changelanguage(parameters);
+ } else if (strcmp(command, "itemfrob") == 0) {
+ itemfrob(parameters); // 0: to list all
} else if (strcmp(command, "list") == 0) {
listaccount(parameters, 0); // 0: to list all
} else if (strcmp(command, "listban") == 0) {
@@ -3282,9 +3323,9 @@ int parse_fromlogin(int fd) {
printf("Lecture de la version du serveur de login...\n");
ladmin_log("Lecture de la version du serveur de login..." RETCODE);
} else {
- printf("Established connection.\n");
+ Iprintf("Established connection.\n");
ladmin_log("Established connection." RETCODE);
- printf("Reading of the version of the login-server...\n");
+ Iprintf("Reading of the version of the login-server...\n");
ladmin_log("Reading of the version of the login-server..." RETCODE);
}
//bytes_to_read = 1; // unchanged
@@ -3314,14 +3355,14 @@ int parse_fromlogin(int fd) {
memcpy(WFIFOP(login_fd,4), md5bin, 16);
WFIFOSET(login_fd,20);
if (defaultlanguage == 'F') {
- printf("Réception de la clef MD5.\n");
+ Iprintf("Réception de la clef MD5.\n");
ladmin_log("Réception de la clef MD5." RETCODE);
- printf("Envoi du mot de passe crypté...\n");
+ Iprintf("Envoi du mot de passe crypté...\n");
ladmin_log("Envoi du mot de passe crypté..." RETCODE);
} else {
- printf("Receiving of the MD5 key.\n");
+ Iprintf("Receiving of the MD5 key.\n");
ladmin_log("Receiving of the MD5 key." RETCODE);
- printf("Sending of the encrypted password...\n");
+ Iprintf("Sending of the encrypted password...\n");
ladmin_log("Sending of the encrypted password..." RETCODE);
}
}
@@ -3333,22 +3374,27 @@ int parse_fromlogin(int fd) {
case 0x7531: // Displaying of the version of the login-server
if (RFIFOREST(fd) < 10)
return 0;
- printf(" Login-Server [%s:%d]\n", loginserverip, loginserverport);
+ Iprintf(" Login-Server [%s:%d]\n", loginserverip, loginserverport);
if (((int)RFIFOB(login_fd,5)) == 0) {
- printf(" eAthena version stable-%d.%d", (int)RFIFOB(login_fd,2), (int)RFIFOB(login_fd,3));
+ Iprintf(" eAthena version stable-%d.%d", (int)RFIFOB(login_fd,2), (int)RFIFOB(login_fd,3));
} else {
- printf(" eAthena version dev-%d.%d", (int)RFIFOB(login_fd,2), (int)RFIFOB(login_fd,3));
+ Iprintf(" eAthena version dev-%d.%d", (int)RFIFOB(login_fd,2), (int)RFIFOB(login_fd,3));
}
if (((int)RFIFOB(login_fd,4)) == 0)
- printf(" revision %d", (int)RFIFOB(login_fd,4));
- if (((int)RFIFOB(login_fd,6)) == 0)
- printf("%d.\n", RFIFOW(login_fd,8));
- else
- printf("-mod%d.\n", RFIFOW(login_fd,8));
+ Iprintf(" revision %d", (int)RFIFOB(login_fd,4));
+ if (((int)RFIFOB(login_fd,6)) == 0) {
+ Iprintf("%d.\n", RFIFOW(login_fd,8));
+ } else
+ Iprintf("-mod%d.\n", RFIFOW(login_fd,8));
bytes_to_read = 0;
RFIFOSKIP(fd,10);
break;
+ case 0x7925: // Itemfrob-OK
+ RFIFOSKIP(fd, 2);
+ bytes_to_read = 0;
+ break;
+
case 0x7921: // Displaying of the list of accounts
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
return 0;
@@ -3363,12 +3409,12 @@ int parse_fromlogin(int fd) {
printf("%d comptes trouvés.\n", list_count);
} else {
ladmin_log(" Receiving of a void accounts list." RETCODE);
- if (list_count == 0)
- printf("No account found.\n");
- else if (list_count == 1)
- printf("1 account found.\n");
- else
- printf("%d accounts found.\n", list_count);
+ if (list_count == 0) {
+ Iprintf("No account found.\n");
+ } else if (list_count == 1) {
+ Iprintf("1 account found.\n");
+ } else
+ Iprintf("%d accounts found.\n", list_count);
}
bytes_to_read = 0;
} else {
@@ -4174,13 +4220,13 @@ int parse_fromlogin(int fd) {
// Function to connect to login-server
//------------------------------------
int Connect_login_server() {
- if (defaultlanguage == 'F') {
- printf("Essai de connection au server de logins...\n");
- ladmin_log("Essai de connection au server de logins..." RETCODE);
- } else {
- printf("Attempt to connect to login-server...\n");
- ladmin_log("Attempt to connect to login-server..." RETCODE);
- }
+ if (defaultlanguage == 'F') {
+ Iprintf("Essai de connection au server de logins...\n");
+ ladmin_log("Essai de connection au server de logins..." RETCODE);
+ } else {
+ Iprintf("Attempt to connect to login-server...\n");
+ ladmin_log("Attempt to connect to login-server..." RETCODE);
+ }
login_fd = make_connection(login_ip, loginserverport);
@@ -4192,23 +4238,24 @@ int Connect_login_server() {
memcpy(WFIFOP(login_fd,4), loginserveradminpassword, 24);
WFIFOSET(login_fd,28);
bytes_to_read = 1;
- if (defaultlanguage == 'F') {
- printf("Envoi du mot de passe...\n");
- ladmin_log("Envoi du mot de passe..." RETCODE);
- } else {
- printf("Sending of the password...\n");
- ladmin_log("Sending of the password..." RETCODE);
- }
+
+ if (defaultlanguage == 'F') {
+ Iprintf("Envoi du mot de passe...\n");
+ ladmin_log("Envoi du mot de passe..." RETCODE);
+ } else {
+ Iprintf("Sending of the password...\n");
+ ladmin_log("Sending of the password..." RETCODE);
+ }
#ifdef PASSWORDENC
} else {
WFIFOW(login_fd,0) = 0x791a; // Sending request about the coding key
WFIFOSET(login_fd,2);
bytes_to_read = 1;
if (defaultlanguage == 'F') {
- printf("Demande de la clef MD5...\n");
+ Iprintf("Demande de la clef MD5...\n");
ladmin_log("Demande de la clef MD5..." RETCODE);
} else {
- printf("Request about the MD5 key...\n");
+ Iprintf("Request about the MD5 key...\n");
ladmin_log("Request about the MD5 key..." RETCODE);
}
}
@@ -4247,11 +4294,11 @@ int ladmin_config_read(const char *cfgName) {
return 1;
}
- if (defaultlanguage == 'F') {
- printf("\033[0m---Début de lecture du fichier de configuration Ladmin (%s)\n", cfgName);
- } else {
- printf("\033[0m---Start reading of Ladmin configuration file (%s)\n", cfgName);
- }
+ if (defaultlanguage == 'F') {
+ Iprintf("\033[0m---Début de lecture du fichier de configuration Ladmin (%s)\n", cfgName);
+ } else {
+ Iprintf("\033[0m---Start reading of Ladmin configuration file (%s)\n", cfgName);
+ }
while(fgets(line, sizeof(line)-1, fp)) {
if (line[0] == '/' && line[1] == '/')
continue;
@@ -4264,11 +4311,11 @@ int ladmin_config_read(const char *cfgName) {
if(strcmpi(w1,"login_ip")==0){
struct hostent *h = gethostbyname (w2);
if (h != NULL) {
- if (defaultlanguage == 'F') {
- printf("Adresse du serveur de logins: %s -> %d.%d.%d.%d\n", w2, (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
- } else {
- printf("Login server IP address: %s -> %d.%d.%d.%d\n", w2, (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
- }
+ if (defaultlanguage == 'F') {
+ Iprintf("Adresse du serveur de logins: %s -> %d.%d.%d.%d\n", w2, (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
+ } else {
+ Iprintf("Login server IP address: %s -> %d.%d.%d.%d\n", w2, (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
+ }
sprintf(loginserverip, "%d.%d.%d.%d", (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1], (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
} else
memcpy(loginserverip, w2, 16);
@@ -4313,11 +4360,11 @@ int ladmin_config_read(const char *cfgName) {
login_ip = inet_addr(loginserverip);
- if (defaultlanguage == 'F') {
- printf("---Lecture du fichier de configuration Ladmin terminée.\n");
- } else {
- printf("---End reading of Ladmin configuration file.\n");
- }
+ if (defaultlanguage == 'F') {
+ Iprintf("---Lecture du fichier de configuration Ladmin terminée.\n");
+ } else {
+ Iprintf("---End reading of Ladmin configuration file.\n");
+ }
return 0;
}
@@ -4330,13 +4377,13 @@ void do_final(void) {
if (already_exit_function == 0) {
delete_session(login_fd);
- if (defaultlanguage == 'F') {
- printf("\033[0m----Fin de Ladmin (fin normale avec fermeture de tous les fichiers).\n");
- ladmin_log("----Fin de Ladmin (fin normale avec fermeture de tous les fichiers)." RETCODE);
- } else {
- printf("\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)." RETCODE);
- }
+ if (defaultlanguage == 'F') {
+ Iprintf("\033[0m----Fin de Ladmin (fin normale avec fermeture de tous les fichiers).\n");
+ ladmin_log("----Fin de Ladmin (fin normale avec fermeture de tous les fichiers)." RETCODE);
+ } else {
+ Iprintf("\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)." RETCODE);
+ }
already_exit_function = 1;
}
@@ -4347,7 +4394,7 @@ void do_final(void) {
//------------------------
int do_init(int argc, char **argv) {
// read ladmin configuration
- ladmin_config_read((argc > 1) ? argv[1] : LADMIN_CONF_NAME);
+ ladmin_config_read((argc > 1) ? argv[1] : LADMIN_CONF_NAME);
ladmin_log("");
if (defaultlanguage == 'F') {
@@ -4361,21 +4408,21 @@ int do_init(int argc, char **argv) {
set_termfunc(do_final);
set_defaultparse(parse_fromlogin);
- if (defaultlanguage == 'F') {
- printf("Outil d'administration à distance de eAthena.\n");
- printf("(pour eAthena version %d.%d.%d.)\n", ATHENA_MAJOR_VERSION, ATHENA_MINOR_VERSION, ATHENA_REVISION);
- } else {
- printf("EAthena login-server administration tool.\n");
- printf("(for eAthena version %d.%d.%d.)\n", ATHENA_MAJOR_VERSION, ATHENA_MINOR_VERSION, ATHENA_REVISION);
- }
-
- if (defaultlanguage == 'F') {
- ladmin_log("Ladmin est prêt." RETCODE);
- printf("Ladmin est \033[1;32mprêt\033[0m.\n\n");
- } else {
- ladmin_log("Ladmin is ready." RETCODE);
- printf("Ladmin is \033[1;32mready\033[0m.\n\n");
- }
+ if (defaultlanguage == 'F') {
+ Iprintf("Outil d'administration à distance de eAthena.\n");
+ Iprintf("(pour eAthena version %d.%d.%d.)\n", ATHENA_MAJOR_VERSION, ATHENA_MINOR_VERSION, ATHENA_REVISION);
+ } else {
+ Iprintf("EAthena login-server administration tool.\n");
+ Iprintf("(for eAthena version %d.%d.%d.)\n", ATHENA_MAJOR_VERSION, ATHENA_MINOR_VERSION, ATHENA_REVISION);
+ }
+
+ if (defaultlanguage == 'F') {
+ ladmin_log("Ladmin est prêt." RETCODE);
+ Iprintf("Ladmin est \033[1;32mprêt\033[0m.\n\n");
+ } else {
+ ladmin_log("Ladmin is ready." RETCODE);
+ Iprintf("Ladmin is \033[1;32mready\033[0m.\n\n");
+ }
Connect_login_server();
diff --git a/src/login/login.c b/src/login/login.c
index bf28e48..40da193 100644
--- a/src/login/login.c
+++ b/src/login/login.c
@@ -1863,6 +1863,16 @@ int parse_admin(int fd) {
}
break;
+ case 0x7924: { // [Fate] Itemfrob package: change item IDs
+ if (RFIFOREST(fd) < 10)
+ return 0;
+ charif_sendallwos(-1, RFIFOP(fd, 0), 10); // forward package to char servers
+ RFIFOSKIP(fd,10);
+ WFIFOW(fd,0) = 0x7925;
+ WFIFOSET(fd, 2);
+ break;
+ }
+
case 0x7930: // Request for an account creation
if (RFIFOREST(fd) < 91)
return 0;
diff --git a/src/map/chrif.c b/src/map/chrif.c
index 05fa603..ad3018e 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -23,13 +23,14 @@
#include "npc.h"
#include "pc.h"
#include "nullpo.h"
+#include "itemdb.h"
#ifdef MEMWATCH
#include "memwatch.h"
#endif
static const int packet_len_table[0x20] = {
- 60, 3,-1,27,22,-1, 6,-1, // 2af8-2aff
+ 60, 3,10,27,22,-1, 6,-1, // 2af8-2aff
6,-1,18, 7,-1,49,44, 0, // 2b00-2b07
6,30,-1,10,86, 7,44,34, // 2b08-2b0f
-1,-1,10, 6,11,-1, 0, 0, // 2b10-2b17
@@ -895,6 +896,105 @@ int chrif_char_offline(struct map_session_data *sd)
return 0;
}
+/*========================================
+ * Map item IDs
+ *----------------------------------------
+ */
+
+static void
+ladmin_itemfrob_fix_item(int source, int dest, struct item *item)
+{
+ if (item && item->nameid == source) {
+ item->nameid = dest;
+ item->equip = 0;
+ }
+}
+
+static int ladmin_itemfrob_c2(struct block_list *bl, int source_id, int dest_id)
+{
+#define IFIX(v) if (v == source_id) {v = dest_id; }
+#define FIX(item) ladmin_itemfrob_fix_item(source_id, dest_id, &item)
+
+ if (!bl)
+ return 0;
+
+ switch (bl->type) {
+ case BL_PC: {
+ struct map_session_data *pc = (struct map_session_data *) bl;
+ struct storage *stor = account2storage2(pc->status.account_id);
+ int j;
+
+ for (j = 0; j < MAX_INVENTORY; j++)
+ IFIX(pc->status.inventory[j].nameid);
+ for (j = 0; j < MAX_CART; j++)
+ IFIX(pc->status.cart[j].nameid);
+ IFIX(pc->status.weapon);
+ IFIX(pc->status.shield);
+ IFIX(pc->status.head_top);
+ IFIX(pc->status.head_mid);
+ IFIX(pc->status.head_bottom);
+
+ if (stor)
+ for (j = 0; j < stor->storage_amount; j++)
+ FIX(stor->storage[j]);
+
+ for (j = 0; j < MAX_INVENTORY; j++) {
+ struct item_data *item = pc->inventory_data[j];
+ if (item && item->nameid == source_id) {
+ item->nameid = dest_id;
+ if (item->equip)
+ pc_unequipitem(pc, j, 0);
+ item->nameid = dest_id;
+ }
+ }
+
+
+ break;
+ }
+
+ case BL_MOB: {
+ struct mob_data *mob = (struct mob_data *) bl;
+ int i;
+ for (i = 0; i < mob->lootitem_count; i++)
+ FIX(mob->lootitem[i]);
+ break;
+ }
+
+ case BL_ITEM: {
+ struct flooritem_data *item = (struct flooritem_data *) bl;
+ FIX(item->item_data);
+ break;
+ }
+ }
+#undef FIX
+#undef IFIX
+
+ return 0;
+}
+
+int ladmin_itemfrob_c(struct block_list *bl, va_list va_args)
+{
+ int source_id = va_arg(va_args, int);
+ int dest_id = va_arg(va_args, int);
+ return ladmin_itemfrob_c2(bl, source_id, dest_id);
+}
+
+void ladmin_itemfrob(int fd)
+{
+ int source_id = RFIFOL(fd, 2);
+ int dest_id = RFIFOL(fd, 6);
+ struct block_list *bl = (struct block_list *)map_get_first_session();
+
+ // flooritems
+ map_foreachobject(ladmin_itemfrob_c, 0 /* any object */, source_id, dest_id);
+
+ // player characters (and, hopefully, mobs)
+ while (bl->next) {
+ ladmin_itemfrob_c2(bl, source_id, dest_id);
+ bl = bl->next;
+ }
+}
+
/*==========================================
*
*------------------------------------------
@@ -939,6 +1039,7 @@ int chrif_parse(int fd)
switch(cmd) {
case 0x2af9: chrif_connectack(fd); break;
+ case 0x2afa: ladmin_itemfrob(fd); break;
case 0x2afb: chrif_sendmapack(fd); break;
case 0x2afd: pc_authok(RFIFOL(fd,4), RFIFOL(fd,8), (time_t)RFIFOL(fd,12), RFIFOW(fd, 16), (struct mmo_charstatus*)RFIFOP(fd,18)); break;
case 0x2afe: pc_authfail(RFIFOL(fd,2)); break;