ds@1952: ds@1952: #define NAME_LENGTH 32 ds@1952: #define CMD_LENGTH 255 ds@1952: ds@1952: #define ARRAY_STRING_LENGTH 32 ds@1952: ds@1952: enum GroupCommands ds@1952: { ds@1952: Handle:groupListName, ds@1952: Handle:groupListCommand ds@1952: }; ds@1952: ds@1952: new g_groupList[GroupCommands]; ds@1952: new g_groupCount; ds@1952: ds@1952: new Handle:g_configParser = INVALID_HANDLE; ds@1952: ds@1952: enum Places ds@1952: { ds@1952: Place_Category, ds@1952: Place_Item, ds@1952: Place_ReplaceNum ds@1952: }; ds@1952: ds@1952: new String:g_command[MAXPLAYERS+1][CMD_LENGTH]; ds@1952: new g_currentPlace[MAXPLAYERS+1][Places]; ds@1952: ds@1952: /** ds@1952: * What to put in the 'info' menu field (for PlayerList and Player_Team menus only) ds@1952: */ ds@1952: enum PlayerMethod ds@1952: { ds@1952: ClientId, /** Client id number ( 1 - Maxplayers) */ ds@1952: UserId, /** Client userid */ ds@1952: Name, /** Client Name */ ds@1952: SteamId, /** Client Steamid */ ds@1952: IpAddress, /** Client's Ip Address */ ds@1952: UserId2 /** Userid (not prefixed with #) */ ds@1952: }; ds@1952: pred@1953: enum ExecuteType pred@1953: { pred@1953: Execute_Player, pred@1953: Execute_Server pred@1953: } pred@1953: pred@1953: enum SubMenu_Type pred@1953: { pred@1953: SubMenu_Group, pred@1953: SubMenu_GroupPlayer, pred@1953: SubMenu_Player, pred@1953: SubMenu_MapCycle, pred@1953: SubMenu_List, pred@1953: SubMenu_OnOff pred@1953: } pred@1953: pred@1953: enum Item pred@1953: { pred@1953: String:Item_cmd[256], pred@1953: ExecuteType:Item_execute, pred@1953: Handle:Item_submenus pred@1953: } pred@1953: pred@1953: enum Submenu pred@1953: { pred@1953: SubMenu_Type:Submenu_type, pred@1953: String:Submenu_title[32], pred@1953: PlayerMethod:Submenu_method, pred@1953: Submenu_listcount, pred@1953: Handle:Submenu_listdata pred@1953: } pred@1953: pred@1953: new Handle:g_DataArray; pred@1953: ds@1952: BuildDynamicMenu() ds@1952: { pred@1953: new itemInput[Item]; pred@1953: g_DataArray = CreateArray(sizeof(itemInput)); ds@1952: pred@1953: new String:executeBuffer[32]; pred@1953: pred@1953: new Handle:kvMenu; pred@1953: kvMenu = CreateKeyValues("Commands"); ds@1952: new String:file[256]; ds@1952: BuildPath(Path_SM, file, 255, "configs/dynamicmenu/menu.ini"); pred@1953: FileToKeyValues(kvMenu, file); ds@1952: ds@1952: new String:name[NAME_LENGTH]; ds@1952: new String:buffer[NAME_LENGTH]; ds@1952: pred@1953: KvSetEscapeSequences(kvMenu, true); pred@1953: pred@1953: if (!KvGotoFirstSubKey(kvMenu)) ds@1952: { ds@1952: return; ds@1952: } ds@1952: ds@1952: decl String:admin[30]; ds@1952: ds@1952: new TopMenuObject:categoryId; ds@1952: ds@1952: do ds@1952: { pred@1953: KvGetSectionName(kvMenu, buffer, sizeof(buffer)); ds@1952: pred@1953: KvGetString(kvMenu, "admin", admin, sizeof(admin),"sm_admin"); ds@1952: ds@1952: if ((categoryId =FindTopMenuCategory(hAdminMenu, buffer)) == INVALID_TOPMENUOBJECT) ds@1952: { ds@1952: categoryId = AddToTopMenu(hAdminMenu, ds@1952: buffer, ds@1952: TopMenuObject_Category, ds@1952: DynamicMenuCategoryHandler, ds@1952: INVALID_TOPMENUOBJECT, ds@1952: admin, ds@1952: ADMFLAG_GENERIC, ds@1952: name); ds@1952: ds@1952: } ds@1952: pred@1953: if (!KvGotoFirstSubKey(kvMenu)) ds@1952: { ds@1952: return; ds@1952: } ds@1952: ds@1952: do ds@1952: { pred@1953: KvGetSectionName(kvMenu, buffer, sizeof(buffer)); pred@1953: pred@1953: KvGetString(kvMenu, "admin", admin, sizeof(admin),""); ds@1952: ds@1952: if (admin[0] == '\0') ds@1952: { ds@1952: //No 'admin' keyvalue was found ds@1952: //Use the first argument of the 'cmd' string instead ds@1952: ds@1952: decl String:temp[64]; pred@1953: KvGetString(kvMenu, "cmd", temp, sizeof(temp),""); ds@1952: ds@1952: BreakString(temp, admin, sizeof(admin)); ds@1952: } pred@1953: pred@1953: pred@1953: KvGetString(kvMenu, "cmd", itemInput[Item_cmd], sizeof(itemInput[Item_cmd])); pred@1953: KvGetString(kvMenu, "execute", executeBuffer, sizeof(executeBuffer)); pred@1953: pred@1953: if (StrEqual(executeBuffer, "server")) ds@1952: { pred@1953: itemInput[Item_execute] = Execute_Server; pred@1953: } pred@1953: else //assume player type execute pred@1953: { pred@1953: itemInput[Item_execute] = Execute_Player; ds@1952: } pred@1953: pred@1953: /* iterate all submenus and load data into itemInput[Item_submenus] (adt array handle) */ pred@1953: pred@1953: new count = 1; pred@1953: decl String:countBuffer[10] = "1"; pred@1953: pred@1953: decl String:inputBuffer[32]; pred@1953: pred@1953: while (KvJumpToKey(kvMenu, countBuffer)) pred@1953: { pred@1953: new submenuInput[Submenu]; pred@1953: pred@1953: if (count == 1) pred@1953: { pred@1953: itemInput[Item_submenus] = CreateArray(sizeof(submenuInput)); pred@1953: } pred@1953: pred@1953: KvGetString(kvMenu, "type", inputBuffer, sizeof(inputBuffer)); pred@1953: pred@1953: if (strncmp(inputBuffer,"group",5)==0) pred@1953: { pred@1953: if (StrContains(inputBuffer, "player") != -1) pred@1953: { pred@1953: submenuInput[Submenu_type] = SubMenu_GroupPlayer; pred@1953: } pred@1953: else pred@1953: { pred@1953: submenuInput[Submenu_type] = SubMenu_Group; pred@1953: } pred@1953: } pred@1953: else if (StrEqual(inputBuffer,"mapcycle")) pred@1953: { pred@1953: submenuInput[Submenu_type] = SubMenu_MapCycle; pred@1953: pred@1953: KvGetString(kvMenu, "path", inputBuffer, sizeof(inputBuffer),"mapcycle.txt"); pred@1953: pred@1953: submenuInput[Submenu_listdata] = CreateDataPack(); pred@1953: WritePackString(submenuInput[Submenu_listdata], inputBuffer); pred@1953: ResetPack(submenuInput[Submenu_listdata]); pred@1953: } pred@1953: else if (StrContains(inputBuffer, "player") != -1) pred@1953: { pred@1953: submenuInput[Submenu_type] = SubMenu_Player; pred@1953: } pred@1953: else if (StrEqual(inputBuffer,"onoff")) pred@1953: { pred@1953: submenuInput[Submenu_type] = SubMenu_OnOff; pred@1953: } pred@1953: else //assume 'list' type pred@1953: { pred@1953: submenuInput[Submenu_type] = SubMenu_List; pred@1953: pred@1953: submenuInput[Submenu_listdata] = CreateDataPack(); pred@1953: pred@1953: new String:temp[6]; pred@1953: new String:value[64]; pred@1953: new String:text[64]; pred@1953: new i=1; pred@1953: new bool:more = true; pred@1953: pred@1953: new listcount = 0; pred@1953: pred@1953: do pred@1953: { pred@1953: Format(temp,3,"%i",i); pred@1953: KvGetString(kvMenu, temp, value, sizeof(value), ""); pred@1953: pred@1953: Format(temp,5,"%i.",i); pred@1953: KvGetString(kvMenu, temp, text, sizeof(text), value); pred@1953: pred@1953: Format(temp,5,"%i*",i); pred@1953: KvGetString(kvMenu, temp, admin, sizeof(admin),""); pred@1953: pred@1953: if (value[0]=='\0') pred@1953: { pred@1953: more = false; pred@1953: } pred@1953: else pred@1953: { pred@1953: listcount++; pred@1953: WritePackString(submenuInput[Submenu_listdata], value); pred@1953: WritePackString(submenuInput[Submenu_listdata], text); pred@1953: WritePackString(submenuInput[Submenu_listdata], admin); pred@1953: } pred@1953: pred@1953: i++; pred@1953: pred@1953: } while (more); pred@1953: pred@1953: ResetPack(submenuInput[Submenu_listdata]); pred@1953: submenuInput[Submenu_listcount] = listcount; pred@1953: } pred@1953: pred@1953: if ((submenuInput[Submenu_type] == SubMenu_Player) || (submenuInput[Submenu_type] == SubMenu_GroupPlayer)) pred@1953: { pred@1953: KvGetString(kvMenu, "method", inputBuffer, sizeof(inputBuffer)); pred@1953: pred@1953: if (StrEqual(inputBuffer, "clientid")) pred@1953: { pred@1953: submenuInput[Submenu_method] = ClientId; pred@1953: } pred@1953: else if (StrEqual(inputBuffer, "steamid")) pred@1953: { pred@1953: submenuInput[Submenu_method] = SteamId; pred@1953: } pred@1953: else if (StrEqual(inputBuffer, "userid2")) pred@1953: { pred@1953: submenuInput[Submenu_method] = UserId2; pred@1953: } pred@1953: else if (StrEqual(inputBuffer, "userid")) pred@1953: { pred@1953: submenuInput[Submenu_method] = UserId; pred@1953: } pred@1953: else if (StrEqual(inputBuffer, "ip")) pred@1953: { pred@1953: submenuInput[Submenu_method] = IpAddress; pred@1953: } pred@1953: else pred@1953: { pred@1953: submenuInput[Submenu_method] = Name; pred@1953: } pred@1953: pred@1953: } pred@1953: pred@1953: KvGetString(kvMenu, "title", inputBuffer, sizeof(inputBuffer)); pred@1953: strcopy(submenuInput[Submenu_title], sizeof(submenuInput[Submenu_title]), inputBuffer); pred@1953: pred@1953: count++; pred@1953: Format(countBuffer, sizeof(countBuffer), "%i", count); pred@1953: pred@1953: PushArrayArray(itemInput[Item_submenus], submenuInput[0]); pred@1953: pred@1953: KvGoBack(kvMenu); pred@1953: } pred@1953: pred@1953: /* Save this entire item into the global items array and add it to the menu */ pred@1953: pred@1953: new location = PushArrayArray(g_DataArray, itemInput[0]); ds@1952: pred@1953: decl String:locString[10]; pred@1953: IntToString(location, locString, sizeof(locString)); pred@1953: ds@1952: AddToTopMenu(hAdminMenu, ds@1952: buffer, ds@1952: TopMenuObject_Item, ds@1952: DynamicMenuItemHandler, ds@1952: categoryId, ds@1952: admin, ds@1952: ADMFLAG_GENERIC, pred@1953: locString); ds@1952: pred@1953: } while (KvGotoNextKey(kvMenu)); ds@1952: pred@1953: KvGoBack(kvMenu); ds@1952: pred@1953: } while (KvGotoNextKey(kvMenu)); ds@1952: pred@1953: CloseHandle(kvMenu); ds@1952: } ds@1952: ds@1952: ParseConfigs() ds@1952: { ds@1952: if (g_configParser == INVALID_HANDLE) ds@1952: { ds@1952: g_configParser = SMC_CreateParser(); ds@1952: } ds@1952: ds@1952: SMC_SetReaders(g_configParser, NewSection, KeyValue, EndSection); ds@1952: ds@1952: if (g_groupList[groupListName] != INVALID_HANDLE) ds@1952: { ds@1952: CloseHandle(g_groupList[groupListName]); ds@1952: } ds@1952: ds@1952: if (g_groupList[groupListCommand] != INVALID_HANDLE) ds@1952: { ds@1952: CloseHandle(g_groupList[groupListCommand]); ds@1952: } ds@1952: ds@1952: g_groupList[groupListName] = CreateArray(ARRAY_STRING_LENGTH); ds@1952: g_groupList[groupListCommand] = CreateArray(ARRAY_STRING_LENGTH); ds@1952: ds@1952: decl String:configPath[256]; ds@1952: BuildPath(Path_SM, configPath, sizeof(configPath), "configs/dynamicmenu/adminmenu_grouping.txt"); ds@1952: ds@1952: if (!FileExists(configPath)) ds@1952: { ds@1952: LogError("Unable to locate admin menu groups file, no groups loaded."); ds@1952: ds@1952: return; ds@1952: } ds@1952: ds@1952: new line; ds@1952: new SMCError:err = SMC_ParseFile(g_configParser, configPath, line); ds@1952: if (err != SMCError_Okay) ds@1952: { ds@1952: decl String:error[256]; ds@1952: SMC_GetErrorString(err, error, sizeof(error)); ds@1952: LogError("Could not parse file (line %d, file \"%s\"):", line, configPath); ds@1952: LogError("Parser encountered error: %s", error); ds@1952: } ds@1952: ds@1952: return; ds@1952: } ds@1952: ds@1952: public SMCResult:NewSection(Handle:smc, const String:name[], bool:opt_quotes) ds@1952: { ds@1952: ds@1952: } ds@1952: ds@1952: public SMCResult:KeyValue(Handle:smc, const String:key[], const String:value[], bool:key_quotes, bool:value_quotes) ds@1952: { ds@1952: PushArrayString(g_groupList[groupListName], key); ds@1952: PushArrayString(g_groupList[groupListCommand], value); ds@1952: } ds@1952: ds@1952: public SMCResult:EndSection(Handle:smc) ds@1952: { ds@1952: g_groupCount = GetArraySize(g_groupList[groupListName]); ds@1952: } ds@1952: ds@1952: public DynamicMenuCategoryHandler(Handle:topmenu, ds@1952: TopMenuAction:action, ds@1952: TopMenuObject:object_id, ds@1952: param, ds@1952: String:buffer[], ds@1952: maxlength) ds@1952: { ds@1952: if ((action == TopMenuAction_DisplayTitle) || (action == TopMenuAction_DisplayOption)) ds@1952: { ds@1952: GetTopMenuObjName(topmenu, object_id, buffer, maxlength); ds@1952: } ds@1952: } ds@1952: ds@1952: public DynamicMenuItemHandler(Handle:topmenu, ds@1952: TopMenuAction:action, ds@1952: TopMenuObject:object_id, ds@1952: param, ds@1952: String:buffer[], ds@1952: maxlength) ds@1952: { ds@1952: if (action == TopMenuAction_DisplayOption) ds@1952: { ds@1952: GetTopMenuObjName(topmenu, object_id, buffer, maxlength); ds@1952: } ds@1952: else if (action == TopMenuAction_SelectOption) ds@1952: { pred@1953: new String:locString[10]; pred@1953: GetTopMenuInfoString(topmenu, object_id, locString, sizeof(locString)); ds@1952: pred@1953: new location = StringToInt(locString); ds@1952: pred@1953: new output[Item]; pred@1953: GetArrayArray(g_DataArray, location, output[0]); ds@1952: pred@1953: strcopy(g_command[param], sizeof(g_command[]), output[Item_cmd]); ds@1952: pred@1953: g_currentPlace[param][Place_Item] = location; ds@1952: ds@1952: ParamCheck(param); ds@1952: } ds@1952: } ds@1952: ds@1952: public ParamCheck(client) ds@1952: { ds@1952: new String:buffer[6]; ds@1952: new String:buffer2[6]; ds@1952: pred@1953: new outputItem[Item]; pred@1953: new outputSubmenu[Submenu]; pred@1953: pred@1953: GetArrayArray(g_DataArray, g_currentPlace[client][Place_Item], outputItem[0]); ds@1952: ds@1952: if (g_currentPlace[client][Place_ReplaceNum] < 1) ds@1952: { ds@1952: g_currentPlace[client][Place_ReplaceNum] = 1; ds@1952: } ds@1952: ds@1952: Format(buffer, 5, "#%i", g_currentPlace[client][Place_ReplaceNum]); ds@1952: Format(buffer2, 5, "@%i", g_currentPlace[client][Place_ReplaceNum]); ds@1952: ds@1952: if (StrContains(g_command[client], buffer) != -1 || StrContains(g_command[client], buffer2) != -1) ds@1952: { pred@1953: GetArrayArray(outputItem[Item_submenus], g_currentPlace[client][Place_ReplaceNum] - 1, outputSubmenu[0]); ds@1952: ds@1952: new Handle:itemMenu = CreateMenu(Menu_Selection); ds@1952: pred@1953: if ((outputSubmenu[Submenu_type] == SubMenu_Group) || (outputSubmenu[Submenu_type] == SubMenu_GroupPlayer)) ds@1952: { ds@1952: decl String:nameBuffer[ARRAY_STRING_LENGTH]; ds@1952: decl String:commandBuffer[ARRAY_STRING_LENGTH]; ds@1952: ds@1952: for (new i = 0; i