diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/char/char.c | 46 | ||||
-rw-r--r-- | src/char/int_storage.c | 9 | ||||
-rw-r--r-- | src/char/int_storage.h | 1 | ||||
-rw-r--r-- | src/ladmin/ladmin.c | 40 | ||||
-rw-r--r-- | src/login/login.c | 10 | ||||
-rw-r--r-- | src/map/chrif.c | 103 |
6 files changed, 206 insertions, 3 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, franais, deutsch, espaol +// on/off, english, franais, 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) } // AJEgqɃf[^CfbNXiVKqɒ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/ladmin/ladmin.c b/src/ladmin/ladmin.c index 0ae5e0c..3cea295 100644 --- a/src/ladmin/ladmin.c +++ b/src/ladmin/ladmin.c @@ -555,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) @@ -738,6 +740,8 @@ void display_help(char* param, int language) { printf(" 'Premier_id', 'Dernier_id': indique les identifiants de dpart 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"); @@ -983,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"); @@ -1102,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"); @@ -2199,6 +2209,29 @@ int listaccount(char* param, int type) { 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 //-------------------------------------------- @@ -3179,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) { @@ -3355,6 +3390,11 @@ int parse_fromlogin(int fd) { 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; 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; |