plugins/adminmenu/dynamicmenu.sp
author David Anderson <dvander@alliedmods.net>
Tue Oct 27 01:43:51 2009 -0700 (2009-10-27)
changeset 2836 5697ddf8bce8
parent 2835 c2567981deab
child 2920 1d5645ab7ae0
permissions -rw-r--r--
Warn user when adminmenu_custom is going to emit duplicate entries (bug 3894, r=pred).
dvander@1945
     1
dvander@2835
     2
#define NAME_LENGTH 64
dvander@1945
     3
#define CMD_LENGTH 255
dvander@1945
     4
dvander@1945
     5
#define ARRAY_STRING_LENGTH 32
dvander@1945
     6
dvander@1945
     7
enum GroupCommands
dvander@1945
     8
{
dvander@1945
     9
	Handle:groupListName,
dvander@1945
    10
	Handle:groupListCommand	
dvander@1945
    11
};
dvander@1945
    12
dvander@1945
    13
new g_groupList[GroupCommands];
dvander@1945
    14
new g_groupCount;
dvander@1945
    15
dvander@1945
    16
new Handle:g_configParser = INVALID_HANDLE;
dvander@1945
    17
dvander@1945
    18
enum Places
dvander@1945
    19
{
dvander@1945
    20
	Place_Category,
dvander@1945
    21
	Place_Item,
dvander@1945
    22
	Place_ReplaceNum	
dvander@1945
    23
};
dvander@1945
    24
dvander@1945
    25
new String:g_command[MAXPLAYERS+1][CMD_LENGTH];
dvander@1945
    26
new g_currentPlace[MAXPLAYERS+1][Places];
dvander@1945
    27
dvander@1945
    28
/**
dvander@1945
    29
 * What to put in the 'info' menu field (for PlayerList and Player_Team menus only)
dvander@1945
    30
 */
dvander@1945
    31
enum PlayerMethod
dvander@1945
    32
{		
dvander@1945
    33
	ClientId,				/** Client id number ( 1 - Maxplayers) */
dvander@1945
    34
	UserId,					/** Client userid */
dvander@1945
    35
	Name,					/** Client Name */
dvander@1945
    36
	SteamId,				/** Client Steamid */
dvander@1945
    37
	IpAddress,				/** Client's Ip Address */
dvander@1945
    38
	UserId2					/** Userid (not prefixed with #) */
dvander@1945
    39
};
dvander@1945
    40
pred@1953
    41
enum ExecuteType
pred@1953
    42
{
pred@1953
    43
	Execute_Player,
pred@1953
    44
	Execute_Server
pred@1953
    45
}
pred@1953
    46
pred@1953
    47
enum SubMenu_Type
pred@1953
    48
{
pred@1953
    49
	SubMenu_Group,
pred@1953
    50
	SubMenu_GroupPlayer,
pred@1953
    51
	SubMenu_Player,
pred@1953
    52
	SubMenu_MapCycle,
pred@1953
    53
	SubMenu_List,
pred@1953
    54
	SubMenu_OnOff	
pred@1953
    55
}
pred@1953
    56
pred@1953
    57
enum Item
pred@1953
    58
{
pred@1953
    59
	String:Item_cmd[256],
pred@1953
    60
	ExecuteType:Item_execute,
pred@1953
    61
	Handle:Item_submenus
pred@1953
    62
}
pred@1953
    63
pred@1953
    64
enum Submenu
pred@1953
    65
{
pred@1953
    66
	SubMenu_Type:Submenu_type,
pred@1953
    67
	String:Submenu_title[32],
pred@1953
    68
	PlayerMethod:Submenu_method,
pred@1953
    69
	Submenu_listcount,
pred@1953
    70
	Handle:Submenu_listdata
pred@1953
    71
}
pred@1953
    72
pred@1953
    73
new Handle:g_DataArray;
pred@1953
    74
dvander@1945
    75
