Merge branch 'fix-menu-vote-handler'

This commit is contained in:
David Anderson 2021-12-09 18:13:30 -08:00
commit 351ac171d2
4 changed files with 50 additions and 100 deletions

View File

@ -69,13 +69,13 @@ void DebugReport::GenerateErrorVA(IPluginContext *ctx, cell_t func_idx, int err,
ke::SafeVsprintf(buffer, sizeof(buffer), message, ap); ke::SafeVsprintf(buffer, sizeof(buffer), message, ap);
const char *plname = pluginsys->FindPluginByContext(ctx->GetContext())->GetFilename(); const char *plname = pluginsys->FindPluginByContext(ctx->GetContext())->GetFilename();
const char *error = g_pSourcePawn2->GetErrorString(err);
if (error) if (err >= 0) {
{ const char *error = g_pSourcePawn2->GetErrorString(err);
g_Logger.LogError("[SM] Plugin \"%s\" encountered error %d: %s", plname, err, error); if (error)
} else { g_Logger.LogError("[SM] Plugin \"%s\" encountered error %d: %s", plname, err, error);
g_Logger.LogError("[SM] Plugin \"%s\" encountered unknown error %d", plname, err); else
g_Logger.LogError("[SM] Plugin \"%s\" encountered unknown error %d", plname, err);
} }
g_Logger.LogError("[SM] %s", buffer); g_Logger.LogError("[SM] %s", buffer);

View File

@ -47,6 +47,8 @@ public: // IDebugListener
void ReportError(const IErrorReport &report, IFrameIterator &iter); void ReportError(const IErrorReport &report, IFrameIterator &iter);
void OnDebugSpew(const char *msg, ...); void OnDebugSpew(const char *msg, ...);
public: public:
// If err is -1, caller assumes the automatic reporting by SourcePawn is
// good enough, and only wants the supplemental logging provided here.
void GenerateError(IPluginContext *ctx, cell_t func_idx, int err, const char *message, ...); void GenerateError(IPluginContext *ctx, cell_t func_idx, int err, const char *message, ...);
void GenerateErrorVA(IPluginContext *ctx, cell_t func_idx, int err, const char *message, va_list ap); void GenerateErrorVA(IPluginContext *ctx, cell_t func_idx, int err, const char *message, va_list ap);
void GenerateCodeError(IPluginContext *ctx, uint32_t code_addr, int err, const char *message, ...); void GenerateCodeError(IPluginContext *ctx, uint32_t code_addr, int err, const char *message, ...);

View File

@ -1,5 +1,5 @@
/** /**
* vim: set ts=4 : * vim: set ts=4 sw=4 tw=99 noet :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
@ -141,10 +141,6 @@ public:
void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style); void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style);
unsigned int OnMenuDisplayItem(IBaseMenu *menu, int client, IMenuPanel *panel, unsigned int item, const ItemDrawInfo &dr); unsigned int OnMenuDisplayItem(IBaseMenu *menu, int client, IMenuPanel *panel, unsigned int item, const ItemDrawInfo &dr);
bool OnSetHandlerOption(const char *option, const void *data); bool OnSetHandlerOption(const char *option, const void *data);
#if 0
void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style);
void OnMenuDisplayItem(IBaseMenu *menu, int client, unsigned int item, const char **display);
#endif
private: private:
cell_t DoAction(IBaseMenu *menu, MenuAction action, cell_t param1, cell_t param2, cell_t def_res=0); cell_t DoAction(IBaseMenu *menu, MenuAction action, cell_t param1, cell_t param2, cell_t def_res=0);
private: private:
@ -496,99 +492,51 @@ void CMenuHandler::OnMenuVoteResults(IBaseMenu *menu, const menu_vote_result_t *
unsigned int winning_votes = results->item_list[0].count; unsigned int winning_votes = results->item_list[0].count;
DoAction(menu, MenuAction_VoteEnd, winning_item, (total_votes << 16) | (winning_votes & 0xFFFF)); DoAction(menu, MenuAction_VoteEnd, winning_item, (total_votes << 16) | (winning_votes & 0xFFFF));
} else { return;
IPluginContext *pContext = m_pVoteResults->GetParentContext(); }
bool no_call = false;
int err;
/* First array */ IPluginContext *pContext = m_pVoteResults->GetParentContext();
cell_t client_array_address = -1; AutoEnterHeapScope heap_scope(pContext);
cell_t *client_array_base = NULL;
cell_t client_array_size = results->num_clients + (results->num_clients * 2); /* First array */
if (client_array_size) cell_t client_array_address = -1;
{ if (cell_t client_array_size = results->num_clients * 2) {
if ((err = pContext->HeapAlloc(client_array_size, &client_array_address, &client_array_base)) auto init = std::make_unique<cell_t[]>(client_array_size);
!= SP_ERROR_NONE) for (unsigned int i = 0; i < results->num_clients; i++) {
{ init[i * 2] = results->client_list[i].client;
g_DbgReporter.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for client list.", client_array_size * sizeof(cell_t)); init[i * 2 + 1] = results->client_list[i].item;
no_call = true;
} else {
cell_t target_offs = sizeof(cell_t) * results->num_clients;
cell_t *cur_index = client_array_base;
cell_t *cur_array;
for (unsigned int i=0; i<results->num_clients; i++)
{
/* Copy the array index */
*cur_index = target_offs;
/* Get the current array address */
cur_array = (cell_t *)((char *)cur_index + target_offs);
/* Store information */
cur_array[0] = results->client_list[i].client;
cur_array[1] = results->client_list[i].item;
/* Adjust for the new target by subtracting one indirection
* and adding one array.
*/
target_offs += (sizeof(cell_t) * 2) - sizeof(cell_t);
cur_index++;
}
}
} }
/* Second array */ if (!pContext->HeapAlloc2dArray(results->num_clients, 2, &client_array_address, init.get())) {
cell_t item_array_address = -1; g_DbgReporter.GenerateError(pContext, m_fnVoteResult, -1,
cell_t *item_array_base = NULL; "Menu callback could not allocate cells for client list.");
cell_t item_array_size = results->num_items + (results->num_items * 2); return;
if (item_array_size)
{
if ((err = pContext->HeapAlloc(item_array_size, &item_array_address, &item_array_base))
!= SP_ERROR_NONE)
{
g_DbgReporter.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for item list.", item_array_size);
no_call = true;
} else {
cell_t target_offs = sizeof(cell_t) * results->num_items;
cell_t *cur_index = item_array_base;
cell_t *cur_array;
for (unsigned int i=0; i<results->num_items; i++)
{
/* Copy the array index */
*cur_index = target_offs;
/* Get the current array address */
cur_array = (cell_t *)((char *)cur_index + target_offs);
/* Store information */
cur_array[0] = results->item_list[i].item;
cur_array[1] = results->item_list[i].count;
/* Adjust for the new target by subtracting one indirection
* and adding one array.
*/
target_offs += (sizeof(cell_t) * 2) - sizeof(cell_t);
cur_index++;
}
}
}
/* Finally, push everything */
if (!no_call)
{
m_pVoteResults->PushCell(menu->GetHandle());
m_pVoteResults->PushCell(results->num_votes);
m_pVoteResults->PushCell(results->num_clients);
m_pVoteResults->PushCell(client_array_address);
m_pVoteResults->PushCell(results->num_items);
m_pVoteResults->PushCell(item_array_address);
m_pVoteResults->Execute(NULL);
}
/* Free what we allocated, in reverse order as required */
if (item_array_address != -1)
{
pContext->HeapPop(item_array_address);
}
if (client_array_address != -1)
{
pContext->HeapPop(client_array_address);
} }
} }
/* Second array */
cell_t item_array_address = -1;
if (cell_t item_array_size = results->num_items * 2) {
auto init = std::make_unique<cell_t[]>(item_array_size);
for (unsigned int i = 0; i < results->num_items; i++) {
init[i * 2] = results->item_list[i].item;
init[i * 2 + 1] = results->item_list[i].count;
}
if (!pContext->HeapAlloc2dArray(results->num_items, 2, &item_array_address, init.get())) {
g_DbgReporter.GenerateError(pContext, m_fnVoteResult, -1,
"Menu callback could not allocate %d cells for item list.",
item_array_size);
return;
}
}
m_pVoteResults->PushCell(menu->GetHandle());
m_pVoteResults->PushCell(results->num_votes);
m_pVoteResults->PushCell(results->num_clients);
m_pVoteResults->PushCell(client_array_address);
m_pVoteResults->PushCell(results->num_items);
m_pVoteResults->PushCell(item_array_address);
m_pVoteResults->Execute(NULL);
} }
bool CMenuHandler::OnSetHandlerOption(const char *option, const void *data) bool CMenuHandler::OnSetHandlerOption(const char *option, const void *data)

@ -1 +1 @@
Subproject commit fa72b5ed2ace4022264a8de83695246256f8b939 Subproject commit 7cb5bede74c184b9b1de4dbf6b0bfc2d23c4a17e