diff options
author | Ben Longbons <b.r.longbons@gmail.com> | 2013-06-29 23:23:43 -0700 |
---|---|---|
committer | Ben Longbons <b.r.longbons@gmail.com> | 2013-08-01 15:19:45 -0700 |
commit | 3b98f3439e33b15bba2036c402f9925340fdb2b9 (patch) | |
tree | f6a59330bb747d9cc64f5f83d06e7f76dc01d540 /src/map | |
parent | 8d1480c1be7c9741876d89008277a2b3629a4d01 (diff) | |
download | tmwa-3b98f3439e33b15bba2036c402f9925340fdb2b9.tar.gz tmwa-3b98f3439e33b15bba2036c402f9925340fdb2b9.tar.bz2 tmwa-3b98f3439e33b15bba2036c402f9925340fdb2b9.tar.xz tmwa-3b98f3439e33b15bba2036c402f9925340fdb2b9.zip |
Poison std::string and use the various string classes
Diffstat (limited to 'src/map')
40 files changed, 2706 insertions, 3096 deletions
diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index 1926f83..18ea0e0 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -8,9 +8,12 @@ #include "../common/core.hpp" #include "../common/cxxstdio.hpp" +#include "../common/extract.hpp" +#include "../common/human_time_diff.hpp" +#include "../common/io.hpp" #include "../common/mmo.hpp" -#include "../common/random.hpp" #include "../common/nullpo.hpp" +#include "../common/random.hpp" #include "../common/socket.hpp" #include "../common/timer.hpp" #include "../common/utils2.hpp" @@ -34,7 +37,7 @@ #include "../poison.hpp" #define ATCOMMAND_FUNC(x) static \ -int atcommand_##x(const int fd, dumb_ptr<map_session_data> sd, const char *, const char *message) +int atcommand_##x(const int fd, dumb_ptr<map_session_data> sd, ZString message) ATCOMMAND_FUNC(setup); ATCOMMAND_FUNC(broadcast); ATCOMMAND_FUNC(localbroadcast); @@ -175,13 +178,16 @@ ATCOMMAND_FUNC(doomspot); *AtCommandInfo atcommand_info[]構造体の定義 *------------------------------------------ */ - struct AtCommandInfo { - const char *command; + ZString command; int level; - int(*proc)(const int, dumb_ptr<map_session_data>, - const char *command, const char *message); + int (*proc)(const int fd, dumb_ptr<map_session_data> sd, ZString message); + + + AtCommandInfo(ZString c, int l, int (*p)(const int, dumb_ptr<map_session_data>, ZString)) + : command(c), level(l), proc(p) + {} }; // First char of commands is configured in atcommand_athena.conf. Leave @ in this list for default value. @@ -335,9 +341,50 @@ AtCommandInfo atcommand_info[] = {"@doomspot", 60, atcommand_doomspot}, // add new commands before this line - {NULL, 1, NULL} + {ZString(), 1, nullptr} }; +// If your last arg is not a ZString, you probably wanted extract() +// but not always ... +static +bool asplit(ZString raw, ZString *last) +{ + *last = raw; + return true; +} + +// but this case is just so common and useful. In fact, is the previous ever used otherwise? +static +bool asplit(ZString raw, CharName *last) +{ + if (raw.size() < 4 || raw.size() > 23) + return false; + *last = stringish<CharName>(raw); + return true; +} + +// huh. +static +bool asplit(ZString raw, NpcName *last) +{ + if (!raw || raw.size() > 23) + return false; + *last = stringish<NpcName>(raw); + return true; +} + +// This differs from extract() in that it does not consume extra spaces. +template<class F, class... R, typename=typename std::enable_if<sizeof...(R) != 0>::type> +bool asplit(ZString raw, F *first_arg, R *... rest_args) +{ + ZString::iterator it = std::find(raw.begin(), raw.end(), ' '); + XString frist = raw.xislice_h(it); + while (*it == ' ') + ++it; + ZString rest = raw.xislice_t(it); + return extract(frist, first_arg) && asplit(rest, rest_args...); +} + /*========================================== * get_atcommand_level @コマンドの必要レベルを取得 *------------------------------------------ @@ -357,28 +404,28 @@ FILE *get_gm_log(); /*======================================== * At-command logging */ -void log_atcommand(dumb_ptr<map_session_data> sd, const_string cmd) +void log_atcommand(dumb_ptr<map_session_data> sd, XString cmd) { FILE *fp = get_gm_log(); if (!fp) return; timestamp_seconds_buffer tmpstr; stamp_time(tmpstr); - fprintf(fp, "[%s] %s(%d,%d) %s(%d) : ", + FPRINTF(fp, "[%s] %s(%d,%d) %s(%d) : ", tmpstr, sd->bl_m->name_, sd->bl_x, sd->bl_y, sd->status.name, sd->status.account_id); fwrite(cmd.data(), 1, cmd.size(), fp); } -std::string gm_logfile_name; +FString gm_logfile_name; /*========================================== * Log a timestamped line to GM log file *------------------------------------------ */ FILE *get_gm_log() { - if (gm_logfile_name.empty()) + if (!gm_logfile_name) return NULL; struct tm ctime = TimeT::now(); @@ -393,65 +440,56 @@ FILE *get_gm_log() return gm_logfile; last_logfile_nr = logfile_nr; - std::string fullname = STRPRINTF("%s.%04d-%02d", + FString fullname = STRPRINTF("%s.%04d-%02d", gm_logfile_name, year, month); if (gm_logfile) - fclose_(gm_logfile); + fclose(gm_logfile); - gm_logfile = fopen_(fullname.c_str(), "a"); + gm_logfile = fopen(fullname.c_str(), "a"); if (!gm_logfile) { perror("GM log file"); - gm_logfile_name.clear(); + gm_logfile_name = FString(); } return gm_logfile; } static -AtCommandInfo *atcommand(const int level, const char *message); +AtCommandInfo *atcommand(const int level, ZString message); /*========================================== *is_atcommand @コマンドに存在するかどうか確認する *------------------------------------------ */ bool is_atcommand(const int fd, dumb_ptr<map_session_data> sd, - const char *message, int gmlvl) + ZString message, int gmlvl) { nullpo_retr(false, sd); - if (!message || message[0] != '@') + if (!message.startswith('@')) return false; AtCommandInfo *info = atcommand(gmlvl > 0 ? gmlvl : pc_isGM(sd), message); if (!info) { - std::string output = STRPRINTF("GM command not found: %s", + FString output = STRPRINTF("GM command not found: %s", message); clif_displaymessage(fd, output); return true; // don't show in chat } { - const char *str = message; - const char *p = message; - // split the first word - while (*p && !isspace(*p)) - p++; - size_t len = p - str; - char command[len + 1]; - strzcpy(command, str, len + 1); - // skip the spaces; pass as argv - while (isspace(*p)) - p++; + XString command; + ZString arg; + asplit(message, &command, &arg); { - if (info->proc(fd, sd, command, p) != 0) + if (info->proc(fd, sd, arg) != 0) { // Command can not be executed - const char *command_ = command; - std::string output = STRPRINTF("%s failed.", command_); + FString output = STRPRINTF("%s failed.", FString(command)); clif_displaymessage(fd, output); } else @@ -469,28 +507,27 @@ bool is_atcommand(const int fd, dumb_ptr<map_session_data> sd, * *------------------------------------------ */ -AtCommandInfo *atcommand(const int level, const char *message) +AtCommandInfo *atcommand(const int level, ZString message) { - const char *p = message; + ZString p = message; if (battle_config.atc_gmonly != 0 && !level) // level = pc_isGM(sd) return nullptr; - if (!p || !*p) + if (!p) { FPRINTF(stderr, "at command message is empty\n"); return nullptr; } - if (*p == '@') - { // check first char. - char command[101]; + if (p.startswith('@')) + { + ZString::iterator space = std::find(p.begin(), p.end(), ' '); + XString command = p.xislice_h(space); int i = 0; - sscanf(p, "%100s", command); - command[sizeof(command) - 1] = '\0'; while (atcommand_info[i].command) { - if (strcasecmp(command, atcommand_info[i].command) == 0 + if (command == atcommand_info[i].command && level >= atcommand_info[i].level) { return &atcommand_info[i]; @@ -522,12 +559,10 @@ void atkillmonster_sub(dumb_ptr<block_list> bl, int flag) *------------------------------------------ */ static -AtCommandInfo *get_atcommandinfo_byname(const char *name) +AtCommandInfo *get_atcommandinfo_byname(XString name) { - int i; - - for (i = 0; atcommand_info[i].command; i++) - if (strcasecmp(atcommand_info[i].command + 1, name) == 0) + for (int i = 0; atcommand_info[i].command; i++) + if (atcommand_info[i].command.xslice_t(1) == name) return &atcommand_info[i]; return NULL; @@ -537,39 +572,36 @@ AtCommandInfo *get_atcommandinfo_byname(const char *name) * *------------------------------------------ */ -int atcommand_config_read(const char *cfgName) +int atcommand_config_read(ZString cfgName) { - char line[1024], w1[1024], w2[1024]; - AtCommandInfo *p; - FILE *fp; - - if ((fp = fopen_(cfgName, "r")) == NULL) + std::ifstream in(cfgName.c_str()); + if (!in.is_open()) { PRINTF("At commands configuration file not found: %s\n", cfgName); return 1; } - while (fgets(line, sizeof(line) - 1, fp)) + FString line; + while (io::getline(in, line)) { - if (line[0] == '/' && line[1] == '/') - continue; - - if (sscanf(line, "%1023[^:]:%1023s", w1, w2) != 2) + SString w1; + TString w2; + if (!split_key_value(line, &w1, &w2)) continue; - p = get_atcommandinfo_byname(w1); + AtCommandInfo *p = get_atcommandinfo_byname(w1); if (p != NULL) { - p->level = atoi(w2); + p->level = atoi(w2.c_str()); if (p->level > 100) p->level = 100; else if (p->level < 0) p->level = 0; } - - if (strcasecmp(w1, "import") == 0) + else if (w1 == "import") atcommand_config_read(w2); + else + PRINTF("%s: bad line: %s\n", cfgName, line); } - fclose_(fp); return 0; } @@ -585,42 +617,41 @@ int atcommand_config_read(const char *cfgName) *------------------------------------------ */ int atcommand_setup(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char character[100] {}; int level = 1; + CharName character; - if (!message || !*message - || sscanf(message, "%d %99[^\n]", &level, character) < 2) + if (!asplit(message, &level, &character)) { clif_displaymessage(fd, "Usage: @setup <level> <char name>"); return -1; } level--; - std::string buf; + FString buf; buf = STRPRINTF("-255 %s", character); - atcommand_character_baselevel(fd, sd, "@charbaselvl", buf.c_str()); + atcommand_character_baselevel(fd, sd, buf); buf = STRPRINTF("%d %s", level, character); - atcommand_character_baselevel(fd, sd, "@charbaselvl", buf.c_str()); + atcommand_character_baselevel(fd, sd, buf); // Emote skill buf = STRPRINTF("1 1 %s", character); - atcommand_skill_learn(fd, sd, "@skill-learn", buf.c_str()); + atcommand_skill_learn(fd, sd, buf); // Trade skill buf = STRPRINTF("2 1 %s", character); - atcommand_skill_learn(fd, sd, "@skill-learn", buf.c_str()); + atcommand_skill_learn(fd, sd, buf); // Party skill STRPRINTF("2 2 %s", character); - atcommand_skill_learn(fd, sd, "@skill-learn", buf.c_str()); + atcommand_skill_learn(fd, sd, buf); STRPRINTF("018-1.gat 24 98 %s", character); - atcommand_charwarp(fd, sd, "@charwarp", buf.c_str()); + atcommand_charwarp(fd, sd, buf); - return (0); + return 0; } @@ -629,19 +660,16 @@ int atcommand_setup(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_charwarp(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char map_name[100] {}; - char character[100] {}; + MapName map_name; + CharName character; int x = 0, y = 0; - dumb_ptr<map_session_data> pl_sd; - if (!message || !*message - || sscanf(message, "%99s %d %d %99[^\n]", map_name, &x, &y, - character) < 4) + if (!asplit(message, &map_name, &x, &y, &character)) { clif_displaymessage(fd, - "Usage: @charwarp/@rura+ <mapname> <x> <y> <char name>"); + "Usage: @charwarp/@rura+ <mapname> <x> <y> <char name>"); return -1; } @@ -649,13 +677,13 @@ int atcommand_charwarp(const int fd, dumb_ptr<map_session_data> sd, x = random_::in(1, 399); if (y <= 0) y = random_::in(1, 399); - if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat) - strcat(map_name, ".gat"); - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd) { if (pc_isGM(sd) >= pc_isGM(pl_sd)) - { // you can rura+ only lower or same GM level + { + // you can rura+ only lower or same GM level if (x > 0 && x < 800 && y > 0 && y < 800) { map_local *m = map_mapname2mapid(map_name); @@ -663,14 +691,14 @@ int atcommand_charwarp(const int fd, dumb_ptr<map_session_data> sd, && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { clif_displaymessage(fd, - "You are not authorised to warp someone to this map."); + "You are not authorised to warp someone to this map."); return -1; } if (pl_sd->bl_m && pl_sd->bl_m->flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { clif_displaymessage(fd, - "You are not authorised to warp this player from its actual map."); + "You are not authorised to warp this player from its actual map."); return -1; } if (pc_setpos(pl_sd, map_name, x, y, BeingRemoveWhy::WARPED) == 0) @@ -710,16 +738,16 @@ int atcommand_charwarp(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_warp(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char map_name[100] {}; + MapName map_name; int x = 0, y = 0; - if (!message || !*message - || sscanf(message, "%99s %d %d", map_name, &x, &y) < 1) + if (!message + || !extract(message, record<' ', 1>(&map_name, &x, &y))) { clif_displaymessage(fd, - "Please, enter a map (usage: @warp <mapname> <x> <y>)."); + "Please, enter a map (usage: @warp <mapname> <x> <y>)."); return -1; } @@ -728,9 +756,6 @@ int atcommand_warp(const int fd, dumb_ptr<map_session_data> sd, if (y <= 0) y = random_::in(1, 399); - if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat) - strcat(map_name, ".gat"); - if (x > 0 && x < 800 && y > 0 && y < 800) { map_local *m = map_mapname2mapid(map_name); @@ -738,14 +763,14 @@ int atcommand_warp(const int fd, dumb_ptr<map_session_data> sd, && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { clif_displaymessage(fd, - "You are not authorised to warp you to this map."); + "You are not authorised to warp you to this map."); return -1; } if (sd->bl_m && sd->bl_m->flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { clif_displaymessage(fd, - "You are not authorised to warp you from your actual map."); + "You are not authorised to warp you from your actual map."); return -1; } if (pc_setpos(sd, map_name, x, y, BeingRemoveWhy::WARPED) == 0) @@ -770,20 +795,18 @@ int atcommand_warp(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_where(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char character[100] {}; - dumb_ptr<map_session_data> pl_sd; + CharName character; + extract(message, &character); - if (sscanf(message, "%99[^\n]", character) < 1) - strcpy(character, sd->status.name); - - if ((pl_sd = map_nick2sd(character)) != NULL && + dumb_ptr<map_session_data> pl_sd = character.to__actual() ? map_nick2sd(character) : sd; + if (pl_sd != NULL && !((battle_config.hide_GM_session || bool(pl_sd->status.option & Option::HIDE)) && (pc_isGM(pl_sd) > pc_isGM(sd)))) { // you can look only lower or same level - std::string output = STRPRINTF("%s: %s (%d,%d)", + FString output = STRPRINTF("%s: %s (%d,%d)", pl_sd->status.name, pl_sd->mapname_, pl_sd->bl_x, pl_sd->bl_y); clif_displaymessage(fd, output); @@ -802,36 +825,36 @@ int atcommand_where(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_goto(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char character[100] {}; - dumb_ptr<map_session_data> pl_sd; + CharName character; - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) + if (!asplit(message, &character)) { clif_displaymessage(fd, - "Please, enter a player name (usage: @jumpto/@warpto/@goto <char name>)."); + "Please, enter a player name (usage: @jumpto/@warpto/@goto <char name>)."); return -1; } - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { if (pl_sd->bl_m && pl_sd->bl_m->flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { clif_displaymessage(fd, - "You are not authorised to warp you to the map of this player."); + "You are not authorised to warp you to the map of this player."); return -1; } if (sd->bl_m && sd->bl_m->flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { clif_displaymessage(fd, - "You are not authorised to warp you from your actual map."); + "You are not authorised to warp you from your actual map."); return -1; } pc_setpos(sd, pl_sd->mapname_, pl_sd->bl_x, pl_sd->bl_y, BeingRemoveWhy::WARPED); - std::string output = STRPRINTF("Jump to %s", character); + FString output = STRPRINTF("Jump to %s", character); clif_displaymessage(fd, output); } else @@ -848,10 +871,11 @@ int atcommand_goto(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_jump(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { int x = 0, y = 0; - sscanf(message, "%d %d", &x, &y); + // may fail + extract(message, record<' '>(&x, &y)); if (x <= 0) x = random_::in(1, 399); @@ -863,18 +887,18 @@ int atcommand_jump(const int fd, dumb_ptr<map_session_data> sd, && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { clif_displaymessage(fd, - "You are not authorised to warp you to your actual map."); + "You are not authorised to warp you to your actual map."); return -1; } if (sd->bl_m && sd->bl_m->flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { clif_displaymessage(fd, - "You are not authorised to warp you from your actual map."); + "You are not authorised to warp you from your actual map."); return -1; } pc_setpos(sd, sd->mapname_, x, y, BeingRemoveWhy::WARPED); - std::string output = STRPRINTF("Jump to %d %d", x, y); + FString output = STRPRINTF("Jump to %d %d", x, y); clif_displaymessage(fd, output); } else @@ -891,17 +915,12 @@ int atcommand_jump(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_who(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { int count; int pl_GM_level, GM_level; - char match_text[100] {}; - char player_name[24] {}; - - if (sscanf(message, "%99[^\n]", match_text) < 1) - strcpy(match_text, ""); - for (int j = 0; match_text[j]; j++) - match_text[j] = tolower(match_text[j]); + VString<23> match_text = message; + match_text = match_text.to_lower(); count = 0; GM_level = pc_isGM(sd); @@ -919,13 +938,11 @@ int atcommand_who(const int fd, dumb_ptr<map_session_data> sd, && (pl_GM_level > GM_level))) { // you can look only lower or same level - strzcpy(player_name, pl_sd->status.name, 24); - for (int j = 0; player_name[j]; j++) - player_name[j] = tolower(player_name[j]); - if (strstr(player_name, match_text) != NULL) + VString<23> player_name = pl_sd->status.name.to__lower(); + if (player_name.contains_seq(match_text)) { // search with no case sensitive - std::string output; + FString output; if (pl_GM_level > 0) output = STRPRINTF( "Name: %s (GM:%d) | Location: %s %d %d", @@ -949,7 +966,7 @@ int atcommand_who(const int fd, dumb_ptr<map_session_data> sd, clif_displaymessage(fd, "1 player found."); else { - std::string output = STRPRINTF("%d players found.", count); + FString output = STRPRINTF("%d players found.", count); clif_displaymessage(fd, output); } @@ -961,18 +978,14 @@ int atcommand_who(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_whogroup(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { int count; int pl_GM_level, GM_level; - char match_text[100] {}; - char player_name[24] {}; struct party *p; - if (sscanf(message, "%99[^\n]", match_text) < 1) - strcpy(match_text, ""); - for (int j = 0; match_text[j]; j++) - match_text[j] = tolower(match_text[j]); + VString<23> match_text = message; + match_text = match_text.to_lower(); count = 0; GM_level = pc_isGM(sd); @@ -990,15 +1003,13 @@ int atcommand_whogroup(const int fd, dumb_ptr<map_session_data> sd, && (pl_GM_level > GM_level))) { // you can look only lower or same level - strzcpy(player_name, pl_sd->status.name, 24); - for (int j = 0; player_name[j]; j++) - player_name[j] = tolower(player_name[j]); - if (strstr(player_name, match_text) != NULL) + VString<23> player_name = pl_sd->status.name.to__lower(); + if (player_name.contains_seq(match_text)) { // search with no case sensitive p = party_search(pl_sd->status.party_id); - const char *temp0 = p ? p->name : "None"; - std::string output; + PartyName temp0 = p ? p->name : stringish<PartyName>("None"); + FString output; if (pl_GM_level > 0) output = STRPRINTF( "Name: %s (GM:%d) | Party: '%s'", @@ -1016,7 +1027,7 @@ int atcommand_whogroup(const int fd, dumb_ptr<map_session_data> sd, clif_displaymessage(fd, "1 player found."); else { - std::string output = STRPRINTF("%d players found.", count); + FString output = STRPRINTF("%d players found.", count); clif_displaymessage(fd, output); } @@ -1028,20 +1039,15 @@ int atcommand_whogroup(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_whomap(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { int count; int pl_GM_level, GM_level; map_local *map_id; - char map_name[100] {}; - if (!message || !*message) - map_id = sd->bl_m; - else { - sscanf(message, "%99s", map_name); - if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat) - strcat(map_name, ".gat"); + MapName map_name; + extract(message, &map_name); map_id = map_mapname2mapid(map_name); if (map_id == nullptr) map_id = sd->bl_m; @@ -1064,7 +1070,7 @@ int atcommand_whomap(const int fd, dumb_ptr<map_session_data> sd, { // you can look only lower or same level if (pl_sd->bl_m == map_id) { - std::string output; + FString output; if (pl_GM_level > 0) output = STRPRINTF( "Name: %s (GM:%d) | Location: %s %d %d", @@ -1082,7 +1088,7 @@ int atcommand_whomap(const int fd, dumb_ptr<map_session_data> sd, } } - std::string output = STRPRINTF("%d players found in map '%s'.", + FString output = STRPRINTF("%d players found in map '%s'.", count, map_id->name_); clif_displaymessage(fd, output); @@ -1094,21 +1100,16 @@ int atcommand_whomap(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_whomapgroup(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { int count; int pl_GM_level, GM_level; - char map_name[100] {}; struct party *p; map_local *map_id; - if (!message || !*message) - map_id = sd->bl_m; - else { - sscanf(message, "%99s", map_name); - if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat) - strcat(map_name, ".gat"); + MapName map_name; + extract(message, &map_name); map_id = map_mapname2mapid(map_name); if (map_id == nullptr) map_id = sd->bl_m; @@ -1133,8 +1134,8 @@ int atcommand_whomapgroup(const int fd, dumb_ptr<map_session_data> sd, if (pl_sd->bl_m == map_id) { p = party_search(pl_sd->status.party_id); - const char *temp0 = p ? p->name : "None"; - std::string output; + PartyName temp0 = p ? p->name : stringish<PartyName>("None"); + FString output; if (pl_GM_level > 0) output = STRPRINTF("Name: %s (GM:%d) | Party: '%s'", pl_sd->status.name, pl_GM_level, temp0); @@ -1148,7 +1149,7 @@ int atcommand_whomapgroup(const int fd, dumb_ptr<map_session_data> sd, } } - std::string output; + FString output; if (count == 0) output = STRPRINTF("No player found in map '%s'.", map_id->name_); else if (count == 1) @@ -1167,18 +1168,14 @@ int atcommand_whomapgroup(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_whogm(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { int count; int pl_GM_level, GM_level; - char match_text[100] {}; - char player_name[24] {}; struct party *p; - if (sscanf(message, "%99[^\n]", match_text) < 1) - strcpy(match_text, ""); - for (int j = 0; match_text[j]; j++) - match_text[j] = tolower(match_text[j]); + VString<23> match_text = message; + match_text = match_text.to_lower(); count = 0; GM_level = pc_isGM(sd); @@ -1198,13 +1195,11 @@ int atcommand_whogm(const int fd, dumb_ptr<map_session_data> sd, && (pl_GM_level > GM_level))) { // you can look only lower or same level - strzcpy(player_name, pl_sd->status.name, 24); - for (int j = 0; player_name[j]; j++) - player_name[j] = tolower(player_name[j]); - if (strstr(player_name, match_text) != NULL) + VString<23> player_name = pl_sd->status.name.to__lower(); + if (player_name.contains_seq(match_text)) { // search with no case sensitive - std::string output; + FString output; output = STRPRINTF( "Name: %s (GM:%d) | Location: %s %d %d", pl_sd->status.name, pl_GM_level, @@ -1217,7 +1212,7 @@ int atcommand_whogm(const int fd, dumb_ptr<map_session_data> sd, pl_sd->status.job_level); clif_displaymessage(fd, output); p = party_search(pl_sd->status.party_id); - const char *temp0 = p ? p->name : "None"; + PartyName temp0 = p ? p->name : stringish<PartyName>("None"); output = STRPRINTF( " Party: '%s'", temp0); @@ -1235,7 +1230,7 @@ int atcommand_whogm(const int fd, dumb_ptr<map_session_data> sd, clif_displaymessage(fd, "1 GM found."); else { - std::string output = STRPRINTF("%d GMs found.", count); + FString output = STRPRINTF("%d GMs found.", count); clif_displaymessage(fd, output); } @@ -1247,7 +1242,7 @@ int atcommand_whogm(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_save(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { nullpo_retr(-1, sd); @@ -1264,7 +1259,7 @@ int atcommand_save(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_load(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { map_local *m = map_mapname2mapid(sd->status.save_point.map_); if (m != nullptr && m->flag.nowarpto @@ -1294,11 +1289,11 @@ int atcommand_load(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_speed(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - if (!message || !*message) + if (!message) { - std::string output = STRPRINTF( + FString output = STRPRINTF( "Please, enter a speed value (usage: @speed <%d-%d>).", static_cast<uint32_t>(MIN_WALK_SPEED.count()), static_cast<uint32_t>(MAX_WALK_SPEED.count())); @@ -1306,7 +1301,7 @@ int atcommand_speed(const int fd, dumb_ptr<map_session_data> sd, return -1; } - interval_t speed = static_cast<interval_t>(atoi(message)); + interval_t speed = static_cast<interval_t>(atoi(message.c_str())); if (speed >= MIN_WALK_SPEED && speed <= MAX_WALK_SPEED) { sd->speed = speed; @@ -1317,7 +1312,7 @@ int atcommand_speed(const int fd, dumb_ptr<map_session_data> sd, } else { - std::string output = STRPRINTF( + FString output = STRPRINTF( "Please, enter a valid speed value (usage: @speed <%d-%d>).", static_cast<uint32_t>(MIN_WALK_SPEED.count()), static_cast<uint32_t>(MAX_WALK_SPEED.count())); @@ -1333,7 +1328,7 @@ int atcommand_speed(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_storage(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { struct storage *stor; //changes from Freya/Yor nullpo_retr(-1, sd); @@ -1361,24 +1356,21 @@ int atcommand_storage(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_option(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - int param1_ = 0, param2_ = 0, param3_ = 0; nullpo_retr(-1, sd); - if (!message || !*message - || sscanf(message, "%d %d %d", ¶m1_, ¶m2_, ¶m3_) < 1 - || param1_ < 0 || param2_ < 0 || param3_ < 0) + Opt1 param1 = Opt1::ZERO; + Opt2 param2 = Opt2::ZERO; + Option param3 = Option::ZERO; + + if (!extract(message, record<',', 1>(¶m1, ¶m2, ¶m3))) { clif_displaymessage(fd, - "Please, enter at least a option (usage: @option <param1:0+> <param2:0+> <param3:0+>)."); + "Please, enter at least a option (usage: @option <param1:0+> <param2:0+> <param3:0+>)."); return -1; } - Opt1 param1 = Opt1(param1_); - Opt2 param2 = Opt2(param2_); - Option param3 = Option(param3_); - sd->opt1 = param1; sd->opt2 = param2; sd->status.option = param3; @@ -1395,7 +1387,7 @@ int atcommand_option(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_hide(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { if (bool(sd->status.option & Option::HIDE)) { @@ -1417,7 +1409,7 @@ int atcommand_hide(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_die(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { pc_damage(NULL, sd, sd->status.hp + 1); clif_displaymessage(fd, "A pity! You've died."); @@ -1430,19 +1422,19 @@ int atcommand_die(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_kill(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char character[100] {}; - dumb_ptr<map_session_data> pl_sd; + CharName character; - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) + if (!asplit(message, &character)) { clif_displaymessage(fd, - "Please, enter a player name (usage: @kill <char name>)."); + "Please, enter a player name (usage: @kill <char name>)."); return -1; } - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can kill only lower or same level @@ -1469,7 +1461,7 @@ int atcommand_kill(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_alive(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { sd->status.hp = sd->status.max_hp; sd->status.sp = sd->status.max_sp; @@ -1489,12 +1481,12 @@ int atcommand_alive(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_kami(const int fd, dumb_ptr<map_session_data>, - const char *, const char *message) + ZString message) { - if (!message || !*message) + if (!message) { clif_displaymessage(fd, - "Please, enter a message (usage: @kami <message>)."); + "Please, enter a message (usage: @kami <message>)."); return -1; } @@ -1508,11 +1500,11 @@ int atcommand_kami(const int fd, dumb_ptr<map_session_data>, *------------------------------------------ */ int atcommand_heal(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { int hp = 0, sp = 0; // [Valaris] thanks to fov - sscanf(message, "%d %d", &hp, &sp); + extract(message, record<' '>(&hp, &sp)); if (hp == 0 && sp == 0) { @@ -1556,18 +1548,17 @@ int atcommand_heal(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_item(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char item_name[100] {}; + ItemName item_name; int number = 0, item_id; struct item_data *item_data; int get_count, i; - if (!message || !*message - || sscanf(message, "%99s %d", item_name, &number) < 1) + if (!extract(message, record<' ', 1>(&item_name, &number))) { clif_displaymessage(fd, - "Please, enter an item name/id (usage: @item <item name or ID> [quantity])."); + "Please, enter an item name/id (usage: @item <item name or ID> [quantity])."); return -1; } @@ -1576,7 +1567,7 @@ int atcommand_item(const int fd, dumb_ptr<map_session_data> sd, item_id = 0; if ((item_data = itemdb_searchname(item_name)) != NULL || - (item_data = itemdb_exists(atoi(item_name))) != NULL) + (item_data = itemdb_exists(atoi(item_name.c_str()))) != NULL) item_id = item_data->nameid; if (item_id >= 500) @@ -1615,7 +1606,7 @@ int atcommand_item(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_itemreset(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { int i; @@ -1635,7 +1626,7 @@ int atcommand_itemreset(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_itemcheck(const int, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { pc_checkitem(sd); @@ -1647,14 +1638,14 @@ int atcommand_itemcheck(const int, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_baselevelup(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { int level, i; - if (!message || !*message || (level = atoi(message)) == 0) + if (!extract(message, &level) || !level) { clif_displaymessage(fd, - "Please, enter a level adjustement (usage: @blvl <number of levels>)."); + "Please, enter a level adjustement (usage: @blvl <number of levels>)."); return -1; } @@ -1713,14 +1704,14 @@ int atcommand_baselevelup(const int fd, dumb_ptr<map_session_data> sd, // TODO: merge this with pc_setparam(SP::JOBLEVEL) // then fix the funny 50 and/or 10 limitation. int atcommand_joblevelup(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { int up_level = 50, level; - if (!message || !*message || (level = atoi(message)) == 0) + if (!extract(message, &level) || !level) { clif_displaymessage(fd, - "Please, enter a level adjustement (usage: @jlvl <number of levels>)."); + "Please, enter a level adjustement (usage: @jlvl <number of levels>)."); return -1; } @@ -1775,20 +1766,23 @@ int atcommand_joblevelup(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_help(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { - std::ifstream in(help_txt); + std::ifstream in(help_txt.c_str()); if (in.is_open()) { clif_displaymessage(fd, "Help commands:"); int gm_level = pc_isGM(sd); - std::string line; - while (std::getline(in, line)) + FString line; + while (io::getline(in, line)) { - std::string w1, w2; + SString w1; + TString w2; if (!split_key_value(line, &w1, &w2)) continue; - if (gm_level >= atoi(w1.c_str())) + int level; + extract(w1, &level); + if (gm_level >= level) clif_displaymessage(fd, w2); } } @@ -1806,14 +1800,12 @@ int atcommand_help(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_gm(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char password[100] {}; - - if (!message || !*message || sscanf(message, "%99[^\n]", password) < 1) + if (!message) { clif_displaymessage(fd, - "Please, enter a password (usage: @gm <password>)."); + "Please, enter a password (usage: @gm <password>)."); return -1; } @@ -1823,8 +1815,7 @@ int atcommand_gm(const int fd, dumb_ptr<map_session_data> sd, return -1; } else - chrif_changegm(sd->status.account_id, password, - strlen(password) + 1); + chrif_changegm(sd->status.account_id, message); return 0; } @@ -1834,7 +1825,7 @@ int atcommand_gm(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_pvpoff(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { if (battle_config.pk_mode) { //disable command if server is in PK mode [Valaris] @@ -1874,7 +1865,7 @@ int atcommand_pvpoff(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_pvpon(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { if (battle_config.pk_mode) { //disable command if server is in PK mode [Valaris] @@ -1918,15 +1909,13 @@ int atcommand_pvpon(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_model(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { int hair_style = 0, hair_color = 0, cloth_color = 0; - if (!message || !*message - || sscanf(message, "%d %d %d", &hair_style, &hair_color, - &cloth_color) < 1) + if (!extract(message, record<' ', 1>(&hair_style, &hair_color, &cloth_color))) { - std::string output = STRPRINTF( + FString output = STRPRINTF( "Please, enter at least a value (usage: @model <hair ID: %d-%d> <hair color: %d-%d> <clothes color: %d-%d>).", MIN_HAIR_STYLE, MAX_HAIR_STYLE, MIN_HAIR_COLOR, MAX_HAIR_COLOR, @@ -1960,13 +1949,13 @@ int atcommand_model(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_dye(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { int cloth_color = 0; - if (!message || !*message || sscanf(message, "%d", &cloth_color) < 1) + if (!extract(message, &cloth_color)) { - std::string output = STRPRINTF( + FString output = STRPRINTF( "Please, enter a clothes color (usage: @dye/@ccolor <clothes color: %d-%d>).", MIN_CLOTH_COLOR, MAX_CLOTH_COLOR); clif_displaymessage(fd, output); @@ -1994,13 +1983,13 @@ int atcommand_dye(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_hair_style(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { int hair_style = 0; - if (!message || !*message || sscanf(message, "%d", &hair_style) < 1) + if (!extract(message, &hair_style)) { - std::string output = STRPRINTF( + FString output = STRPRINTF( "Please, enter a hair style (usage: @hairstyle/@hstyle <hair ID: %d-%d>).", MIN_HAIR_STYLE, MAX_HAIR_STYLE); clif_displaymessage(fd, output); @@ -2028,13 +2017,13 @@ int atcommand_hair_style(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_hair_color(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { int hair_color = 0; - if (!message || !*message || sscanf(message, "%d", &hair_color) < 1) + if (!extract(message, &hair_color)) { - std::string output = STRPRINTF( + FString output = STRPRINTF( "Please, enter a hair color (usage: @haircolor/@hcolor <hair color: %d-%d>).", MIN_HAIR_COLOR, MAX_HAIR_COLOR); clif_displaymessage(fd, output); @@ -2062,9 +2051,9 @@ int atcommand_hair_color(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_spawn(const int fd, dumb_ptr<map_session_data> sd, - const char *command, const char *message) + ZString message) { - char monster[100] {}; + MobName monster; int mob_id; int number = 0; int x = 0, y = 0; @@ -2072,8 +2061,7 @@ int atcommand_spawn(const int fd, dumb_ptr<map_session_data> sd, int i, j, k; int mx, my, range; - if (!message || !*message - || sscanf(message, "%99s %d %d %d", monster, &number, &x, &y) < 1) + if (!extract(message, record<' ', 1>(&monster, &number, &x, &y))) { clif_displaymessage(fd, "Give a monster name/id please."); return -1; @@ -2081,7 +2069,7 @@ int atcommand_spawn(const int fd, dumb_ptr<map_session_data> sd, // If monster identifier/name argument is a name if ((mob_id = mobdb_searchname(monster)) == 0) // check name first (to avoid possible name begining by a number) - mob_id = mobdb_checkid(atoi(monster)); + mob_id = mobdb_checkid(atoi(monster.c_str())); if (mob_id == 0) { @@ -2089,12 +2077,6 @@ int atcommand_spawn(const int fd, dumb_ptr<map_session_data> sd, return -1; } - if (mob_id == 1288) - { - clif_displaymessage(fd, "Cannot spawn emperium."); - return -1; - } - if (number <= 0) number = 1; @@ -2104,8 +2086,8 @@ int atcommand_spawn(const int fd, dumb_ptr<map_session_data> sd, number = battle_config.atc_spawn_quantity_limit; if (battle_config.etc_log) - PRINTF("%s monster='%s' id=%d count=%d (%d,%d)\n", command, monster, - mob_id, number, x, y); + PRINTF("@spawn monster='%s' id=%d count=%d (%d,%d)\n", + monster, mob_id, number, x, y); count = 0; range = sqrt(number) / 2; @@ -2125,7 +2107,7 @@ int atcommand_spawn(const int fd, dumb_ptr<map_session_data> sd, my = sd->bl_y + random_::in(-range / 2, range / 2); else my = y; - k = mob_once_spawn(sd, "this", mx, my, "", mob_id, 1, ""); + k = mob_once_spawn(sd, MOB_THIS_MAP, mx, my, MobName(), mob_id, 1, NpcEvent()); } count += (k != 0) ? 1 : 0; } @@ -2135,7 +2117,7 @@ int atcommand_spawn(const int fd, dumb_ptr<map_session_data> sd, clif_displaymessage(fd, "All monster summoned!"); else { - std::string output = STRPRINTF("%d monster(s) summoned!", + FString output = STRPRINTF("%d monster(s) summoned!", count); clif_displaymessage(fd, output); } @@ -2154,17 +2136,12 @@ int atcommand_spawn(const int fd, dumb_ptr<map_session_data> sd, */ static void atcommand_killmonster_sub(const int fd, dumb_ptr<map_session_data> sd, - const char *message, const int drop) + ZString message, const int drop) { - char map_name[100] {}; - map_local *map_id; - if (!message || !*message || sscanf(message, "%99s", map_name) < 1) - map_id = sd->bl_m; - else { - if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat) - strcat(map_name, ".gat"); + MapName map_name; + extract(message, &map_name); map_id = map_mapname2mapid(map_name); if (map_id == nullptr) map_id = sd->bl_m; @@ -2177,8 +2154,6 @@ void atcommand_killmonster_sub(const int fd, dumb_ptr<map_session_data> sd, BL::MOB); clif_displaymessage(fd, "All monsters killed!"); - - return; } /*========================================== @@ -2186,7 +2161,7 @@ void atcommand_killmonster_sub(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_killmonster(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { atcommand_killmonster_sub(fd, sd, message, 1); @@ -2202,7 +2177,7 @@ void atlist_nearby_sub(dumb_ptr<block_list> bl, int fd) { nullpo_retv(bl); - std::string buf = STRPRINTF(" - \"%s\"", + FString buf = STRPRINTF(" - \"%s\"", bl->as_player()->status.name); clif_displaymessage(fd, buf); } @@ -2212,7 +2187,7 @@ void atlist_nearby_sub(dumb_ptr<block_list> bl, int fd) *------------------------------------------ */ int atcommand_list_nearby(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { clif_displaymessage(fd, "Nearby players:"); map_foreachinarea(std::bind(atlist_nearby_sub, ph::_1, fd), @@ -2229,7 +2204,7 @@ int atcommand_list_nearby(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_killmonster2(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { atcommand_killmonster_sub(fd, sd, message, 0); @@ -2241,13 +2216,13 @@ int atcommand_killmonster2(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_gat(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { int y; for (y = 2; y >= -2; y--) { - std::string output = STRPRINTF( + FString output = STRPRINTF( "%s (x= %d, y= %d) %02X %02X %02X %02X %02X", sd->bl_m->name_, sd->bl_x - 2, sd->bl_y + y, map_getcell(sd->bl_m, sd->bl_x - 2, sd->bl_y + y), @@ -2266,18 +2241,19 @@ int atcommand_gat(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_packet(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - int type = 0, flag = 0; + StatusChange type {}; + int flag = 0; - if (!message || !*message || sscanf(message, "%d %d", &type, &flag) < 2) + if (!extract(message, record<' '>(&type, &flag))) { clif_displaymessage(fd, - "Please, enter a status type/flag (usage: @packet <status type> <flag>)."); + "Please, enter a status type/flag (usage: @packet <status type> <flag>)."); return -1; } - clif_status_change(sd, StatusChange(type), flag); + clif_status_change(sd, type, flag); return 0; } @@ -2287,14 +2263,14 @@ int atcommand_packet(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_statuspoint(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { int point, new_status_point; - if (!message || !*message || (point = atoi(message)) == 0) + if (!extract(message, &point) || point == 0) { clif_displaymessage(fd, - "Please, enter a number (usage: @stpoint <number of points>)."); + "Please, enter a number (usage: @stpoint <number of points>)."); return -1; } @@ -2327,14 +2303,14 @@ int atcommand_statuspoint(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_skillpoint(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { int point, new_skill_point; - if (!message || !*message || (point = atoi(message)) == 0) + if (!extract(message, &point) || point == 0) { clif_displaymessage(fd, - "Please, enter a number (usage: @skpoint <number of points>)."); + "Please, enter a number (usage: @skpoint <number of points>)."); return -1; } @@ -2367,14 +2343,14 @@ int atcommand_skillpoint(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_zeny(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { int zeny, new_zeny; - if (!message || !*message || (zeny = atoi(message)) == 0) + if (!extract(message, &zeny) || zeny == 0) { clif_displaymessage(fd, - "Please, enter an amount (usage: @zeny <amount>)."); + "Please, enter an amount (usage: @zeny <amount>)."); return -1; } @@ -2408,14 +2384,13 @@ int atcommand_zeny(const int fd, dumb_ptr<map_session_data> sd, */ template<ATTR attr> int atcommand_param(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { int value = 0, new_value; - if (!message || !*message || sscanf(message, "%d", &value) < 1 + if (!extract(message, &value) || value == 0) { - // there was a clang bug here // fortunately, STRPRINTF was not actually needed clif_displaymessage(fd, @@ -2455,11 +2430,11 @@ int atcommand_param(const int fd, dumb_ptr<map_session_data> sd, */ //** Stat all by fritz (rewritten by [Yor]) int atcommand_all_stats(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { int count, value = 0, new_value; - if (!message || !*message || sscanf(message, "%d", &value) < 1 + if (!extract(message, &value) || value == 0) value = battle_config.max_parameter; @@ -2501,19 +2476,19 @@ int atcommand_all_stats(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_recall(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char character[100] {}; - dumb_ptr<map_session_data> pl_sd; + CharName character; - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) + if (!asplit(message, &character)) { clif_displaymessage(fd, - "Please, enter a player name (usage: @recall <char name>)."); + "Please, enter a player name (usage: @recall <char name>)."); return -1; } - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can recall only lower or same level @@ -2521,18 +2496,18 @@ int atcommand_recall(const int fd, dumb_ptr<map_session_data> sd, && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { clif_displaymessage(fd, - "You are not authorised to warp somenone to your actual map."); + "You are not authorised to warp somenone to your actual map."); return -1; } if (pl_sd->bl_m && pl_sd->bl_m->flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { clif_displaymessage(fd, - "You are not authorised to warp this player from its actual map."); + "You are not authorised to warp this player from its actual map."); return -1; } pc_setpos(pl_sd, sd->mapname_, sd->bl_x, sd->bl_y, BeingRemoveWhy::QUIT); - std::string output = STRPRINTF("%s recalled!", character); + FString output = STRPRINTF("%s recalled!", character); clif_displaymessage(fd, output); } else @@ -2555,19 +2530,19 @@ int atcommand_recall(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_revive(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char character[100] {}; - dumb_ptr<map_session_data> pl_sd; + CharName character; - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) + if (!asplit(message, &character)) { clif_displaymessage(fd, - "Please, enter a player name (usage: @revive <char name>)."); + "Please, enter a player name (usage: @revive <char name>)."); return -1; } - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { pl_sd->status.hp = pl_sd->status.max_hp; pc_setstand(pl_sd); @@ -2592,21 +2567,21 @@ int atcommand_revive(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_character_stats(const int fd, dumb_ptr<map_session_data>, - const char *, const char *message) + ZString message) { - char character[100] {}; - dumb_ptr<map_session_data> pl_sd; + CharName character; - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) + if (!asplit(message, &character)) { clif_displaymessage(fd, - "Please, enter a player name (usage: @charstats <char name>)."); + "Please, enter a player name (usage: @charstats <char name>)."); return -1; } - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { - std::string output; + FString output; output = STRPRINTF("'%s' stats:", pl_sd->status.name); clif_displaymessage(fd, output); output = STRPRINTF("Base Level - %d", pl_sd->status.base_level), @@ -2651,7 +2626,7 @@ int atcommand_character_stats(const int fd, dumb_ptr<map_session_data>, */ //** Character Stats All by fritz int atcommand_character_stats_all(const int fd, dumb_ptr<map_session_data>, - const char *, const char *) + ZString) { int count; @@ -2663,13 +2638,13 @@ int atcommand_character_stats_all(const int fd, dumb_ptr<map_session_data>, dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(session[i]->session_data.get())); if (pl_sd && pl_sd->state.auth) { - std::string gmlevel; + FString gmlevel; if (pc_isGM(pl_sd) > 0) gmlevel = STRPRINTF("| GM Lvl: %d", pc_isGM(pl_sd)); else gmlevel = " "; - std::string output; + FString output; output = STRPRINTF( "Name: %s | BLvl: %d | Job: Novice/Human (Lvl: %d) | HP: %d/%d | SP: %d/%d", pl_sd->status.name, pl_sd->status.base_level, @@ -2698,7 +2673,7 @@ int atcommand_character_stats_all(const int fd, dumb_ptr<map_session_data>, clif_displaymessage(fd, "1 player found."); else { - std::string output = STRPRINTF("%d players found.", count); + FString output = STRPRINTF("%d players found.", count); clif_displaymessage(fd, output); } @@ -2710,26 +2685,21 @@ int atcommand_character_stats_all(const int fd, dumb_ptr<map_session_data>, *------------------------------------------ */ int atcommand_character_option(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char character[100] {}; - int opt1_ = 0, opt2_ = 0, opt3_ = 0; - dumb_ptr<map_session_data> pl_sd; - - if (!message || !*message - || sscanf(message, "%d %d %d %99[^\n]", &opt1_, &opt2_, &opt3_, - character) < 4 || opt1_ < 0 || opt2_ < 0 || opt3_ < 0) + Opt1 opt1; + Opt2 opt2; + Option opt3; + CharName character; + if (!asplit(message, &opt1, &opt2, &opt3, &character)) { clif_displaymessage(fd, - "Please, enter valid options and a player name (usage: @charoption <param1> <param2> <param3> <charname>)."); + "Please, enter valid options and a player name (usage: @charoption <param1> <param2> <param3> <charname>)."); return -1; } - Opt1 opt1 = Opt1(opt1_); - Opt2 opt2 = Opt2(opt2_); - Option opt3 = Option(opt3_); - - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { if (pc_isGM(sd) >= pc_isGM(pl_sd)) { @@ -2762,31 +2732,19 @@ int atcommand_character_option(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_char_change_sex(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char character[100] {}; + CharName character; - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) + if (!asplit(message, &character)) { clif_displaymessage(fd, - "Please, enter a player name (usage: @charchangesex <name>)."); + "Please, enter a player name (usage: @charchangesex <name>)."); return -1; } - // check player name - if (strlen(character) < 4) { - clif_displaymessage(fd, "Sorry, but a player name have at least 4 characters."); - return -1; - } - else if (strlen(character) > 23) - { - clif_displaymessage(fd, "Sorry, but a player name have 23 characters maximum."); - return -1; - } - else - { - chrif_char_ask_name(sd->status.account_id, character, 5, 0, 0, 0, 0, 0, 0); // type: 5 - changesex + chrif_char_ask_name(sd->status.account_id, character, 5, HumanTimeDiff()); // type: 5 - changesex clif_displaymessage(fd, "Character name sends to char-server to ask it."); } @@ -2799,31 +2757,19 @@ int atcommand_char_change_sex(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_char_block(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char character[100] {}; + CharName character; - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) + if (!asplit(message, &character)) { clif_displaymessage(fd, - "Please, enter a player name (usage: @block <name>)."); + "Please, enter a player name (usage: @block <name>)."); return -1; } - // check player name - if (strlen(character) < 4) { - clif_displaymessage(fd, "Sorry, but a player name have at least 4 characters."); - return -1; - } - else if (strlen(character) > 23) - { - clif_displaymessage(fd, "Sorry, but a player name have 23 characters maximum."); - return -1; - } - else - { - chrif_char_ask_name(sd->status.account_id, character, 1, 0, 0, 0, 0, 0, 0); // type: 1 - block + chrif_char_ask_name(sd->status.account_id, character, 1, HumanTimeDiff()); // type: 1 - block clif_displaymessage(fd, "Character name sends to char-server to ask it."); } @@ -2847,94 +2793,21 @@ int atcommand_char_block(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_char_ban(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char modif[100] {}; - char character[100] {}; - char *modif_p; - int year, month, day, hour, minute, second, value; + HumanTimeDiff modif; + CharName character; - if (!message || !*message - || sscanf(message, "%s %99[^\n]", modif, character) < 2) + if (!asplit(message, &modif, &character) + || !modif) { clif_displaymessage(fd, - "Please, enter ban time and a player name (usage: @charban/@ban/@banish/@charbanish <time> <name>)."); - return -1; - } - - modif[sizeof(modif) - 1] = '\0'; - character[sizeof(character) - 1] = '\0'; - - modif_p = modif; - year = month = day = hour = minute = second = 0; - while (modif_p[0] != '\0') - { - value = atoi(modif_p); - if (value == 0) - modif_p++; - else - { - if (modif_p[0] == '-' || modif_p[0] == '+') - modif_p++; - while (modif_p[0] >= '0' && modif_p[0] <= '9') - modif_p++; - if (modif_p[0] == 's') - { - second = value; - modif_p++; - } - else if (modif_p[0] == 'm' && modif_p[1] == 'n') - { - minute = value; - modif_p = modif_p + 2; - } - else if (modif_p[0] == 'h') - { - hour = value; - modif_p++; - } - else if (modif_p[0] == 'd' || modif_p[0] == 'j') - { - day = value; - modif_p++; - } - else if (modif_p[0] == 'm') - { - month = value; - modif_p++; - } - else if (modif_p[0] == 'y' || modif_p[0] == 'a') - { - year = value; - modif_p++; - } - else if (modif_p[0] != '\0') - { - modif_p++; - } - } - } - if (year == 0 && month == 0 && day == 0 && hour == 0 && minute == 0 - && second == 0) - { - clif_displaymessage(fd, "Invalid time for ban command."); + "Please, enter ban time and a player name (usage: @charban/@ban/@banish/@charbanish <time> <name>)."); return -1; } - // check player name - if (strlen(character) < 4) - { - clif_displaymessage(fd, "Sorry, but a player name have at least 4 characters."); - return -1; - } - else if (strlen(character) > 23) { - clif_displaymessage(fd, "Sorry, but a player name have 23 characters maximum."); - return -1; - } - else - { - chrif_char_ask_name(sd->status.account_id, character, 2, year, month, day, hour, minute, second); // type: 2 - ban + chrif_char_ask_name(sd->status.account_id, character, 2, modif); // type: 2 - ban clif_displaymessage(fd, "Character name sends to char-server to ask it."); } @@ -2946,32 +2819,20 @@ int atcommand_char_ban(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_char_unblock(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char character[100] {}; + CharName character; - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) + if (!asplit(message, &character)) { clif_displaymessage(fd, - "Please, enter a player name (usage: @charunblock <player_name>)."); + "Please, enter a player name (usage: @charunblock <player_name>)."); return -1; } - // check player name - if (strlen(character) < 4) - { - clif_displaymessage(fd, "Sorry, but a player name have at least 4 characters."); - return -1; - } - else if (strlen(character) > 23) - { - clif_displaymessage(fd, "Sorry, but a player name have 23 characters maximum."); - return -1; - } - else { // send answer to login server via char-server - chrif_char_ask_name(sd->status.account_id, character, 3, 0, 0, 0, 0, 0, 0); // type: 3 - unblock + chrif_char_ask_name(sd->status.account_id, character, 3, HumanTimeDiff()); // type: 3 - unblock clif_displaymessage(fd, "Character name sends to char-server to ask it."); } @@ -2983,32 +2844,20 @@ int atcommand_char_unblock(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_char_unban(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char character[100] {}; + CharName character; - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) + if (!asplit(message, &character)) { clif_displaymessage(fd, - "Please, enter a player name (usage: @charunban <player_name>)."); + "Please, enter a player name (usage: @charunban <player_name>)."); return -1; } - // check player name - if (strlen(character) < 4) - { - clif_displaymessage(fd, "Sorry, but a player name have at least 4 characters."); - return -1; - } - else if (strlen(character) > 23) - { - clif_displaymessage(fd, "Sorry, but a player name have 23 characters maximum."); - return -1; - } - else { // send answer to login server via char-server - chrif_char_ask_name(sd->status.account_id, character, 4, 0, 0, 0, 0, 0, 0); // type: 4 - unban + chrif_char_ask_name(sd->status.account_id, character, 4, HumanTimeDiff()); // type: 4 - unban clif_displaymessage(fd, "Character name sends to char-server to ask it."); } @@ -3020,26 +2869,22 @@ int atcommand_char_unban(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_character_save(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char map_name[100] {}; - char character[100] {}; - dumb_ptr<map_session_data> pl_sd; + MapName map_name; + CharName character; int x = 0, y = 0; - if (!message || !*message - || sscanf(message, "%99s %d %d %99[^\n]", map_name, &x, &y, - character) < 4 || x < 0 || y < 0) + if (!asplit(message, &map_name, &x, &y, &character) + || x < 0 || y < 0) { clif_displaymessage(fd, - "Please, enter a valid save point and a player name (usage: @charsave <map> <x> <y> <charname>)."); + "Please, enter a valid save point and a player name (usage: @charsave <map> <x> <y> <charname>)."); return -1; } - if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat) - strcat(map_name, ".gat"); - - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { if (pc_isGM(sd) >= pc_isGM(pl_sd)) { @@ -3056,7 +2901,7 @@ int atcommand_character_save(const int fd, dumb_ptr<map_session_data> sd, && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { clif_displaymessage(fd, - "You are not authorised to set this map as a save map."); + "You are not authorised to set this map as a save map."); return -1; } pc_setsavepoint(pl_sd, map_name, x, y); @@ -3083,7 +2928,7 @@ int atcommand_character_save(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_doom(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { for (int i = 0; i < fd_max; i++) { @@ -3108,7 +2953,7 @@ int atcommand_doom(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_doommap(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { for (int i = 0; i < fd_max; i++) { @@ -3152,7 +2997,7 @@ void atcommand_raise_sub(dumb_ptr<map_session_data> sd) *------------------------------------------ */ int atcommand_raise(const int fd, dumb_ptr<map_session_data>, - const char *, const char *) + ZString) { for (int i = 0; i < fd_max; i++) { @@ -3171,7 +3016,7 @@ int atcommand_raise(const int fd, dumb_ptr<map_session_data>, *------------------------------------------ */ int atcommand_raisemap(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { for (int i = 0; i < fd_max; i++) { @@ -3192,26 +3037,24 @@ int atcommand_raisemap(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_character_baselevel(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - dumb_ptr<map_session_data> pl_sd; - char character[100] {}; + CharName character; int level = 0, i; - if (!message || !*message - || sscanf(message, "%d %99[^\n]", &level, character) < 2 + if (!asplit(message, &level, &character) || level == 0) { clif_displaymessage(fd, - "Please, enter a level adjustement and a player name (usage: @charblvl <#> <nickname>)."); + "Please, enter a level adjustement and a player name (usage: @charblvl <#> <nickname>)."); return -1; } - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can change base level only lower or same gm level - if (level > 0) { if (pl_sd->status.base_level == battle_config.maximum_level) @@ -3262,7 +3105,7 @@ int atcommand_character_baselevel(const int fd, dumb_ptr<map_session_data> sd, clif_displaymessage(fd, "Character's base level lowered."); } // Reset their stat points to prevent extra points from stacking - atcommand_charstreset(fd, sd,"@charstreset", character); + atcommand_charstreset(fd, sd, character.to__actual()); } else { @@ -3284,22 +3127,21 @@ int atcommand_character_baselevel(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_character_joblevel(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - dumb_ptr<map_session_data> pl_sd; - char character[100] {}; + CharName character; int max_level = 50, level = 0; - if (!message || !*message - || sscanf(message, "%d %99[^\n]", &level, character) < 2 + if (!asplit(message, &level, &character) || level == 0) { clif_displaymessage(fd, - "Please, enter a level adjustement and a player name (usage: @charjlvl <#> <nickname>)."); + "Please, enter a level adjustement and a player name (usage: @charjlvl <#> <nickname>)."); return -1; } - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { if (pc_isGM(sd) >= pc_isGM(pl_sd)) { @@ -3367,19 +3209,19 @@ int atcommand_character_joblevel(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_kick(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - dumb_ptr<map_session_data> pl_sd; - char character[100] {}; + CharName character; - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) + if (!asplit(message, &character)) { clif_displaymessage(fd, - "Please, enter a player name (usage: @kick <charname>)."); + "Please, enter a player name (usage: @kick <charname>)."); return -1; } - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { if (pc_isGM(sd) >= pc_isGM(pl_sd)) // you can kick only lower or same gm level clif_GM_kick(sd, pl_sd, 1); @@ -3403,7 +3245,7 @@ int atcommand_kick(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_kickall(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { for (int i = 0; i < fd_max; i++) { @@ -3429,19 +3271,17 @@ int atcommand_kickall(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_questskill(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - int skill_id_; + SkillID skill_id; - if (!message || !*message || (skill_id_ = atoi(message)) < 0) + if (!extract(message, &skill_id)) { clif_displaymessage(fd, - "Please, enter a quest skill number (usage: @questskill <#:0+>)."); + "Please, enter a quest skill number (usage: @questskill <#:0+>)."); return -1; } - SkillID skill_id = SkillID(skill_id_); - if (/*skill_id >= SkillID() &&*/ skill_id < SkillID::MAX_SKILL_DB) { if (skill_get_inf2(skill_id) & 0x01) @@ -3477,28 +3317,24 @@ int atcommand_questskill(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_charquestskill(const int fd, dumb_ptr<map_session_data>, - const char *, const char *message) + ZString message) { - char character[100] {}; - dumb_ptr<map_session_data> pl_sd; - int skill_id_ = 0; + CharName character; + SkillID skill_id; - if (!message || !*message - || sscanf(message, "%d %99[^\n]", &skill_id_, character) < 2 - || skill_id_ < 0) + if (!asplit(message, &skill_id, &character)) { clif_displaymessage(fd, - "Please, enter a quest skill number and a player name (usage: @charquestskill <#:0+> <char_name>)."); + "Please, enter a quest skill number and a player name (usage: @charquestskill <#:0+> <char_name>)."); return -1; } - SkillID skill_id = SkillID(skill_id_); - if (/*skill_id >= SkillID() &&*/ skill_id < SkillID::MAX_SKILL_DB) { if (skill_get_inf2(skill_id) & 0x01) { - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { if (pc_checkskill(pl_sd, skill_id) == 0) { @@ -3537,19 +3373,17 @@ int atcommand_charquestskill(const int fd, dumb_ptr<map_session_data>, *------------------------------------------ */ int atcommand_lostskill(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - int skill_id_; + SkillID skill_id; - if (!message || !*message || (skill_id_ = atoi(message)) < 0) + if (!extract(message, &skill_id)) { clif_displaymessage(fd, - "Please, enter a quest skill number (usage: @lostskill <#:0+>)."); + "Please, enter a quest skill number (usage: @lostskill <#:0+>)."); return -1; } - SkillID skill_id = SkillID(skill_id_); - if (/*skill_id >= SkillID() &&*/ skill_id < MAX_SKILL) { if (skill_get_inf2(skill_id) & 0x01) @@ -3587,28 +3421,24 @@ int atcommand_lostskill(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_charlostskill(const int fd, dumb_ptr<map_session_data>, - const char *, const char *message) + ZString message) { - char character[100] {}; - dumb_ptr<map_session_data> pl_sd; - int skill_id_ = 0; + CharName character; + SkillID skill_id; - if (!message || !*message - || sscanf(message, "%d %99[^\n]", &skill_id_, character) < 2 - || skill_id_ < 0) + if (!asplit(message, &skill_id, &character)) { clif_displaymessage(fd, - "Please, enter a quest skill number and a player name (usage: @charlostskill <#:0+> <char_name>)."); + "Please, enter a quest skill number and a player name (usage: @charlostskill <#:0+> <char_name>)."); return -1; } - SkillID skill_id = SkillID(skill_id_); - if (/*skill_id >= SkillID() &&*/ skill_id < MAX_SKILL) { if (skill_get_inf2(skill_id) & 0x01) { - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { if (pc_checkskill(pl_sd, skill_id) > 0) { @@ -3649,14 +3479,14 @@ int atcommand_charlostskill(const int fd, dumb_ptr<map_session_data>, *------------------------------------------ */ int atcommand_party(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char party[100] {}; + PartyName party; - if (!message || !*message || sscanf(message, "%99[^\n]", party) < 1) + if (!extract(message, &party) || !party) { clif_displaymessage(fd, - "Please, enter a party name (usage: @party <party_name>)."); + "Please, enter a party name (usage: @party <party_name>)."); return -1; } @@ -3670,7 +3500,7 @@ int atcommand_party(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_mapexit(const int, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { for (int i = 0; i < fd_max; i++) { @@ -3695,26 +3525,26 @@ int atcommand_mapexit(const int, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_idsearch(const int fd, dumb_ptr<map_session_data>, - const char *, const char *message) + ZString message) { - char item_name[100] {}; + ItemName item_name; int i, match; struct item_data *item; - if (!message || !*message || sscanf(message, "%99s", item_name) < 0) + if (!extract(message, &item_name) || !item_name) { clif_displaymessage(fd, - "Please, enter a part of item name (usage: @idsearch <part_of_item_name>)."); + "Please, enter a part of item name (usage: @idsearch <part_of_item_name>)."); return -1; } - std::string output = STRPRINTF("The reference result of '%s' (name: id):", item_name); + FString output = STRPRINTF("The reference result of '%s' (name: id):", item_name); clif_displaymessage(fd, output); match = 0; for (i = 0; i < 20000; i++) { if ((item = itemdb_exists(i)) != NULL - && strstr(item->jname, item_name) != NULL) + && item->jname.contains_seq(item_name)) { match++; output = STRPRINTF("%s: %d", item->jname, item->nameid); @@ -3732,24 +3562,24 @@ int atcommand_idsearch(const int fd, dumb_ptr<map_session_data>, *------------------------------------------ */ int atcommand_charskreset(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char character[100] {}; - dumb_ptr<map_session_data> pl_sd; + CharName character; - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) + if (!asplit(message, &character)) { clif_displaymessage(fd, - "Please, enter a player name (usage: @charskreset <charname>)."); + "Please, enter a player name (usage: @charskreset <charname>)."); return -1; } - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can reset skill points only lower or same gm level pc_resetskill(pl_sd); - std::string output = STRPRINTF( + FString output = STRPRINTF( "'%s' skill points reseted!", character); clif_displaymessage(fd, output); } @@ -3773,24 +3603,24 @@ int atcommand_charskreset(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_charstreset(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char character[100] {}; - dumb_ptr<map_session_data> pl_sd; + CharName character; - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) + if (!asplit(message, &character)) { clif_displaymessage(fd, - "Please, enter a player name (usage: @charstreset <charname>)."); + "Please, enter a player name (usage: @charstreset <charname>)."); return -1; } - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can reset stats points only lower or same gm level pc_resetstate(pl_sd); - std::string output = STRPRINTF( + FString output = STRPRINTF( "'%s' stats points reseted!", character); clif_displaymessage(fd, output); @@ -3815,27 +3645,27 @@ int atcommand_charstreset(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_charreset(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char character[100] {}; - dumb_ptr<map_session_data> pl_sd; + CharName character; - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) + if (!asplit(message, &character)) { clif_displaymessage(fd, - "Please, enter a player name (usage: @charreset <charname>)."); + "Please, enter a player name (usage: @charreset <charname>)."); return -1; } - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can reset a character only for lower or same GM level pc_resetstate(pl_sd); pc_resetskill(pl_sd); - pc_setglobalreg(pl_sd, "MAGIC_FLAGS", 0); // [Fate] Reset magic quest variables - pc_setglobalreg(pl_sd, "MAGIC_EXP", 0); // [Fate] Reset magic experience - std::string output = STRPRINTF( + pc_setglobalreg(pl_sd, stringish<VarName>("MAGIC_FLAGS"), 0); // [Fate] Reset magic quest variables + pc_setglobalreg(pl_sd, stringish<VarName>("MAGIC_EXP"), 0); // [Fate] Reset magic experience + FString output = STRPRINTF( "'%s' skill and stats points reseted!", character); clif_displaymessage(fd, output); } @@ -3859,19 +3689,19 @@ int atcommand_charreset(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_char_wipe(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char character[100] {}; - dumb_ptr<map_session_data> pl_sd; + CharName character; - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) + if (!asplit(message, &character)) { clif_displaymessage(fd, - "Please, enter a player name (usage: @charwipe <charname>)."); + "Please, enter a player name (usage: @charwipe <charname>)."); return -1; } - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can reset a character only for lower or same GM level @@ -3919,10 +3749,10 @@ int atcommand_char_wipe(const int fd, dumb_ptr<map_session_data> sd, pc_calcstatus(pl_sd, 0); pc_resetstate(pl_sd); pc_resetskill(pl_sd); - pc_setglobalreg(pl_sd, "MAGIC_FLAGS", 0); // [Fate] Reset magic quest variables - pc_setglobalreg(pl_sd, "MAGIC_EXP", 0); // [Fate] Reset magic experience + pc_setglobalreg(pl_sd, stringish<VarName>("MAGIC_FLAGS"), 0); // [Fate] Reset magic quest variables + pc_setglobalreg(pl_sd, stringish<VarName>("MAGIC_EXP"), 0); // [Fate] Reset magic experience - std::string output = STRPRINTF("%s: wiped.", character); + FString output = STRPRINTF("%s: wiped.", character); clif_displaymessage(fd, output); } else @@ -3945,18 +3775,14 @@ int atcommand_char_wipe(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_charmodel(const int fd, dumb_ptr<map_session_data>, - const char *, const char *message) + ZString message) { - int hair_style = 0, hair_color = 0, cloth_color = 0; - dumb_ptr<map_session_data> pl_sd; - char character[100] {}; + unsigned hair_style = 0, hair_color = 0, cloth_color = 0; + CharName character; - if (!message || !*message - || sscanf(message, "%d %d %d %99[^\n]", &hair_style, &hair_color, - &cloth_color, character) < 4 || hair_style < 0 - || hair_color < 0 || cloth_color < 0) + if (!asplit(message, &hair_style, &hair_color, &cloth_color, &character)) { - std::string output = STRPRINTF( + FString output = STRPRINTF( "Please, enter a valid model and a player name (usage: @charmodel <hair ID: %d-%d> <hair color: %d-%d> <clothes color: %d-%d> <name>).", MIN_HAIR_STYLE, MAX_HAIR_STYLE, MIN_HAIR_COLOR, MAX_HAIR_COLOR, @@ -3965,7 +3791,8 @@ int atcommand_charmodel(const int fd, dumb_ptr<map_session_data>, return -1; } - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { if (hair_style >= MIN_HAIR_STYLE && hair_style <= MAX_HAIR_STYLE && hair_color >= MIN_HAIR_COLOR && hair_color <= MAX_HAIR_COLOR && @@ -3998,23 +3825,22 @@ int atcommand_charmodel(const int fd, dumb_ptr<map_session_data>, *------------------------------------------ */ int atcommand_charskpoint(const int fd, dumb_ptr<map_session_data>, - const char *, const char *message) + ZString message) { - dumb_ptr<map_session_data> pl_sd; - char character[100] {}; + CharName character; int new_skill_point; int point = 0; - if (!message || !*message - || sscanf(message, "%d %99[^\n]", &point, character) < 2 + if (!asplit(message, &point, &character) || point == 0) { clif_displaymessage(fd, - "Please, enter a number and a player name (usage: @charskpoint <amount> <name>)."); + "Please, enter a number and a player name (usage: @charskpoint <amount> <name>)."); return -1; } - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { new_skill_point = pl_sd->status.skill_point + point; if (point > 0 && (point > 0x7FFF || new_skill_point > 0x7FFF)) // fix positiv overflow @@ -4050,23 +3876,22 @@ int atcommand_charskpoint(const int fd, dumb_ptr<map_session_data>, *------------------------------------------ */ int atcommand_charstpoint(const int fd, dumb_ptr<map_session_data>, - const char *, const char *message) + ZString message) { - dumb_ptr<map_session_data> pl_sd; - char character[100] {}; + CharName character; int new_status_point; int point = 0; - if (!message || !*message - || sscanf(message, "%d %99[^\n]", &point, character) < 2 + if (!asplit(message, &point, &character) || point == 0) { clif_displaymessage(fd, - "Please, enter a number and a player name (usage: @charstpoint <amount> <name>)."); + "Please, enter a number and a player name (usage: @charstpoint <amount> <name>)."); return -1; } - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { new_status_point = pl_sd->status.status_point + point; if (point > 0 && (point > 0x7FFF || new_status_point > 0x7FFF)) // fix positiv overflow @@ -4102,21 +3927,20 @@ int atcommand_charstpoint(const int fd, dumb_ptr<map_session_data>, *------------------------------------------ */ int atcommand_charzeny(const int fd, dumb_ptr<map_session_data>, - const char *, const char *message) + ZString message) { - dumb_ptr<map_session_data> pl_sd; - char character[100] {}; + CharName character; int zeny = 0, new_zeny; - if (!message || !*message - || sscanf(message, "%d %99[^\n]", &zeny, character) < 2 || zeny == 0) + if (!asplit(message, &zeny, &character) || zeny == 0) { clif_displaymessage(fd, - "Please, enter a number and a player name (usage: @charzeny <zeny> <name>)."); + "Please, enter a number and a player name (usage: @charzeny <zeny> <name>)."); return -1; } - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { new_zeny = pl_sd->status.zeny + zeny; if (zeny > 0 && (zeny > MAX_ZENY || new_zeny > MAX_ZENY)) // fix positiv overflow @@ -4152,7 +3976,7 @@ int atcommand_charzeny(const int fd, dumb_ptr<map_session_data>, *------------------------------------------ */ int atcommand_recallall(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { int count; @@ -4160,7 +3984,7 @@ int atcommand_recallall(const int fd, dumb_ptr<map_session_data> sd, && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { clif_displaymessage(fd, - "You are not authorised to warp somenone to your actual map."); + "You are not authorised to warp somenone to your actual map."); return -1; } @@ -4187,7 +4011,7 @@ int atcommand_recallall(const int fd, dumb_ptr<map_session_data> sd, clif_displaymessage(fd, "All characters recalled!"); if (count) { - std::string output = STRPRINTF( + FString output = STRPRINTF( "Because you are not authorised to warp from some maps, %d player(s) have not been recalled.", count); clif_displaymessage(fd, output); @@ -4201,16 +4025,16 @@ int atcommand_recallall(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_partyrecall(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char party_name[100] {}; + PartyName party_name; struct party *p; int count; - if (!message || !*message || sscanf(message, "%99[^\n]", party_name) < 1) + if (!extract(message, &party_name) || !party_name) { clif_displaymessage(fd, - "Please, enter a party name/id (usage: @partyrecall <party_name/id>)."); + "Please, enter a party name/id (usage: @partyrecall <party_name/id>)."); return -1; } @@ -4218,12 +4042,12 @@ int atcommand_partyrecall(const int fd, dumb_ptr<map_session_data> sd, && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { clif_displaymessage(fd, - "You are not authorised to warp somenone to your actual map."); + "You are not authorised to warp somenone to your actual map."); return -1; } if ((p = party_searchname(party_name)) != NULL || // name first to avoid error when name begin with a number - (p = party_search(atoi(message))) != NULL) + (p = party_search(atoi(message.c_str()))) != NULL) { count = 0; for (int i = 0; i < fd_max; i++) @@ -4242,7 +4066,7 @@ int atcommand_partyrecall(const int fd, dumb_ptr<map_session_data> sd, pc_setpos(pl_sd, sd->mapname_, sd->bl_x, sd->bl_y, BeingRemoveWhy::QUIT); } } - std::string output = STRPRINTF("All online characters of the %s party are near you.", p->name); + FString output = STRPRINTF("All online characters of the %s party are near you.", p->name); clif_displaymessage(fd, output); if (count) { @@ -4266,7 +4090,7 @@ int atcommand_partyrecall(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_reloaditemdb(const int fd, dumb_ptr<map_session_data>, - const char *, const char *) + ZString) { itemdb_reload(); clif_displaymessage(fd, "Item database reloaded."); @@ -4279,7 +4103,7 @@ int atcommand_reloaditemdb(const int fd, dumb_ptr<map_session_data>, *------------------------------------------ */ int atcommand_reloadmobdb(const int fd, dumb_ptr<map_session_data>, - const char *, const char *) + ZString) { mob_reload(); clif_displaymessage(fd, "Monster database reloaded."); @@ -4292,7 +4116,7 @@ int atcommand_reloadmobdb(const int fd, dumb_ptr<map_session_data>, *------------------------------------------ */ int atcommand_reloadskilldb(const int fd, dumb_ptr<map_session_data>, - const char *, const char *) + ZString) { skill_reload(); clif_displaymessage(fd, "Skill database reloaded."); @@ -4305,7 +4129,7 @@ int atcommand_reloadskilldb(const int fd, dumb_ptr<map_session_data>, *------------------------------------------ */ int atcommand_reloadscript(const int fd, dumb_ptr<map_session_data>, - const char *, const char *) + ZString) { do_init_npc(); do_init_script(); @@ -4322,7 +4146,7 @@ int atcommand_reloadscript(const int fd, dumb_ptr<map_session_data>, *------------------------------------------ */ int atcommand_reloadgmdb(const int fd, dumb_ptr<map_session_data>, - const char *, const char *) + ZString) { chrif_reloadGMdb(); @@ -4340,26 +4164,24 @@ int atcommand_reloadgmdb(const int fd, dumb_ptr<map_session_data>, *------------------------------------------ */ int atcommand_mapinfo(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { dumb_ptr<npc_data> nd = NULL; - char map_name[100] {}; + MapName map_name; const char *direction = NULL; int list = 0; - sscanf(message, "%d %99[^\n]", &list, map_name); + extract(message, record<' '>(&list, &map_name)); if (list < 0 || list > 3) { clif_displaymessage(fd, - "Please, enter at least a valid list number (usage: @mapinfo <0-3> [map])."); + "Please, enter at least a valid list number (usage: @mapinfo <0-3> [map])."); return -1; } - if (map_name[0] == '\0') - strcpy(map_name, sd->mapname_); - if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat) - strcat(map_name, ".gat"); + if (!map_name) + map_name = sd->mapname_; map_local *m_id = map_mapname2mapid(map_name); if (m_id != nullptr) @@ -4369,7 +4191,7 @@ int atcommand_mapinfo(const int fd, dumb_ptr<map_session_data> sd, } clif_displaymessage(fd, "------ Map Info ------"); - std::string output = STRPRINTF("Map Name: %s", map_name); + FString output = STRPRINTF("Map Name: %s", map_name); clif_displaymessage(fd, output); output = STRPRINTF("Players In Map: %d", m_id->users); clif_displaymessage(fd, output); @@ -4418,11 +4240,11 @@ int atcommand_mapinfo(const int fd, dumb_ptr<map_session_data> sd, continue; dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(session[i]->session_data.get())); if (pl_sd && pl_sd->state.auth - && strcmp(pl_sd->mapname_, map_name) == 0) + && pl_sd->mapname_ == map_name) { output = STRPRINTF( - "Player '%s' (session #%d) | Location: %d,%d", - pl_sd->status.name, i, pl_sd->bl_x, pl_sd->bl_y); + "Player '%s' (session #%d) | Location: %d,%d", + pl_sd->status.name, i, pl_sd->bl_x, pl_sd->bl_y); clif_displaymessage(fd, output); } } @@ -4476,7 +4298,7 @@ int atcommand_mapinfo(const int fd, dumb_ptr<map_session_data> sd, break; default: // normally impossible to arrive here clif_displaymessage(fd, - "Please, enter at least a valid list number (usage: @mapinfo <0-2> [map])."); + "Please, enter at least a valid list number (usage: @mapinfo <0-2> [map])."); return -1; } @@ -4488,31 +4310,31 @@ int atcommand_mapinfo(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_partyspy(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char party_name[100] {}; - struct party *p; + PartyName party_name; - if (!message || !*message || sscanf(message, "%99[^\n]", party_name) < 1) + if (!extract(message, &party_name)) { clif_displaymessage(fd, - "Please, enter a party name/id (usage: @partyspy <party_name/id>)."); + "Please, enter a party name/id (usage: @partyspy <party_name/id>)."); return -1; } + struct party *p; if ((p = party_searchname(party_name)) != NULL || // name first to avoid error when name begin with a number - (p = party_search(atoi(message))) != NULL) + (p = party_search(atoi(message.c_str()))) != NULL) { if (sd->partyspy == p->party_id) { sd->partyspy = 0; - std::string output = STRPRINTF("No longer spying on the %s party.", p->name); + FString output = STRPRINTF("No longer spying on the %s party.", p->name); clif_displaymessage(fd, output); } else { sd->partyspy = p->party_id; - std::string output = STRPRINTF("Spying on the %s party.", p->name); + FString output = STRPRINTF("Spying on the %s party.", p->name); clif_displaymessage(fd, output); } } @@ -4530,14 +4352,14 @@ int atcommand_partyspy(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_enablenpc(const int fd, dumb_ptr<map_session_data>, - const char *, const char *message) + ZString message) { - char NPCname[100] {}; + NpcName NPCname; - if (!message || !*message || sscanf(message, "%99[^\n]", NPCname) < 1) + if (!extract(message, &NPCname) || !NPCname) { clif_displaymessage(fd, - "Please, enter a NPC name (usage: @npcon <NPC_name>)."); + "Please, enter a NPC name (usage: @npcon <NPC_name>)."); return -1; } @@ -4560,14 +4382,14 @@ int atcommand_enablenpc(const int fd, dumb_ptr<map_session_data>, *------------------------------------------ */ int atcommand_disablenpc(const int fd, dumb_ptr<map_session_data>, - const char *, const char *message) + ZString message) { - char NPCname[100] {}; + NpcName NPCname; - if (!message || !*message || sscanf(message, "%99[^\n]", NPCname) < 1) + if (!extract(message, &NPCname) || !NPCname) { clif_displaymessage(fd, - "Please, enter a NPC name (usage: @npcoff <NPC_name>)."); + "Please, enter a NPC name (usage: @npcoff <NPC_name>)."); return -1; } @@ -4591,11 +4413,11 @@ int atcommand_disablenpc(const int fd, dumb_ptr<map_session_data>, *------------------------------------------ */ int atcommand_servertime(const int fd, dumb_ptr<map_session_data>, - const char *, const char *) + ZString) { timestamp_seconds_buffer tsbuf; stamp_time(tsbuf); - std::string temp = STRPRINTF("Server time: %s", tsbuf); + FString temp = STRPRINTF("Server time: %s", tsbuf); clif_displaymessage(fd, temp); { @@ -4614,31 +4436,29 @@ int atcommand_servertime(const int fd, dumb_ptr<map_session_data>, *------------------------------------------ */ int atcommand_chardelitem(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - dumb_ptr<map_session_data> pl_sd; - char character[100] {}; - char item_name[100] {}; + CharName character; + ItemName item_name; int i, number = 0, item_id, item_position, count; struct item_data *item_data; - if (!message || !*message - || sscanf(message, "%s %d %99[^\n]", item_name, &number, - character) < 3 || number < 1) + if (!asplit(message, &item_name, &number, &character) || number < 1) { clif_displaymessage(fd, - "Please, enter an item name/id, a quantity and a player name (usage: @chardelitem <item_name_or_ID> <quantity> <player>)."); + "Please, enter an item name/id, a quantity and a player name (usage: @chardelitem <item_name_or_ID> <quantity> <player>)."); return -1; } item_id = 0; if ((item_data = itemdb_searchname(item_name)) != NULL || - (item_data = itemdb_exists(atoi(item_name))) != NULL) + (item_data = itemdb_exists(atoi(item_name.c_str()))) != NULL) item_id = item_data->nameid; if (item_id > 500) { - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can kill only lower or same level @@ -4652,7 +4472,7 @@ int atcommand_chardelitem(const int fd, dumb_ptr<map_session_data> sd, count++; item_position = pc_search_inventory(pl_sd, item_id); // for next loop } - std::string output = STRPRINTF( + FString output = STRPRINTF( "%d item(s) removed by a GM.", count); clif_displaymessage(pl_sd->fd, output); @@ -4695,16 +4515,16 @@ int atcommand_chardelitem(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_broadcast(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - if (!message || !*message) + if (!message) { clif_displaymessage(fd, - "Please, enter a message (usage: @broadcast <message>)."); + "Please, enter a message (usage: @broadcast <message>)."); return -1; } - std::string output = STRPRINTF("%s : %s", sd->status.name, message); + FString output = STRPRINTF("%s : %s", sd->status.name, message); intif_GMmessage(output); return 0; @@ -4715,16 +4535,16 @@ int atcommand_broadcast(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_localbroadcast(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - if (!message || !*message) + if (!message) { clif_displaymessage(fd, - "Please, enter a message (usage: @localbroadcast <message>)."); + "Please, enter a message (usage: @localbroadcast <message>)."); return -1; } - std::string output = STRPRINTF("%s : %s", sd->status.name, message); + FString output = STRPRINTF("%s : %s", sd->status.name, message); clif_GMmessage(sd, output, 1); // 1: ALL_SAMEMAP @@ -4736,35 +4556,34 @@ int atcommand_localbroadcast(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_email(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char actual_email[100] {}; - char new_email[100] {}; + AccountEmail actual_email; + AccountEmail new_email; - if (!message || !*message - || sscanf(message, "%99s %99s", actual_email, new_email) < 2) + if (!extract(message, record<' '>(&actual_email, &new_email))) { clif_displaymessage(fd, - "Please enter 2 emails (usage: @email <actual@email> <new@email>)."); + "Please enter 2 emails (usage: @email <actual@email> <new@email>)."); return -1; } - if (e_mail_check(actual_email) == 0) + if (!e_mail_check(actual_email)) { clif_displaymessage(fd, "Invalid actual email. If you have default e-mail, type a@a.com."); // Invalid actual email. If you have default e-mail, give a@a.com. return -1; } - else if (e_mail_check(new_email) == 0) + else if (!e_mail_check(new_email)) { clif_displaymessage(fd, "Invalid new email. Please enter a real e-mail."); return -1; } - else if (strcasecmp(new_email, "a@a.com") == 0) + else if (new_email == DEFAULT_EMAIL) { clif_displaymessage(fd, "New email must be a real e-mail."); return -1; } - else if (strcasecmp(actual_email, new_email) == 0) + else if (actual_email == new_email) { clif_displaymessage(fd, "New email must be different of the actual e-mail."); return -1; @@ -4783,14 +4602,14 @@ int atcommand_email(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_effect(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { int type = 0, flag = 0; - if (!message || !*message || sscanf(message, "%d %d", &type, &flag) < 2) + if (!extract(message, record<' '>(&type, &flag))) { clif_displaymessage(fd, - "Please, enter at least a option (usage: @effect <type+>)."); + "Please, enter at least a option (usage: @effect <type+>)."); return -1; } if (flag <= 0) @@ -4821,22 +4640,21 @@ int atcommand_effect(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_character_item_list(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - dumb_ptr<map_session_data> pl_sd; struct item_data *item_data, *item_temp; int i, j, count, counter, counter2; - char character[100] {}; - char equipstr[100]; + CharName character; - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) + if (!asplit(message, &character)) { clif_displaymessage(fd, - "Please, enter a player name (usage: @charitemlist <char name>)."); + "Please, enter a player name (usage: @charitemlist <char name>)."); return -1; } - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can look items only lower or same level @@ -4853,50 +4671,51 @@ int atcommand_character_item_list(const int fd, dumb_ptr<map_session_data> sd, count++; if (count == 1) { - std::string output = STRPRINTF( + FString output = STRPRINTF( "------ Items list of '%s' ------", pl_sd->status.name); clif_displaymessage(fd, output); } - EPOS equip; - if (bool(equip = pl_sd->status.inventory[i].equip)) + EPOS equip = pl_sd->status.inventory[i].equip; + MString equipstr; + if (bool(equip)) { - strcpy(equipstr, "| equiped: "); + equipstr += "| equiped: "; if (bool(equip & EPOS::GLOVES)) - strcat(equipstr, "robe/gargment, "); + equipstr += "robe/gargment, "; if (bool(equip & EPOS::CAPE)) - strcat(equipstr, "left accessory, "); + equipstr += "left accessory, "; if (bool(equip & EPOS::MISC1)) - strcat(equipstr, "body/armor, "); + equipstr += "body/armor, "; if ((equip & (EPOS::WEAPON | EPOS::SHIELD)) == EPOS::WEAPON) - strcat(equipstr, "right hand, "); + equipstr += "right hand, "; if ((equip & (EPOS::WEAPON | EPOS::SHIELD)) == EPOS::SHIELD) - strcat(equipstr, "left hand, "); + equipstr += "left hand, "; if ((equip & (EPOS::WEAPON | EPOS::SHIELD)) == (EPOS::WEAPON | EPOS::SHIELD)) - strcat(equipstr, "both hands, "); + equipstr += "both hands, "; if (bool(equip & EPOS::SHOES)) - strcat(equipstr, "feet, "); + equipstr += "feet, "; if (bool(equip & EPOS::MISC2)) - strcat(equipstr, "right accessory, "); + equipstr += "right accessory, "; if ((equip & (EPOS::TORSO | EPOS::HAT | EPOS::LEGS)) == EPOS::LEGS) - strcat(equipstr, "lower head, "); + equipstr += "lower head, "; if ((equip & (EPOS::TORSO | EPOS::HAT | EPOS::LEGS)) == EPOS::HAT) - strcat(equipstr, "top head, "); + equipstr += "top head, "; if ((equip & (EPOS::TORSO | EPOS::HAT | EPOS::LEGS)) == (EPOS::HAT | EPOS::LEGS)) - strcat(equipstr, "lower/top head, "); + equipstr += "lower/top head, "; if ((equip & (EPOS::TORSO | EPOS::HAT | EPOS::LEGS)) == EPOS::TORSO) - strcat(equipstr, "mid head, "); + equipstr += "mid head, "; if ((equip & (EPOS::TORSO | EPOS::HAT | EPOS::LEGS)) == (EPOS::TORSO | EPOS::LEGS)) - strcat(equipstr, "lower/mid head, "); + equipstr += "lower/mid head, "; if ((equip & (EPOS::TORSO | EPOS::HAT | EPOS::LEGS)) == (EPOS::TORSO | EPOS::HAT | EPOS::LEGS)) - strcat(equipstr, "lower/mid/top head, "); + equipstr += "lower/mid/top head, "; // remove final ', ' - equipstr[strlen(equipstr) - 2] = '\0'; + equipstr.pop_back(2); } else - strzcpy(equipstr, "", sizeof(equipstr)); + equipstr = MString(); - std::string output; + FString output; if (sd->status.inventory[i].refine) output = STRPRINTF("%d %s %+d (%s %+d, id: %d) %s", pl_sd->status.inventory[i].amount, @@ -4904,15 +4723,17 @@ int atcommand_character_item_list(const int fd, dumb_ptr<map_session_data> sd, pl_sd->status.inventory[i].refine, item_data->jname, pl_sd->status.inventory[i].refine, - pl_sd->status.inventory[i].nameid, equipstr); + pl_sd->status.inventory[i].nameid, + FString(equipstr)); else output = STRPRINTF("%d %s (%s, id: %d) %s", pl_sd->status.inventory[i].amount, item_data->name, item_data->jname, - pl_sd->status.inventory[i].nameid, equipstr); + pl_sd->status.inventory[i].nameid, + FString(equipstr)); clif_displaymessage(fd, output); - output.clear(); + MString voutput; counter2 = 0; for (j = 0; j < item_data->slot; j++) { @@ -4923,14 +4744,15 @@ int atcommand_character_item_list(const int fd, dumb_ptr<map_session_data> sd, inventory[i].card[j])) != NULL) { - if (output.empty()) - output = STRPRINTF( - " -> (card(s): #%d %s (%s), ", + if (!voutput) + voutput += STRPRINTF( + " -> (card(s): " + "#%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname); else - output += STRPRINTF( + voutput += STRPRINTF( "#%d %s (%s), ", ++counter2, item_temp->name, @@ -4938,16 +4760,12 @@ int atcommand_character_item_list(const int fd, dumb_ptr<map_session_data> sd, } } } - if (!output.empty()) + if (voutput) { // replace trailing ", " -#ifdef WORKAROUND_GCC46_LIBRARY - output.resize(output.size() - 1); -#else - output.pop_back(); -#endif - output.back() = ')'; - clif_displaymessage(fd, output); + voutput.pop_back(); + voutput.back() = ')'; + clif_displaymessage(fd, FString(voutput)); } } } @@ -4955,7 +4773,7 @@ int atcommand_character_item_list(const int fd, dumb_ptr<map_session_data> sd, clif_displaymessage(fd, "No item found on this player."); else { - std::string output = STRPRINTF( + FString output = STRPRINTF( "%d item(s) found in %d kind(s) of items.", counter, count); clif_displaymessage(fd, output); @@ -4981,22 +4799,22 @@ int atcommand_character_item_list(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_character_storage_list(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { struct storage *stor; - dumb_ptr<map_session_data> pl_sd; struct item_data *item_data, *item_temp; int i, j, count, counter, counter2; - char character[100] {}; + CharName character; - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) + if (!asplit(message, &character)) { clif_displaymessage(fd, - "Please, enter a player name (usage: @charitemlist <char name>)."); + "Please, enter a player name (usage: @charitemlist <char name>)."); return -1; } - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can look items only lower or same level @@ -5014,12 +4832,12 @@ int atcommand_character_storage_list(const int fd, dumb_ptr<map_session_data> sd count++; if (count == 1) { - std::string output = STRPRINTF( - "------ Storage items list of '%s' ------", - pl_sd->status.name); + FString output = STRPRINTF( + "------ Storage items list of '%s' ------", + pl_sd->status.name); clif_displaymessage(fd, output); } - std::string output; + FString output; if (stor->storage_[i].refine) output = STRPRINTF("%d %s %+d (%s %+d, id: %d)", stor->storage_[i].amount, @@ -5035,7 +4853,7 @@ int atcommand_character_storage_list(const int fd, dumb_ptr<map_session_data> sd stor->storage_[i].nameid); clif_displaymessage(fd, output); - output.clear(); + MString voutput; counter2 = 0; for (j = 0; j < item_data->slot; j++) { @@ -5046,14 +4864,15 @@ int atcommand_character_storage_list(const int fd, dumb_ptr<map_session_data> sd storage_[i].card[j])) != NULL) { - if (output.empty()) - output = STRPRINTF( - " -> (card(s): #%d %s (%s), ", + if (!voutput) + voutput += STRPRINTF( + " -> (card(s): " + "#%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname); else - output += STRPRINTF( + voutput += STRPRINTF( "#%d %s (%s), ", ++counter2, item_temp->name, @@ -5061,27 +4880,23 @@ int atcommand_character_storage_list(const int fd, dumb_ptr<map_session_data> sd } } } - if (!output.empty()) + if (voutput) { // replace last ", " -#ifdef WORKAROUND_GCC46_LIBRARY - output.resize(output.size() - 1); -#else - output.pop_back(); -#endif - output.back() = ')'; - clif_displaymessage(fd, output); + voutput.pop_back(); + voutput.back() = ')'; + clif_displaymessage(fd, FString(voutput)); } } } if (count == 0) clif_displaymessage(fd, - "No item found in the storage of this player."); + "No item found in the storage of this player."); else { - std::string output = STRPRINTF( - "%d item(s) found in %d kind(s) of items.", - counter, count); + FString output = STRPRINTF( + "%d item(s) found in %d kind(s) of items.", + counter, count); clif_displaymessage(fd, output); } } @@ -5111,21 +4926,21 @@ int atcommand_character_storage_list(const int fd, dumb_ptr<map_session_data> sd *------------------------------------------ */ int atcommand_character_cart_list(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - dumb_ptr<map_session_data> pl_sd; struct item_data *item_data, *item_temp; int i, j, count, counter, counter2; - char character[100] {}; + CharName character; - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) + if (!asplit(message, &character)) { clif_displaymessage(fd, - "Please, enter a player name (usage: @charitemlist <char name>)."); + "Please, enter a player name (usage: @charitemlist <char name>)."); return -1; } - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can look items only lower or same level @@ -5141,13 +4956,13 @@ int atcommand_character_cart_list(const int fd, dumb_ptr<map_session_data> sd, count++; if (count == 1) { - std::string output = STRPRINTF( + FString output = STRPRINTF( "------ Cart items list of '%s' ------", pl_sd->status.name); clif_displaymessage(fd, output); } - std::string output; + FString output; if (pl_sd->status.cart[i].refine) output = STRPRINTF("%d %s %+d (%s %+d, id: %d)", pl_sd->status.cart[i].amount, @@ -5164,7 +4979,7 @@ int atcommand_character_cart_list(const int fd, dumb_ptr<map_session_data> sd, pl_sd->status.cart[i].nameid); clif_displaymessage(fd, output); - output.clear(); + MString voutput; counter2 = 0; for (j = 0; j < item_data->slot; j++) { @@ -5174,14 +4989,15 @@ int atcommand_character_cart_list(const int fd, dumb_ptr<map_session_data> sd, itemdb_search(pl_sd->status. cart[i].card[j])) != NULL) { - if (output.empty()) - output = STRPRINTF( - " -> (card(s): #%d %s (%s), ", + if (!voutput) + voutput += STRPRINTF( + " -> (card(s): " + "#%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname); else - output += STRPRINTF( + voutput += STRPRINTF( "#%d %s (%s), ", ++counter2, item_temp->name, @@ -5189,24 +5005,20 @@ int atcommand_character_cart_list(const int fd, dumb_ptr<map_session_data> sd, } } } - if (!output.empty()) + if (voutput) { -#ifdef WORKAROUND_GCC46_LIBRARY - output.resize(output.size() - 1); -#else - output.pop_back(); -#endif - output.back() = '0'; - clif_displaymessage(fd, output); + voutput.pop_back(); + voutput.back() = '0'; + clif_displaymessage(fd, FString(voutput)); } } } if (count == 0) clif_displaymessage(fd, - "No item found in the cart of this player."); + "No item found in the cart of this player."); else { - std::string output = STRPRINTF("%d item(s) found in %d kind(s) of items.", + FString output = STRPRINTF("%d item(s) found in %d kind(s) of items.", counter, count); clif_displaymessage(fd, output); } @@ -5232,7 +5044,7 @@ int atcommand_character_cart_list(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_killer(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { sd->special_state.killer = !sd->special_state.killer; @@ -5250,7 +5062,7 @@ int atcommand_killer(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_killable(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { sd->special_state.killable = !sd->special_state.killable; @@ -5268,14 +5080,15 @@ int atcommand_killable(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_charkillable(const int fd, dumb_ptr<map_session_data>, - const char *, const char *message) + ZString message) { - dumb_ptr<map_session_data> pl_sd = NULL; + CharName character; - if (!message || !*message) + if (!asplit(message, &character)) return -1; - if ((pl_sd = map_nick2sd(message)) == NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd == NULL) return -1; pl_sd->special_state.killable = !pl_sd->special_state.killable; @@ -5295,19 +5108,16 @@ int atcommand_charkillable(const int fd, dumb_ptr<map_session_data>, *------------------------------------------ */ int atcommand_npcmove(const int, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char character[100] {}; + NpcName character; int x = 0, y = 0; dumb_ptr<npc_data> nd = 0; if (sd == NULL) return -1; - if (!message || !*message) - return -1; - - if (sscanf(message, "%d %d %99[^\n]", &x, &y, character) < 3) + if (!asplit(message, &x, &y, &character)) return -1; nd = npc_name2id(character); @@ -5329,24 +5139,22 @@ int atcommand_npcmove(const int, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_addwarp(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char mapname[30]; - int x, y, ret; + MapName mapname; + int x, y; - if (!message || !*message) + if (!extract(message, record<' '>(&mapname, &x, &y))) return -1; - if (sscanf(message, "%29s %d %d[^\n]", mapname, &x, &y) < 3) - return -1; - - std::string w1 = STRPRINTF("%s,%d,%d", sd->mapname_, sd->bl_x, sd->bl_y); - std::string w3 = STRPRINTF("%s%d%d%d%d", mapname, sd->bl_x, sd->bl_y, x, y); - std::string w4 = STRPRINTF("1,1,%s.gat,%d,%d", mapname, x, y); + FString w1 = STRPRINTF("%s,%d,%d", sd->mapname_, sd->bl_x, sd->bl_y); + FString w3 = STRPRINTF("%s%d%d%d%d", mapname, sd->bl_x, sd->bl_y, x, y); + FString w4 = STRPRINTF("1,1,%s.gat,%d,%d", mapname, x, y); - ret = npc_parse_warp(w1.c_str(), "warp", w3.c_str(), w4.c_str()); + NpcName w3name = stringish<NpcName>(w3); + int ret = npc_parse_warp(w1, ZString("warp"), w3name, w4); - std::string output = STRPRINTF("New warp NPC => %s", w3); + FString output = STRPRINTF("New warp NPC => %s", w3); clif_displaymessage(fd, output); return ret; @@ -5359,20 +5167,19 @@ int atcommand_addwarp(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_chareffect(const int fd, dumb_ptr<map_session_data>, - const char *, const char *message) + ZString message) { - dumb_ptr<map_session_data> pl_sd = NULL; - char target[255]; + CharName target; int type = 0; - if (!message || !*message - || sscanf(message, "%d %s", &type, target) != 2) + if (!asplit(message, &type, &target)) { clif_displaymessage(fd, "usage: @chareffect <type+> <target>."); return -1; } - if ((pl_sd = map_nick2sd(target)) == NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(target); + if (pl_sd == NULL) return -1; clif_specialeffect(pl_sd, type, 0); @@ -5388,7 +5195,7 @@ int atcommand_chareffect(const int fd, dumb_ptr<map_session_data>, *------------------------------------------ */ int atcommand_dropall(const int, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { int i; for (i = 0; i < MAX_INVENTORY; i++) @@ -5411,16 +5218,16 @@ int atcommand_dropall(const int, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_chardropall(const int fd, dumb_ptr<map_session_data>, - const char *, const char *message) + ZString message) { - int i; - dumb_ptr<map_session_data> pl_sd = NULL; + CharName character; - if (!message || !*message) + if (!asplit(message, &character)) return -1; - if ((pl_sd = map_nick2sd(message)) == NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd == NULL) return -1; - for (i = 0; i < MAX_INVENTORY; i++) + for (int i = 0; i < MAX_INVENTORY; i++) { if (pl_sd->status.inventory[i].amount) { @@ -5445,7 +5252,7 @@ int atcommand_chardropall(const int fd, dumb_ptr<map_session_data>, *------------------------------------------ */ int atcommand_storeall(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { int i; nullpo_retr(-1, sd); @@ -5459,7 +5266,7 @@ int atcommand_storeall(const int fd, dumb_ptr<map_session_data> sd, return 0; case 1: //Failure clif_displaymessage(fd, - "You can't open the storage currently."); + "You can't open the storage currently."); return 1; } } @@ -5485,24 +5292,24 @@ int atcommand_storeall(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_charstoreall(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - int i; - dumb_ptr<map_session_data> pl_sd = NULL; + CharName character; - if (!message || !*message) + if (!asplit(message, &character)) return -1; - if ((pl_sd = map_nick2sd(message)) == NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd == NULL) return -1; if (storage_storageopen(pl_sd) == 1) { clif_displaymessage(fd, - "Had to open the characters storage window..."); + "Had to open the characters storage window..."); clif_displaymessage(fd, "run this command again.."); return 0; } - for (i = 0; i < MAX_INVENTORY; i++) + for (int i = 0; i < MAX_INVENTORY; i++) { if (pl_sd->status.inventory[i].amount) { @@ -5514,9 +5321,9 @@ int atcommand_charstoreall(const int fd, dumb_ptr<map_session_data> sd, storage_storageclose(pl_sd); clif_displaymessage(pl_sd->fd, - "Everything you own has been put away for safe keeping."); + "Everything you own has been put away for safe keeping."); clif_displaymessage(pl_sd->fd, - "go to the nearest kafka to retrieve it.."); + "go to the nearest kafka to retrieve it.."); clif_displaymessage(pl_sd->fd, " -- the management"); clif_displaymessage(fd, "It is done"); @@ -5529,7 +5336,7 @@ int atcommand_charstoreall(const int fd, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_rain(const int, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { int effno = 0; effno = 161; @@ -5547,7 +5354,7 @@ int atcommand_rain(const int, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_snow(const int, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { int effno = 0; effno = 162; @@ -5565,7 +5372,7 @@ int atcommand_snow(const int, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_sakura(const int, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { int effno = 0; effno = 163; @@ -5583,7 +5390,7 @@ int atcommand_sakura(const int, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_fog(const int, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { int effno = 0; effno = 233; @@ -5602,7 +5409,7 @@ int atcommand_fog(const int, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_leaves(const int, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { int effno = 0; effno = 333; @@ -5620,24 +5427,21 @@ int atcommand_leaves(const int, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_summon(const int, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char name[100]; + MobName name; int mob_id = 0; int x = 0; int y = 0; int id = 0; - dumb_ptr<mob_data> md; tick_t tick = gettick(); nullpo_retr(-1, sd); - if (!message || !*message) - return -1; - if (sscanf(message, "%99[^\n]", name) < 1) + if (!extract(message, &name) || !name) return -1; - if ((mob_id = atoi(name)) == 0) + if ((mob_id = atoi(name.c_str())) == 0) mob_id = mobdb_searchname(name); if (mob_id == 0) return -1; @@ -5645,8 +5449,9 @@ int atcommand_summon(const int, dumb_ptr<map_session_data> sd, x = sd->bl_x + random_::in(-5, 4); y = sd->bl_y + random_::in(-5, 4); - id = mob_once_spawn(sd, "this", x, y, "--ja--", mob_id, 1, ""); - if ((md = map_id_as_mob(id))) + id = mob_once_spawn(sd, MOB_THIS_MAP, x, y, JAPANESE_NAME, mob_id, 1, NpcEvent()); + dumb_ptr<mob_data> md = map_id_as_mob(id); + if (md) { md->master_id = sd->bl_id; md->state.special_mob_ai = 1; @@ -5670,19 +5475,19 @@ int atcommand_summon(const int, dumb_ptr<map_session_data> sd, *------------------------------------------ */ int atcommand_adjcmdlvl(const int fd, dumb_ptr<map_session_data>, - const char *, const char *message) + ZString message) { - int i, newlev; - char cmd[100]; + int newlev; + XString cmd; - if (!message || !*message || sscanf(message, "%d %s", &newlev, cmd) != 2) + if (!extract(message, record<' '>(&newlev, &cmd))) { clif_displaymessage(fd, "usage: @adjcmdlvl <lvl> <command>."); return -1; } - for (i = 0; atcommand_info[i].command; i++) - if (strcasecmp(cmd, atcommand_info[i].command + 1) == 0) + for (int i = 0; atcommand_info[i].command; i++) + if (cmd == atcommand_info[i].command.xslice_t(1)) { atcommand_info[i].level = newlev; clif_displaymessage(fd, "@command level changed."); @@ -5703,21 +5508,20 @@ int atcommand_adjcmdlvl(const int fd, dumb_ptr<map_session_data>, *------------------------------------------ */ int atcommand_adjgmlvl(const int fd, dumb_ptr<map_session_data>, - const char *, const char *message) + ZString message) { int newlev; - char user[100]; - dumb_ptr<map_session_data> pl_sd; + CharName user; - if (!message || !*message - || sscanf(message, "%d %s", &newlev, user) != 2 + if (!asplit(message, &newlev, &user) || newlev < 0 || newlev > 99) { clif_displaymessage(fd, "usage: @adjgmlvl <lvl> <user>."); return -1; } - if ((pl_sd = map_nick2sd(user)) == NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(user); + if (pl_sd == NULL) return -1; pc_set_gm_level(pl_sd->status.account_id, newlev); @@ -5735,13 +5539,15 @@ int atcommand_adjgmlvl(const int fd, dumb_ptr<map_session_data>, *------------------------------------------ */ int atcommand_trade(const int, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - dumb_ptr<map_session_data> pl_sd = NULL; + CharName character; - if (!message || !*message) + if (!asplit(message, &character)) return -1; - if ((pl_sd = map_nick2sd(message)) != NULL) + + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd) { trade_traderequest(sd, pl_sd->bl_id); return 0; @@ -5766,7 +5572,7 @@ constexpr size_t magic_skills_nr = sizeof(magic_skills) / sizeof(magic_skills[0]); static -const char *magic_skill_names[magic_skills_nr] = +ZString magic_skill_names[magic_skills_nr] = { "magic", "life", @@ -5777,20 +5583,20 @@ const char *magic_skill_names[magic_skills_nr] = }; int atcommand_magic_info(const int fd, dumb_ptr<map_session_data>, - const char *, const char *message) + ZString message) { - char character[100] {}; - dumb_ptr<map_session_data> pl_sd; + CharName character; - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) + if (!asplit(message, &character)) { clif_displaymessage(fd, "Usage: @magicinfo <char_name>"); return -1; } - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd) { - std::string buf = STRPRINTF( + FString buf = STRPRINTF( "`%s' has the following magic skills:", character); clif_displaymessage(fd, buf); @@ -5821,30 +5627,27 @@ void set_skill(dumb_ptr<map_session_data> sd, SkillID i, int level) } int atcommand_set_magic(const int fd, dumb_ptr<map_session_data>, - const char *, const char *message) + ZString message) { - char character[100] {}; - char magic_type[20]; + CharName character; + XString magic_type; int value; - dumb_ptr<map_session_data> pl_sd; - if (!message || !*message - || sscanf(message, "%19s %i %99[^\n]", magic_type, &value, - character) < 1) + if (!asplit(message, &magic_type, &value, &character)) { clif_displaymessage(fd, - "Usage: @setmagic <school> <value> <char-name>, where <school> is either `magic', one of the school names, or `all'."); + "Usage: @setmagic <school> <value> <char-name>, where <school> is either `magic', one of the school names, or `all'."); return -1; } SkillID skill_index = SkillID::NEGATIVE; - if (!strcasecmp("all", magic_type)) + if ("all" == magic_type) skill_index = SkillID::ZERO; else { for (size_t i = 0; i < magic_skills_nr; i++) { - if (!strcasecmp(magic_skill_names[i], magic_type)) + if (magic_skill_names[i] == magic_type) { skill_index = magic_skills[i]; break; @@ -5855,11 +5658,12 @@ int atcommand_set_magic(const int fd, dumb_ptr<map_session_data>, if (skill_index == SkillID::NEGATIVE) { clif_displaymessage(fd, - "Incorrect school of magic. Use `magic', `nature', `life', `war', `transmute', `ether', or `all'."); + "Incorrect school of magic. Use `magic', `nature', `life', `war', `transmute', `ether', or `all'."); return -1; } - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { if (skill_index == SkillID::ZERO) for (SkillID sk : magic_skills) @@ -5877,32 +5681,32 @@ int atcommand_set_magic(const int fd, dumb_ptr<map_session_data>, } int atcommand_log(const int, dumb_ptr<map_session_data>, - const char *, const char *) + ZString) { return 0; // only used for (implicit) logging } int atcommand_tee(const int, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { - char data[strlen(message) + 28]; - strcpy(data, sd->status.name); - strcat(data, " : "); - strcat(data, message); - clif_message(sd, data); + MString data; + data += sd->status.name.to__actual(); + data += " : "; + data += message; + clif_message(sd, FString(data)); return 0; } int atcommand_invisible(const int, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { pc_invisibility(sd, 1); return 0; } int atcommand_visible(const int, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { pc_invisibility(sd, 0); return 0; @@ -5910,7 +5714,6 @@ int atcommand_visible(const int, dumb_ptr<map_session_data> sd, static int atcommand_jump_iterate(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *, dumb_ptr<map_session_data> (*get_start)(void), dumb_ptr<map_session_data> (*get_next)(dumb_ptr<map_session_data>)) { @@ -5935,18 +5738,18 @@ int atcommand_jump_iterate(const int fd, dumb_ptr<map_session_data> sd, && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { clif_displaymessage(fd, - "You are not authorised to warp you to the map of this player."); + "You are not authorised to warp you to the map of this player."); return -1; } if (sd->bl_m && sd->bl_m->flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { clif_displaymessage(fd, - "You are not authorised to warp you from your actual map."); + "You are not authorised to warp you from your actual map."); return -1; } pc_setpos(sd, pl_sd->bl_m->name_, pl_sd->bl_x, pl_sd->bl_y, BeingRemoveWhy::WARPED); - std::string output = STRPRINTF("Jump to %s", pl_sd->status.name); + FString output = STRPRINTF("Jump to %s", pl_sd->status.name); clif_displaymessage(fd, output); sd->followtarget = pl_sd->bl_id; @@ -5954,33 +5757,23 @@ int atcommand_jump_iterate(const int fd, dumb_ptr<map_session_data> sd, return 0; } -int atcommand_iterate_forward_over_players(const int fd, - dumb_ptr<map_session_data> sd, - const char *command, - const char *message) +int atcommand_iterate_forward_over_players(const int fd, dumb_ptr<map_session_data> sd, ZString) { - return atcommand_jump_iterate(fd, sd, command, message, - map_get_first_session, - map_get_next_session); + return atcommand_jump_iterate(fd, sd, map_get_first_session, map_get_next_session); } -int atcommand_iterate_backwards_over_players(const int fd, - dumb_ptr<map_session_data> sd, - const char *command, - const char *message) +int atcommand_iterate_backwards_over_players(const int fd, dumb_ptr<map_session_data> sd, ZString) { - return atcommand_jump_iterate(fd, sd, command, message, - map_get_last_session, - map_get_prev_session); + return atcommand_jump_iterate(fd, sd, map_get_last_session, map_get_prev_session); } int atcommand_wgm(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *message) + ZString message) { if (tmw_CheckChatSpam(sd, message)) return 0; - tmw_GmHackMsg(STRPRINTF("[GM] %s: %s", sd->status.name, message).c_str()); + tmw_GmHackMsg(STRPRINTF("[GM] %s: %s", sd->status.name, message)); if (!pc_isGM(sd)) clif_displaymessage(fd, "Message sent."); @@ -5989,24 +5782,24 @@ int atcommand_wgm(const int fd, dumb_ptr<map_session_data> sd, int atcommand_skillpool_info(const int fd, dumb_ptr<map_session_data>, - const char *, const char *message) + ZString message) { - char character[100]; - dumb_ptr<map_session_data> pl_sd; + CharName character; - if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1) + if (!asplit(message, &character)) { clif_displaymessage(fd, "Usage: @sp-info <char_name>"); return -1; } - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { SkillID pool_skills[MAX_SKILL_POOL]; int pool_skills_nr = skill_pool(pl_sd, pool_skills); int i; - std::string buf = STRPRINTF( + FString buf = STRPRINTF( "Active skills %d out of %d for %s:", pool_skills_nr, skill_pool_max(pl_sd), character); clif_displaymessage(fd, buf); @@ -6044,22 +5837,19 @@ int atcommand_skillpool_info(const int fd, dumb_ptr<map_session_data>, } int atcommand_skillpool_focus(const int fd, dumb_ptr<map_session_data>, - const char *, const char *message) + ZString message) { - char character[100]; - int skill_; - dumb_ptr<map_session_data> pl_sd; + CharName character; + SkillID skill; - if (!message || !*message - || sscanf(message, "%d %99[^\n]", &skill_, character) < 1) + if (!asplit(message, &skill, &character)) { clif_displaymessage(fd, "Usage: @sp-focus <skill-nr> <char_name>"); return -1; } - SkillID skill = SkillID(skill_); - - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { if (skill_pool_activate(pl_sd, skill)) clif_displaymessage(fd, "Activation failed."); @@ -6073,22 +5863,19 @@ int atcommand_skillpool_focus(const int fd, dumb_ptr<map_session_data>, } int atcommand_skillpool_unfocus(const int fd, dumb_ptr<map_session_data>, - const char *, const char *message) + ZString message) { - char character[100]; - int skill_; - dumb_ptr<map_session_data> pl_sd; + CharName character; + SkillID skill; - if (!message || !*message - || sscanf(message, "%d %99[^\n]", &skill_, character) < 1) + if (!asplit(message, &skill, &character)) { clif_displaymessage(fd, "Usage: @sp-unfocus <skill-nr> <char_name>"); return -1; } - SkillID skill = SkillID(skill_); - - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { if (skill_pool_deactivate(pl_sd, skill)) clif_displaymessage(fd, "Deactivation failed."); @@ -6102,23 +5889,21 @@ int atcommand_skillpool_unfocus(const int fd, dumb_ptr<map_session_data>, } int atcommand_skill_learn(const int fd, dumb_ptr<map_session_data>, - const char *, const char *message) + ZString message) { - char character[100]; - int skill_, level; - dumb_ptr<map_session_data> pl_sd; + CharName character; + SkillID skill; + int level; - if (!message || !*message - || sscanf(message, "%d %d %99[^\n]", &skill_, &level, character) < 1) + if (!asplit(message, &skill, &level, &character)) { clif_displaymessage(fd, - "Usage: @skill-learn <skill-nr> <level> <char_name>"); + "Usage: @skill-learn <skill-nr> <level> <char_name>"); return -1; } - SkillID skill = SkillID(skill_); - - if ((pl_sd = map_nick2sd(character)) != NULL) + dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); + if (pl_sd != NULL) { set_skill(pl_sd, skill, level); clif_skillinfoblock(pl_sd); @@ -6130,14 +5915,14 @@ int atcommand_skill_learn(const int fd, dumb_ptr<map_session_data>, } int atcommand_ipcheck(const int fd, dumb_ptr<map_session_data>, - const char *, const char *message) + ZString message) { struct sockaddr_in sai; - char character[25] {}; + CharName character; socklen_t sa_len = sizeof(struct sockaddr); unsigned long ip; - if (sscanf(message, "%24[^\n]", character) < 1) + if (!asplit(message, &character)) { clif_displaymessage(fd, "Usage: @ipcheck <char name>"); return -1; @@ -6153,7 +5938,7 @@ int atcommand_ipcheck(const int fd, dumb_ptr<map_session_data>, if (getpeername(pl_sd->fd, reinterpret_cast<struct sockaddr *>(&sai), &sa_len)) { clif_displaymessage(fd, - "Guru Meditation Error: getpeername() failed"); + "Guru Meditation Error: getpeername() failed"); return -1; } @@ -6175,7 +5960,7 @@ int atcommand_ipcheck(const int fd, dumb_ptr<map_session_data>, // Is checking GM levels really needed here? if (ip == sai.sin_addr.s_addr) { - std::string output = STRPRINTF( + FString output = STRPRINTF( "Name: %s | Location: %s %d %d", pl_sd->status.name, pl_sd->mapname_, pl_sd->bl_x, pl_sd->bl_y); @@ -6189,7 +5974,7 @@ int atcommand_ipcheck(const int fd, dumb_ptr<map_session_data>, } int atcommand_doomspot(const int fd, dumb_ptr<map_session_data> sd, - const char *, const char *) + ZString) { for (int i = 0; i < fd_max; i++) { diff --git a/src/map/atcommand.hpp b/src/map/atcommand.hpp index d81f04d..7f31491 100644 --- a/src/map/atcommand.hpp +++ b/src/map/atcommand.hpp @@ -6,13 +6,13 @@ #include "map.hpp" bool is_atcommand(const int fd, dumb_ptr<map_session_data> sd, - const char *message, int gmlvl); + ZString message, int gmlvl); -int atcommand_config_read(const char *cfgName); +int atcommand_config_read(ZString cfgName); -void log_atcommand(dumb_ptr<map_session_data> sd, const_string cmd); +void log_atcommand(dumb_ptr<map_session_data> sd, XString cmd); // only used by map.cpp -extern std::string gm_logfile_name; +extern FString gm_logfile_name; #endif // ATCOMMAND_HPP diff --git a/src/map/battle.cpp b/src/map/battle.cpp index abef80b..4045348 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -5,8 +5,9 @@ #include <fstream> #include "../common/cxxstdio.hpp" -#include "../common/random.hpp" +#include "../common/io.hpp" #include "../common/nullpo.hpp" +#include "../common/random.hpp" #include "clif.hpp" #include "itemdb.hpp" @@ -2290,7 +2291,7 @@ int battle_check_range(dumb_ptr<block_list> src, dumb_ptr<block_list> bl, * 設定ファイルを読み込む *------------------------------------------ */ -int battle_config_read(const char *cfgName) +int battle_config_read(ZString cfgName) { static int count = 0; @@ -2458,200 +2459,203 @@ int battle_config_read(const char *cfgName) battle_config.mob_splash_radius = -1; } - std::ifstream in(cfgName); + std::ifstream in(cfgName.c_str()); if (!in.is_open()) { PRINTF("file not found: %s\n", cfgName); return 1; } - std::string line; - while (std::getline(in, line)) + FString line; + while (io::getline(in, line)) { +#define BATTLE_CONFIG_VAR2(name, varname) {{name}, &battle_config.varname} +#define BATTLE_CONFIG_VAR(name) BATTLE_CONFIG_VAR2(#name, name) // s/{"\([a-zA-Z_0-9]*\)", &battle_config.\1}/BATTLE_CONFIG_VAR(\1)/ const struct { - const char *str; + ZString str; int *val; } data[] = { - {"warp_point_debug", &battle_config.warp_point_debug}, - {"enemy_critical", &battle_config.enemy_critical}, - {"enemy_critical_rate", &battle_config.enemy_critical_rate}, - {"enemy_str", &battle_config.enemy_str}, - {"enemy_perfect_flee", &battle_config.enemy_perfect_flee}, - {"casting_rate", &battle_config.cast_rate}, - {"delay_rate", &battle_config.delay_rate}, - {"delay_dependon_dex", &battle_config.delay_dependon_dex}, - {"skill_delay_attack_enable", &battle_config.sdelay_attack_enable}, - {"left_cardfix_to_right", &battle_config.left_cardfix_to_right}, - {"player_skill_add_range", &battle_config.pc_skill_add_range}, - {"skill_out_range_consume", &battle_config.skill_out_range_consume}, - {"monster_skill_add_range", &battle_config.mob_skill_add_range}, - {"player_damage_delay", &battle_config.pc_damage_delay}, - {"defunit_not_enemy", &battle_config.defnotenemy}, - {"random_monster_checklv", &battle_config.random_monster_checklv}, - {"attribute_recover", &battle_config.attr_recover}, - {"flooritem_lifetime", &battle_config.flooritem_lifetime}, - {"item_auto_get", &battle_config.item_auto_get}, - {"drop_pickup_safety_zone", &battle_config.drop_pickup_safety_zone}, - {"item_first_get_time", &battle_config.item_first_get_time}, - {"item_second_get_time", &battle_config.item_second_get_time}, - {"item_third_get_time", &battle_config.item_third_get_time}, - {"base_exp_rate", &battle_config.base_exp_rate}, - {"job_exp_rate", &battle_config.job_exp_rate}, - {"gtb_pvp_only", &battle_config.gtb_pvp_only}, - {"death_penalty_type", &battle_config.death_penalty_type}, - {"death_penalty_base", &battle_config.death_penalty_base}, - {"death_penalty_job", &battle_config.death_penalty_job}, - {"zeny_penalty", &battle_config.zeny_penalty}, - {"restart_hp_rate", &battle_config.restart_hp_rate}, - {"restart_sp_rate", &battle_config.restart_sp_rate}, - {"monster_hp_rate", &battle_config.monster_hp_rate}, - {"monster_max_aspd", &battle_config.monster_max_aspd}, - {"atcommand_gm_only", &battle_config.atc_gmonly}, - {"atcommand_spawn_quantity_limit", &battle_config.atc_spawn_quantity_limit}, - {"gm_all_skill", &battle_config.gm_allskill}, - {"gm_all_skill_add_abra", &battle_config.gm_allskill_addabra}, - {"gm_all_equipment", &battle_config.gm_allequip}, - {"gm_skill_unconditional", &battle_config.gm_skilluncond}, - {"player_skillfree", &battle_config.skillfree}, - {"player_skillup_limit", &battle_config.skillup_limit}, - {"weapon_produce_rate", &battle_config.wp_rate}, - {"potion_produce_rate", &battle_config.pp_rate}, - {"monster_active_enable", &battle_config.monster_active_enable}, - {"mob_skill_use", &battle_config.mob_skill_use}, - {"mob_count_rate", &battle_config.mob_count_rate}, - {"quest_skill_learn", &battle_config.quest_skill_learn}, - {"quest_skill_reset", &battle_config.quest_skill_reset}, - {"basic_skill_check", &battle_config.basic_skill_check}, - {"player_invincible_time", &battle_config.pc_invincible_time}, - {"skill_min_damage", &battle_config.skill_min_damage}, - {"finger_offensive_type", &battle_config.finger_offensive_type}, - {"heal_exp", &battle_config.heal_exp}, - {"resurrection_exp", &battle_config.resurrection_exp}, - {"shop_exp", &battle_config.shop_exp}, - {"combo_delay_rate", &battle_config.combo_delay_rate}, - {"wedding_modifydisplay", &battle_config.wedding_modifydisplay}, - {"natural_healhp_interval", &battle_config.natural_healhp_interval}, - {"natural_healsp_interval", &battle_config.natural_healsp_interval}, - {"natural_heal_skill_interval", &battle_config.natural_heal_skill_interval}, - {"natural_heal_weight_rate", &battle_config.natural_heal_weight_rate}, - {"itemheal_regeneration_factor", &battle_config.itemheal_regeneration_factor}, - {"item_name_override_grffile", &battle_config.item_name_override_grffile}, - {"arrow_decrement", &battle_config.arrow_decrement}, - {"max_aspd", &battle_config.max_aspd}, - {"max_hp", &battle_config.max_hp}, - {"max_sp", &battle_config.max_sp}, - {"max_lv", &battle_config.max_lv}, - {"max_parameter", &battle_config.max_parameter}, - {"max_cart_weight", &battle_config.max_cart_weight}, - {"player_skill_log", &battle_config.pc_skill_log}, - {"monster_skill_log", &battle_config.mob_skill_log}, - {"battle_log", &battle_config.battle_log}, - {"save_log", &battle_config.save_log}, - {"error_log", &battle_config.error_log}, - {"etc_log", &battle_config.etc_log}, - {"save_clothcolor", &battle_config.save_clothcolor}, - {"undead_detect_type", &battle_config.undead_detect_type}, - {"player_auto_counter_type", &battle_config.pc_auto_counter_type}, - {"monster_auto_counter_type", &battle_config.monster_auto_counter_type}, - {"agi_penaly_type", &battle_config.agi_penaly_type}, - {"agi_penaly_count", &battle_config.agi_penaly_count}, - {"agi_penaly_num", &battle_config.agi_penaly_num}, - {"agi_penaly_count_lv", &battle_config.agi_penaly_count_lv}, - {"vit_penaly_type", &battle_config.vit_penaly_type}, - {"vit_penaly_count", &battle_config.vit_penaly_count}, - {"vit_penaly_num", &battle_config.vit_penaly_num}, - {"vit_penaly_count_lv", &battle_config.vit_penaly_count_lv}, - {"player_skill_reiteration", &battle_config.pc_skill_reiteration}, - {"monster_skill_reiteration", &battle_config.monster_skill_reiteration}, - {"player_skill_nofootset", &battle_config.pc_skill_nofootset}, - {"monster_skill_nofootset", &battle_config.monster_skill_nofootset}, - {"player_cloak_check_type", &battle_config.pc_cloak_check_type}, - {"monster_cloak_check_type", &battle_config.monster_cloak_check_type}, - {"mob_changetarget_byskill", &battle_config.mob_changetarget_byskill}, - {"player_attack_direction_change", &battle_config.pc_attack_direction_change}, - {"monster_attack_direction_change", &battle_config.monster_attack_direction_change}, - {"player_land_skill_limit", &battle_config.pc_land_skill_limit}, - {"monster_land_skill_limit", &battle_config.monster_land_skill_limit}, - {"party_skill_penaly", &battle_config.party_skill_penaly}, - {"monster_class_change_full_recover", &battle_config.monster_class_change_full_recover}, - {"produce_item_name_input", &battle_config.produce_item_name_input}, - {"produce_potion_name_input", &battle_config.produce_potion_name_input}, - {"making_arrow_name_input", &battle_config.making_arrow_name_input}, - {"holywater_name_input", &battle_config.holywater_name_input}, - {"display_delay_skill_fail", &battle_config.display_delay_skill_fail}, - {"chat_warpportal", &battle_config.chat_warpportal}, - {"mob_warpportal", &battle_config.mob_warpportal}, - {"dead_branch_active", &battle_config.dead_branch_active}, - {"show_steal_in_same_party", &battle_config.show_steal_in_same_party}, - {"enable_upper_class", &battle_config.enable_upper_class}, - {"mob_attack_attr_none", &battle_config.mob_attack_attr_none}, - {"mob_ghostring_fix", &battle_config.mob_ghostring_fix}, - {"pc_attack_attr_none", &battle_config.pc_attack_attr_none}, - {"gx_allhit", &battle_config.gx_allhit}, - {"gx_cardfix", &battle_config.gx_cardfix}, - {"gx_dupele", &battle_config.gx_dupele}, - {"gx_disptype", &battle_config.gx_disptype}, - {"player_skill_partner_check", &battle_config.player_skill_partner_check}, - {"hide_GM_session", &battle_config.hide_GM_session}, - {"unit_movement_type", &battle_config.unit_movement_type}, - {"invite_request_check", &battle_config.invite_request_check}, - {"skill_removetrap_type", &battle_config.skill_removetrap_type}, - {"disp_experience", &battle_config.disp_experience}, - {"riding_weight", &battle_config.riding_weight}, - {"prevent_logout", &battle_config.prevent_logout}, // Added by RoVeRT - {"alchemist_summon_reward", &battle_config.alchemist_summon_reward}, // [Valaris] - {"maximum_level", &battle_config.maximum_level}, // [Valaris] - {"drops_by_luk", &battle_config.drops_by_luk}, // [Valaris] - {"monsters_ignore_gm", &battle_config.monsters_ignore_gm}, // [Valaris] - {"pk_mode", &battle_config.pk_mode}, // [Valaris] - {"multi_level_up", &battle_config.multi_level_up}, // [Valaris] - {"backstab_bow_penalty", &battle_config.backstab_bow_penalty}, - {"show_mob_hp", &battle_config.show_mob_hp}, // [Valaris] - {"hack_info_GM_level", &battle_config.hack_info_GM_level}, // added by [Yor] - {"any_warp_GM_min_level", &battle_config.any_warp_GM_min_level}, // added by [Yor] - {"packet_ver_flag", &battle_config.packet_ver_flag}, // added by [Yor] - {"min_hair_style", &battle_config.min_hair_style}, // added by [MouseJstr] - {"max_hair_style", &battle_config.max_hair_style}, // added by [MouseJstr] - {"min_hair_color", &battle_config.min_hair_color}, // added by [MouseJstr] - {"max_hair_color", &battle_config.max_hair_color}, // added by [MouseJstr] - {"min_cloth_color", &battle_config.min_cloth_color}, // added by [MouseJstr] - {"max_cloth_color", &battle_config.max_cloth_color}, // added by [MouseJstr] - {"castrate_dex_scale", &battle_config.castrate_dex_scale}, // added by [MouseJstr] - {"area_size", &battle_config.area_size}, // added by [MouseJstr] - {"chat_lame_penalty", &battle_config.chat_lame_penalty}, - {"chat_spam_threshold", &battle_config.chat_spam_threshold}, - {"chat_spam_flood", &battle_config.chat_spam_flood}, - {"chat_spam_ban", &battle_config.chat_spam_ban}, - {"chat_spam_warn", &battle_config.chat_spam_warn}, - {"chat_maxline", &battle_config.chat_maxline}, - {"packet_spam_threshold", &battle_config.packet_spam_threshold}, - {"packet_spam_flood", &battle_config.packet_spam_flood}, - {"packet_spam_kick", &battle_config.packet_spam_kick}, - {"mask_ip_gms", &battle_config.mask_ip_gms}, - {"mob_splash_radius", &battle_config.mob_splash_radius}, + BATTLE_CONFIG_VAR(warp_point_debug), + BATTLE_CONFIG_VAR(enemy_critical), + BATTLE_CONFIG_VAR(enemy_critical_rate), + BATTLE_CONFIG_VAR(enemy_str), + BATTLE_CONFIG_VAR(enemy_perfect_flee), + BATTLE_CONFIG_VAR2("casting_rate", cast_rate), + BATTLE_CONFIG_VAR(delay_rate), + BATTLE_CONFIG_VAR(delay_dependon_dex), + BATTLE_CONFIG_VAR2("skill_delay_attack_enable", sdelay_attack_enable), + BATTLE_CONFIG_VAR(left_cardfix_to_right), + BATTLE_CONFIG_VAR2("player_skill_add_range", pc_skill_add_range), + BATTLE_CONFIG_VAR(skill_out_range_consume), + BATTLE_CONFIG_VAR2("monster_skill_add_range", mob_skill_add_range), + BATTLE_CONFIG_VAR2("player_damage_delay", pc_damage_delay), + BATTLE_CONFIG_VAR2("defunit_not_enemy", defnotenemy), + BATTLE_CONFIG_VAR(random_monster_checklv), + BATTLE_CONFIG_VAR2("attribute_recover", attr_recover), + BATTLE_CONFIG_VAR(flooritem_lifetime), + BATTLE_CONFIG_VAR(item_auto_get), + BATTLE_CONFIG_VAR(drop_pickup_safety_zone), + BATTLE_CONFIG_VAR(item_first_get_time), + BATTLE_CONFIG_VAR(item_second_get_time), + BATTLE_CONFIG_VAR(item_third_get_time), + BATTLE_CONFIG_VAR(base_exp_rate), + BATTLE_CONFIG_VAR(job_exp_rate), + BATTLE_CONFIG_VAR(gtb_pvp_only), + BATTLE_CONFIG_VAR(death_penalty_type), + BATTLE_CONFIG_VAR(death_penalty_base), + BATTLE_CONFIG_VAR(death_penalty_job), + BATTLE_CONFIG_VAR(zeny_penalty), + BATTLE_CONFIG_VAR(restart_hp_rate), + BATTLE_CONFIG_VAR(restart_sp_rate), + BATTLE_CONFIG_VAR(monster_hp_rate), + BATTLE_CONFIG_VAR(monster_max_aspd), + BATTLE_CONFIG_VAR2("atcommand_gm_only", atc_gmonly), + BATTLE_CONFIG_VAR2("atcommand_spawn_quantity_limit", atc_spawn_quantity_limit), + BATTLE_CONFIG_VAR2("gm_all_skill", gm_allskill), + BATTLE_CONFIG_VAR2("gm_all_skill_add_abra", gm_allskill_addabra), + BATTLE_CONFIG_VAR2("gm_all_equipment", gm_allequip), + BATTLE_CONFIG_VAR2("gm_skill_unconditional", gm_skilluncond), + BATTLE_CONFIG_VAR2("player_skillfree", skillfree), + BATTLE_CONFIG_VAR2("player_skillup_limit", skillup_limit), + BATTLE_CONFIG_VAR2("weapon_produce_rate", wp_rate), + BATTLE_CONFIG_VAR2("potion_produce_rate", pp_rate), + BATTLE_CONFIG_VAR(monster_active_enable), + BATTLE_CONFIG_VAR(mob_skill_use), + BATTLE_CONFIG_VAR(mob_count_rate), + BATTLE_CONFIG_VAR(quest_skill_learn), + BATTLE_CONFIG_VAR(quest_skill_reset), + BATTLE_CONFIG_VAR(basic_skill_check), + BATTLE_CONFIG_VAR2("player_invincible_time", pc_invincible_time), + BATTLE_CONFIG_VAR(skill_min_damage), + BATTLE_CONFIG_VAR(finger_offensive_type), + BATTLE_CONFIG_VAR(heal_exp), + BATTLE_CONFIG_VAR(resurrection_exp), + BATTLE_CONFIG_VAR(shop_exp), + BATTLE_CONFIG_VAR(combo_delay_rate), + BATTLE_CONFIG_VAR(wedding_modifydisplay), + BATTLE_CONFIG_VAR(natural_healhp_interval), + BATTLE_CONFIG_VAR(natural_healsp_interval), + BATTLE_CONFIG_VAR(natural_heal_skill_interval), + BATTLE_CONFIG_VAR(natural_heal_weight_rate), + BATTLE_CONFIG_VAR(itemheal_regeneration_factor), + BATTLE_CONFIG_VAR(item_name_override_grffile), + BATTLE_CONFIG_VAR(arrow_decrement), + BATTLE_CONFIG_VAR(max_aspd), + BATTLE_CONFIG_VAR(max_hp), + BATTLE_CONFIG_VAR(max_sp), + BATTLE_CONFIG_VAR(max_lv), + BATTLE_CONFIG_VAR(max_parameter), + BATTLE_CONFIG_VAR(max_cart_weight), + BATTLE_CONFIG_VAR2("player_skill_log", pc_skill_log), + BATTLE_CONFIG_VAR2("monster_skill_log", mob_skill_log), + BATTLE_CONFIG_VAR(battle_log), + BATTLE_CONFIG_VAR(save_log), + BATTLE_CONFIG_VAR(error_log), + BATTLE_CONFIG_VAR(etc_log), + BATTLE_CONFIG_VAR(save_clothcolor), + BATTLE_CONFIG_VAR(undead_detect_type), + BATTLE_CONFIG_VAR2("player_auto_counter_type", pc_auto_counter_type), + BATTLE_CONFIG_VAR(monster_auto_counter_type), + BATTLE_CONFIG_VAR(agi_penaly_type), + BATTLE_CONFIG_VAR(agi_penaly_count), + BATTLE_CONFIG_VAR(agi_penaly_num), + BATTLE_CONFIG_VAR(agi_penaly_count_lv), + BATTLE_CONFIG_VAR(vit_penaly_type), + BATTLE_CONFIG_VAR(vit_penaly_count), + BATTLE_CONFIG_VAR(vit_penaly_num), + BATTLE_CONFIG_VAR(vit_penaly_count_lv), + BATTLE_CONFIG_VAR2("player_skill_reiteration", pc_skill_reiteration), + BATTLE_CONFIG_VAR(monster_skill_reiteration), + BATTLE_CONFIG_VAR2("player_skill_nofootset", pc_skill_nofootset), + BATTLE_CONFIG_VAR(monster_skill_nofootset), + BATTLE_CONFIG_VAR2("player_cloak_check_type", pc_cloak_check_type), + BATTLE_CONFIG_VAR(monster_cloak_check_type), + BATTLE_CONFIG_VAR(mob_changetarget_byskill), + BATTLE_CONFIG_VAR2("player_attack_direction_change", pc_attack_direction_change), + BATTLE_CONFIG_VAR(monster_attack_direction_change), + BATTLE_CONFIG_VAR2("player_land_skill_limit", pc_land_skill_limit), + BATTLE_CONFIG_VAR(monster_land_skill_limit), + BATTLE_CONFIG_VAR(party_skill_penaly), + BATTLE_CONFIG_VAR(monster_class_change_full_recover), + BATTLE_CONFIG_VAR(produce_item_name_input), + BATTLE_CONFIG_VAR(produce_potion_name_input), + BATTLE_CONFIG_VAR(making_arrow_name_input), + BATTLE_CONFIG_VAR(holywater_name_input), + BATTLE_CONFIG_VAR(display_delay_skill_fail), + BATTLE_CONFIG_VAR(chat_warpportal), + BATTLE_CONFIG_VAR(mob_warpportal), + BATTLE_CONFIG_VAR(dead_branch_active), + BATTLE_CONFIG_VAR(show_steal_in_same_party), + BATTLE_CONFIG_VAR(enable_upper_class), + BATTLE_CONFIG_VAR(mob_attack_attr_none), + BATTLE_CONFIG_VAR(mob_ghostring_fix), + BATTLE_CONFIG_VAR(pc_attack_attr_none), + BATTLE_CONFIG_VAR(gx_allhit), + BATTLE_CONFIG_VAR(gx_cardfix), + BATTLE_CONFIG_VAR(gx_dupele), + BATTLE_CONFIG_VAR(gx_disptype), + BATTLE_CONFIG_VAR(player_skill_partner_check), + BATTLE_CONFIG_VAR(hide_GM_session), + BATTLE_CONFIG_VAR(unit_movement_type), + BATTLE_CONFIG_VAR(invite_request_check), + BATTLE_CONFIG_VAR(skill_removetrap_type), + BATTLE_CONFIG_VAR(disp_experience), + BATTLE_CONFIG_VAR(riding_weight), + BATTLE_CONFIG_VAR(prevent_logout), // Added by RoVeRT + BATTLE_CONFIG_VAR(alchemist_summon_reward), // [Valaris] + BATTLE_CONFIG_VAR(maximum_level), // [Valaris] + BATTLE_CONFIG_VAR(drops_by_luk), // [Valaris] + BATTLE_CONFIG_VAR(monsters_ignore_gm), // [Valaris] + BATTLE_CONFIG_VAR(pk_mode), // [Valaris] + BATTLE_CONFIG_VAR(multi_level_up), // [Valaris] + BATTLE_CONFIG_VAR(backstab_bow_penalty), + BATTLE_CONFIG_VAR(show_mob_hp), // [Valaris] + BATTLE_CONFIG_VAR(hack_info_GM_level), // added by [Yor] + BATTLE_CONFIG_VAR(any_warp_GM_min_level), // added by [Yor] + BATTLE_CONFIG_VAR(packet_ver_flag), // added by [Yor] + BATTLE_CONFIG_VAR(min_hair_style), // added by [MouseJstr] + BATTLE_CONFIG_VAR(max_hair_style), // added by [MouseJstr] + BATTLE_CONFIG_VAR(min_hair_color), // added by [MouseJstr] + BATTLE_CONFIG_VAR(max_hair_color), // added by [MouseJstr] + BATTLE_CONFIG_VAR(min_cloth_color), // added by [MouseJstr] + BATTLE_CONFIG_VAR(max_cloth_color), // added by [MouseJstr] + BATTLE_CONFIG_VAR(castrate_dex_scale), // added by [MouseJstr] + BATTLE_CONFIG_VAR(area_size), // added by [MouseJstr] + BATTLE_CONFIG_VAR(chat_lame_penalty), + BATTLE_CONFIG_VAR(chat_spam_threshold), + BATTLE_CONFIG_VAR(chat_spam_flood), + BATTLE_CONFIG_VAR(chat_spam_ban), + BATTLE_CONFIG_VAR(chat_spam_warn), + BATTLE_CONFIG_VAR(chat_maxline), + BATTLE_CONFIG_VAR(packet_spam_threshold), + BATTLE_CONFIG_VAR(packet_spam_flood), + BATTLE_CONFIG_VAR(packet_spam_kick), + BATTLE_CONFIG_VAR(mask_ip_gms), + BATTLE_CONFIG_VAR(mob_splash_radius), }; - std::string w1, w2; + SString w1; + TString w2; if (!split_key_value(line, &w1, &w2)) continue; if (w1 == "import") { - battle_config_read(w2.c_str()); + battle_config_read(w2); continue; } for (auto datum : data) if (w1 == datum.str) { - *datum.val = config_switch(w2.c_str()); + *datum.val = config_switch(w2); goto continue_outer; } - PRINTF("WARNING: unknown battle conf key: %s\n", w1); + PRINTF("WARNING: unknown battle conf key: %s\n", FString(w1)); continue_outer: ; diff --git a/src/map/battle.hpp b/src/map/battle.hpp index 0f9b2d1..6ed32fd 100644 --- a/src/map/battle.hpp +++ b/src/map/battle.hpp @@ -259,6 +259,6 @@ extern struct Battle_Config int mob_splash_radius; } battle_config; -int battle_config_read(const char *cfgName); +int battle_config_read(ZString cfgName); #endif // BATTLE_HPP diff --git a/src/map/chrif.cpp b/src/map/chrif.cpp index a1e0f55..126235c 100644 --- a/src/map/chrif.cpp +++ b/src/map/chrif.cpp @@ -32,13 +32,15 @@ const int packet_len_table[0x20] = int char_fd; static -char char_ip_str[16]; +IP_String char_ip_str; static int char_ip; static int char_port = 6121; static -char userid[24], passwd[24]; +AccountName userid; +static +AccountPass passwd; static int chrif_state; @@ -47,21 +49,21 @@ int chrif_state; * *------------------------------------------ */ -void chrif_setuserid(const char *id) +void chrif_setuserid(AccountName id) { - strzcpy(userid, id, sizeof(userid)); + userid = id; } /*========================================== * *------------------------------------------ */ -void chrif_setpasswd(const char *pwd) +void chrif_setpasswd(AccountPass pwd) { - strzcpy(passwd, pwd, sizeof(passwd)); + passwd = pwd; } -char *chrif_getpasswd(void) +AccountPass chrif_getpasswd(void) { return passwd; } @@ -70,10 +72,10 @@ char *chrif_getpasswd(void) * *------------------------------------------ */ -void chrif_setip(const char *ip) +void chrif_setip(IP_String ip) { - strzcpy(char_ip_str, ip, sizeof(char_ip_str)); - char_ip = inet_addr(char_ip_str); + char_ip_str = ip; + char_ip = inet_addr(char_ip_str.c_str()); } /*========================================== @@ -180,8 +182,7 @@ int chrif_recvmap(int fd) port = RFIFOW(fd, 8); for (i = 10, j = 0; i < RFIFOW(fd, 2); i += 16, j++) { - char map[16]; - RFIFO_STRING(fd, i, map, 16); + MapName map = RFIFO_STRING<16>(fd, i); map_setipport(map, ip, port); } if (battle_config.etc_log) @@ -194,8 +195,8 @@ int chrif_recvmap(int fd) * マップ鯖間移動のためのデータ準備要求 *------------------------------------------ */ -int chrif_changemapserver(dumb_ptr<map_session_data> sd, char *name, int x, - int y, struct in_addr ip, short port) +int chrif_changemapserver(dumb_ptr<map_session_data> sd, + MapName name, int x, int y, struct in_addr ip, short port) { int i, s_ip; @@ -245,8 +246,7 @@ int chrif_changemapserverack(int fd) pc_authfail(sd->fd); return 0; } - char mapname[16]; - RFIFO_STRING(fd, 18, mapname, 16); + MapName mapname = RFIFO_STRING<16>(fd, 18); uint16_t x = RFIFOW(fd, 34); uint16_t y = RFIFOW(fd, 36); auto ip = in_addr{RFIFOL(fd, 38)}; @@ -274,9 +274,9 @@ int chrif_connectack(int fd) chrif_sendmap(fd); PRINTF("chrif: OnCharIfInit event done. (%d events)\n", - npc_event_doall("OnCharIfInit")); + npc_event_doall(stringish<ScriptLabel>("OnCharIfInit"))); PRINTF("chrif: OnInterIfInit event done. (%d events)\n", - npc_event_doall("OnInterIfInit")); + npc_event_doall(stringish<ScriptLabel>("OnInterIfInit"))); // <Agit> Run Event [AgitInit] // PRINTF("NPC_Event:[OnAgitInit] do (%d) events (Agit Initialize).\n", npc_event_doall("OnAgitInit")); @@ -298,7 +298,7 @@ int chrif_sendmapack(int fd) exit(1); } - RFIFO_STRING(fd, 3, wisp_server_name, 24); + wisp_server_name = stringish<CharName>(RFIFO_STRING<24>(fd, 3)); chrif_state = 2; @@ -385,26 +385,25 @@ int chrif_searchcharid(int char_id) * GMに変化要求 *------------------------------------------ */ -int chrif_changegm(int id, const char *pass, int len) +void chrif_changegm(int id, ZString pass) { if (battle_config.etc_log) PRINTF("chrif_changegm: account: %d, password: '%s'.\n", id, pass); + size_t len = pass.size() + 1; WFIFOW(char_fd, 0) = 0x2b0a; WFIFOW(char_fd, 2) = len + 8; WFIFOL(char_fd, 4) = id; WFIFO_STRING(char_fd, 8, pass, len); WFIFOSET(char_fd, len + 8); - - return 0; } /*========================================== * Change Email *------------------------------------------ */ -int chrif_changeemail(int id, const char *actual_email, - const char *new_email) +void chrif_changeemail(int id, AccountEmail actual_email, + AccountEmail new_email) { if (battle_config.etc_log) PRINTF("chrif_changeemail: account: %d, actual_email: '%s', new_email: '%s'.\n", @@ -415,8 +414,6 @@ int chrif_changeemail(int id, const char *actual_email, WFIFO_STRING(char_fd, 6, actual_email, 40); WFIFO_STRING(char_fd, 46, new_email, 40); WFIFOSET(char_fd, 86); - - return 0; } /*========================================== @@ -430,27 +427,17 @@ int chrif_changeemail(int id, const char *actual_email, * 5: changesex *------------------------------------------ */ -int chrif_char_ask_name(int id, char *character_name, short operation_type, - int year, int month, int day, int hour, int minute, - int second) +void chrif_char_ask_name(int id, CharName character_name, short operation_type, + HumanTimeDiff modif) { WFIFOW(char_fd, 0) = 0x2b0e; WFIFOL(char_fd, 2) = id; // account_id of who ask (for answer) -1 if nobody - WFIFO_STRING(char_fd, 6, character_name, 24); + WFIFO_STRING(char_fd, 6, character_name.to__actual(), 24); WFIFOW(char_fd, 30) = operation_type; // type of operation if (operation_type == 2) - { - WFIFOW(char_fd, 32) = year; - WFIFOW(char_fd, 34) = month; - WFIFOW(char_fd, 36) = day; - WFIFOW(char_fd, 38) = hour; - WFIFOW(char_fd, 40) = minute; - WFIFOW(char_fd, 42) = second; - } + WFIFO_STRUCT(char_fd, 32, modif); PRINTF("chrif : sended 0x2b0e\n"); WFIFOSET(char_fd, 44); - - return 0; } /*========================================== @@ -472,17 +459,13 @@ int chrif_char_ask_name(int id, char *character_name, short operation_type, static int chrif_char_ask_name_answer(int fd) { - int acc; - dumb_ptr<map_session_data> sd; - char player_name[24]; + int acc = RFIFOL(fd, 2); // account_id of who has asked (-1 if nobody) + CharName player_name = stringish<CharName>(RFIFO_STRING<24>(fd, 6)); - acc = RFIFOL(fd, 2); // account_id of who has asked (-1 if nobody) - RFIFO_STRING(fd, 6, player_name, 24); - - sd = map_id2sd(acc); + dumb_ptr<map_session_data> sd = map_id2sd(acc); if (acc >= 0 && sd != NULL) { - std::string output; + FString output; if (RFIFOW(fd, 32) == 1) // player not found output = STRPRINTF("The player '%s' doesn't exist.", player_name); @@ -597,7 +580,7 @@ int chrif_char_ask_name_answer(int fd) break; } } - if (!output.empty()) + if (output) clif_displaymessage(sd->fd, output); } else @@ -611,7 +594,7 @@ int chrif_char_ask_name_answer(int fd) *------------------------------------------ */ static -int chrif_changedgm(int fd) +void chrif_changedgm(int fd) { int acc, level; dumb_ptr<map_session_data> sd = NULL; @@ -631,8 +614,6 @@ int chrif_changedgm(int fd) else clif_displaymessage(sd->fd, "Failure of GM modification."); } - - return 0; } /*========================================== @@ -640,7 +621,7 @@ int chrif_changedgm(int fd) *------------------------------------------ */ static -int chrif_changedsex(int fd) +void chrif_changedsex(int fd) { int acc, sex, i; dumb_ptr<map_session_data> sd; @@ -678,8 +659,6 @@ int chrif_changedsex(int fd) PRINTF("chrif_changedsex failed.\n"); } } - - return 0; } /*========================================== @@ -726,11 +705,10 @@ int chrif_accountreg2(int fd) for (p = 8, j = 0; p < RFIFOW(fd, 2) && j < ACCOUNT_REG2_NUM; p += 36, j++) { - RFIFO_STRING(fd, p, sd->status.account_reg2[j].str, 32); + sd->status.account_reg2[j].str = stringish<VarName>(RFIFO_STRING<32>(fd, p)); sd->status.account_reg2[j].value = RFIFOL(fd, p + 32); } sd->status.account_reg2_num = j; -// PRINTF("chrif: accountreg2\n"); return 0; } @@ -1133,8 +1111,7 @@ void chrif_parse(int fd) case 0x2b09: { int charid = RFIFOL(fd, 2); - char name[24]; - RFIFO_STRING(fd, 6, name, 24); + CharName name = stringish<CharName>(RFIFO_STRING<24>(fd, 6)); map_addchariddb(charid, name); } break; diff --git a/src/map/chrif.hpp b/src/map/chrif.hpp index 6dca70c..97760c3 100644 --- a/src/map/chrif.hpp +++ b/src/map/chrif.hpp @@ -2,14 +2,15 @@ #define CHRIF_HPP #include "../common/dumb_ptr.hpp" +#include "../common/human_time_diff.hpp" #include "map.hpp" -void chrif_setuserid(const char *); -void chrif_setpasswd(const char *); -char *chrif_getpasswd(void); +void chrif_setuserid(AccountName); +void chrif_setpasswd(AccountPass); +AccountPass chrif_getpasswd(void); -void chrif_setip(const char *); +void chrif_setip(IP_String); void chrif_setport(int); int chrif_isconnect(void); @@ -19,15 +20,14 @@ int chrif_save(dumb_ptr<map_session_data>); int chrif_charselectreq(dumb_ptr<map_session_data>); int chrif_changemapserver(dumb_ptr<map_session_data> sd, - char *name, int x, int y, + MapName name, int x, int y, struct in_addr ip, short port); int chrif_searchcharid(int char_id); -int chrif_changegm(int id, const char *pass, int len); -int chrif_changeemail(int id, const char *actual_email, - const char *new_email); -int chrif_char_ask_name(int id, char *character_name, short operation_type, - int year, int month, int day, int hour, int minute, int second); +void chrif_changegm(int id, ZString pass); +void chrif_changeemail(int id, AccountEmail actual_email, AccountEmail new_email); +void chrif_char_ask_name(int id, CharName character_name, short operation_type, + HumanTimeDiff modif); int chrif_saveaccountreg2(dumb_ptr<map_session_data> sd); int chrif_reloadGMdb(void); int chrif_send_divorce(int char_id); diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 9f06bfc..494e09f 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -107,7 +107,7 @@ void WFIFOPOS2(int fd, size_t pos, uint16_t x0, uint16_t y0, uint16_t x1, uint16 } static -char map_ip_str[16]; +IP_String map_ip_str; static struct in_addr map_ip; static @@ -121,10 +121,10 @@ int clif_changelook_towards(dumb_ptr<block_list> bl, LOOK type, int val, * map鯖のip設定 *------------------------------------------ */ -void clif_setip(const char *ip) +void clif_setip(IP_String ip) { - strzcpy(map_ip_str, ip, 16); - map_ip.s_addr = inet_addr(map_ip_str); + map_ip_str = ip; + map_ip.s_addr = inet_addr(map_ip_str.c_str()); } /*========================================== @@ -212,7 +212,7 @@ enum class ChatType }; static -std::string clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type); +FString clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type); /*========================================== * clif_sendでSendWho::AREA*指定時用 @@ -1096,7 +1096,7 @@ void clif_setwaitclose(int fd) * *------------------------------------------ */ -void clif_changemap(dumb_ptr<map_session_data> sd, const char *mapname, int x, int y) +void clif_changemap(dumb_ptr<map_session_data> sd, MapName mapname, int x, int y) { nullpo_retv(sd); @@ -1113,8 +1113,8 @@ void clif_changemap(dumb_ptr<map_session_data> sd, const char *mapname, int x, i * *------------------------------------------ */ -void clif_changemapserver(dumb_ptr<map_session_data> sd, const char *mapname, int x, - int y, struct in_addr ip, int port) +void clif_changemapserver(dumb_ptr<map_session_data> sd, + MapName mapname, int x, int y, struct in_addr ip, int port) { nullpo_retv(sd); @@ -1228,125 +1228,103 @@ int clif_selllist(dumb_ptr<map_session_data> sd) * *------------------------------------------ */ -int clif_scriptmes(dumb_ptr<map_session_data> sd, int npcid, const char *mes) +void clif_scriptmes(dumb_ptr<map_session_data> sd, int npcid, XString mes) { - nullpo_ret(sd); + nullpo_retv(sd); int fd = sd->fd; - size_t len = strlen(mes) + 1; + size_t len = mes.size() + 1; WFIFOW(fd, 0) = 0xb4; WFIFOW(fd, 2) = len + 8; WFIFOL(fd, 4) = npcid; WFIFO_STRING(fd, 8, mes, len); WFIFOSET(fd, WFIFOW(fd, 2)); - - return 0; } /*========================================== * *------------------------------------------ */ -int clif_scriptnext(dumb_ptr<map_session_data> sd, int npcid) +void clif_scriptnext(dumb_ptr<map_session_data> sd, int npcid) { - int fd; - - nullpo_ret(sd); + nullpo_retv(sd); - fd = sd->fd; + int fd = sd->fd; WFIFOW(fd, 0) = 0xb5; WFIFOL(fd, 2) = npcid; WFIFOSET(fd, clif_parse_func_table[0xb5].len); - - return 0; } /*========================================== * *------------------------------------------ */ -int clif_scriptclose(dumb_ptr<map_session_data> sd, int npcid) +void clif_scriptclose(dumb_ptr<map_session_data> sd, int npcid) { - int fd; - - nullpo_ret(sd); + nullpo_retv(sd); - fd = sd->fd; + int fd = sd->fd; WFIFOW(fd, 0) = 0xb6; WFIFOL(fd, 2) = npcid; WFIFOSET(fd, clif_parse_func_table[0xb6].len); - - return 0; } /*========================================== * *------------------------------------------ */ -int clif_scriptmenu(dumb_ptr<map_session_data> sd, int npcid, const char *mes) +void clif_scriptmenu(dumb_ptr<map_session_data> sd, int npcid, XString mes) { - nullpo_ret(sd); + nullpo_retv(sd); int fd = sd->fd; - size_t len = strlen(mes) + 1; + size_t len = mes.size() + 1; WFIFOW(fd, 0) = 0xb7; WFIFOW(fd, 2) = len + 8; WFIFOL(fd, 4) = npcid; WFIFO_STRING(fd, 8, mes, len); WFIFOSET(fd, WFIFOW(fd, 2)); - - return 0; } /*========================================== * *------------------------------------------ */ -int clif_scriptinput(dumb_ptr<map_session_data> sd, int npcid) +void clif_scriptinput(dumb_ptr<map_session_data> sd, int npcid) { - int fd; - - nullpo_ret(sd); + nullpo_retv(sd); - fd = sd->fd; + int fd = sd->fd; WFIFOW(fd, 0) = 0x142; WFIFOL(fd, 2) = npcid; WFIFOSET(fd, clif_parse_func_table[0x142].len); - - return 0; } /*========================================== * *------------------------------------------ */ -int clif_scriptinputstr(dumb_ptr<map_session_data> sd, int npcid) +void clif_scriptinputstr(dumb_ptr<map_session_data> sd, int npcid) { - int fd; - - nullpo_ret(sd); + nullpo_retv(sd); - fd = sd->fd; + int fd = sd->fd; WFIFOW(fd, 0) = 0x1d4; WFIFOL(fd, 2) = npcid; WFIFOSET(fd, clif_parse_func_table[0x1d4].len); - - return 0; } /*========================================== * *------------------------------------------ */ -int clif_viewpoint(dumb_ptr<map_session_data> sd, int npc_id, int type, int x, - int y, int id, int color) +void clif_viewpoint(dumb_ptr<map_session_data> sd, int npc_id, int type, + int x, int y, int id, int color) { - int fd; - - nullpo_ret(sd); + nullpo_retv(sd); - fd = sd->fd; + int fd = sd->fd; WFIFOW(fd, 0) = 0x144; WFIFOL(fd, 2) = npc_id; WFIFOL(fd, 6) = type; @@ -1355,8 +1333,6 @@ int clif_viewpoint(dumb_ptr<map_session_data> sd, int npc_id, int type, int x, WFIFOB(fd, 18) = id; WFIFOL(fd, 19) = color; WFIFOSET(fd, clif_parse_func_table[0x144].len); - - return 0; } /*========================================== @@ -1432,29 +1408,25 @@ int clif_additem(dumb_ptr<map_session_data> sd, int n, int amount, PickupFail fa * *------------------------------------------ */ -int clif_delitem(dumb_ptr<map_session_data> sd, int n, int amount) +void clif_delitem(dumb_ptr<map_session_data> sd, int n, int amount) { - int fd; - - nullpo_ret(sd); + nullpo_retv(sd); - fd = sd->fd; + int fd = sd->fd; WFIFOW(fd, 0) = 0xaf; WFIFOW(fd, 2) = n + 2; WFIFOW(fd, 4) = amount; WFIFOSET(fd, clif_parse_func_table[0xaf].len); - - return 0; } /*========================================== * *------------------------------------------ */ -int clif_itemlist(dumb_ptr<map_session_data> sd) +void clif_itemlist(dumb_ptr<map_session_data> sd) { - nullpo_ret(sd); + nullpo_retv(sd); int n = 0; int arrow = -1; @@ -1492,16 +1464,15 @@ int clif_itemlist(dumb_ptr<map_session_data> sd) } if (arrow >= 0) clif_arrowequip(sd, arrow); - return 0; } /*========================================== * *------------------------------------------ */ -int clif_equiplist(dumb_ptr<map_session_data> sd) +void clif_equiplist(dumb_ptr<map_session_data> sd) { - nullpo_ret(sd); + nullpo_retv(sd); int fd = sd->fd; WFIFOW(fd, 0) = 0xa4; @@ -1549,7 +1520,6 @@ int clif_equiplist(dumb_ptr<map_session_data> sd) WFIFOW(fd, 2) = 4 + n * 20; WFIFOSET(fd, WFIFOW(fd, 2)); } - return 0; } /*========================================== @@ -2153,45 +2123,39 @@ int clif_useitemack(dumb_ptr<map_session_data> sd, int index, int amount, * 取り引き要請受け *------------------------------------------ */ -int clif_traderequest(dumb_ptr<map_session_data> sd, const char *name) +void clif_traderequest(dumb_ptr<map_session_data> sd, CharName name) { - nullpo_ret(sd); + nullpo_retv(sd); int fd = sd->fd; WFIFOW(fd, 0) = 0xe5; - WFIFO_STRING(fd, 2, name, 24); + WFIFO_STRING(fd, 2, name.to__actual(), 24); WFIFOSET(fd, clif_parse_func_table[0xe5].len); - - return 0; } /*========================================== * 取り引き要求応答 *------------------------------------------ */ -int clif_tradestart(dumb_ptr<map_session_data> sd, int type) +void clif_tradestart(dumb_ptr<map_session_data> sd, int type) { - int fd; - - nullpo_ret(sd); + nullpo_retv(sd); - fd = sd->fd; + int fd = sd->fd; WFIFOW(fd, 0) = 0xe7; WFIFOB(fd, 2) = type; WFIFOSET(fd, clif_parse_func_table[0xe7].len); - - return 0; } /*========================================== * 相手方からのアイテム追加 *------------------------------------------ */ -int clif_tradeadditem(dumb_ptr<map_session_data> sd, - dumb_ptr<map_session_data> tsd, int index, int amount) +void clif_tradeadditem(dumb_ptr<map_session_data> sd, + dumb_ptr<map_session_data> tsd, int index, int amount) { - nullpo_ret(sd); - nullpo_ret(tsd); + nullpo_retv(sd); + nullpo_retv(tsd); int fd = tsd->fd; WFIFOW(fd, 0) = 0xe9; @@ -2235,8 +2199,6 @@ int clif_tradeadditem(dumb_ptr<map_session_data> sd, } } WFIFOSET(fd, clif_parse_func_table[0xe9].len); - - return 0; } /*========================================== @@ -2967,7 +2929,7 @@ int clif_status_change(dumb_ptr<block_list> bl, StatusChange type, int flag) * Send message (modified by [Yor]) *------------------------------------------ */ -void clif_displaymessage(int fd, ZString mes) +void clif_displaymessage(int fd, XString mes) { if (mes) { @@ -2975,7 +2937,7 @@ void clif_displaymessage(int fd, ZString mes) WFIFOW(fd, 0) = 0x8e; size_t str_len = mes.size() + 1; // NUL (might not be NUL yet) WFIFOW(fd, 2) = 4 + str_len; - WFIFO_STRING(fd, 4, mes.c_str(), str_len); + WFIFO_STRING(fd, 4, mes, str_len); WFIFOSET(fd, 4 + str_len); } } @@ -2984,14 +2946,14 @@ void clif_displaymessage(int fd, ZString mes) * 天の声を送信する *------------------------------------------ */ -void clif_GMmessage(dumb_ptr<block_list> bl, ZString mes, int flag) +void clif_GMmessage(dumb_ptr<block_list> bl, XString mes, int flag) { size_t str_len = mes.size() + 1; unsigned char buf[str_len + 4]; WBUFW(buf, 0) = 0x9a; WBUFW(buf, 2) = str_len + 4; - WBUF_STRING(buf, 4, mes.c_str(), str_len); + WBUF_STRING(buf, 4, mes, str_len); flag &= 0x07; clif_send(buf, WBUFW(buf, 2), bl, (flag == 1) ? SendWho::ALL_SAMEMAP : @@ -3022,12 +2984,12 @@ void clif_resurrection(dumb_ptr<block_list> bl, int type) * Wisp/page is transmitted to the destination player *------------------------------------------ */ -void clif_wis_message(int fd, const char *nick, const char *mes) // R 0097 <len>.w <nick>.24B <message>.?B +void clif_wis_message(int fd, CharName nick, XString mes) // R 0097 <len>.w <nick>.24B <message>.?B { - size_t mes_len = strlen(mes) + 1; + size_t mes_len = mes.size() + 1; WFIFOW(fd, 0) = 0x97; WFIFOW(fd, 2) = mes_len + 24 + 4; - WFIFO_STRING(fd, 4, nick, 24); + WFIFO_STRING(fd, 4, nick.to__actual(), 24); WFIFO_STRING(fd, 28, mes, mes_len); WFIFOSET(fd, WFIFOW(fd, 2)); } @@ -3090,7 +3052,7 @@ int clif_party_info(struct party *p, int fd) if (sd == NULL) sd = dumb_ptr<map_session_data>(m->sd); WBUFL(buf, 28 + c * 46) = m->account_id; - WBUF_STRING(buf, 28 + c * 46 + 4, m->name, 24); + WBUF_STRING(buf, 28 + c * 46 + 4, m->name.to__actual(), 24); WBUF_STRING(buf, 28 + c * 46 + 28, m->map, 16); WBUFB(buf, 28 + c * 46 + 44) = (m->leader) ? 0 : 1; WBUFB(buf, 28 + c * 46 + 45) = (m->online) ? 0 : 1; @@ -3153,18 +3115,15 @@ void clif_party_invite(dumb_ptr<map_session_data> sd, * 4 The character is in the same party. *------------------------------------------ */ -int clif_party_inviteack(dumb_ptr<map_session_data> sd, const char *nick, int flag) +void clif_party_inviteack(dumb_ptr<map_session_data> sd, CharName nick, int flag) { - int fd; - - nullpo_ret(sd); + nullpo_retv(sd); - fd = sd->fd; + int fd = sd->fd; WFIFOW(fd, 0) = 0xfd; - WFIFO_STRING(fd, 2, nick, 24); + WFIFO_STRING(fd, 2, nick.to__actual(), 24); WFIFOB(fd, 26) = flag; WFIFOSET(fd, clif_parse_func_table[0xfd].len); - return 0; } /*========================================== @@ -3207,17 +3166,17 @@ void clif_party_option(struct party *p, dumb_ptr<map_session_data> sd, int flag) * パーティ脱退(脱退前に呼ぶこと) *------------------------------------------ */ -int clif_party_leaved(struct party *p, dumb_ptr<map_session_data> sd, - int account_id, const char *name, int flag) +void clif_party_leaved(struct party *p, dumb_ptr<map_session_data> sd, + int account_id, CharName name, int flag) { unsigned char buf[64]; int i; - nullpo_ret(p); + nullpo_retv(p); WBUFW(buf, 0) = 0x105; WBUFL(buf, 2) = account_id; - WBUF_STRING(buf, 6, name, 24); + WBUF_STRING(buf, 6, name.to__actual(), 24); WBUFB(buf, 30) = flag & 0x0f; if ((flag & 0xf0) == 0) @@ -3237,14 +3196,13 @@ int clif_party_leaved(struct party *p, dumb_ptr<map_session_data> sd, WFIFO_BUF_CLONE(sd->fd, buf, clif_parse_func_table[0x105].len); WFIFOSET(sd->fd, clif_parse_func_table[0x105].len); } - return 0; } /*========================================== * パーティメッセージ送信 *------------------------------------------ */ -void clif_party_message(struct party *p, int account_id, const char *mes) +void clif_party_message(struct party *p, int account_id, XString mes) { // always set, but clang is not smart enough dumb_ptr<map_session_data> sd = nullptr; @@ -3260,7 +3218,7 @@ void clif_party_message(struct party *p, int account_id, const char *mes) } if (sd != NULL) { - size_t len = strlen(mes) + 1; + size_t len = mes.size() + 1; unsigned char buf[len + 8]; WBUFW(buf, 0) = 0x109; WBUFW(buf, 2) = len + 8; @@ -3748,12 +3706,12 @@ void clif_parse_GetCharNameRequest(int fd, dumb_ptr<map_session_data> sd) if (ssd->state.shroud_active) WFIFO_STRING(fd, 6, "", 24); else - WFIFO_STRING(fd, 6, ssd->status.name, 24); + WFIFO_STRING(fd, 6, ssd->status.name.to__actual(), 24); WFIFOSET(fd, clif_parse_func_table[0x95].len); struct party *p = NULL; - const char *party_name = ""; + PartyName party_name; int send = 0; @@ -3782,7 +3740,7 @@ void clif_parse_GetCharNameRequest(int fd, dumb_ptr<map_session_data> sd) // Mask the IP using the char-server password if (battle_config.mask_ip_gms) - ip = MD5_ip(chrif_getpasswd(), ssd->ip); + ip = MD5_ip(ssd->ip); WFIFOL(fd, 2) = account_id; WFIFOL(fd, 6) = ip.s_addr; @@ -3793,18 +3751,10 @@ void clif_parse_GetCharNameRequest(int fd, dumb_ptr<map_session_data> sd) break; case BL::NPC: { - char name[24]; - strzcpy(name, bl->as_npc()->name, 24); + NpcName name = bl->as_npc()->name; // [fate] elim hashed out/invisible names for the client - *strchrnul(name, '#') = '\0'; - for (char& c : name) - { - // [fate] Elim preceding underscores for (hackish) name position fine-tuning - if (c != '_') - break; - c = ' '; - } - WFIFO_STRING(fd, 6, name, 24); + auto it = std::find(name.begin(), name.end(), '#'); + WFIFO_STRING(fd, 6, name.oislice_h(it), 24); WFIFOSET(fd, clif_parse_func_table[0x95].len); } break; @@ -3838,20 +3788,20 @@ void clif_parse_GlobalMessage(int fd, dumb_ptr<map_session_data> sd) { nullpo_retv(sd); - std::string mbuf = clif_validate_chat(sd, ChatType::Global); - if (mbuf.empty()) + FString mbuf = clif_validate_chat(sd, ChatType::Global); + if (!mbuf) { clif_displaymessage(fd, "Your message could not be sent."); return; } - if (is_atcommand(fd, sd, mbuf.c_str(), 0)) + if (is_atcommand(fd, sd, mbuf, 0)) return; if (!magic_message(sd, mbuf)) { /* Don't send chat that results in an automatic ban. */ - if (tmw_CheckChatSpam(sd, mbuf.c_str())) + if (tmw_CheckChatSpam(sd, mbuf)) { clif_displaymessage(fd, "Your message could not be sent."); return; @@ -3863,7 +3813,7 @@ void clif_parse_GlobalMessage(int fd, dumb_ptr<map_session_data> sd) WBUFW(sendbuf, 0) = 0x8d; WBUFW(sendbuf, 2) = mbuf_size + 8; /* Header(2) + length(2) + ID(4). */ WBUFL(sendbuf, 4) = sd->bl_id; - WBUF_STRING(sendbuf, 8, mbuf.c_str(), mbuf_size); + WBUF_STRING(sendbuf, 8, mbuf, mbuf_size); clif_send(sendbuf, mbuf_size + 8, sd, SendWho::AREA_CHAT_WOC); } @@ -3875,9 +3825,9 @@ void clif_parse_GlobalMessage(int fd, dumb_ptr<map_session_data> sd) WFIFOSET(fd, len); } -void clif_message(dumb_ptr<block_list> bl, const char *msg) +void clif_message(dumb_ptr<block_list> bl, XString msg) { - size_t msg_len = strlen(msg) + 1; + size_t msg_len = msg.size() + 1; uint8_t buf[512]; if (msg_len + 16 > 512) @@ -4079,20 +4029,20 @@ void clif_parse_Wis(int fd, dumb_ptr<map_session_data> sd) nullpo_retv(sd); - std::string mbuf = clif_validate_chat(sd, ChatType::Whisper); - if (mbuf.empty()) + FString mbuf = clif_validate_chat(sd, ChatType::Whisper); + if (!mbuf) { clif_displaymessage(fd, "Your message could not be sent."); return; } - if (is_atcommand(fd, sd, mbuf.c_str(), 0)) + if (is_atcommand(fd, sd, mbuf, 0)) { return; } /* Don't send chat that results in an automatic ban. */ - if (tmw_CheckChatSpam(sd, mbuf.c_str())) + if (tmw_CheckChatSpam(sd, mbuf)) { clif_displaymessage(fd, "Your message could not be sent."); return; @@ -4104,17 +4054,16 @@ void clif_parse_Wis(int fd, dumb_ptr<map_session_data> sd) * conflict (for instance, "Test" versus "test"), the char-server must * settle the discrepancy. */ - char tname[24]; - RFIFO_STRING(fd, 4, tname, 24); + CharName tname = stringish<CharName>(RFIFO_STRING<24>(fd, 4)); if (!(dstsd = map_nick2sd(tname)) - || strcmp(dstsd->status.name, tname) != 0) - intif_wis_message(sd, tname, mbuf.c_str()); + || dstsd->status.name != tname) + intif_wis_message(sd, tname, mbuf); else { /* Refuse messages addressed to self. */ if (dstsd->fd == fd) { - const char *mes = "You cannot page yourself."; + ZString mes = "You cannot page yourself."; clif_wis_message(fd, wisp_server_name, mes); } else @@ -4122,7 +4071,7 @@ void clif_parse_Wis(int fd, dumb_ptr<map_session_data> sd) { /* The player is not being ignored. */ { - clif_wis_message(dstsd->fd, sd->status.name, mbuf.c_str()); + clif_wis_message(dstsd->fd, sd->status.name, mbuf); /* The whisper was sent successfully. */ clif_wis_end(fd, 0); } @@ -4519,9 +4468,7 @@ void clif_parse_NpcStringInput(int fd, dumb_ptr<map_session_data> sd) */ if (len < 0) return; - char buf[len]; - RFIFO_STRING(fd, 8, buf, len); - sd->npc_str = buf; + sd->npc_str = RFIFO_STRING(fd, 8, len); map_scriptcont(sd, RFIFOL(fd, 4)); } @@ -4606,8 +4553,7 @@ void clif_parse_CreateParty(int fd, dumb_ptr<map_session_data> sd) if (battle_config.basic_skill_check == 0 || pc_checkskill(sd, SkillID::NV_PARTY) >= 2) { - char name[24]; - RFIFO_STRING(fd, 2, name, 24); + PartyName name = stringish<PartyName>(RFIFO_STRING<24>(fd, 2)); party_create(sd, name); } else @@ -4667,9 +4613,8 @@ static void clif_parse_RemovePartyMember(int fd, dumb_ptr<map_session_data> sd) { int account_id = RFIFOL(fd, 2); - char name[24]; - RFIFO_STRING(fd, 6, name, 24); - party_removemember(sd, account_id, name); + // unused RFIFO_STRING<24>(fd, 6); + party_removemember(sd, account_id); } /*========================================== @@ -4695,24 +4640,24 @@ void clif_parse_PartyMessage(int fd, dumb_ptr<map_session_data> sd) { nullpo_retv(sd); - std::string mbuf = clif_validate_chat(sd, ChatType::Party); - if (mbuf.empty()) + FString mbuf = clif_validate_chat(sd, ChatType::Party); + if (!mbuf) { clif_displaymessage(fd, "Your message could not be sent."); return; } - if (is_atcommand(fd, sd, mbuf.c_str(), 0)) + if (is_atcommand(fd, sd, mbuf, 0)) return; /* Don't send chat that results in an automatic ban. */ - if (tmw_CheckChatSpam(sd, mbuf.c_str())) + if (tmw_CheckChatSpam(sd, mbuf)) { clif_displaymessage(fd, "Your message could not be sent."); return; } - party_send_message(sd, mbuf.c_str()); + party_send_message(sd, mbuf); } func_table clif_parse_func_table[0x0220] = @@ -5361,19 +5306,19 @@ void WARN_MALFORMED_MSG(dumb_ptr<map_session_data> sd, const char *msg) * @return a dynamically allocated copy of the message, or empty string upon failure */ static -std::string clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type) +FString clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type) { - nullpo_retr(std::string(), sd); + nullpo_retr(FString(), sd); /* * Don't send chat in the period between the ban and the connection's * closure. */ if (sd->auto_ban_info.in_progress) - return std::string(); + return FString(); int fd = sd->fd; size_t msg_len = RFIFOW(fd, 2) - 4; - size_t name_len = strlen(sd->status.name); + size_t name_len = sd->status.name.to__actual().size(); /* * At least one character is required in all instances. * Notes for length checks: @@ -5393,14 +5338,14 @@ std::string clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type) if (!msg_len) { WARN_MALFORMED_MSG(sd, "no message sent"); - return std::string(); + return FString(); } /* The client sent (or claims to have sent) an empty message. */ if (msg_len == min_len) { WARN_MALFORMED_MSG(sd, "empty message"); - return std::string(); + return FString(); } /* The protocol specifies that the target must be 24 bytes long. */ @@ -5409,7 +5354,7 @@ std::string clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type) /* Disallow malformed messages. */ clif_setwaitclose(fd); WARN_MALFORMED_MSG(sd, "illegal target name"); - return std::string(); + return FString(); } size_t pstart = 4; @@ -5419,9 +5364,7 @@ std::string clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type) pstart += 24; buf_len -= 24; } - char pbuf[buf_len + 1]; - // I had to change strzcpy for this :( - RFIFO_STRING(fd, pstart, pbuf, buf_len + 1); + FString pbuf = RFIFO_STRING(fd, pstart, buf_len); /* * The client attempted to exceed the maximum message length. @@ -5433,22 +5376,22 @@ std::string clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type) if (buf_len >= battle_config.chat_maxline) { WARN_MALFORMED_MSG(sd, "exceeded maximum message length"); - return std::string(); + return FString(); } if (type == ChatType::Global) { - XString p = ZString(ZString::really_construct_from_a_pointer, pbuf); - if (!(p.startswith(const_(sd->status.name)) && p.xslice_t(name_len).startswith(" : "))) + XString p = pbuf; + if (!(p.startswith(sd->status.name.to__actual()) && p.xslice_t(name_len).startswith(" : "))) { /* Disallow malformed/spoofed messages. */ clif_setwaitclose(fd); WARN_MALFORMED_MSG(sd, "spoofed name/invalid format"); - return std::string(); + return FString(); } /* Step beyond the separator. */ XString xs = p.xslice_t(name_len + 3); - return std::string(xs.begin(), xs.end()); + return xs; } return pbuf; } @@ -5483,10 +5426,8 @@ void clif_parse(int fd) { pc_logout(sd); clif_quitsave(fd, sd); - if (sd->status.name != NULL) - PRINTF("Player [%s] has logged off your server.\n", sd->status.name); // Player logout display [Valaris] - else - PRINTF("Player with account [%d] has logged off your server.\n", sd->bl_id); // Player logout display [Yor] + + PRINTF("Player [%s] has logged off your server.\n", sd->status.name); // Player logout display [Valaris] } else if (sd) { // not authentified! (refused by char-server or disconnect before to be authentified) @@ -5587,17 +5528,14 @@ void clif_parse(int fd) } if (sd && sd->state.auth) { - if (sd->status.name != NULL) - PRINTF("\nAccount ID %d, character ID %d, player name %s.\n", - sd->status.account_id, sd->status.char_id, - sd->status.name); - else - PRINTF("\nAccount ID %d.\n", sd->bl_id); + PRINTF("\nAccount ID %d, character ID %d, player name %s.\n", + sd->status.account_id, sd->status.char_id, + sd->status.name); } else if (sd) // not authentified! (refused by char-server or disconnect before to be authentified) PRINTF("\nAccount ID %d.\n", sd->bl_id); - if ((fp = fopen_(packet_txt, "a")) == NULL) + if ((fp = fopen(packet_txt, "a")) == NULL) { PRINTF("clif.c: cant write [%s] !!! data is lost !!!\n", packet_txt); @@ -5609,16 +5547,11 @@ void clif_parse(int fd) stamp_time(now); if (sd && sd->state.auth) { - if (sd->status.name != NULL) - FPRINTF(fp, - "%s\nPlayer with account ID %d (character ID %d, player name %s) sent wrong packet:\n", - now, - sd->status.account_id, - sd->status.char_id, sd->status.name); - else - FPRINTF(fp, - "%s\nPlayer with account ID %d sent wrong packet:\n", - now, sd->bl_id); + FPRINTF(fp, + "%s\nPlayer with account ID %d (character ID %d, player name %s) sent wrong packet:\n", + now, + sd->status.account_id, + sd->status.char_id, sd->status.name); } else if (sd) // not authentified! (refused by char-server or disconnect before to be authentified) FPRINTF(fp, @@ -5634,7 +5567,7 @@ void clif_parse(int fd) FPRINTF(fp, "%02X ", RFIFOB(fd, i)); } FPRINTF(fp, "\n\n"); - fclose_(fp); + fclose(fp); } } #endif diff --git a/src/map/clif.hpp b/src/map/clif.hpp index b9e2233..20f9912 100644 --- a/src/map/clif.hpp +++ b/src/map/clif.hpp @@ -14,7 +14,7 @@ #include "pc.t.hpp" #include "skill.t.hpp" -void clif_setip(const char *); +void clif_setip(IP_String); void clif_setport(int); struct in_addr clif_getip(void); @@ -38,23 +38,23 @@ int clif_spawnmob(dumb_ptr<mob_data>); // area int clif_walkok(dumb_ptr<map_session_data>); // self int clif_movechar(dumb_ptr<map_session_data>); // area int clif_movemob(dumb_ptr<mob_data>); //area -void clif_changemap(dumb_ptr<map_session_data>, const char *, int, int); //self -void clif_changemapserver(dumb_ptr<map_session_data>, const char *, int, int, struct in_addr, int); //self +void clif_changemap(dumb_ptr<map_session_data>, MapName, int, int); //self +void clif_changemapserver(dumb_ptr<map_session_data>, MapName, int, int, struct in_addr, int); //self void clif_fixpos(dumb_ptr<block_list>); // area int clif_fixmobpos(dumb_ptr<mob_data> md); int clif_fixpcpos(dumb_ptr<map_session_data> sd); int clif_npcbuysell(dumb_ptr<map_session_data>, int); //self int clif_buylist(dumb_ptr<map_session_data>, dumb_ptr<npc_data_shop>); //self int clif_selllist(dumb_ptr<map_session_data>); //self -int clif_scriptmes(dumb_ptr<map_session_data>, int, const char *); //self -int clif_scriptnext(dumb_ptr<map_session_data>, int); //self -int clif_scriptclose(dumb_ptr<map_session_data>, int); //self -int clif_scriptmenu(dumb_ptr<map_session_data>, int, const char *); //self -int clif_scriptinput(dumb_ptr<map_session_data>, int); //self -int clif_scriptinputstr(dumb_ptr<map_session_data> sd, int npcid); // self -int clif_viewpoint(dumb_ptr<map_session_data>, int, int, int, int, int, int); //self +void clif_scriptmes(dumb_ptr<map_session_data>, int, XString); //self +void clif_scriptnext(dumb_ptr<map_session_data>, int); //self +void clif_scriptclose(dumb_ptr<map_session_data>, int); //self +void clif_scriptmenu(dumb_ptr<map_session_data>, int, XString); //self +void clif_scriptinput(dumb_ptr<map_session_data>, int); //self +void clif_scriptinputstr(dumb_ptr<map_session_data> sd, int npcid); // self +void clif_viewpoint(dumb_ptr<map_session_data>, int, int, int, int, int, int); //self int clif_additem(dumb_ptr<map_session_data>, int, int, PickupFail); //self -int clif_delitem(dumb_ptr<map_session_data>, int, int); //self +void clif_delitem(dumb_ptr<map_session_data>, int, int); //self int clif_updatestatus(dumb_ptr<map_session_data>, SP); //self int clif_damage(dumb_ptr<block_list>, dumb_ptr<block_list>, tick_t, interval_t, interval_t, @@ -79,9 +79,9 @@ void clif_emotion(dumb_ptr<block_list> bl, int type); void clif_sitting(int fd, dumb_ptr<map_session_data> sd); // trade -int clif_traderequest(dumb_ptr<map_session_data> sd, const char *name); -int clif_tradestart(dumb_ptr<map_session_data> sd, int type); -int clif_tradeadditem(dumb_ptr<map_session_data> sd, +void clif_traderequest(dumb_ptr<map_session_data> sd, CharName name); +void clif_tradestart(dumb_ptr<map_session_data> sd, int type); +void clif_tradeadditem(dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> tsd, int index, int amount); int clif_tradeitemok(dumb_ptr<map_session_data> sd, int index, int amount, int fail); @@ -122,11 +122,11 @@ int clif_skill_damage(dumb_ptr<block_list> src, dumb_ptr<block_list> dst, int clif_status_change(dumb_ptr<block_list> bl, StatusChange type, int flag); -void clif_wis_message(int fd, const char *nick, const char *mes); +void clif_wis_message(int fd, CharName nick, XString mes); void clif_wis_end(int fd, int flag); -int clif_itemlist(dumb_ptr<map_session_data> sd); -int clif_equiplist(dumb_ptr<map_session_data> sd); +void clif_itemlist(dumb_ptr<map_session_data> sd); +void clif_equiplist(dumb_ptr<map_session_data> sd); int clif_mvp_effect(dumb_ptr<map_session_data> sd); @@ -137,22 +137,22 @@ int clif_party_created(dumb_ptr<map_session_data> sd, int flag); int clif_party_info(struct party *p, int fd); void clif_party_invite(dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> tsd); -int clif_party_inviteack(dumb_ptr<map_session_data> sd, const char *nick, int flag); +void clif_party_inviteack(dumb_ptr<map_session_data> sd, CharName nick, int flag); void clif_party_option(struct party *p, dumb_ptr<map_session_data> sd, int flag); -int clif_party_leaved(struct party *p, dumb_ptr<map_session_data> sd, - int account_id, const char *name, int flag); -void clif_party_message(struct party *p, int account_id, const char *mes); +void clif_party_leaved(struct party *p, dumb_ptr<map_session_data> sd, + int account_id, CharName name, int flag); +void clif_party_message(struct party *p, int account_id, XString mes); int clif_party_xy(struct party *p, dumb_ptr<map_session_data> sd); int clif_party_hp(struct party *p, dumb_ptr<map_session_data> sd); // atcommand -void clif_displaymessage(int fd, ZString mes); -void clif_GMmessage(dumb_ptr<block_list> bl, ZString mes, int flag); +void clif_displaymessage(int fd, XString mes); +void clif_GMmessage(dumb_ptr<block_list> bl, XString mes, int flag); void clif_resurrection(dumb_ptr<block_list> bl, int type); int clif_specialeffect(dumb_ptr<block_list> bl, int type, int flag); // special effects [Valaris] -void clif_message(dumb_ptr<block_list> bl, const char *msg); // messages (from mobs/npcs) [Valaris] +void clif_message(dumb_ptr<block_list> bl, XString msg); // messages (from mobs/npcs) [Valaris] int clif_GM_kick(dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> tsd, int type); diff --git a/src/map/grfio.cpp b/src/map/grfio.cpp index a190d1b..cbb5a86 100644 --- a/src/map/grfio.cpp +++ b/src/map/grfio.cpp @@ -15,11 +15,12 @@ #include "../common/cxxstdio.hpp" #include "../common/extract.hpp" +#include "../common/io.hpp" #include "../poison.hpp" static -std::map<std::string, std::string> load_resnametable() +std::map<MapName, FString> load_resnametable() { std::ifstream in("data/resnametable.txt"); if (!in.is_open()) @@ -27,12 +28,13 @@ std::map<std::string, std::string> load_resnametable() fprintf(stderr, "Missing data/resnametable.txt"); abort(); } - std::map<std::string, std::string> out; + std::map<MapName, FString> out; - std::string line; - while (std::getline(in, line)) + FString line; + while (io::getline(in, line)) { - std::string key, value; + MapName key; + FString value; if (!extract(line, record<'#'>(&key, &value))) continue; @@ -43,29 +45,32 @@ std::map<std::string, std::string> load_resnametable() /// Change *.gat to *.wlk static -std::string grfio_resnametable(const_string rname) +FString grfio_resnametable(MapName rname) { static - std::map<std::string, std::string> resnametable = load_resnametable(); + std::map<MapName, FString> resnametable = load_resnametable(); - return resnametable.at(std::string(rname.begin(), rname.end())); + return resnametable.at(rname); } -std::vector<uint8_t> grfio_reads(const_string rname) +std::vector<uint8_t> grfio_reads(MapName rname) { - std::string lfname = "data/" + grfio_resnametable(rname); + MString lfname_; + lfname_ += "data/"; + lfname_ += grfio_resnametable(rname); + FString lfname = FString(lfname_); int fd = open(lfname.c_str(), O_RDONLY); if (fd == -1) { FPRINTF(stderr, "Resource %s (file %s) not found\n", - std::string(rname.begin(), rname.end()), lfname); + rname, lfname); return {}; } off_t len = lseek(fd, 0, SEEK_END); assert (len != -1); std::vector<uint8_t> buffer(len); - int err = pread(fd, buffer.data(), len, 0); + ssize_t err = pread(fd, buffer.data(), len, 0); assert (err == len); close(fd); return buffer; diff --git a/src/map/grfio.hpp b/src/map/grfio.hpp index fd7b871..aa222c6 100644 --- a/src/map/grfio.hpp +++ b/src/map/grfio.hpp @@ -5,11 +5,12 @@ #include <vector> -#include "../common/const_array.hpp" +#include "../common/mmo.hpp" +#include "../common/strings.hpp" /// Load a resource into memory, subject to data/resnametable.txt. /// Normally, resourcename is xxx-y.gat and the file is xxx-y.wlk. /// Currently there is exactly one .wlk per .gat, but multiples are fine. -std::vector<uint8_t> grfio_reads(const_string resourcename); +std::vector<uint8_t> grfio_reads(MapName resourcename); #endif // GRFIO_HPP diff --git a/src/map/intif.cpp b/src/map/intif.cpp index 311c661..d22519b 100644 --- a/src/map/intif.cpp +++ b/src/map/intif.cpp @@ -36,25 +36,25 @@ const int packet_len_table[] = // inter serverへの送信 // Message for all GMs on all map servers -void intif_GMmessage(const_string mes) +void intif_GMmessage(XString mes) { WFIFOW(char_fd, 0) = 0x3000; size_t len = mes.size() + 1; WFIFOW(char_fd, 2) = 4 + len; - WFIFO_STRING(char_fd, 4, mes.data(), len); + WFIFO_STRING(char_fd, 4, mes, len); WFIFOSET(char_fd, WFIFOW(char_fd, 2)); } // The transmission of Wisp/Page to inter-server (player not found on this server) -void intif_wis_message(dumb_ptr<map_session_data> sd, const char *nick, const char *mes) +void intif_wis_message(dumb_ptr<map_session_data> sd, CharName nick, ZString mes) { nullpo_retv(sd); - size_t mes_len = strlen(mes) + 1; + size_t mes_len = mes.size() + 1; WFIFOW(char_fd, 0) = 0x3001; WFIFOW(char_fd, 2) = mes_len + 52; - WFIFO_STRING(char_fd, 4, sd->status.name, 24); - WFIFO_STRING(char_fd, 28, nick, 24); + WFIFO_STRING(char_fd, 4, sd->status.name.to__actual(), 24); + WFIFO_STRING(char_fd, 28, nick.to__actual(), 24); WFIFO_STRING(char_fd, 52, mes, mes_len); WFIFOSET(char_fd, WFIFOW(char_fd, 2)); @@ -77,19 +77,19 @@ void intif_wis_replay(int id, int flag) } // The transmission of GM only Wisp/Page from server to inter-server -void intif_wis_message_to_gm(const char *Wisp_name, int min_gm_level, const char *mes) +void intif_wis_message_to_gm(CharName Wisp_name, int min_gm_level, ZString mes) { - size_t mes_len = strlen(mes) + 1; + size_t mes_len = mes.size() + 1; WFIFOW(char_fd, 0) = 0x3003; WFIFOW(char_fd, 2) = mes_len + 30; - WFIFO_STRING(char_fd, 4, Wisp_name, 24); + WFIFO_STRING(char_fd, 4, Wisp_name.to__actual(), 24); WFIFOW(char_fd, 28) = min_gm_level; WFIFO_STRING(char_fd, 30, mes, mes_len); WFIFOSET(char_fd, WFIFOW(char_fd, 2)); if (battle_config.etc_log) PRINTF("intif_wis_message_to_gm: from: '%s', min level: %d, message: '%s'.\n", - Wisp_name, min_gm_level, mes); + Wisp_name, min_gm_level, mes); } // アカウント変数送信 @@ -140,14 +140,14 @@ void intif_send_storage(struct storage *stor) } // パーティ作成要求 -void intif_create_party(dumb_ptr<map_session_data> sd, const char *name) +void intif_create_party(dumb_ptr<map_session_data> sd, PartyName name) { nullpo_retv(sd); WFIFOW(char_fd, 0) = 0x3020; WFIFOL(char_fd, 2) = sd->status.account_id; WFIFO_STRING(char_fd, 6, name, 24); - WFIFO_STRING(char_fd, 30, sd->status.name, 24); + WFIFO_STRING(char_fd, 30, sd->status.name.to__actual(), 24); WFIFO_STRING(char_fd, 54, sd->bl_m->name_, 16); WFIFOW(char_fd, 70) = sd->status.base_level; WFIFOSET(char_fd, 72); @@ -171,7 +171,7 @@ void intif_party_addmember(int party_id, int account_id) WFIFOW(char_fd, 0) = 0x3022; WFIFOL(char_fd, 2) = party_id; WFIFOL(char_fd, 6) = account_id; - WFIFO_STRING(char_fd, 10, sd->status.name, 24); + WFIFO_STRING(char_fd, 10, sd->status.name.to__actual(), 24); WFIFO_STRING(char_fd, 34, sd->bl_m->name_, 16); WFIFOW(char_fd, 50) = sd->status.base_level; WFIFOSET(char_fd, 52); @@ -214,9 +214,9 @@ void intif_party_changemap(dumb_ptr<map_session_data> sd, int online) } // パーティ会話送信 -void intif_party_message(int party_id, int account_id, const char *mes) +void intif_party_message(int party_id, int account_id, XString mes) { - size_t len = strlen(mes) + 1; + size_t len = mes.size() + 1; WFIFOW(char_fd, 0) = 0x3027; WFIFOW(char_fd, 2) = len + 12; WFIFOL(char_fd, 4) = party_id; @@ -226,12 +226,12 @@ void intif_party_message(int party_id, int account_id, const char *mes) } // パーティ競合チェック要求 -void intif_party_checkconflict(int party_id, int account_id, const char *nick) +void intif_party_checkconflict(int party_id, int account_id, CharName nick) { WFIFOW(char_fd, 0) = 0x3028; WFIFOL(char_fd, 2) = party_id; WFIFOL(char_fd, 6) = account_id; - WFIFO_STRING(char_fd, 10, nick, 24); + WFIFO_STRING(char_fd, 10, nick.to__actual(), 24); WFIFOSET(char_fd, 34); } @@ -245,26 +245,22 @@ int intif_parse_WisMessage(int fd) // rewritten by [Yor] dumb_ptr<map_session_data> sd; - char from[24]; - RFIFO_STRING(fd, 8, from, 24); - char to[24]; - RFIFO_STRING(fd, 32, to, 24); + CharName from = stringish<CharName>(RFIFO_STRING<24>(fd, 8)); + CharName to = stringish<CharName>(RFIFO_STRING<24>(fd, 32)); size_t len = RFIFOW(fd, 2) - 56; - char buf[len]; - RFIFO_STRING(fd, 56, buf, len); + FString buf = RFIFO_STRING(fd, 56, len); if (battle_config.etc_log) { - const char *mes = buf; PRINTF("intif_parse_wismessage: id: %d, from: %s, to: %s, message: '%s'\n", RFIFOL(fd, 4), from, to, - mes); + buf); } sd = map_nick2sd(to); // Searching destination player - if (sd != NULL && strcmp(sd->status.name, to) == 0) + if (sd != NULL && sd->status.name == to) { // exactly same name (inter-server have checked the name before) { @@ -286,8 +282,7 @@ int intif_parse_WisEnd(int fd) { dumb_ptr<map_session_data> sd; - char name[24]; - RFIFO_STRING(fd, 2, name, 24); + CharName name = stringish<CharName>(RFIFO_STRING<24>(fd, 2)); uint8_t flag = RFIFOB(fd, 26); if (battle_config.etc_log) // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target @@ -306,17 +301,15 @@ void mapif_parse_WisToGM(int fd) { // 0x3003/0x3803 <packet_len>.w <wispname>.24B <min_gm_level>.w <message>.?B int min_gm_level, len; - char Wisp_name[24]; if (RFIFOW(fd, 2) - 30 <= 0) return; len = RFIFOW(fd, 2) - 30; - char message[len]; min_gm_level = RFIFOW(fd, 28); - RFIFO_STRING(fd, 4, Wisp_name, 24); - RFIFO_STRING(fd, 30, message, len); + CharName Wisp_name = stringish<CharName>(RFIFO_STRING<24>(fd, 4)); + FString message = RFIFO_STRING(fd, 30, len); // information is sended to all online GM for (int i = 0; i < fd_max; i++) { @@ -341,7 +334,7 @@ int intif_parse_AccountReg(int fd) for (p = 8, j = 0; p < RFIFOW(fd, 2) && j < ACCOUNT_REG_NUM; p += 36, j++) { - RFIFO_STRING(fd, p, sd->status.account_reg[j].str, 32); + sd->status.account_reg[j].str = stringish<VarName>(RFIFO_STRING<32>(fd, p)); sd->status.account_reg[j].value = RFIFOL(fd, p + 32); } sd->status.account_reg_num = j; @@ -420,8 +413,7 @@ void intif_parse_PartyCreated(int fd) int account_id = RFIFOL(fd, 2); int fail = RFIFOB(fd, 6); int party_id = RFIFOL(fd, 7); - char name[24]; - RFIFO_STRING(fd, 11, name, 24); + PartyName name = stringish<PartyName>(RFIFO_STRING<24>(fd, 11)); party_created(account_id, fail, party_id, name); } @@ -474,8 +466,7 @@ void intif_parse_PartyMemberLeaved(int fd) { int party_id = RFIFOL(fd, 2); int account_id = RFIFOL(fd, 6); - char name[24]; - RFIFO_STRING(fd, 10, name, 24); + CharName name = stringish<CharName>(RFIFO_STRING<24>(fd, 10)); if (battle_config.etc_log) PRINTF("intif: party member leaved %d %d %s\n", party_id, account_id, name); @@ -495,8 +486,7 @@ void intif_parse_PartyMove(int fd) { int party_id = RFIFOL(fd, 2); int account_id = RFIFOL(fd, 6); - char map[16]; - RFIFO_STRING(fd, 10, map, 16); + MapName map = stringish<MapName>(RFIFO_STRING<16>(fd, 10)); uint8_t online = RFIFOB(fd, 26); uint16_t lv = RFIFOW(fd, 27); party_recv_movemap(party_id, account_id, map, online, lv); @@ -507,8 +497,7 @@ static void intif_parse_PartyMessage(int fd) { size_t len = RFIFOW(fd, 2) - 12; - char buf[len]; - RFIFO_STRING(fd, 12, buf, len); + FString buf = RFIFO_STRING(fd, 12, len); party_recv_message(RFIFOL(fd, 4), RFIFOL(fd, 8), buf); } @@ -547,9 +536,8 @@ int intif_parse(int fd) { case 0x3800: { - char mes[packet_len - 4]; - RFIFO_STRING(fd, 4, mes, packet_len - 4); - clif_GMmessage(NULL, ZString(ZString::really_construct_from_a_pointer, mes), 0); + FString mes = RFIFO_STRING(fd, 4, packet_len - 4); + clif_GMmessage(NULL, mes, 0); } break; case 0x3801: diff --git a/src/map/intif.hpp b/src/map/intif.hpp index 73a06e5..08added 100644 --- a/src/map/intif.hpp +++ b/src/map/intif.hpp @@ -7,10 +7,10 @@ int intif_parse(int fd); -void intif_GMmessage(const_string mes); +void intif_GMmessage(XString mes); -void intif_wis_message(dumb_ptr<map_session_data> sd, const char *nick, const char *mes); -void intif_wis_message_to_gm(const char *Wisp_name, int min_gm_level, const char *mes); +void intif_wis_message(dumb_ptr<map_session_data> sd, CharName nick, ZString mes); +void intif_wis_message_to_gm(CharName Wisp_name, int min_gm_level, ZString mes); void intif_saveaccountreg(dumb_ptr<map_session_data> sd); void intif_request_accountreg(dumb_ptr<map_session_data> sd); @@ -18,14 +18,14 @@ void intif_request_accountreg(dumb_ptr<map_session_data> sd); void intif_request_storage(int account_id); void intif_send_storage(struct storage *stor); -void intif_create_party(dumb_ptr<map_session_data> sd, const char *name); +void intif_create_party(dumb_ptr<map_session_data> sd, PartyName name); void intif_request_partyinfo(int party_id); void intif_party_addmember(int party_id, int account_id); void intif_party_changeoption(int party_id, int account_id, int exp, int item); void intif_party_leave(int party_id, int accound_id); void intif_party_changemap(dumb_ptr<map_session_data> sd, int online); -void intif_party_message(int party_id, int account_id, const char *mes); -void intif_party_checkconflict(int party_id, int account_id, const char *nick); +void intif_party_message(int party_id, int account_id, XString mes); +void intif_party_checkconflict(int party_id, int account_id, CharName nick); #endif // INTIF_HPP diff --git a/src/map/itemdb.cpp b/src/map/itemdb.cpp index 570b517..cb47b21 100644 --- a/src/map/itemdb.cpp +++ b/src/map/itemdb.cpp @@ -3,10 +3,14 @@ #include <cstdlib> #include <cstring> +#include <fstream> + #include "../common/cxxstdio.hpp" #include "../common/db.hpp" -#include "../common/random.hpp" +#include "../common/extract.hpp" +#include "../common/io.hpp" #include "../common/nullpo.hpp" +#include "../common/random.hpp" #include "../common/socket.hpp" #include "../poison.hpp" @@ -33,9 +37,9 @@ int itemdb_readdb(void); */ // name = item alias, so we should find items aliases first. if not found then look for "jname" (full name) static -void itemdb_searchname_sub(struct item_data *item, const char *str, struct item_data **dst) +void itemdb_searchname_sub(struct item_data *item, ItemName str, struct item_data **dst) { - if (strcasecmp(item->name, str) == 0) //by lupus + if (item->name == str) *dst = item; } @@ -43,7 +47,7 @@ void itemdb_searchname_sub(struct item_data *item, const char *str, struct item_ * 名前で検索 *------------------------------------------ */ -struct item_data *itemdb_searchname(const char *str) +struct item_data *itemdb_searchname(ItemName str) { struct item_data *item = NULL; for (auto& pair : item_db) @@ -148,62 +152,70 @@ int itemdb_isequip3(int nameid) static int itemdb_readdb(void) { - FILE *fp; - char line[1024]; int ln = 0, lines = 0; - int nameid, j; - struct item_data *id; - int i = 0; - const char *filename[] = { "db/item_db.txt", "db/item_db2.txt" }; + const char *filename = "db/item_db.txt"; - for (i = 0; i < 2; i++) { + std::ifstream in(filename); - fp = fopen_(filename[i], "r"); - if (fp == NULL) + if (!in.is_open()) { - if (i > 0) - continue; - PRINTF("can't read %s\n", filename[i]); + PRINTF("can't read %s\n", filename); exit(1); } lines = 0; - while (fgets(line, 1020, fp)) + + FString line; + while (io::getline(in, line)) { lines++; - if (line[0] == '/' && line[1] == '/') + if (!line) continue; - char *str[32] {}; - char *p; - char *np; - for (j = 0, np = p = line; j < 17 && p; j++) + if (line.startswith("//")) + continue; + // a line is 17 normal fields followed by 2 {} fields + // the fields are separated by ", *", but there may be , + // in the {}. + + auto it = std::find(line.begin(), line.end(), '{'); + XString main_part = line.xislice_h(it).rstrip(); + // According to the code, tail_part may be empty. See later. + ZString tail_part = line.xislice_t(it); + + item_data idv {}; + if (!extract( + main_part, record<','>( + &idv.nameid, + lstripping(&idv.name), + lstripping(&idv.jname), + lstripping(&idv.type), + lstripping(&idv.value_buy), + lstripping(&idv.value_sell), + lstripping(&idv.weight), + lstripping(&idv.atk), + lstripping(&idv.def), + lstripping(&idv.range), + lstripping(&idv.magic_bonus), + lstripping(&idv.slot), + lstripping(&idv.sex), + lstripping(&idv.equip), + lstripping(&idv.wlv), + lstripping(&idv.elv), + lstripping(&idv.look) + ) + ) + ) { - while (*p == '\t' || *p == ' ') - p++; - str[j] = p; - p = strchr(p, ','); - if (p) - { - *p++ = 0; - np = p; - } - } - if (str[0] == NULL) + PRINTF("%s:%d: error: bad item line: %s\n", + filename, lines, line); continue; + } - nameid = atoi(str[0]); - if (nameid <= 0 || nameid >= 20000) - continue; ln++; - //ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Gender,Loc,wLV,eLV,View - id = itemdb_search(nameid); - strzcpy(id->name, str[1], 24); - strzcpy(id->jname, str[2], 24); - id->type = ItemType(atoi(str[3])); - id->value_buy = atoi(str[4]); - id->value_sell = atoi(str[5]); + struct item_data *id = itemdb_search(idv.nameid); + *id = std::move(idv); if (id->value_buy == 0 && id->value_sell == 0) { } @@ -215,31 +227,20 @@ int itemdb_readdb(void) { id->value_sell = id->value_buy / 2; } - id->weight = atoi(str[6]); - id->atk = atoi(str[7]); - id->def = atoi(str[8]); - id->range = atoi(str[9]); - id->magic_bonus = atoi(str[10]); - id->slot = atoi(str[11]); - id->sex = atoi(str[12]); - id->equip = EPOS(atoi(str[13])); - id->wlv = atoi(str[14]); - id->elv = atoi(str[15]); - id->look = static_cast<ItemLook>(atoi(str[16])); id->use_script = NULL; id->equip_script = NULL; - if ((p = strchr(np, '{')) == NULL) + if (!tail_part) continue; - id->use_script = parse_script(p, lines); + id->use_script = parse_script(tail_part, lines); - if ((p = strchr(p + 1, '{')) == NULL) + tail_part = tail_part.xislice_t(std::find(tail_part.begin() + 1, tail_part.end(), '{')); + if (!tail_part) continue; - id->equip_script = parse_script(p, lines); + id->equip_script = parse_script(tail_part, lines); } - fclose_(fp); - PRINTF("read %s done (count=%d)\n", filename[i], ln); + PRINTF("read %s done (count=%d)\n", filename, ln); } return 0; } diff --git a/src/map/itemdb.hpp b/src/map/itemdb.hpp index 17b2057..7e5aa34 100644 --- a/src/map/itemdb.hpp +++ b/src/map/itemdb.hpp @@ -9,9 +9,7 @@ struct item_data { int nameid; - char name[24], jname[24]; - char prefix[24], suffix[24]; - char cardillustname[64]; + ItemName name, jname; int value_buy; int value_sell; ItemType type; @@ -37,7 +35,7 @@ struct random_item_data int per; }; -struct item_data *itemdb_searchname(const char *name); +struct item_data *itemdb_searchname(ItemName name); struct item_data *itemdb_search(int nameid); struct item_data *itemdb_exists(int nameid); diff --git a/src/map/magic-expr-eval.hpp b/src/map/magic-expr-eval.hpp index 9c9591b..76b86f8 100644 --- a/src/map/magic-expr-eval.hpp +++ b/src/map/magic-expr-eval.hpp @@ -7,7 +7,7 @@ /* Helper definitions for dealing with functions and operations */ -int magic_signature_check(const char *opname, const char *funname, const char *signature, +int magic_signature_check(ZString opname, ZString funname, ZString signature, int args_nr, val_t *args, int line, int column); void magic_area_rect(map_local **m, int *x, int *y, int *width, int *height, @@ -15,7 +15,7 @@ void magic_area_rect(map_local **m, int *x, int *y, int *width, int *height, #define ARGINT(x) args[x].v.v_int #define ARGDIR(x) args[x].v.v_dir -#define ARGSTR(x) args[x].v.v_string +#define ARGSTR(x) ZString(args[x].v.v_string) #define ARGENTITY(x) args[x].v.v_entity #define ARGLOCATION(x) args[x].v.v_location #define ARGAREA(x) args[x].v.v_area diff --git a/src/map/magic-expr.cpp b/src/map/magic-expr.cpp index 5aad257..872ba6f 100644 --- a/src/map/magic-expr.cpp +++ b/src/map/magic-expr.cpp @@ -87,12 +87,12 @@ void magic_clear_var(val_t *v) } static -const char *show_entity(dumb_ptr<block_list> entity) +FString show_entity(dumb_ptr<block_list> entity) { switch (entity->bl_type) { case BL::PC: - return entity->as_player()->status.name; + return entity->as_player()->status.name.to__actual(); case BL::NPC: return entity->as_npc()->name; case BL::MOB: @@ -104,23 +104,23 @@ const char *show_entity(dumb_ptr<block_list> entity) // return ((struct item_data *) (&entity->as_item()->item_data))->name; abort(); case BL::SPELL: - return "%invocation(ERROR:this-should-not-be-an-entity)"; + return {"%invocation(ERROR:this-should-not-be-an-entity)"}; default: - return "%unknown-entity"; + return {"%unknown-entity"}; } } static void stringify(val_t *v, int within_op) { - static const char *dirs[8] = - { - "south", "south-west", - "west", "north-west", - "north", "north-east", - "east", "south-east" - }; - std::string buf; + static earray<ZString, DIR, DIR::COUNT> dirs //= + {{ + {"south"}, {"south-west"}, + {"west"}, {"north-west"}, + {"north"}, {"north-east"}, + {"east"}, {"south-east"}, + }}; + FString buf; switch (v->ty) { @@ -136,7 +136,7 @@ void stringify(val_t *v, int within_op) return; case TYPE::DIR: - buf = dirs[v->v.v_int]; + buf = dirs[v->v.v_dir]; break; case TYPE::ENTITY: @@ -278,7 +278,10 @@ int fun_add(dumb_ptr<env_t>, val_t *result, const_array<val_t> args) stringify(&args[1], 1); /* Yes, we could speed this up. */ // ugh - RESULTSTR = dumb_string::copys(ARGSTR(0).str() + ARGSTR(1).str()); + MString m; + m += ARGSTR(0); + m += ARGSTR(1); + RESULTSTR = dumb_string::copys(FString(m)); result->ty = TYPE::STRING; } return 0; @@ -351,7 +354,6 @@ int fun_gte(dumb_ptr<env_t>, val_t *result, const_array<val_t> args) { stringify(&args[0], 1); stringify(&args[1], 1); - using namespace operators; RESULTINT = ARGSTR(0) >= ARGSTR(1); } else @@ -370,7 +372,6 @@ int fun_gt(dumb_ptr<env_t>, val_t *result, const_array<val_t> args) { stringify(&args[0], 1); stringify(&args[1], 1); - using namespace operators; RESULTINT = ARGSTR(0) > ARGSTR(1); } else @@ -389,7 +390,6 @@ int fun_eq(dumb_ptr<env_t>, val_t *result, const_array<val_t> args) { stringify(&args[0], 1); stringify(&args[1], 1); - using namespace operators; RESULTINT = ARGSTR(0) == ARGSTR(1); } else if (ARG_TYPE(0) == TYPE::DIR && ARG_TYPE(1) == TYPE::DIR) @@ -652,7 +652,7 @@ int fun_name_of(dumb_ptr<env_t>, val_t *result, const_array<val_t> args) { if (ARG_TYPE(0) == TYPE::ENTITY) { - RESULTSTR = dumb_string::copy(show_entity(ARGENTITY(0))); + RESULTSTR = dumb_string::copys(show_entity(ARGENTITY(0))); return 0; } else if (ARG_TYPE(0) == TYPE::SPELL) @@ -745,7 +745,7 @@ magic_find_item(const_array<val_t> args, int index, struct item *item_, int *sta if (ARG_TYPE(index) == TYPE::INT) item_data = itemdb_exists(ARGINT(index)); else if (ARG_TYPE(index) == TYPE::STRING) - item_data = itemdb_searchname(ARGSTR(index).c_str()); + item_data = itemdb_searchname(stringish<ItemName>(ARGSTR(index))); else return -1; @@ -874,14 +874,16 @@ int fun_failed(dumb_ptr<env_t>, val_t *result, const_array<val_t> args) static int fun_npc(dumb_ptr<env_t>, val_t *result, const_array<val_t> args) { - RESULTENTITY = npc_name2id(ARGSTR(0).c_str()); + NpcName name = stringish<NpcName>(ARGSTR(0)); + RESULTENTITY = npc_name2id(name); return RESULTENTITY == NULL; } static int fun_pc(dumb_ptr<env_t>, val_t *result, const_array<val_t> args) { - RESULTENTITY = map_nick2sd(ARGSTR(0).c_str()); + CharName name = stringish<CharName>(ARGSTR(0)); + RESULTENTITY = map_nick2sd(name); return RESULTENTITY == NULL; } @@ -913,7 +915,7 @@ int fun_rdistance(dumb_ptr<env_t>, val_t *result, const_array<val_t> args) static int fun_anchor(dumb_ptr<env_t> env, val_t *result, const_array<val_t> args) { - dumb_ptr<teleport_anchor_t> anchor = magic_find_anchor(ARGSTR(0).str()); + dumb_ptr<teleport_anchor_t> anchor = magic_find_anchor(ARGSTR(0)); if (!anchor) return 1; @@ -997,12 +999,12 @@ static int fun_read_script_int(dumb_ptr<env_t>, val_t *result, const_array<val_t> args) { dumb_ptr<block_list> subject_p = ARGENTITY(0); - dumb_string var_name = ARGSTR(1); + VarName var_name = stringish<VarName>(ARGSTR(1)); if (subject_p->bl_type != BL::PC) return 1; - RESULTINT = pc_readglobalreg(subject_p->as_player(), var_name.c_str()); + RESULTINT = pc_readglobalreg(subject_p->as_player(), var_name); return 0; } @@ -1055,13 +1057,6 @@ int fun_element_level(dumb_ptr<env_t>, val_t *result, const_array<val_t> args) } static -int fun_index(dumb_ptr<env_t>, val_t *result, const_array<val_t> args) -{ - RESULTINT = ARGSPELL(0)->index_; - return 0; -} - -static int fun_is_exterior(dumb_ptr<env_t>, val_t *result, const_array<val_t> args) { #warning "Evil assumptions!" @@ -1136,7 +1131,7 @@ static int fun_map_nr(dumb_ptr<env_t>, val_t *result, const_array<val_t> args) { #warning "Evil assumptions!" - const char *mapname = ARGLOCATION(0).m->name_; + MapName mapname = ARGLOCATION(0).m->name_; RESULTINT = ((mapname[0] - '0') * 100) + ((mapname[1] - '0') * 10) + ((mapname[2] - '0')); @@ -1221,123 +1216,93 @@ int fun_extract_healer_xp(dumb_ptr<env_t>, val_t *result, const_array<val_t> arg return 0; } -static -fun_t functions[] = -{ - {"+", "..", '.', fun_add}, - {"-", "ii", 'i', fun_sub}, - {"*", "ii", 'i', fun_mul}, - {"/", "ii", 'i', fun_div}, - {"%", "ii", 'i', fun_mod}, - {"||", "ii", 'i', fun_or}, - {"&&", "ii", 'i', fun_and}, - {">", "..", 'i', fun_gt}, - {">=", "..", 'i', fun_gte}, - {"=", "..", 'i', fun_eq}, - {"|", "..", 'i', fun_bitor}, - {"&", "ii", 'i', fun_bitand}, - {"^", "ii", 'i', fun_bitxor}, - {"<<", "ii", 'i', fun_bitshl}, - {">>", "ii", 'i', fun_bitshr}, - {"not", "i", 'i', fun_not}, - {"neg", "i", 'i', fun_neg}, - {"max", "ii", 'i', fun_max}, - {"min", "ii", 'i', fun_min}, - {"is_in", "la", 'i', fun_is_in}, - {"if_then_else", "i__", '_', fun_if_then_else}, - {"skill", "ei", 'i', fun_skill}, - {"str", "e", 'i', fun_get_str}, - {"agi", "e", 'i', fun_get_agi}, - {"vit", "e", 'i', fun_get_vit}, - {"dex", "e", 'i', fun_get_dex}, - {"luk", "e", 'i', fun_get_luk}, - {"int", "e", 'i', fun_get_int}, - {"level", "e", 'i', fun_get_lv}, - {"mdef", "e", 'i', fun_get_mdef}, - {"def", "e", 'i', fun_get_def}, - {"hp", "e", 'i', fun_get_hp}, - {"max_hp", "e", 'i', fun_get_max_hp}, - {"sp", "e", 'i', fun_get_sp}, - {"max_sp", "e", 'i', fun_get_max_sp}, - {"dir", "e", 'd', fun_get_dir}, - {"name_of", ".", 's', fun_name_of}, - {"mob_id", "e", 'i', fun_mob_id}, - {"location", "e", 'l', fun_location}, - {"random", "i", 'i', fun_random}, - {"random_dir", "i", 'd', fun_random_dir}, - {"hash_entity", "e", 'i', fun_hash_entity}, - {"is_married", "e", 'i', fun_is_married}, - {"partner", "e", 'e', fun_partner}, - {"awayfrom", "ldi", 'l', fun_awayfrom}, - {"failed", "_", 'i', fun_failed}, - {"pc", "s", 'e', fun_pc}, - {"npc", "s", 'e', fun_npc}, - {"distance", "ll", 'i', fun_distance}, - {"rdistance", "ll", 'i', fun_rdistance}, - {"anchor", "s", 'a', fun_anchor}, - {"random_location", "a", 'l', fun_pick_location}, - {"script_int", "es", 'i', fun_read_script_int}, - {"rbox", "li", 'a', fun_rbox}, - {"count_item", "e.", 'i', fun_count_item}, - {"line_of_sight", "ll", 'i', fun_line_of_sight}, - {"running_status_update", "ei", 'i', fun_running_status_update}, - {"status_option", "ei", 'i', fun_status_option}, - {"element", "e", 'i', fun_element}, - {"element_level", "e", 'i', fun_element_level}, - {"has_shroud", "e", 'i', fun_has_shroud}, - {"is_equipped", "e.", 'i', fun_is_equipped}, - {"spell_index", "S", 'i', fun_index}, - {"is_exterior", "l", 'i', fun_is_exterior}, - {"contains_string", "ss", 'i', fun_contains_string}, - {"strstr", "ss", 'i', fun_strstr}, - {"strlen", "s", 'i', fun_strlen}, - {"substr", "sii", 's', fun_substr}, - {"sqrt", "i", 'i', fun_sqrt}, - {"map_level", "l", 'i', fun_map_level}, - {"map_nr", "l", 'i', fun_map_nr}, - {"dir_towards", "lli", 'd', fun_dir_towards}, - {"is_dead", "e", 'i', fun_is_dead}, - {"is_pc", "e", 'i', fun_is_pc}, - {"extract_healer_experience", "ei", 'i', fun_extract_healer_xp}, - {NULL, NULL, '.', NULL} +#define MAGIC_FUNCTION(name, args, ret, impl) {{name}, {{name}, {args}, ret, impl}} +#define MAGIC_FUNCTION1(name, args, ret) MAGIC_FUNCTION(#name, args, ret, fun_##name) +static +std::map<ZString, fun_t> functions = +{ + MAGIC_FUNCTION("+", "..", '.', fun_add), + MAGIC_FUNCTION("-", "ii", 'i', fun_sub), + MAGIC_FUNCTION("*", "ii", 'i', fun_mul), + MAGIC_FUNCTION("/", "ii", 'i', fun_div), + MAGIC_FUNCTION("%", "ii", 'i', fun_mod), + MAGIC_FUNCTION("||", "ii", 'i', fun_or), + MAGIC_FUNCTION("&&", "ii", 'i', fun_and), + MAGIC_FUNCTION(">", "..", 'i', fun_gt), + MAGIC_FUNCTION(">=", "..", 'i', fun_gte), + MAGIC_FUNCTION("=", "..", 'i', fun_eq), + MAGIC_FUNCTION("|", "..", 'i', fun_bitor), + MAGIC_FUNCTION("&", "ii", 'i', fun_bitand), + MAGIC_FUNCTION("^", "ii", 'i', fun_bitxor), + MAGIC_FUNCTION("<<", "ii", 'i', fun_bitshl), + MAGIC_FUNCTION(">>", "ii", 'i', fun_bitshr), + MAGIC_FUNCTION1(not, "i", 'i'), + MAGIC_FUNCTION1(neg, "i", 'i'), + MAGIC_FUNCTION1(max, "ii", 'i'), + MAGIC_FUNCTION1(min, "ii", 'i'), + MAGIC_FUNCTION1(is_in, "la", 'i'), + MAGIC_FUNCTION1(if_then_else, "i__", '_'), + MAGIC_FUNCTION1(skill, "ei", 'i'), + MAGIC_FUNCTION("str", "e", 'i', fun_get_str), + MAGIC_FUNCTION("agi", "e", 'i', fun_get_agi), + MAGIC_FUNCTION("vit", "e", 'i', fun_get_vit), + MAGIC_FUNCTION("dex", "e", 'i', fun_get_dex), + MAGIC_FUNCTION("luk", "e", 'i', fun_get_luk), + MAGIC_FUNCTION("int", "e", 'i', fun_get_int), + MAGIC_FUNCTION("level", "e", 'i', fun_get_lv), + MAGIC_FUNCTION("mdef", "e", 'i', fun_get_mdef), + MAGIC_FUNCTION("def", "e", 'i', fun_get_def), + MAGIC_FUNCTION("hp", "e", 'i', fun_get_hp), + MAGIC_FUNCTION("max_hp", "e", 'i', fun_get_max_hp), + MAGIC_FUNCTION("sp", "e", 'i', fun_get_sp), + MAGIC_FUNCTION("max_sp", "e", 'i', fun_get_max_sp), + MAGIC_FUNCTION("dir", "e", 'd', fun_get_dir), + MAGIC_FUNCTION1(name_of, ".", 's'), + MAGIC_FUNCTION1(mob_id, "e", 'i'), + MAGIC_FUNCTION1(location, "e", 'l'), + MAGIC_FUNCTION1(random, "i", 'i'), + MAGIC_FUNCTION1(random_dir, "i", 'd'), + MAGIC_FUNCTION1(hash_entity, "e", 'i'), + MAGIC_FUNCTION1(is_married, "e", 'i'), + MAGIC_FUNCTION1(partner, "e", 'e'), + MAGIC_FUNCTION1(awayfrom, "ldi", 'l'), + MAGIC_FUNCTION1(failed, "_", 'i'), + MAGIC_FUNCTION1(pc, "s", 'e'), + MAGIC_FUNCTION1(npc, "s", 'e'), + MAGIC_FUNCTION1(distance, "ll", 'i'), + MAGIC_FUNCTION1(rdistance, "ll", 'i'), + MAGIC_FUNCTION1(anchor, "s", 'a'), + MAGIC_FUNCTION("random_location", "a", 'l', fun_pick_location), + MAGIC_FUNCTION("script_int", "es", 'i', fun_read_script_int), + MAGIC_FUNCTION1(rbox, "li", 'a'), + MAGIC_FUNCTION1(count_item, "e.", 'i'), + MAGIC_FUNCTION1(line_of_sight, "ll", 'i'), + MAGIC_FUNCTION1(running_status_update, "ei", 'i'), + MAGIC_FUNCTION1(status_option, "ei", 'i'), + MAGIC_FUNCTION1(element, "e", 'i'), + MAGIC_FUNCTION1(element_level, "e", 'i'), + MAGIC_FUNCTION1(has_shroud, "e", 'i'), + MAGIC_FUNCTION1(is_equipped, "e.", 'i'), + MAGIC_FUNCTION1(is_exterior, "l", 'i'), + MAGIC_FUNCTION1(contains_string, "ss", 'i'), + MAGIC_FUNCTION1(strstr, "ss", 'i'), + MAGIC_FUNCTION1(strlen, "s", 'i'), + MAGIC_FUNCTION1(substr, "sii", 's'), + MAGIC_FUNCTION1(sqrt, "i", 'i'), + MAGIC_FUNCTION1(map_level, "l", 'i'), + MAGIC_FUNCTION1(map_nr, "l", 'i'), + MAGIC_FUNCTION1(dir_towards, "lli", 'd'), + MAGIC_FUNCTION1(is_dead, "e", 'i'), + MAGIC_FUNCTION1(is_pc, "e", 'i'), + MAGIC_FUNCTION("extract_healer_experience", "ei", 'i', fun_extract_healer_xp), }; -static -int functions_are_sorted = 0; - -static __attribute__((deprecated)) -int compare_fun(const void *lhs, const void *rhs) -{ - return strcmp(static_cast<const fun_t *>(lhs)->name, static_cast<const fun_t *>(rhs)->name); -} - -fun_t *magic_get_fun(const std::string& name, int *index) +fun_t *magic_get_fun(ZString name) { - static - int functions_nr; - fun_t *result; - fun_t key; - - if (!functions_are_sorted) - { - fun_t *it = functions; - - while (it->name) - ++it; - functions_nr = it - functions; - - qsort(functions, functions_nr, sizeof(fun_t), compare_fun); - functions_are_sorted = 1; - } - - key.name = name.c_str(); - result = static_cast<fun_t *>(bsearch(&key, functions, functions_nr, sizeof(fun_t), - compare_fun)); - - if (result && index) - *index = result - functions; - - return result; + auto it = functions.find(name); + if (it == functions.end()) + return nullptr; + return &it->second; } // 1 on failure @@ -1352,7 +1317,8 @@ int eval_location(dumb_ptr<env_t> env, location_t *dest, e_location_t *expr) if (CHECK_TYPE(&m, TYPE::STRING) && CHECK_TYPE(&x, TYPE::INT) && CHECK_TYPE(&y, TYPE::INT)) { - map_local *map_id = map_mapname2mapid(m.v.v_string.c_str()); + MapName name = VString<15>(ZString(m.v.v_string)); + map_local *map_id = map_mapname2mapid(name); magic_clear_var(&m); if (!map_id) return 1; @@ -1509,8 +1475,8 @@ TYPE type_key(char ty_key) } } -int magic_signature_check(const char *opname, const char *funname, const char *signature, - int args_nr, val_t *args, int line, int column) +int magic_signature_check(ZString opname, ZString funname, ZString signature, + int args_nr, val_t *args, int line, int column) { int i; for (i = 0; i < args_nr; i++) @@ -1620,7 +1586,7 @@ void magic_eval(dumb_ptr<env_t> env, val_t *dest, dumb_ptr<expr_t> expr) val_t arguments[MAX_ARGS]; int args_nr = expr->e.e_funapp.args_nr; int i; - fun_t *f = functions + expr->e.e_funapp.id; + fun_t *f = expr->e.e_funapp.funp; for (i = 0; i < args_nr; ++i) magic_eval(env, &arguments[i], expr->e.e_funapp.args[i]); @@ -1705,13 +1671,13 @@ int magic_eval_int(dumb_ptr<env_t> env, dumb_ptr<expr_t> expr) return result.v.v_int; } -std::string magic_eval_str(dumb_ptr<env_t> env, dumb_ptr<expr_t> expr) +FString magic_eval_str(dumb_ptr<env_t> env, dumb_ptr<expr_t> expr) { val_t result; magic_eval(env, &result, expr); if (result.ty == TYPE::FAIL || result.ty == TYPE::UNDEF) - return "?"; + return {"?"}; stringify(&result, 0); diff --git a/src/map/magic-expr.hpp b/src/map/magic-expr.hpp index 7f3e1e1..2bffcbc 100644 --- a/src/map/magic-expr.hpp +++ b/src/map/magic-expr.hpp @@ -16,34 +16,34 @@ * . : any, except for fail/undef * _ : any, including fail, but not undef */ -typedef struct fun +struct fun_t { - const char *name; - const char *signature; + ZString name; + ZString signature; char ret_ty; int (*fun)(dumb_ptr<env_t> env, val_t *result, const_array<val_t> arga); -} fun_t; +}; -typedef struct op +struct op_t { - const char *name; - const char *signature; + ZString name; + ZString signature; int (*op)(dumb_ptr<env_t> env, const_array<val_t> arga); -} op_t; +}; /** * Retrieves a function by name * @param name The name to look up - * @return A function of that name, or NULL, and a function index + * @return A function of that name, or NULL. */ -fun_t *magic_get_fun(const std::string& name, int *index); +fun_t *magic_get_fun(ZString name); /** * Retrieves an operation by name * @param name The name to look up * @return An operation of that name, or NULL, and a function index */ -op_t *magic_get_op(const std::string& name, int *index); +op_t *magic_get_op(ZString name); /** * Evaluates an expression and stores the result in `dest' @@ -58,7 +58,7 @@ int magic_eval_int(dumb_ptr<env_t> env, dumb_ptr<expr_t> expr); /** * Evaluates an expression and coerces the result into a string */ -std::string magic_eval_str(dumb_ptr<env_t> env, dumb_ptr<expr_t> expr); +FString magic_eval_str(dumb_ptr<env_t> env, dumb_ptr<expr_t> expr); dumb_ptr<expr_t> magic_new_expr(EXPR ty); diff --git a/src/map/magic-interpreter-base.cpp b/src/map/magic-interpreter-base.cpp index 3d0c853..1a80617 100644 --- a/src/map/magic-interpreter-base.cpp +++ b/src/map/magic-interpreter-base.cpp @@ -62,16 +62,16 @@ void set_spell SETTER(dumb_ptr<spell_t>, TYPE::SPELL, v_spell) magic_conf_t magic_conf; /* Global magic conf */ env_t magic_default_env = { &magic_conf, NULL }; -const char *magic_find_invocation(const std::string& spellname) +FString magic_find_invocation(XString spellname) { auto it = magic_conf.spells_by_name.find(spellname); if (it != magic_conf.spells_by_name.end()) - return it->second->invocation.c_str(); + return it->second->invocation; - return NULL; + return FString(); } -dumb_ptr<spell_t> magic_find_spell(const std::string& invocation) +dumb_ptr<spell_t> magic_find_spell(XString invocation) { auto it = magic_conf.spells_by_invocation.find(invocation); if (it != magic_conf.spells_by_invocation.end()) @@ -84,17 +84,17 @@ dumb_ptr<spell_t> magic_find_spell(const std::string& invocation) /* Spell anchors */ /* -------------------------------------------------------------------------------- */ -const char *magic_find_anchor_invocation(const std::string& anchor_name) +FString magic_find_anchor_invocation(XString anchor_name) { auto it = magic_conf.anchors_by_name.find(anchor_name); if (it != magic_conf.anchors_by_name.end()) - return it->second->invocation.c_str(); + return it->second->invocation; - return NULL; + return FString(); } -dumb_ptr<teleport_anchor_t> magic_find_anchor(const std::string& name) +dumb_ptr<teleport_anchor_t> magic_find_anchor(XString name) { auto it = magic_conf.anchors_by_invocation.find(name); if (it != magic_conf.anchors_by_invocation.end()) @@ -137,7 +137,7 @@ void magic_free_env(dumb_ptr<env_t> env) } dumb_ptr<env_t> spell_create_env(magic_conf_t *conf, dumb_ptr<spell_t> spell, - dumb_ptr<map_session_data> caster, int spellpower, const_string param) + dumb_ptr<map_session_data> caster, int spellpower, XString param) { dumb_ptr<env_t> env = alloc_env(conf); @@ -145,12 +145,13 @@ dumb_ptr<env_t> spell_create_env(magic_conf_t *conf, dumb_ptr<spell_t> spell, { case SPELLARG::STRING: - set_env_string(spell->arg, dumb_string::copyc(param)); + set_env_string(spell->arg, dumb_string::copys(param)); break; case SPELLARG::PC: { - dumb_ptr<map_session_data> subject = map_nick2sd(std::string(param.begin(), param.end()).c_str()); + CharName name = stringish<CharName>(param); + dumb_ptr<map_session_data> subject = map_nick2sd(name); if (!subject) subject = caster; set_env_entity(spell->arg, subject); diff --git a/src/map/magic-interpreter-parser.ypp b/src/map/magic-interpreter-parser.ypp index a392bc7..e6d69b4 100644 --- a/src/map/magic-interpreter-parser.ypp +++ b/src/map/magic-interpreter-parser.ypp @@ -19,21 +19,25 @@ // I still don't get why this is necessary. #define YYLEX_PARAM 0, 0 +// can't use src/warnings.hpp in generated code #pragma GCC diagnostic warning "-Wall" #pragma GCC diagnostic warning "-Wextra" #pragma GCC diagnostic warning "-Wformat" +#ifndef __clang__ +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif static -size_t intern_id(const_string id_name); +size_t intern_id(ZString id_name); static -dumb_ptr<expr_t> fun_expr(const std::string& name, const_array<dumb_ptr<expr_t>> argv, int line, int column); +dumb_ptr<expr_t> fun_expr(FString name, const_array<dumb_ptr<expr_t>> argv, int line, int column); static dumb_ptr<expr_t> dot_expr(dumb_ptr<expr_t> lhs, int id); static -void BIN_EXPR(dumb_ptr<expr_t> & x, const std::string& name, dumb_ptr<expr_t> arg1, dumb_ptr<expr_t> arg2, int line, int column) +void BIN_EXPR(dumb_ptr<expr_t>& x, FString name, dumb_ptr<expr_t> arg1, dumb_ptr<expr_t> arg2, int line, int column) { dumb_ptr<expr_t> e[2]; e[0] = arg1; @@ -72,7 +76,7 @@ static void add_teleport_anchor(dumb_ptr<teleport_anchor_t> anchor, int line_nr); static -dumb_ptr<effect_t> op_effect(const std::string& name, const_array<dumb_ptr<expr_t>> argv, int line, int column); +dumb_ptr<effect_t> op_effect(FString name, const_array<dumb_ptr<expr_t>> argv, int line, int column); // in magic-interpreter-lexer.cpp int magic_frontend_lex(YYSTYPE *, YYLTYPE *); @@ -81,13 +85,13 @@ static void install_proc(dumb_ptr<proc_t> proc); static -dumb_ptr<effect_t> call_proc(const_string name, dumb_ptr<std::vector<dumb_ptr<expr_t>>> argvp, int line_nr, int column); +dumb_ptr<effect_t> call_proc(ZString name, dumb_ptr<std::vector<dumb_ptr<expr_t>>> argvp, int line_nr, int column); static -void bind_constant(const std::string& name, val_t *val, int line_nr); +void bind_constant(FString name, val_t *val, int line_nr); static -val_t *find_constant(const std::string& name); +val_t *find_constant(FString name); } // %code @@ -919,7 +923,7 @@ item_name : STRING { - struct item_data *item = itemdb_searchname($1.c_str()); + struct item_data *item = itemdb_searchname(stringish<ItemName>(ZString($1))); if (!item) { fail(@1.first_line, @1.first_column, "Unknown item `%s'\n", $1.c_str()); @@ -1066,7 +1070,7 @@ effect | SCRIPT_DATA { $$ = new_effect(EFFECT::SCRIPT); - $$->e.e_script = dumb_ptr<const ScriptBuffer>(parse_script($1.c_str(), @1.first_line).release()); + $$->e.e_script = dumb_ptr<const ScriptBuffer>(parse_script(ZString($1), @1.first_line).release()); $1.delete_(); if ($$->e.e_script == NULL) fail(@1.first_line, @1.first_column, "Failed to compile script\n"); @@ -1098,9 +1102,8 @@ effect_list %% -size_t intern_id(const_string id_name_) +size_t intern_id(ZString id_name) { - std::string id_name(id_name_.begin(), id_name_.end()); size_t i; for (i = 0; i < magic_conf.varv.size(); i++) if (id_name == magic_conf.varv[i].name) @@ -1173,18 +1176,17 @@ dumb_ptr<expr_t> dot_expr(dumb_ptr<expr_t> expr, int id) return retval; } -dumb_ptr<expr_t> fun_expr(const std::string& name, const_array<dumb_ptr<expr_t>> argv, int line, int column) +dumb_ptr<expr_t> fun_expr(FString name, const_array<dumb_ptr<expr_t>> argv, int line, int column) { - int id; dumb_ptr<expr_t> expr; - fun_t *fun = magic_get_fun(name, &id); + fun_t *fun = magic_get_fun(name); if (!fun) fail(line, column, "Unknown function `%s'\n", name.c_str()); - else if (strlen(fun->signature) != argv.size()) + else if (fun->signature.size() != argv.size()) { fail(line, column, "Incorrect number of arguments to function `%s': Expected %zu, found %zu\n", - name.c_str(), strlen(fun->signature), argv.size()); + name.c_str(), fun->signature.size(), argv.size()); fun = NULL; } @@ -1193,7 +1195,7 @@ dumb_ptr<expr_t> fun_expr(const std::string& name, const_array<dumb_ptr<expr_t>> expr = magic_new_expr(EXPR::FUNAPP); expr->e.e_funapp.line_nr = line; expr->e.e_funapp.column = column; - expr->e.e_funapp.id = id; + expr->e.e_funapp.funp = fun; assert (argv.size() <= MAX_ARGS); expr->e.e_funapp.args_nr = argv.size(); @@ -1212,10 +1214,7 @@ dumb_ptr<expr_t> fun_expr(const std::string& name, const_array<dumb_ptr<expr_t>> dumb_ptr<spell_t> new_spell(dumb_ptr<spellguard_t> guard) { - static int spell_counter = 0; - auto retval = dumb_ptr<spell_t>::make(); - retval->index_ = ++spell_counter; retval->spellguard = guard; return retval; } @@ -1288,18 +1287,17 @@ dumb_ptr<effect_t> set_effect_continuation(dumb_ptr<effect_t> src, dumb_ptr<effe return retval; } -dumb_ptr<effect_t> op_effect(const std::string& name, const_array<dumb_ptr<expr_t>> argv, int line, int column) +dumb_ptr<effect_t> op_effect(FString name, const_array<dumb_ptr<expr_t>> argv, int line, int column) { - int id; dumb_ptr<effect_t> effect; - op_t *op = magic_get_op(name, &id); + op_t *op = magic_get_op(name); if (!op) fail(line, column, "Unknown operation `%s'\n", name.c_str()); - else if (strlen(op->signature) != argv.size()) + else if (op->signature.size() != argv.size()) { fail(line, column, "Incorrect number of arguments to operation `%s': Expected %zu, found %zu\n", - name.c_str(), strlen(op->signature), argv.size()); + name.c_str(), op->signature.size(), argv.size()); op = NULL; } @@ -1308,7 +1306,7 @@ dumb_ptr<effect_t> op_effect(const std::string& name, const_array<dumb_ptr<expr_ effect = new_effect(EFFECT::OP); effect->e.e_op.line_nr = line; effect->e.e_op.column = column; - effect->e.e_op.id = id; + effect->e.e_op.opp = op; assert (argv.size() <= MAX_ARGS); effect->e.e_op.args_nr = argv.size(); @@ -1321,7 +1319,7 @@ dumb_ptr<effect_t> op_effect(const std::string& name, const_array<dumb_ptr<expr_ } -std::map<std::string, proc_t> procs; +std::map<FString, proc_t> procs; // I think this was a memory leak (or undefined behavior) void install_proc(dumb_ptr<proc_t> proc) @@ -1329,9 +1327,8 @@ void install_proc(dumb_ptr<proc_t> proc) procs.insert({proc->name, std::move(*proc)}); } -dumb_ptr<effect_t> call_proc(const_string name_, dumb_ptr<std::vector<dumb_ptr<expr_t>>> argvp, int line_nr, int column) +dumb_ptr<effect_t> call_proc(ZString name, dumb_ptr<std::vector<dumb_ptr<expr_t>>> argvp, int line_nr, int column) { - std::string name(name_.begin(), name_.end()); auto pi = procs.find(name); if (pi == procs.end()) { @@ -1355,9 +1352,9 @@ dumb_ptr<effect_t> call_proc(const_string name_, dumb_ptr<std::vector<dumb_ptr<e return retval; } -std::map<std::string, val_t> const_defm; +std::map<FString, val_t> const_defm; -void bind_constant(const std::string& name, val_t *val, int line_nr) +void bind_constant(FString name, val_t *val, int line_nr) { if (!const_defm.insert({name, *val}).second) { @@ -1365,7 +1362,7 @@ void bind_constant(const std::string& name, val_t *val, int line_nr) } } -val_t *find_constant(const std::string& name) +val_t *find_constant(FString name) { auto it = const_defm.find(name); if (it != const_defm.end()) @@ -1379,7 +1376,7 @@ static int error_flag; inline -void INTERN_ASSERT(const char *name, int id) +void INTERN_ASSERT(ZString name, int id) { int zid = intern_id(name); if (zid != id) diff --git a/src/map/magic-interpreter.hpp b/src/map/magic-interpreter.hpp index 9b60d998..13c91e9 100644 --- a/src/map/magic-interpreter.hpp +++ b/src/map/magic-interpreter.hpp @@ -10,6 +10,8 @@ #include "script.hpp" #include "skill.t.hpp" +struct fun_t; +struct op_t; struct expr_t; struct val_t; struct location_t; @@ -118,7 +120,8 @@ struct expr_t e_area_t e_area; struct { - int id, line_nr, column; + fun_t *funp; + int line_nr, column; int args_nr; dumb_ptr<expr_t> args[MAX_ARGS]; } e_funapp; @@ -169,7 +172,7 @@ struct effect_t dumb_ptr<const ScriptBuffer> e_script; struct { - int id; + op_t *opp; int args_nr; int line_nr, column; dumb_ptr<expr_t> args[MAX_ARGS]; @@ -238,9 +241,8 @@ struct letdef_t struct spell_t { - std::string name; - std::string invocation; - int index_; // Relative location in the definitions file + FString name; + FString invocation; SPELL_FLAG flags; int arg; SPELLARG spellarg_ty; @@ -256,8 +258,8 @@ struct spell_t struct teleport_anchor_t { - std::string name; - std::string invocation; + FString name; + FString invocation; dumb_ptr<expr_t> location; }; @@ -269,15 +271,15 @@ struct magic_conf_t { struct mcvar { - std::string name; + FString name; val_t val; }; // This should probably be done by a dedicated "intern pool" class std::vector<mcvar> varv; - std::map<std::string, dumb_ptr<spell_t>> spells_by_name, spells_by_invocation; + std::map<FString, dumb_ptr<spell_t>> spells_by_name, spells_by_invocation; - std::map<std::string, dumb_ptr<teleport_anchor_t>> anchors_by_name, anchors_by_invocation; + std::map<FString, dumb_ptr<teleport_anchor_t>> anchors_by_name, anchors_by_invocation; }; /* Execution environment */ @@ -390,10 +392,10 @@ extern env_t magic_default_env; /* Fake default environment */ */ void magic_add_component(dumb_ptr<component_t> *component_holder, int id, int count); -dumb_ptr<teleport_anchor_t> magic_find_anchor(const std::string& name); +dumb_ptr<teleport_anchor_t> magic_find_anchor(XString name); dumb_ptr<env_t> spell_create_env(magic_conf_t *conf, dumb_ptr<spell_t> spell, - dumb_ptr<map_session_data> caster, int spellpower, const_string param); + dumb_ptr<map_session_data> caster, int spellpower, XString param); void magic_free_env(dumb_ptr<env_t> env); @@ -419,7 +421,7 @@ int spell_unbind(dumb_ptr<map_session_data> subject, dumb_ptr<invocation> invoca */ dumb_ptr<invocation> spell_clone_effect(dumb_ptr<invocation> source); -dumb_ptr<spell_t> magic_find_spell(const std::string& invocation); +dumb_ptr<spell_t> magic_find_spell(XString invocation); /* The following is used only by the parser: */ struct args_rec_t @@ -429,7 +431,7 @@ struct args_rec_t struct proc_t { - std::string name; + FString name; std::vector<int> argv; dumb_ptr<effect_t> body; diff --git a/src/map/magic-stmt.cpp b/src/map/magic-stmt.cpp index 5d732c8..6b013ab 100644 --- a/src/map/magic-stmt.cpp +++ b/src/map/magic-stmt.cpp @@ -276,7 +276,7 @@ dumb_ptr<npc_data> local_spell_effect(map_local *m, int x, int y, int effect, /* 1 minute should be enough for all interesting spell effects, I hope */ std::chrono::seconds delay = std::chrono::seconds(30); dumb_ptr<npc_data> effect_npc = npc_spawn_text(m, x, y, - INVISIBLE_NPC, "", "?"); + INVISIBLE_NPC, NpcName(), "?"); int effect_npc_id = effect_npc->bl_id; entity_effect(effect_npc, effect, tdelay); @@ -415,8 +415,9 @@ int op_messenger_npc(dumb_ptr<env_t>, const_array<val_t> args) dumb_ptr<npc_data> npc; location_t *loc = &ARGLOCATION(0); + NpcName npcname = stringish<NpcName>(ARGSTR(2)); npc = npc_spawn_text(loc->m, loc->x, loc->y, - ARGINT(1), ARGSTR(2).c_str(), ARGSTR(3).c_str()); + ARGINT(1), npcname, ARGSTR(3)); Timer(gettick() + static_cast<interval_t>(ARGINT(4)), std::bind(timer_callback_kill_npc, ph::_1, ph::_2, @@ -446,13 +447,13 @@ void entity_warp(dumb_ptr<block_list> target, map_local *destm, int destx, int d pc_touch_all_relevant_npcs(character); // Note that touching NPCs may have triggered warping and thereby updated x and y: - const char *map_name = character->bl_m->name_; + MapName map_name = character->bl_m->name_; // Warp part #1: update relevant data, interrupt trading etc.: pc_setpos(character, map_name, character->bl_x, character->bl_y, BeingRemoveWhy::GONE); // Warp part #2: now notify the client clif_changemap(character, map_name, - character->bl_x, character->bl_y); + character->bl_x, character->bl_y); break; } case BL::MOB: @@ -688,8 +689,8 @@ int op_spawn(dumb_ptr<env_t>, const_array<val_t> args) int mob_id; dumb_ptr<mob_data> mob; - mob_id = mob_once_spawn(owner, loc.m->name_, loc.x, loc.y, "--ja--", // Is that needed? - monster_id, 1, ""); + mob_id = mob_once_spawn(owner, loc.m->name_, loc.x, loc.y, JAPANESE_NAME, // Is that needed? + monster_id, 1, NpcEvent()); mob = map_id_as_mob(mob_id); @@ -823,7 +824,8 @@ int op_set_script_variable(dumb_ptr<env_t>, const_array<val_t> args) if (!c) return 1; - pc_setglobalreg(c, ARGSTR(1).c_str(), ARGINT(2)); + VarName varname = stringish<VarName>(ARGSTR(1)); + pc_setglobalreg(c, varname, ARGINT(2)); return 0; } @@ -893,73 +895,43 @@ int op_gain_exp(dumb_ptr<env_t>, const_array<val_t> args) return 0; } +#define MAGIC_OPERATION(name, args, impl) {{name}, {{name}, {args}, impl}} +#define MAGIC_OPERATION1(name, args) MAGIC_OPERATION(#name, args, op_##name) static -op_t operations[] = -{ - {"sfx", ".ii", op_sfx}, - {"instaheal", "eii", op_instaheal}, - {"itemheal", "eii", op_itemheal}, - {"shroud", "ei", op_shroud}, - {"unshroud", "e", op_reveal}, - {"message", "es", op_message}, - {"messenger_npc", "lissi", op_messenger_npc}, - {"move", "ed", op_move}, - {"warp", "el", op_warp}, - {"banish", "e", op_banish}, - {"status_change", "eiiiiii", op_status_change}, - {"stop_status_change", "ei", op_stop_status_change}, - {"override_attack", "eiiiiii", op_override_attack}, - {"create_item", "e.i", op_create_item}, - {"aggravate", "eie", op_aggravate}, - {"spawn", "aeiiii", op_spawn}, - {"injure", "eeii", op_injure}, - {"emote", "ei", op_emote}, - {"set_script_variable", "esi", op_set_script_variable}, - {"set_hair_colour", "ei", op_set_hair_colour}, - {"set_hair_style", "ei", op_set_hair_style}, - {"drop_item", "l.ii", op_drop_item_for}, - {"drop_item_for", "l.iiei", op_drop_item_for}, - {"gain_experience", "eiii", op_gain_exp}, - {NULL, NULL, NULL} +std::map<ZString, op_t> operations = +{ + MAGIC_OPERATION1(sfx, ".ii"), + MAGIC_OPERATION1(instaheal, "eii"), + MAGIC_OPERATION1(itemheal, "eii"), + MAGIC_OPERATION1(shroud, "ei"), + MAGIC_OPERATION("unshroud", "e", op_reveal), + MAGIC_OPERATION1(message, "es"), + MAGIC_OPERATION1(messenger_npc, "lissi"), + MAGIC_OPERATION1(move, "ed"), + MAGIC_OPERATION1(warp, "el"), + MAGIC_OPERATION1(banish, "e"), + MAGIC_OPERATION1(status_change, "eiiiiii"), + MAGIC_OPERATION1(stop_status_change, "ei"), + MAGIC_OPERATION1(override_attack, "eiiiiii"), + MAGIC_OPERATION1(create_item, "e.i"), + MAGIC_OPERATION1(aggravate, "eie"), + MAGIC_OPERATION1(spawn, "aeiiii"), + MAGIC_OPERATION1(injure, "eeii"), + MAGIC_OPERATION1(emote, "ei"), + MAGIC_OPERATION1(set_script_variable, "esi"), + MAGIC_OPERATION1(set_hair_colour, "ei"), + MAGIC_OPERATION1(set_hair_style, "ei"), + MAGIC_OPERATION("drop_item", "l.ii", op_drop_item_for), + MAGIC_OPERATION1(drop_item_for, "l.iiei"), + MAGIC_OPERATION("gain_experience", "eiii", op_gain_exp), }; -static -int operations_sorted = 0; -static -int operation_count; - -static __attribute__((deprecated)) -int compare_operations(const void *lhs, const void *rhs) -{ - return strcmp(static_cast<const op_t *>(lhs)->name, static_cast<const op_t *>(rhs)->name); -} - -op_t *magic_get_op(const std::string& name, int *index) +op_t *magic_get_op(ZString name) { - op_t key; - - if (!operations_sorted) - { - op_t *opc = operations; - - while (opc->name) - ++opc; - - operation_count = opc - operations; - - qsort(operations, operation_count, sizeof(op_t), - compare_operations); - operations_sorted = 1; - } - - key.name = name.c_str(); - op_t *op = static_cast<op_t *>(bsearch(&key, operations, operation_count, sizeof(op_t), - compare_operations)); - - if (op && index) - *index = op - operations; - - return op; + auto it = operations.find(name); + if (it == operations.end()) + return nullptr; + return &it->second; } void spell_effect_report_termination(int invocation_id, int bl_id, @@ -1443,11 +1415,12 @@ interval_t spell_run(dumb_ptr<invocation> invocation_, int allow_delete) if (caster) { dumb_ptr<env_t> env = invocation_->env; - argrec_t arg[] = + ZString caster_name = (caster ? caster->status.name : CharName()).to__actual(); + argrec_t arg[3] = { {"@target", env->VAR(VAR_TARGET).ty == TYPE::ENTITY ? 0 : env->VAR(VAR_TARGET).v.v_int}, {"@caster", invocation_->caster}, - {"@caster_name$", caster ? caster->status.name : ""}, + {"@caster_name$", caster_name}, }; int message_recipient = env->VAR(VAR_SCRIPTTARGET).ty == @@ -1461,14 +1434,13 @@ interval_t spell_run(dumb_ptr<invocation> invocation_, int allow_delete) if (!invocation_->script_pos) // first time running this script? clif_spawn_fake_npc_for_player(recipient, - invocation_->bl_id); + invocation_->bl_id); // We have to do this or otherwise the client won't think that it's // dealing with an NPC int newpos = run_script_l( ScriptPointer(&*e->e.e_script, invocation_->script_pos), - message_recipient, - invocation_->bl_id, + message_recipient, invocation_->bl_id, 3, arg); /* Returns the new script position, or -1 once the script is finished */ if (newpos != -1) @@ -1492,7 +1464,7 @@ interval_t spell_run(dumb_ptr<invocation> invocation_, int allow_delete) case EFFECT::OP: { - op_t *op = &operations[e->e.e_op.id]; + op_t *op = e->e.e_op.opp; val_t args[MAX_ARGS]; for (i = 0; i < e->e.e_op.args_nr; i++) diff --git a/src/map/magic.cpp b/src/map/magic.cpp index e225830..9c07dd1 100644 --- a/src/map/magic.cpp +++ b/src/map/magic.cpp @@ -12,31 +12,29 @@ /// Return a pair of strings, {spellname, parameter} /// Parameter may be empty. static -std::pair<std::string, std::string> magic_tokenise(std::string src) +std::pair<XString, XString> magic_tokenise(XString src) { - std::string retval = std::move(src); - const std::string::iterator rvb = retval.begin(), rve = retval.end(); - std::string::iterator seeker = std::find(rvb, rve, ' '); + auto seeker = std::find(src.begin(), src.end(), ' '); - if (seeker == retval.end()) + if (seeker == src.end()) { - return {retval, std::string()}; + return {src, XString()}; } else { - std::string rv1(rvb, seeker); + XString rv1 = src.xislice_h(seeker); ++seeker; - while (seeker != rve && *seeker == ' ') + while (seeker != src.end() && *seeker == ' ') ++seeker; // Note: this very well could be empty - std::string rv2(seeker, rve); + XString rv2 = src.xislice_t(seeker); return {rv1, rv2}; } } -int magic_message(dumb_ptr<map_session_data> caster, const std::string& source_invocation) +int magic_message(dumb_ptr<map_session_data> caster, XString source_invocation) { if (pc_isdead(caster)) return 0; @@ -52,8 +50,8 @@ int magic_message(dumb_ptr<map_session_data> caster, const std::string& source_i magic_unshroud(caster); auto pair = magic_tokenise(source_invocation); - std::string spell_invocation = std::move(pair.first); - std::string parameter = std::move(pair.second); + XString spell_invocation = pair.first; + XString parameter = pair.second; dumb_ptr<spell_t> spell = magic_find_spell(spell_invocation); diff --git a/src/map/magic.hpp b/src/map/magic.hpp index cec5bf4..5b10367 100644 --- a/src/map/magic.hpp +++ b/src/map/magic.hpp @@ -21,7 +21,7 @@ struct invocation; /* Spell invocation */ * \return 1 or -1 if the input message was magic and was handled by this function, 0 otherwise. -1 is returned when the * message should not be repeated. */ -int magic_message(dumb_ptr<map_session_data> caster, const std::string& source_invocation); +int magic_message(dumb_ptr<map_session_data> caster, XString source_invocation); /** * Removes the shroud from a character @@ -49,16 +49,16 @@ void do_init_magic(void); /** * Identifies the invocation used to trigger a spell * - * Returns NULL if not found + * Returns empty string if not found */ -const char *magic_find_invocation(const std::string& spellame); +FString magic_find_invocation(XString spellname); /** * Identifies the invocation used to denote a teleport location * - * Returns NULL if not found + * Returns empty string if not found */ -const char *magic_find_anchor_invocation(const std::string& teleport_location); +FString magic_find_anchor_invocation(XString teleport_location); /** * Execute a spell invocation and sets up timers to finish diff --git a/src/map/map.cpp b/src/map/map.cpp index fdae071..f2eefe5 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -15,6 +15,8 @@ #include "../common/core.hpp" #include "../common/cxxstdio.hpp" #include "../common/db.hpp" +#include "../common/extract.hpp" +#include "../common/io.hpp" #include "../common/random2.hpp" #include "../common/nullpo.hpp" #include "../common/socket.hpp" @@ -41,14 +43,14 @@ DMap<int, dumb_ptr<block_list>> id_db; -UPMap<std::string, map_abstract> maps_db; +UPMap<MapName, map_abstract> maps_db; static -DMap<std::string, dumb_ptr<map_session_data>> nick_db; +DMap<CharName, dumb_ptr<map_session_data>> nick_db; struct charid2nick { - char nick[24]; + CharName nick; int req_id; }; @@ -65,19 +67,25 @@ int first_free_object_id = 0, last_object_id = 0; interval_t autosave_interval = DEFAULT_AUTOSAVE_INTERVAL; int save_settings = 0xFFFF; -char motd_txt[256] = "conf/motd.txt"; -char help_txt[256] = "conf/help.txt"; +FString motd_txt = "conf/motd.txt"; +FString help_txt = "conf/help.txt"; -char wisp_server_name[24] = "Server"; // can be modified in char-server configuration file +CharName wisp_server_name = stringish<CharName>("Server"); // can be modified in char-server configuration file static -void map_delmap(const std::string& mapname); +void map_delmap(MapName mapname); void SessionDeleter::operator()(SessionData *sd) { really_delete1 static_cast<map_session_data *>(sd); } +bool extract(XString str, NpcEvent *ev) +{ + XString mid; + return extract(str, record<':'>(&ev->npc, &mid, &ev->label)) && !mid; +} + /*========================================== * 全map鯖総計での接続数設定 * (char鯖から送られてくる) @@ -740,13 +748,13 @@ int map_addflooritem(struct item *item_data, int amount, * charid_dbへ追加(返信待ちがあれば返信) *------------------------------------------ */ -void map_addchariddb(int charid, const char *name) +void map_addchariddb(int charid, CharName name) { struct charid2nick *p = charid_db.search(charid); if (p == NULL) p = charid_db.init(charid); - strzcpy(p->nick, name, 24); + p->nick = name; p->req_id = 0; } @@ -876,14 +884,14 @@ dumb_ptr<map_session_data> map_id2sd(int id) * char_id番号の名前を探す *------------------------------------------ */ -char *map_charid2nick(int id) +CharName map_charid2nick(int id) { struct charid2nick *p = charid_db.search(id); if (p == NULL) - return NULL; + return CharName(); if (p->req_id != 0) - return NULL; + return CharName(); return p->nick; } @@ -958,40 +966,21 @@ dumb_ptr<map_session_data> map_get_prev_session(dumb_ptr<map_session_data> d) * return map_session_data pointer or NULL *------------------------------------------ */ -dumb_ptr<map_session_data> map_nick2sd(const char *nick) +dumb_ptr<map_session_data> map_nick2sd(CharName nick) { - int i, quantity = 0, nicklen; - dumb_ptr<map_session_data> sd = NULL; - - if (nick == NULL) - return NULL; - - nicklen = strlen(nick); - - for (i = 0; i < fd_max; i++) + for (int i = 0; i < fd_max; i++) { if (!session[i]) continue; map_session_data *pl_sd = static_cast<map_session_data *>(session[i]->session_data.get()); if (pl_sd && pl_sd->state.auth) { - // Without case sensitive check (increase the number of similar character names found) - if (strncasecmp(pl_sd->status.name, nick, nicklen) == 0) { - // Strict comparison (if found, we finish the function immediatly with correct value) - if (strcmp(pl_sd->status.name, nick) == 0) + if (pl_sd->status.name == nick) return dumb_ptr<map_session_data>(pl_sd); - quantity++; - sd = dumb_ptr<map_session_data>(pl_sd); } } } - // Here, the exact character name is not found - // We return the found index of a similar account ONLY if there is 1 similar character - if (quantity == 1) - return sd; - - // Exact character name is not found and 0 or more than 1 similar characters have been found ==> we say not found return NULL; } @@ -1077,7 +1066,7 @@ void map_removenpc(void) * map名からmap番号へ変換 *------------------------------------------ */ -map_local *map_mapname2mapid(const char *name) +map_local *map_mapname2mapid(MapName name) { map_abstract *md = maps_db.get(name); if (md == NULL || md->gat == NULL) @@ -1089,7 +1078,7 @@ map_local *map_mapname2mapid(const char *name) * 他鯖map名からip,port変換 *------------------------------------------ */ -int map_mapname2ipport(const char *name, struct in_addr *ip, int *port) +int map_mapname2ipport(MapName name, struct in_addr *ip, int *port) { map_abstract *md = maps_db.get(name); if (md == NULL || md->gat) @@ -1198,14 +1187,14 @@ void map_setcell(map_local *m, int x, int y, MapCell t) * 他鯖管理のマップをdbに追加 *------------------------------------------ */ -int map_setipport(const char *name, struct in_addr ip, int port) +int map_setipport(MapName name, struct in_addr ip, int port) { map_abstract *md = maps_db.get(name); if (md == NULL) { // not exist -> add new data auto mdos = make_unique<map_remote>(); - strzcpy(mdos->name_, name, 16); + mdos->name_ = name; mdos->gat = NULL; mdos->ip = ip; mdos->port = port; @@ -1239,7 +1228,7 @@ int map_setipport(const char *name, struct in_addr ip, int port) *------------------------------------------ */ static -bool map_readmap(map_local *m, size_t num, const std::string& fn) +bool map_readmap(map_local *m, size_t num, MapName fn) { // read & convert fn std::vector<uint8_t> gat_v = grfio_reads(fn); @@ -1251,7 +1240,7 @@ bool map_readmap(map_local *m, size_t num, const std::string& fn) int ys = m->ys = gat_v[2] | gat_v[3] << 8; PRINTF("\rLoading Maps [%zu/%zu]: %-30s (%i, %i)", num, maps_db.size(), - std::string(fn.begin(), fn.end()), xs, ys); + fn, xs, ys); fflush(stdout); assert (s == xs * ys); @@ -1284,7 +1273,6 @@ int map_readallmap(void) for (auto& mit : maps_db) { - assert (strstr(mit.second->name_, ".gat") != NULL); { { map_local *ml = static_cast<map_local *>(mit.second.get()); @@ -1316,7 +1304,7 @@ int map_readallmap(void) *------------------------------------------ */ static -void map_addmap(const std::string& mapname) +void map_addmap(MapName mapname) { if (mapname == "clear") { @@ -1325,9 +1313,10 @@ void map_addmap(const std::string& mapname) } auto newmap = make_unique<map_local>(); - strzcpy(newmap->name_, mapname.c_str(), 16); - // novice challenge: figure out why this is necessary, and why it works - const char *name = newmap->name_; + newmap->name_ = mapname; + // novice challenge: figure out why this is necessary, + // and why the previous version worked + MapName name = newmap->name_; maps_db.put(name, std::move(newmap)); } @@ -1335,7 +1324,7 @@ void map_addmap(const std::string& mapname) * 読み込むmapを削除する *------------------------------------------ */ -void map_delmap(const std::string& mapname) +void map_delmap(MapName mapname) { if (mapname == "all") { @@ -1351,7 +1340,7 @@ constexpr int LOGFILE_SECONDS_PER_CHUNK_SHIFT = 10; static FILE *map_logfile = NULL; static -std::string map_logfile_name; +FString map_logfile_name; static long map_logfile_index; @@ -1360,7 +1349,7 @@ void map_close_logfile(void) { if (map_logfile) { - std::string filename = STRPRINTF("%s.%ld", map_logfile_name, map_logfile_index); + FString filename = STRPRINTF("%s.%ld", map_logfile_name, map_logfile_index); const char *args[] = { "gzip", @@ -1386,7 +1375,7 @@ void map_start_logfile(long index) { map_logfile_index = index; - std::string filename_buf = STRPRINTF( + FString filename_buf = STRPRINTF( "%s.%ld", map_logfile_name, map_logfile_index); @@ -1396,7 +1385,7 @@ void map_start_logfile(long index) } static -void map_set_logfile(std::string filename) +void map_set_logfile(FString filename) { struct timeval tv; @@ -1408,7 +1397,7 @@ void map_set_logfile(std::string filename) MAP_LOG("log-start v5"); } -void map_log(const_string line) +void map_log(XString line) { if (!map_logfile) return; @@ -1430,49 +1419,51 @@ void map_log(const_string line) *------------------------------------------ */ static -int map_config_read(const char *cfgName) +int map_config_read(ZString cfgName) { struct hostent *h = NULL; - std::ifstream in(cfgName); + std::ifstream in(cfgName.c_str()); if (!in.is_open()) { PRINTF("Map configuration file not found at: %s\n", cfgName); exit(1); } - std::string line; - while (std::getline(in, line)) + FString line; + while (io::getline(in, line)) { - std::string w1, w2; + SString w1; + TString w2; if (!split_key_value(line, &w1, &w2)) continue; if (w1 == "userid") { - chrif_setuserid(w2.c_str()); + AccountName name = stringish<AccountName>(w2); + chrif_setuserid(name); } else if (w1 == "passwd") { - chrif_setpasswd(w2.c_str()); + AccountPass pass = stringish<AccountPass>(w2); + chrif_setpasswd(pass); } else if (w1 == "char_ip") { h = gethostbyname(w2.c_str()); + IP_String w2ip; if (h != NULL) { - PRINTF("Character server IP address : %s -> %d.%d.%d.%d\n", - w2, - static_cast<uint8_t>(h->h_addr[0]), - static_cast<uint8_t>(h->h_addr[1]), - static_cast<uint8_t>(h->h_addr[2]), - static_cast<uint8_t>(h->h_addr[3])); - SPRINTF(w2, "%d.%d.%d.%d", - static_cast<uint8_t>(h->h_addr[0]), - static_cast<uint8_t>(h->h_addr[1]), - static_cast<uint8_t>(h->h_addr[2]), - static_cast<uint8_t>(h->h_addr[3])); + SNPRINTF(w2ip, 16, "%d.%d.%d.%d", + static_cast<uint8_t>(h->h_addr[0]), + static_cast<uint8_t>(h->h_addr[1]), + static_cast<uint8_t>(h->h_addr[2]), + static_cast<uint8_t>(h->h_addr[3])); + PRINTF("Character server IP address : %s -> %s\n", + w2, w2ip); } - chrif_setip(w2.c_str()); + else + w2ip = stringish<IP_String>(w2); + chrif_setip(w2ip); } else if (w1 == "char_port") { @@ -1481,20 +1472,20 @@ int map_config_read(const char *cfgName) else if (w1 == "map_ip") { h = gethostbyname(w2.c_str()); + IP_String w2ip; if (h != NULL) { - PRINTF("Map server IP address : %s -> %d.%d.%d.%d\n", w2, - static_cast<uint8_t>(h->h_addr[0]), - static_cast<uint8_t>(h->h_addr[1]), - static_cast<uint8_t>(h->h_addr[2]), - static_cast<uint8_t>(h->h_addr[3])); - SPRINTF(w2, "%d.%d.%d.%d", + SNPRINTF(w2ip, 16, "%d.%d.%d.%d", static_cast<uint8_t>(h->h_addr[0]), static_cast<uint8_t>(h->h_addr[1]), static_cast<uint8_t>(h->h_addr[2]), static_cast<uint8_t>(h->h_addr[3])); + PRINTF("Map server IP address : %s -> %s\n", + w2, w2ip); } - clif_setip(w2.c_str()); + else + w2ip = stringish<IP_String>(w2); + clif_setip(w2ip); } else if (w1 == "map_port") { @@ -1502,19 +1493,21 @@ int map_config_read(const char *cfgName) } else if (w1 == "map") { - map_addmap(w2.c_str()); + MapName name = VString<15>(w2); + map_addmap(name); } else if (w1 == "delmap") { - map_delmap(w2.c_str()); + MapName name = VString<15>(w2); + map_delmap(name); } else if (w1 == "npc") { - npc_addsrcfile(w2.c_str()); + npc_addsrcfile(w2); } else if (w1 == "delnpc") { - npc_delsrcfile(w2.c_str()); + npc_delsrcfile(w2); } else if (w1 == "autosave_time") { @@ -1524,15 +1517,15 @@ int map_config_read(const char *cfgName) } else if (w1 == "motd_txt") { - strzcpy(motd_txt, w2.c_str(), sizeof(motd_txt)); + motd_txt = w2; } else if (w1 == "help_txt") { - strzcpy(help_txt, w2.c_str(), sizeof(help_txt)); + help_txt = w2; } else if (w1 == "mapreg_txt") { - strzcpy(mapreg_txt, w2.c_str(), sizeof(mapreg_txt)); + mapreg_txt = w2; } else if (w1 == "gm_log") { @@ -1540,11 +1533,11 @@ int map_config_read(const char *cfgName) } else if (w1 == "log_file") { - map_set_logfile(w2.c_str()); + map_set_logfile(w2); } else if (w1 == "import") { - map_config_read(w2.c_str()); + map_config_read(w2); } } @@ -1632,26 +1625,26 @@ int compare_item(struct item *a, struct item *b) * Map-Server Init and Command-line Arguments [Valaris] *------------------------------------------------------ */ -int do_init(int argc, char *argv[]) +int do_init(int argc, ZString *argv) { int i; - const char *MAP_CONF_NAME = "conf/map_athena.conf"; - const char *BATTLE_CONF_FILENAME = "conf/battle_athena.conf"; - const char *ATCOMMAND_CONF_FILENAME = "conf/atcommand_athena.conf"; + ZString MAP_CONF_NAME = "conf/map_athena.conf"; + ZString BATTLE_CONF_FILENAME = "conf/battle_athena.conf"; + ZString ATCOMMAND_CONF_FILENAME = "conf/atcommand_athena.conf"; for (i = 1; i < argc; i++) { - if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "--h") == 0 - || strcmp(argv[i], "--?") == 0 || strcmp(argv[i], "/?") == 0) + if (argv[i] == "--help" || argv[i] == "-h" + || argv[i] == "-?" || argv[i] == "/?") map_helpscreen(); - else if (strcmp(argv[i], "--map_config") == 0) - MAP_CONF_NAME = argv[i + 1]; - else if (strcmp(argv[i], "--battle_config") == 0) - BATTLE_CONF_FILENAME = argv[i + 1]; - else if (strcmp(argv[i], "--atcommand_config") == 0) - ATCOMMAND_CONF_FILENAME = argv[i + 1]; + else if (argv[i] == "--map_config") + MAP_CONF_NAME = argv[++i]; + else if (argv[i] == "--battle_config") + BATTLE_CONF_FILENAME = argv[++i]; + else if (argv[i] == "--atcommand_config") + ATCOMMAND_CONF_FILENAME = argv[++i]; } map_config_read(MAP_CONF_NAME); diff --git a/src/map/map.hpp b/src/map/map.hpp index f0d0310..87bf1f9 100644 --- a/src/map/map.hpp +++ b/src/map/map.hpp @@ -8,9 +8,11 @@ #include <functional> #include <list> +#include "../common/cxxstdio.hpp" #include "../common/db.hpp" #include "../common/matrix.hpp" #include "../common/socket.hpp" +#include "../common/strings.hpp" #include "../common/timer.t.hpp" #include "battle.t.hpp" @@ -33,6 +35,38 @@ constexpr int MAX_DROP_PER_MAP = 48; constexpr interval_t DEFAULT_AUTOSAVE_INTERVAL = std::chrono::minutes(1); +// formerly VString<49>, as name::label +struct NpcEvent +{ + NpcName npc; + ScriptLabel label; + + explicit operator bool() + { + return npc || label; + } + bool operator !() + { + return !bool(*this); + } + + friend bool operator == (const NpcEvent& l, const NpcEvent& r) + { + return l.npc == r.npc && l.label == r.label; + } + + friend bool operator < (const NpcEvent& l, const NpcEvent& r) + { + return l.npc < r.npc || (l.npc == r.npc && l.label < r.label); + } + + friend VString<49> convert_for_printf(NpcEvent ev) + { + return STRNPRINTF(50, "%s::%s", ev.npc, ev.label); + } +}; +bool extract(XString str, NpcEvent *ev); + struct map_session_data; struct npc_data; struct mob_data; @@ -71,16 +105,6 @@ struct walkpath_data unsigned char path_len, path_pos, path_half; DIR path[MAX_WALKPATH]; }; -struct script_reg -{ - int index; - int data; -}; -struct script_regstr -{ - int index; - char data[256]; -}; struct status_change { Timer timer; @@ -92,7 +116,6 @@ struct invocation; struct npc_data; struct item_data; -struct square; struct quick_regeneration { // [Fate] @@ -141,7 +164,7 @@ struct map_session_data : block_list, SessionData earray<short, EQUIP, EQUIP::COUNT> equip_index; int weight, max_weight; int cart_weight, cart_max_weight, cart_num, cart_max_num; - char mapname_[16]; + MapName mapname_; int fd, new_fd; short to_x, to_y; interval_t speed; @@ -161,7 +184,7 @@ struct map_session_data : block_list, SessionData // but one should probably be replaced with a ScriptPointer ??? const ScriptBuffer *npc_script, *npc_scriptroot; std::vector<struct script_data> npc_stackbuf; - std::string npc_str; + FString npc_str; struct { unsigned storage:1; @@ -236,7 +259,7 @@ struct map_session_data : block_list, SessionData DMap<SIR, int> regm; // can't be DMap because we want predictable .c_str()s // This could change once FString ensures CoW. - Map<SIR, std::string> regstrm; + Map<SIR, FString> regstrm; earray<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data; short sc_count; @@ -252,15 +275,13 @@ struct map_session_data : block_list, SessionData int partyspy; // [Syrus22] - char message[80]; - int catch_target_class; int pvp_point, pvp_rank; Timer pvp_timer; int pvp_lastusers; - std::list<std::string> eventqueuel; + std::list<NpcEvent> eventqueuel; Timer eventtimer[MAX_EVENTTIMER]; struct @@ -272,7 +293,7 @@ struct map_session_data : block_list, SessionData TimeT chat_repeat_reset_due; int chat_lines_in; int chat_total_repeats; - char chat_lastmsg[513]; + FString chat_lastmsg; tick_t flood_rates[0x220]; TimeT packet_flood_reset_due; @@ -288,7 +309,7 @@ struct npc_timerevent_list }; struct npc_label_list { - char name[24]; + ScriptLabel name; int pos; }; struct npc_item_list @@ -307,15 +328,14 @@ struct npc_data : block_list short npc_class; DIR dir; interval_t speed; - char name[24]; - char exname[24]; + NpcName name; Opt1 opt1; Opt2 opt2; Opt3 opt3; Option option; short flag; - std::list<std::string> eventqueuel; + std::list<FString> eventqueuel; Timer eventtimer[MAX_EVENTTIMER]; short arenaflag; @@ -370,14 +390,14 @@ public: { short xs, ys; short x, y; - char name[16]; + MapName name; } warp; }; class npc_data_message : public npc_data { public: - std::string message; + FString message; }; constexpr int MOB_XP_BONUS_BASE = 1024; @@ -395,7 +415,7 @@ struct mob_data : block_list short x0, y0, xs, ys; interval_t delay1, delay2; } spawn; - char name[24]; + MobName name; struct { MS state; @@ -448,7 +468,7 @@ struct mob_data : block_list LevelElement def_ele; int master_id, master_dist; int exclusion_src, exclusion_party; - char npc_event[50]; + NpcEvent npc_event; // [Fate] mob-specific stats earray<unsigned short, mob_stat, mob_stat::LAST> stats; short size; @@ -461,14 +481,14 @@ struct BlockLists struct map_abstract { - char name_[16]; + MapName name_; // gat is NULL for map_remote and non-NULL or map_local std::unique_ptr<MapCell[]> gat; virtual ~map_abstract() {} }; extern -UPMap<std::string, map_abstract> maps_db; +UPMap<MapName, map_abstract> maps_db; struct map_local : map_abstract { @@ -537,10 +557,10 @@ struct flooritem_data : block_list extern interval_t autosave_interval; extern int save_settings; -extern char motd_txt[]; -extern char help_txt[]; +extern FString motd_txt; +extern FString help_txt; -extern char wisp_server_name[]; +extern CharName wisp_server_name; // 鯖全体情報 void map_setusers(int); @@ -587,13 +607,13 @@ void map_quit(dumb_ptr<map_session_data>); // npc int map_addnpc(map_local *, dumb_ptr<npc_data>); -void map_log(const_string line); +void map_log(XString line); #define MAP_LOG(format, ...) \ - map_log(static_cast<const std::string&>(STRPRINTF(format, ## __VA_ARGS__))) + map_log(STRPRINTF(format, ## __VA_ARGS__)) #define MAP_LOG_PC(sd, fmt, ...) \ MAP_LOG("PC%d %s:%d,%d " fmt, \ - sd->status.char_id, (sd->bl_m ? sd->bl_m->name_ : "undefined.gat"), sd->bl_x, sd->bl_y, ## __VA_ARGS__) + sd->status.char_id, (sd->bl_m ? sd->bl_m->name_ : stringish<MapName>("undefined.gat")), sd->bl_x, sd->bl_y, ## __VA_ARGS__) // 床アイテム関連 void map_clearflooritem_timer(TimerData *, tick_t, int); @@ -614,8 +634,8 @@ int map_addflooritem(struct item *, int, // キャラid=>キャラ名 変換関連 extern DMap<int, dumb_ptr<block_list>> id_db; -void map_addchariddb(int charid, const char *name); -char *map_charid2nick(int); +void map_addchariddb(int charid, CharName name); +CharName map_charid2nick(int); dumb_ptr<map_session_data> map_id2sd(int); dumb_ptr<block_list> map_id2bl(int); @@ -683,14 +703,14 @@ dumb_ptr<invocation> map_id_is_spell(int id) } -map_local *map_mapname2mapid(const char *); -int map_mapname2ipport(const char *, struct in_addr *, int *); -int map_setipport(const char *name, struct in_addr ip, int port); +map_local *map_mapname2mapid(MapName); +int map_mapname2ipport(MapName, struct in_addr *, int *); +int map_setipport(MapName name, struct in_addr ip, int port); void map_addiddb(dumb_ptr<block_list>); void map_deliddb(dumb_ptr<block_list> bl); void map_addnickdb(dumb_ptr<map_session_data>); int map_scriptcont(dumb_ptr<map_session_data> sd, int id); /* Continues a script either on a spell or on an NPC */ -dumb_ptr<map_session_data> map_nick2sd(const char *); +dumb_ptr<map_session_data> map_nick2sd(CharName); int compare_item(struct item *a, struct item *b); dumb_ptr<map_session_data> map_get_first_session(void); diff --git a/src/map/map.t.hpp b/src/map/map.t.hpp index d7b86ec..19f80c3 100644 --- a/src/map/map.t.hpp +++ b/src/map/map.t.hpp @@ -555,4 +555,9 @@ ENUM_BITWISE_OPERATORS(MapCell) } using e::MapCell; +struct MobName : VString<23> {}; +struct NpcName : VString<23> {}; +struct ScriptLabel : VString<23> {}; +struct ItemName : VString<23> {}; + #endif // MAP_T_HPP diff --git a/src/map/mob.cpp b/src/map/mob.cpp index 345f5a6..a2122d6 100644 --- a/src/map/mob.cpp +++ b/src/map/mob.cpp @@ -7,10 +7,13 @@ #include <cstring> #include <algorithm> +#include <fstream> #include "../common/cxxstdio.hpp" -#include "../common/random.hpp" +#include "../common/extract.hpp" +#include "../common/io.hpp" #include "../common/nullpo.hpp" +#include "../common/random.hpp" #include "../common/socket.hpp" #include "../common/timer.hpp" @@ -53,14 +56,13 @@ int mobskill_use_id(dumb_ptr<mob_data> md, dumb_ptr<block_list> target, * Mob is searched with a name. *------------------------------------------ */ -int mobdb_searchname(const char *str) +int mobdb_searchname(MobName str) { int i; for (i = 0; i < sizeof(mob_db) / sizeof(mob_db[0]); i++) { - if (strcasecmp(mob_db[i].name, str) == 0 - || strcmp(mob_db[i].jname, str) == 0) + if (mob_db[i].name == str || mob_db[i].jname == str) return i; } @@ -88,16 +90,16 @@ void mob_init(dumb_ptr<mob_data> md); *------------------------------------------ */ static -void mob_spawn_dataset(dumb_ptr<mob_data> md, const char *mobname, int mob_class) +void mob_spawn_dataset(dumb_ptr<mob_data> md, MobName mobname, int mob_class) { nullpo_retv(md); - if (strcmp(mobname, "--en--") == 0) - strzcpy(md->name, mob_db[mob_class].name, 24); - else if (strcmp(mobname, "--ja--") == 0) - strzcpy(md->name, mob_db[mob_class].jname, 24); + if (mobname == ENGLISH_NAME) + md->name = mob_db[mob_class].name; + else if (mobname == JAPANESE_NAME) + md->name = mob_db[mob_class].jname; else - strzcpy(md->name, mobname, 24); + md->name = mobname; md->bl_prev = NULL; md->bl_next = NULL; @@ -362,15 +364,16 @@ void mob_init(dumb_ptr<mob_data> md) * The MOB appearance for one time (for scripts) *------------------------------------------ */ -int mob_once_spawn(dumb_ptr<map_session_data> sd, const char *mapname, - int x, int y, const char *mobname, int mob_class, int amount, - const char *event) +int mob_once_spawn(dumb_ptr<map_session_data> sd, + MapName mapname, int x, int y, + MobName mobname, int mob_class, int amount, + NpcEvent event) { dumb_ptr<mob_data> md = NULL; map_local *m; int count, r = mob_class; - if (sd && strcmp(mapname, "this") == 0) + if (sd && mapname == MOB_THIS_MAP) m = sd->bl_m; else m = map_mapname2mapid(mapname); @@ -410,7 +413,7 @@ int mob_once_spawn(dumb_ptr<map_session_data> sd, const char *mapname, md->spawn.delay1 = static_cast<interval_t>(-1); // Only once is a flag. md->spawn.delay2 = static_cast<interval_t>(-1); // Only once is a flag. - strzcpy(md->npc_event, event, 50); + md->npc_event = event; md->bl_type = BL::MOB; map_addiddb(md); @@ -423,15 +426,15 @@ int mob_once_spawn(dumb_ptr<map_session_data> sd, const char *mapname, * The MOB appearance for one time (& area specification for scripts) *------------------------------------------ */ -int mob_once_spawn_area(dumb_ptr<map_session_data> sd, const char *mapname, - int x0, int y0, int x1, int y1, - const char *mobname, int mob_class, int amount, - const char *event) +int mob_once_spawn_area(dumb_ptr<map_session_data> sd, + MapName mapname, int x0, int y0, int x1, int y1, + MobName mobname, int mob_class, int amount, + NpcEvent event) { int x, y, i, max, lx = -1, ly = -1, id = 0; map_local *m; - if (strcmp(mapname, "this") == 0) + if (mapname == MOB_THIS_MAP) m = sd->bl_m; else m = map_mapname2mapid(mapname); @@ -2624,7 +2627,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, } // [MouseJstr] // SCRIPT実行 - if (md->npc_event[0]) + if (md->npc_event) { if (sd == NULL) { @@ -2877,7 +2880,7 @@ int mob_summonslave(dumb_ptr<mob_data> md2, int *value, int amount, int flag) y = by; } - mob_spawn_dataset(md, "--ja--", mob_class); + mob_spawn_dataset(md, JAPANESE_NAME, mob_class); md->bl_prev = NULL; md->bl_next = NULL; md->bl_m = m; @@ -2893,7 +2896,7 @@ int mob_summonslave(dumb_ptr<mob_data> md2, int *value, int amount, int flag) md->spawn.delay1 = static_cast<interval_t>(-1); // 一度のみフラグ md->spawn.delay2 = static_cast<interval_t>(-1); // 一度のみフラグ - strzcpy(md->npc_event, "", 50); + md->npc_event = NpcEvent(); md->bl_type = BL::MOB; map_addiddb(md); mob_spawn(md->bl_id); @@ -3341,8 +3344,8 @@ int mob_makedummymobdb(int mob_class) { int i; - sprintf(mob_db[mob_class].name, "mob%d", mob_class); - sprintf(mob_db[mob_class].jname, "mob%d", mob_class); + SNPRINTF(mob_db[mob_class].name, 24, "mob%d", mob_class); + SNPRINTF(mob_db[mob_class].jname, 24, "mob%d", mob_class); mob_db[mob_class].lv = 1; mob_db[mob_class].max_hp = 1000; mob_db[mob_class].max_sp = 1; @@ -3377,6 +3380,18 @@ int mob_makedummymobdb(int mob_class) return 0; } +static +bool extract(XString str, LevelElement *le) +{ + int tmp; + if (extract(str, &tmp)) + { + le->unpack(tmp); + return true; + } + return false; +} + /*========================================== * db/mob_db.txt reading *------------------------------------------ @@ -3384,57 +3399,95 @@ int mob_makedummymobdb(int mob_class) static int mob_readdb(void) { - FILE *fp; - char line[1024]; - const char *filename[] = { "db/mob_db.txt", "db/mob_db2.txt" }; + const char *filename = "db/mob_db.txt"; for (mob_db_& e : mob_db) e = mob_db_{}; - for (int j = 0; j < 2; j++) { - - fp = fopen_(filename[j], "r"); - if (fp == NULL) + std::ifstream in(filename); + if (!in.is_open()) { - if (j > 0) - continue; return -1; } - while (fgets(line, 1020, fp)) + FString line; + while (io::getline(in, line)) { int mob_class; - char *str[57], *p, *np; - if (line[0] == '/' && line[1] == '/') + if (line.startswith("//")) continue; + struct mob_db_ mdbv {}; + + XString ignore; + + extract(line, record<','>( + &mob_class, + lstripping(&mdbv.name), + lstripping(&mdbv.jname), + lstripping(&mdbv.lv), + lstripping(&mdbv.max_hp), + lstripping(&mdbv.max_sp), + lstripping(&mdbv.base_exp), + lstripping(&mdbv.job_exp), + lstripping(&mdbv.range), + lstripping(&mdbv.atk1), + lstripping(&mdbv.atk2), + lstripping(&mdbv.def), + lstripping(&mdbv.mdef), + lstripping(&mdbv.attrs[ATTR::STR]), + lstripping(&mdbv.attrs[ATTR::AGI]), + lstripping(&mdbv.attrs[ATTR::VIT]), + lstripping(&mdbv.attrs[ATTR::INT]), + lstripping(&mdbv.attrs[ATTR::DEX]), + lstripping(&mdbv.attrs[ATTR::LUK]), + lstripping(&mdbv.range2), + lstripping(&mdbv.range3), + lstripping(&mdbv.size), + lstripping(&mdbv.race), + lstripping(&mdbv.element), + lstripping(&mdbv.mode), + lstripping(&mdbv.speed), + lstripping(&mdbv.adelay), + lstripping(&mdbv.amotion), + lstripping(&mdbv.dmotion), + lstripping(&mdbv.dropitem[0].nameid), + lstripping(&mdbv.dropitem[0].p.num), + lstripping(&mdbv.dropitem[1].nameid), + lstripping(&mdbv.dropitem[1].p.num), + lstripping(&mdbv.dropitem[2].nameid), + lstripping(&mdbv.dropitem[2].p.num), + lstripping(&mdbv.dropitem[3].nameid), + lstripping(&mdbv.dropitem[3].p.num), + lstripping(&mdbv.dropitem[4].nameid), + lstripping(&mdbv.dropitem[4].p.num), + lstripping(&mdbv.dropitem[5].nameid), + lstripping(&mdbv.dropitem[5].p.num), + lstripping(&mdbv.dropitem[6].nameid), + lstripping(&mdbv.dropitem[6].p.num), + lstripping(&mdbv.dropitem[7].nameid), + lstripping(&mdbv.dropitem[7].p.num), + &ignore, + &ignore, + &ignore, + &ignore, + &ignore, + &ignore, + &ignore, + &ignore, + &ignore, + &ignore, + lstripping(&mdbv.mutations_nr), + lstripping(&mdbv.mutation_power) + ) + ); - p = line; - for (int i = 0; i < 57; i++) - { - while (*p == '\t' || *p == ' ') - p++; - if ((np = strchr(p, ',')) != NULL) - { - str[i] = p; - *np = 0; - p = np + 1; - } - else - str[i] = p; - } - - mob_class = atoi(str[0]); if (mob_class <= 1000 || mob_class > 2000) continue; - strzcpy(mob_db[mob_class].name, str[1], 24); - strzcpy(mob_db[mob_class].jname, str[2], 24); - mob_db[mob_class].lv = atoi(str[3]); - mob_db[mob_class].max_hp = atoi(str[4]); - mob_db[mob_class].max_sp = atoi(str[5]); + // TODO move this lower + mob_db[mob_class] = std::move(mdbv); - mob_db[mob_class].base_exp = atoi(str[6]); if (mob_db[mob_class].base_exp < 0) mob_db[mob_class].base_exp = 0; else if (mob_db[mob_class].base_exp > 0 @@ -3444,9 +3497,8 @@ int mob_readdb(void) battle_config.base_exp_rate / 100 < 0)) mob_db[mob_class].base_exp = 1000000000; else - mob_db[mob_class].base_exp *= battle_config.base_exp_rate / 100; + mob_db[mob_class].base_exp = mob_db[mob_class].base_exp * battle_config.base_exp_rate / 100; - mob_db[mob_class].job_exp = atoi(str[7]); if (mob_db[mob_class].job_exp < 0) mob_db[mob_class].job_exp = 0; else if (mob_db[mob_class].job_exp > 0 @@ -3456,40 +3508,16 @@ int mob_readdb(void) battle_config.job_exp_rate / 100 < 0)) mob_db[mob_class].job_exp = 1000000000; else - mob_db[mob_class].job_exp *= battle_config.job_exp_rate / 100; - - mob_db[mob_class].range = atoi(str[8]); - mob_db[mob_class].atk1 = atoi(str[9]); - mob_db[mob_class].atk2 = atoi(str[10]); - mob_db[mob_class].def = atoi(str[11]); - mob_db[mob_class].mdef = atoi(str[12]); - mob_db[mob_class].attrs[ATTR::STR] = atoi(str[13]); - mob_db[mob_class].attrs[ATTR::AGI] = atoi(str[14]); - mob_db[mob_class].attrs[ATTR::VIT] = atoi(str[15]); - mob_db[mob_class].attrs[ATTR::INT] = atoi(str[16]); - mob_db[mob_class].attrs[ATTR::DEX] = atoi(str[17]); - mob_db[mob_class].attrs[ATTR::LUK] = atoi(str[18]); - mob_db[mob_class].range2 = atoi(str[19]); - mob_db[mob_class].range3 = atoi(str[20]); - mob_db[mob_class].size = atoi(str[21]); // always 1 - mob_db[mob_class].race = static_cast<Race>(atoi(str[22])); - mob_db[mob_class].element = LevelElement::unpack(atoi(str[23])); - mob_db[mob_class].mode = static_cast<MobMode>(atoi(str[24])); - mob_db[mob_class].speed = atoi(str[25]); - mob_db[mob_class].adelay = atoi(str[26]); - mob_db[mob_class].amotion = atoi(str[27]); - mob_db[mob_class].dmotion = atoi(str[28]); + mob_db[mob_class].job_exp = mob_db[mob_class].job_exp * battle_config.job_exp_rate / 100; for (int i = 0; i < 8; i++) { - mob_db[mob_class].dropitem[i].nameid = atoi(str[29 + i * 2]); - int rate = atoi(str[30 + i * 2]); + int rate = mob_db[mob_class].dropitem[i].p.num; if (rate < 1) rate = 1; if (rate > 10000) rate = 10000; mob_db[mob_class].dropitem[i].p.num = rate; } - mob_db[mob_class].mutations_nr = atoi(str[55]); - mob_db[mob_class].mutation_power = atoi(str[56]); + mob_db[mob_class].skills.clear(); @@ -3506,22 +3534,14 @@ int mob_readdb(void) if (mob_db[mob_class].base_exp == 0) mob_db[mob_class].base_exp = mob_gen_exp(&mob_db[mob_class]); } - fclose_(fp); - PRINTF("read %s done\n", filename[j]); + PRINTF("read %s done\n", filename); } return 0; } -/*========================================== - * db/mob_skill_db.txt reading - *------------------------------------------ - */ -static -int mob_readskilldb(void) +template<> +bool extract<MobSkillCondition, void, void>(XString str, MobSkillCondition *msc) { - FILE *fp; - char line[1024]; - const struct { char str[32]; @@ -3534,6 +3554,18 @@ int mob_readskilldb(void) {"slavelt", MobSkillCondition::MSC_SLAVELT}, {"slavele", MobSkillCondition::MSC_SLAVELE}, }; + for (auto& pair : cond1) + if (str == pair.str) + { + *msc = pair.id; + return true; + } + return false; +} + +template<> +bool extract<MobSkillState, void, void>(XString str, MobSkillState *mss) +{ const struct { char str[32]; @@ -3545,6 +3577,18 @@ int mob_readskilldb(void) {"walk", MobSkillState::MSS_WALK}, {"attack", MobSkillState::MSS_ATTACK}, }; + for (auto& pair : state) + if (str == pair.str) + { + *mss = pair.id; + return true; + } + return false; +} + +template<> +bool extract<MobSkillTarget, void, void>(XString str, MobSkillTarget *mst) +{ const struct { char str[32]; @@ -3554,90 +3598,93 @@ int mob_readskilldb(void) {"target", MobSkillTarget::MST_TARGET}, {"self", MobSkillTarget::MST_SELF}, }; + for (auto& pair : target) + if (str == pair.str) + { + *mst = pair.id; + return true; + } + return false; +} - int x; - const char *filename[] = { "db/mob_skill_db.txt", "db/mob_skill_db2.txt" }; +/*========================================== + * db/mob_skill_db.txt reading + *------------------------------------------ + */ +static +int mob_readskilldb(void) +{ + const char *filename = "db/mob_skill_db.txt"; - for (x = 0; x < 2; x++) { - - fp = fopen_(filename[x], "r"); - if (fp == NULL) + std::ifstream in(filename); + if (!in.is_open()) { - if (x == 0) - PRINTF("can't read %s\n", filename[x]); - continue; + PRINTF("can't read %s\n", filename); + return 0; } - while (fgets(line, 1020, fp)) + FString line; + while (io::getline(in, line)) { int mob_id; - int j = 0; - - if (line[0] == '/' && line[1] == '/') - continue; - char *sp[20] {}; - char *p; - int i; - for (i = 0, p = line; i < 18 && p; i++) - { - sp[i] = p; - p = strchr(p, ','); - if (p != NULL) - *p++ = 0; - } - if ((mob_id = atoi(sp[0])) <= 0) + if (line.startswith("//")) continue; - if (strcmp(sp[1], "clear") == 0) + XString blah; + if (extract(line, record<','>(&mob_id, &blah)) && mob_id > 0 && blah == "clear") { mob_db[mob_id].skills.clear(); continue; } - mob_db[mob_id].skills.push_back(mob_skill{}); - struct mob_skill *ms = &mob_db[mob_id].skills.back(); - - ms->state = static_cast<MobSkillState>(atoi(sp[2])); - for (j = 0; j < sizeof(state) / sizeof(state[0]); j++) - { - if (strcmp(sp[2], state[j].str) == 0) - ms->state = state[j].id; - } - ms->skill_id = SkillID(atoi(sp[3])); - ms->skill_lv = atoi(sp[4]); - - ms->permillage = atoi(sp[5]); - ms->casttime = static_cast<interval_t>(atoi(sp[6])); - ms->delay = static_cast<interval_t>(atoi(sp[7])); - ms->cancel = atoi(sp[8]); - if (strcmp(sp[8], "yes") == 0) - ms->cancel = 1; - ms->target = static_cast<MobSkillTarget>(atoi(sp[9])); - for (j = 0; j < sizeof(target) / sizeof(target[0]); j++) - { - if (strcmp(sp[9], target[j].str) == 0) - ms->target = target[j].id; - } - ms->cond1 = MobSkillCondition::ANY; - for (j = 0; j < sizeof(cond1) / sizeof(cond1[0]); j++) - { - if (strcmp(sp[10], cond1[j].str) == 0) - ms->cond1 = cond1[j].id; - } - ms->cond2i = atoi(sp[11]); - ms->val[0] = atoi(sp[12]); - ms->val[1] = atoi(sp[13]); - ms->val[2] = atoi(sp[14]); - ms->val[3] = atoi(sp[15]); - ms->val[4] = atoi(sp[16]); - if (sp[17] != NULL && strlen(sp[17]) > 2) - ms->emotion = atoi(sp[17]); + struct mob_skill msv {}; + msv.emotion = -1; + int casttime, delay; + XString cancellable; + + if (!extract( + line, + record<',', 17>( + &mob_id, + &blah, + &msv.state, + &msv.skill_id, + &msv.skill_lv, + &msv.permillage, + &casttime, + &delay, + &cancellable, + &msv.target, + &msv.cond1, + &msv.cond2i, + &msv.val[0], + &msv.val[1], + &msv.val[2], + &msv.val[3], + &msv.val[4], + + &msv.emotion + ) + ) + ) + continue; + if (cancellable == "yes") + msv.cancel = true; + else if (cancellable == "no") + msv.cancel = false; else - ms->emotion = -1; + continue; + + msv.casttime = std::chrono::milliseconds(casttime); + msv.delay = std::chrono::milliseconds(delay); + + if (mob_id <= 0) + continue; + + mob_db[mob_id].skills.push_back(std::move(msv)); } - fclose_(fp); - PRINTF("read %s done\n", filename[x]); + PRINTF("read %s done\n", filename); } return 0; } diff --git a/src/map/mob.hpp b/src/map/mob.hpp index 66dbc53..bf53798 100644 --- a/src/map/mob.hpp +++ b/src/map/mob.hpp @@ -11,6 +11,10 @@ #include "map.hpp" #include "skill.t.hpp" +#define ENGLISH_NAME stringish<MobName>("--en--") +#define JAPANESE_NAME stringish<MobName>("--ja--") +#define MOB_THIS_MAP stringish<MapName>("this") + struct mob_skill { MobSkillState state; @@ -18,7 +22,7 @@ struct mob_skill short skill_lv; short permillage; interval_t casttime, delay; - short cancel; + bool cancel; MobSkillCondition cond1; int cond2i; MobSkillTarget target; @@ -28,7 +32,7 @@ struct mob_skill struct mob_db_ { - char name[24], jname[24]; + MobName name, jname; int lv; int max_hp, max_sp; int base_exp, job_exp; @@ -55,14 +59,16 @@ struct mob_db_ }; extern struct mob_db_ mob_db[]; -int mobdb_searchname(const char *str); +int mobdb_searchname(MobName str); int mobdb_checkid(const int id); int mob_once_spawn(dumb_ptr<map_session_data> sd, - const char *mapname, int x, int y, - const char *mobname, int class_, int amount, const char *event); + MapName mapname, int x, int y, + MobName mobname, int class_, int amount, + NpcEvent event); int mob_once_spawn_area(dumb_ptr<map_session_data> sd, - const char *mapname, int x0, int y0, int x1, int y1, - const char *mobname, int class_, int amount, const char *event); + MapName mapname, int x0, int y0, int x1, int y1, + MobName mobname, int class_, int amount, + NpcEvent event); int mob_target(dumb_ptr<mob_data> md, dumb_ptr<block_list> bl, int dist); int mob_stop_walking(dumb_ptr<mob_data> md, int type); diff --git a/src/map/npc.cpp b/src/map/npc.cpp index 68b5ad7..41f0966 100644 --- a/src/map/npc.cpp +++ b/src/map/npc.cpp @@ -9,6 +9,7 @@ #include "../common/cxxstdio.hpp" #include "../common/db.hpp" +#include "../common/extract.hpp" #include "../common/nullpo.hpp" #include "../common/socket.hpp" #include "../common/timer.hpp" @@ -25,7 +26,7 @@ #include "../poison.hpp" static -std::list<std::string> npc_srcs; +std::list<FString> npc_srcs; static int npc_id = START_NPC_NUM; @@ -43,9 +44,9 @@ struct event_data int pos; }; static -Map<std::string, struct event_data> ev_db; +Map<NpcEvent, struct event_data> ev_db; static -DMap<std::string, dumb_ptr<npc_data>> npcname_db; +DMap<NpcName, dumb_ptr<npc_data>> npcname_db; // used for clock-based event triggers // only tm_min, tm_hour, and tm_mday are used @@ -62,7 +63,6 @@ static void npc_enable_sub(dumb_ptr<block_list> bl, dumb_ptr<npc_data> nd) { dumb_ptr<map_session_data> sd; - char aname[50] {}; nullpo_retv(bl); @@ -74,16 +74,17 @@ void npc_enable_sub(dumb_ptr<block_list> bl, dumb_ptr<npc_data> nd) if (nd->flag & 1) return; - strzcpy(aname, nd->name, sizeof(nd->name)); + NpcEvent aname; + aname.npc = nd->name; + aname.label = stringish<ScriptLabel>("OnTouch"); if (sd->areanpc_id == nd->bl_id) return; sd->areanpc_id = nd->bl_id; - strcat(aname, "::OnTouch"); npc_event(sd, aname, 0); } } -int npc_enable(const char *name, bool flag) +int npc_enable(NpcName name, bool flag) { dumb_ptr<npc_data> nd = npcname_db.get(name); if (nd == NULL) @@ -121,7 +122,7 @@ int npc_enable(const char *name, bool flag) * NPCを名前で探す *------------------------------------------ */ -dumb_ptr<npc_data> npc_name2id(const char *name) +dumb_ptr<npc_data> npc_name2id(NpcName name) { return npcname_db.get(name); } @@ -138,7 +139,7 @@ int npc_event_dequeue(dumb_ptr<map_session_data> sd) if (!sd->eventqueuel.empty()) { - if (!pc_addeventtimer(sd, std::chrono::milliseconds(100), sd->eventqueuel.front().c_str())) + if (!pc_addeventtimer(sd, std::chrono::milliseconds(100), sd->eventqueuel.front())) { PRINTF("npc_event_dequeue(): Event timer is full.\n"); return 0; @@ -163,7 +164,7 @@ int npc_delete(dumb_ptr<npc_data> nd) return 0; } -int npc_timer_event(const char *eventname) // Added by RoVeRT +void npc_timer_event(NpcEvent eventname) { struct event_data *ev = ev_db.search(eventname); dumb_ptr<npc_data_script> nd; @@ -171,13 +172,12 @@ int npc_timer_event(const char *eventname) // Added by RoVeRT if ((ev == NULL || (nd = ev->nd) == NULL)) { - PRINTF("npc_event: event not found [%s]\n", eventname); - return 0; + PRINTF("npc_event: event not found [%s]\n", + eventname); + return; } run_script(ScriptPointer(nd->scr.script.get(), ev->pos), nd->bl_id, nd->bl_id); - - return 0; } /*========================================== @@ -185,55 +185,51 @@ int npc_timer_event(const char *eventname) // Added by RoVeRT *------------------------------------------ */ static -void npc_event_doall_sub(const std::string& key, struct event_data *ev, - int *c, const char *name, int rid, int argc, argrec_t *argv) +void npc_event_doall_sub(NpcEvent key, struct event_data *ev, + int *c, ScriptLabel name, int rid, int argc, argrec_t *argv) { - const char *p = key.c_str(); + ScriptLabel p = key.label; nullpo_retv(ev); - if ((p = strchr(p, ':')) && p && strcasecmp(name, p) == 0) + if (name == p) { - run_script_l(ScriptPointer(ev->nd->scr.script.get(), ev->pos), rid, ev->nd->bl_id, argc, - argv); + run_script_l(ScriptPointer(ev->nd->scr.script.get(), ev->pos), rid, ev->nd->bl_id, + argc, argv); (*c)++; } } -int npc_event_doall_l(const char *name, int rid, int argc, argrec_t *args) +int npc_event_doall_l(ScriptLabel name, int rid, int argc, argrec_t *args) { int c = 0; - char buf[64] = "::"; - strzcpy(buf + 2, name, 62); for (auto& pair : ev_db) - npc_event_doall_sub(pair.first, &pair.second, &c, buf, rid, argc, args); + npc_event_doall_sub(pair.first, &pair.second, &c, name, rid, argc, args); return c; } static -void npc_event_do_sub(const std::string& key, struct event_data *ev, - int *c, const char *name, int rid, int argc, argrec_t *argv) +void npc_event_do_sub(NpcEvent key, struct event_data *ev, + int *c, NpcEvent name, int rid, int argc, argrec_t *argv) { - const char *p = key.c_str(); - nullpo_retv(ev); - if (p && strcasecmp(name, p) == 0) + if (name == key) { - run_script_l(ScriptPointer(ev->nd->scr.script.get(), ev->pos), rid, ev->nd->bl_id, argc, - argv); + run_script_l(ScriptPointer(ev->nd->scr.script.get(), ev->pos), rid, ev->nd->bl_id, + argc, argv); (*c)++; } } -int npc_event_do_l(const char *name, int rid, int argc, argrec_t *args) +int npc_event_do_l(NpcEvent name, int rid, int argc, argrec_t *args) { int c = 0; - if (*name == ':' && name[1] == ':') + if (!name.npc) { - return npc_event_doall_l(name + 2, rid, argc, args); + return npc_event_doall_l(name.label, rid, argc, args); } for (auto& pair : ev_db) @@ -250,25 +246,23 @@ void npc_event_do_clock(TimerData *, tick_t) { struct tm t = TimeT::now(); + ScriptLabel buf; if (t.tm_min != ev_tm_b.tm_min) { - std::string buf; - buf = STRPRINTF("OnMinute%02d", t.tm_min); - npc_event_doall(buf.c_str()); - buf = STRPRINTF("OnClock%02d%02d", t.tm_hour, t.tm_min); - npc_event_doall(buf.c_str()); + SNPRINTF(buf, 24, "OnMinute%02d", t.tm_min); + npc_event_doall(buf); + SNPRINTF(buf, 24, "OnClock%02d%02d", t.tm_hour, t.tm_min); + npc_event_doall(buf); } if (t.tm_hour != ev_tm_b.tm_hour) { - std::string buf; - buf = STRPRINTF("OnHour%02d", t.tm_hour); - npc_event_doall(buf.c_str()); + SNPRINTF(buf, 24, "OnHour%02d", t.tm_hour); + npc_event_doall(buf); } if (t.tm_mday != ev_tm_b.tm_mday) { - std::string buf; - buf = STRPRINTF("OnDay%02d%02d", t.tm_mon + 1, t.tm_mday); - npc_event_doall(buf.c_str()); + SNPRINTF(buf, 24, "OnDay%02d%02d", t.tm_mon + 1, t.tm_mday); + npc_event_doall(buf); } ev_tm_b = t; } @@ -279,7 +273,7 @@ void npc_event_do_clock(TimerData *, tick_t) */ int npc_event_do_oninit(void) { - int c = npc_event_doall("OnInit"); + int c = npc_event_doall(stringish<ScriptLabel>("OnInit")); PRINTF("npc: OnInit Event done. (%d npc)\n", c); Timer(gettick() + std::chrono::milliseconds(100), @@ -414,41 +408,34 @@ void npc_settimerevent_tick(dumb_ptr<npc_data_script> nd, interval_t newtimer) * イベント型のNPC処理 *------------------------------------------ */ -int npc_event(dumb_ptr<map_session_data> sd, const char *eventname, - int mob_kill) +int npc_event(dumb_ptr<map_session_data> sd, NpcEvent eventname, + int mob_kill) { struct event_data *ev = ev_db.search(eventname); dumb_ptr<npc_data_script> nd; int xs, ys; - char mobevent[100]; if (sd == NULL) { PRINTF("npc_event nullpo?\n"); } - if (ev == NULL && eventname - && strcmp(((eventname) + strlen(eventname) - 9), "::OnTouch") == 0) + if (ev == NULL && eventname.label == stringish<ScriptLabel>("OnTouch")) return 1; if (ev == NULL || (nd = ev->nd) == NULL) { - if (mob_kill && (ev == NULL || (nd = ev->nd) == NULL)) + if (mob_kill) { - strcpy(mobevent, eventname); - strcat(mobevent, "::OnMyMobDead"); - ev = ev_db.search(mobevent); - if (ev == NULL || (nd = ev->nd) == NULL) { - if (strncasecmp(eventname, "GM_MONSTER", 10) != 0) - PRINTF("npc_event: event not found [%s]\n", mobevent); return 0; } } else { if (battle_config.error_log) - PRINTF("npc_event: event not found [%s]\n", eventname); + PRINTF("npc_event: event not found [%s]\n", + eventname); return 0; } } @@ -485,22 +472,19 @@ int npc_event(dumb_ptr<map_session_data> sd, const char *eventname, } static -void npc_command_sub(const std::string& key, struct event_data *ev, const char *npcname, const char *command) +void npc_command_sub(NpcEvent key, struct event_data *ev, NpcName npcname, XString command) { - const char *p = key.c_str(); - char temp[100]; - - if (strcmp(ev->nd->name, npcname) == 0 && (p = strchr(p, ':')) && p - && strncasecmp("::OnCommand", p, 10) == 0) + if (ev->nd->name == npcname + && key.label.startswith("OnCommand")) { - sscanf(&p[11], "%s", temp); + XString temp = key.label.xslice_t(9); - if (strcmp(command, temp) == 0) + if (command == temp) run_script(ScriptPointer(ev->nd->scr.script.get(), ev->pos), 0, ev->nd->bl_id); } } -int npc_command(dumb_ptr<map_session_data>, const char *npcname, const char *command) +int npc_command(dumb_ptr<map_session_data>, NpcName npcname, XString command) { for (auto& pair : ev_db) npc_command_sub(pair.first, &pair.second, npcname, command); @@ -575,14 +559,14 @@ int npc_touch_areanpc(dumb_ptr<map_session_data> sd, map_local *m, int x, int y) break; case NpcSubtype::SCRIPT: { - char aname[50] {}; - strzcpy(aname, m->npc[i]->name, 24); + NpcEvent aname; + aname.npc = m->npc[i]->name; + aname.label = stringish<ScriptLabel>("OnTouch"); if (sd->areanpc_id == m->npc[i]->bl_id) return 1; sd->areanpc_id = m->npc[i]->bl_id; - strcat(aname, "::OnTouch"); if (npc_event(sd, aname, 0) > 0) npc_click(sd, m->npc[i]->bl_id); break; @@ -658,9 +642,9 @@ int npc_click(dumb_ptr<map_session_data> sd, int id) sd->npc_pos = run_script(ScriptPointer(nd->as_script()->scr.script.get(), 0), sd->bl_id, id); break; case NpcSubtype::MESSAGE: - if (!nd->as_message()->message.empty()) + if (nd->as_message()->message) { - clif_scriptmes(sd, id, nd->as_message()->message.c_str()); + clif_scriptmes(sd, id, nd->as_message()->message); clif_scriptclose(sd, id); } break; @@ -893,9 +877,9 @@ void npc_clearsrcfile(void) * 読み込むnpcファイルの追加 *------------------------------------------ */ -void npc_addsrcfile(const char *name) +void npc_addsrcfile(FString name) { - if (strcasecmp(name, "clear") == 0) + if (name == "clear") { npc_clearsrcfile(); return; @@ -908,9 +892,9 @@ void npc_addsrcfile(const char *name) * 読み込むnpcファイルの削除 *------------------------------------------ */ -void npc_delsrcfile(const char *name) +void npc_delsrcfile(FString name) { - if (strcasecmp(name, "all") == 0) + if (name == "all") { npc_clearsrcfile(); return; @@ -930,17 +914,15 @@ void npc_delsrcfile(const char *name) * warp行解析 *------------------------------------------ */ -int npc_parse_warp(const char *w1, const char *, const char *w3, const char *w4) +int npc_parse_warp(XString w1, XString, NpcName w3, XString w4) { int x, y, xs, ys, to_x, to_y; int i, j; - char mapname[24], to_mapname[24]; + MapName mapname, to_mapname; dumb_ptr<npc_data_warp> nd; - // 引数の個数チェック - if (sscanf(w1, "%[^,],%d,%d", mapname, &x, &y) != 3 || - sscanf(w4, "%d,%d,%[^,],%d,%d", &xs, &ys, to_mapname, &to_x, - &to_y) != 5) + if (!extract(w1, record<','>(&mapname, &x, &y)) || + !extract(w4, record<','>(&xs, &ys, &to_mapname, &to_x, &to_y))) { PRINTF("bad warp line : %s\n", w3); return 1; @@ -958,8 +940,7 @@ int npc_parse_warp(const char *w1, const char *, const char *w3, const char *w4) nd->bl_y = y; nd->dir = DIR::S; nd->flag = 0; - strzcpy(nd->name, w3, 24); - strzcpy(nd->exname, w3, 24); + nd->name = w3; if (!battle_config.warp_point_debug) nd->npc_class = WARP_CLASS; @@ -970,7 +951,7 @@ int npc_parse_warp(const char *w1, const char *, const char *w3, const char *w4) nd->opt1 = Opt1::ZERO; nd->opt2 = Opt2::ZERO; nd->opt3 = Opt3::ZERO; - strzcpy(nd->warp.name, to_mapname, 16); + nd->warp.name = to_mapname; xs += 2; ys += 2; nd->warp.x = to_x; @@ -1004,24 +985,51 @@ int npc_parse_warp(const char *w1, const char *, const char *w3, const char *w4) return 0; } +static +bool extract(XString xs, npc_item_list *itv) +{ + XString name_or_id; + if (!extract(xs, record<':'>(&name_or_id, &itv->value))) + return false; + struct item_data *id = nullptr; + if (extract(name_or_id, &itv->nameid) && itv->nameid > 0) + goto return_true; + + id = itemdb_searchname(stringish<ItemName>(name_or_id.rstrip())); + if (id == NULL) + return false; + itv->nameid = id->nameid; + goto return_true; + +return_true: + if (itv->value < 0) + { + if (id == NULL) + id = itemdb_search(itv->nameid); + itv->value = id->value_buy * abs(itv->value); + } + return true; +} + /*========================================== * shop行解析 *------------------------------------------ */ static -int npc_parse_shop(char *w1, char *, char *w3, char *w4) +int npc_parse_shop(XString w1, XString, NpcName w3, ZString w4a) { - char *p; int x, y; DIR dir; - char mapname[24]; + MapName mapname; dumb_ptr<npc_data_shop> nd; + ZString::iterator w4comma; + int npc_class; - // 引数の個数チェック - int dir_; // TODO use SSCANF or extract - if (sscanf(w1, "%[^,],%d,%d,%d", mapname, &x, &y, &dir_) != 4 + int dir_; // TODO use enum directly in extract + if (!extract(w1, record<','>(&mapname, &x, &y, &dir_)) || dir_ < 0 || dir_ >= 8 - || strchr(w4, ',') == NULL) + || (w4comma = std::find(w4a.begin(), w4a.end(), ',')) == w4a.end() + || !extract(w4a.xislice_h(w4comma), &npc_class)) { PRINTF("bad shop line : %s\n", w3); return 1; @@ -1030,44 +1038,15 @@ int npc_parse_shop(char *w1, char *, char *w3, char *w4) map_local *m = map_mapname2mapid(mapname); nd.new_(); - p = strchr(w4, ','); + ZString w4b = w4a.xislice_t(w4comma + 1); - while (p) + if (!extract(w4b, vrec<','>(&nd->shop_items))) { - int nameid, value; - char name[24]; - struct item_data *id = NULL; - p++; - if (sscanf(p, "%d:%d", &nameid, &value) == 2) - { - } - else if (sscanf(p, "%s :%d", name, &value) == 2) - { - id = itemdb_searchname(name); - if (id == NULL) - nameid = -1; - else - nameid = id->nameid; - } - else - break; - - if (nameid > 0) - { - npc_item_list sh_it; - sh_it.nameid = nameid; - if (value < 0) - { - if (id == NULL) - id = itemdb_search(nameid); - value = id->value_buy * abs(value); - - } - sh_it.value = value; - nd->shop_items.push_back(sh_it); - } - p = strchr(p, ','); + PRINTF("bad shop items : %s\n", w3); + PRINTF(" somewhere --> %s\n", w4b); + nd->shop_items.clear(); } + if (nd->shop_items.empty()) { nd.delete_(); @@ -1081,15 +1060,14 @@ int npc_parse_shop(char *w1, char *, char *w3, char *w4) nd->bl_id = npc_get_new_npc_id(); nd->dir = dir; nd->flag = 0; - strzcpy(nd->name, w3, 24); - nd->npc_class = atoi(w4); + nd->name = w3; + nd->npc_class = npc_class; nd->speed = std::chrono::milliseconds(200); nd->option = Option::ZERO; nd->opt1 = Opt1::ZERO; nd->opt2 = Opt2::ZERO; nd->opt3 = Opt3::ZERO; - //PRINTF("shop npc %s %d read done\n",mapname,nd->bl_id); npc_shop++; nd->bl_type = BL::NPC; nd->npc_subtype = NpcSubtype::SHOP; @@ -1106,12 +1084,12 @@ int npc_parse_shop(char *w1, char *, char *w3, char *w4) *------------------------------------------ */ static -void npc_convertlabel_db(const std::string& lname, int pos, dumb_ptr<npc_data_script> nd) +void npc_convertlabel_db(ScriptLabel lname, int pos, dumb_ptr<npc_data_script> nd) { nullpo_retv(nd); struct npc_label_list eln {}; - strzcpy(eln.name, lname.c_str(), sizeof(eln.name)); + eln.name = lname; eln.pos = pos; nd->scr.label_listv.push_back(std::move(eln)); } @@ -1121,20 +1099,19 @@ void npc_convertlabel_db(const std::string& lname, int pos, dumb_ptr<npc_data_sc *------------------------------------------ */ static -int npc_parse_script(char *w1, char *w2, char *w3, char *w4, - const char *first_line, FILE * fp, int *lines) +int npc_parse_script(XString w1, XString w2, NpcName w3, ZString w4, + XString first_line, FILE *fp, int *lines) { int x, y; DIR dir = DIR::S; map_local *m; int xs = 0, ys = 0, npc_class = 0; // [Valaris] thanks to fov - char mapname[24]; + MapName mapname; std::unique_ptr<const ScriptBuffer> script = NULL; dumb_ptr<npc_data_script> nd; int evflag = 0; - char *p; - if (strcmp(w1, "-") == 0) + if (w1 == "-") { x = 0; y = 0; @@ -1142,11 +1119,10 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4, } else { - // 引数の個数チェック - int dir_; // TODO use SSCANF or extract - if (sscanf(w1, "%[^,],%d,%d,%d", mapname, &x, &y, &dir_) != 4 + int dir_; // TODO use enum directly in extract + if (!extract(w1, record<','>(&mapname, &x, &y, &dir_)) || dir_ < 0 || dir_ >= 8 - || (strcmp(w2, "script") == 0 && strchr(w4, ',') == NULL)) + || (w2 == "script" && !w4.contains(','))) { PRINTF("bad script line : %s\n", w3); return 1; @@ -1155,29 +1131,33 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4, m = map_mapname2mapid(mapname); } - if (strcmp(w2, "script") == 0) + if (w2 == "script") { // may be empty - std::string srcbuf = strchrnul(first_line, '{'); + MString srcbuf; + srcbuf += first_line.xislice_t(std::find(first_line.begin(), first_line.end(), '{')); // Note: it was a bug that this was missing. I think. int startline = *lines; - while (1) + // while (!srcbuf.rstrip().endswith('}')) + while (true) { - size_t i = srcbuf.find_last_not_of(" \t\n\r\f\v"); - if (i != std::string::npos && srcbuf[i] == '}') + auto it = std::find_if_not(srcbuf.rbegin(), srcbuf.rend(), [](char c){ return c == ' ' || c == '\n'; }); + if (it != srcbuf.rend() && *it == '}') break; - char line[1024]; - if (!fgets(line, 1020, fp)) + + char line_[1024]; + if (!fgets(line_, 1020, fp)) // eof break; (*lines)++; if (feof(fp)) break; - if (srcbuf.empty()) + ZString line(ZString::really_construct_from_a_pointer, line_, nullptr); + if (!srcbuf) { // may be a no-op - srcbuf = strchrnul(line, '{'); + srcbuf += line.xislice_t(std::find(line.begin(), line.end(), '{')); // safe to execute more than once // But will usually only happen once startline = *lines; @@ -1185,7 +1165,7 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4, else srcbuf += line; } - script = parse_script(srcbuf.c_str(), startline); + script = parse_script(FString(srcbuf), startline); if (script == NULL) // script parse error? return 1; @@ -1200,13 +1180,9 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4, if (m == nullptr) { - // スクリプトコピー用のダミーNPC } - else if (sscanf(w4, "%d,%d,%d", &npc_class, &xs, &ys) == 3) + else if (extract(w4, record<','>(&npc_class, &xs, &ys))) { - // 接触型NPC - int i, j; - if (xs >= 0) xs = xs * 2 + 1; if (ys >= 0) @@ -1215,9 +1191,9 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4, if (npc_class >= 0) { - for (i = 0; i < ys; i++) + for (int i = 0; i < ys; i++) { - for (j = 0; j < xs; j++) + for (int j = 0; j < xs; j++) { int x_lo = x - xs / 2; int y_lo = y - ys / 2; @@ -1235,32 +1211,24 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4, nd->scr.ys = ys; } else - { // クリック型NPC - npc_class = atoi(w4); + { + npc_class = atoi(w4.c_str()); nd->scr.xs = 0; nd->scr.ys = 0; } if (npc_class < 0 && m != nullptr) - { // イベント型NPC + { evflag = 1; } - while ((p = strchr(w3, ':'))) - { - if (p[1] == ':') - break; - } - if (p) + if (w3.contains(':')) { - *p = 0; - strzcpy(nd->name, w3, 24); - strzcpy(nd->exname, p + 2, 24); + assert(false && "feature removed"); + abort(); } - else { - strzcpy(nd->name, w3, 24); - strzcpy(nd->exname, w3, 24); + nd->name = w3; } nd->bl_prev = nd->bl_next = NULL; @@ -1288,37 +1256,36 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4, map_addblock(nd); if (evflag) - { // イベント型 + { struct event_data ev {}; ev.nd = nd; ev.pos = 0; - ev_db.insert(nd->exname, ev); + NpcEvent npcev; + npcev.npc = nd->name; + npcev.label = ScriptLabel(); + ev_db.insert(npcev, ev); } else clif_spawnnpc(nd); } - npcname_db.put(nd->exname, nd); + npcname_db.put(nd->name, nd); for (auto& pair : scriptlabel_db) npc_convertlabel_db(pair.first, pair.second, nd); for (npc_label_list& el : nd->scr.label_listv) { - char *lname = el.name; + ScriptLabel lname = el.name; int pos = el.pos; - if ((lname[0] == 'O' || lname[0] == 'o') - && (lname[1] == 'N' || lname[1] == 'n')) + if (lname.startswith("On")) { - if (strlen(lname) > 24) - { - PRINTF("npc_parse_script: label name error !\n"); - exit(1); - } struct event_data ev {}; ev.nd = nd; ev.pos = pos; - std::string buf = STRPRINTF("%s::%s", nd->exname, lname); + NpcEvent buf; + buf.npc = nd->name; + buf.label = lname; ev_db.insert(buf, ev); } } @@ -1327,10 +1294,10 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4, // ラベルデータからタイマーイベント取り込み for (npc_label_list& el : nd->scr.label_listv) { - int t_ = 0, n = 0; - char *lname = el.name; + int t_ = 0; + ScriptLabel lname = el.name; int pos = el.pos; - if (sscanf(lname, "OnTimer%d%n", &t_, &n) == 1 && lname[n] == '\0') + if (lname.startswith("OnTimer") && extract(lname.xslice_t(7), &t_)) { interval_t t = static_cast<interval_t>(t_); @@ -1360,40 +1327,41 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4, *------------------------------------------ */ static -int npc_parse_function(char *, char *, char *w3, char *, - char *first_line, FILE * fp, int *lines) +int npc_parse_function(XString, XString, XString w3, ZString, + XString first_line, FILE *fp, int *lines) { - std::string srcbuf = strchrnul(first_line, '{'); + MString srcbuf; + srcbuf += first_line.xislice_t(std::find(first_line.begin(), first_line.end(), '{')); int startline = *lines; - while (1) + while (true) { - size_t i = srcbuf.find_last_not_of(" \t\n\r\f\v"); - if (i != std::string::npos && srcbuf[i] == '}') + auto it = std::find_if_not(srcbuf.rbegin(), srcbuf.rend(), [](char c){ return c == ' ' || c == '\n'; }); + if (it != srcbuf.rend() && *it == '}') break; - char line[1024]; - if (!fgets(line, 1020, fp)) + char line_[1024]; + if (!fgets(line_, 1020, fp)) break; (*lines)++; if (feof(fp)) break; - if (srcbuf.empty()) + ZString line(ZString::really_construct_from_a_pointer, line_, nullptr); + if (!srcbuf) { - srcbuf = strchrnul(line, '{'); + srcbuf += line.xislice_t(std::find(line.begin(), line.end(), '{')); startline = *lines; } else srcbuf += line; } - std::unique_ptr<const ScriptBuffer> script = parse_script(srcbuf.c_str(), startline); + std::unique_ptr<const ScriptBuffer> script = parse_script(FString(srcbuf), startline); if (script == NULL) { // script parse error? return 1; } - std::string p = w3; - userfunc_db.put(p, std::move(script)); + userfunc_db.put(w3, std::move(script)); return 0; } @@ -1403,20 +1371,18 @@ int npc_parse_function(char *, char *, char *w3, char *, *------------------------------------------ */ static -int npc_parse_mob(const char *w1, const char *, const char *w3, const char *w4) +int npc_parse_mob(XString w1, XString, MobName w3, ZString w4) { int x, y, xs, ys, mob_class, num; int i; - char mapname[24]; - char eventname[24] = ""; + MapName mapname; + NpcEvent eventname; dumb_ptr<mob_data> md; xs = ys = 0; int delay1_ = 0, delay2_ = 0; - // 引数の個数チェック - if (sscanf(w1, "%[^,],%d,%d,%d,%d", mapname, &x, &y, &xs, &ys) < 3 || - sscanf(w4, "%d,%d,%d,%d,%s", &mob_class, &num, &delay1_, &delay2_, - eventname) < 2) + if (!extract(w1, record<',', 3>(&mapname, &x, &y, &xs, &ys)) || + !extract(w4, record<',', 2>(&mob_class, &num, &delay1_, &delay2_, &eventname))) { PRINTF("bad monster line : %s\n", w3); return 1; @@ -1441,12 +1407,12 @@ int npc_parse_mob(const char *w1, const char *, const char *w3, const char *w4) md->bl_m = m; md->bl_x = x; md->bl_y = y; - if (strcmp(w3, "--en--") == 0) - strzcpy(md->name, mob_db[mob_class].name, 24); - else if (strcmp(w3, "--ja--") == 0) - strzcpy(md->name, mob_db[mob_class].jname, 24); + if (w3 == ENGLISH_NAME) + md->name = mob_db[mob_class].name; + else if (w3 == JAPANESE_NAME) + md->name = mob_db[mob_class].jname; else - strzcpy(md->name, w3, 24); + md->name = w3; md->n = i; md->mob_class = mob_class; @@ -1466,10 +1432,7 @@ int npc_parse_mob(const char *w1, const char *, const char *w3, const char *w4) md->lootitemv.clear(); - if (strlen(eventname) >= 4) - strzcpy(md->npc_event, eventname, 24); - else - strzcpy(md->npc_event, "", 24); + md->npc_event = eventname; md->bl_type = BL::MOB; map_addiddb(md); @@ -1487,123 +1450,121 @@ int npc_parse_mob(const char *w1, const char *, const char *w3, const char *w4) *------------------------------------------ */ static -int npc_parse_mapflag(char *w1, char *, char *w3, char *w4) +int npc_parse_mapflag(XString w1, XString, XString w3, ZString w4) { - char mapname[24], savemap[16]; + MapName mapname, savemap; int savex, savey; - // 引数の個数チェック -// if ( sscanf(w1,"%[^,],%d,%d,%d",mapname,&x,&y,&dir) != 4 ) - if (sscanf(w1, "%[^,]", mapname) != 1) + mapname = stringish<MapName>(w1); + if (!mapname) return 1; map_local *m = map_mapname2mapid(mapname); if (m == nullptr) return 1; -//マップフラグ - if (strcasecmp(w3, "nosave") == 0) + if (w3 == "nosave") { - if (strcmp(w4, "SavePoint") == 0) + if (w4 == "SavePoint") { - strzcpy(m->save.map_, "SavePoint", 16); + m->save.map_ = stringish<MapName>("SavePoint"); m->save.x = -1; m->save.y = -1; } - else if (sscanf(w4, "%[^,],%d,%d", savemap, &savex, &savey) == 3) + else if (extract(w4, record<','>(&savemap, &savex, &savey))) { - strzcpy(m->save.map_, savemap, 16); + m->save.map_ = savemap; m->save.x = savex; m->save.y = savey; } m->flag.nosave = 1; } - else if (strcasecmp(w3, "nomemo") == 0) + else if (w3 == "nomemo") { m->flag.nomemo = 1; } - else if (strcasecmp(w3, "noteleport") == 0) + else if (w3 == "noteleport") { m->flag.noteleport = 1; } - else if (strcasecmp(w3, "nowarp") == 0) + else if (w3 == "nowarp") { m->flag.nowarp = 1; } - else if (strcasecmp(w3, "nowarpto") == 0) + else if (w3 == "nowarpto") { m->flag.nowarpto = 1; } - else if (strcasecmp(w3, "noreturn") == 0) + else if (w3 == "noreturn") { m->flag.noreturn = 1; } - else if (strcasecmp(w3, "monster_noteleport") == 0) + else if (w3 == "monster_noteleport") { m->flag.monster_noteleport = 1; } - else if (strcasecmp(w3, "nobranch") == 0) + else if (w3 == "nobranch") { m->flag.nobranch = 1; } - else if (strcasecmp(w3, "nopenalty") == 0) + else if (w3 == "nopenalty") { m->flag.nopenalty = 1; } - else if (strcasecmp(w3, "pvp") == 0) + else if (w3 == "pvp") { m->flag.pvp = 1; } - else if (strcasecmp(w3, "pvp_noparty") == 0) + else if (w3 == "pvp_noparty") { m->flag.pvp_noparty = 1; } - else if (strcasecmp(w3, "pvp_nocalcrank") == 0) + else if (w3 == "pvp_nocalcrank") { m->flag.pvp_nocalcrank = 1; } - else if (strcasecmp(w3, "nozenypenalty") == 0) + else if (w3 == "nozenypenalty") { m->flag.nozenypenalty = 1; } - else if (strcasecmp(w3, "notrade") == 0) + else if (w3 == "notrade") { m->flag.notrade = 1; } - else if (battle_config.pk_mode && strcasecmp(w3, "nopvp") == 0) + else if (battle_config.pk_mode && w3 == "nopvp") { // nopvp for pk mode [Valaris] m->flag.nopvp = 1; m->flag.pvp = 0; } - else if (strcasecmp(w3, "noicewall") == 0) + else if (w3 == "noicewall") { // noicewall [Valaris] m->flag.noicewall = 1; } - else if (strcasecmp(w3, "snow") == 0) + else if (w3 == "snow") { // snow [Valaris] m->flag.snow = 1; } - else if (strcasecmp(w3, "fog") == 0) + else if (w3 == "fog") { // fog [Valaris] m->flag.fog = 1; } - else if (strcasecmp(w3, "sakura") == 0) + else if (w3 == "sakura") { // sakura [Valaris] m->flag.sakura = 1; } - else if (strcasecmp(w3, "leaves") == 0) + else if (w3 == "leaves") { // leaves [Valaris] m->flag.leaves = 1; } - else if (strcasecmp(w3, "rain") == 0) + else if (w3 == "rain") { // rain [Valaris] m->flag.rain = 1; } - else if (strcasecmp(w3, "no_player_drops") == 0) + else if (w3 == "no_player_drops") { // no player drops [Jaxad0127] m->flag.no_player_drops = 1; } - else if (strcasecmp(w3, "town") == 0) + else if (w3 == "town") { // town/safe zone [remoitnane] m->flag.town = 1; } @@ -1612,7 +1573,7 @@ int npc_parse_mapflag(char *w1, char *, char *w3, char *w4) } dumb_ptr<npc_data> npc_spawn_text(map_local *m, int x, int y, - int npc_class, const char *name, const char *message) + int npc_class, NpcName name, FString message) { dumb_ptr<npc_data_message> retval; retval.new_(); @@ -1623,8 +1584,7 @@ dumb_ptr<npc_data> npc_spawn_text(map_local *m, int x, int y, retval->bl_type = BL::NPC; retval->npc_subtype = NpcSubtype::MESSAGE; - strzcpy(retval->name, name, 24); - strzcpy(retval->exname, name, 24); + retval->name = name; if (message) retval->message = message; @@ -1656,7 +1616,7 @@ void npc_free_internal(dumb_ptr<npc_data> nd_) else if (nd_->npc_subtype == NpcSubtype::MESSAGE) { dumb_ptr<npc_data_message> nd = nd_->as_message(); - nd->message.clear(); + nd->message = FString(); } nd_.delete_(); } @@ -1699,100 +1659,91 @@ int do_init_npc(void) for (; !npc_srcs.empty(); npc_srcs.pop_front()) { - std::string& nsl = npc_srcs.front(); - FILE *fp = fopen_(nsl.c_str(), "r"); + FString nsl = npc_srcs.front(); + FILE *fp = fopen(nsl.c_str(), "r"); if (fp == NULL) { PRINTF("file not found : %s\n", nsl); exit(1); } int lines = 0; - char line[1024]; - while (fgets(line, 1020, fp)) + char line_[1024]; + while (fgets(line_, 1020, fp)) { - char w1[1024], w2[1024], w3[1024], w4[1024], mapname[1024]; - int i, j, w4pos, count; + // because it's still fgets + line_[strlen(line_) - 1] = '\0'; + ZString zline(ZString::really_construct_from_a_pointer, line_, nullptr); + XString w1, w2, w3, w4x; + ZString w4z; lines++; - if (line[0] == '/' && line[1] == '/') + if (!zline) + continue; + if (zline.startswith("//")) continue; - // 不要なスペースやタブの連続は詰める - for (i = j = 0; line[i]; i++) + + if (!extract(zline, record<'|', 3>(&w1, &w2, &w3, &w4x)) || !w1 || !w2 || !w3) { - if (line[i] == ' ') - { - if (! - ((line[i + 1] - && (isspace(line[i + 1]) || line[i + 1] == ',')) - || (j && line[j - 1] == ','))) - line[j++] = ' '; - } - else if (line[i] == '\t' || line[i] == '|') - { - if (!(j && (line[j - 1] == '\t' || line[j - 1] == '|'))) - line[j++] = '\t'; - } - else - line[j++] = line[i]; + FPRINTF(stderr, "%s:%d: Broken script line: %s\n", nsl, lines, zline); + continue; } - // 最初はタブ区切りでチェックしてみて、ダメならスペース区切りで確認 - if ((count = - sscanf(line, "%[^\t]\t%[^\t]\t%[^\t\r\n]\t%n%[^\t\r\n]", w1, - w2, w3, &w4pos, w4)) < 3 - && (count = - sscanf(line, "%s%s%s%n%s", w1, w2, w3, &w4pos, w4)) < 3) + if (&*w4x.end() == &*zline.end()) { - continue; + w4z = zline.xrslice_t(w4x.size()); } - // マップの存在確認 - if (strcmp(w1, "-") != 0 && strcasecmp(w1, "function") != 0) + assert(bool(w4x) == bool(w4z)); + + if (w1 != "-" && w1 != "function") { - sscanf(w1, "%[^,]", mapname); + auto comma = std::find(w1.begin(), w1.end(), ','); + MapName mapname = stringish<MapName>(w1.xislice_h(comma)); map_local *m = map_mapname2mapid(mapname); - if (strlen(mapname) > 16 || m == nullptr) + if (m == nullptr) { // "mapname" is not assigned to this server + FPRINTF(stderr, "%s:%d: Map not found: %s\n", nsl, lines, mapname); continue; } } - if (strcasecmp(w2, "warp") == 0 && count > 3) + if (w2 == "warp") { - npc_parse_warp(w1, w2, w3, w4); + NpcName npcname = stringish<NpcName>(w3); + npc_parse_warp(w1, w2, npcname, w4z); } - else if (strcasecmp(w2, "shop") == 0 && count > 3) + else if (w2 == "shop") { - npc_parse_shop(w1, w2, w3, w4); + NpcName npcname = stringish<NpcName>(w3); + npc_parse_shop(w1, w2, npcname, w4z); } - else if (strcasecmp(w2, "script") == 0 && count > 3) + else if (w2 == "script") { - if (strcasecmp(w1, "function") == 0) + if (w1 == "function") { - npc_parse_function(w1, w2, w3, w4, line + w4pos, fp, - &lines); + npc_parse_function(w1, w2, w3, w4z, + w4x, fp, &lines); } else { - npc_parse_script(w1, w2, w3, w4, line + w4pos, fp, - &lines); + NpcName npcname = stringish<NpcName>(w3); + npc_parse_script(w1, w2, npcname, w4z, + w4x, fp, &lines); } } - else if ((i = - 0, sscanf(w2, "duplicate%n", &i), (i > 0 - && w2[i] == '(')) - && count > 3) + else if (w2 == "monster") { - npc_parse_script(w1, w2, w3, w4, line + w4pos, fp, &lines); + MobName mobname = stringish<MobName>(w3); + npc_parse_mob(w1, w2, mobname, w4z); } - else if (strcasecmp(w2, "monster") == 0 && count > 3) + else if (w2 == "mapflag") { - npc_parse_mob(w1, w2, w3, w4); + npc_parse_mapflag(w1, w2, w3, w4z); } - else if (strcasecmp(w2, "mapflag") == 0 && count >= 3) + else { - npc_parse_mapflag(w1, w2, w3, w4); + PRINTF("odd script line: %s\n", zline); } } - fclose_(fp); + fclose(fp); PRINTF("\rLoading NPCs [%d]: %-54s", npc_id - START_NPC_NUM, nsl); fflush(stdout); diff --git a/src/map/npc.hpp b/src/map/npc.hpp index 539152f..36f4e4d 100644 --- a/src/map/npc.hpp +++ b/src/map/npc.hpp @@ -15,19 +15,19 @@ constexpr int WARP_DEBUG_CLASS = 722; constexpr int INVISIBLE_CLASS = 32767; int npc_event_dequeue(dumb_ptr<map_session_data> sd); -int npc_event(dumb_ptr<map_session_data> sd, const char *npcname, int); -int npc_timer_event(const char *eventname); // Added by RoVeRT -int npc_command(dumb_ptr<map_session_data> sd, const char *npcname, const char *command); +int npc_event(dumb_ptr<map_session_data> sd, NpcEvent npcname, int); +void npc_timer_event(NpcEvent eventname); // Added by RoVeRT +int npc_command(dumb_ptr<map_session_data> sd, NpcName npcname, XString command); int npc_touch_areanpc(dumb_ptr<map_session_data>, map_local *, int, int); int npc_click(dumb_ptr<map_session_data>, int); int npc_scriptcont(dumb_ptr<map_session_data>, int); int npc_buysellsel(dumb_ptr<map_session_data>, int, int); int npc_buylist(dumb_ptr<map_session_data>, int, const uint16_t *); int npc_selllist(dumb_ptr<map_session_data>, int, const uint16_t *); -int npc_parse_warp(const char *w1, const char *w2, const char *w3, const char *w4); +int npc_parse_warp(XString w1, XString, NpcName w3, XString w4); -int npc_enable(const char *name, bool flag); -dumb_ptr<npc_data> npc_name2id(const char *name); +int npc_enable(NpcName name, bool flag); +dumb_ptr<npc_data> npc_name2id(NpcName name); int npc_get_new_npc_id(void); @@ -37,30 +37,27 @@ int npc_get_new_npc_id(void); * \param message The message to speak. If message is NULL, the NPC will not do anything at all. */ dumb_ptr<npc_data> npc_spawn_text(map_local *m, int x, int y, - int class_, const char *name, const char *message); // message is strdup'd within + int class_, NpcName name, FString message); /** * Uninstalls and frees an NPC */ void npc_free(dumb_ptr<npc_data> npc); -void npc_addsrcfile(const char *); -void npc_delsrcfile(const char *); +void npc_addsrcfile(FString); +void npc_delsrcfile(FString); int do_init_npc(void); int npc_event_do_oninit(void); -struct argrec; -int npc_event_doall_l(const char *name, int rid, - int argc, struct argrec *argv); -int npc_event_do_l(const char *name, int rid, - int argc, struct argrec *argv); +int npc_event_doall_l(ScriptLabel name, int rid, int argc, struct argrec_t *argv); +int npc_event_do_l(NpcEvent name, int rid, int argc, struct argrec_t *argv); inline -int npc_event_doall(const char *name) +int npc_event_doall(ScriptLabel name) { return npc_event_doall_l(name, 0, 0, NULL); } inline -int npc_event_do(const char *name) +int npc_event_do(NpcEvent name) { return npc_event_do_l(name, 0, 0, NULL); } diff --git a/src/map/party.cpp b/src/map/party.cpp index 62493c8..c6b0bcc 100644 --- a/src/map/party.cpp +++ b/src/map/party.cpp @@ -44,14 +44,14 @@ struct party *party_search(int party_id) } static -void party_searchname_sub(struct party *p, const char *str, struct party **dst) +void party_searchname_sub(struct party *p, PartyName str, struct party **dst) { - if (strcasecmp(p->name, str) == 0) + if (p->name == str) *dst = p; } // パーティ名検索 -struct party *party_searchname(const char *str) +struct party *party_searchname(PartyName str) { struct party *p = NULL; for (auto& pair : party_db) @@ -60,21 +60,19 @@ struct party *party_searchname(const char *str) } /* Process a party creation request. */ -int party_create(dumb_ptr<map_session_data> sd, const char *name) +int party_create(dumb_ptr<map_session_data> sd, PartyName name) { - char pname[24]; nullpo_ret(sd); - strzcpy(pname, name, 24); - tmw_TrimStr(pname); + name = stringish<PartyName>(name.strip()); /* The party name is empty/invalid. */ - if (!*pname) + if (!name) clif_party_created(sd, 1); /* Make sure the character isn't already in a party. */ if (sd->status.party_id == 0) - intif_create_party(sd, pname); + intif_create_party(sd, name); else clif_party_created(sd, 2); @@ -82,7 +80,7 @@ int party_create(dumb_ptr<map_session_data> sd, const char *name) } /* Relay the result of a party creation request. */ -void party_created(int account_id, int fail, int party_id, const char *name) +void party_created(int account_id, int fail, int party_id, PartyName name) { dumb_ptr<map_session_data> sd; sd = map_id2sd(account_id); @@ -103,7 +101,7 @@ void party_created(int account_id, int fail, int party_id, const char *name) p = party_db.init(party_id); p->party_id = party_id; - strzcpy(p->name, name, 24); + p->name = name; /* The party was created successfully. */ clif_party_created(sd, 0); @@ -139,7 +137,7 @@ int party_check_member(struct party *p) { // パーティにデータがあるか確認 if (p->member[j].account_id == sd->status.account_id) { - if (strcmp(p->member[j].name, sd->status.name) == 0) + if (p->member[j].name == sd->status.name) f = 0; // データがある else { @@ -369,7 +367,7 @@ int party_member_added(int party_id, int account_id, int flag) } // パーティ除名要求 -int party_removemember(dumb_ptr<map_session_data> sd, int account_id, const char *) +int party_removemember(dumb_ptr<map_session_data> sd, int account_id) { struct party *p; int i; @@ -420,7 +418,7 @@ int party_leave(dumb_ptr<map_session_data> sd) } // パーティメンバが脱退した -int party_member_leaved(int party_id, int account_id, const char *name) +int party_member_leaved(int party_id, int account_id, CharName name) { dumb_ptr<map_session_data> sd = map_id2sd(account_id); struct party *p = party_search(party_id); @@ -499,8 +497,8 @@ int party_optionchanged(int party_id, int account_id, int exp, int item, } // パーティメンバの移動通知 -void party_recv_movemap(int party_id, int account_id, const char *mapname, int online, - int lv) +void party_recv_movemap(int party_id, int account_id, MapName mapname, + int online, int lv) { struct party *p; int i; @@ -516,7 +514,7 @@ void party_recv_movemap(int party_id, int account_id, const char *mapname, int o } if (m->account_id == account_id) { - strzcpy(m->map, mapname, 16); + m->map = mapname; m->online = online; m->lv = lv; break; @@ -597,7 +595,7 @@ int party_send_logout(dumb_ptr<map_session_data> sd) } // パーティメッセージ送信 -void party_send_message(dumb_ptr<map_session_data> sd, const char *mes) +void party_send_message(dumb_ptr<map_session_data> sd, XString mes) { if (sd->status.party_id == 0) return; @@ -605,7 +603,7 @@ void party_send_message(dumb_ptr<map_session_data> sd, const char *mes) } // パーティメッセージ受信 -void party_recv_message(int party_id, int account_id, const char *mes) +void party_recv_message(int party_id, int account_id, XString mes) { struct party *p; if ((p = party_search(party_id)) == NULL) @@ -618,8 +616,8 @@ void party_check_conflict(dumb_ptr<map_session_data> sd) { nullpo_retv(sd); - intif_party_checkconflict(sd->status.party_id, sd->status.account_id, - sd->status.name); + intif_party_checkconflict(sd->status.party_id, + sd->status.account_id, sd->status.name); } // 位置やHP通知用 diff --git a/src/map/party.hpp b/src/map/party.hpp index c27cc08..80679ad 100644 --- a/src/map/party.hpp +++ b/src/map/party.hpp @@ -11,22 +11,21 @@ struct block_list; void do_init_party(void); struct party *party_search(int party_id); -struct party *party_searchname(const char *str); +struct party *party_searchname(PartyName str); -int party_create(dumb_ptr<map_session_data> sd, const char *name); -void party_created(int account_id, int fail, int party_id, const char *name); +int party_create(dumb_ptr<map_session_data> sd, PartyName name); +void party_created(int account_id, int fail, int party_id, PartyName name); void party_request_info(int party_id); int party_invite(dumb_ptr<map_session_data> sd, int account_id); int party_member_added(int party_id, int account_id, int flag); int party_leave(dumb_ptr<map_session_data> sd); -int party_removemember(dumb_ptr<map_session_data> sd, int account_id, - const char *name); -int party_member_leaved(int party_id, int account_id, const char *name); +int party_removemember(dumb_ptr<map_session_data> sd, int account_id); +int party_member_leaved(int party_id, int account_id, CharName name); int party_reply_invite(dumb_ptr<map_session_data> sd, int account_id, int flag); int party_recv_noinfo(int party_id); int party_recv_info(const struct party *sp); -void party_recv_movemap(int party_id, int account_id, const char *map, +void party_recv_movemap(int party_id, int account_id, MapName map, int online, int lv); int party_broken(int party_id); int party_optionchanged(int party_id, int account_id, int exp, int item, @@ -36,8 +35,8 @@ int party_changeoption(dumb_ptr<map_session_data> sd, int exp, int item); int party_send_movemap(dumb_ptr<map_session_data> sd); int party_send_logout(dumb_ptr<map_session_data> sd); -void party_send_message(dumb_ptr<map_session_data> sd, const char *mes); -void party_recv_message(int party_id, int account_id, const char *mes); +void party_send_message(dumb_ptr<map_session_data> sd, XString mes); +void party_recv_message(int party_id, int account_id, XString mes); void party_send_xy_clear(struct party *p); void party_send_hp_check(dumb_ptr<block_list> bl, int party_id, int *flag); diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 08f873a..8cc74b8 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -7,8 +7,9 @@ #include <fstream> #include "../common/cxxstdio.hpp" -#include "../common/random.hpp" +#include "../common/io.hpp" #include "../common/nullpo.hpp" +#include "../common/random.hpp" #include "../common/socket.hpp" #include "../common/timer.hpp" @@ -56,7 +57,7 @@ constexpr int MAGIC_SKILL_THRESHOLD = 200; MAP_LOG_PC(sd, "XP %d %d JOB %d %d %d ZENY %d + %d " suffix, \ sd->status.base_level, sd->status.base_exp, \ sd->status.job_level, sd->status.job_exp, sd->status.skill_point, \ - sd->status.zeny, pc_readaccountreg(sd, "BankAccount")) + sd->status.zeny, pc_readaccountreg(sd, stringish<VarName>("BankAccount"))) #define MAP_LOG_MAGIC(sd, suffix) \ MAP_LOG_PC(sd, "MAGIC %d %d %d %d %d %d EXP %d %d " suffix, \ @@ -66,8 +67,8 @@ constexpr int MAGIC_SKILL_THRESHOLD = 200; sd->status.skill[SkillID::TMW_MAGIC_TRANSMUTE].lv, \ sd->status.skill[SkillID::TMW_MAGIC_NATURE].lv, \ sd->status.skill[SkillID::TMW_MAGIC_ETHER].lv, \ - pc_readglobalreg(sd, "MAGIC_EXPERIENCE") & 0xffff, \ - (pc_readglobalreg(sd, "MAGIC_EXPERIENCE") >> 24) & 0xff) + pc_readglobalreg(sd, stringish<VarName>("MAGIC_EXPERIENCE")) & 0xffff, \ + (pc_readglobalreg(sd, stringish<VarName>("MAGIC_EXPERIENCE")) >> 24) & 0xff) static //const int max_weight_base_0 = 20000; @@ -412,7 +413,7 @@ void pc_makesavestatus(dumb_ptr<map_session_data> sd) } else { - strzcpy(sd->status.last_point.map_, sd->mapname_, 16); + sd->status.last_point.map_ = sd->mapname_; sd->status.last_point.x = sd->bl_x; sd->status.last_point.y = sd->bl_y; } @@ -421,7 +422,7 @@ void pc_makesavestatus(dumb_ptr<map_session_data> sd) if (sd->bl_m->flag.nosave) { map_local *m = sd->bl_m; - if (strcmp(m->save.map_, "SavePoint") == 0) + if (m->save.map_ == "SavePoint") sd->status.last_point = sd->status.save_point; else sd->status.last_point = m->save; @@ -712,11 +713,11 @@ int pc_authok(int id, int login_id2, TimeT connect_until_time, clif_authok(sd); map_addnickdb(sd); - if (map_charid2nick(sd->status.char_id) == NULL) + if (!map_charid2nick(sd->status.char_id).to__actual()) map_addchariddb(sd->status.char_id, sd->status.name); //スパノビ用死にカウンターのスクリプト変数からの読み出しとsdへのセット - sd->die_counter = pc_readglobalreg(sd, "PC_DIE_COUNTER"); + sd->die_counter = pc_readglobalreg(sd, stringish<VarName>("PC_DIE_COUNTER")); // ステータス初期計算など pc_calcstatus(sd, 1); @@ -732,12 +733,13 @@ int pc_authok(int id, int login_id2, TimeT connect_until_time, sd->status.name, sd->status.account_id); // TODO fix this to cache and use inotify + // this is far from the only such thing, but most of the others are logs { - std::ifstream in(motd_txt); + std::ifstream in(motd_txt.c_str()); if (in.is_open()) { - std::string buf; - while (std::getline(in, buf)) + FString buf; + while (io::getline(in, buf)) { clif_displaymessage(sd->fd, buf); } @@ -750,7 +752,7 @@ int pc_authok(int id, int login_id2, TimeT connect_until_time, sd->chat_reset_due = TimeT(); sd->chat_lines_in = sd->chat_total_repeats = 0; sd->chat_repeat_reset_due = TimeT(); - sd->chat_lastmsg[0] = '\0'; + sd->chat_lastmsg = FString(); for (tick_t& t : sd->flood_rates) t = tick_t(); @@ -768,7 +770,7 @@ int pc_authok(int id, int login_id2, TimeT connect_until_time, char tmpstr[] = WITH_TIMESTAMP("Your account time limit is: "); REPLACE_TIMESTAMP(tmpstr, connect_until_time); - clif_wis_message(sd->fd, wisp_server_name, tmpstr); + clif_wis_message(sd->fd, wisp_server_name, const_(tmpstr)); } pc_calcstatus(sd, 1); @@ -1024,16 +1026,16 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) int c = sd->status.inventory[index].card[j]; if (c > 0) { - argrec_t arg[2]; - arg[0].name = "@slotId"; - arg[0].v.i = int(i); - arg[1].name = "@itemId"; - arg[1].v.i = sd->inventory_data[index]->nameid; + argrec_t arg[2] = + { + {"@slotId", static_cast<int>(i)}, + {"@itemId", sd->inventory_data[index]->nameid}, + }; if (i == EQUIP::SHIELD && sd->status.inventory[index].equip == EPOS::SHIELD) sd->state.lr_flag = 1; - run_script_l(ScriptPointer(itemdb_equipscript(c), 0), sd->bl_id, - 0, 2, arg); + run_script_l(ScriptPointer(itemdb_equipscript(c), 0), sd->bl_id, 0, + 2, arg); sd->state.lr_flag = 0; } } @@ -1050,13 +1052,13 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) { // カード int c = sd->status.inventory[index].card[j]; if (c > 0) { - argrec_t arg[2]; - arg[0].name = "@slotId"; - arg[0].v.i = int(i); - arg[1].name = "@itemId"; - arg[1].v.i = sd->inventory_data[index]->nameid; - run_script_l(ScriptPointer(itemdb_equipscript(c), 0), sd->bl_id, - 0, 2, arg); + argrec_t arg[2] = + { + {"@slotId", static_cast<int>(i)}, + {"@itemId", sd->inventory_data[index]->nameid} + }; + run_script_l(ScriptPointer(itemdb_equipscript(c), 0), sd->bl_id, 0, + 2, arg); } } } @@ -1113,23 +1115,25 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) sd->attackrange_ += sd->inventory_data[index]->range; sd->state.lr_flag = 1; { - argrec_t arg[2]; - arg[0].name = "@slotId"; - arg[0].v.i = int(i); - arg[1].name = "@itemId"; - arg[1].v.i = sd->inventory_data[index]->nameid; + argrec_t arg[2] = + { + {"@slotId", static_cast<int>(i)}, + {"@itemId", sd->inventory_data[index]->nameid}, + }; run_script_l(ScriptPointer(sd->inventory_data[index]->equip_script.get(), 0), - sd->bl_id, 0, 2, arg); + sd->bl_id, 0, + 2, arg); } sd->state.lr_flag = 0; } else - { //二刀流武器以外 - argrec_t arg[2]; - arg[0].name = "@slotId"; - arg[0].v.i = int(i); - arg[1].name = "@itemId"; - arg[1].v.i = sd->inventory_data[index]->nameid; + { + //二刀流武器以外 + argrec_t arg[2] = + { + {"@slotId", static_cast<int>(i)}, + {"@itemId", sd->inventory_data[index]->nameid}, + }; sd->watk += sd->inventory_data[index]->atk; sd->watk2 += (r = sd->status.inventory[index].refine) * // 精錬攻撃力 0; @@ -1142,21 +1146,23 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) } sd->attackrange += sd->inventory_data[index]->range; run_script_l(ScriptPointer(sd->inventory_data[index]->equip_script.get(), 0), - sd->bl_id, 0, 2, arg); + sd->bl_id, 0, + 2, arg); } } else if (sd->inventory_data[index]->type == ItemType::ARMOR) { - argrec_t arg[2]; - arg[0].name = "@slotId"; - arg[0].v.i = int(i); - arg[1].name = "@itemId"; - arg[1].v.i = sd->inventory_data[index]->nameid; + argrec_t arg[2] = + { + {"@slotId", static_cast<int>(i)}, + {"@itemId", sd->inventory_data[index]->nameid}, + }; sd->watk += sd->inventory_data[index]->atk; refinedef += sd->status.inventory[index].refine * 0; run_script_l(ScriptPointer(sd->inventory_data[index]->equip_script.get(), 0), - sd->bl_id, 0, 2, arg); + sd->bl_id, 0, + 2, arg); } } } @@ -1174,14 +1180,15 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) index = sd->equip_index[EQUIP::ARROW]; if (sd->inventory_data[index]) { //まだ属性が入っていない - argrec_t arg[2]; - arg[0].name = "@slotId"; - arg[0].v.i = int(EQUIP::ARROW); - arg[1].name = "@itemId"; - arg[1].v.i = sd->inventory_data[index]->nameid; + argrec_t arg[2] = + { + {"@slotId", static_cast<int>(EQUIP::ARROW)}, + {"@itemId", sd->inventory_data[index]->nameid}, + }; sd->state.lr_flag = 2; - run_script_l(ScriptPointer(sd->inventory_data[index]->equip_script.get(), 0), sd->bl_id, - 0, 2, arg); + run_script_l(ScriptPointer(sd->inventory_data[index]->equip_script.get(), 0), + sd->bl_id, 0, + 2, arg); sd->state.lr_flag = 0; sd->arrow_atk += sd->inventory_data[index]->atk; } @@ -1888,7 +1895,6 @@ int pc_payzeny(dumb_ptr<map_session_data> sd, int zeny) { nullpo_ret(sd); -#warning "Why is this a double?" double z = sd->status.zeny; if (sd->status.zeny < zeny || z - zeny > MAX_ZENY) return 1; @@ -2270,10 +2276,10 @@ int pc_useitem(dumb_ptr<map_session_data> sd, int n) * PCの位置設定 *------------------------------------------ */ -int pc_setpos(dumb_ptr<map_session_data> sd, const char *mapname_org, int x, int y, - BeingRemoveWhy clrtype) +int pc_setpos(dumb_ptr<map_session_data> sd, + MapName mapname_org, int x, int y, BeingRemoveWhy clrtype) { - char mapname_[16]; + MapName mapname_; nullpo_ret(sd); @@ -2294,16 +2300,12 @@ int pc_setpos(dumb_ptr<map_session_data> sd, const char *mapname_org, int x, int // pc_setstand (sd); // [fate] Nothing wrong with warping while sitting } - strzcpy(mapname_, mapname_org, 16); - if (strstr(mapname_, ".gat") == NULL && strlen(mapname_) < 16 - 4) - { - strcat(mapname_, ".gat"); - } + mapname_ = mapname_org; map_local *m = map_mapname2mapid(mapname_); if (!m) { - if (sd->mapname_[0]) + if (sd->mapname_) { struct in_addr ip; int port; @@ -2312,7 +2314,7 @@ int pc_setpos(dumb_ptr<map_session_data> sd, const char *mapname_org, int x, int skill_stop_dancing(sd, 1); clif_clearchar(sd, clrtype); map_delblock(sd); - strzcpy(sd->mapname_, mapname_, 16); + sd->mapname_ = mapname_; sd->bl_x = x; sd->bl_y = y; sd->state.waitingdisconnect = 1; @@ -2359,7 +2361,7 @@ int pc_setpos(dumb_ptr<map_session_data> sd, const char *mapname_org, int x, int clif_changemap(sd, m->name_, x, y); // [MouseJstr] } - strzcpy(sd->mapname_, mapname_, 16); + sd->mapname_ = mapname_; sd->bl_m = m; sd->to_x = x; sd->to_y = y; @@ -3080,7 +3082,7 @@ int pc_gainexp_reason(dumb_ptr<map_session_data> sd, int base_exp, int job_exp, if (battle_config.disp_experience) { - std::string output = STRPRINTF( + FString output = STRPRINTF( "Experienced Gained Base:%d Job:%d", base_exp, job_exp); clif_displaymessage(sd->fd, output); @@ -3476,7 +3478,7 @@ int pc_damage(dumb_ptr<block_list> src, dumb_ptr<map_session_data> sd, pc_stop_walking(sd, 0); skill_castcancel(sd, 0); // 詠唱の中止 clif_clearchar(sd, BeingRemoveWhy::DEAD); - pc_setglobalreg(sd, "PC_DIE_COUNTER", ++sd->die_counter); //死にカウンター書き込み + pc_setglobalreg(sd, stringish<VarName>("PC_DIE_COUNTER"), ++sd->die_counter); //死にカウンター書き込み skill_status_change_clear(sd, 0); // ステータス異常を解除する clif_updatestatus(sd, SP::HP); pc_calcstatus(sd, 0); @@ -3566,17 +3568,16 @@ int pc_damage(dumb_ptr<block_list> src, dumb_ptr<map_session_data> sd, if (src && src->bl_type == BL::PC) { // [Fate] PK death, trigger scripts - argrec_t arg[3]; - arg[0].name = "@killerrid"; - arg[0].v.i = src->bl_id; - arg[1].name = "@victimrid"; - arg[1].v.i = sd->bl_id; - arg[2].name = "@victimlvl"; - arg[2].v.i = sd->status.base_level; - npc_event_doall_l("OnPCKilledEvent", sd->bl_id, 3, arg); - npc_event_doall_l("OnPCKillEvent", src->bl_id, 3, arg); - } - npc_event_doall_l("OnPCDieEvent", sd->bl_id, 0, NULL); + argrec_t arg[3] = + { + {"@killerrid", src->bl_id}, + {"@victimrid", sd->bl_id}, + {"@victimlvl", sd->status.base_level}, + }; + npc_event_doall_l(stringish<ScriptLabel>("OnPCKilledEvent"), sd->bl_id, 3, arg); + npc_event_doall_l(stringish<ScriptLabel>("OnPCKillEvent"), src->bl_id, 3, arg); + } + npc_event_doall_l(stringish<ScriptLabel>("OnPCDieEvent"), sd->bl_id, 0, NULL); return 0; } @@ -4101,26 +4102,26 @@ void pc_setreg(dumb_ptr<map_session_data> sd, SIR reg, int val) * script用文字列変数の値を読む *------------------------------------------ */ -const char *pc_readregstr(dumb_ptr<map_session_data> sd, SIR reg) +ZString pc_readregstr(dumb_ptr<map_session_data> sd, SIR reg) { - nullpo_ret(sd); + nullpo_retr(ZString(), sd); - std::string *s = sd->regstrm.search(reg); + FString *s = sd->regstrm.search(reg); if (s) - return s->c_str(); + return *s; - return NULL; + return ZString(); } /*========================================== * script用文字列変数の値を設定 *------------------------------------------ */ -void pc_setregstr(dumb_ptr<map_session_data> sd, SIR reg, const char *str) +void pc_setregstr(dumb_ptr<map_session_data> sd, SIR reg, FString str) { nullpo_retv(sd); - if (!*str) + if (!str) { sd->regstrm.erase(reg); return; @@ -4133,7 +4134,7 @@ void pc_setregstr(dumb_ptr<map_session_data> sd, SIR reg, const char *str) * script用グローバル変数の値を読む *------------------------------------------ */ -int pc_readglobalreg(dumb_ptr<map_session_data> sd, const char *reg) +int pc_readglobalreg(dumb_ptr<map_session_data> sd, VarName reg) { int i; @@ -4141,7 +4142,7 @@ int pc_readglobalreg(dumb_ptr<map_session_data> sd, const char *reg) for (i = 0; i < sd->status.global_reg_num; i++) { - if (strcmp(sd->status.global_reg[i].str, reg) == 0) + if (sd->status.global_reg[i].str == reg) return sd->status.global_reg[i].value; } @@ -4152,14 +4153,14 @@ int pc_readglobalreg(dumb_ptr<map_session_data> sd, const char *reg) * script用グローバル変数の値を設定 *------------------------------------------ */ -int pc_setglobalreg(dumb_ptr<map_session_data> sd, const char *reg, int val) +int pc_setglobalreg(dumb_ptr<map_session_data> sd, VarName reg, int val) { int i; nullpo_ret(sd); //PC_DIE_COUNTERがスクリプトなどで変更された時の処理 - if (strcmp(reg, "PC_DIE_COUNTER") == 0 && sd->die_counter != val) + if (reg == stringish<VarName>("PC_DIE_COUNTER") && sd->die_counter != val) { sd->die_counter = val; pc_calcstatus(sd, 0); @@ -4168,7 +4169,7 @@ int pc_setglobalreg(dumb_ptr<map_session_data> sd, const char *reg, int val) { for (i = 0; i < sd->status.global_reg_num; i++) { - if (strcmp(sd->status.global_reg[i].str, reg) == 0) + if (sd->status.global_reg[i].str == reg) { sd->status.global_reg[i] = sd->status.global_reg[sd->status.global_reg_num - 1]; @@ -4180,7 +4181,7 @@ int pc_setglobalreg(dumb_ptr<map_session_data> sd, const char *reg, int val) } for (i = 0; i < sd->status.global_reg_num; i++) { - if (strcmp(sd->status.global_reg[i].str, reg) == 0) + if (sd->status.global_reg[i].str == reg) { sd->status.global_reg[i].value = val; return 0; @@ -4188,7 +4189,7 @@ int pc_setglobalreg(dumb_ptr<map_session_data> sd, const char *reg, int val) } if (sd->status.global_reg_num < GLOBAL_REG_NUM) { - strcpy(sd->status.global_reg[i].str, reg); + sd->status.global_reg[i].str = reg; sd->status.global_reg[i].value = val; sd->status.global_reg_num++; return 0; @@ -4204,7 +4205,7 @@ int pc_setglobalreg(dumb_ptr<map_session_data> sd, const char *reg, int val) * script用アカウント変数の値を読む *------------------------------------------ */ -int pc_readaccountreg(dumb_ptr<map_session_data> sd, const char *reg) +int pc_readaccountreg(dumb_ptr<map_session_data> sd, VarName reg) { int i; @@ -4212,7 +4213,7 @@ int pc_readaccountreg(dumb_ptr<map_session_data> sd, const char *reg) for (i = 0; i < sd->status.account_reg_num; i++) { - if (strcmp(sd->status.account_reg[i].str, reg) == 0) + if (sd->status.account_reg[i].str == reg) return sd->status.account_reg[i].value; } @@ -4223,7 +4224,7 @@ int pc_readaccountreg(dumb_ptr<map_session_data> sd, const char *reg) * script用アカウント変数の値を設定 *------------------------------------------ */ -int pc_setaccountreg(dumb_ptr<map_session_data> sd, const char *reg, int val) +int pc_setaccountreg(dumb_ptr<map_session_data> sd, VarName reg, int val) { int i; @@ -4233,7 +4234,7 @@ int pc_setaccountreg(dumb_ptr<map_session_data> sd, const char *reg, int val) { for (i = 0; i < sd->status.account_reg_num; i++) { - if (strcmp(sd->status.account_reg[i].str, reg) == 0) + if (sd->status.account_reg[i].str == reg) { sd->status.account_reg[i] = sd->status.account_reg[sd->status.account_reg_num - 1]; @@ -4246,7 +4247,7 @@ int pc_setaccountreg(dumb_ptr<map_session_data> sd, const char *reg, int val) } for (i = 0; i < sd->status.account_reg_num; i++) { - if (strcmp(sd->status.account_reg[i].str, reg) == 0) + if (sd->status.account_reg[i].str == reg) { sd->status.account_reg[i].value = val; intif_saveaccountreg(sd); @@ -4255,7 +4256,7 @@ int pc_setaccountreg(dumb_ptr<map_session_data> sd, const char *reg, int val) } if (sd->status.account_reg_num < ACCOUNT_REG_NUM) { - strcpy(sd->status.account_reg[i].str, reg); + sd->status.account_reg[i].str == reg; sd->status.account_reg[i].value = val; sd->status.account_reg_num++; intif_saveaccountreg(sd); @@ -4272,7 +4273,7 @@ int pc_setaccountreg(dumb_ptr<map_session_data> sd, const char *reg, int val) * script用アカウント変数2の値を読む *------------------------------------------ */ -int pc_readaccountreg2(dumb_ptr<map_session_data> sd, const char *reg) +int pc_readaccountreg2(dumb_ptr<map_session_data> sd, VarName reg) { int i; @@ -4280,7 +4281,7 @@ int pc_readaccountreg2(dumb_ptr<map_session_data> sd, const char *reg) for (i = 0; i < sd->status.account_reg2_num; i++) { - if (strcmp(sd->status.account_reg2[i].str, reg) == 0) + if (sd->status.account_reg2[i].str == reg) return sd->status.account_reg2[i].value; } @@ -4291,7 +4292,7 @@ int pc_readaccountreg2(dumb_ptr<map_session_data> sd, const char *reg) * script用アカウント変数2の値を設定 *------------------------------------------ */ -int pc_setaccountreg2(dumb_ptr<map_session_data> sd, const char *reg, int val) +int pc_setaccountreg2(dumb_ptr<map_session_data> sd, VarName reg, int val) { int i; @@ -4301,7 +4302,7 @@ int pc_setaccountreg2(dumb_ptr<map_session_data> sd, const char *reg, int val) { for (i = 0; i < sd->status.account_reg2_num; i++) { - if (strcmp(sd->status.account_reg2[i].str, reg) == 0) + if (sd->status.account_reg2[i].str == reg) { sd->status.account_reg2[i] = sd->status.account_reg2[sd->status.account_reg2_num - 1]; @@ -4314,7 +4315,7 @@ int pc_setaccountreg2(dumb_ptr<map_session_data> sd, const char *reg, int val) } for (i = 0; i < sd->status.account_reg2_num; i++) { - if (strcmp(sd->status.account_reg2[i].str, reg) == 0) + if (sd->status.account_reg2[i].str == reg) { sd->status.account_reg2[i].value = val; chrif_saveaccountreg2(sd); @@ -4323,7 +4324,7 @@ int pc_setaccountreg2(dumb_ptr<map_session_data> sd, const char *reg, int val) } if (sd->status.account_reg2_num < ACCOUNT_REG2_NUM) { - strcpy(sd->status.account_reg2[i].str, reg); + sd->status.account_reg2[i].str = reg; sd->status.account_reg2[i].value = val; sd->status.account_reg2_num++; chrif_saveaccountreg2(sd); @@ -4341,21 +4342,19 @@ int pc_setaccountreg2(dumb_ptr<map_session_data> sd, const char *reg, int val) *------------------------------------------ */ static -void pc_eventtimer(TimerData *, tick_t, int id, dumb_string data) +void pc_eventtimer(TimerData *, tick_t, int id, NpcEvent data) { dumb_ptr<map_session_data> sd = map_id2sd(id); assert (sd != NULL); - npc_event(sd, data.c_str(), 0); - - data.delete_(); + npc_event(sd, data, 0); } /*========================================== * イベントタイマー追加 *------------------------------------------ */ -int pc_addeventtimer(dumb_ptr<map_session_data> sd, interval_t tick, const char *name) +int pc_addeventtimer(dumb_ptr<map_session_data> sd, interval_t tick, NpcEvent name) { int i; @@ -4367,10 +4366,9 @@ int pc_addeventtimer(dumb_ptr<map_session_data> sd, interval_t tick, const char if (i < MAX_EVENTTIMER) { - dumb_string evname = dumb_string::copyn(name, 24); sd->eventtimer[i] = Timer(gettick() + tick, std::bind(pc_eventtimer, ph::_1, ph::_2, - sd->bl_id, evname)); + sd->bl_id, name)); return 1; } @@ -4869,13 +4867,12 @@ int pc_divorce(dumb_ptr<map_session_data> sd) dumb_ptr<map_session_data> pc_get_partner(dumb_ptr<map_session_data> sd) { dumb_ptr<map_session_data> p_sd = NULL; - char *nick; if (sd == NULL || !pc_ismarried(sd)) return NULL; - nick = map_charid2nick(sd->status.partner_id); + CharName nick = map_charid2nick(sd->status.partner_id); - if (nick == NULL) + if (!nick.to__actual()) return NULL; if ((p_sd = map_nick2sd(nick)) == NULL) @@ -5167,11 +5164,11 @@ void pc_natural_heal(TimerData *, tick_t tick) * セーブポイントの保存 *------------------------------------------ */ -void pc_setsavepoint(dumb_ptr<map_session_data> sd, const char *mapname, int x, int y) +void pc_setsavepoint(dumb_ptr<map_session_data> sd, MapName mapname, int x, int y) { nullpo_retv(sd); - strzcpy(sd->status.save_point.map_, mapname, 16); + sd->status.save_point.map_ = mapname; sd->status.save_point.x = x; sd->status.save_point.y = y; } @@ -5316,7 +5313,7 @@ int pc_logout(dumb_ptr<map_session_data> sd) // [fate] Player logs out } else #endif - pc_setglobalreg(sd, "MAGIC_CAST_TICK", 0); + pc_setglobalreg(sd, stringish<VarName>("MAGIC_CAST_TICK"), 0); MAP_LOG_STATS(sd, "LOGOUT"); return 0; diff --git a/src/map/pc.hpp b/src/map/pc.hpp index 4ebfa1b..4796011 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -62,8 +62,8 @@ int pc_checkequip(dumb_ptr<map_session_data> sd, EPOS pos); int pc_walktoxy(dumb_ptr<map_session_data>, int, int); int pc_stop_walking(dumb_ptr<map_session_data>, int); int pc_movepos(dumb_ptr<map_session_data>, int, int); -int pc_setpos(dumb_ptr<map_session_data>, const char *, int, int, BeingRemoveWhy); -void pc_setsavepoint(dumb_ptr<map_session_data>, const char *, int, int); +int pc_setpos(dumb_ptr<map_session_data>, MapName, int, int, BeingRemoveWhy); +void pc_setsavepoint(dumb_ptr<map_session_data>, MapName, int, int); int pc_randomwarp(dumb_ptr<map_session_data> sd, BeingRemoveWhy type); ADDITEM pc_checkadditem(dumb_ptr<map_session_data>, int, int); @@ -120,17 +120,17 @@ int pc_readparam(dumb_ptr<map_session_data>, SP); int pc_setparam(dumb_ptr<map_session_data>, SP, int); int pc_readreg(dumb_ptr<map_session_data>, SIR); void pc_setreg(dumb_ptr<map_session_data>, SIR, int); -const char *pc_readregstr(dumb_ptr<map_session_data> sd, SIR reg); -void pc_setregstr(dumb_ptr<map_session_data> sd, SIR reg, const char *str); -int pc_readglobalreg(dumb_ptr<map_session_data>, const char *); -int pc_setglobalreg(dumb_ptr<map_session_data>, const char *, int); -int pc_readaccountreg(dumb_ptr<map_session_data>, const char *); -int pc_setaccountreg(dumb_ptr<map_session_data>, const char *, int); -int pc_readaccountreg2(dumb_ptr<map_session_data>, const char *); -int pc_setaccountreg2(dumb_ptr<map_session_data>, const char *, int); +ZString pc_readregstr(dumb_ptr<map_session_data> sd, SIR reg); +void pc_setregstr(dumb_ptr<map_session_data> sd, SIR reg, FString str); +int pc_readglobalreg(dumb_ptr<map_session_data>, VarName ); +int pc_setglobalreg(dumb_ptr<map_session_data>, VarName , int); +int pc_readaccountreg(dumb_ptr<map_session_data>, VarName ); +int pc_setaccountreg(dumb_ptr<map_session_data>, VarName , int); +int pc_readaccountreg2(dumb_ptr<map_session_data>, VarName ); +int pc_setaccountreg2(dumb_ptr<map_session_data>, VarName , int); int pc_addeventtimer(dumb_ptr<map_session_data> sd, interval_t tick, - const char *name); + NpcEvent name); int pc_cleareventtimer(dumb_ptr<map_session_data> sd); int pc_calc_pvprank(dumb_ptr<map_session_data> sd); diff --git a/src/map/script.cpp b/src/map/script.cpp index 854a42f..e82c843 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -13,6 +13,7 @@ #include "../common/db.hpp" #include "../common/extract.hpp" #include "../common/intern-pool.hpp" +#include "../common/io.hpp" #include "../common/lock.hpp" #include "../common/random.hpp" #include "../common/socket.hpp" @@ -42,27 +43,27 @@ constexpr bool DEBUG_RUN = false; struct str_data_t { ByteCode type; - std::string strs; + FString strs; int backpatch; int label_; int val; }; static -Map<std::string, str_data_t> str_datam; +Map<FString, str_data_t> str_datam; static str_data_t LABEL_NEXTLINE_; static DMap<SIR, int> mapreg_db; static -Map<SIR, std::string> mapregstr_db; +Map<SIR, FString> mapregstr_db; static int mapreg_dirty = -1; -char mapreg_txt[256] = "save/mapreg.txt"; +FString mapreg_txt = "save/mapreg.txt"; constexpr std::chrono::milliseconds MAPREG_AUTOSAVE_INTERVAL = std::chrono::seconds(10); -Map<std::string, int> scriptlabel_db; -UPMap<std::string, const ScriptBuffer> userfunc_db; +Map<ScriptLabel, int> scriptlabel_db; +UPMap<FString, const ScriptBuffer> userfunc_db; static const char *pos[11] = @@ -101,13 +102,13 @@ void run_func(ScriptState *st); static void mapreg_setreg(SIR num, int val); static -void mapreg_setregstr(SIR num, const char *str); +void mapreg_setregstr(SIR num, XString str); struct BuiltinFunction { void (*func)(ScriptState *); - const char *name; - const char *arg; + ZString name; + ZString arg; }; // defined later extern BuiltinFunction builtin_functions[]; @@ -132,29 +133,21 @@ enum class ByteCode : uint8_t }; static -str_data_t *search_strp(const std::string& p) +str_data_t *search_strp(XString p) { return str_datam.search(p); } static -str_data_t *add_strp(const std::string& p) +str_data_t *add_strp(XString p) { - // TODO remove lowcase - std::string lowcase = p; - for (char& c : lowcase) - c = tolower(c); - - if (str_data_t *rv = search_strp(lowcase)) - return rv; - - // ? if (str_data_t *rv = search_strp(p)) return rv; - str_data_t *datum = str_datam.init(p); + FString p2 = p; + str_data_t *datum = str_datam.init(p2); datum->type = ByteCode::NOP; - datum->strs = p; + datum->strs = p2; datum->backpatch = -1; datum->label_ = -1; return datum; @@ -266,7 +259,7 @@ void ScriptBuffer::set_label(str_data_t *ld, int pos_) *------------------------------------------ */ static -const char *skip_space(const char *p) +ZString::iterator skip_space(ZString::iterator p) { while (1) { @@ -296,7 +289,7 @@ const char *skip_space(const char *p) *------------------------------------------ */ static -const char *skip_word(const char *p) +ZString::iterator skip_word(ZString::iterator p) { // prefix if (*p == '$') @@ -320,8 +313,10 @@ const char *skip_word(const char *p) return p; } +// TODO: replace this whole mess with some sort of input stream that works +// a line at a time. static -const char *startptr; +ZString startptr; static int startline; @@ -331,30 +326,23 @@ int script_errors = 0; *------------------------------------------ */ static -void disp_error_message(const char *mes, const char *pos_) +void disp_error_message(ZString mes, ZString::iterator pos_) { script_errors++; + assert (startptr.begin() <= pos_ && pos_ <= startptr.end()); + int line; - const char *p; + ZString::iterator p; - for (line = startline, p = startptr; p && *p; line++) + for (line = startline, p = startptr.begin(); p != startptr.end(); line++) { - const char *linestart = p; - char *lineend = const_cast<char *>(strchr(p, '\n')); - // always initialized, but clang is not smart enough - char c = '\0'; - if (lineend) - { - c = *lineend; - *lineend = 0; - } - if (lineend == NULL || pos_ < lineend) + ZString::iterator linestart = p; + ZString::iterator lineend = std::find(p, startptr.end(), '\n'); + if (pos_ < lineend) { PRINTF("\n%s\nline %d : ", mes, line); - for (int i = 0; - (linestart[i] != '\r') && (linestart[i] != '\n') - && linestart[i]; i++) + for (int i = 0; linestart + i != lineend; i++) { if (linestart + i != pos_) PRINTF("%c", linestart[i]); @@ -362,11 +350,8 @@ void disp_error_message(const char *mes, const char *pos_) PRINTF("\'%c\'", linestart[i]); } PRINTF("\a\n"); - if (lineend) - *lineend = c; return; } - *lineend = c; p = lineend + 1; } } @@ -375,9 +360,8 @@ void disp_error_message(const char *mes, const char *pos_) * 項の解析 *------------------------------------------ */ -const char *ScriptBuffer::parse_simpleexpr(const char *p) +ZString::iterator ScriptBuffer::parse_simpleexpr(ZString::iterator p) { - int i; p = skip_space(p); if (*p == ';' || *p == ',') @@ -399,9 +383,9 @@ const char *ScriptBuffer::parse_simpleexpr(const char *p) else if (isdigit(*p) || ((*p == '-' || *p == '+') && isdigit(p[1]))) { char *np; - i = strtoul(p, &np, 0); + int i = strtoul(&*p, &np, 0); add_scripti(i); - p = np; + p += np - &*p; } else if (*p == '"') { @@ -409,7 +393,7 @@ const char *ScriptBuffer::parse_simpleexpr(const char *p) p++; while (*p && *p != '"') { - if (p[-1] <= 0x7e && *p == '\\') + if (*p == '\\') p++; else if (*p == '\n') { @@ -429,13 +413,13 @@ const char *ScriptBuffer::parse_simpleexpr(const char *p) else { // label , register , function etc - const char *p2 = skip_word(p); + ZString::iterator p2 = skip_word(p); if (p2 == p) { disp_error_message("unexpected character", p); exit(1); } - std::string word(p, p2); + XString word(&*p, &*p2, nullptr); if (parse_cmd_if && (word == "callsub" || word == "callfunc")) { disp_error_message("callsub/callfunc not allowed in an if statement", p); @@ -476,7 +460,7 @@ const char *ScriptBuffer::parse_simpleexpr(const char *p) * 式の解析 *------------------------------------------ */ -const char *ScriptBuffer::parse_subexpr(const char *p, int limit) +ZString::iterator ScriptBuffer::parse_subexpr(ZString::iterator p, int limit) { ByteCode op; int opl, len; @@ -485,7 +469,7 @@ const char *ScriptBuffer::parse_subexpr(const char *p, int limit) if (*p == '-') { - const char *tmpp = skip_space(p + 1); + ZString::iterator tmpp = skip_space(p + 1); if (*tmpp == ';' || *tmpp == ',') { add_scriptl(&LABEL_NEXTLINE_); @@ -493,7 +477,7 @@ const char *ScriptBuffer::parse_subexpr(const char *p, int limit) return p; } } - const char *tmpp = p; + ZString::iterator tmpp = p; if ((op = ByteCode::NEG, *p == '-') || (op = ByteCode::LNOT, *p == '!') || (op = ByteCode::NOT, *p == '~')) { @@ -528,7 +512,7 @@ const char *ScriptBuffer::parse_subexpr(const char *p, int limit) { int i = 0; str_data_t *funcp = parse_cmdp; - const char *plist[128]; + ZString::iterator plist[128]; if (funcp->type != ByteCode::FUNC_) { @@ -563,7 +547,7 @@ const char *ScriptBuffer::parse_subexpr(const char *p, int limit) if (funcp->type == ByteCode::FUNC_ && script_config.warn_func_mismatch_paramnum) { - const char *arg = builtin_functions[funcp->val].arg; + ZString arg = builtin_functions[funcp->val].arg; int j = 0; for (j = 0; arg[j]; j++) if (arg[j] == '*') @@ -571,7 +555,7 @@ const char *ScriptBuffer::parse_subexpr(const char *p, int limit) if ((arg[j] == 0 && i != j) || (arg[j] == '*' && i < j)) { disp_error_message("illegal number of parameters", - plist[(i < j) ? i : j]); + plist[std::min(i, j)]); } } } @@ -589,7 +573,7 @@ const char *ScriptBuffer::parse_subexpr(const char *p, int limit) * 式の評価 *------------------------------------------ */ -const char *ScriptBuffer::parse_expr(const char *p) +ZString::iterator ScriptBuffer::parse_expr(ZString::iterator p) { switch (*p) { @@ -610,10 +594,10 @@ const char *ScriptBuffer::parse_expr(const char *p) * 行の解析 *------------------------------------------ */ -const char *ScriptBuffer::parse_line(const char *p) +ZString::iterator ScriptBuffer::parse_line(ZString::iterator p) { int i = 0; - const char *plist[128]; + ZString::iterator plist[128]; p = skip_space(p); if (*p == ';') @@ -622,7 +606,7 @@ const char *ScriptBuffer::parse_line(const char *p) parse_cmd_if = 0; // warn_cmd_no_commaのために必要 // 最初は関数名 - const char *p2 = p; + ZString::iterator p2 = p; p = parse_simpleexpr(p); p = skip_space(p); @@ -634,7 +618,7 @@ const char *ScriptBuffer::parse_line(const char *p) } add_scriptc(ByteCode::ARG); - while (p && *p && *p != ';' && i < 128) + while (*p && *p != ';' && i < 128) { plist[i] = p; @@ -652,7 +636,7 @@ const char *ScriptBuffer::parse_line(const char *p) i++; } plist[i] = p; - if (!p || *(p++) != ';') + if (*(p++) != ';') { disp_error_message("need ';'", p); exit(1); @@ -662,7 +646,7 @@ const char *ScriptBuffer::parse_line(const char *p) if (cmd->type == ByteCode::FUNC_ && script_config.warn_cmd_mismatch_paramnum) { - const char *arg = builtin_functions[cmd->val].arg; + ZString arg = builtin_functions[cmd->val].arg; int j = 0; for (j = 0; arg[j]; j++) if (arg[j] == '*') @@ -670,7 +654,7 @@ const char *ScriptBuffer::parse_line(const char *p) if ((arg[j] == 0 && i != j) || (arg[j] == '*' && i < j)) { disp_error_message("illegal number of parameters", - plist[(i < j) ? i : j]); + plist[std::min(i, j)]); } } @@ -706,26 +690,24 @@ void read_constdb(void) return; } - std::string line; - while (std::getline(in, line)) + FString line; + while (io::getline(in, line)) { - if (line[0] == '/' && line[1] == '/') + if (line.startswith("//")) continue; - std::string name; + FString name; int val; int type = 0; // if not provided if (SSCANF(line, "%m[A-Za-z0-9_] %i %i", &name, &val, &type) < 2) continue; - for (char& c : name) - c = tolower(c); str_data_t *n = add_strp(name); n->type = type ? ByteCode::PARAM_ : ByteCode::INT; n->val = val; } } -std::unique_ptr<const ScriptBuffer> parse_script(const char *src, int line) +std::unique_ptr<const ScriptBuffer> parse_script(ZString src, int line) { auto script_buf = make_unique<ScriptBuffer>(); script_buf->parse_script(src, line); @@ -736,9 +718,8 @@ std::unique_ptr<const ScriptBuffer> parse_script(const char *src, int line) * スクリプトの解析 *------------------------------------------ */ -void ScriptBuffer::parse_script(const char *src, int line) +void ScriptBuffer::parse_script(ZString src, int line) { - const char *p; static int first = 1; if (first) @@ -768,21 +749,20 @@ void ScriptBuffer::parse_script(const char *src, int line) startptr = src; startline = line; - p = src; + ZString::iterator p = src.begin(); p = skip_space(p); if (*p != '{') { disp_error_message("not found '{'", p); abort(); } - for (p++; p && *p && *p != '}';) + for (p++; *p && *p != '}';) { p = skip_space(p); - // labelだけ特殊処理 if (*skip_space(skip_word(p)) == ':') { - const char *tmpp = skip_word(p); - std::string str(p, tmpp); + ZString::iterator tmpp = skip_word(p); + XString str(&*p, &*tmpp, nullptr); str_data_t *ld = add_strp(str); bool e1 = ld->type != ByteCode::NOP; bool e2 = ld->type == ByteCode::POS; @@ -794,7 +774,7 @@ void ScriptBuffer::parse_script(const char *src, int line) exit(1); } set_label(ld, script_buf.size()); - scriptlabel_db.insert(str, script_buf.size()); + scriptlabel_db.insert(stringish<ScriptLabel>(str), script_buf.size()); p = tmpp + 1; continue; } @@ -894,7 +874,8 @@ void get_val(ScriptState *st, struct script_data *data) } else if (data->type == ByteCode::VARIABLE) { - const std::string& name = variable_names.outtern(data->u.reg.base()); + ZString name_ = variable_names.outtern(data->u.reg.base()); + VarName name = stringish<VarName>(name_); char prefix = name.front(); char postfix = name.back(); @@ -913,8 +894,8 @@ void get_val(ScriptState *st, struct script_data *data) } else if (prefix == '$') { - std::string *s = mapregstr_db.search(data->u.reg); - data->u.str = s ? dumb_string::fake(s->c_str()) : dumb_string(); + FString *s = mapregstr_db.search(data->u.reg); + data->u.str = s ? dumb_string::fake(*s) : dumb_string(); } else { @@ -941,18 +922,18 @@ void get_val(ScriptState *st, struct script_data *data) if (name[1] == '#') { if (sd) - data->u.numi = pc_readaccountreg2(sd, name.c_str()); + data->u.numi = pc_readaccountreg2(sd, name); } else { if (sd) - data->u.numi = pc_readaccountreg(sd, name.c_str()); + data->u.numi = pc_readaccountreg(sd, name); } } else { if (sd) - data->u.numi = pc_readglobalreg(sd, name.c_str()); + data->u.numi = pc_readglobalreg(sd, name); } } } @@ -988,7 +969,8 @@ void set_reg(dumb_ptr<map_session_data> sd, ByteCode type, SIR reg, struct scrip } assert (type == ByteCode::VARIABLE); - const std::string& name = variable_names.outtern(reg.base()); + ZString name_ = variable_names.outtern(reg.base()); + VarName name = stringish<VarName>(name_); char prefix = name.front(); char postfix = name.back(); @@ -997,11 +979,11 @@ void set_reg(dumb_ptr<map_session_data> sd, ByteCode type, SIR reg, struct scrip dumb_string str = vd.u.str; if (prefix == '@' || prefix == 'l') { - pc_setregstr(sd, reg, str.c_str()); + pc_setregstr(sd, reg, str.str()); } else if (prefix == '$') { - mapreg_setregstr(reg, str.c_str()); + mapreg_setregstr(reg, str.str()); } else { @@ -1023,13 +1005,13 @@ void set_reg(dumb_ptr<map_session_data> sd, ByteCode type, SIR reg, struct scrip else if (prefix == '#') { if (name[1] == '#') - pc_setaccountreg2(sd, name.c_str(), val); + pc_setaccountreg2(sd, name, val); else - pc_setaccountreg(sd, name.c_str(), val); + pc_setaccountreg(sd, name, val); } else { - pc_setglobalreg(sd, name.c_str(), val); + pc_setglobalreg(sd, name, val); } } } @@ -1063,7 +1045,7 @@ dumb_string conv_str(ScriptState *st, struct script_data *data) assert (data->type != ByteCode::RETINFO); if (data->type == ByteCode::INT) { - std::string buf = STRPRINTF("%d", data->u.numi); + FString buf = STRPRINTF("%d", data->u.numi); data->type = ByteCode::STR; data->u.str = dumb_string::copys(buf); } @@ -1193,7 +1175,7 @@ static void builtin_mes(ScriptState *st) { dumb_string mes = conv_str(st, &AARGO2(2)); - clif_scriptmes(script_rid2sd(st), st->oid, mes.c_str()); + clif_scriptmes(script_rid2sd(st), st->oid, ZString(mes)); } /*========================================== @@ -1334,17 +1316,17 @@ void builtin_menu(ScriptState *st) st->state = ScriptEndState::RERUNLINE; sd->state.menu_or_input = 1; - std::string buf; + MString buf; for (int i = st->start + 2; i < st->end; i += 2) { dumb_string choice_str = conv_str(st, &AARGO2(i - st->start)); if (!choice_str[0]) break; - buf += choice_str.c_str(); + buf += ZString(choice_str); buf += ':'; } - clif_scriptmenu(script_rid2sd(st), st->oid, buf.c_str()); + clif_scriptmenu(script_rid2sd(st), st->oid, FString(buf)); } else { @@ -1427,14 +1409,13 @@ void builtin_isat(ScriptState *st) int x, y; dumb_ptr<map_session_data> sd = script_rid2sd(st); - dumb_string str = conv_str(st, &AARGO2(2)); + MapName str = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); x = conv_num(st, &AARGO2(3)); y = conv_num(st, &AARGO2(4)); if (!sd) return; - using namespace operators; push_int(st->stack, ByteCode::INT, (x == sd->bl_x) && (y == sd->bl_y) && (str == sd->bl_m->name_)); @@ -1450,10 +1431,9 @@ void builtin_warp(ScriptState *st) int x, y; dumb_ptr<map_session_data> sd = script_rid2sd(st); - dumb_string str = conv_str(st, &AARGO2(2)); + MapName str = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); x = conv_num(st, &AARGO2(3)); y = conv_num(st, &AARGO2(4)); - using namespace operators; if (str == "Random") pc_randomwarp(sd, BeingRemoveWhy::WARPED); else if (str == "SavePoint") @@ -1461,19 +1441,19 @@ void builtin_warp(ScriptState *st) if (sd->bl_m->flag.noreturn) // 蝶禁止 return; - pc_setpos(sd, sd->status.save_point.map_, - sd->status.save_point.x, sd->status.save_point.y, BeingRemoveWhy::WARPED); + pc_setpos(sd, sd->status.save_point.map_, sd->status.save_point.x, sd->status.save_point.y, + BeingRemoveWhy::WARPED); } else if (str == "Save") { if (sd->bl_m->flag.noreturn) // 蝶禁止 return; - pc_setpos(sd, sd->status.save_point.map_, - sd->status.save_point.x, sd->status.save_point.y, BeingRemoveWhy::WARPED); + pc_setpos(sd, sd->status.save_point.map_, sd->status.save_point.x, sd->status.save_point.y, + BeingRemoveWhy::WARPED); } else - pc_setpos(sd, str.c_str(), x, y, BeingRemoveWhy::GONE); + pc_setpos(sd, str, x, y, BeingRemoveWhy::GONE); } /*========================================== @@ -1481,14 +1461,13 @@ void builtin_warp(ScriptState *st) *------------------------------------------ */ static -void builtin_areawarp_sub(dumb_ptr<block_list> bl, dumb_string mapname, int x, int y) +void builtin_areawarp_sub(dumb_ptr<block_list> bl, MapName mapname, int x, int y) { dumb_ptr<map_session_data> sd = bl->as_player(); - using namespace operators; if (mapname == "Random") pc_randomwarp(sd, BeingRemoveWhy::WARPED); else - pc_setpos(sd, mapname.c_str(), x, y, BeingRemoveWhy::GONE); + pc_setpos(sd, mapname, x, y, BeingRemoveWhy::GONE); } static @@ -1497,16 +1476,16 @@ void builtin_areawarp(ScriptState *st) int x, y; int x0, y0, x1, y1; - dumb_string mapname = conv_str(st, &AARGO2(2)); + MapName mapname = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); x0 = conv_num(st, &AARGO2(3)); y0 = conv_num(st, &AARGO2(4)); x1 = conv_num(st, &AARGO2(5)); y1 = conv_num(st, &AARGO2(6)); - dumb_string str = conv_str(st, &AARGO2(7)); + MapName str = stringish<MapName>(ZString(conv_str(st, &AARGO2(7)))); x = conv_num(st, &AARGO2(8)); y = conv_num(st, &AARGO2(9)); - map_local *m = map_mapname2mapid(mapname.c_str()); + map_local *m = map_mapname2mapid(mapname); if (m == nullptr) return; @@ -1572,7 +1551,7 @@ void builtin_input(ScriptState *st) assert (type == ByteCode::VARIABLE); SIR reg = scrd.u.reg; - const std::string& name = variable_names.outtern(reg.base()); + ZString name = variable_names.outtern(reg.base()); // char prefix = name.front(); char postfix = name.back(); @@ -1583,7 +1562,7 @@ void builtin_input(ScriptState *st) sd->state.menu_or_input = 0; if (postfix == '$') { - set_reg(sd, type, reg, dumb_string::fake(sd->npc_str.c_str())); + set_reg(sd, type, reg, dumb_string::fake(sd->npc_str)); } else { @@ -1653,7 +1632,7 @@ void builtin_set(ScriptState *st) set_reg(sd, ByteCode::PARAM_, reg, val); return; } - const std::string& name = variable_names.outtern(reg.base()); + ZString name = variable_names.outtern(reg.base()); char prefix = name.front(); char postfix = name.back(); @@ -1687,7 +1666,7 @@ void builtin_setarray(ScriptState *st) dumb_ptr<map_session_data> sd = NULL; assert (AARGO2(2).type == ByteCode::VARIABLE); SIR reg = AARGO2(2).u.reg; - const std::string& name = variable_names.outtern(reg.base()); + ZString name = variable_names.outtern(reg.base()); char prefix = name.front(); char postfix = name.back(); @@ -1718,7 +1697,7 @@ void builtin_cleararray(ScriptState *st) dumb_ptr<map_session_data> sd = NULL; assert (AARGO2(2).type == ByteCode::VARIABLE); SIR reg = AARGO2(2).u.reg; - const std::string& name = variable_names.outtern(reg.base()); + ZString name = variable_names.outtern(reg.base()); char prefix = name.front(); char postfix = name.back(); int sz = conv_num(st, &AARGO2(4)); @@ -1764,7 +1743,7 @@ void builtin_getarraysize(ScriptState *st) { assert (AARGO2(2).type == ByteCode::VARIABLE); SIR reg = AARGO2(2).u.reg; - const std::string& name = variable_names.outtern(reg.base()); + ZString name = variable_names.outtern(reg.base()); char prefix = name.front(); char postfix = name.back(); @@ -1838,8 +1817,8 @@ void builtin_countitem(ScriptState *st) get_val(st, data); if (data->type == ByteCode::STR || data->type == ByteCode::CONSTSTR) { - dumb_string name = conv_str(st, data); - struct item_data *item_data = itemdb_searchname(name.c_str()); + ItemName name = stringish<ItemName>(ZString(conv_str(st, data))); + struct item_data *item_data = itemdb_searchname(name); if (item_data != NULL) nameid = item_data->nameid; } @@ -1878,8 +1857,8 @@ void builtin_checkweight(ScriptState *st) get_val(st, data); if (data->type == ByteCode::STR || data->type == ByteCode::CONSTSTR) { - dumb_string name = conv_str(st, data); - struct item_data *item_data = itemdb_searchname(name.c_str()); + ItemName name = stringish<ItemName>(ZString(conv_str(st, data))); + struct item_data *item_data = itemdb_searchname(name); if (item_data) nameid = item_data->nameid; } @@ -1922,8 +1901,8 @@ void builtin_getitem(ScriptState *st) get_val(st, data); if (data->type == ByteCode::STR || data->type == ByteCode::CONSTSTR) { - dumb_string name = conv_str(st, data); - struct item_data *item_data = itemdb_searchname(name.c_str()); + ItemName name = stringish<ItemName>(ZString(conv_str(st, data))); + struct item_data *item_data = itemdb_searchname(name); nameid = 727; //Default to iten if (item_data != NULL) nameid = item_data->nameid; @@ -1976,8 +1955,8 @@ void builtin_makeitem(ScriptState *st) get_val(st, data); if (data->type == ByteCode::STR || data->type == ByteCode::CONSTSTR) { - dumb_string name = conv_str(st, data); - struct item_data *item_data = itemdb_searchname(name.c_str()); + ItemName name = stringish<ItemName>(ZString(conv_str(st, data))); + struct item_data *item_data = itemdb_searchname(name); nameid = 512; //Apple Item ID if (item_data) nameid = item_data->nameid; @@ -1986,16 +1965,15 @@ void builtin_makeitem(ScriptState *st) nameid = conv_num(st, data); amount = conv_num(st, &AARGO2(3)); - dumb_string mapname = conv_str(st, &AARGO2(4)); + MapName mapname = stringish<MapName>(ZString(conv_str(st, &AARGO2(4)))); x = conv_num(st, &AARGO2(5)); y = conv_num(st, &AARGO2(6)); map_local *m; - using namespace operators; - if (sd && mapname == "this") + if (sd && mapname == MOB_THIS_MAP) m = sd->bl_m; else - m = map_mapname2mapid(mapname.c_str()); + m = map_mapname2mapid(mapname); if (nameid > 0) { @@ -2028,8 +2006,8 @@ void builtin_delitem(ScriptState *st) get_val(st, data); if (data->type == ByteCode::STR || data->type == ByteCode::CONSTSTR) { - dumb_string name = conv_str(st, data); - struct item_data *item_data = itemdb_searchname(name.c_str()); + ItemName name = stringish<ItemName>(ZString(conv_str(st, data))); + struct item_data *item_data = itemdb_searchname(name); //nameid=512; if (item_data) nameid = item_data->nameid; @@ -2087,7 +2065,7 @@ void builtin_readparam(ScriptState *st) SP type = SP(conv_num(st, &AARGO2(2))); if (HARGO2(3)) - sd = map_nick2sd(conv_str(st, &AARGO2(3)).c_str()); + sd = map_nick2sd(stringish<CharName>(ZString(conv_str(st, &AARGO2(3))))); else sd = script_rid2sd(st); @@ -2113,7 +2091,7 @@ void builtin_getcharid(ScriptState *st) num = conv_num(st, &AARGO2(2)); if (HARGO2(3)) - sd = map_nick2sd(conv_str(st, &AARGO2(3)).c_str()); + sd = map_nick2sd(stringish<CharName>(ZString(conv_str(st, &AARGO2(3))))); else sd = script_rid2sd(st); if (sd == NULL) @@ -2141,7 +2119,7 @@ dumb_string builtin_getpartyname_sub(int party_id) struct party *p = party_search(party_id); if (p) - return dumb_string::copy(p->name); + return dumb_string::copys(p->name); return dumb_string(); } @@ -2160,7 +2138,7 @@ void builtin_strcharinfo(ScriptState *st) num = conv_num(st, &AARGO2(2)); if (num == 0) { - dumb_string buf = dumb_string::copy(sd->status.name); + dumb_string buf = dumb_string::copys(sd->status.name.to__actual()); push_str(st->stack, ByteCode::STR, buf); } if (num == 1) @@ -2240,7 +2218,7 @@ void builtin_getequipname(ScriptState *st) dumb_ptr<map_session_data> sd; struct item_data *item; - std::string buf; + FString buf; sd = script_rid2sd(st); num = conv_num(st, &AARGO2(2)); @@ -2418,10 +2396,10 @@ void builtin_savepoint(ScriptState *st) { int x, y; - dumb_string str = conv_str(st, &AARGO2(2)); + MapName str = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); x = conv_num(st, &AARGO2(3)); y = conv_num(st, &AARGO2(4)); - pc_setsavepoint(script_rid2sd(st), str.c_str(), x, y); + pc_setsavepoint(script_rid2sd(st), str, x, y); } /*========================================== @@ -2551,19 +2529,19 @@ static void builtin_monster(ScriptState *st) { int mob_class, amount, x, y; - const char *event = ""; + NpcEvent event; - dumb_string mapname = conv_str(st, &AARGO2(2)); + MapName mapname = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); x = conv_num(st, &AARGO2(3)); y = conv_num(st, &AARGO2(4)); - dumb_string str = conv_str(st, &AARGO2(5)); + MobName str = stringish<MobName>(ZString(conv_str(st, &AARGO2(5)))); mob_class = conv_num(st, &AARGO2(6)); amount = conv_num(st, &AARGO2(7)); if (HARGO2(8)) - event = conv_str(st, &AARGO2(8)).c_str(); + extract(ZString(conv_str(st, &AARGO2(8))), &event); - mob_once_spawn(map_id2sd(st->rid), mapname.c_str(), x, y, str.c_str(), mob_class, amount, - event); + mob_once_spawn(map_id2sd(st->rid), mapname, x, y, str, mob_class, amount, + event); } /*========================================== @@ -2574,21 +2552,21 @@ static void builtin_areamonster(ScriptState *st) { int mob_class, amount, x0, y0, x1, y1; - const char *event = ""; + NpcEvent event; - dumb_string mapname = conv_str(st, &AARGO2(2)); + MapName mapname = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); x0 = conv_num(st, &AARGO2(3)); y0 = conv_num(st, &AARGO2(4)); x1 = conv_num(st, &AARGO2(5)); y1 = conv_num(st, &AARGO2(6)); - dumb_string str = conv_str(st, &AARGO2(7)); + MobName str = stringish<MobName>(ZString(conv_str(st, &AARGO2(7)))); mob_class = conv_num(st, &AARGO2(8)); amount = conv_num(st, &AARGO2(9)); if (HARGO2(10)) - event = conv_str(st, &AARGO2(10)).c_str(); + extract(ZString(conv_str(st, &AARGO2(10))), &event); - mob_once_spawn_area(map_id2sd(st->rid), mapname.c_str(), x0, y0, x1, y1, str.c_str(), mob_class, - amount, event); + mob_once_spawn_area(map_id2sd(st->rid), mapname, x0, y0, x1, y1, str, mob_class, + amount, event); } /*========================================== @@ -2596,17 +2574,16 @@ void builtin_areamonster(ScriptState *st) *------------------------------------------ */ static -void builtin_killmonster_sub(dumb_ptr<block_list> bl, dumb_string event, int allflag) +void builtin_killmonster_sub(dumb_ptr<block_list> bl, NpcEvent event) { dumb_ptr<mob_data> md = bl->as_mob(); - if (!allflag) + if (event) { - using namespace operators; if (event == md->npc_event) mob_delete(md); return; } - else if (allflag) + else if (!event) { if (md->spawn.delay1 == static_cast<interval_t>(-1) && md->spawn.delay2 == static_cast<interval_t>(-1)) @@ -2618,17 +2595,16 @@ void builtin_killmonster_sub(dumb_ptr<block_list> bl, dumb_string event, int all static void builtin_killmonster(ScriptState *st) { - int allflag = 0; - dumb_string mapname = conv_str(st, &AARGO2(2)); - dumb_string event = conv_str(st, &AARGO2(3)); - using namespace operators; - if (event == "All") - allflag = 1; + MapName mapname = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); + ZString event_ = ZString(conv_str(st, &AARGO2(3))); + NpcEvent event; + if (event_ != "All") + extract(event_, &event); - map_local *m = map_mapname2mapid(mapname.c_str()); + map_local *m = map_mapname2mapid(mapname); if (m == nullptr) return; - map_foreachinarea(std::bind(builtin_killmonster_sub, ph::_1, event, allflag), + map_foreachinarea(std::bind(builtin_killmonster_sub, ph::_1, event), m, 0, 0, m->xs, m->ys, @@ -2644,9 +2620,9 @@ void builtin_killmonsterall_sub(dumb_ptr<block_list> bl) static void builtin_killmonsterall(ScriptState *st) { - dumb_string mapname = conv_str(st, &AARGO2(2)); + MapName mapname = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); - map_local *m = map_mapname2mapid(mapname.c_str()); + map_local *m = map_mapname2mapid(mapname); if (m == nullptr) return; map_foreachinarea(builtin_killmonsterall_sub, @@ -2663,8 +2639,10 @@ void builtin_killmonsterall(ScriptState *st) static void builtin_donpcevent(ScriptState *st) { - dumb_string event = conv_str(st, &AARGO2(2)); - npc_event_do(event.c_str()); + ZString event_ = ZString(conv_str(st, &AARGO2(2))); + NpcEvent event; + extract(event_, &event); + npc_event_do(event); } /*========================================== @@ -2675,8 +2653,10 @@ static void builtin_addtimer(ScriptState *st) { interval_t tick = static_cast<interval_t>(conv_num(st, &AARGO2(2))); - dumb_string event = conv_str(st, &AARGO2(3)); - pc_addeventtimer(script_rid2sd(st), tick, event.c_str()); + ZString event_ = ZString(conv_str(st, &AARGO2(3))); + NpcEvent event; + extract(event_, &event); + pc_addeventtimer(script_rid2sd(st), tick, event); } /*========================================== @@ -2688,7 +2668,7 @@ void builtin_initnpctimer(ScriptState *st) { dumb_ptr<npc_data> nd_; if (HARGO2(2)) - nd_ = npc_name2id(conv_str(st, &AARGO2(2)).c_str()); + nd_ = npc_name2id(stringish<NpcName>(ZString(conv_str(st, &AARGO2(2))))); else nd_ = map_id_as_npc(st->oid); assert (nd_ && nd_->npc_subtype == NpcSubtype::SCRIPT); @@ -2707,7 +2687,7 @@ void builtin_startnpctimer(ScriptState *st) { dumb_ptr<npc_data> nd_; if (HARGO2(2)) - nd_ = npc_name2id(conv_str(st, &AARGO2(2)).c_str()); + nd_ = npc_name2id(stringish<NpcName>(ZString(conv_str(st, &AARGO2(2))))); else nd_ = map_id_as_npc(st->oid); assert (nd_ && nd_->npc_subtype == NpcSubtype::SCRIPT); @@ -2725,7 +2705,7 @@ void builtin_stopnpctimer(ScriptState *st) { dumb_ptr<npc_data> nd_; if (HARGO2(2)) - nd_ = npc_name2id(conv_str(st, &AARGO2(2)).c_str()); + nd_ = npc_name2id(stringish<NpcName>(ZString(conv_str(st, &AARGO2(2))))); else nd_ = map_id_as_npc(st->oid); assert (nd_ && nd_->npc_subtype == NpcSubtype::SCRIPT); @@ -2745,7 +2725,7 @@ void builtin_getnpctimer(ScriptState *st) int type = conv_num(st, &AARGO2(2)); int val = 0; if (HARGO2(3)) - nd_ = npc_name2id(conv_str(st, &AARGO2(3)).c_str()); + nd_ = npc_name2id(stringish<NpcName>(ZString(conv_str(st, &AARGO2(3))))); else nd_ = map_id_as_npc(st->oid); assert (nd_ && nd_->npc_subtype == NpcSubtype::SCRIPT); @@ -2776,7 +2756,7 @@ void builtin_setnpctimer(ScriptState *st) dumb_ptr<npc_data> nd_; interval_t tick = static_cast<interval_t>(conv_num(st, &AARGO2(2))); if (HARGO2(3)) - nd_ = npc_name2id(conv_str(st, &AARGO2(3)).c_str()); + nd_ = npc_name2id(stringish<NpcName>(ZString(conv_str(st, &AARGO2(3))))); else nd_ = map_id_as_npc(st->oid); assert (nd_ && nd_->npc_subtype == NpcSubtype::SCRIPT); @@ -2793,7 +2773,7 @@ static void builtin_announce(ScriptState *st) { int flag; - dumb_string str = conv_str(st, &AARGO2(2)); + ZString str = ZString(conv_str(st, &AARGO2(2))); flag = conv_num(st, &AARGO2(3)); if (flag & 0x0f) @@ -2814,7 +2794,7 @@ void builtin_announce(ScriptState *st) *------------------------------------------ */ static -void builtin_mapannounce_sub(dumb_ptr<block_list> bl, dumb_string str, int flag) +void builtin_mapannounce_sub(dumb_ptr<block_list> bl, XString str, int flag) { clif_GMmessage(bl, str, flag | 3); } @@ -2824,11 +2804,11 @@ void builtin_mapannounce(ScriptState *st) { int flag; - dumb_string mapname = conv_str(st, &AARGO2(2)); - dumb_string str = conv_str(st, &AARGO2(3)); + MapName mapname = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); + ZString str = ZString(conv_str(st, &AARGO2(3))); flag = conv_num(st, &AARGO2(4)); - map_local *m = map_mapname2mapid(mapname.c_str()); + map_local *m = map_mapname2mapid(mapname); if (m == nullptr) return; map_foreachinarea(std::bind(builtin_mapannounce_sub, ph::_1, str, flag & 0x10), @@ -2867,8 +2847,8 @@ void builtin_getusers(ScriptState *st) static void builtin_getmapusers(ScriptState *st) { - dumb_string str = conv_str(st, &AARGO2(2)); - map_local *m = map_mapname2mapid(str.c_str()); + MapName str = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); + map_local *m = map_mapname2mapid(str); if (m == nullptr) { push_int(st->stack, ByteCode::INT, -1); @@ -2898,7 +2878,7 @@ static void builtin_getareausers(ScriptState *st) { int x0, y0, x1, y1, users = 0; - dumb_string str = conv_str(st, &AARGO2(2)); + MapName str = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); x0 = conv_num(st, &AARGO2(3)); y0 = conv_num(st, &AARGO2(4)); x1 = conv_num(st, &AARGO2(5)); @@ -2909,7 +2889,7 @@ void builtin_getareausers(ScriptState *st) { living = conv_num(st, &AARGO2(7)); } - map_local *m = map_mapname2mapid(str.c_str()); + map_local *m = map_mapname2mapid(str); if (m == nullptr) { push_int(st->stack, ByteCode::INT, -1); @@ -2956,7 +2936,7 @@ void builtin_getareadropitem(ScriptState *st) int x0, y0, x1, y1, item, amount = 0, delitems = 0; struct script_data *data; - dumb_string str = conv_str(st, &AARGO2(2)); + MapName str = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); x0 = conv_num(st, &AARGO2(3)); y0 = conv_num(st, &AARGO2(4)); x1 = conv_num(st, &AARGO2(5)); @@ -2966,8 +2946,8 @@ void builtin_getareadropitem(ScriptState *st) get_val(st, data); if (data->type == ByteCode::STR || data->type == ByteCode::CONSTSTR) { - dumb_string name = conv_str(st, data); - struct item_data *item_data = itemdb_searchname(name.c_str()); + ItemName name = stringish<ItemName>(ZString(conv_str(st, data))); + struct item_data *item_data = itemdb_searchname(name); item = 512; if (item_data) item = item_data->nameid; @@ -2978,7 +2958,7 @@ void builtin_getareadropitem(ScriptState *st) if (HARGO2(8)) delitems = conv_num(st, &AARGO2(8)); - map_local *m = map_mapname2mapid(str.c_str()); + map_local *m = map_mapname2mapid(str); if (m == nullptr) { push_int(st->stack, ByteCode::INT, -1); @@ -3007,8 +2987,8 @@ void builtin_getareadropitem(ScriptState *st) static void builtin_enablenpc(ScriptState *st) { - dumb_string str = conv_str(st, &AARGO2(2)); - npc_enable(str.c_str(), 1); + NpcName str = stringish<NpcName>(ZString(conv_str(st, &AARGO2(2)))); + npc_enable(str, 1); } /*========================================== @@ -3018,8 +2998,8 @@ void builtin_enablenpc(ScriptState *st) static void builtin_disablenpc(ScriptState *st) { - dumb_string str = conv_str(st, &AARGO2(2)); - npc_enable(str.c_str(), 0); + NpcName str = stringish<NpcName>(ZString(conv_str(st, &AARGO2(2)))); + npc_enable(str, 0); } /*========================================== @@ -3118,7 +3098,7 @@ void builtin_changesex(ScriptState *st) sd->status.sex = 0; sd->sex = 0; } - chrif_char_ask_name(-1, sd->status.name, 5, 0, 0, 0, 0, 0, 0); // type: 5 - changesex + chrif_char_ask_name(-1, sd->status.name, 5, HumanTimeDiff()); // type: 5 - changesex chrif_save(sd); } @@ -3187,9 +3167,9 @@ enum static void builtin_setmapflag(ScriptState *st) { - dumb_string str = conv_str(st, &AARGO2(2)); + MapName str = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); int i = conv_num(st, &AARGO2(3)); - map_local *m = map_mapname2mapid(str.c_str()); + map_local *m = map_mapname2mapid(str); if (m != nullptr) { switch (i) @@ -3247,9 +3227,9 @@ void builtin_setmapflag(ScriptState *st) static void builtin_removemapflag(ScriptState *st) { - dumb_string str = conv_str(st, &AARGO2(2)); + MapName str = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); int i = conv_num(st, &AARGO2(3)); - map_local *m = map_mapname2mapid(str.c_str()); + map_local *m = map_mapname2mapid(str); if (m != nullptr) { switch (i) @@ -3308,9 +3288,9 @@ void builtin_getmapflag(ScriptState *st) { int r = -1; - dumb_string str = conv_str(st, &AARGO2(2)); + MapName str = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); int i = conv_num(st, &AARGO2(3)); - map_local *m = map_mapname2mapid(str.c_str()); + map_local *m = map_mapname2mapid(str); if (m != nullptr) { switch (i) @@ -3369,8 +3349,8 @@ void builtin_getmapflag(ScriptState *st) static void builtin_pvpon(ScriptState *st) { - dumb_string str = conv_str(st, &AARGO2(2)); - map_local *m = map_mapname2mapid(str.c_str()); + MapName str = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); + map_local *m = map_mapname2mapid(str); if (m != nullptr && !m->flag.pvp && !m->flag.nopvp) { m->flag.pvp = 1; @@ -3403,8 +3383,8 @@ void builtin_pvpon(ScriptState *st) static void builtin_pvpoff(ScriptState *st) { - dumb_string str = conv_str(st, &AARGO2(2)); - map_local *m = map_mapname2mapid(str.c_str()); + MapName str = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); + map_local *m = map_mapname2mapid(str); if (m != nullptr && m->flag.pvp && m->flag.nopvp) { m->flag.pvp = 0; @@ -3450,13 +3430,13 @@ void builtin_mapwarp(ScriptState *st) // Added by RoVeRT int x, y; int x0, y0, x1, y1; - dumb_string mapname = conv_str(st, &AARGO2(2)); + MapName mapname = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); x0 = 0; y0 = 0; - map_local *m = map_mapname2mapid(mapname.c_str()); + map_local *m = map_mapname2mapid(mapname); x1 = m->xs; y1 = m->ys; - dumb_string str = conv_str(st, &AARGO2(3)); + MapName str = stringish<MapName>(ZString(conv_str(st, &AARGO2(3)))); x = conv_num(st, &AARGO2(4)); y = conv_num(st, &AARGO2(5)); @@ -3473,16 +3453,15 @@ void builtin_mapwarp(ScriptState *st) // Added by RoVeRT static void builtin_cmdothernpc(ScriptState *st) // Added by RoVeRT { - dumb_string npc = conv_str(st, &AARGO2(2)); - dumb_string command = conv_str(st, &AARGO2(3)); + NpcName npc = stringish<NpcName>(ZString(conv_str(st, &AARGO2(2)))); + ZString command = ZString(conv_str(st, &AARGO2(3))); - npc_command(map_id2sd(st->rid), npc.c_str(), command.c_str()); + npc_command(map_id2sd(st->rid), npc, command); } static -void builtin_mobcount_sub(dumb_ptr<block_list> bl, dumb_string event, int *c) +void builtin_mobcount_sub(dumb_ptr<block_list> bl, NpcEvent event, int *c) { - using namespace operators; if (event == bl->as_mob()->npc_event) (*c)++; } @@ -3491,10 +3470,12 @@ static void builtin_mobcount(ScriptState *st) // Added by RoVeRT { int c = 0; - dumb_string mapname = conv_str(st, &AARGO2(2)); - dumb_string event = conv_str(st, &AARGO2(3)); + MapName mapname = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); + ZString event_ = ZString(conv_str(st, &AARGO2(3))); + NpcEvent event; + extract(event_, &event); - map_local *m = map_mapname2mapid(mapname.c_str()); + map_local *m = map_mapname2mapid(mapname); if (m == nullptr) { push_int(st->stack, ByteCode::INT, -1); @@ -3513,9 +3494,9 @@ void builtin_mobcount(ScriptState *st) // Added by RoVeRT static void builtin_marriage(ScriptState *st) { - dumb_string partner = conv_str(st, &AARGO2(2)); + CharName partner = stringish<CharName>(ZString(conv_str(st, &AARGO2(2)))); dumb_ptr<map_session_data> sd = script_rid2sd(st); - dumb_ptr<map_session_data> p_sd = map_nick2sd(partner.c_str()); + dumb_ptr<map_session_data> p_sd = map_nick2sd(partner); if (sd == NULL || p_sd == NULL || pc_marriage(sd, p_sd) < 0) { @@ -3557,8 +3538,8 @@ void builtin_getitemname(ScriptState *st) get_val(st, data); if (data->type == ByteCode::STR || data->type == ByteCode::CONSTSTR) { - dumb_string name = conv_str(st, data); - i_data = itemdb_searchname(name.c_str()); + ItemName name = stringish<ItemName>(ZString(conv_str(st, data))); + i_data = itemdb_searchname(name); } else { @@ -3568,9 +3549,9 @@ void builtin_getitemname(ScriptState *st) dumb_string item_name; if (i_data) - item_name = dumb_string::copy(i_data->jname); + item_name = dumb_string::copys(i_data->jname); else - item_name = dumb_string::copy("Unknown Item"); + item_name = dumb_string::copys("Unknown Item"); push_str(st->stack, ByteCode::STR, item_name); } @@ -3580,11 +3561,11 @@ void builtin_getspellinvocation(ScriptState *st) { dumb_string name = conv_str(st, &AARGO2(2)); - const char *invocation = magic_find_invocation(name.str()); + FString invocation = magic_find_invocation(name.str()); if (!invocation) invocation = "..."; - push_str(st->stack, ByteCode::STR, dumb_string::copy(invocation)); + push_str(st->stack, ByteCode::STR, dumb_string::copys(invocation)); } static @@ -3661,7 +3642,7 @@ void builtin_getactivatedpoolskilllist(ScriptState *st) pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_flag"), count), static_cast<uint16_t>(sd->status.skill[skill_id].flags)); pc_setregstr(sd, SIR::from(variable_names.intern("@skilllist_name$"), count), - skill_name(skill_id).c_str()); + skill_name(skill_id)); ++count; } } @@ -3692,7 +3673,7 @@ void builtin_getunactivatedpoolskilllist(ScriptState *st) pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_flag"), count), static_cast<uint16_t>(sd->status.skill[skill_id].flags)); pc_setregstr(sd, SIR::from(variable_names.intern("@skilllist_name$"), count), - skill_name(skill_id).c_str()); + skill_name(skill_id)); ++count; } } @@ -3737,7 +3718,7 @@ void builtin_misceffect(ScriptState *st) { int type; int id = 0; - dumb_string name; + CharName name; dumb_ptr<block_list> bl = NULL; type = conv_num(st, &AARGO2(2)); @@ -3749,14 +3730,14 @@ void builtin_misceffect(ScriptState *st) get_val(st, sdata); if (sdata->type == ByteCode::STR || sdata->type == ByteCode::CONSTSTR) - name = conv_str(st, sdata); + name = stringish<CharName>(ZString(conv_str(st, sdata))); else id = conv_num(st, sdata); } - if (name) + if (name.to__actual()) { - dumb_ptr<map_session_data> sd = map_nick2sd(name.c_str()); + dumb_ptr<map_session_data> sd = map_nick2sd(name); if (sd) bl = sd; } @@ -3867,7 +3848,7 @@ void builtin_gmcommand(ScriptState *st) sd = script_rid2sd(st); dumb_string cmd = conv_str(st, &AARGO2(2)); - is_atcommand(sd->fd, sd, cmd.c_str(), 99); + is_atcommand(sd->fd, sd, cmd, 99); } @@ -3884,8 +3865,8 @@ void builtin_npcwarp(ScriptState *st) x = conv_num(st, &AARGO2(2)); y = conv_num(st, &AARGO2(3)); - dumb_string npc = conv_str(st, &AARGO2(4)); - nd = npc_name2id(npc.c_str()); + NpcName npc = stringish<NpcName>(ZString(conv_str(st, &AARGO2(4)))); + nd = npc_name2id(npc); if (!nd) return; @@ -3898,12 +3879,12 @@ void builtin_npcwarp(ScriptState *st) || y < 0 || y > m->ys - 1) return; - npc_enable(npc.c_str(), 0); + npc_enable(npc, 0); map_delblock(nd); /* [Freeyorp] */ nd->bl_x = x; nd->bl_y = y; map_addblock(nd); - npc_enable(npc.c_str(), 1); + npc_enable(npc, 1); } @@ -3915,10 +3896,10 @@ void builtin_npcwarp(ScriptState *st) static void builtin_message(ScriptState *st) { - dumb_string player = conv_str(st, &AARGO2(2)); - dumb_string msg = conv_str(st, &AARGO2(3)); + CharName player = stringish<CharName>(ZString(conv_str(st, &AARGO2(2)))); + ZString msg = ZString(conv_str(st, &AARGO2(3))); - dumb_ptr<map_session_data> pl_sd = map_nick2sd(player.c_str()); + dumb_ptr<map_session_data> pl_sd = map_nick2sd(player); if (pl_sd == NULL) return; clif_displaymessage(pl_sd->fd, msg); @@ -3939,8 +3920,11 @@ void builtin_npctalk(ScriptState *st) if (nd) { - std::string message = std::string(nd->name) + " : " + str.c_str(); - clif_message(nd, message.c_str()); + MString message; + message += nd->name; + message += " : "; + message += ZString(str); + clif_message(nd, FString(message)); } } @@ -4008,7 +3992,7 @@ void builtin_getsavepoint(ScriptState *st) { case 0: { - dumb_string mapname = dumb_string::copy(sd->status.save_point.map_); + dumb_string mapname = dumb_string::copys(sd->status.save_point.map_); push_str(st->stack, ByteCode::STR, mapname); } break; @@ -4026,9 +4010,9 @@ void builtin_getsavepoint(ScriptState *st) *------------------------------------------ */ static -void builtin_areatimer_sub(dumb_ptr<block_list> bl, interval_t tick, dumb_string event) +void builtin_areatimer_sub(dumb_ptr<block_list> bl, interval_t tick, NpcEvent event) { - pc_addeventtimer(bl->as_player(), tick, event.c_str()); + pc_addeventtimer(bl->as_player(), tick, event); } static @@ -4036,15 +4020,17 @@ void builtin_areatimer(ScriptState *st) { int x0, y0, x1, y1; - dumb_string mapname = conv_str(st, &AARGO2(2)); + MapName mapname = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); x0 = conv_num(st, &AARGO2(3)); y0 = conv_num(st, &AARGO2(4)); x1 = conv_num(st, &AARGO2(5)); y1 = conv_num(st, &AARGO2(6)); interval_t tick = static_cast<interval_t>(conv_num(st, &AARGO2(7))); - dumb_string event = conv_str(st, &AARGO2(8)); + ZString event_ = ZString(conv_str(st, &AARGO2(8))); + NpcEvent event; + extract(event_, &event); - map_local *m = map_mapname2mapid(mapname.c_str()); + map_local *m = map_mapname2mapid(mapname); if (m == nullptr) return; @@ -4065,7 +4051,7 @@ void builtin_isin(ScriptState *st) int x1, y1, x2, y2; dumb_ptr<map_session_data> sd = script_rid2sd(st); - dumb_string str = conv_str(st, &AARGO2(2)); + MapName str = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); x1 = conv_num(st, &AARGO2(3)); y1 = conv_num(st, &AARGO2(4)); x2 = conv_num(st, &AARGO2(5)); @@ -4074,7 +4060,6 @@ void builtin_isin(ScriptState *st) if (!sd) return; - using namespace operators; push_int(st->stack, ByteCode::INT, (sd->bl_x >= x1 && sd->bl_x <= x2) && (sd->bl_y >= y1 && sd->bl_y <= y2) @@ -4091,7 +4076,7 @@ void builtin_shop(ScriptState *st) if (!sd) return; - nd = npc_name2id(conv_str(st, &AARGO2(2)).c_str()); + nd = npc_name2id(stringish<NpcName>(ZString(conv_str(st, &AARGO2(2))))); if (!nd) return; @@ -4118,18 +4103,18 @@ void builtin_isdead(ScriptState *st) static void builtin_fakenpcname(ScriptState *st) { - dumb_string name = conv_str(st, &AARGO2(2)); - dumb_string newname = conv_str(st, &AARGO2(3)); + NpcName name = stringish<NpcName>(ZString(conv_str(st, &AARGO2(2)))); + NpcName newname = stringish<NpcName>(ZString(conv_str(st, &AARGO2(3)))); int newsprite = conv_num(st, &AARGO2(4)); - dumb_ptr<npc_data> nd = npc_name2id(name.c_str()); + dumb_ptr<npc_data> nd = npc_name2id(name); if (!nd) return; - strzcpy(nd->name, newname.c_str(), sizeof(nd->name)); + nd->name = newname; nd->npc_class = newsprite; // Refresh this npc - npc_enable(name.c_str(), 0); - npc_enable(name.c_str(), 1); + npc_enable(name, 0); + npc_enable(name, 1); } @@ -4254,13 +4239,15 @@ void op_add(ScriptState *st) { dumb_string sb = conv_str(st, &back); dumb_string sb1 = conv_str(st, &back1); - std::string buf = sb1.str() + sb.str(); + MString buf; + buf += ZString(sb1); + buf += ZString(sb); if (back1.type == ByteCode::STR) back1.u.str.delete_(); if (back.type == ByteCode::STR) back.u.str.delete_(); back1.type = ByteCode::STR; - back1.u.str = dumb_string::copys(buf); + back1.u.str = dumb_string::copys(FString(buf)); } } @@ -4269,11 +4256,12 @@ void op_add(ScriptState *st) *------------------------------------------ */ static -void op_2str(ScriptState *st, ByteCode op, dumb_string s1, dumb_string s2) +void op_2str(ScriptState *st, ByteCode op, dumb_string s1_, dumb_string s2_) { + ZString s1 = ZString(s1_); + ZString s2 = ZString(s2_); int a = 0; - using namespace operators; switch (op) { case ByteCode::EQ: @@ -4697,7 +4685,7 @@ int run_script(ScriptPointer sp, int rid, int oid) } int run_script_l(ScriptPointer sp, int rid, int oid, - int args_nr, argrec_t *args) + int args_nr, argrec_t *args) { struct script_stack stack; ScriptState st; @@ -4719,7 +4707,7 @@ int run_script_l(ScriptPointer sp, int rid, int oid, st.oid = oid; for (i = 0; i < args_nr; i++) { - if (args[i].name[strlen(args[i].name) - 1] == '$') + if (args[i].name.back() == '$') pc_setregstr(sd, SIR::from(variable_names.intern(args[i].name)), args[i].v.s); else pc_setreg(sd, SIR::from(variable_names.intern(args[i].name)), args[i].v.i); @@ -4745,9 +4733,9 @@ void mapreg_setreg(SIR reg, int val) * 文字列型マップ変数の変更 *------------------------------------------ */ -void mapreg_setregstr(SIR reg, const char *str) +void mapreg_setregstr(SIR reg, XString str) { - if (!str || !*str) + if (!str) mapregstr_db.erase(reg); else mapregstr_db.insert(reg, str); @@ -4762,15 +4750,15 @@ void mapreg_setregstr(SIR reg, const char *str) static void script_load_mapreg(void) { - std::ifstream in(mapreg_txt); + std::ifstream in(mapreg_txt.c_str()); if (!in.is_open()) return; - std::string line; - while (std::getline(in, line)) + FString line; + while (io::getline(in, line)) { - std::string buf1, buf2; + XString buf1, buf2; int index = 0; if (extract(line, record<'\t'>( @@ -4798,7 +4786,7 @@ void script_load_mapreg(void) else { borken: - PRINTF("%s: %s broken data !\n", mapreg_txt, buf1); + PRINTF("%s: %s broken data !\n", mapreg_txt, FString(buf1)); continue; } } @@ -4813,7 +4801,7 @@ static void script_save_mapreg_intsub(SIR key, int data, FILE *fp) { int num = key.base(), i = key.index(); - const std::string& name = variable_names.outtern(num); + ZString name = variable_names.outtern(num); if (name[1] != '@') { if (i == 0) @@ -4824,10 +4812,10 @@ void script_save_mapreg_intsub(SIR key, int data, FILE *fp) } static -void script_save_mapreg_strsub(SIR key, const std::string& data, FILE *fp) +void script_save_mapreg_strsub(SIR key, ZString data, FILE *fp) { int num = key.base(), i = key.index(); - const std::string& name = variable_names.outtern(num); + ZString name = variable_names.outtern(num); if (name[1] != '@') { if (i == 0) @@ -4876,12 +4864,8 @@ void do_final_script(void) script_save_mapreg(); mapreg_db.clear(); - for (auto& pair : mapregstr_db) - pair.second.clear(); mapregstr_db.clear(); scriptlabel_db.clear(); - for (auto& pair : userfunc_db) - pair.second.reset(); userfunc_db.clear(); str_datam.clear(); @@ -4902,7 +4886,7 @@ void do_init_script(void) } #define BUILTIN(func, args) \ -{builtin_##func, #func, args} +{builtin_##func, {#func}, {args}} BuiltinFunction builtin_functions[] = { @@ -5022,5 +5006,5 @@ BuiltinFunction builtin_functions[] = BUILTIN(getx, ""), BUILTIN(gety, ""), BUILTIN(getmap, ""), - {NULL, NULL, NULL}, + {nullptr, ZString(), ZString()}, }; diff --git a/src/map/script.hpp b/src/map/script.hpp index 66939aa..4e8f9ac 100644 --- a/src/map/script.hpp +++ b/src/map/script.hpp @@ -4,11 +4,11 @@ #include <cstdint> #include <cstring> // for inlined get_str - TODO remove -#include <string> #include <vector> #include "../common/db.hpp" #include "../common/dumb_ptr.hpp" +#include "../common/utils.hpp" #include "map.t.hpp" @@ -25,17 +25,17 @@ public: void add_scripti(uint32_t a); void add_scriptl(str_data_t *a); void set_label(str_data_t *ld, int pos_); - const char *parse_simpleexpr(const char *p); - const char *parse_subexpr(const char *p, int limit); - const char *parse_expr(const char *p); - const char *parse_line(const char *p); - void parse_script(const char *src, int line); + ZString::iterator parse_simpleexpr(ZString::iterator p); + ZString::iterator parse_subexpr(ZString::iterator p, int limit); + ZString::iterator parse_expr(ZString::iterator p); + ZString::iterator parse_line(ZString::iterator p); + void parse_script(ZString src, int line); // consumption methods used only by script.cpp ByteCode operator[](size_t i) const { return script_buf[i]; } - const char *get_str(size_t i) const + ZString get_str(size_t i) const { - return reinterpret_cast<const char *>(&script_buf[i]); + return ZString(ZString::really_construct_from_a_pointer, reinterpret_cast<const char *>(&script_buf[i]), nullptr); } // method used elsewhere @@ -58,10 +58,10 @@ struct ScriptPointer ByteCode peek() const { return (*code)[pos]; } ByteCode pop() { return (*code)[pos++]; } - const char *pops() + ZString pops() { - const char *rv = code->get_str(pos); - pos += strlen(rv); + ZString rv = code->get_str(pos); + pos += rv.size(); ++pos; return rv; } @@ -129,33 +129,36 @@ public: int defsp, new_defsp; }; -std::unique_ptr<const ScriptBuffer> parse_script(const char *, int); -typedef struct argrec +std::unique_ptr<const ScriptBuffer> parse_script(ZString, int); +struct argrec_t { - const char *name; + ZString name; union _aru { int i; - const char *s; + ZString s; - _aru() = default; _aru(int n) : i(n) {} - _aru(const char *z) : s(z) {} + _aru(ZString z) : s(z) {} } v; -} argrec_t; + + argrec_t(ZString n, int i) : name(n), v(i) {} + argrec_t(ZString n, ZString z) : name(n), v(z) {} +}; int run_script_l(ScriptPointer, int, int, int, argrec_t *args); int run_script(ScriptPointer, int, int); +struct ScriptLabel; extern -Map<std::string, int> scriptlabel_db; +Map<ScriptLabel, int> scriptlabel_db; extern -UPMap<std::string, const ScriptBuffer> userfunc_db; +UPMap<FString, const ScriptBuffer> userfunc_db; void script_config_read(); void do_init_script(void); void do_final_script(void); -extern char mapreg_txt[256]; +extern FString mapreg_txt; extern int script_errors; diff --git a/src/map/skill.cpp b/src/map/skill.cpp index c4b1dc8..7489731 100644 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -5,9 +5,13 @@ #include <cstring> #include <ctime> +#include <fstream> + #include "../common/cxxstdio.hpp" -#include "../common/random.hpp" +#include "../common/extract.hpp" +#include "../common/io.hpp" #include "../common/nullpo.hpp" +#include "../common/random.hpp" #include "../common/socket.hpp" #include "../common/timer.hpp" @@ -1144,24 +1148,24 @@ void skill_unit_timer_sub_ondelete(dumb_ptr<block_list> bl, */ static -SP scan_stat(char *statname) +SP scan_stat(XString statname) { - if (!strcasecmp(statname, "str")) + if (statname == "str") return SP::STR; - if (!strcasecmp(statname, "dex")) + if (statname == "dex") return SP::DEX; - if (!strcasecmp(statname, "agi")) + if (statname == "agi") return SP::AGI; - if (!strcasecmp(statname, "vit")) + if (statname == "vit") return SP::VIT; - if (!strcasecmp(statname, "int")) + if (statname == "int") return SP::INT; - if (!strcasecmp(statname, "luk")) + if (statname == "luk") return SP::LUK; - if (!strcasecmp(statname, "none")) + if (statname == "none") return SP::ZERO; - FPRINTF(stderr, "Unknown stat `%s'\n", statname); + FPRINTF(stderr, "Unknown stat `%s'\n", FString(statname)); return SP::ZERO; } @@ -1174,93 +1178,89 @@ SP scan_stat(char *statname) static int skill_readdb(void) { - int j; - FILE *fp; - char line[1024], *p; - /* The main skill database */ for (skill_db_& skdb : skill_db) skdb = skill_db_{}; - fp = fopen_("db/skill_db.txt", "r"); - if (fp == NULL) + std::ifstream in("db/skill_db.txt"); + if (!in) { PRINTF("can't read db/skill_db.txt\n"); return 1; } - while (fgets(line, 1020, fp)) + + FString line_; + while (io::getline(in, line_)) { - char *split[50]; - if (line[0] == '/' && line[1] == '/') + XString comment = "//"; + XString line = line_.xislice_h(std::search(line_.begin(), line_.end(), comment.begin(), comment.end())).rstrip(); + if (!line) continue; - for (j = 0, p = line; j < 18 && p; j++) - { - while (*p == '\t' || *p == ' ') - p++; - split[j] = p; - p = strchr(p, ','); - if (p) - *p++ = 0; - } - if (split[17] == NULL || j < 18) - { - FPRINTF(stderr, "Incomplete skill db data online (%d entries)\n", - j); - continue; - } - SkillID i = SkillID(atoi(split[0])); + struct skill_db_ skdb {}; + + SkillID i; + XString castcancel, ignore, flags, stat, desc; + if (!extract(line, + record<','>( + &i, + lstripping(&skdb.range_k), + lstripping(&skdb.hit), + lstripping(&skdb.inf), + lstripping(&skdb.pl), + lstripping(&skdb.nk), + lstripping(&skdb.max_raise), + lstripping(&skdb.max), + lstripping(&skdb.num_k), + lstripping(&castcancel), + lstripping(&skdb.cast_def_rate), + lstripping(&skdb.inf2), + lstripping(&skdb.maxcount), + lstripping(&ignore), // weapon/magic/misc/none + lstripping(&ignore), // blow count + lstripping(&flags), + lstripping(&stat), + lstripping(&desc) + ) + ) + ) + continue; if (/*i < SkillID() ||*/ i > SkillID::MAX_SKILL_DB) continue; - char *split2_0; - split2_0 = split[1]; - skill_db[i].range_k = atoi(split2_0); - skill_db[i].hit = atoi(split[2]); - skill_db[i].inf = atoi(split[3]); - skill_db[i].pl = atoi(split[4]); - skill_db[i].nk = atoi(split[5]); - skill_db[i].max_raise = atoi(split[6]); - skill_db[i].max = atoi(split[7]); - - split2_0 = split[8]; - skill_db[i].num_k = atoi(split2_0); - - if (strcasecmp(split[9], "yes") == 0) - skill_db[i].castcancel = 1; + if (castcancel == "yes") + skdb.castcancel = true; + else if (castcancel == "no") + skdb.castcancel = false; else - skill_db[i].castcancel = 0; - skill_db[i].cast_def_rate = atoi(split[10]); - skill_db[i].inf2 = atoi(split[11]); - skill_db[i].maxcount = atoi(split[12]); - // split[13] was one of: BF::WEAPON, BF::MAGIC, BF::MISC, BF::ZERO - // split[14] was colon-separated blow counts. - - if (!strcasecmp(split[15], "passive")) + continue; + + if (flags == "passive") { skill_pool_register(i); - skill_db[i].poolflags = SkillFlags::POOL_FLAG; + skdb.poolflags = SkillFlags::POOL_FLAG; } - else if (!strcasecmp(split[15], "active")) + else if (flags == "active") { skill_pool_register(i); - skill_db[i].poolflags = SkillFlags::POOL_FLAG | SkillFlags::POOL_ACTIVE; + skdb.poolflags = SkillFlags::POOL_FLAG | SkillFlags::POOL_ACTIVE; } + else if (flags == "no") + skdb.poolflags = SkillFlags::ZERO; else - skill_db[i].poolflags = SkillFlags::ZERO; + continue; - skill_db[i].stat = scan_stat(split[16]); + skdb.stat = scan_stat(stat); - std::string tmp = split[17]; - size_t space = tmp.find_first_of(" \t\n"); - if (space != std::string::npos) - tmp.resize(space); + MString tmp; + tmp += desc; for (char& c : tmp) if (c == '_') c = ' '; - skill_lookup_by_id(i).desc = std::move(tmp); + + skill_db[i] = skdb; + skill_lookup_by_id(i).desc = FString(tmp); } - fclose_(fp); PRINTF("read db/skill_db.txt done\n"); return 0; @@ -1299,10 +1299,10 @@ skill_name_db& skill_lookup_by_id(SkillID id) return skill_names[num_names - 1]; } -skill_name_db& skill_lookup_by_name(const char *name) +skill_name_db& skill_lookup_by_name(XString name) { for (skill_name_db& ner : skill_names) - if (!strcasecmp(name, ner.name.c_str()) || !strcasecmp(name, ner.desc.c_str())) + if (name == ner.name || name == ner.desc) return ner; return skill_names[num_names - 1]; } diff --git a/src/map/skill.hpp b/src/map/skill.hpp index c5a2f03..bcd0261 100644 --- a/src/map/skill.hpp +++ b/src/map/skill.hpp @@ -21,7 +21,8 @@ struct skill_db_ int num_k; int cast[MAX_SKILL_LEVEL], delay[MAX_SKILL_LEVEL]; int upkeep_time[MAX_SKILL_LEVEL], upkeep_time2[MAX_SKILL_LEVEL]; - int castcancel, cast_def_rate; + bool castcancel; + int cast_def_rate; int inf2, maxcount; int hp[MAX_SKILL_LEVEL], sp[MAX_SKILL_LEVEL], mhp[MAX_SKILL_LEVEL], hp_rate[MAX_SKILL_LEVEL], sp_rate[MAX_SKILL_LEVEL], @@ -49,7 +50,7 @@ struct skill_name_db extern struct skill_name_db skill_names[]; skill_name_db& skill_lookup_by_id(SkillID id); -skill_name_db& skill_lookup_by_name(const char *name); +skill_name_db& skill_lookup_by_name(XString name); struct block_list; struct map_session_data; diff --git a/src/map/tmw.cpp b/src/map/tmw.cpp index 7afe3ca..ed00110 100644 --- a/src/map/tmw.cpp +++ b/src/map/tmw.cpp @@ -17,14 +17,12 @@ #include "../poison.hpp" static -void tmw_AutoBan(dumb_ptr<map_session_data> sd, const char *reason, int length); +void tmw_AutoBan(dumb_ptr<map_session_data> sd, ZString reason, int length); static -int tmw_CheckChatLameness(dumb_ptr<map_session_data> sd, const char *message); -static -int tmw_ShorterStrlen(const char *s1, const char *s2); +bool tmw_CheckChatLameness(dumb_ptr<map_session_data> sd, XString message); -int tmw_CheckChatSpam(dumb_ptr<map_session_data> sd, const char *message) +int tmw_CheckChatSpam(dumb_ptr<map_session_data> sd, XString message) { nullpo_retr(1, sd); TimeT now = TimeT::now(); @@ -48,8 +46,7 @@ int tmw_CheckChatSpam(dumb_ptr<map_session_data> sd, const char *message) sd->chat_lines_in++; // Penalty for repeats. - if (strncmp(sd->chat_lastmsg, message, - tmw_ShorterStrlen(sd->chat_lastmsg, message)) == 0) + if (sd->chat_lastmsg.startswith(message) || message.startswith(sd->chat_lastmsg)) { sd->chat_lines_in += battle_config.chat_lame_penalty; sd->chat_total_repeats++; @@ -63,7 +60,7 @@ int tmw_CheckChatSpam(dumb_ptr<map_session_data> sd, const char *message) if (tmw_CheckChatLameness(sd, message)) sd->chat_lines_in += battle_config.chat_lame_penalty; - strzcpy(sd->chat_lastmsg, message, battle_config.chat_maxline); + sd->chat_lastmsg = message; if (sd->chat_lines_in >= battle_config.chat_spam_flood || sd->chat_total_repeats >= battle_config.chat_spam_flood) @@ -86,73 +83,58 @@ int tmw_CheckChatSpam(dumb_ptr<map_session_data> sd, const char *message) return 0; } -void tmw_AutoBan(dumb_ptr<map_session_data> sd, const char *reason, int length) +void tmw_AutoBan(dumb_ptr<map_session_data> sd, ZString reason, int length) { if (length == 0 || sd->auto_ban_info.in_progress) return; sd->auto_ban_info.in_progress = 1; - std::string hack_msg = STRPRINTF("[GM] %s has been autobanned for %s spam", + FString hack_msg = STRPRINTF("[GM] %s has been autobanned for %s spam", sd->status.name, reason); - tmw_GmHackMsg(hack_msg.c_str()); + tmw_GmHackMsg(hack_msg); - std::string fake_command = STRPRINTF("@autoban %s %dh (%s spam)", + FString fake_command = STRPRINTF("@autoban %s %dh (%s spam)", sd->status.name, length, reason); log_atcommand(sd, fake_command); - std::string anotherbuf = STRPRINTF("You have been banned for %s spamming. Please do not spam.", + FString anotherbuf = STRPRINTF("You have been banned for %s spamming. Please do not spam.", reason); clif_displaymessage(sd->fd, anotherbuf); /* type: 2 - ban(year, month, day, hour, minute, second) */ - chrif_char_ask_name(-1, sd->status.name, 2, 0, 0, 0, length, 0, 0); + HumanTimeDiff ban_len {}; + ban_len.hour = length; + chrif_char_ask_name(-1, sd->status.name, 2, ban_len); clif_setwaitclose(sd->fd); } -// Compares the length of two strings and returns that of the shorter -int tmw_ShorterStrlen(const char *s1, const char *s2) -{ - int s1_len = strlen(s1); - int s2_len = strlen(s2); - return (s2_len >= s1_len ? s1_len : s2_len); -} - // Returns true if more than 50% of input message is caps or punctuation -int tmw_CheckChatLameness(dumb_ptr<map_session_data>, const char *message) +bool tmw_CheckChatLameness(dumb_ptr<map_session_data>, XString message) { - int count, lame; - - for (count = lame = 0; *message; message++, count++) - if (isupper(*message) || ispunct(*message)) - lame++; + int lame = 0; - if (count > 7 && lame > count / 2) - return (1); + for (char c : message) + { + if (c <= ' ') + continue; + if (c > '~') + continue; + if ('0' <= c && c <= '9') + continue; + if ('a' <= c && c <= 'z') + continue; + lame++; + } - return (0); + return message.size() > 7 && lame > message.size() / 2; } // Sends a whisper to all GMs -void tmw_GmHackMsg(const char *line) +void tmw_GmHackMsg(ZString line) { intif_wis_message_to_gm(wisp_server_name, - battle_config.hack_info_GM_level, - line); -} - -/* Remove leading and trailing spaces from a string, modifying in place. */ -void tmw_TrimStr(char *const ob) -{ - char *const oe = ob + strlen(ob); - char *nb = ob; - while (*nb && isspace(*nb)) - nb++; - char *ne = oe; - while (ne != nb && isspace(ne[-1])) - ne--; - // not like memcpy - allowed to overlap one way - char *zb = std::copy(nb, ne, ob); - std::fill(zb, oe, '\0'); + battle_config.hack_info_GM_level, + line); } diff --git a/src/map/tmw.hpp b/src/map/tmw.hpp index 5551504..5f1d215 100644 --- a/src/map/tmw.hpp +++ b/src/map/tmw.hpp @@ -6,8 +6,7 @@ #include "map.hpp" -int tmw_CheckChatSpam(dumb_ptr<map_session_data> sd, const char *message); -void tmw_GmHackMsg(const char *line); -void tmw_TrimStr(char *str); +int tmw_CheckChatSpam(dumb_ptr<map_session_data> sd, XString message); +void tmw_GmHackMsg(ZString line); #endif // TMW_HPP |