BuildDynamicMenu()
dvander@1945
    76
{
pred@1953
    77
	new itemInput[Item];
pred@1953
    78
	g_DataArray = CreateArray(sizeof(itemInput));
dvander@1945
    79
	
pred@1953
    80
	new String:executeBuffer[32];
pred@1953
    81
	
pred@1953
    82
	new Handle:kvMenu;
pred@1953
    83
	kvMenu = CreateKeyValues("Commands");
pred@2103
    84
	KvSetEscapeSequences(kvMenu, true); 
dvander@2099
    85
	
dvander@1945
    86
	new String:file[256];
dvander@2099
    87
	
dvander@2099
    88
	/* As a compatibility shim, we use the old file if it exists. */
dvander@1945
    89
	BuildPath(Path_SM, file, 255, "configs/dynamicmenu/menu.ini");
dvander@2099
    90
	if (FileExists(file))
dvander@2099
    91
	{
dvander@2099
    92
		LogError("Warning! configs/dynamicmenu/menu.ini is now configs/adminmenu_custom.txt.");
dvander@2099
    93
		LogError("Read the 1.0.2 release notes, as the dynamicmenu folder has been removed.");
dvander@2099
    94
	}
dvander@2099
    95
	else
dvander@2099
    96
	{
dvander@2099
    97
		BuildPath(Path_SM, file, 255, "configs/adminmenu_custom.txt");
dvander@2099
    98
	}
dvander@2099
    99
	
pred@1953
   100
	FileToKeyValues(kvMenu, file);
dvander@1945
   101
	
dvander@1945
   102
	new String:name[NAME_LENGTH];
dvander@1945
   103
	new String:buffer[NAME_LENGTH];
pred@1953
   104
		
pred@1953
   105
	if (!KvGotoFirstSubKey(kvMenu))
dvander@1945
   106
	{
dvander@1945
   107
		return;
dvander@1945
   108
	}
dvander@1945
   109
	
dvander@1945
   110
	decl String:admin[30];
dvander@1945
   111
	
dvander@1945
   112
	new TopMenuObject:categoryId;
dvander@1945
   113
	
dvander@1945
   114
	do
dvander@1945
   115
	{		
pred@1953
   116
		KvGetSectionName(kvMenu, buffer, sizeof(buffer));
dvander@1945
   117
pred@1953
   118
		KvGetString(kvMenu, "admin", admin, sizeof(admin),"sm_admin");
dvander@1945
   119
				
dvander@1945
   120
		if ((categoryId =FindTopMenuCategory(hAdminMenu, buffer)) == INVALID_TOPMENUOBJECT)
dvander@1945
   121
		{
dvander@1945
   122
			categoryId = AddToTopMenu(hAdminMenu,
dvander@1945
   123
							buffer,
dvander@1945
   124
							TopMenuObject_Category,
dvander@1945
   125
							DynamicMenuCategoryHandler,
dvander@1945
   126
							INVALID_TOPMENUOBJECT,
dvander@1945
   127
							admin,
dvander@1945
   128
							ADMFLAG_GENERIC,
dvander@1945
   129
							name);
dvander@1945
   130
dvander@1945
   131
		}
dvander@2836
   132
dvander@2836
   133
		decl String:category_name[NAME_LENGTH];
dvander@2836
   134
		strcopy(category_name, sizeof(category_name), buffer);
dvander@1945
   135
		
pred@1953
   136
		if (!KvGotoFirstSubKey(kvMenu))
dvander@1945
   137
		{
dvander@1945
   138
			return;
dvander@1945
   139
		}
dvander@1945
   140
		
dvander@1945
   141
		do
dvander@1945
   142
		{		
pred@1953
   143
			KvGetSectionName(kvMenu, buffer, sizeof(buffer));
pred@1953
   144
			
pred@1953
   145
			KvGetString(kvMenu, "admin", admin, sizeof(admin),"");
dvander@1945
   146
			
dvander@1945
   147
			if (admin[0] == '\0')
dvander@1945
   148
			{
dvander@1945
   149
				//No 'admin' keyvalue was found
dvander@1945
   150
				//Use the first argument of the 'cmd' string instead
dvander@1945
   151
				
dvander@1945
   152
				decl String:temp[64];
pred@1953
   153
				KvGetString(kvMenu, "cmd", temp, sizeof(temp),"");
dvander@1945
   154
				
dvander@1945
   155
				BreakString(temp, admin, sizeof(admin));
dvander@1945
   156
			}
pred@1953
   157
			
pred@1953
   158
			
pred@1953
   159
			KvGetString(kvMenu, "cmd", itemInput[Item_cmd], sizeof(itemInput[Item_cmd]));	
pred@1953
   160
			KvGetString(kvMenu, "execute", executeBuffer, sizeof(executeBuffer));
pred@1953
   161
			
pred@1953
   162
			if (StrEqual(executeBuffer, "server"))
dvander@1945
   163
			{
pred@1953
   164
				itemInput[Item_execute] = Execute_Server;
pred@1953
   165
			}
pred@1953
   166
			else //assume player type execute
pred@1953
   167
			{
pred@1953
   168
				itemInput[Item_execute] = Execute_Player;
dvander@1945
   169
			}
pred@1953
   170
  							
pred@1953
   171
  			/* iterate all submenus and load data into itemInput[Item_submenus] (adt array handle) */
pred@1953
   172
  			
pred@1953
   173
  			new count = 1;
pred@1953
   174
  			decl String:countBuffer[10] = "1";
pred@1953
   175
  			
mr@2565
   176
  			decl String:inputBuffer[48];
pred@1953
   177
  			
pred@1953
   178
  			while (KvJumpToKey(kvMenu, countBuffer))
pred@1953
   179
  			{
pred@1953
   180
	  			new submenuInput[Submenu];
pred@1953
   181
	  			
pred@1953
   182
	  			if (count == 1)
pred@1953
   183
	  			{
pred@1953
   184
		  			itemInput[Item_submenus] = CreateArray(sizeof(submenuInput));	
pred@1953
   185
	  			}
pred@1953
   186
	  			
pred@1953
   187
	  			KvGetString(kvMenu, "type", inputBuffer, sizeof(inputBuffer));
pred@1953
   188
	  			
pred@1953
   189
	  			if (strncmp(inputBuffer,"group",5)==0)
pred@1953
   190
				{	
pred@1953
   191
					if (StrContains(inputBuffer, "player") != -1)
pred@1953
   192
					{			
pred@1953
   193
						submenuInput[Submenu_type] = SubMenu_GroupPlayer;
pred@1953
   194
					}
pred@1953
   195
					else
pred@1953
   196
					{
pred@1953
   197
						submenuInput[Submenu_type] = SubMenu_Group;
pred@1953
   198
					}
pred@1953
   199
				}			
pred@1953
   200
				else if (StrEqual(inputBuffer,"mapcycle"))
pred@1953
   201
				{
pred@1953
   202
					submenuInput[Submenu_type] = SubMenu_MapCycle;
pred@1953
   203
					
pred@1953
   204
					KvGetString(kvMenu, "path", inputBuffer, sizeof(inputBuffer),"mapcycle.txt");
pred@1953
   205
					
pred@1953
   206
					submenuInput[Submenu_listdata] = CreateDataPack();
pred@1953
   207
					WritePackString(submenuInput[Submenu_listdata], inputBuffer);
pred@1953
   208
					ResetPack(submenuInput[Submenu_listdata]);
pred@1953
   209
				}
pred@1953
   210
				else if (StrContains(inputBuffer, "player") != -1)
pred@1953
   211
				{			
pred@1953
   212
					submenuInput[Submenu_type] = SubMenu_Player;
pred@1953
   213
				}
pred@1953
   214
				else if (StrEqual(inputBuffer,"onoff"))
pred@1953
   215
				{
pred@1953
   216
					submenuInput[Submenu_type] = SubMenu_OnOff;
pred@1953
   217
				}		
pred@1953
   218
				else //assume 'list' type
pred@1953
   219
				{
pred@1953
   220
					submenuInput[Submenu_type] = SubMenu_List;
pred@1953
   221
					
pred@1953
   222
					submenuInput[Submenu_listdata] = CreateDataPack();
pred@1953
   223
					
pred@1953
   224
					new String:temp[6];
pred@1953
   225
					new String:value[64];
pred@1953
   226
					new String:text[64];
mr@2776
   227
					new String:subadm[30];	//  same as "admin", cf. line 110
pred@1953
   228
					new i=1;
pred@1953
   229
					new bool:more = true;
pred@1953
   230
					
pred@1953
   231
					new listcount = 0;
pred@1953
   232
								
pred@1953
   233
					do
pred@1953
   234
					{
pred@1953
   235
						Format(temp,3,"%i",i);
pred@1953
   236
						KvGetString(kvMenu, temp, value, sizeof(value), "");
pred@1953
   237
						
pred@1953
   238
						Format(temp,5,"%i.",i);
pred@1953
   239
						KvGetString(kvMenu, temp, text, sizeof(text), value);
pred@1953
   240
						
pred@1953
   241
						Format(temp,5,"%i*",i);
mr@2776
   242
						KvGetString(kvMenu, temp, subadm, sizeof(subadm),"");	
pred@1953
   243
						
pred@1953
   244
						if (value[0]=='\0')
pred@1953
   245
						{
pred@1953
   246
							more = false;
pred@1953
   247
						}
pred@1953
   248
						else
pred@1953
   249
						{
pred@1953
   250
							listcount++;
pred@1953
   251
							WritePackString(submenuInput[Submenu_listdata], value);
pred@1953
   252
							WritePackString(submenuInput[Submenu_listdata], text);
mr@2776
   253
							WritePackString(submenuInput[Submenu_listdata], subadm);
pred@1953
   254
						}
pred@1953
   255
						
pred@1953
   256
						i++;
pred@1953
   257
										
pred@1953
   258
					} while (more);
pred@1953
   259
					
pred@1953
   260
					ResetPack(submenuInput[Submenu_listdata]);
pred@1953
   261
					submenuInput[Submenu_listcount] = listcount;
pred@1953
   262
				}
pred@1953
   263
				
pred@1953
   264
				if ((submenuInput[Submenu_type] == SubMenu_Player) || (submenuInput[Submenu_type] == SubMenu_GroupPlayer))
pred@1953
   265
				{
pred@1953
   266
					KvGetString(kvMenu, "method", inputBuffer, sizeof(inputBuffer));
pred@1953
   267
					
pred@1953
   268
					if (StrEqual(inputBuffer, "clientid"))
pred@1953
   269
					{
pred@1953
   270
						submenuInput[Submenu_method] = ClientId;
pred@1953
   271
					}
pred@1953
   272
					else if (StrEqual(inputBuffer, "steamid"))
pred@1953
   273
					{
pred@1953
   274
						submenuInput[Submenu_method] = SteamId;
pred@1953
   275
					}
pred@1953
   276
					else if (StrEqual(inputBuffer, "userid2"))
pred@1953
   277
					{
pred@1953
   278
						submenuInput[Submenu_method] = UserId2;
pred@1953
   279
					}
pred@1953
   280
					else if (StrEqual(inputBuffer, "userid"))
pred@1953
   281
					{
pred@1953
   282
						submenuInput[Submenu_method] = UserId;
pred@1953
   283
					}
pred@1953
   284
					else if (StrEqual(inputBuffer, "ip"))
pred@1953
   285
					{
pred@1953
   286
						submenuInput[Submenu_method] = IpAddress;
pred@1953
   287
					}
pred@1953
   288
					else
pred@1953
   289
					{
pred@1953
   290
						submenuInput[Submenu_method] = Name;
pred@2177
   291
					}				
pred@1953
   292
				}
pred@1953
   293
				
pred@1953
   294
				KvGetString(kvMenu, "title", inputBuffer, sizeof(inputBuffer));
pred@1953
   295
				strcopy(submenuInput[Submenu_title], sizeof(submenuInput[Submenu_title]), inputBuffer);
pred@1953
   296
	  			
pred@1953
   297
	  			count++;
pred@1953
   298
	  			Format(countBuffer, sizeof(countBuffer), "%i", count);
pred@1953
   299
	  			
pred@1953
   300
	  			PushArrayArray(itemInput[Item_submenus], submenuInput[0]);
pred@1953
   301
	  		
pred@1953
   302
	  			KvGoBack(kvMenu);	
pred@1953
   303
  			}
pred@1953
   304
  			
pred@1953
   305
  			/* Save this entire item into the global items array and add it to the menu */
pred@1953
   306
  			
pred@1953
   307
  			new location = PushArrayArray(g_DataArray, itemInput[0]);
dvander@1945
   308
			
pred@1953
   309
			decl String:locString[10];
pred@1953
   310
			IntToString(location, locString, sizeof(locString));
pred@1953
   311
dvander@2836
   312
			if (AddToTopMenu(hAdminMenu,
dvander@2836
   313
				buffer,
dvander@2836
   314
				TopMenuObject_Item,
dvander@2836
   315
				DynamicMenuItemHandler,
dvander@2836
   316
  				categoryId,
dvander@2836
   317
  				admin,
dvander@2836
   318
  				ADMFLAG_GENERIC,
dvander@2836
   319
  				locString) == INVALID_TOPMENUOBJECT)
dvander@2836
   320
			{
dvander@2836
   321
				LogError("Duplicate command name \"%s\" in adminmenu_custom.txt category \"%s\"", buffer, category_name);
dvander@2836
   322
			}
dvander@1945
   323
		
pred@1953
   324
		} while (KvGotoNextKey(kvMenu));
dvander@1945
   325
		
pred@1953
   326
		KvGoBack(kvMenu);
dvander@1945
   327
		
pred@1953
   328
	} while (KvGotoNextKey(kvMenu));
dvander@1945
   329
	
pred@1953
   330
	CloseHandle(kvMenu);
dvander@1945
   331
}
dvander@1945
   332
