- added topmenus extension to build

- basecommands is slowly getting split into multiple source files now
- added experimental api of a potential admin menu design
- added experimental admin menu entry to basecommands to kick things off

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401516
This commit is contained in:
David Anderson 2007-10-01 18:50:07 +00:00
parent 2c5cd63552
commit 602b0aa6a5
6 changed files with 487 additions and 47 deletions

176
plugins/adminmenu.sp Normal file
View File

@ -0,0 +1,176 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod Anti-Flood Plugin
* Protects against chat flooding.
*
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#pragma semicolon 1
#include <sourcemod>
#include <topmenus>
public Plugin:myinfo =
{
name = "Admin Menu",
author = "AlliedModders LLC",
description = "Administration Menu",
version = SOURCEMOD_VERSION,
url = "http://www.sourcemod.net/"
};
/* Forwards */
new Handle:hOnAdminMenuReady = INVALID_HANDLE;
new Handle:hOnAdminMenuCreated = INVALID_HANDLE;
/* Menus */
new Handle:hAdminMenu = INVALID_HANDLE;
/* Top menu objects */
new TopMenuObject:obj_playercmds = INVALID_TOPMENUOBJECT;
public bool:AskPluginLoad(Handle:myself, bool:late, String:error[], err_max)
{
CreateNative("GetAdminTopMenu", __GetAdminTopMenu);
CreateNative("AddTargetsToMenu", __AddTargetsToMenu);
RegPluginLibrary("adminmenu");
return true;
}
public OnPluginStart()
{
LoadTranslations("common.phrases");
hOnAdminMenuCreated = CreateGlobalForward("OnAdminMenuCreated", ET_Ignore, Param_Cell);
hOnAdminMenuReady = CreateGlobalForward("OnAdminMenuReady", ET_Ignore, Param_Cell);
RegAdminCmd("sm_admin", Command_DisplayMenu, ADMFLAG_GENERIC, "sm_admin");
}
public OnAllPluginsLoaded()
{
hAdminMenu = CreateTopMenu(CategoryHandler);
obj_playercmds = AddToTopMenu(hAdminMenu,
"PlayerCommands",
TopMenuObject_Category,
CategoryHandler,
INVALID_TOPMENUOBJECT);
Call_StartForward(hOnAdminMenuCreated);
Call_PushCell(hAdminMenu);
Call_Finish();
Call_StartForward(hOnAdminMenuReady);
Call_PushCell(hAdminMenu);
Call_Finish();
}
public CategoryHandler(Handle:topmenu,
TopMenuAction:action,
TopMenuObject:object_id,
param,
String:buffer[],
maxlength)
{
if (action == TopMenuAction_DrawTitle)
{
if (object_id == INVALID_TOPMENUOBJECT)
{
Format(buffer, maxlength, "%T:", "Admin Menu", param);
}
else if (object_id == obj_playercmds)
{
Format(buffer, maxlength, "%T:", "Player Commands", param);
}
}
else if (action == TopMenuAction_DrawOption)
{
if (object_id == obj_playercmds)
{
Format(buffer, maxlength, "%T", "Player Commands", param);
}
return ITEMDRAW_DEFAULT;
}
return 0;
}
public __GetAdminTopMenu(Handle:plugin, numParams)
{
return _:hAdminMenu;
}
public __AddTargetsToMenu(Handle:plugin, numParams)
{
return UTIL_AddTargetsToMenu(GetNativeCell(1), GetNativeCell(2), GetNativeCell(3));
}
public Action:Command_DisplayMenu(client, args)
{
DisplayTopMenu(hAdminMenu, client, TopMenuPosition_Start);
return Plugin_Handled;
}
stock UTIL_AddTargetsToMenu(Handle:menu, source_client, bool:in_game_only)
{
new max_clients = GetMaxClients();
decl String:user_id[12];
decl String:name[MAX_NAME_LENGTH];
decl String:display[MAX_NAME_LENGTH+12];
new num_clients;
for (new i = 1; i <= max_clients; i++)
{
if (!IsClientConnected(i) || IsClientInKickQueue(i))
{
continue;
}
if (in_game_only && !IsClientInGame(i))
{
continue;
}
if (source_client && !CanUserTarget(source_client, i))
{
continue;
}
IntToString(GetClientUserId(i), user_id, sizeof(user_id));
GetClientName(i, name, sizeof(name));
Format(display, sizeof(display), "%s (%s)", name, user_id);
AddMenuItem(menu, user_id, display);
num_clients++;
}
return num_clients;
}

View File

