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(); } }