dvander@1945
   333
ParseConfigs()
dvander@1945
   334
{
dvander@1945
   335
	if (g_configParser == INVALID_HANDLE)
dvander@1945
   336
	{
dvander@1945
   337
		g_configParser = SMC_CreateParser();
dvander@1945
   338
	}
dvander@1945
   339
	
dvander@1945
   340
	SMC_SetReaders(g_configParser, NewSection, KeyValue, EndSection);
dvander@1945
   341
	
dvander@1945
   342
	if (g_groupList[groupListName] != INVALID_HANDLE)
dvander@1945
   343
	{
dvander@1945
   344
		CloseHandle(g_groupList[groupListName]);
dvander@1945
   345
	}
dvander@1945
   346
	
dvander@1945
   347
	if (g_groupList[groupListCommand] != INVALID_HANDLE)
dvander@1945
   348
	{
dvander@1945
   349
		CloseHandle(g_groupList[groupListCommand]);
dvander@1945
   350
	}
dvander@1945
   351
	
dvander@1945
   352
	g_groupList[groupListName] = CreateArray(ARRAY_STRING_LENGTH);
dvander@1945
   353
	g_groupList[groupListCommand] = CreateArray(ARRAY_STRING_LENGTH);
dvander@1945
   354
	
dvander@1945
   355
	decl String:configPath[256];
dvander@1945
   356
	BuildPath(Path_SM, configPath, sizeof(configPath), "configs/dynamicmenu/adminmenu_grouping.txt");
dvander@2099
   357
	if (FileExists(configPath))
dvander@2099
   358
	{
dvander@2099
   359
		LogError("Warning! configs/dynamicmenu/adminmenu_grouping.txt is now configs/adminmenu_grouping.txt.");
dvander@2099
   360
		LogError("Read the 1.0.2 release notes, as the dynamicmenu folder has been removed.");
dvander@2099
   361
	}
dvander@2099
   362
	else
dvander@2099
   363
	{
dvander@2099
   364
		BuildPath(Path_SM, configPath, sizeof(configPath), "configs/adminmenu_grouping.txt");
dvander@2099
   365
	}
dvander@1945
   366
	
dvander@1945
   367
	if (!FileExists(configPath))
dvander@1945
   368
	{
ds@1984
   369
		LogError("Unable to locate admin menu groups file: %s", configPath);
dvander@1945
   370
			
dvander@1945
   371
		return;		
dvander@1945
   372
	}
dvander@1945
   373
	
dvander@1945
   374
	new line;
dvander@1945
   375
	new SMCError:err = SMC_ParseFile(g_configParser, configPath, line);
dvander@1945
   376
	if (err != SMCError_Okay)
dvander@1945
   377
	{
dvander@1945
   378
		decl String:error[256];
dvander@1945
   379
		SMC_GetErrorString(err, error, sizeof(error));
dvander@1945
   380
		LogError("Could not parse file (line %d, file \"%s\"):", line, configPath);
dvander@1945
   381
		LogError("Parser encountered error: %s", error);
dvander@1945
   382
	}
dvander@1945
   383
	
dvander@1945
   384
	return;
dvander@1945
   385
}
dvander@1945
   386
