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:
parent
3bc3376145
commit
40b3dfe73b
@ -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.
|
||||
**/
|
||||
|
@ -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 ) {
|
||||
|
@ -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_ */
|
||||
|
25
src/map/pc.h
25
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 )
|
||||
|
@ -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);
|
||||
|
@ -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_
|
||||
|
Loading…
x
Reference in New Issue
Block a user