Added 2 (3) new atcommands:

* @unloadnpcfile <file path>
** e.g. "@unloadnpcfile npc/cities/alberta.txt" unloads all npcs created by the npc/cities/alberta.txt file.
* @addperm/@rmvperm <permission_name>
** e.g. "@addperm skill_unconditional" / "#rmvperm "player" skill_unconditional"

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@16656 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
shennetsind 2012-08-17 19:41:29 +00:00
parent 3bc3376145
commit 40b3dfe73b
6 changed files with 165 additions and 69 deletions

View File

@ -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 <permission_name>",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 <file name>");
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.
**/

View File

@ -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 )
{// <Display name>::<Unique name>
if( p ) { // <Display name>::<Unique name>
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
{// <Display name>
} else {// <Display name>
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 ) {

View File

@ -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_ */

View File

@ -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 )

View File

@ -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);

View File

@ -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_