dvander@1945
   387
public SMCResult:NewSection(Handle:smc, const String:name[], bool:opt_quotes)
dvander@1945
   388
{
dvander@1945
   389
dvander@1945
   390
}
dvander@1945
   391
dvander@1945
   392
public SMCResult:KeyValue(Handle:smc, const String:key[], const String:value[], bool:key_quotes, bool:value_quotes)
dvander@1945
   393
{
dvander@1945
   394
	PushArrayString(g_groupList[groupListName], key);
dvander@1945
   395
	PushArrayString(g_groupList[groupListCommand], value);
dvander@1945
   396
}
dvander@1945
   397
dvander@1945
   398
public SMCResult:EndSection(Handle:smc)
dvander@1945
   399
{
dvander@1945
   400
	g_groupCount = GetArraySize(g_groupList[groupListName]);
dvander@1945
   401
}
dvander@1945
   402
dvander@1945
   403
public DynamicMenuCategoryHandler(Handle:topmenu, 
dvander@1945
   404
						TopMenuAction:action,
dvander@1945
   405
						TopMenuObject:object_id,
dvander@1945
   406
						param,
dvander@1945
   407
						String:buffer[],
dvander@1945
   408
						maxlength)
dvander@1945
   409
{
dvander@1945
   410
	if ((action == TopMenuAction_DisplayTitle) || (action == TopMenuAction_DisplayOption))
dvander@1945
   411
	{
dvander@1945
   412
		GetTopMenuObjName(topmenu, object_id, buffer, maxlength);
dvander@1945
   413
	}
dvander@1945
   414
}
dvander@1945
   415
