3 * =============================================================================
4 * SourceMod TopMenus Extension
5 * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
6 * =============================================================================
8 * This program is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, version 3.0, as published by the
10 * Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to link the
21 * code of this program (as well as its derivative works) to "Half-Life 2," the
22 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
23 * by the Valve Corporation. You must obey the GNU General Public License in
24 * all respects for all other code used. Additionally, AlliedModders LLC grants
25 * this exception to all derivative works. AlliedModders LLC defines further
26 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
27 * or <http://www.sourcemod.net/license.php>.
32 #include "extension.h"
33 #include "TopMenuManager.h"
36 HandleType_t hTopMenuType;
38 class TopMenuHandle : public IHandleTypeDispatch
41 void OnHandleDestroy(HandleType_t type, void *object)
43 ITopMenu *pTopMenu = (ITopMenu *)object;
44 g_TopMenus.DestroyTopMenu(pTopMenu);
46 bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize)
48 *pSize = ((TopMenu *)object)->CalcMemUsage();
53 void Initialize_Natives()
55 hTopMenuType = handlesys->CreateType("ITopMenu",
60 myself->GetIdentity(),
64 void Shutdown_Natives()
66 handlesys->RemoveType(hTopMenuType, myself->GetIdentity());
71 TopMenuAction_DisplayOption = 0,
72 TopMenuAction_DisplayTitle = 1,
73 TopMenuAction_SelectOption = 2,
74 TopMenuAction_DrawOption = 3,
75 TopMenuAction_RemoveObject = 4,
78 class TopMenuCallbacks : public ITopMenuObjectCallbacks
81 TopMenuCallbacks(IPluginFunction *pFunction) : m_pFunction(pFunction)
85 unsigned int OnTopMenuDrawOption(ITopMenu *menu,
87 unsigned int object_id)
89 char buffer[2] = {ITEMDRAW_DEFAULT, 0x0};
90 m_pFunction->PushCell(m_hMenuHandle);
91 m_pFunction->PushCell(TopMenuAction_DrawOption);
92 m_pFunction->PushCell(object_id);
93 m_pFunction->PushCell(client);
94 m_pFunction->PushStringEx(buffer, sizeof(buffer), SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK);
95 m_pFunction->PushCell(sizeof(buffer));
96 m_pFunction->Execute(NULL);
97 return (unsigned int)buffer[0];
100 void OnTopMenuDisplayOption(ITopMenu *menu,
102 unsigned int object_id,
106 m_pFunction->PushCell(m_hMenuHandle);
107 m_pFunction->PushCell(TopMenuAction_DisplayOption);
108 m_pFunction->PushCell(object_id);
109 m_pFunction->PushCell(client);
110 m_pFunction->PushStringEx(buffer, maxlength, 0, SM_PARAM_COPYBACK);
111 m_pFunction->PushCell(maxlength);
112 m_pFunction->Execute(NULL);
115 void OnTopMenuDisplayTitle(ITopMenu *menu,
117 unsigned int object_id,
121 m_pFunction->PushCell(m_hMenuHandle);
122 m_pFunction->PushCell(TopMenuAction_DisplayTitle);
123 m_pFunction->PushCell(object_id);
124 m_pFunction->PushCell(client);
125 m_pFunction->PushStringEx(buffer, maxlength, 0, SM_PARAM_COPYBACK);
126 m_pFunction->PushCell(maxlength);
127 m_pFunction->Execute(NULL);
130 void OnTopMenuSelectOption(ITopMenu *menu,
132 unsigned int object_id)
134 unsigned int old_reply = playerhelpers->SetReplyTo(SM_REPLY_CHAT);
135 m_pFunction->PushCell(m_hMenuHandle);
136 m_pFunction->PushCell(TopMenuAction_SelectOption);
137 m_pFunction->PushCell(object_id);
138 m_pFunction->PushCell(client);
139 m_pFunction->PushString("");
140 m_pFunction->PushCell(0);
141 m_pFunction->Execute(NULL);
142 playerhelpers->SetReplyTo(old_reply);
145 void OnTopMenuObjectRemoved(ITopMenu *menu, unsigned int object_id)
147 m_pFunction->PushCell(m_hMenuHandle);
148 m_pFunction->PushCell(TopMenuAction_RemoveObject);
149 m_pFunction->PushCell(object_id);
150 m_pFunction->PushCell(0);
151 m_pFunction->PushString("");
152 m_pFunction->PushCell(0);
153 m_pFunction->Execute(NULL);
158 Handle_t m_hMenuHandle;
159 IPluginFunction *m_pFunction;
162 static cell_t CreateTopMenu(IPluginContext *pContext, const cell_t *params)
164 IPluginFunction *func = pContext->GetFunctionById(params[1]);
167 return pContext ->ThrowNativeError("Invalid function specified");
170 TopMenuCallbacks *cb = new TopMenuCallbacks(func);
172 ITopMenu *pMenu = g_TopMenus.CreateTopMenu(cb);
180 Handle_t hndl = handlesys->CreateHandle(hTopMenuType,
182 pContext->GetIdentity(),
183 myself->GetIdentity(),
187 g_TopMenus.DestroyTopMenu(pMenu);
191 cb->m_hMenuHandle = hndl;
196 static cell_t LoadTopMenuConfig(IPluginContext *pContext, const cell_t *params)
200 HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
202 if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu))
205 return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
208 char *file, *err_buf;
209 pContext->LocalToString(params[2], &file);
210 pContext->LocalToString(params[3], &err_buf);
212 char path[PLATFORM_MAX_PATH];
213 g_pSM->BuildPath(Path_Game, path, sizeof(path), "%s", file);
215 return pMenu->LoadConfiguration(path, err_buf, params[4]) ? 1 : 0;
218 static cell_t AddToTopMenu(IPluginContext *pContext, const cell_t *params)
222 HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
224 if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu))
227 return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
230 IPluginFunction *func = pContext->GetFunctionById(params[4]);
233 return pContext ->ThrowNativeError("Invalid function specified");
236 TopMenuCallbacks *cb = new TopMenuCallbacks(func);
238 char *name, *cmdname, *info_string = NULL;
239 pContext->LocalToString(params[2], &name);
240 pContext->LocalToString(params[6], &cmdname);
244 pContext->LocalToString(params[8], &info_string);
247 TopMenuObjectType obj_type = (TopMenuObjectType)params[3];
249 unsigned int object_id;
250 if ((object_id = pMenu->AddToMenu2(name,
253 pContext->GetIdentity(),
263 cb->m_hMenuHandle = params[1];
268 static cell_t RemoveFromTopMenu(IPluginContext *pContext, const cell_t *params)
272 HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
274 if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu))
277 return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
280 pMenu->RemoveFromMenu(params[2]);
285 static cell_t FindTopMenuCategory(IPluginContext *pContext, const cell_t *params)
289 HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
291 if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu))
294 return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
298 pContext->LocalToString(params[2], &name);
300 return pMenu->FindCategory(name);
303 static cell_t DisplayTopMenu(IPluginContext *pContext, const cell_t *params)
307 HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
309 if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu))
312 return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
315 int client = params[2];
316 IGamePlayer *player = playerhelpers->GetGamePlayer(client);
319 return pContext->ThrowNativeError("Invalid client index %d", client);
321 else if (!player->IsInGame())
323 return pContext->ThrowNativeError("Client %d is not in game", client);
326 return pMenu->DisplayMenu(client, 0, (TopMenuPosition)params[3]);
329 static cell_t GetTopMenuInfoString(IPluginContext *pContext, const cell_t *params)
333 HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
335 if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu))
338 return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
342 if ((str = pMenu->GetObjectInfoString(params[2])) == NULL)
344 return pContext->ThrowNativeError("Invalid menu object %d", params[2]);
348 pContext->LocalToString(params[3], &buffer);
350 return strncopy(buffer, str, params[4]);
353 static cell_t GetTopMenuName(IPluginContext *pContext, const cell_t *params)
357 HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
359 if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu))
362 return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
366 if ((str = pMenu->GetObjectName(params[2])) == NULL)
368 return pContext->ThrowNativeError("Invalid menu object %d", params[2]);
372 pContext->LocalToString(params[3], &buffer);
374 return strncopy(buffer, str, params[4]);
377 sp_nativeinfo_t g_TopMenuNatives[] =
379 {"AddToTopMenu", AddToTopMenu},
380 {"CreateTopMenu", CreateTopMenu},
381 {"DisplayTopMenu", DisplayTopMenu},
382 {"LoadTopMenuConfig", LoadTopMenuConfig},
383 {"RemoveFromTopMenu", RemoveFromTopMenu},
384 {"FindTopMenuCategory", FindTopMenuCategory},
385 {"GetTopMenuInfoString", GetTopMenuInfoString},
386 {"GetTopMenuObjName", GetTopMenuName},