initial import of UNTESTED, UNFINISHED topmenus extension
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401494
This commit is contained in:
parent
6867f28071
commit
924cfb4f9f
87
extensions/topmenus/Makefile
Normal file
87
extensions/topmenus/Makefile
Normal file
@ -0,0 +1,87 @@
|
||||
#(C)2004-2006 SourceMM Development Team
|
||||
# Makefile written by David "BAILOPAN" Anderson
|
||||
|
||||
SMSDK = ../..
|
||||
SRCDS = ~/srcds
|
||||
SOURCEMM = ../../../../sourcemm
|
||||
|
||||
#####################################
|
||||
### EDIT BELOW FOR OTHER PROJECTS ###
|
||||
#####################################
|
||||
|
||||
PROJECT = sample
|
||||
|
||||
#Uncomment for SourceMM-enabled extensions
|
||||
#LINK_HL2 = $(HL2LIB)/tier1_i486.a vstdlib_i486.so tier0_i486.so
|
||||
|
||||
OBJECTS = sdk/smsdk_ext.cpp extension.cpp
|
||||
|
||||
##############################################
|
||||
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
|
||||
##############################################
|
||||
|
||||
C_OPT_FLAGS = -O3 -funroll-loops -s -pipe -fno-strict-aliasing
|
||||
C_DEBUG_FLAGS = -g -ggdb3
|
||||
CPP_GCC4_FLAGS = -fvisibility=hidden -fvisibility-inlines-hidden
|
||||
CPP = gcc-4.1
|
||||
|
||||
HL2PUB = $(HL2SDK)/public
|
||||
HL2LIB = $(HL2SDK)/linux_sdk
|
||||
HL2SDK = $(SOURCEMM)/hl2sdk
|
||||
SMM_TRUNK = $(SOURCEMM)/trunk
|
||||
|
||||
LINK = $(LINK_HL2) -static-libgcc
|
||||
|
||||
INCLUDE = -I. -I.. -Isdk -I$(HL2PUB) -I$(HL2PUB)/dlls -I$(HL2PUB)/engine -I$(HL2PUB)/tier0 -I$(HL2PUB)/tier1 \
|
||||
-I$(HL2PUB)/vstdlib -I$(HL2SDK)/tier1 -I$(SMM_TRUNK) -I$(SMM_TRUNK)/sourcehook -I$(SMM_TRUNK)/sourcemm \
|
||||
-I$(SMSDK)/public -I$(SMSDK)/public/sourcepawn -I$(SMSDK)/public/extensions \
|
||||
|
||||
CFLAGS = -D_LINUX -DNDEBUG -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp -D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp -Wall -Werror -fPIC -msse -DSOURCEMOD_BUILD -DHAVE_STDINT_H
|
||||
CPPFLAGS = -Wno-non-virtual-dtor -fno-exceptions -fno-rtti
|
||||
|
||||
################################################
|
||||
### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ###
|
||||
################################################
|
||||
|
||||
ifeq "$(DEBUG)" "true"
|
||||
BIN_DIR = Debug
|
||||
CFLAGS += $(C_DEBUG_FLAGS)
|
||||
else
|
||||
BIN_DIR = Release
|
||||
CFLAGS += $(C_OPT_FLAGS)
|
||||
endif
|
||||
|
||||
|
||||
GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1)
|
||||
ifeq "$(GCC_VERSION)" "4"
|
||||
CPPFLAGS += $(CPP_GCC4_FLAGS)
|
||||
endif
|
||||
|
||||
BINARY = $(PROJECT).ext.so
|
||||
|
||||
OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
|
||||
|
||||
$(BIN_DIR)/%.o: %.cpp
|
||||
$(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
|
||||
|
||||
all:
|
||||
mkdir -p $(BIN_DIR)/sdk
|
||||
ln -sf $(SRCDS)/bin/vstdlib_i486.so vstdlib_i486.so
|
||||
ln -sf $(SRCDS)/bin/tier0_i486.so tier0_i486.so
|
||||
$(MAKE) extension
|
||||
|
||||
extension: $(OBJ_LINUX)
|
||||
$(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) $(OBJ_LINUX) $(LINK) -shared -ldl -lm -o$(BIN_DIR)/$(BINARY)
|
||||
|
||||
debug:
|
||||
$(MAKE) all DEBUG=true
|
||||
|
||||
default: all
|
||||
|
||||
clean:
|
||||
rm -rf Release/*.o
|
||||
rm -rf Release/sdk/*.o
|
||||
rm -rf Release/$(BINARY)
|
||||
rm -rf Debug/*.o
|
||||
rm -rf Debug/sdk/*.o
|
||||
rm -rf Debug/$(BINARY)
|
942
extensions/topmenus/TopMenu.cpp
Normal file
942
extensions/topmenus/TopMenu.cpp
Normal file
@ -0,0 +1,942 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Sample Extension
|
||||
* Copyright (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: extension.cpp 1336 2007-08-15 06:19:30Z damagedsoul $
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "TopMenu.h"
|
||||
|
||||
struct obj_by_name_t
|
||||
{
|
||||
unsigned int obj_index;
|
||||
char name[64];
|
||||
};
|
||||
|
||||
int _SortObjectNamesDescending(const void *ptr1, const void *ptr2);
|
||||
unsigned int strncopy(char *dest, const char *src, size_t count);
|
||||
size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...);
|
||||
|
||||
TopMenu::TopMenu(ITopMenuObjectCallbacks *callbacks)
|
||||
{
|
||||
m_clients = NULL;
|
||||
m_SerialNo = 1;
|
||||
m_pTitle = callbacks;
|
||||
m_max_clients = 0;
|
||||
|
||||
if (playerhelpers->IsServerActivated())
|
||||
{
|
||||
CreatePlayers(playerhelpers->GetMaxClients());
|
||||
}
|
||||
}
|
||||
|
||||
TopMenu::~TopMenu()
|
||||
{
|
||||
/* Delete all categories */
|
||||
for (size_t i = 0; i < m_Categories.size(); i++)
|
||||
{
|
||||
delete m_Categories[i];
|
||||
}
|
||||
|
||||
/* Delete all items */
|
||||
for (size_t i = 0; i < m_Objects.size(); i++)
|
||||
{
|
||||
delete m_Objects[i];
|
||||
}
|
||||
|
||||
/* Delete all cached config entries */
|
||||
for (size_t i = 0; i < m_Config.cats.size(); i++)
|
||||
{
|
||||
delete m_Config.cats[i];
|
||||
}
|
||||
|
||||
/* Sweep players */
|
||||
for (int i = 0; i <= m_max_clients; i++)
|
||||
{
|
||||
TearDownClient(&m_clients[i]);
|
||||
}
|
||||
delete [] m_clients;
|
||||
}
|
||||
|
||||
void TopMenu::OnClientConnected(int client)
|
||||
{
|
||||
if (m_clients == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
topmenu_player_t *player = &m_clients[client];
|
||||
TearDownClient(player);
|
||||
}
|
||||
|
||||
void TopMenu::OnClientDisconnected(int client)
|
||||
{
|
||||
if (m_clients == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
topmenu_player_t *player = &m_clients[client];
|
||||
TearDownClient(player);
|
||||
}
|
||||
|
||||
void TopMenu::OnServerActivated(int max_clients)
|
||||
{
|
||||
if (m_clients == NULL)
|
||||
{
|
||||
CreatePlayers(max_clients);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int TopMenu::AddToMenu(const char *name,
|
||||
TopMenuObjectType type,
|
||||
ITopMenuObjectCallbacks *callbacks,
|
||||
IdentityToken_t *owner,
|
||||
const char *cmdname,
|
||||
FlagBits flags,
|
||||
unsigned int parent)
|
||||
{
|
||||
/* Sanity checks */
|
||||
if (type == TopMenuObject_Category && parent != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (type == TopMenuObject_Item && parent == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (m_ObjLookup.retrieve(name) != NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If we're adding an item, make sure the parent is valid,
|
||||
* and that the parent is a category.
|
||||
*/
|
||||
topmenu_object_t *parent_obj = NULL;
|
||||
topmenu_category_t *parent_cat = NULL;
|
||||
if (type == TopMenuObject_Item)
|
||||
{
|
||||
/* Check parent index. Note it will be >= 1 here. */
|
||||
if (parent > m_Objects.size() || m_Objects[parent - 1]->is_free)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
parent_obj = m_Objects[parent - 1];
|
||||
|
||||
/* Find an equivalent pointer in the category array. */
|
||||
for (size_t i = 0; i < m_Categories.size(); i++)
|
||||
{
|
||||
if (m_Categories[i]->obj == parent_obj)
|
||||
{
|
||||
parent_cat = m_Categories[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If none was found, leave. */
|
||||
if (parent_cat == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Re-use an old object pointer if we can. */
|
||||
topmenu_object_t *obj = NULL;
|
||||
for (size_t i = 0; i < m_Objects.size(); i++)
|
||||
{
|
||||
if (m_Objects[i]->is_free == true)
|
||||
{
|
||||
obj = m_Objects[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise, allocate a new one. */
|
||||
if (obj == NULL)
|
||||
{
|
||||
obj = new topmenu_object_t;
|
||||
obj->object_id = ((unsigned int)m_Objects.size()) + 1;
|
||||
m_Objects.push_back(obj);
|
||||
}
|
||||
|
||||
/* Initialize the object's properties. */
|
||||
obj->callbacks = callbacks;
|
||||
obj->flags = flags;
|
||||
obj->owner = owner;
|
||||
obj->type = type;
|
||||
obj->is_free = false;
|
||||
obj->parent = parent_obj;
|
||||
strncopy(obj->name, name, sizeof(obj->name));
|
||||
strncopy(obj->cmdname, cmdname ? cmdname : "", sizeof(obj->cmdname));
|
||||
|
||||
if (obj->type == TopMenuObject_Category)
|
||||
{
|
||||
/* Create a new category entry */
|
||||
topmenu_category_t *cat = new topmenu_category_t;
|
||||
cat->obj = obj;
|
||||
cat->reorder = false;
|
||||
cat->serial = 1;
|
||||
|
||||
/* Add it, then update our serial change number. */
|
||||
m_Categories.push_back(cat);
|
||||
m_SerialNo++;
|
||||
|
||||
/* Updating sorting info */
|
||||
m_bCatsNeedResort = true;
|
||||
}
|
||||
else if (obj->type == TopMenuObject_Item)
|
||||
{
|
||||
/* Update the category, mark it as needing changes */
|
||||
parent_cat->obj_list.push_back(obj);
|
||||
parent_cat->reorder = true;
|
||||
parent_cat->serial++;
|
||||
}
|
||||
|
||||
m_ObjLookup.insert(name, obj);
|
||||
|
||||
return obj->object_id;
|
||||
}
|
||||
|
||||
void TopMenu::RemoveFromMenu(unsigned int object_id)
|
||||
{
|
||||
if (object_id == 0
|
||||
|| object_id > m_Objects.size()
|
||||
|| m_Objects[object_id - 1]->is_free)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
topmenu_object_t *obj = m_Objects[object_id - 1];
|
||||
|
||||
m_ObjLookup.remove(obj->name);
|
||||
|
||||
if (obj->type == TopMenuObject_Category)
|
||||
{
|
||||
/* Find it in the category list */
|
||||
for (size_t i = 0; i < m_Categories.size(); i++)
|
||||
{
|
||||
if (m_Categories[i]->obj == obj)
|
||||
{
|
||||
/* Erase from here */
|
||||
delete m_Categories[i];
|
||||
m_Categories.erase(m_Categories.iterAt(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Update us as changed */
|
||||
m_SerialNo++;
|
||||
m_bCatsNeedResort = true;
|
||||
}
|
||||
else if (obj->type == TopMenuObject_Item)
|
||||
{
|
||||
/* Find the category this item is in. */
|
||||
topmenu_category_t *parent_cat = NULL;
|
||||
for (size_t i = 0; i < m_Categories.size(); i++)
|
||||
{
|
||||
if (m_Categories[i]->obj == obj->parent)
|
||||
{
|
||||
parent_cat = m_Categories[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Erase it from the category's lists. */
|
||||
if (parent_cat)
|
||||
{
|
||||
for (size_t i = 0; i < parent_cat->obj_list.size(); i++)
|
||||
{
|
||||
if (parent_cat->obj_list[i] == obj)
|
||||
{
|
||||
parent_cat->obj_list.erase(parent_cat->obj_list.iterAt(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
parent_cat->reorder = true;
|
||||
parent_cat->serial++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally, mark the object as free. */
|
||||
obj->is_free = true;
|
||||
}
|
||||
|
||||
bool TopMenu::DisplayMenu(int client, unsigned int hold_time, TopMenuPosition position)
|
||||
{
|
||||
if (m_clients == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client);
|
||||
if (!pPlayer->IsInGame())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
UpdateClientRoot(client, pPlayer);
|
||||
|
||||
topmenu_player_t *pClient = &m_clients[client];
|
||||
if (pClient->root == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool return_value = false;
|
||||
|
||||
if (position == TopMenuPosition_LastCategory &&
|
||||
pClient->last_category < m_Categories.size())
|
||||
{
|
||||
return_value = DisplayCategory(client, pClient->last_category, hold_time, true);
|
||||
}
|
||||
else if (position == TopMenuPosition_LastRoot)
|
||||
{
|
||||
pClient->root->DisplayAtItem(client, hold_time, pClient->last_root_pos);
|
||||
}
|
||||
else if (position == TopMenuPosition_Start)
|
||||
{
|
||||
pClient->last_position = 0;
|
||||
pClient->last_category = 0;
|
||||
return_value = pClient->root->Display(client, hold_time);
|
||||
}
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
bool TopMenu::DisplayCategory(int client, unsigned int category, unsigned int hold_time, bool last_position)
|
||||
{
|
||||
UpdateClientCategory(client, category);
|
||||
|
||||
topmenu_player_t *pClient = &m_clients[client];
|
||||
if (category >= pClient->cat_count
|
||||
|| pClient->cats[category].menu == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool return_value = false;
|
||||
|
||||
topmenu_player_category_t *player_cat = &(pClient->cats[category]);
|
||||
|
||||
pClient->last_category = category;
|
||||
if (last_position)
|
||||
{
|
||||
return_value = player_cat->menu->DisplayAtItem(client, hold_time, pClient->last_position);
|
||||
}
|
||||
else
|
||||
{
|
||||
return_value = player_cat->menu->Display(client, hold_time);
|
||||
}
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
void TopMenu::OnMenuSelect2(IBaseMenu *menu, int client, unsigned int item, unsigned int item_on_page)
|
||||
{
|
||||
const char *item_name = menu->GetItemInfo(item, NULL);
|
||||
if (!item_name)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
topmenu_object_t *obj;
|
||||
topmenu_player_t *pClient = &m_clients[client];
|
||||
topmenu_object_t **pObject = m_ObjLookup.retrieve(item_name);
|
||||
if (pObject == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
obj = *pObject;
|
||||
|
||||
/* We now have the object... what do we do with it? */
|
||||
if (obj->type == TopMenuObject_Category)
|
||||
{
|
||||
/* If it's a category, the user wants to view it.. */
|
||||
for (size_t i = 0; i < m_Categories.size(); i++)
|
||||
{
|
||||
if (m_Categories[i]->obj == obj)
|
||||
{
|
||||
pClient->last_root_pos = item_on_page;
|
||||
DisplayCategory(client, (unsigned int)i, MENU_TIME_FOREVER, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pClient->last_position = item_on_page;
|
||||
|
||||
/* Re-check access in case this user had their credentials revoked */
|
||||
if (obj->cmdname[0] != '\0' && !adminsys->CheckAccess(client, obj->cmdname, obj->flags, false))
|
||||
{
|
||||
DisplayMenu(client, 0, TopMenuPosition_LastCategory);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Pass the information on to the callback */
|
||||
obj->callbacks->OnTopMenuSelectOption(client, obj->object_id);
|
||||
}
|
||||
}
|
||||
|
||||
void TopMenu::OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style)
|
||||
{
|
||||
const char *item_name = menu->GetItemInfo(item, NULL);
|
||||
if (!item_name)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
topmenu_object_t *obj;
|
||||
topmenu_object_t **pObject = m_ObjLookup.retrieve(item_name);
|
||||
if (pObject == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
obj = *pObject;
|
||||
|
||||
if (obj->cmdname[0] == '\0')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!adminsys->CheckAccess(client, obj->cmdname, obj->flags, false))
|
||||
{
|
||||
style = ITEMDRAW_IGNORE;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int TopMenu::OnMenuDisplayItem(IBaseMenu *menu,
|
||||
int client,
|
||||
IMenuPanel *panel,
|
||||
unsigned int item,
|
||||
const ItemDrawInfo &dr)
|
||||
{
|
||||
const char *item_name = menu->GetItemInfo(item, NULL);
|
||||
if (!item_name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
topmenu_object_t *obj;
|
||||
topmenu_object_t **pObject = m_ObjLookup.retrieve(item_name);
|
||||
if (pObject == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
obj = *pObject;
|
||||
|
||||
/* Ask the object to render the text for this client */
|
||||
char renderbuf[64];
|
||||
obj->callbacks->OnTopMenuDrawOption(client, obj->object_id, renderbuf, sizeof(renderbuf));
|
||||
|
||||
/* Build the new draw info */
|
||||
ItemDrawInfo new_dr = dr;
|
||||
new_dr.display = renderbuf;
|
||||
|
||||
/* Man I love the menu API. Ask the panel to draw the item and give the position
|
||||
* back to Core's renderer. This way we don't have to worry about keeping the
|
||||
* render buffer static!
|
||||
*/
|
||||
return panel->DrawItem(new_dr);
|
||||
}
|
||||
|
||||
void TopMenu::OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason)
|
||||
{
|
||||
if (reason == MenuCancel_ExitBack)
|
||||
{
|
||||
/* If the client chose exit back, they were on a category menu, and we can
|
||||
* now display the root menu from the last known position.
|
||||
*/
|
||||
DisplayMenu(client, 0, TopMenuPosition_LastRoot);
|
||||
}
|
||||
}
|
||||
|
||||
void TopMenu::UpdateClientRoot(int client, IGamePlayer *pGamePlayer)
|
||||
{
|
||||
topmenu_player_t *pClient = &m_clients[client];
|
||||
IGamePlayer *pPlayer = pGamePlayer ? pGamePlayer : playerhelpers->GetGamePlayer(client);
|
||||
|
||||
/* Determine if an update is necessary */
|
||||
bool is_update_needed = false;
|
||||
if (pClient->menu_serial != m_SerialNo)
|
||||
{
|
||||
is_update_needed = true;
|
||||
}
|
||||
else if (pPlayer->GetUserId() != pClient->user_id)
|
||||
{
|
||||
is_update_needed = true;
|
||||
}
|
||||
|
||||
/* If no update is needed at the root level, just leave now */
|
||||
if (!is_update_needed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* First we need to flush the cache... */
|
||||
TearDownClient(pClient);
|
||||
|
||||
/* Now, rebuild the category list, but don't create menus */
|
||||
if (m_Categories.size() == 0)
|
||||
{
|
||||
pClient->cat_count = 0;
|
||||
pClient->cats = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pClient->cat_count = (unsigned int)m_Categories.size();
|
||||
pClient->cats = new topmenu_player_category_t[pClient->cat_count];
|
||||
memset(pClient->cats, 0, sizeof(topmenu_player_category_t) * pClient->cat_count);
|
||||
}
|
||||
|
||||
/* Re-sort the root categories if needed */
|
||||
SortCategoriesIfNeeded();
|
||||
|
||||
/* Build the root menu */
|
||||
IBaseMenu *root_menu = menus->GetDefaultStyle()->CreateMenu(this, myself->GetIdentity());
|
||||
|
||||
/* Add the sorted items */
|
||||
for (size_t i = 0; i < m_SortedCats.size(); i++)
|
||||
{
|
||||
root_menu->AppendItem(m_Categories[m_SortedCats[i]]->obj->name, ItemDrawInfo(""));
|
||||
}
|
||||
|
||||
/* Now we need to handle un-sorted items. This is slightly trickier, as we need to
|
||||
* pre-render each category name, and cache those names. Phew!
|
||||
*/
|
||||
if (m_UnsortedCats.size())
|
||||
{
|
||||
obj_by_name_t *item_list = new obj_by_name_t[m_UnsortedCats.size()];
|
||||
for (size_t i = 0; i < m_UnsortedCats.size(); i++)
|
||||
{
|
||||
obj_by_name_t *temp_obj = &item_list[i];
|
||||
topmenu_object_t *obj = m_Categories[m_UnsortedCats[i]]->obj;
|
||||
obj->callbacks->OnTopMenuDrawOption(client,
|
||||
obj->object_id,
|
||||
temp_obj->name,
|
||||
sizeof(temp_obj->name));
|
||||
temp_obj->obj_index = m_UnsortedCats[i];
|
||||
}
|
||||
|
||||
/* Sort our temp list */
|
||||
qsort(item_list, m_UnsortedCats.size(), sizeof(obj_by_name_t), _SortObjectNamesDescending);
|
||||
|
||||
/* Add the new sorted categories */
|
||||
for (size_t i = 0; i < m_SortedCats.size(); i++)
|
||||
{
|
||||
root_menu->AppendItem(m_Categories[item_list[i].obj_index]->obj->name, ItemDrawInfo(""));
|
||||
}
|
||||
|
||||
delete [] item_list;
|
||||
}
|
||||
|
||||
/* Set the menu's title */
|
||||
char renderbuf[128];
|
||||
m_pTitle->OnTopMenuDrawTitle(client, 0, renderbuf, sizeof(renderbuf));
|
||||
root_menu->SetDefaultTitle(renderbuf);
|
||||
|
||||
/* The client is now fully updated */
|
||||
pClient->root = root_menu;
|
||||
pClient->user_id = pPlayer->GetUserId();
|
||||
pClient->menu_serial = m_SerialNo;
|
||||
pClient->last_position = 0;
|
||||
pClient->last_category = 0;
|
||||
pClient->last_root_pos = 0;
|
||||
}
|
||||
|
||||
void TopMenu::UpdateClientCategory(int client, unsigned int category)
|
||||
{
|
||||
/* Update the client's root menu just in case it needs it. This
|
||||
* will validate that we have both a valid client and a valid
|
||||
* category structure for that client.
|
||||
*/
|
||||
UpdateClientRoot(client);
|
||||
|
||||
/* Now it's guaranteed that our category tables will be usable */
|
||||
topmenu_player_t *pClient = &m_clients[client];
|
||||
topmenu_category_t *cat = m_Categories[category];
|
||||
topmenu_player_category_t *player_cat = &(pClient->cats[category]);
|
||||
|
||||
/* Does the category actually need updating? */
|
||||
if (player_cat->serial == cat->serial)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Destroy any existing menu */
|
||||
if (player_cat->menu)
|
||||
{
|
||||
player_cat->menu->Destroy();
|
||||
player_cat->menu = NULL;
|
||||
}
|
||||
|
||||
if (pClient->last_category == category)
|
||||
{
|
||||
pClient->last_position = 0;
|
||||
}
|
||||
|
||||
IBaseMenu *cat_menu = menus->GetDefaultStyle()->CreateMenu(this, myself->GetIdentity());
|
||||
|
||||
/* Categories get an "exit back" button */
|
||||
cat_menu->SetMenuOptionFlags(cat_menu->GetMenuOptionFlags() | MENUFLAG_BUTTON_EXITBACK);
|
||||
|
||||
/* Re-sort the category if needed */
|
||||
SortCategoryIfNeeded(category);
|
||||
|
||||
/* Build the menu with the sorted items first */
|
||||
for (size_t i = 0; i < cat->sorted.size(); i++)
|
||||
{
|
||||
cat_menu->AppendItem(cat->sorted[i]->name, ItemDrawInfo(""));
|
||||
}
|
||||
|
||||
/* Now handle unsorted items */
|
||||
if (cat->unsorted.size())
|
||||
{
|
||||
/* Build a list of the item names */
|
||||
obj_by_name_t *item_list = new obj_by_name_t[cat->unsorted.size()];
|
||||
for (size_t i = 0; i < cat->unsorted.size(); i++)
|
||||
{
|
||||
obj_by_name_t *item = &item_list[i];
|
||||
topmenu_object_t *obj = cat->unsorted[i];
|
||||
obj->callbacks->OnTopMenuDrawOption(client,
|
||||
obj->object_id,
|
||||
item->name,
|
||||
sizeof(item->name));
|
||||
item->obj_index = (unsigned int)i;
|
||||
}
|
||||
|
||||
/* Sort the names */
|
||||
qsort(item_list, cat->unsorted.size(), sizeof(obj_by_name_t), _SortObjectNamesDescending);
|
||||
|
||||
/* Add to the menu */
|
||||
for (size_t i = 0; i < cat->unsorted.size(); i++)
|
||||
{
|
||||
cat_menu->AppendItem(cat->unsorted[item_list[i].obj_index]->name, ItemDrawInfo(""));
|
||||
}
|
||||
|
||||
delete [] item_list;
|
||||
}
|
||||
|
||||
/* Set the menu's title */
|
||||
char renderbuf[128];
|
||||
cat->obj->callbacks->OnTopMenuDrawTitle(client, cat->obj->object_id, renderbuf, sizeof(renderbuf));
|
||||
cat_menu->SetDefaultTitle(renderbuf);
|
||||
|
||||
/* We're done! */
|
||||
player_cat->menu = cat_menu;
|
||||
player_cat->serial = cat->serial;
|
||||
}
|
||||
|
||||
void TopMenu::SortCategoryIfNeeded(unsigned int category)
|
||||
{
|
||||
topmenu_category_t *cat = m_Categories[category];
|
||||
if (!cat->reorder)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cat->sorted.clear();
|
||||
cat->unsorted.clear();
|
||||
|
||||
if (cat->obj_list.size() == 0)
|
||||
{
|
||||
cat->reorder = false;
|
||||
return;
|
||||
}
|
||||
|
||||
CVector<unsigned int> to_sort;
|
||||
for (size_t i = 0; i < cat->obj_list.size(); i++)
|
||||
{
|
||||
to_sort.push_back(i);
|
||||
}
|
||||
|
||||
/* Find a matching category in the configs */
|
||||
config_category_t *config_cat = NULL;
|
||||
for (size_t i = 0; i < m_Config.cats.size(); i++)
|
||||
{
|
||||
if (strcmp(m_Config.strings.GetString(m_Config.cats[i]->name), cat->obj->name) == 0)
|
||||
{
|
||||
config_cat = m_Config.cats[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If there is a matching category, build a pre-sorted item list */
|
||||
if (config_cat != NULL)
|
||||
{
|
||||
/* Find matching objects in this category */
|
||||
for (size_t i = 0; i < config_cat->commands.size(); i++)
|
||||
{
|
||||
const char *config_name = m_Config.strings.GetString(config_cat->commands[i]);
|
||||
for (size_t j = 0; j < to_sort.size(); j++)
|
||||
{
|
||||
if (strcmp(config_name, cat->obj_list[to_sort[j]]->name) == 0)
|
||||
{
|
||||
/* Place in the final list, then remove from the temporary list */
|
||||
cat->sorted.push_back(cat->obj_list[to_sort[j]]);
|
||||
to_sort.erase(to_sort.iterAt(j));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Push any remaining items onto the unsorted list */
|
||||
for (size_t i = 0; i < to_sort.size(); i++)
|
||||
{
|
||||
cat->unsorted.push_back(cat->obj_list[to_sort[i]]);
|
||||
}
|
||||
|
||||
cat->reorder = false;
|
||||
}
|
||||
|
||||
void TopMenu::SortCategoriesIfNeeded()
|
||||
{
|
||||
if (!m_bCatsNeedResort)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Clear sort results */
|
||||
m_SortedCats.clear();
|
||||
m_UnsortedCats.clear();
|
||||
|
||||
if (m_Categories.size() == 0)
|
||||
{
|
||||
m_bCatsNeedResort = false;
|
||||
return;
|
||||
}
|
||||
|
||||
CVector<unsigned int> to_sort;
|
||||
for (unsigned int i = 0; i < (unsigned int)m_Categories.size(); i++)
|
||||
{
|
||||
to_sort.push_back(i);
|
||||
}
|
||||
|
||||
/* If we have any predefined categories, add them in as they appear. */
|
||||
for (size_t i= 0; i < m_Config.cats.size(); i++)
|
||||
{
|
||||
/* Find this category and map it in if we can */
|
||||
for (size_t j = 0; j < to_sort.size(); j++)
|
||||
{
|
||||
if (strcmp(m_Config.strings.GetString(m_Config.cats[i]->name),
|
||||
m_Categories[to_sort[j]]->obj->name) == 0)
|
||||
{
|
||||
/* Add to the real list and remove from the temporary */
|
||||
m_SortedCats.push_back(to_sort[j]);
|
||||
to_sort.erase(to_sort.iterAt(j));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Push any remaining items onto the unsorted list */
|
||||
for (size_t i = 0; i < to_sort.size(); i++)
|
||||
{
|
||||
m_UnsortedCats.push_back(to_sort[i]);
|
||||
}
|
||||
|
||||
m_bCatsNeedResort = false;
|
||||
}
|
||||
|
||||
void TopMenu::CreatePlayers(int max_clients)
|
||||
{
|
||||
m_max_clients = max_clients;
|
||||
m_clients = (topmenu_player_t *)malloc(sizeof(topmenu_player_t) * (max_clients + 1));
|
||||
memset(m_clients, 0, sizeof(topmenu_player_t) * (max_clients + 1));
|
||||
}
|
||||
|
||||
void TopMenu::TearDownClient(topmenu_player_t *player)
|
||||
{
|
||||
if (player->cats != NULL)
|
||||
{
|
||||
for (unsigned int i = 0; i < player->cat_count; i++)
|
||||
{
|
||||
topmenu_player_category_t *player_cat = &(player->cats[i]);
|
||||
if (player_cat->menu != NULL)
|
||||
{
|
||||
player_cat->menu->Destroy();
|
||||
}
|
||||
}
|
||||
delete [] player->cats;
|
||||
}
|
||||
|
||||
if (player->root != NULL)
|
||||
{
|
||||
player->root->Destroy();
|
||||
}
|
||||
|
||||
memset(player, 0, sizeof(topmenu_player_t));
|
||||
}
|
||||
|
||||
bool TopMenu::LoadConfiguration(const char *file, char *error, size_t maxlength)
|
||||
{
|
||||
SMCParseError err;
|
||||
unsigned int line = 0, col = 0;
|
||||
|
||||
if ((err = textparsers->ParseFile_SMC(file, this, &line, &col))
|
||||
!= SMCParse_Okay)
|
||||
{
|
||||
const char *err_string = textparsers->GetSMCErrorString(err);
|
||||
if (!err_string)
|
||||
{
|
||||
err_string = "Unknown";
|
||||
}
|
||||
|
||||
UTIL_Format(error, maxlength, "%s", err_string);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define PARSE_STATE_NONE 0
|
||||
#define PARSE_STATE_CATEGORY 1
|
||||
unsigned int ignore_parse_level = 0;
|
||||
unsigned int current_parse_state = 0;
|
||||
config_category_t *cur_cat = NULL;
|
||||
|
||||
void TopMenu::ReadSMC_ParseStart()
|
||||
{
|
||||
current_parse_state = PARSE_STATE_NONE;
|
||||
ignore_parse_level = 0;
|
||||
cur_cat = NULL;
|
||||
|
||||
/* Reset the old config */
|
||||
m_Config.strings.Reset();
|
||||
for (size_t i = 0; i < m_Config.cats.size(); i++)
|
||||
{
|
||||
delete m_Config.cats[i];
|
||||
}
|
||||
m_Config.cats.clear();
|
||||
}
|
||||
|
||||
SMCParseResult TopMenu::ReadSMC_NewSection(const char *name, bool opt_quotes)
|
||||
{
|
||||
if (ignore_parse_level)
|
||||
{
|
||||
ignore_parse_level++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (current_parse_state == PARSE_STATE_NONE)
|
||||
{
|
||||
cur_cat = new config_category_t;
|
||||
cur_cat->name = m_Config.strings.AddString(name);
|
||||
m_Config.cats.push_back(cur_cat);
|
||||
current_parse_state = PARSE_STATE_CATEGORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
ignore_parse_level = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
SMCParseResult TopMenu::ReadSMC_KeyValue(const char *key, const char *value, bool key_quotes, bool value_quotes)
|
||||
{
|
||||
if (ignore_parse_level > 0
|
||||
|| current_parse_state != PARSE_STATE_CATEGORY
|
||||
|| cur_cat == NULL)
|
||||
{
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
if (strcmp(key, "item") == 0)
|
||||
{
|
||||
cur_cat->commands.push_back(m_Config.strings.AddString(value));
|
||||
}
|
||||
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
SMCParseResult TopMenu::ReadSMC_LeavingSection()
|
||||
{
|
||||
if (ignore_parse_level)
|
||||
{
|
||||
ignore_parse_level--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (current_parse_state == PARSE_STATE_CATEGORY)
|
||||
{
|
||||
cur_cat = NULL;
|
||||
current_parse_state = PARSE_STATE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
int _SortObjectNamesDescending(const void *ptr1, const void *ptr2)
|
||||
{
|
||||
obj_by_name_t *obj1 = (obj_by_name_t *)ptr1;
|
||||
obj_by_name_t *obj2 = (obj_by_name_t *)ptr2;
|
||||
return strcmp(obj1->name, obj2->name);
|
||||
}
|
||||
|
||||
unsigned int strncopy(char *dest, const char *src, size_t count)
|
||||
{
|
||||
if (!count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *start = dest;
|
||||
while ((*src) && (--count))
|
||||
{
|
||||
*dest++ = *src++;
|
||||
}
|
||||
*dest = '\0';
|
||||
|
||||
return (dest - start);
|
||||
}
|
||||
|
||||
size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
size_t len = vsnprintf(buffer, maxlength, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (len >= maxlength)
|
||||
{
|
||||
buffer[maxlength - 1] = '\0';
|
||||
return (maxlength - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return len;
|
||||
}
|
||||
}
|
167
extensions/topmenus/TopMenu.h
Normal file
167
extensions/topmenus/TopMenu.h
Normal file
@ -0,0 +1,167 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Sample Extension
|
||||
* Copyright (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: extension.cpp 1336 2007-08-15 06:19:30Z damagedsoul $
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SOURCEMOD_TOP_MENU_H_
|
||||
#define _INCLUDE_SOURCEMOD_TOP_MENU_H_
|
||||
|
||||
#include <sh_list.h>
|
||||
#include <sh_vector.h>
|
||||
#include <sm_trie_tpl.h>
|
||||
#include <ITopMenus.h>
|
||||
#include "smsdk_ext.h"
|
||||
#include "sm_memtable.h"
|
||||
|
||||
using namespace SourceHook;
|
||||
using namespace SourceMod;
|
||||
|
||||
struct config_category_t
|
||||
{
|
||||
int name;
|
||||
CVector<int> commands;
|
||||
};
|
||||
|
||||
struct config_root_t
|
||||
{
|
||||
config_root_t() : strings(1024)
|
||||
{
|
||||
}
|
||||
BaseStringTable strings;
|
||||
CVector<config_category_t *> cats;
|
||||
};
|
||||
|
||||
struct topmenu_object_t
|
||||
{
|
||||
char name[64]; /** Name */
|
||||
char cmdname[64]; /** Command name */
|
||||
FlagBits flags; /** Admin flags */
|
||||
ITopMenuObjectCallbacks *callbacks; /** Callbacks */
|
||||
IdentityToken_t *owner; /** Owner */
|
||||
unsigned int object_id; /** Object ID */
|
||||
topmenu_object_t *parent; /** Parent, if any */
|
||||
TopMenuObjectType type; /** Object Type */
|
||||
bool is_free; /** Free or not? */
|
||||
};
|
||||
|
||||
struct topmenu_category_t
|
||||
{
|
||||
CVector<topmenu_object_t *> obj_list; /** Full object list */
|
||||
CVector<topmenu_object_t *> sorted; /** Sorted items */
|
||||
CVector<topmenu_object_t *> unsorted; /** Unsorted items */
|
||||
topmenu_object_t *obj; /** Bound object */
|
||||
unsigned int serial; /** Serial number */
|
||||
bool reorder; /** Whether ordering needs updating */
|
||||
};
|
||||
|
||||
struct topmenu_player_category_t
|
||||
{
|
||||
IBaseMenu *menu; /** menu pointer */
|
||||
unsigned int serial; /** last known serial */
|
||||
};
|
||||
|
||||
struct topmenu_player_t
|
||||
{
|
||||
int user_id; /** userid on server */
|
||||
unsigned int menu_serial; /** menu serial no */
|
||||
IBaseMenu *root; /** root menu display */
|
||||
topmenu_player_category_t *cats; /** category display */
|
||||
unsigned int cat_count; /** number of categories */
|
||||
unsigned int last_category; /** last category they selected */
|
||||
unsigned int last_position; /** last position in that category */
|
||||
unsigned int last_root_pos; /** last page in the root menu */
|
||||
};
|
||||
|
||||
class TopMenu :
|
||||
public ITopMenu,
|
||||
public IMenuHandler,
|
||||
public ITextListener_SMC
|
||||
{
|
||||
friend class TopMenuManager;
|
||||
public:
|
||||
TopMenu(ITopMenuObjectCallbacks *callbacks);
|
||||
~TopMenu();
|
||||
public: //ITopMenu
|
||||
virtual unsigned int AddToMenu(const char *name,
|
||||
TopMenuObjectType type,
|
||||
ITopMenuObjectCallbacks *callbacks,
|
||||
IdentityToken_t *owner,
|
||||
const char *cmdname,
|
||||
FlagBits flags,
|
||||
unsigned int parent);
|
||||
virtual void RemoveFromMenu(unsigned int object_id);
|
||||
virtual bool DisplayMenu(int client,
|
||||
unsigned int hold_time,
|
||||
TopMenuPosition position);
|
||||
virtual bool LoadConfiguration(const char *file, char *error, size_t maxlength);
|
||||
public: //IMenuHandler
|
||||
virtual void OnMenuSelect2(IBaseMenu *menu, int client, unsigned int item, unsigned int item_on_page);
|
||||
virtual void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style);
|
||||
virtual unsigned int OnMenuDisplayItem(IBaseMenu *menu,
|
||||
int client,
|
||||
IMenuPanel *panel,
|
||||
unsigned int item,
|
||||
const ItemDrawInfo &dr);
|
||||
virtual void OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason);
|
||||
public: //ITextListener_SMC
|
||||
virtual void ReadSMC_ParseStart();
|
||||
SMCParseResult ReadSMC_NewSection(const char *name, bool opt_quotes);
|
||||
SMCParseResult ReadSMC_KeyValue(const char *key,
|
||||
const char *value,
|
||||
bool key_quotes,
|
||||
bool value_quotes);
|
||||
SMCParseResult ReadSMC_LeavingSection();
|
||||
private:
|
||||
void SortCategoriesIfNeeded();
|
||||
void SortCategoryIfNeeded(unsigned int category);
|
||||
private:
|
||||
bool DisplayCategory(int client, unsigned int category, unsigned int hold_time, bool last_position);
|
||||
void CreatePlayers(int max_clients);
|
||||
void UpdateClientRoot(int client, IGamePlayer *pGamePlayer=NULL);
|
||||
void UpdateClientCategory(int client, unsigned int category);
|
||||
void TearDownClient(topmenu_player_t *player);
|
||||
private:
|
||||
void OnClientConnected(int client);
|
||||
void OnClientDisconnected(int client);
|
||||
void OnServerActivated(int max_clients);
|
||||
private:
|
||||
config_root_t m_Config; /* Configuration from file */
|
||||
topmenu_player_t *m_clients; /* Client array */
|
||||
CVector<unsigned int> m_SortedCats; /* Sorted categories */
|
||||
CVector<unsigned int> m_UnsortedCats; /* Un-sorted categories */
|
||||
CVector<topmenu_category_t *> m_Categories; /* Category array */
|
||||
CVector<topmenu_object_t *> m_Objects; /* Object array */
|
||||
KTrie<topmenu_object_t *> m_ObjLookup; /* Object lookup trie */
|
||||
unsigned int m_SerialNo; /* Serial number for updating */
|
||||
ITopMenuObjectCallbacks *m_pTitle; /* Title callbacks */
|
||||
int m_max_clients; /* Maximum number of clients */
|
||||
bool m_bCatsNeedResort; /* True if categories need a resort */
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_SOURCEMOD_TOP_MENU_H_
|
101
extensions/topmenus/TopMenuManager.cpp
Normal file
101
extensions/topmenus/TopMenuManager.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Sample Extension
|
||||
* Copyright (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: extension.cpp 1336 2007-08-15 06:19:30Z damagedsoul $
|
||||
*/
|
||||
|
||||
#include "TopMenuManager.h"
|
||||
#include "TopMenu.h"
|
||||
|
||||
TopMenuManager g_TopMenus;
|
||||
bool is_server_activated = false;
|
||||
|
||||
const char *TopMenuManager::GetInterfaceName()
|
||||
{
|
||||
return SMINTERFACE_TOPMENUS_NAME;
|
||||
}
|
||||
|
||||
unsigned int TopMenuManager::GetInterfaceVersion()
|
||||
{
|
||||
return SMINTERFACE_TOPMENUS_VERSION;
|
||||
}
|
||||
|
||||
ITopMenu *TopMenuManager::CreateTopMenu(ITopMenuObjectCallbacks *callbacks)
|
||||
{
|
||||
TopMenu *pMenu = new TopMenu(callbacks);
|
||||
|
||||
m_TopMenus.push_back(pMenu);
|
||||
|
||||
return pMenu;
|
||||
}
|
||||
|
||||
void TopMenuManager::OnClientConnected(int client)
|
||||
{
|
||||
List<TopMenu *>::iterator iter;
|
||||
|
||||
for (iter = m_TopMenus.begin(); iter != m_TopMenus.end(); iter++)
|
||||
{
|
||||
(*iter)->OnClientConnected(client);
|
||||
}
|
||||
}
|
||||
|
||||
void TopMenuManager::OnClientDisconnected(int client)
|
||||
{
|
||||
List<TopMenu *>::iterator iter;
|
||||
|
||||
for (iter = m_TopMenus.begin(); iter != m_TopMenus.end(); iter++)
|
||||
{
|
||||
(*iter)->OnClientDisconnected(client);
|
||||
}
|
||||
}
|
||||
|
||||
void TopMenuManager::OnServerActivated(int max_clients)
|
||||
{
|
||||
if (is_server_activated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<TopMenu *>::iterator iter;
|
||||
|
||||
for (iter = m_TopMenus.begin(); iter != m_TopMenus.end(); iter++)
|
||||
{
|
||||
(*iter)->OnServerActivated(max_clients);
|
||||
}
|
||||
|
||||
is_server_activated = true;
|
||||
}
|
||||
|
||||
void TopMenuManager::DestroyTopMenu(ITopMenu *topmenu)
|
||||
{
|
||||
TopMenu *pMenu = (TopMenu *)topmenu;
|
||||
|
||||
m_TopMenus.remove(pMenu);
|
||||
|
||||
delete pMenu;
|
||||
}
|
64
extensions/topmenus/TopMenuManager.h
Normal file
64
extensions/topmenus/TopMenuManager.h
Normal file
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Sample Extension
|
||||
* Copyright (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: extension.cpp 1336 2007-08-15 06:19:30Z damagedsoul $
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _INCLUDE_SOURCEMOD_TOP_MENU_MANAGER_IMPL_H_
|
||||
#define _INCLUDE_SOURCEMOD_TOP_MENU_MANAGER_IMPL_H_
|
||||
|
||||
#include <ITopMenus.h>
|
||||
#include <IPlayerHelpers.h>
|
||||
#include <sh_list.h>
|
||||
|
||||
using namespace SourceMod;
|
||||
using namespace SourceHook;
|
||||
|
||||
class TopMenu;
|
||||
|
||||
class TopMenuManager :
|
||||
public ITopMenuManager,
|
||||
public IClientListener
|
||||
{
|
||||
public:
|
||||
const char *GetInterfaceName();
|
||||
unsigned int GetInterfaceVersion();
|
||||
ITopMenu *CreateTopMenu(ITopMenuObjectCallbacks *callbacks);
|
||||
void DestroyTopMenu(ITopMenu *topmenu);
|
||||
public:
|
||||
void OnClientConnected(int client);
|
||||
void OnClientDisconnected(int client);
|
||||
void OnServerActivated(int max_clients);
|
||||
private:
|
||||
List<TopMenu *> m_TopMenus;
|
||||
};
|
||||
|
||||
extern TopMenuManager g_TopMenus;
|
||||
|
||||
#endif //_INCLUDE_SOURCEMOD_TOP_MENU_MANAGER_IMPL_H_
|
55
extensions/topmenus/extension.cpp
Normal file
55
extensions/topmenus/extension.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Sample Extension
|
||||
* Copyright (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: extension.cpp 1336 2007-08-15 06:19:30Z damagedsoul $
|
||||
*/
|
||||
|
||||
#include "extension.h"
|
||||
#include "TopMenuManager.h"
|
||||
|
||||
/**
|
||||
* @file extension.cpp
|
||||
* @brief Implement extension code here.
|
||||
*/
|
||||
|
||||
TopMenuExtension g_TopMenuExt; /**< Global singleton for extension's main interface */
|
||||
|
||||
SMEXT_LINK(&g_TopMenuExt);
|
||||
|
||||
bool TopMenuExtension::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||
{
|
||||
sharesys->AddInterface(myself, &g_TopMenus);
|
||||
playerhelpers->AddClientListener(&g_TopMenus);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TopMenuExtension::SDK_OnUnload()
|
||||
{
|
||||
playerhelpers->RemoveClientListener(&g_TopMenus);
|
||||
}
|
66
extensions/topmenus/extension.h
Normal file
66
extensions/topmenus/extension.h
Normal file
@ -0,0 +1,66 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Sample Extension
|
||||
* Copyright (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: extension.h 1336 2007-08-15 06:19:30Z damagedsoul $
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||
#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||
|
||||
/**
|
||||
* @file extension.h
|
||||
* @brief Sample extension code header.
|
||||
*/
|
||||
|
||||
#include "smsdk_ext.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief Sample implementation of the SDK Extension.
|
||||
* Note: Uncomment one of the pre-defined virtual functions in order to use it.
|
||||
*/
|
||||
class TopMenuExtension : public SDKExtension
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief This is called after the initial loading sequence has been processed.
|
||||
*
|
||||
* @param error Error message buffer.
|
||||
* @param maxlength Size of error message buffer.
|
||||
* @param late Whether or not the module was loaded after map load.
|
||||
* @return True to succeed loading, false to fail.
|
||||
*/
|
||||
virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late);
|
||||
|
||||
/**
|
||||
* @brief This is called right before the extension is unloaded.
|
||||
*/
|
||||
virtual void SDK_OnUnload();
|
||||
};
|
||||
|
||||
#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
20
extensions/topmenus/msvc8/topmenus.sln
Normal file
20
extensions/topmenus/msvc8/topmenus.sln
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual Studio 2005
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "topmenus", "topmenus.vcproj", "{B3E797CF-4E77-4C9D-B8A8-7589B6902206}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
256
extensions/topmenus/msvc8/topmenus.vcproj
Normal file
256
extensions/topmenus/msvc8/topmenus.vcproj
Normal file
@ -0,0 +1,256 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="topmenus"
|
||||
ProjectGUID="{B3E797CF-4E77-4C9D-B8A8-7589B6902206}"
|
||||
RootNamespace="topmenus"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..;..\sdk;..\..\..\public;..\..\..\public\sourcepawn;..\..\..\public\extensions"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;SDK_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)\sample.ext.dll"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="..;..\sdk;..\..\..\public;..\..\..\public\sourcepawn"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;SDK_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD"
|
||||
RuntimeLibrary="0"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)\sample.ext.dll"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\extension.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\TopMenu.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\TopMenuManager.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\extension.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\TopMenu.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\TopMenuManager.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="SourceMod SDK"
|
||||
UniqueIdentifier="{31958233-BB2D-4e41-A8F9-CE8A4684F436}"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\sdk\sm_memtable.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sdk\sm_memtable.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sdk\smsdk_config.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sdk\smsdk_ext.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sdk\smsdk_ext.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Interfaces"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\..\public\extensions\ITopMenus.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
112
extensions/topmenus/sdk/sm_memtable.cpp
Normal file
112
extensions/topmenus/sdk/sm_memtable.cpp
Normal file
@ -0,0 +1,112 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (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: sm_memtable.cpp 1336 2007-08-15 06:19:30Z damagedsoul $
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include "sm_memtable.h"
|
||||
|
||||
BaseMemTable::BaseMemTable(unsigned int init_size)
|
||||
{
|
||||
membase = (unsigned char *)malloc(init_size);
|
||||
size = init_size;
|
||||
tail = 0;
|
||||
}
|
||||
|
||||
BaseMemTable::~BaseMemTable()
|
||||
{
|
||||
free(membase);
|
||||
membase = NULL;
|
||||
}
|
||||
|
||||
int BaseMemTable::CreateMem(unsigned int addsize, void **addr)
|
||||
{
|
||||
int idx = (int)tail;
|
||||
|
||||
while (tail + addsize >= size)
|
||||
{
|
||||
size *= 2;
|
||||
membase = (unsigned char *)realloc(membase, size);
|
||||
}
|
||||
|
||||
tail += addsize;
|
||||
|
||||
if (addr)
|
||||
{
|
||||
*addr = (void *)&membase[idx];
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
void *BaseMemTable::GetAddress(int index)
|
||||
{
|
||||
if (index < 0 || (unsigned int)index >= tail)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &membase[index];
|
||||
}
|
||||
|
||||
void BaseMemTable::Reset()
|
||||
{
|
||||
tail = 0;
|
||||
}
|
||||
|
||||
BaseStringTable::BaseStringTable(unsigned int init_size) : m_table(init_size)
|
||||
{
|
||||
}
|
||||
|
||||
BaseStringTable::~BaseStringTable()
|
||||
{
|
||||
}
|
||||
|
||||
int BaseStringTable::AddString(const char *string)
|
||||
{
|
||||
size_t len = strlen(string) + 1;
|
||||
int idx;
|
||||
char *addr;
|
||||
|
||||
idx = m_table.CreateMem(len, (void **)&addr);
|
||||
strcpy(addr, string);
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
/*const char *BaseStringTable::GetString(int str)
|
||||
{
|
||||
return (const char *)m_table.GetAddress(str);
|
||||
}*/
|
||||
|
||||
void BaseStringTable::Reset()
|
||||
{
|
||||
m_table.Reset();
|
||||
}
|
105
extensions/topmenus/sdk/sm_memtable.h
Normal file
105
extensions/topmenus/sdk/sm_memtable.h
Normal file
@ -0,0 +1,105 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (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: sm_memtable.h 1336 2007-08-15 06:19:30Z damagedsoul $
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_
|
||||
#define _INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_
|
||||
|
||||
class BaseMemTable
|
||||
{
|
||||
public:
|
||||
BaseMemTable(unsigned int init_size);
|
||||
~BaseMemTable();
|
||||
public:
|
||||
/**
|
||||
* Allocates 'size' bytes of memory.
|
||||
* Optionally outputs the address through 'addr'.
|
||||
* Returns an index >= 0 on success, < 0 on failure.
|
||||
*/
|
||||
int CreateMem(unsigned int size, void **addr);
|
||||
|
||||
/**
|
||||
* Given an index into the memory table, returns its address.
|
||||
* Returns NULL if invalid.
|
||||
*/
|
||||
void *GetAddress(int index);
|
||||
|
||||
/**
|
||||
* Scraps the memory table. For caching purposes, the memory
|
||||
* is not freed, however subsequent calls to CreateMem() will
|
||||
* begin at the first index again.
|
||||
*/
|
||||
void Reset();
|
||||
|
||||
|
||||
private:
|
||||
unsigned char *membase;
|
||||
unsigned int size;
|
||||
unsigned int tail;
|
||||
};
|
||||
|
||||
class BaseStringTable
|
||||
{
|
||||
public:
|
||||
BaseStringTable(unsigned int init_size);
|
||||
~BaseStringTable();
|
||||
public:
|
||||
/**
|
||||
* Adds a string to the string table and returns its index.
|
||||
*/
|
||||
int AddString(const char *string);
|
||||
|
||||
/**
|
||||
* Given an index into the string table, returns the associated string.
|
||||
*/
|
||||
inline const char *GetString(int str)
|
||||
{
|
||||
return (const char *)m_table.GetAddress(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scraps the string table. For caching purposes, the memory
|
||||
* is not freed, however subsequent calls to AddString() will
|
||||
* begin at the first index again.
|
||||
*/
|
||||
void Reset();
|
||||
|
||||
/**
|
||||
* Returns the parent BaseMemTable that this string table uses.
|
||||
*/
|
||||
inline BaseMemTable *GetMemTable()
|
||||
{
|
||||
return &m_table;
|
||||
}
|
||||
private:
|
||||
BaseMemTable m_table;
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_
|
78
extensions/topmenus/sdk/smsdk_config.h
Normal file
78
extensions/topmenus/sdk/smsdk_config.h
Normal file
@ -0,0 +1,78 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Sample Extension
|
||||
* Copyright (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: smsdk_config.h 1336 2007-08-15 06:19:30Z damagedsoul $
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
|
||||
#define _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
|
||||
|
||||
/**
|
||||
* @file smsdk_config.h
|
||||
* @brief Contains macros for configuring basic extension information.
|
||||
*/
|
||||
|
||||
/* Basic information exposed publicly */
|
||||
#define SMEXT_CONF_NAME "Main Menu"
|
||||
#define SMEXT_CONF_DESCRIPTION "Manages SourceMod's main menus"
|
||||
#define SMEXT_CONF_VERSION "1.0.0.0"
|
||||
#define SMEXT_CONF_AUTHOR "AlliedModders"
|
||||
#define SMEXT_CONF_URL "http://www.sourcemod.net/"
|
||||
#define SMEXT_CONF_LOGTAG "MAINMENU"
|
||||
#define SMEXT_CONF_LICENSE "GPLv3"
|
||||
#define SMEXT_CONF_DATESTRING __DATE__
|
||||
|
||||
/**
|
||||
* @brief Exposes plugin's main interface.
|
||||
*/
|
||||
#define SMEXT_LINK(name) SDKExtension *g_pExtensionIface = name;
|
||||
|
||||
/**
|
||||
* @brief Sets whether or not this plugin required Metamod.
|
||||
* NOTE: Uncomment to enable, comment to disable.
|
||||
*/
|
||||
//#define SMEXT_CONF_METAMOD
|
||||
|
||||
/** Enable interfaces you want to use here by uncommenting lines */
|
||||
//#define SMEXT_ENABLE_FORWARDSYS
|
||||
//#define SMEXT_ENABLE_HANDLESYS
|
||||
#define SMEXT_ENABLE_PLAYERHELPERS
|
||||
//#define SMEXT_ENABLE_DBMANAGER
|
||||
//#define SMEXT_ENABLE_GAMECONF
|
||||
//#define SMEXT_ENABLE_MEMUTILS
|
||||
//#define SMEXT_ENABLE_GAMEHELPERS
|
||||
//#define SMEXT_ENABLE_TIMERSYS
|
||||
//#define SMEXT_ENABLE_THREADER
|
||||
//#define SMEXT_ENABLE_LIBSYS
|
||||
#define SMEXT_ENABLE_MENUS
|
||||
//#define SMEXT_ENABLE_ADTFACTORY
|
||||
//#define SMEXT_ENABLE_PLUGINSYS
|
||||
#define SMEXT_ENABLE_ADMINSYS
|
||||
#define SMEXT_ENABLE_TEXTPARSERS
|
||||
|
||||
#endif // _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
|
440
extensions/topmenus/sdk/smsdk_ext.cpp
Normal file
440
extensions/topmenus/sdk/smsdk_ext.cpp
Normal file
@ -0,0 +1,440 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Base Extension Code
|
||||
* Copyright (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: smsdk_ext.cpp 1336 2007-08-15 06:19:30Z damagedsoul $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include "smsdk_ext.h"
|
||||
|
||||
/**
|
||||
* @file smsdk_ext.cpp
|
||||
* @brief Contains wrappers for making Extensions easier to write.
|
||||
*/
|
||||
|
||||
IExtension *myself = NULL; /**< Ourself */
|
||||
IShareSys *g_pShareSys = NULL; /**< Share system */
|
||||
IShareSys *sharesys = NULL; /**< Share system */
|
||||
ISourceMod *g_pSM = NULL; /**< SourceMod helpers */
|
||||
ISourceMod *smutils = NULL; /**< SourceMod helpers */
|
||||
|
||||
#if defined SMEXT_ENABLE_FORWARDSYS
|
||||
IForwardManager *g_pForwards = NULL; /**< Forward system */
|
||||
IForwardManager *forwards = NULL; /**< Forward system */
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_HANDLESYS
|
||||
IHandleSys *g_pHandleSys = NULL; /**< Handle system */
|
||||
IHandleSys *handlesys = NULL; /**< Handle system */
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_PLAYERHELPERS
|
||||
IPlayerManager *playerhelpers = NULL; /**< Player helpers */
|
||||
#endif //SMEXT_ENABLE_PLAYERHELPERS
|
||||
#if defined SMEXT_ENABLE_DBMANAGER
|
||||
IDBManager *dbi = NULL; /**< DB Manager */
|
||||
#endif //SMEXT_ENABLE_DBMANAGER
|
||||
#if defined SMEXT_ENABLE_GAMECONF
|
||||
IGameConfigManager *gameconfs = NULL; /**< Game config manager */
|
||||
#endif //SMEXT_ENABLE_DBMANAGER
|
||||
#if defined SMEXT_ENABLE_MEMUTILS
|
||||
IMemoryUtils *memutils = NULL;
|
||||
#endif //SMEXT_ENABLE_DBMANAGER
|
||||
#if defined SMEXT_ENABLE_GAMEHELPERS
|
||||
IGameHelpers *gamehelpers = NULL;
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_TIMERSYS
|
||||
ITimerSystem *timersys = NULL;
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_ADTFACTORY
|
||||
IADTFactory *adtfactory = NULL;
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_THREADER
|
||||
IThreader *threader = NULL;
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_LIBSYS
|
||||
ILibrarySys *libsys = NULL;
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_PLUGINSYS
|
||||
SourceMod::IPluginManager *plsys;
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_MENUS
|
||||
IMenuManager *menus = NULL;
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_ADMINSYS
|
||||
IAdminSystem *adminsys = NULL;
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_TEXTPARSERS
|
||||
ITextParsers *textparsers = NULL;
|
||||
#endif
|
||||
|
||||
/** Exports the main interface */
|
||||
PLATFORM_EXTERN_C IExtensionInterface *GetSMExtAPI()
|
||||
{
|
||||
return g_pExtensionIface;
|
||||
}
|
||||
|
||||
SDKExtension::SDKExtension()
|
||||
{
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
m_SourceMMLoaded = false;
|
||||
m_WeAreUnloaded = false;
|
||||
m_WeGotPauseChange = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SDKExtension::OnExtensionLoad(IExtension *me, IShareSys *sys, char *error, size_t maxlength, bool late)
|
||||
{
|
||||
g_pShareSys = sharesys = sys;
|
||||
myself = me;
|
||||
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
m_WeAreUnloaded = true;
|
||||
|
||||
if (!m_SourceMMLoaded)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
snprintf(error, maxlength, "Metamod attach failed");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
SM_GET_IFACE(SOURCEMOD, g_pSM);
|
||||
smutils = g_pSM;
|
||||
#if defined SMEXT_ENABLE_HANDLESYS
|
||||
SM_GET_IFACE(HANDLESYSTEM, g_pHandleSys);
|
||||
handlesys = g_pHandleSys;
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_FORWARDSYS
|
||||
SM_GET_IFACE(FORWARDMANAGER, g_pForwards);
|
||||
forwards = g_pForwards;
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_PLAYERHELPERS
|
||||
SM_GET_IFACE(PLAYERMANAGER, playerhelpers);
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_DBMANAGER
|
||||
SM_GET_IFACE(DBI, dbi);
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_GAMECONF
|
||||
SM_GET_IFACE(GAMECONFIG, gameconfs);
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_MEMUTILS
|
||||
SM_GET_IFACE(MEMORYUTILS, memutils);
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_GAMEHELPERS
|
||||
SM_GET_IFACE(GAMEHELPERS, gamehelpers);
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_TIMERSYS
|
||||
SM_GET_IFACE(TIMERSYS, timersys);
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_ADTFACTORY
|
||||
SM_GET_IFACE(ADTFACTORY, adtfactory);
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_THREADER
|
||||
SM_GET_IFACE(THREADER, threader);
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_LIBSYS
|
||||
SM_GET_IFACE(LIBRARYSYS, libsys);
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_PLUGINSYS
|
||||
SM_GET_IFACE(PLUGINSYSTEM, plsys);
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_MENUS
|
||||
SM_GET_IFACE(MENUMANAGER, menus);
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_ADMINSYS
|
||||
SM_GET_IFACE(ADMINSYS, adminsys);
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_TEXTPARSERS
|
||||
SM_GET_IFACE(TEXTPARSERS, textparsers);
|
||||
#endif
|
||||
|
||||
if (SDK_OnLoad(error, maxlength, late))
|
||||
{
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
m_WeAreUnloaded = true;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SDKExtension::IsMetamodExtension()
|
||||
{
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SDKExtension::OnExtensionPauseChange(bool state)
|
||||
{
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
m_WeGotPauseChange = true;
|
||||
#endif
|
||||
SDK_OnPauseChange(state);
|
||||
}
|
||||
|
||||
void SDKExtension::OnExtensionsAllLoaded()
|
||||
{
|
||||
SDK_OnAllLoaded();
|
||||
}
|
||||
|
||||
void SDKExtension::OnExtensionUnload()
|
||||
{
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
m_WeAreUnloaded = true;
|
||||
#endif
|
||||
SDK_OnUnload();
|
||||
}
|
||||
|
||||
const char *SDKExtension::GetExtensionAuthor()
|
||||
{
|
||||
return SMEXT_CONF_AUTHOR;
|
||||
}
|
||||
|
||||
const char *SDKExtension::GetExtensionDateString()
|
||||
{
|
||||
return SMEXT_CONF_DATESTRING;
|
||||
}
|
||||
|
||||
const char *SDKExtension::GetExtensionDescription()
|
||||
{
|
||||
return SMEXT_CONF_DESCRIPTION;
|
||||
}
|
||||
|
||||
const char *SDKExtension::GetExtensionVerString()
|
||||
{
|
||||
return SMEXT_CONF_VERSION;
|
||||
}
|
||||
|
||||
const char *SDKExtension::GetExtensionName()
|
||||
{
|
||||
return SMEXT_CONF_NAME;
|
||||
}
|
||||
|
||||
const char *SDKExtension::GetExtensionTag()
|
||||
{
|
||||
return SMEXT_CONF_LOGTAG;
|
||||
}
|
||||
|
||||
const char *SDKExtension::GetExtensionURL()
|
||||
{
|
||||
return SMEXT_CONF_URL;
|
||||
}
|
||||
|
||||
bool SDKExtension::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void SDKExtension::SDK_OnUnload()
|
||||
{
|
||||
}
|
||||
|
||||
void SDKExtension::SDK_OnPauseChange(bool paused)
|
||||
{
|
||||
}
|
||||
|
||||
void SDKExtension::SDK_OnAllLoaded()
|
||||
{
|
||||
}
|
||||
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
|
||||
PluginId g_PLID = 0; /**< Metamod plugin ID */
|
||||
ISmmPlugin *g_PLAPI = NULL; /**< Metamod plugin API */
|
||||
SourceHook::ISourceHook *g_SHPtr = NULL; /**< SourceHook pointer */
|
||||
ISmmAPI *g_SMAPI = NULL; /**< SourceMM API pointer */
|
||||
|
||||
IVEngineServer *engine = NULL; /**< IVEngineServer pointer */
|
||||
IServerGameDLL *gamedll = NULL; /**< IServerGameDLL pointer */
|
||||
|
||||
/** Exposes the extension to Metamod */
|
||||
SMM_API void *PL_EXPOSURE(const char *name, int *code)
|
||||
{
|
||||
if (name && !strcmp(name, PLAPI_NAME))
|
||||
{
|
||||
if (code)
|
||||
{
|
||||
*code = IFACE_OK;
|
||||
}
|
||||
return static_cast<void *>(g_pExtensionIface);
|
||||
}
|
||||
|
||||
if (code)
|
||||
{
|
||||
*code = IFACE_FAILED;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool SDKExtension::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late)
|
||||
{
|
||||
PLUGIN_SAVEVARS();
|
||||
|
||||
GET_V_IFACE_ANY(serverFactory, gamedll, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL);
|
||||
GET_V_IFACE_CURRENT(engineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER);
|
||||
|
||||
m_SourceMMLoaded = true;
|
||||
|
||||
return SDK_OnMetamodLoad(ismm, error, maxlen, late);
|
||||
}
|
||||
|
||||
bool SDKExtension::Unload(char *error, size_t maxlen)
|
||||
{
|
||||
if (!m_WeAreUnloaded)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
snprintf(error, maxlen, "This extension must be unloaded by SourceMod.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return SDK_OnMetamodUnload(error, maxlen);
|
||||
}
|
||||
|
||||
bool SDKExtension::Pause(char *error, size_t maxlen)
|
||||
{
|
||||
if (!m_WeGotPauseChange)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
snprintf(error, maxlen, "This extension must be paused by SourceMod.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
m_WeGotPauseChange = false;
|
||||
|
||||
return SDK_OnMetamodPauseChange(true, error, maxlen);
|
||||
}
|
||||
|
||||
bool SDKExtension::Unpause(char *error, size_t maxlen)
|
||||
{
|
||||
if (!m_WeGotPauseChange)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
snprintf(error, maxlen, "This extension must be unpaused by SourceMod.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
m_WeGotPauseChange = false;
|
||||
|
||||
return SDK_OnMetamodPauseChange(false, error, maxlen);
|
||||
}
|
||||
|
||||
const char *SDKExtension::GetAuthor()
|
||||
{
|
||||
return GetExtensionAuthor();
|
||||
}
|
||||
|
||||
const char *SDKExtension::GetDate()
|
||||
{
|
||||
return GetExtensionDateString();
|
||||
}
|
||||
|
||||
const char *SDKExtension::GetDescription()
|
||||
{
|
||||
return GetExtensionDescription();
|
||||
}
|
||||
|
||||
const char *SDKExtension::GetLicense()
|
||||
{
|
||||
return SMEXT_CONF_LICENSE;
|
||||
}
|
||||
|
||||
const char *SDKExtension::GetLogTag()
|
||||
{
|
||||
return GetExtensionTag();
|
||||
}
|
||||
|
||||
const char *SDKExtension::GetName()
|
||||
{
|
||||
return GetExtensionName();
|
||||
}
|
||||
|
||||
const char *SDKExtension::GetURL()
|
||||
{
|
||||
return GetExtensionURL();
|
||||
}
|
||||
|
||||
const char *SDKExtension::GetVersion()
|
||||
{
|
||||
return GetExtensionVerString();
|
||||
}
|
||||
|
||||
bool SDKExtension::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SDKExtension::SDK_OnMetamodUnload(char *error, size_t maxlength)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SDKExtension::SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Overload a few things to prevent libstdc++ linking */
|
||||
#if defined __linux__
|
||||
extern "C" void __cxa_pure_virtual(void)
|
||||
{
|
||||
}
|
||||
|
||||
void *operator new(size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void *operator new[](size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void operator delete(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void operator delete[](void * ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
#endif
|
313
extensions/topmenus/sdk/smsdk_ext.h
Normal file
313
extensions/topmenus/sdk/smsdk_ext.h
Normal file
@ -0,0 +1,313 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Base Extension Code
|
||||
* Copyright (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: smsdk_ext.h 1336 2007-08-15 06:19:30Z damagedsoul $
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_
|
||||
#define _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_
|
||||
|
||||
/**
|
||||
* @file smsdk_ext.h
|
||||
* @brief Contains wrappers for making Extensions easier to write.
|
||||
*/
|
||||
|
||||
#include "smsdk_config.h"
|
||||
#include <IExtensionSys.h>
|
||||
#include <IHandleSys.h>
|
||||
#include <sp_vm_api.h>
|
||||
#include <sm_platform.h>
|
||||
#include <ISourceMod.h>
|
||||
#if defined SMEXT_ENABLE_FORWARDSYS
|
||||
#include <IForwardSys.h>
|
||||
#endif //SMEXT_ENABLE_FORWARDSYS
|
||||
#if defined SMEXT_ENABLE_PLAYERHELPERS
|
||||
#include <IPlayerHelpers.h>
|
||||
#endif //SMEXT_ENABLE_PlAYERHELPERS
|
||||
#if defined SMEXT_ENABLE_DBMANAGER
|
||||
#include <IDBDriver.h>
|
||||
#endif //SMEXT_ENABLE_DBMANAGER
|
||||
#if defined SMEXT_ENABLE_GAMECONF
|
||||
#include <IGameConfigs.h>
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_MEMUTILS
|
||||
#include <IMemoryUtils.h>
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_GAMEHELPERS
|
||||
#include <IGameHelpers.h>
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_TIMERSYS
|
||||
#include <ITimerSystem.h>
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_ADTFACTORY
|
||||
#include <IADTFactory.h>
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_THREADER
|
||||
#include <IThreader.h>
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_LIBSYS
|
||||
#include <ILibrarySys.h>
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_PLUGINSYS
|
||||
#include <IPluginSys.h>
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_MENUS
|
||||
#include <IMenuManager.h>
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_ADMINSYS
|
||||
#include <IAdminSystem.h>
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_TEXTPARSERS
|
||||
#include <ITextParsers.h>
|
||||
#endif
|
||||
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
#include <ISmmPlugin.h>
|
||||
#include <eiface.h>
|
||||
#endif
|
||||
|
||||
using namespace SourceMod;
|
||||
using namespace SourcePawn;
|
||||
|
||||
class SDKExtension :
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
public ISmmPlugin,
|
||||
#endif
|
||||
public IExtensionInterface
|
||||
{
|
||||
public:
|
||||
/** Constructor */
|
||||
SDKExtension();
|
||||
public:
|
||||
/**
|
||||
* @brief This is called after the initial loading sequence has been processed.
|
||||
*
|
||||
* @param error Error message buffer.
|
||||
* @param maxlength Size of error message buffer.
|
||||
* @param late Whether or not the module was loaded after map load.
|
||||
* @return True to succeed loading, false to fail.
|
||||
*/
|
||||
virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late);
|
||||
|
||||
/**
|
||||
* @brief This is called right before the extension is unloaded.
|
||||
*/
|
||||
virtual void SDK_OnUnload();
|
||||
|
||||
/**
|
||||
* @brief This is called once all known extensions have been loaded.
|
||||
*/
|
||||
virtual void SDK_OnAllLoaded();
|
||||
|
||||
/**
|
||||
* @brief Called when the pause state is changed.
|
||||
*/
|
||||
virtual void SDK_OnPauseChange(bool paused);
|
||||
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
/**
|
||||
* @brief Called when Metamod is attached, before the extension version is called.
|
||||
*
|
||||
* @param error Error buffer.
|
||||
* @param maxlength Maximum size of error buffer.
|
||||
* @param late Whether or not Metamod considers this a late load.
|
||||
* @return True to succeed, false to fail.
|
||||
*/
|
||||
virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late);
|
||||
|
||||
/**
|
||||
* @brief Called when Metamod is detaching, after the extension version is called.
|
||||
* NOTE: By default this is blocked unless sent from SourceMod.
|
||||
*
|
||||
* @param error Error buffer.
|
||||
* @param maxlength Maximum size of error buffer.
|
||||
* @return True to succeed, false to fail.
|
||||
*/
|
||||
virtual bool SDK_OnMetamodUnload(char *error, size_t maxlength);
|
||||
|
||||
/**
|
||||
* @brief Called when Metamod's pause state is changing.
|
||||
* NOTE: By default this is blocked unless sent from SourceMod.
|
||||
*
|
||||
* @param paused Pause state being set.
|
||||
* @param error Error buffer.
|
||||
* @param maxlength Maximum size of error buffer.
|
||||
* @return True to succeed, false to fail.
|
||||
*/
|
||||
virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength);
|
||||
#endif
|
||||
|
||||
public: //IExtensionInterface
|
||||
virtual bool OnExtensionLoad(IExtension *me, IShareSys *sys, char *error, size_t maxlength, bool late);
|
||||
virtual void OnExtensionUnload();
|
||||
virtual void OnExtensionsAllLoaded();
|
||||
|
||||
/** Returns whether or not this is a Metamod-based extension */
|
||||
virtual bool IsMetamodExtension();
|
||||
|
||||
/**
|
||||
* @brief Called when the pause state changes.
|
||||
*
|
||||
* @param state True if being paused, false if being unpaused.
|
||||
*/
|
||||
virtual void OnExtensionPauseChange(bool state);
|
||||
|
||||
/** Returns name */
|
||||
virtual const char *GetExtensionName();
|
||||
/** Returns URL */
|
||||
virtual const char *GetExtensionURL();
|
||||
/** Returns log tag */
|
||||
virtual const char *GetExtensionTag();
|
||||
/** Returns author */
|
||||
virtual const char *GetExtensionAuthor();
|
||||
/** Returns version string */
|
||||
virtual const char *GetExtensionVerString();
|
||||
/** Returns description string */
|
||||
virtual const char *GetExtensionDescription();
|
||||
/** Returns date string */
|
||||
virtual const char *GetExtensionDateString();
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
public: //ISmmPlugin
|
||||
/** Called when the extension is attached to Metamod. */
|
||||
virtual bool Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlength, bool late);
|
||||
/** Returns the author to MM */
|
||||
virtual const char *GetAuthor();
|
||||
/** Returns the name to MM */
|
||||
virtual const char *GetName();
|
||||
/** Returns the description to MM */
|
||||
virtual const char *GetDescription();
|
||||
/** Returns the URL to MM */
|
||||
virtual const char *GetURL();
|
||||
/** Returns the license to MM */
|
||||
virtual const char *GetLicense();
|
||||
/** Returns the version string to MM */
|
||||
virtual const char *GetVersion();
|
||||
/** Returns the date string to MM */
|
||||
virtual const char *GetDate();
|
||||
/** Returns the logtag to MM */
|
||||
virtual const char *GetLogTag();
|
||||
/** Called on unload */
|
||||
virtual bool Unload(char *error, size_t maxlength);
|
||||
/** Called on pause */
|
||||
virtual bool Pause(char *error, size_t maxlength);
|
||||
/** Called on unpause */
|
||||
virtual bool Unpause(char *error, size_t maxlength);
|
||||
private:
|
||||
bool m_SourceMMLoaded;
|
||||
bool m_WeAreUnloaded;
|
||||
bool m_WeGotPauseChange;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern SDKExtension *g_pExtensionIface;
|
||||
extern IExtension *myself;
|
||||
|
||||
extern IShareSys *g_pShareSys;
|
||||
extern IShareSys *sharesys; /* Note: Newer name */
|
||||
extern ISourceMod *g_pSM;
|
||||
extern ISourceMod *smutils; /* Note: Newer name */
|
||||
|
||||
/* Optional interfaces are below */
|
||||
#if defined SMEXT_ENABLE_FORWARDSYS
|
||||
extern IForwardManager *g_pForwards;
|
||||
extern IForwardManager *forwards; /* Note: Newer name */
|
||||
#endif //SMEXT_ENABLE_FORWARDSYS
|
||||
#if defined SMEXT_ENABLE_HANDLESYS
|
||||
extern IHandleSys *g_pHandleSys;
|
||||
extern IHandleSys *handlesys; /* Note: Newer name */
|
||||
#endif //SMEXT_ENABLE_HANDLESYS
|
||||
#if defined SMEXT_ENABLE_PLAYERHELPERS
|
||||
extern IPlayerManager *playerhelpers;
|
||||
#endif //SMEXT_ENABLE_PLAYERHELPERS
|
||||
#if defined SMEXT_ENABLE_DBMANAGER
|
||||
extern IDBManager *dbi;
|
||||
#endif //SMEXT_ENABLE_DBMANAGER
|
||||
#if defined SMEXT_ENABLE_GAMECONF
|
||||
extern IGameConfigManager *gameconfs;
|
||||
#endif //SMEXT_ENABLE_DBMANAGER
|
||||
#if defined SMEXT_ENABLE_MEMUTILS
|
||||
extern IMemoryUtils *memutils;
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_GAMEHELPERS
|
||||
extern IGameHelpers *gamehelpers;
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_TIMERSYS
|
||||
extern ITimerSystem *timersys;
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_ADTFACTORY
|
||||
extern IADTFactory *adtfactory;
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_THREADER
|
||||
extern IThreader *threader;
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_LIBSYS
|
||||
extern ILibrarySys *libsys;
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_PLUGINSYS
|
||||
extern SourceMod::IPluginManager *plsys;
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_MENUS
|
||||
extern IMenuManager *menus;
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_ADMINSYS
|
||||
extern IAdminSystem *adminsys;
|
||||
#endif
|
||||
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
PLUGIN_GLOBALVARS();
|
||||
extern IVEngineServer *engine;
|
||||
extern IServerGameDLL *gamedll;
|
||||
#endif
|
||||
|
||||
/** Creates a SourceMod interface macro pair */
|
||||
#define SM_MKIFACE(name) SMINTERFACE_##name##_NAME, SMINTERFACE_##name##_VERSION
|
||||
/** Automates retrieving SourceMod interfaces */
|
||||
#define SM_GET_IFACE(prefix, addr) \
|
||||
if (!g_pShareSys->RequestInterface(SM_MKIFACE(prefix), myself, (SMInterface **)&addr)) \
|
||||
{ \
|
||||
if (error) \
|
||||
{ \
|
||||
snprintf(error, maxlength, "Could not find interface: %s (version: %d)", SMINTERFACE_##prefix##_NAME, SMINTERFACE_##prefix##_VERSION); \
|
||||
return false; \
|
||||
} \
|
||||
}
|
||||
/** Automates retrieving SourceMod interfaces when needed outside of SDK_OnLoad() */
|
||||
#define SM_GET_LATE_IFACE(prefix, addr) \
|
||||
g_pShareSys->RequestInterface(SM_MKIFACE(prefix), myself, (SMInterface **)&addr)
|
||||
/** Validates a SourceMod interface pointer */
|
||||
#define SM_CHECK_IFACE(prefix, addr) \
|
||||
if (!addr) \
|
||||
{ \
|
||||
if (error) \
|
||||
{ \
|
||||
snprintf(error, maxlength, "Could not find interface: %s", SMINTERFACE_##prefix##_NAME); \
|
||||
return false; \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif // _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_
|
219
public/extensions/ITopMenus.h
Normal file
219
public/extensions/ITopMenus.h
Normal file
@ -0,0 +1,219 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (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$
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SOURCEMOD_MAIN_MENU_INTERFACE_H_
|
||||
#define _INCLUDE_SOURCEMOD_MAIN_MENU_INTERFACE_H_
|
||||
|
||||
#include <IShareSys.h>
|
||||
#include <ILibrarySys.h>
|
||||
#include <IAdminSystem.h>
|
||||
#include <IMenuManager.h>
|
||||
|
||||
/**
|
||||
* @file ITopMenus.h
|
||||
* @brief Interface header for creating and managing top-level menus.
|
||||
*/
|
||||
|
||||
#define SMINTERFACE_TOPMENUS_NAME "ITopMenus"
|
||||
#define SMINTERFACE_TOPMENUS_VERSION 1
|
||||
|
||||
namespace SourceMod
|
||||
{
|
||||
/**
|
||||
* @brief Top menu object types.
|
||||
*/
|
||||
enum TopMenuObjectType
|
||||
{
|
||||
TopMenuObject_Category = 0, /**< Category (sub-menu branching from root) */
|
||||
TopMenuObject_Item = 1 /**< Item on a sub-menu */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Top menu starting positions for display.
|
||||
*/
|
||||
enum TopMenuPosition
|
||||
{
|
||||
TopMenuPosition_Start = 0, /**< Start/root of the menu */
|
||||
TopMenuPosition_LastRoot = 1, /**< Last position in the root menu */
|
||||
TopMenuPosition_LastCategory = 3, /**< Last position in their last category */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Top Menu callbacks for rendering/drawing.
|
||||
*/
|
||||
class ITopMenuObjectCallbacks
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Must return the topmenu API version.
|
||||
*
|
||||
* @return Top Menu API version.
|
||||
*/
|
||||
virtual unsigned int GetTopMenuAPIVersion1()
|
||||
{
|
||||
return SMINTERFACE_TOPMENUS_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Requests how the given item should be drawn for a client.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param object_id Object ID returned from ITopMenu::AddToMenu().
|
||||
* @param buffer Buffer to store rendered text.
|
||||
* @param maxlength Maximum length of the rendering buffer.
|
||||
* @return ITEMDRAW flags to disable or not draw the
|
||||
* option for this operation.
|
||||
*/
|
||||
virtual unsigned int OnTopMenuDrawOption(int client,
|
||||
unsigned int object_id,
|
||||
char buffer[],
|
||||
size_t maxlength) =0;
|
||||
|
||||
/**
|
||||
* @brief Requests how the given item's title should be drawn for
|
||||
* a client. This is called on any object_id that is a category.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param object_id Object ID returned from ITopMenu::AddToMenu(),
|
||||
* or 0 if the title is the root menu title.
|
||||
* @param buffer Buffer to store rendered text.
|
||||
* @param maxlength Maximum length of the rendering buffer.
|
||||
*/
|
||||
virtual void OnTopMenuDrawTitle(int client,
|
||||
unsigned int object_id,
|
||||
char buffer[],
|
||||
size_t maxlength) =0;
|
||||
|
||||
/**
|
||||
* @brief Notifies the listener that the menu option has been selected.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param object_id Object ID returned from ITopMenu::AddToMenu().
|
||||
*/
|
||||
virtual void OnTopMenuSelectOption(int client, unsigned int object_id) =0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief "Top menu" interface, for managing top-level categorized menus.
|
||||
*/
|
||||
class ITopMenu
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Creates and adds an object type type to the top menu.
|
||||
*
|
||||
* @param name Unique, string name to give the object.
|
||||
* @param type Object type.
|
||||
* @param callbacks ITopMenuObjectCallbacks pointer.
|
||||
* @param owner IdentityToken_t owner of the object.
|
||||
* @param cmdname Command name used for override access checks.
|
||||
* If NULL or empty, access will not be Checked.
|
||||
* @param flags Default flag(s) to use for access checks.
|
||||
* @param parent Parent object, or 0 if none.
|
||||
* Currently, categories cannot have a parent,
|
||||
* and items must have a category parent.
|
||||
* @return An object ID, or 0 on failure.
|
||||
*/
|
||||
virtual unsigned int AddToMenu(const char *name,
|
||||
TopMenuObjectType type,
|
||||
ITopMenuObjectCallbacks *callbacks,
|
||||
IdentityToken_t *owner,
|
||||
const char *cmdname,
|
||||
FlagBits flags,
|
||||
unsigned int parent) =0;
|
||||
|
||||
/**
|
||||
* @brief Removes an object from a menu. If the object has any
|
||||
* children, those will be removed.
|
||||
*
|
||||
* @param command_id Command ID returned from AddToMenu.
|
||||
*/
|
||||
virtual void RemoveFromMenu(unsigned int object_id) =0;
|
||||
|
||||
/**
|
||||
* @brief Sends the main menu to a given client.
|
||||
*
|
||||
* Once the menu is drawn to a client, the drawing order is cached.
|
||||
* If text on the menu is rendered differently for the client's next
|
||||
* viewing, the text will render properly, but its order will not
|
||||
* change. The menu is sorted by its configuration. Remaining items
|
||||
* are sorted in alphabetical order using the initial display text.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param hold_time Time to hold the menu on the screen for.
|
||||
* @param position TopMenuPosition enumeration value.
|
||||
* @return True on success, false if nothing displayed.
|
||||
*/
|
||||
virtual bool DisplayMenu(int client, unsigned int hold_time, TopMenuPosition position) =0;
|
||||
|
||||
/**
|
||||
* @brief Loads a configuration file for organizing the menu. This
|
||||
* forces all known categories to be re-sorted.
|
||||
*
|
||||
* Only one configuration can be active at a time. Loading a new one
|
||||
* will cause the old sorting to disappear.
|
||||
*
|
||||
* @param file File path.
|
||||
* @param error Error buffer.
|
||||
* @param maxlength Maximum length of the error buffer.
|
||||
* @return True on success, false on failure.
|
||||
*/
|
||||
virtual bool LoadConfiguration(const char *file, char *error, size_t maxlength) =0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Top menu manager.
|
||||
*/
|
||||
class ITopMenuManager : public SMInterface
|
||||
{
|
||||
public:
|
||||
virtual const char *GetInterfaceName() =0;
|
||||
virtual unsigned int GetInterfaceVersion() =0;
|
||||
public:
|
||||
/**
|
||||
* @brief Creates a new top-level menu.
|
||||
*
|
||||
* @param callbacks Callbacks for the title text.
|
||||
* The object_id for the title will always be 0.
|
||||
* @return A new ITopMenu pointer.
|
||||
*/
|
||||
virtual ITopMenu *CreateTopMenu(ITopMenuObjectCallbacks *callbacks) =0;
|
||||
|
||||
/**
|
||||
* @brief Destroys a top-level menu.
|
||||
*
|
||||
* @param topmenu Pointer to an ITopMenu.
|
||||
*/
|
||||
virtual void DestroyTopMenu(ITopMenu *topmenu) =0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //_INCLUDE_SOURCEMOD_MAIN_MENU_INTERFACE_H_
|
Loading…
Reference in New Issue
Block a user