dvander@1945
   416
public DynamicMenuItemHandler(Handle:topmenu, 
dvander@1945
   417
					  TopMenuAction:action,
dvander@1945
   418
					  TopMenuObject:object_id,
dvander@1945
   419
					  param,
dvander@1945
   420
					  String:buffer[],
dvander@1945
   421
					  maxlength)
dvander@1945
   422
{
dvander@1945
   423
	if (action == TopMenuAction_DisplayOption)
dvander@1945
   424
	{
dvander@1945
   425
		GetTopMenuObjName(topmenu, object_id, buffer, maxlength);
dvander@1945
   426
	}
dvander@1945
   427
	else if (action == TopMenuAction_SelectOption)
dvander@1945
   428
	{	
pred@1953
   429
		new String:locString[10];
pred@1953
   430
		GetTopMenuInfoString(topmenu, object_id, locString, sizeof(locString));
dvander@1945
   431
		
pred@1953
   432
		new location = StringToInt(locString);
dvander@1945
   433
		
pred@1953
   434
		new output[Item];
pred@1953
   435
		GetArrayArray(g_DataArray, location, output[0]);
dvander@1945
   436
		
pred@1953
   437
		strcopy(g_command[param], sizeof(g_command[]), output[Item_cmd]);
dvander@1945
   438
					
pred@1953
   439
		g_currentPlace[param][Place_Item] = location;
pred@2078
   440
		g_currentPlace[param][Place_ReplaceNum] = 1;
dvander@1945
   441
		
dvander@1945
   442
		ParamCheck(param);
dvander@1945
   443
	}
dvander@1945
   444
}
dvander@1945
   445
dvander@1945
   446