@ -34,6 +34,8 @@
#pragma semicolon 1
#include <sourcemod>
#undef REQUIRE_PLUGIN
#include <adminmenu>
public Plugin:myinfo =
{
@ -44,6 +46,10 @@ public Plugin:myinfo =
url = "http://www.sourcemod.net/"
};
new Handle:hTopMenu = INVALID_HANDLE;
#include "basecommands/kick.sp"
public OnPluginStart()
{
LoadTranslations("common.phrases");
@ -56,6 +62,47 @@ public OnPluginStart()
RegAdminCmd("sm_who", Command_Who, ADMFLAG_GENERIC, "sm_who [#userid|name]");
RegAdminCmd("sm_reloadadmins", Command_ReloadAdmins, ADMFLAG_BAN, "sm_reloadadmins");
RegAdminCmd("sm_cancelvote", Command_CancelVote, ADMFLAG_VOTE, "sm_cancelvote");
/* Account for late loading */
new Handle:topmenu;
if (LibraryExists("adminmenu") && ((topmenu = GetAdminTopMenu()) != INVALID_HANDLE))
{
OnAdminMenuReady(topmenu);
}
}
public OnAdminMenuReady(Handle:topmenu)
{
/* Block us from being called twice */
if (topmenu == hTopMenu)
{
return;
}
/* Save the Handle */
hTopMenu = topmenu;
/* Build the "Player Commands" category */
new TopMenuObject:player_commands = FindTopMenuCategory(hTopMenu, ADMINMENU_PLAYERCOMMANDS);
if (player_commands != INVALID_TOPMENUOBJECT)
{
AddToTopMenu(hTopMenu,
"Kick",
TopMenuObject_Item,
AdminMenu_Kick,
player_commands,
"sm_kick",
ADMFLAG_KICK);
}
}
public OnLibraryRemoved(const String:name[])
{
if (strcmp(name, "adminmenu") == 0)
{
hTopMenu = INVALID_HANDLE;
}
}
public Action:Command_ReloadAdmins(client, args)
@ -365,51 +412,6 @@ public Action:Timer_ChangeMap(Handle:timer, Handle:dp)
return Plugin_Stop;
}
public Action:Command_Kick(client, args)
{
if (args < 1)
{
ReplyToCommand(client, "[SM] Usage: sm_kick <#userid|name> [reason]");
return Plugin_Handled;
}
decl String:Arguments[256];
GetCmdArgString(Arguments, sizeof(Arguments));
decl String:arg[65];
new len = BreakString(Arguments, arg, sizeof(arg));
new target = FindTarget(client, arg);
if (target == -1)
{
return Plugin_Handled;
}
GetClientName(target, arg, sizeof(arg));
if (len == -1)
{
/* Safely null terminate */
len = 0;
Arguments[0] = '\0';
}
ShowActivity(client, "%t", "Kicked player", arg);
LogAction(client, target, "\"%L\" kicked \"%L\" (reason \"%s\")", client, target, Arguments[len]);
if (Arguments[0] == '\0')
{
KickClient(target, "%t", "Kicked by admin");
}
else
{
KickClient(target, "%s", Arguments[len]);
}
return Plugin_Handled;
}
public Action:Command_CancelVote(client, args)
{
if (!IsVoteInProgress())
@ -424,3 +426,4 @@ public Action:Command_CancelVote(client, args)
return Plugin_Handled;
}

View File

@ -0,0 +1,124 @@
PerformKick(client, target, const String:reason[])
{
decl String:name[MAX_NAME_LENGTH];
GetClientName(target, name, sizeof(name));
ShowActivity(client, "%t", "Kicked player", name);
LogAction(client, target, "\"%L\" kicked \"%L\" (reason \"%s\")", client, target, reason);
if (reason[0] == '\0')
{
KickClient(target, "%t", "Kicked by admin");
}
else
{
KickClient(target, "%s", reason);
}
}
DisplayKickMenu(client)
{
new Handle:menu = CreateMenu(MenuHandler_Kick);
decl String:title[100];
Format(title, sizeof(title), "%T:", "Kick player", client);
SetMenuTitle(menu, title);
SetMenuExitBackButton(menu, true);
AddTargetsToMenu(menu, client, false);
DisplayMenu(menu, client, MENU_TIME_FOREVER);
}
public AdminMenu_Kick(Handle:topmenu,
TopMenuAction:action,
TopMenuObject:object_id,
param,
String:buffer[],
maxlength)
{
if (action == TopMenuAction_DrawOption)
{
Format(buffer, maxlength, "%T", "Kick player", param);
}
else if (action == TopMenuAction_SelectOption)
{
DisplayKickMenu(param);
}
}
public MenuHandler_Kick(Handle:menu, MenuAction:action, param1, param2)
{
if (action == MenuAction_End)
{
CloseHandle(menu);
}
else if (action == MenuAction_Cancel)
{
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
{
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
}
}
else if (action == MenuAction_Select)
{
decl String:info[32];
new userid, target;
GetMenuItem(menu, param2, info, sizeof(info));
userid = StringToInt(info);
if ((target = GetClientOfUserId(userid)) == 0)
{
PrintToChat(param1, "[SM] %t", "Player no longer available");
}
else if (!CanUserTarget(param1, target))
{
PrintToChat(param1, "[SM] %t", "Unable to target");
}
else
{
PerformKick(param1, target, "");
}
/* Re-draw the menu if they're still valid */
if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
{
DisplayKickMenu(param1);
}
}
}
public Action:Command_Kick(client, args)
{
if (args < 1)
{
ReplyToCommand(client, "[SM] Usage: sm_kick <#userid|name> [reason]");
return Plugin_Handled;
}
decl String:Arguments[256];
GetCmdArgString(Arguments, sizeof(Arguments));
decl String:arg[65];
new len = BreakString(Arguments, arg, sizeof(arg));
new target = FindTarget(client, arg);
if (target == -1)
{
return Plugin_Handled;
}
if (len == -1)
{
/* Safely null terminate */
len = 0;
Arguments[0] = '\0';
}
PerformKick(client, target, Arguments[len]);
return Plugin_Handled;
}

