void ValveMenuStyle::HookCreateMessage(edict_t *pEdict, DIALOG_TYPE type, KeyValues *kv, IServerPluginCallbacks *plugin) { if (type != DIALOG_MENU) { return; } int client = IndexOfEdict(pEdict); if (client < 1 || client > 256) { return; } CValveMenuPlayer *player = &m_players[client]; /* We don't care if the player is in a menu because, for all intents and purposes, * the menu is completely private. Instead, we just figure out the level we'll need * in order to override it. */ player->curPrioLevel = kv->GetInt("level", player->curPrioLevel); /* Oh no! What happens if we got a menu that overwrites ours?! */ if (player->bInMenu) { /* Okay, let the external menu survive for now. It may live another * day to avenge its grandfather, killed in the great Menu Interruption * battle. */ _CancelClientMenu(client, MenuCancel_Interrupted, true); } }
void BaseMenuStyle::ProcessWatchList() { if (!m_WatchList.size()) { return; } #if defined MENU_DEBUG g_Logger.LogMessage("BaseMenuStyle::ProcessWatchList(%d,%d,%d,%d,%d,%p)", m_WatchList.m_Size, m_WatchList.m_FirstLink, m_WatchList.m_FreeNodes, m_WatchList.m_LastLink, m_WatchList.m_MaxSize, m_WatchList.m_Nodes); #endif unsigned int total = 0; for (FastLink<int>::iterator iter=m_WatchList.begin(); iter!=m_WatchList.end(); ++iter) { do_lookup[total++] = (*iter); } #if defined MENU_DEBUG if (total) { g_Logger.LogMessage("[SM_MENU] ProcessWatchList() found %d clients", total); } #endif int client; CBaseMenuPlayer *player; float curTime = gpGlobals->curtime; for (unsigned int i=0; i<total; i++) { client = do_lookup[i]; player = GetMenuPlayer(client); #if defined MENU_DEBUG g_Logger.LogMessage("[SM_MENU] ProcessWatchList() (client %d) (bInMenu %d) (menuHoldTime %d) (curTime %f) (menuStartTime %f)", client, player->bInMenu, player->menuHoldTime, curTime, player->menuStartTime); #endif if (!player->bInMenu || !player->menuHoldTime) { #if defined MENU_DEBUG g_Logger.LogMessage("[SM_MENU] ProcessWatchList() removing client %d", client); #endif m_WatchList.remove(client); continue; } if (curTime > player->menuStartTime + player->menuHoldTime) { _CancelClientMenu(client, MenuCancel_Timeout, false); } } }
bool BaseMenuStyle::DoClientMenu(int client, IMenuPanel *menu, IMenuHandler *mh, unsigned int time) { #if defined MENU_DEBUG g_Logger.LogMessage("[SM_MENU] DoClientMenu() (client %d) (panel %p) (mh %p) (time %d)", client, menu, mh, time); #endif CPlayer *pPlayer = g_Players.GetPlayerByIndex(client); if (!pPlayer || pPlayer->IsFakeClient() || !pPlayer->IsInGame()) { return false; } CBaseMenuPlayer *player = GetMenuPlayer(client); if (player->bAutoIgnore) { return false; } /* For the duration of this, we are going to totally ignore whether * the player is already in a menu or not (except to cancel the old one). * Instead, we are simply going to ignore any further menu displays, so * this display can't be interrupted. */ player->bAutoIgnore = true; /* Cancel any old menus */ menu_states_t &states = player->states; if (player->bInMenu) { _CancelClientMenu(client, MenuCancel_Interrupted, true); } states.firstItem = 0; states.lastItem = 0; states.menu = NULL; states.mh = mh; states.apiVers = SMINTERFACE_MENUMANAGER_VERSION; player->bInMenu = true; player->bInExternMenu = false; player->menuStartTime = gpGlobals->curtime; player->menuHoldTime = time; if (time) { AddClientToWatch(client); } /* Draw the display */ SendDisplay(client, menu); /* We can be interrupted again! */ player->bAutoIgnore = false; return true; }
void BaseMenuStyle::OnClientDisconnected(int client) { #if defined MENU_DEBUG g_Logger.LogMessage("[SM_MENU] OnClientDisconnected(%d)", client); #endif CBaseMenuPlayer *player = GetMenuPlayer(client); if (!player->bInMenu) { return; } _CancelClientMenu(client, MenuCancel_Disconnected, true); player->bInMenu = false; player->bInExternMenu = false; }
void BaseMenuStyle::CancelMenu(CBaseMenu *menu) { #if defined MENU_DEBUG g_Logger.LogMessage("[SM_MENU] CancelMenu() (menu %p)", menu); #endif int maxClients = g_Players.GetMaxClients(); for (int i=1; i<=maxClients; i++) { CBaseMenuPlayer *player = GetMenuPlayer(i); if (player->bInMenu) { menu_states_t &states = player->states; if (states.menu == menu) { _CancelClientMenu(i, MenuCancel_Interrupted); } } } }
void CRadioStyle::OnUserMessageSent(int msg_id) { for (unsigned int i=0; i<g_last_client_count; i++) { int client = g_last_clients[i]; #if defined MENU_DEBUG g_Logger.LogMessage("[SM_MENU] CRadioStyle got ShowMenu (client %d) (bInMenu %d)", client, m_players[client].bInExternMenu); #endif if (m_players[client].bInMenu) { _CancelClientMenu(client, MenuCancel_Interrupted, true); } m_players[client].bInExternMenu = true; m_players[client].menuHoldTime = g_last_holdtime; } g_last_client_count = 0; }
bool BaseMenuStyle::CancelClientMenu(int client, bool autoIgnore) { #if defined MENU_DEBUG g_Logger.LogMessage("[SM_MENU] CancelClientMenu() (client %d) (bAutoIgnore %d)", client, autoIgnore); #endif if (client < 1 || client > g_Players.MaxClients()) { return false; } CBaseMenuPlayer *player = GetMenuPlayer(client); if (!player->bInMenu) { return false; } _CancelClientMenu(client, MenuCancel_Interrupted, autoIgnore); return true; }
bool BaseMenuStyle::DoClientMenu(int client, CBaseMenu *menu, unsigned int first_item, IMenuHandler *mh, unsigned int time) { #if defined MENU_DEBUG g_Logger.LogMessage("[SM_MENU] DoClientMenu() (client %d) (menu %p) (mh %p) (time %d)", client, menu, mh, time); #endif mh->OnMenuStart(menu); CPlayer *pPlayer = g_Players.GetPlayerByIndex(client); if (!pPlayer || pPlayer->IsFakeClient() || !pPlayer->IsInGame()) { #if defined MENU_DEBUG g_Logger.LogMessage("[SM_MENU] DoClientMenu(): Failed to display to client %d", client); #endif mh->OnMenuCancel(menu, client, MenuCancel_NoDisplay); mh->OnMenuEnd(menu, MenuEnd_Cancelled); return false; } CBaseMenuPlayer *player = GetMenuPlayer(client); if (player->bAutoIgnore) { #if defined MENU_DEBUG g_Logger.LogMessage("[SM_MENU] DoClientMenu(): Client %d is autoIgnoring", client); #endif mh->OnMenuCancel(menu, client, MenuCancel_NoDisplay); mh->OnMenuEnd(menu, MenuEnd_Cancelled); return false; } /* For the duration of this, we are going to totally ignore whether * the player is already in a menu or not (except to cancel the old one). * Instead, we are simply going to ignore any further menu displays, so * this display can't be interrupted. */ player->bAutoIgnore = true; /* Cancel any old menus */ menu_states_t &states = player->states; if (player->bInMenu) { #if defined MENU_DEBUG g_Logger.LogMessage("[SM_MENU] DoClientMenu(): Cancelling old menu to client %d", client); #endif _CancelClientMenu(client, MenuCancel_Interrupted, true); } states.firstItem = 0; states.lastItem = first_item; states.menu = menu; states.mh = mh; states.apiVers = SMINTERFACE_MENUMANAGER_VERSION; IMenuPanel *display = g_Menus.RenderMenu(client, states, ItemOrder_Ascending); if (!display) { #if defined MENU_DEBUG g_Logger.LogMessage("[SM_MENU] DoClientMenu(): Failed to render to client %d", client); #endif player->bAutoIgnore = false; player->bInMenu = false; mh->OnMenuCancel(menu, client, MenuCancel_NoDisplay); mh->OnMenuEnd(menu, MenuEnd_Cancelled); return false; } /* Finally, set our states */ player->bInMenu = true; player->bInExternMenu = false; player->menuStartTime = gpGlobals->curtime; player->menuHoldTime = time; if (time) { AddClientToWatch(client); } /* Draw the display */ SendDisplay(client, display); /* Free the display pointer */ display->DeleteThis(); /* We can be interrupted again! */ player->bAutoIgnore = false; #if defined MENU_DEBUG g_Logger.LogMessage("[SM_MENU] DoClientMenu() finished successfully (client %d)", client); #endif return true; }