public ParamCheck(client)
dvander@1945
   447
{
dvander@1945
   448
	new String:buffer[6];
dvander@1945
   449
	new String:buffer2[6];
dvander@1945
   450
	
pred@1953
   451
	new outputItem[Item];
pred@1953
   452
	new outputSubmenu[Submenu];
pred@1953
   453
	
pred@1953
   454
	GetArrayArray(g_DataArray, g_currentPlace[client][Place_Item], outputItem[0]);
dvander@1945
   455
		
dvander@1945
   456
	if (g_currentPlace[client][Place_ReplaceNum] < 1)
dvander@1945
   457
	{
dvander@1945
   458
		g_currentPlace[client][Place_ReplaceNum] = 1;
dvander@1945
   459
	}
dvander@1945
   460
	
dvander@1945
   461
	Format(buffer, 5, "#%i", g_currentPlace[client][Place_ReplaceNum]);
dvander@1945
   462
	Format(buffer2, 5, "@%i", g_currentPlace[client][Place_ReplaceNum]);
dvander@1945
   463
	
dvander@1945
   464
	if (StrContains(g_command[client], buffer) != -1 || StrContains(g_command[client], buffer2) != -1)
dvander@1945
   465
	{
pred@1953
   466
		GetArrayArray(outputItem[Item_submenus], g_currentPlace[client][Place_ReplaceNum] - 1, outputSubmenu[0]);
dvander@1945
   467
		
dvander@1945
   468
		new Handle:itemMenu = CreateMenu(Menu_Selection);
pred@2079
   469
		SetMenuExitBackButton(itemMenu, true);
dvander@1945
   470
			
pred@1953
   471
		if ((outputSubmenu[Submenu_type] == SubMenu_Group) || (outputSubmenu[Submenu_type] == SubMenu_GroupPlayer))
dvander@1945
   472
		{	
dvander@1945
   473
			decl String:nameBuffer[ARRAY_STRING_LENGTH];
dvander@1945
   474
			decl String:commandBuffer[ARRAY_STRING_LENGTH];
dvander@1945
   475
		
dvander@1945
   476
			for (new i = 0; i<g_groupCount; i++)
dvander@1945
   477
			{			
dvander@1945
   478
				GetArrayString(g_groupList[groupListName], i, nameBuffer, sizeof(nameBuffer));
dvander@1945
   479
				GetArrayString(g_groupList[groupListCommand], i, commandBuffer, sizeof(commandBuffer));
dvander@1945
   480
				AddMenuItem(itemMenu, commandBuffer, nameBuffer);
dvander@1945
   481
			}
dvander@1945
   482
		}
dvander@1945
   483
		
pred@1953
   484
		if (outputSubmenu[Submenu_type] == SubMenu_MapCycle)
pred@1953
   485
		{	
dvander@1945
   486
			decl String:path[200];
pred@1953
   487
			ReadPackString(outputSubmenu[Submenu_listdata], path, sizeof(path));
pred@1953
   488
			ResetPack(outputSubmenu[Submenu_listdata]);
dvander@1945
   489
		
dvander@1945
   490
			new Handle:file = OpenFile(path, "rt");
dvander@1945
   491
			new String:readData[128];
dvander@1945
   492
			
dvander@1945
   493
			if(file != INVALID_HANDLE)
dvander@1945
   494
			{
dvander@1945
   495
				while(!IsEndOfFile(file) && ReadFileLine(file, readData, sizeof(readData)))
dvander@1945
   496
				{
dvander@1945
   497
					TrimString(readData);
dvander@1945
   498
					
dvander@1945
   499
					if (IsMapValid(readData))
dvander@1945
   500
					{
dvander@1945
   501
						AddMenuItem(itemMenu, readData, readData);
dvander@1945
   502
					}
dvander@1945
   503
				}
dvander@1945
   504
			}
dvander@1945
   505
		}
pred@1953
   506
		else if ((outputSubmenu[Submenu_type] == SubMenu_Player) || (outputSubmenu[Submenu_type] == SubMenu_GroupPlayer))
dvander@1945
   507
		{
pred@1953
   508
			new PlayerMethod:playermethod = outputSubmenu[Submenu_method];
pred@1953
   509
		
dvander@1945
   510
			new String:nameBuffer[32];
dvander@1945
   511
			new String:infoBuffer[32];
dvander@1945
   512
			new String:temp[4];
dvander@1945
   513
			
dvander@1945
   514
			//loop through players. Add name as text and name/userid/steamid as info
dvander@1945
   515
			for (new i=1; i<=g_maxPlayers; i++)
dvander@1945
   516
			{
dvander@1945
   517
				if (IsClientInGame(i))
dvander@1945
   518
				{			
dvander@1945
   519
					GetClientName(i, nameBuffer, 31);
dvander@1945
   520
					
dvander@1945
   521
					switch (playermethod)
dvander@1945
   522
					{
dvander@1945
   523
						case UserId:
dvander@1945
   524
						{
dvander@1945
   525
							new userid = GetClientUserId(i);
dvander@1945
   526
							Format(infoBuffer, sizeof(infoBuffer), "#%i", userid);
dvander@1945
   527
							AddMenuItem(itemMenu, infoBuffer, nameBuffer);	
dvander@1945
   528
						}
dvander@1945
   529
						case UserId2:
dvander@1945
   530
						{
dvander@1945
   531
							new userid = GetClientUserId(i);
dvander@1945
   532
							Format(infoBuffer, sizeof(infoBuffer), "%i", userid);
dvander@1945
   533
							AddMenuItem(itemMenu, infoBuffer, nameBuffer);							
dvander@1945
   534
						}
dvander@1945
   535
						case SteamId:
dvander@1945
   536
						{
dvander@1945
   537
							GetClientAuthString(i, infoBuffer, sizeof(infoBuffer));
dvander@1945
   538
							AddMenuItem(itemMenu, infoBuffer, nameBuffer);							
dvander@1945
   539
						}	
dvander@1945
   540
						case IpAddress:
dvander@1945
   541
						{
dvander@1945
   542
							GetClientIP(i, infoBuffer, sizeof(infoBuffer));
dvander@1945
   543
							AddMenuItem(itemMenu, infoBuffer, nameBuffer);							
dvander@1945
   544
						}
dvander@1945
   545
						case Name:
dvander@1945
   546
						{
dvander@1945
   547
							AddMenuItem(itemMenu, nameBuffer, nameBuffer);
dvander@1945
   548
						}	
dvander@1945
   549
						default: //assume client id
dvander@1945
   550
						{
dvander@1945
   551
							Format(temp,3,"%i",i);
dvander@1945
   552
							AddMenuItem(itemMenu, temp, nameBuffer);						
dvander@1945
   553
						}								
dvander@1945
   554
					}
dvander@1945
   555
				}
dvander@1945
   556
			}
dvander@1945
   557
		}
pred@1953
   558
		else if (outputSubmenu[Submenu_type] == SubMenu_OnOff)
dvander@1945
   559
		{
dvander@1945
   560
			AddMenuItem(itemMenu, "1", "On");
dvander@1945
   561
			AddMenuItem(itemMenu, "0", "Off");
dvander@1945
   562
		}		
dvander@1945
   563
		else
dvander@1945
   564
		{
dvander@1945
   565
			new String:value[64];
dvander@1945
   566
			new String:text[64];
dvander@1945
   567
					
dvander@1945
   568
			new String:admin[NAME_LENGTH];
pred@1953
   569
			
pred@1953
   570
			for (new i=0; i<outputSubmenu[Submenu_listcount]; i++)
dvander@1945
   571
			{
pred@1953
   572
				ReadPackString(outputSubmenu[Submenu_listdata], value, sizeof(value));
pred@1953
   573
				ReadPackString(outputSubmenu[Submenu_listdata], text, sizeof(text));
pred@1953
   574
				ReadPackString(outputSubmenu[Submenu_listdata], admin, sizeof(admin));
dvander@1945
   575
				
pred@1953
   576
				if (CheckCommandAccess(client, admin, 0))
dvander@1945
   577
				{
dvander@1945
   578
					AddMenuItem(itemMenu, value, text);
dvander@1945
   579
				}
pred@1953
   580
			}
pred@1953
   581
			
pred@1953
   582
			ResetPack(outputSubmenu[Submenu_listdata]);	
dvander@1945
   583
		}
dvander@1945
   584
		
pred@1953
   585
		SetMenuTitle(itemMenu, outputSubmenu[Submenu_title]);
dvander@1945
   586
		
dvander@1945
   587
		DisplayMenu(itemMenu, client, MENU_TIME_FOREVER);
dvander@1945
   588
	}
dvander@1945
   589
	else
dvander@1945
   590
	{	
dvander@1945
   591
		//nothing else need to be done. Run teh command.
dvander@1945
   592
		
dvander@1945
   593
		DisplayTopMenu(hAdminMenu, client, TopMenuPosition_LastCategory);
dvander@1945
   594
		
pred@2177
   595
		decl String:unquotedCommand[CMD_LENGTH];
pred@2177
   596
		UnQuoteString(g_command[client], unquotedCommand, sizeof(unquotedCommand), "#@");
pred@2177
   597
		
pred@1953
   598
		if (outputItem[Item_execute] == Execute_Player) // assume 'player' type execute option
dvander@1945
   599
		{
pred@2177
   600
			FakeClientCommand(client, unquotedCommand);
dvander@1945
   601
		}
dvander@1945
   602
		else // assume 'server' type execute option
dvander@1945
   603
		{
pred@2177
   604
			InsertServerCommand(unquotedCommand);
dvander@1945
   605
			ServerExecute();
dvander@1945
   606
		}
dvander@1945
   607
dvander@1945
   608
		g_command[client][0] = '\0';
dvander@1945
   609
		g_currentPlace[client][Place_ReplaceNum] = 1;
dvander@1945
   610
	}
dvander@1945
   611
}
dvander@1945
   612
