final function run() { try { $this->init(); Dispatcher::dispatch(new Event(Event::ON_RUN)); self::$startTime = microtime(true); $nextCycleStart = self::$startTime; $cycleTime = 1 / static::CYCLES_PER_SECOND; } catch (\Exception $e) { ErrorHandling::processRuntimeException($e); } try { while ($this->running) { Dispatcher::dispatch(new Event(Event::ON_PRE_LOOP)); $calls = $this->connection->executeCallbacks(); if (!empty($calls)) { foreach ($calls as $call) { $method = preg_replace('/^[[:alpha:]]+\\./', '', $call[0]); // remove trailing "Whatever." $params = (array) $call[1]; Dispatcher::dispatch(new \ManiaLive\DedicatedApi\Callback\Event($method, $params)); } } $this->connection->executeMulticall(); Dispatcher::dispatch(new Event(Event::ON_POST_LOOP)); $endCycleTime = microtime(true) + $cycleTime / 10; do { $nextCycleStart += $cycleTime; } while ($nextCycleStart < $endCycleTime); @time_sleep_until($nextCycleStart); } } catch (\Exception $e) { ErrorHandling::processRuntimeException($e); } Dispatcher::dispatch(new Event(Event::ON_TERMINATE)); }
function onPreLoop() { // If server is stopped, we don't need to send manialinks if (Storage::getInstance()->serverStatus->code <= Status::LAUNCHING) { return; } // Before loops (stopping if too soon) $startTime = microtime(true); if ($startTime < $this->nextLoop) { return; } $stackByPlayer = array(); $playersOnServer = array_merge(array_keys(Storage::getInstance()->players), array_keys(Storage::getInstance()->spectators)); $playersHidingGui = array_keys(array_filter($this->hidingGui)); $playersShowingGui = array_intersect(array_diff(array_keys($this->hidingGui), $playersHidingGui), $playersOnServer); // First loop to prepare player stacks foreach ($this->nextWindows as $windowId => $visibilityByLogin) { $showing = array_intersect(array_diff(array_keys(array_filter($visibilityByLogin)), $playersHidingGui), $playersOnServer); $hiding = array_intersect(array_diff(array_keys($visibilityByLogin), $showing, $playersHidingGui), $playersOnServer); if (count($showing)) { sort($showing); $stackByPlayer[implode(',', $showing)][] = $visibilityByLogin[reset($showing)]; } if (count($hiding)) { sort($hiding); $stackByPlayer[implode(',', $hiding)][] = $windowId; } } // Second loop to add modals and regroup identical custom UIs $loginsByDiff = array(); $customUIsByDiff = array(); foreach ($playersShowingGui as $login) { $modal = $this->getNextModal($login); if ($modal) { $stackByPlayer[$login][] = self::NEXT_IS_MODAL; $stackByPlayer[$login][] = $modal; $this->modalShown[$login] = $modal; } $customUI = CustomUI::Create($login); $diff = $customUI->getDiff(); if ($diff) { $loginsByDiff[$diff][] = $login; $customUIsByDiff[$diff][] = $customUI; } } // Third loop to add custom UIs foreach ($loginsByDiff as $diff => $logins) { $stackByPlayer[implode(',', $logins)][] = $customUIsByDiff[$diff]; } // Final loop to send manialinks $nextIsModal = false; foreach ($stackByPlayer as $login => $data) { Manialinks::load(); foreach ($data as $toDraw) { if ($nextIsModal) { $this->drawModal($toDraw); $nextIsModal = false; } else { if ($toDraw === self::NEXT_IS_MODAL) { // special delimiter for modals $nextIsModal = true; } else { if (is_string($toDraw)) { // a window's id alone means it has to be hidden $this->drawHidden($toDraw); } else { if (is_array($toDraw)) { array_shift($toDraw)->save(); foreach ($toDraw as $customUI) { $customUI->hasBeenSaved(); } } else { $this->drawWindow($toDraw); } } } } } $this->connection->sendDisplayManialinkPage((string) $login, Manialinks::getXml(), 0, false, true); } $this->connection->executeMulticall(); // Merging windows and deleting hidden ones to keep clean the current state foreach ($this->nextWindows as $windowId => $visibilityByLogin) { if (isset($this->currentWindows[$windowId])) { $newCurrent = array_filter(array_merge($this->currentWindows[$windowId], $visibilityByLogin)); } else { $newCurrent = array_filter($visibilityByLogin); } if ($newCurrent) { $this->currentWindows[$windowId] = $newCurrent; } else { unset($this->currentWindows[$windowId]); } } $this->nextWindows = array(); // After loops $endTime = microtime(true); do { $this->nextLoop += 0.2; } while ($this->nextLoop < $endTime); // Profiling $this->sendingTimes[] = $endTime - $startTime; if (count($this->sendingTimes) >= 10) { $this->averageSendingTimes = array_sum($this->sendingTimes) / count($this->sendingTimes); $this->sendingTimes = array(); } }