瀏覽代碼

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

shennetsind 12 年之前
父節點
當前提交
40b3dfe73b
共有 6 個文件被更改,包括 165 次插入69 次删除
  1. 77 0
      src/map/atcommand.c
  2. 29 14
      src/map/npc.c
  3. 4 1
      src/map/npc.h
  4. 1 24
      src/map/pc.h
  5. 4 30
      src/map/pc_groups.c
  6. 50 0
      src/map/pc_groups.h

+ 77 - 0
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 <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.
 		 **/

+ 29 - 14
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 )
-	{// <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 ) {

+ 4 - 1
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_ */

+ 1 - 24
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 )

+ 4 - 30
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);

+ 50 - 0
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_