dvander@1945
   613
public Menu_Selection(Handle:menu, MenuAction:action, param1, param2)
dvander@1945
   614
{
dvander@1945
   615
	if (action == MenuAction_End)
dvander@1945
   616
	{
dvander@1945
   617
		CloseHandle(menu);
dvander@1945
   618
	}
dvander@1945
   619
	
dvander@1945
   620
	if (action == MenuAction_Select)
dvander@1945
   621
	{
pred@2177
   622
		new String:unquotedinfo[NAME_LENGTH];
dvander@1945
   623
 
dvander@1945
   624
		/* Get item info */
pred@2177
   625
		new bool:found = GetMenuItem(menu, param2, unquotedinfo, sizeof(unquotedinfo));
dvander@1945
   626
		
dvander@1945
   627
		if (!found)
dvander@1945
   628
		{
dvander@1945
   629
			return;
dvander@1945
   630
		}
dvander@1945
   631
		
pred@2177
   632
		new String:info[NAME_LENGTH*2+1];
pred@2177
   633
		QuoteString(unquotedinfo, info, sizeof(info), "#@");
pred@2177
   634
		
pred@2177
   635
		
dvander@1945
   636
		new String:buffer[6];
dvander@1945
   637
		new String:infobuffer[NAME_LENGTH+2];
dvander@1945
   638
		Format(infobuffer, sizeof(infobuffer), "\"%s\"", info);
dvander@1945
   639
		
dvander@1945
   640
		Format(buffer, 5, "#%i", g_currentPlace[param1][Place_ReplaceNum]);
dvander@1945
   641
		ReplaceString(g_command[param1], sizeof(g_command[]), buffer, infobuffer);
dvander@1945
   642
		//replace #num with the selected option (quoted)
dvander@1945
   643
		
dvander@1945
   644
		Format(buffer, 5, "@%i", g_currentPlace[param1][Place_ReplaceNum]);
dvander@1945
   645
		ReplaceString(g_command[param1], sizeof(g_command[]), buffer, info);
dvander@1945
   646
		//replace @num with the selected option (unquoted)
dvander@1945
   647
		
dvander@1945
   648
		// Increment the parameter counter.
dvander@1945
   649
		g_currentPlace[param1][Place_ReplaceNum]++;
dvander@1945
   650
		
dvander@1945
   651
		ParamCheck(param1);
dvander@1945
   652
	}
dvander@1945
   653
	
pred@2079
   654
	if (action == MenuAction_Cancel && param2 == MenuCancel_ExitBack)
dvander@1945
   655
	{
dvander@1945
   656
		//client exited we should go back to submenu i think
dvander@1945
   657
		DisplayTopMenu(hAdminMenu, param1, TopMenuPosition_LastCategory);
dvander@1945
   658
	}
pred@2177
   659
}
pred@2177
   660