View File

@ -0,0 +1,110 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This file is part of the SourceMod/SourcePawn SDK.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#if defined _adminmenu_included
#endinput
#endif
#define _adminmenu_included
/* Decide whether topmenus should be required */
#if !defined REQUIRE_PLUGIN
#if defined REQUIRE_EXTENSIONS
#define TEMP_REQUIRE_EXTENSIONS
#undef REQUIRE_EXTENSIONS
#endif
#include <topmenus>
/* Restore old REQUIRE_EXTENSIONS value if necessary */
#if defined TEMP_REQUIRE_EXTENSIONS
#define REQUIRE_EXTENSIONS
#undef TEMP_REQUIRE_EXTENSIONS
#endif
/** Category for player commands. */
#define ADMINMENU_PLAYERCOMMANDS "PlayerCommands"
/**
* Called when the admin menu is created and 3rd party plugins can grab
* the Handle or add categories.
*
* @param topmenu Handle to the admin menu's TopMenu.
* @noreturn
*/
forward OnAdminMenuCreated(Handle:topmenu);
/**
* Called when the admin menu is ready to have items added.
*
* @param topmenu Handle to the admin menu's TopMenu.
* @noreturn
*/
forward OnAdminMenuReady(Handle:topmenu);
/**
* Retrieves the Handle to the admin top menu.
*
* @return Handle to the admin menu's TopMenu,
* or INVALID_HANDLE if not created yet.
*/
native Handle:GetAdminTopMenu();
/**
* Adds targets to an admin menu.
*
* Each client is displayed as: name (userid)
* Each item contains the userid as a string for its info.
*
* @param menu Menu Handle.
* @param source_client Source client, or 0 to ignore immunity.
* @param in_game_only True to only select in-game players.
* @return Number of clients added.
*/
native AddTargetsToMenu(Handle:menu, source_client, bool:in_game_only=true);
/* DO NOT EDIT BELOW THIS LINE */
public SharedPlugin:__pl_adminmenu =
{
name = "adminmenu",
file = "adminmenu.smx",
#if defined REQUIRE_PLUGIN
required = 1,
#else
required = 0,
#endif
};
public __pl_adminmenu_SetNTVOptional()
{
MarkNativeAsOptional("GetAdminTopMenu");
}

View File

@ -29,7 +29,7 @@ namespace builder
*/
public override string [] GetFolders()
{
string [] folders = new string[16];
string [] folders = new string[17];
folders[0] = "addons/sourcemod/bin";
folders[1] = "addons/sourcemod/plugins/disabled";
@ -47,6 +47,7 @@ namespace builder
folders[13] = "addons/sourcemod/configs/sql-init-scripts/mysql";
folders[14] = "addons/sourcemod/configs/sql-init-scripts/sqlite";
folders[15] = "addons/sourcemod/extensions/games";
folders[16] = "addons/sourcemod/scripting/basecommands";
return folders;
}
@ -93,6 +94,7 @@ namespace builder
builder.CopyFolder(this, "public/licenses", "addons/sourcemod", null);
builder.CopyFolder(this, "plugins/admin-flatfile", "addons/sourcemod/scripting/admin-flatfile", null);
builder.CopyFolder(this, "plugins/testsuite", "addons/sourcemod/scripting/testsuite", null);
builder.CopyFolder(this, "plugins/basecommands", "addons/sourcemod/scripting/basecommands", null);
}
/**
@ -100,7 +102,7 @@ namespace builder
*/
public override Library [] GetLibraries()
{
Library [] libs = new Library[9];
Library [] libs = new Library[10];
for (int i=0; i<libs.Length; i++)
{
@ -152,6 +154,11 @@ namespace builder
libs[8].Name = "game.cstrike.ext";
libs[8].ProjectFile = "cstrike";
libs[9].Destination = "addons/sourcemod/extenions";
libs[9].LocalPath = "extensions/topmenus";
libs[9].Name = "topmenus.ext";
libs[9].ProjectFile = "topmenus";
return libs;
}

View File

@ -21,6 +21,16 @@
"en" "More than one client matches the pattern \"{1}\""
}
"Player no longer available"
{
"en" "The player you selected is no longer available."
}
"Kick player"
{
"en" "Kick player"
}
"Kicked player"
{
"#format" "{1:s}"
@ -236,5 +246,15 @@
{
"en" "You have specified an invalid Steam ID (must start with 'STEAM_0:')."
}
"Admin Menu"
{
"en" "Admin Menu"
}
"Player Commands"
{
"en" "Player Commands"
}
}