bool TypeDir::removeDir(const TypeDir &dir) { enterCritical(); auto it = std::find(m_dirs.begin(), m_dirs.end(), dir); if (it == m_dirs.end()) { leaveCritical(); return false; } m_dirs.erase(it); leaveCritical(); return true; }
bool TypeDir::removeFile(const TypeFile &file) { enterCritical(); auto it = std::find(m_files.begin(), m_files.end(), file); if (it == m_files.end()) { leaveCritical(); return false; } m_files.erase(it); leaveCritical(); return true; }
bool TypeDir::replaceFile(const TypeFile &oldfile, const TypeFile &newfile) { enterCritical(); auto it = std::find(m_files.begin(), m_files.end(), oldfile); if (it == m_files.end()) { leaveCritical(); return false; } m_files.erase(it); m_files.insert(newfile); leaveCritical(); return true; }
const TypeFile *TypeDir::file(const std::string &name) const { enterCritical(); auto it = std::find(m_files.begin(), m_files.end(), name); leaveCritical(); if (it == m_files.end()) return nullptr; return &*it; }
// Repeatedly read input from the input slot. // Returns when last player exits game. void GameServer::run() { DWORD nNextMessageSize, nMessagesLeft, nBytesRead; InputData idMessage; char szBuffer[245]; // Call randomize() in the GameServer's operational thread (usually same thread as main()) myRandomize(); while ( true ) { nMessagesLeft = 0; nNextMessageSize = MAILSLOT_NO_MESSAGE; // Check the status of the slot. GetMailslotInfo(hInputSlot, NULL, &nNextMessageSize, &nMessagesLeft, NULL); // If there's no input, sleep and then return to top of loop. if ( nNextMessageSize == MAILSLOT_NO_MESSAGE ) { Sleep(100); continue; } // If there's a message, read it and process it. if ( nMessagesLeft > 0 ) { // Ignore invalid message sizes (see MS Knowledge Base Q192276) if ( nNextMessageSize < 0 || nNextMessageSize > 500 ) continue; ReadFile(hInputSlot, szBuffer, nNextMessageSize, &nBytesRead, NULL); idMessage = szBuffer; enterCritical(); handleInput(idMessage); leaveCritical(); // If last player just exited, shut down the server. if ( idMessage.nType == IP_FINISHED && nPlayersInGame == 0 ) { CloseHandle(hInputSlot); DeleteCriticalSection(&csCritical); return; } } } }
void TypeDir::addFile(const TypeFile &file) { enterCritical(); m_files.insert(file); leaveCritical(); }
void TypeDir::addDir(const TypeDir &dir) { enterCritical(); m_dirs.insert(dir); leaveCritical(); }
// Processes input messages and redirects them to the proper node thread. void GameServer::handleInput(InputData idMessage) { // If message is from a totally out-of-range node number, ignore it. if ( idMessage.nFrom < 0 || idMessage.nFrom >= MAX_NODE ) return; // If an enter-game message: if ( idMessage.nType == IP_ENTER_GAME ) { if ( gNode[idMessage.nFrom] != NULL ) { gNode[idMessage.nFrom]->print("Error: Node already in game. Please wait 5 seconds and re-enter game."); gNode[idMessage.nFrom]->exitGame(); return; } // Create the new node and then return. Start round thread if needed. Verify the player isn't a dupe. nPlayersInGame++; addNode(idMessage.nFrom, idMessage.szMessage); if ( nPlayersInGame == 1 ) _beginthread(startRoundThread, 4096, this); for ( short n = 0; n < MAX_NODE; n++ ) { if ( gNode[n] == NULL || n == idMessage.nFrom ) continue; if ( strcmpi(gNode[n]->szRealName, gNode[idMessage.nFrom]->szRealName) == 0 ) { gNode[idMessage.nFrom]->print("You are on-line on multiple nodes!\r\nPlease wait 5 seconds and re-enter the game."); gNode[n]->print("You are on-line on multiple nodes!\r\nPlease wait 5 seconds and re-enter the game."); gNode[idMessage.nFrom]->exitGame(); gNode[n]->exitGame(); } } return; } // If input is from an invalid node, ignore it. if ( gNode[idMessage.nFrom] == NULL ) return; // If an exit-game message: if ( idMessage.nType == IP_FINISHED ) { // Kill the node. If the node has a thread, wait until the // thread is terminated (by a IP_FORCE_EXIT) before proceeding. while ( gNode[idMessage.nFrom]->bHasThread ) { leaveCritical(); Sleep(200); enterCritical(); } CloseHandle(gNode[idMessage.nFrom]->hOutputSlot); delete gNode[idMessage.nFrom]; gNode[idMessage.nFrom] = NULL; nPlayersInGame--; return; } // Otherwise, message is IP_NORMAL or IP_FORCE_EXIT. In either case, route the // InputData to the appropriate node, and let the node's thread take care of it. // If not using separate threads for each node, have an outside function handle // the message instead. if ( gNode[idMessage.nFrom]->bHasThread ) gNode[idMessage.nFrom]->mqInput.enqueue(idMessage); else centralInput(idMessage); }