pred@2177
   661
pred@2177
   662
stock bool:QuoteString(String:input[], String:output[], maxlen, String:quotechars[])
pred@2177
   663
{
pred@2177
   664
	new count = 0;
pred@2177
   665
	new len = strlen(input);
pred@2177
   666
	
pred@2177
   667
	for (new i=0; i<len; i++)
pred@2177
   668
	{
pred@2177
   669
		output[count] = input[i];
pred@2177
   670
		count++;
pred@2177
   671
		
pred@2177
   672
		if (count >= maxlen)
pred@2177
   673
		{
pred@2177
   674
			/* Null terminate for safety */
pred@2177
   675
			output[maxlen-1] = 0;
pred@2177
   676
			return false;	
pred@2177
   677
		}
pred@2177
   678
		
pred@2177
   679
		if (FindCharInString(quotechars, input[i]) != -1 || input[i] == '\\')
pred@2177
   680
		{
pred@2177
   681
			/* This char needs escaping */
pred@2177
   682
			output[count] = '\\';
pred@2177
   683
			count++;
pred@2177
   684
			
pred@2177
   685
			if (count >= maxlen)
pred@2177
   686
			{
pred@2177
   687
				/* Null terminate for safety */
pred@2177
   688
				output[maxlen-1] = 0;
pred@2177
   689
				return false;	
pred@2177
   690
			}		
pred@2177
   691
		}
pred@2177
   692
	}
pred@2177
   693
	
pred@2177
   694
	output[count] = 0;
pred@2177
   695
	
pred@2177
   696
	return true;
pred@2177
   697
}
pred@2177
   698
pred@2177
   699
stock bool:UnQuoteString(String:input[], String:output[], maxlen, String:quotechars[])
pred@2177
   700
{
pred@2177
   701
	new count = 1;
pred@2177
   702
	new len = strlen(input);
pred@2177
   703
	
pred@2177
   704
	output[0] = input[0];
pred@2177
   705
	
pred@2177
   706
	for (new i=1; i<len; i++)
pred@2177
   707
	{
pred@2177
   708
		output[count] = input[i];
pred@2177
   709
		count++;
pred@2177
   710
		
pred@2177
   711
		if (input[i+1] == '\\' && (input[i] == '\\' || FindCharInString(quotechars, input[i]) != -1))
pred@2177
   712
		{
pred@2177
   713
			/* valid quotechar followed by a backslash - Skip */
pred@2177
   714
			i++; 
pred@2177
   715
		}
pred@2177
   716
		
pred@2177
   717
		if (count >= maxlen)
pred@2177
   718
		{
pred@2177
   719
			/* Null terminate for safety */
pred@2177
   720
			output[maxlen-1] = 0;
pred@2177
   721
			return false;	
pred@2177
   722
		}
pred@2177
   723
	}
pred@2177
   724
	
pred@2177
   725
	output[count] = 0;
pred@2177
   726
	
pred@2177
   727
	return true;
mr@2565
   728
}