From d398b01eb2dceba231b7c313e402817554c3a43d Mon Sep 17 00:00:00 2001 From: shennetsind Date: Fri, 17 Aug 2012 19:41:29 +0000 Subject: Added 2 (3) new atcommands: * @unloadnpcfile ** e.g. "@unloadnpcfile npc/cities/alberta.txt" unloads all npcs created by the npc/cities/alberta.txt file. * @addperm/@rmvperm ** e.g. "@addperm skill_unconditional" / "#rmvperm "player" skill_unconditional" git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@16656 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/atcommand.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/map/npc.c | 43 ++++++++++++++++++++---------- src/map/npc.h | 5 +++- src/map/pc.h | 25 +---------------- src/map/pc_groups.c | 34 +++-------------------- src/map/pc_groups.h | 50 ++++++++++++++++++++++++++++++++++ 6 files changed, 165 insertions(+), 69 deletions(-) (limited to 'src/map') diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 58204b491..feda37060 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -8780,6 +8780,80 @@ ACMD_FUNC(reloadquestdb) { clif_displaymessage(fd, "Quest DB has been reloaded"); return 0; } +ACMD_FUNC(addperm) { + int perm_size = ARRAYLENGTH(pc_g_permission_name); + bool add = (strcmpi(command+1, "addperm") == 0) ? true : false; + int i; + + if( !message || !*message ) { + sprintf(atcmd_output, "Usage: %s ",command); + clif_displaymessage(fd, atcmd_output); + clif_displaymessage(fd, "-- Permission List"); + for( i = 0; i < perm_size; i++ ) { + sprintf(atcmd_output,"- %s",pc_g_permission_name[i].name); + clif_displaymessage(fd, atcmd_output); + } + return -1; + } + + ARR_FIND(0, perm_size, i, strcmpi(pc_g_permission_name[i].name, message) == 0); + + if( i == perm_size ) { + sprintf(atcmd_output,"'%s' is not a known permission",message); + clif_displaymessage(fd, atcmd_output); + clif_displaymessage(fd, "-- Permission List"); + for( i = 0; i < perm_size; i++ ) { + sprintf(atcmd_output,"- %s",pc_g_permission_name[i].name); + clif_displaymessage(fd, atcmd_output); + } + return -1; + } + + if( add && (sd->permissions&pc_g_permission_name[i].permission) ) { + sprintf(atcmd_output, "User '%s' already possesses the '%s' permission",sd->status.name,pc_g_permission_name[i].name); + clif_displaymessage(fd, atcmd_output); + return -1; + } else if ( !add && !(sd->permissions&pc_g_permission_name[i].permission) ) { + sprintf(atcmd_output, "User '%s' doesn't possess the '%s' permission",sd->status.name,pc_g_permission_name[i].name); + clif_displaymessage(fd, atcmd_output); + sprintf(atcmd_output,"-- User '%s' Permissions",sd->status.name); + clif_displaymessage(fd, atcmd_output); + for( i = 0; i < perm_size; i++ ) { + if( sd->permissions&pc_g_permission_name[i].permission ) { + sprintf(atcmd_output,"- %s",pc_g_permission_name[i].name); + clif_displaymessage(fd, atcmd_output); + } + } + + return -1; + } + + if( add ) + sd->permissions |= pc_g_permission_name[i].permission; + else + sd->permissions &=~ pc_g_permission_name[i].permission; + + + sprintf(atcmd_output, "User '%s' permissions were updated successfully, be aware the changes are temporary.",sd->status.name); + clif_displaymessage(fd, atcmd_output); + + return 0; +} +ACMD_FUNC(unloadnpcfile) { + + if( !message || !*message ) { + clif_displaymessage(fd, "Usage: @unloadnpcfile "); + return -1; + } + + if( npc_unloadfile(message) ) + clif_displaymessage(fd, "File unloaded, be aware mapflags and monsters spawned directly are not removed"); + else { + clif_displaymessage(fd, "File not found"); + return -1; + } + return 0; +} /** * Fills the reference of available commands in atcommand DBMap **/ @@ -9030,6 +9104,9 @@ void atcommand_basecommands(void) { ACMD_DEF(disguiseguild), ACMD_DEF(sizeall), ACMD_DEF(sizeguild), + ACMD_DEF(addperm), + ACMD_DEF2("rmvperm", addperm), + ACMD_DEF(unloadnpcfile), /** * For Testing Purposes, not going to be here after we're done. **/ diff --git a/src/map/npc.c b/src/map/npc.c index 4faa54e24..e8ebb3180 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -1749,6 +1749,9 @@ int npc_unload(struct npc_data* nd, bool single) { npc_chat_finalize(nd); // deallocate npc PCRE data structures #endif + if( nd->path ) + aFree(nd->path); + if( (nd->subtype == SHOP || nd->subtype == CASHSHOP) && nd->src_id == 0) //src check for duplicate shops [Orcao] aFree(nd->u.shop.shop_item); else if( nd->subtype == SCRIPT ) { @@ -1892,16 +1895,12 @@ static void npc_parsename(struct npc_data* nd, const char* name, const char* sta // parse name p = strstr(name,"::"); - if( p ) - {// :: + if( p ) { // :: size_t len = p-name; - if( len > NAME_LENGTH ) - { + if( len > NAME_LENGTH ) { ShowWarning("npc_parsename: Display name of '%s' is too long (len=%u) in file '%s', line'%d'. Truncating to %u characters.\n", name, (unsigned int)len, filepath, strline(buffer,start-buffer), NAME_LENGTH); safestrncpy(nd->name, name, sizeof(nd->name)); - } - else - { + } else { memcpy(nd->name, name, len); memset(nd->name+len, 0, sizeof(nd->name)-len); } @@ -1909,9 +1908,7 @@ static void npc_parsename(struct npc_data* nd, const char* name, const char* sta if( len > NAME_LENGTH ) ShowWarning("npc_parsename: Unique name of '%s' is too long (len=%u) in file '%s', line'%d'. Truncating to %u characters.\n", name, (unsigned int)len, filepath, strline(buffer,start-buffer), NAME_LENGTH); safestrncpy(nd->exname, p+2, sizeof(nd->exname)); - } - else - {// + } else {// size_t len = strlen(name); if( len > NAME_LENGTH ) ShowWarning("npc_parsename: Name '%s' is too long (len=%u) in file '%s', line'%d'. Truncating to %u characters.\n", name, (unsigned int)len, filepath, strline(buffer,start-buffer), NAME_LENGTH); @@ -1919,15 +1916,13 @@ static void npc_parsename(struct npc_data* nd, const char* name, const char* sta safestrncpy(nd->exname, name, sizeof(nd->exname)); } - if( *nd->exname == '\0' || strstr(nd->exname,"::") != NULL ) - {// invalid + if( *nd->exname == '\0' || strstr(nd->exname,"::") != NULL ) {// invalid snprintf(newname, ARRAYLENGTH(newname), "0_%d_%d_%d", nd->bl.m, nd->bl.x, nd->bl.y); ShowWarning("npc_parsename: Invalid unique name in file '%s', line'%d'. Renaming '%s' to '%s'.\n", filepath, strline(buffer,start-buffer), nd->exname, newname); safestrncpy(nd->exname, newname, sizeof(nd->exname)); } - if( (dnd=npc_name2id(nd->exname)) != NULL ) - {// duplicate unique name, generate new one + if( (dnd=npc_name2id(nd->exname)) != NULL ) {// duplicate unique name, generate new one char this_mapname[32]; char other_mapname[32]; int i = 0; @@ -1947,6 +1942,9 @@ static void npc_parsename(struct npc_data* nd, const char* name, const char* sta ShowDebug("other npc:\n display name '%s'\n unique name '%s'\n map=%s, x=%d, y=%d\n", dnd->name, dnd->exname, other_mapname, dnd->bl.x, dnd->bl.y); safestrncpy(nd->exname, newname, sizeof(nd->exname)); } + + CREATE(nd->path, char, strlen(filepath)+1); + safestrncpy(nd->path, filepath, strlen(filepath)+1); } struct npc_data* npc_add_warp(short from_mapid, short from_x, short from_y, short xs, short ys, unsigned short to_mapindex, short to_x, short to_y) @@ -3588,6 +3586,22 @@ int npc_reload(void) { } return 0; } +bool npc_unloadfile( const char* path ) { + DBIterator * iter = db_iterator(npcname_db); + struct npc_data* nd = NULL; + bool found = false; + + for( nd = dbi_first(iter); dbi_exists(iter); nd = dbi_next(iter) ) { + if( nd->path && strcasecmp(nd->path,path) == 0 ) { + found = true; + npc_unload(nd, true); + } + } + + dbi_destroy(iter); + + return found; +} void do_clear_npc(void) { db_clear(npcname_db); db_clear(ev_db); @@ -3657,6 +3671,7 @@ int do_init_npc(void) npcname_db = strdb_alloc(DB_OPT_BASE,NAME_LENGTH); timer_event_ers = ers_new(sizeof(struct timer_event_data)); + // process all npc files ShowStatus("Loading NPCs...\r"); for( file = npc_src_files; file != NULL; file = file->next ) { diff --git a/src/map/npc.h b/src/map/npc.h index f5dd9011c..7198ad905 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -40,6 +40,7 @@ struct npc_data { unsigned size : 2; void* chatdb; // pointer to a npc_parse struct (see npc_chat.c) + char* path;/* path dir */ enum npc_subtype subtype; int src_id; union { @@ -169,10 +170,12 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns * For the Secure NPC Timeout option (check config/Secure.h) [RR] **/ #if SECURE_NPCTIMEOUT -int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t data); + int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t data); #endif // @commands (script-based) int npc_do_atcmd_event(struct map_session_data* sd, const char* command, const char* message, const char* eventname); +bool npc_unloadfile( const char* path ); + #endif /* _NPC_H_ */ diff --git a/src/map/pc.h b/src/map/pc.h index a62ea2b3b..a87544d0c 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -18,6 +18,7 @@ #include "vending.h" // struct s_vending #include "mob.h" #include "log.h" +#include "pc_groups.h" #define MAX_PC_BONUS 10 #define MAX_PC_SKILL_REQUIRE 5 @@ -580,30 +581,6 @@ enum equip_index { EQI_MAX }; -enum e_pc_permission { - PC_PERM_NONE = 0, - PC_PERM_TRADE = 0x00001, - PC_PERM_PARTY = 0x00002, - PC_PERM_ALL_SKILL = 0x00004, - PC_PERM_USE_ALL_EQUIPMENT = 0x00008, - PC_PERM_SKILL_UNCONDITIONAL = 0x00010, - PC_PERM_JOIN_ALL_CHAT = 0x00020, - PC_PERM_NO_CHAT_KICK = 0x00040, - PC_PERM_HIDE_SESSION = 0x00080, - PC_PERM_WHO_DISPLAY_AID = 0x00100, - PC_PERM_RECEIVE_HACK_INFO = 0x00200, - PC_PERM_WARP_ANYWHERE = 0x00400, - PC_PERM_VIEW_HPMETER = 0x00800, - PC_PERM_VIEW_EQUIPMENT = 0x01000, - PC_PERM_USE_CHECK = 0x02000, - PC_PERM_USE_CHANGEMAPTYPE = 0x04000, - PC_PERM_USE_ALL_COMMANDS = 0x08000, - PC_PERM_RECEIVE_REQUESTS = 0x10000, - PC_PERM_SHOW_BOSS = 0x20000, - PC_PERM_DISABLE_PVM = 0x40000, - PC_PERM_DISABLE_PVP = 0x80000, -}; - #define pc_setdead(sd) ( (sd)->state.dead_sit = (sd)->vd.dead_sit = 1 ) #define pc_setsit(sd) ( (sd)->state.dead_sit = (sd)->vd.dead_sit = 2 ) #define pc_isdead(sd) ( (sd)->state.dead_sit == 1 ) diff --git a/src/map/pc_groups.c b/src/map/pc_groups.c index a2bf5f0c5..3111e2788 100644 --- a/src/map/pc_groups.c +++ b/src/map/pc_groups.c @@ -38,32 +38,6 @@ static config_t pc_group_config; static DBMap* pc_group_db; // id -> GroupSettings static DBMap* pc_groupname_db; // name -> GroupSettings -static const struct { - const char *name; - int permission; -} permission_name[] = { - { "can_trade", PC_PERM_TRADE }, - { "can_party", PC_PERM_PARTY }, - { "all_skill", PC_PERM_ALL_SKILL }, - { "all_equipment", PC_PERM_USE_ALL_EQUIPMENT }, - { "skill_unconditional", PC_PERM_SKILL_UNCONDITIONAL }, - { "join_chat", PC_PERM_JOIN_ALL_CHAT }, - { "kick_chat", PC_PERM_NO_CHAT_KICK }, - { "hide_session", PC_PERM_HIDE_SESSION }, - { "who_display_aid", PC_PERM_WHO_DISPLAY_AID }, - { "hack_info", PC_PERM_RECEIVE_HACK_INFO }, - { "any_warp", PC_PERM_WARP_ANYWHERE }, - { "view_hpmeter", PC_PERM_VIEW_HPMETER }, - { "view_equipment", PC_PERM_VIEW_EQUIPMENT }, - { "use_check", PC_PERM_USE_CHECK }, - { "use_changemaptype", PC_PERM_USE_CHANGEMAPTYPE }, - { "all_commands", PC_PERM_USE_ALL_COMMANDS }, - { "receive_requests", PC_PERM_RECEIVE_REQUESTS }, - { "show_bossmobs", PC_PERM_SHOW_BOSS }, - { "disable_pvm", PC_PERM_DISABLE_PVM }, - { "disable_pvp", PC_PERM_DISABLE_PVP }, -}; - /** * @retval NULL if not found * @private @@ -199,8 +173,8 @@ static void read_config(void) const char *name = config_setting_name(permission); int j; - ARR_FIND(0, ARRAYLENGTH(permission_name), j, strcmp(permission_name[j].name, name) == 0); - if (j == ARRAYLENGTH(permission_name)) { + ARR_FIND(0, ARRAYLENGTH(pc_g_permission_name), j, strcmp(pc_g_permission_name[j].name, name) == 0); + if (j == ARRAYLENGTH(pc_g_permission_name)) { ShowConfigWarning(permission, "pc_groups:read_config: non-existent permission name '%s', removing...", name); config_setting_remove(permissions, name); --i; @@ -291,8 +265,8 @@ static void read_config(void) if (val == 0) // does not have this permission continue; - ARR_FIND(0, ARRAYLENGTH(permission_name), j, strcmp(permission_name[j].name, name) == 0); - group_settings->e_permissions |= permission_name[j].permission; + ARR_FIND(0, ARRAYLENGTH(pc_g_permission_name), j, strcmp(pc_g_permission_name[j].name, name) == 0); + group_settings->e_permissions |= pc_g_permission_name[j].permission; } } dbi_destroy(iter); diff --git a/src/map/pc_groups.h b/src/map/pc_groups.h index 259b74585..8951a41cd 100644 --- a/src/map/pc_groups.h +++ b/src/map/pc_groups.h @@ -20,4 +20,54 @@ void do_init_pc_groups(void); void do_final_pc_groups(void); void pc_groups_reload(void); +enum e_pc_permission { + PC_PERM_NONE = 0, + PC_PERM_TRADE = 0x00001, + PC_PERM_PARTY = 0x00002, + PC_PERM_ALL_SKILL = 0x00004, + PC_PERM_USE_ALL_EQUIPMENT = 0x00008, + PC_PERM_SKILL_UNCONDITIONAL = 0x00010, + PC_PERM_JOIN_ALL_CHAT = 0x00020, + PC_PERM_NO_CHAT_KICK = 0x00040, + PC_PERM_HIDE_SESSION = 0x00080, + PC_PERM_WHO_DISPLAY_AID = 0x00100, + PC_PERM_RECEIVE_HACK_INFO = 0x00200, + PC_PERM_WARP_ANYWHERE = 0x00400, + PC_PERM_VIEW_HPMETER = 0x00800, + PC_PERM_VIEW_EQUIPMENT = 0x01000, + PC_PERM_USE_CHECK = 0x02000, + PC_PERM_USE_CHANGEMAPTYPE = 0x04000, + PC_PERM_USE_ALL_COMMANDS = 0x08000, + PC_PERM_RECEIVE_REQUESTS = 0x10000, + PC_PERM_SHOW_BOSS = 0x20000, + PC_PERM_DISABLE_PVM = 0x40000, + PC_PERM_DISABLE_PVP = 0x80000, +}; + +static const struct { + const char *name; + unsigned int permission; +} pc_g_permission_name[] = { + { "can_trade", PC_PERM_TRADE }, + { "can_party", PC_PERM_PARTY }, + { "all_skill", PC_PERM_ALL_SKILL }, + { "all_equipment", PC_PERM_USE_ALL_EQUIPMENT }, + { "skill_unconditional", PC_PERM_SKILL_UNCONDITIONAL }, + { "join_chat", PC_PERM_JOIN_ALL_CHAT }, + { "kick_chat", PC_PERM_NO_CHAT_KICK }, + { "hide_session", PC_PERM_HIDE_SESSION }, + { "who_display_aid", PC_PERM_WHO_DISPLAY_AID }, + { "hack_info", PC_PERM_RECEIVE_HACK_INFO }, + { "any_warp", PC_PERM_WARP_ANYWHERE }, + { "view_hpmeter", PC_PERM_VIEW_HPMETER }, + { "view_equipment", PC_PERM_VIEW_EQUIPMENT }, + { "use_check", PC_PERM_USE_CHECK }, + { "use_changemaptype", PC_PERM_USE_CHANGEMAPTYPE }, + { "all_commands", PC_PERM_USE_ALL_COMMANDS }, + { "receive_requests", PC_PERM_RECEIVE_REQUESTS }, + { "show_bossmobs", PC_PERM_SHOW_BOSS }, + { "disable_pvm", PC_PERM_DISABLE_PVM }, + { "disable_pvp", PC_PERM_DISABLE_PVP }, +}; + #endif // _PC_GROUPS_H_ -- cgit v1.2.3-60-g2f50