public function onCompletion(Server $server)
 {
     $friends = [Session::FRIEND_LEVEL_NONE => [], Session::FRIEND_LEVEL_ACQUAINTANCE => [], Session::FRIEND_LEVEL_GOOD_FRIEND => [], Session::FRIEND_LEVEL_BEST_FRIEND => []];
     if ($this->session->getPlayer()->isOnline()) {
         $result = $this->getResult()["result"];
         foreach ($result as $row) {
             $type = $row["type"];
             $nick = array_filter(explode("|", $row["nicks"]))[0];
             $isOnline = $server->getPlayerExact($nick) instanceof Player;
             $class = $type & ~Session::FRIEND_BITMASK_REQUEST;
             $req = $type & Session::FRIEND_BITMASK_REQUEST;
             if ($isOnline) {
                 $nick = TextFormat::GREEN . "*" . TextFormat::WHITE . $nick;
             }
             if ($req === Session::FRIEND_IN) {
                 $nick .= TextFormat::GOLD . ">";
             } elseif ($req === Session::FRIEND_OUT) {
                 $nick .= TextFormat::DARK_AQUA . "<";
             }
             $nick .= TextFormat::WHITE;
             $friends[$class][] = $nick;
         }
         $this->session->send(Phrases::CMD_FRIEND_LIST_KEY);
         $this->session->sendCurlyLines();
         foreach ($friends as $class => $list) {
             $type = $this->session->translate(Session::$FRIEND_TYPES[$class]);
             $this->session->setMaintainedPopup(TextFormat::BLUE . $type . ": " . implode(TextFormat::WHITE . ":", $list));
         }
         $this->session->sendCurlyLines();
     }
 }
 public function censor(&$message)
 {
     $this->chatLog[] = new ChatLogEntry($message);
     if (count($this->chatLog) > 5) {
         array_shift($this->chatLog);
     }
     if (!$this->detectBadWords($message)) {
         return false;
     }
     $this->detectAds($message);
     if (count($this->chatLog) < 5) {
         return true;
     }
     $lengthSum = 0;
     foreach ($this->chatLog as $log) {
         $lengthSum += $log->length;
     }
     if ($lengthSum < 10) {
         $this->session->send(Phrases::CHAT_BLOCKED_TOO_SHORT);
         return false;
     }
     $cpm = $lengthSum / (microtime(true) - $this->chatLog[0]->time) * 60;
     if ($cpm > 200) {
         $this->session->send(Phrases::CHAT_BLOCKED_TOO_FAST, ["cpm" => $cpm]);
         return false;
     }
     if (microtime(true) - $this->chatLog[3]->time < 2) {
         $this->session->send(Phrases::CHAT_BLOCKED_TOO_FREQUENT);
         return false;
     }
     return true;
 }
 protected function run(array $args, Session $sender)
 {
     if (!isset($args[0])) {
         $lbl = $sender->getLoginDatum("lbl");
         $appr = $sender->getLoginDatum("lblappr");
         $sender->send(Phrases::CMD_LABEL_VIEW, ["label" => $lbl, "state" => self::$APPROVAL_LEVELS[$appr]]);
         return true;
     }
     $sender->send(Phrases::CMD_ERR_LOADING);
     new FetchLabelQuery($this->getPlugin(), $args[0], $sender);
     return true;
 }
 protected function run(array $args, Session $sender)
 {
     if (!isset($args[0])) {
         switch ($sender->getCurrentChatState()) {
             case Session::CHANNEL_LOCAL:
                 $sender->send(Phrases::CMD_CHANNEL_VIEW_LOCAL);
                 break;
             case Session::CHANNEL_TEAM:
                 $sender->send(Phrases::CMD_CHANNEL_VIEW_TEAM);
                 break;
             default:
                 $sender->send(Phrases::CMD_CHANNEL_VIEW_OTHER, ["chan" => $sender->getCurrentChatState()]);
         }
         return $sender->translate(Phrases::CMD_CHANNEL_VIEW_SUBSCRIBING_TO_CHANNELS, ["channels" => implode(", ", $sender->getChannelSubscriptions())]);
     }
     $name = array_shift($args);
     if (strtolower($name) === "local" or strtolower($name) === "g" or strtolower($name) === "l") {
         $sender->setCurrentChatState(Session::CHANNEL_LOCAL);
         return $sender->translate(Phrases::CMD_CHANNEL_SET_LOCAL);
     } elseif (strtolower($name) === "team" or strtolower($name) === "t") {
         if ($sender->getTeamId() === -1) {
             return $sender->translate(Phrases::CMD_TEAM_ERR_NOT_IN_TEAM);
         }
         $sender->setCurrentChatState(Session::CHANNEL_TEAM);
         return $sender->translate(Phrases::CMD_CHANNEL_SET_TEAM);
     } elseif (strtolower($name) === "quit") {
         if (!isset($args[0])) {
             return false;
         }
         $ch = array_shift($args);
         if (!$sender->isOnChannel($ch)) {
             return $sender->translate(Phrases::CMD_CHANNEL_QUIT_NOT_ON_CHANNEL);
         }
         $sender->partChannel($ch);
         return $sender->translate(Phrases::CMD_CHANNEL_QUIT_SUCCESS);
     } else {
         if (!$sender->isOnChannel($name)) {
             $sender->joinChannel($name);
             $sender->send(Phrases::CMD_CHANNEL_JOINED_SELF, ["channel" => $name]);
         }
         $sender->setCurrentChatState($name);
         return $sender->translate(Phrases::CMD_CHANNEL_SET_OTHER, ["chan" => $name]);
     }
 }
 protected function run(array $args, Session $sender)
 {
     if ($sender->getTeamId() !== -1) {
         return $sender->translate(Phrases::CMD_TEAM_ERR_ALREADY_IN_TEAM);
     }
     $name = array_shift($args);
     if ($name === null) {
         return false;
     }
     if (!preg_match('/^[A-Za-z0-9_]{5,}$/', $name)) {
         $sender->send(Phrases::CMD_TEAM_CREATE_INVALID_NAME);
         return true;
     }
     new CreateTeamQuery($this->getMain(), $sender->getUid(), $name);
     return $sender->translate(Phrases::CMD_TEAM_LOADING);
 }
 protected function run(array $args, Session $sender)
 {
     $lbl = func_get_arg(2);
     if (is_string($lbl) and $lbl !== "cg") {
         $sender->send(Phrases::CMD_GRIND_COIN_ADVICE);
     }
     if (!$sender->canStartGrind()) {
         return $sender->translate(Phrases::CMD_GRIND_COIN_CANNOT_START, ["time" => MUtils::time_secsToString($sender->getGrindWaitTime())]);
     }
     if (!$sender->confirmGrind) {
         $sender->confirmGrind = true;
         return $sender->translate(Phrases::CMD_GRIND_COIN_REQUEST_CONFIRM, ["length" => MUtils::time_secsToString(Settings::getGrindLength($sender->getRank())), "amplitude" => Settings::getGrindFactor($sender->getRank())]);
     }
     $sender->confirmGrind = false;
     $sender->startGrinding();
     return $sender->translate(Phrases::CMD_GRIND_COIN_STARTED);
 }
 public function detectBadWords($string)
 {
     $badWords = $this->session->getMain()->getBadWords();
     $string = preg_replace('#[^A-Za-z0-9]#i', "", $string);
     $string = str_replace("0", "o", $string);
     $string = str_replace("4", "a", $string);
     $string = str_replace("3", "e", $string);
     foreach ($badWords as $word) {
         if (($pos = stripos(str_replace("1", "i", $string), $word)) !== false or ($pos = stripos(str_replace("1", "l", $string), $word)) !== false) {
             $this->session->send(Phrases::CHAT_SWEAR_WARN, ["word" => $word]);
             $type = Hormone::get($this->session->getMain(), Hormone::CONSOLE_MESSAGE, "{BOT}SwearDetector", Phrases::VAR_notify2 . "Player {$this->session->getPlayer()->getName()}@" . Settings::$LOCALIZE_IP . ":" . Settings::$LOCALIZE_PORT . " said: " . substr($string, 0, $pos) . Phrases::VAR_em . substr($string, $pos, strlen($word)) . Phrases::VAR_notify2 . substr($string, $pos + strlen($word)), Settings::CLASS_ALL, ["ip" => Settings::$LOCALIZE_IP, "port" => Settings::$LOCALIZE_PORT]);
             $type->release();
             return false;
         }
     }
     return true;
 }
 protected function run(array $args, Session $sender)
 {
     $sender->send(Phrases::CMD_PRIV_MSG_REMIND_QUERY);
     $target = $this->getSession($name = array_shift($args));
     if ($target === null) {
         return $this->offline($sender, $name);
     }
     if (!isset($args[0])) {
         return false;
     }
     $message = implode(" ", $args);
     if (!$sender->getSpamDetector()->censor($message)) {
         return true;
     }
     $target->getPlayer()->sendMessage($msg = Phrases::VAR_info . "[" . $sender->getPlayer()->getName() . " > " . $target->getPlayer()->getName() . "] " . Phrases::VAR_info . $message);
     fwrite($this->getMain()->pmLog, "|from:{$sender->getPlayer()->getName()}|to:{$target->getPlayer()->getName()}|msg:{$message}|" . PHP_EOL);
     return $msg;
 }
 public function sendToSession(Session $session)
 {
     $session->send(Phrases::WARNING_MUTED_NOTIFICATION, ["length" => MUtils::time_secsToString($this->length), "since" => date($session->translate(Phrases::WORDS_DATE_FORMAT), $this->since), "till" => date($session->translate(Phrases::WORDS_DATE_FORMAT), $this->since + $this->length), "passed" => MUtils::time_secsToString(time() - $this->since), "left" => MUtils::time_secsToString($this->since + $this->length - time()), "issuer" => $this->src]);
 }
 /**
  * @param Session|CommandSender $sender
  * @param string|null $name
  * @return bool
  */
 protected function notOnline($sender, $name = null)
 {
     if ($sender instanceof Session) {
         if ($name === null) {
             $sender->send(Phrases::CMD_ERR_ABSENT_PLAYER_NAME_UNKNOWN);
         } else {
             $sender->send(Phrases::CMD_ERR_ABSENT_PLAYER_NAME_KNOWN, ["player" => $name]);
         }
         return true;
     }
     if ($sender instanceof CommandSender) {
         if ($sender instanceof Player and ($ses = $this->getSession($sender)) instanceof Session) {
             if ($name === null) {
                 $ses->send(Phrases::CMD_ERR_ABSENT_PLAYER_NAME_UNKNOWN);
             } else {
                 $ses->send(Phrases::CMD_ERR_ABSENT_PLAYER_NAME_KNOWN, ["player" => $name]);
             }
         } else {
             $sender->sendMessage(TextFormat::RED . "There is no player online with " . ($name === null ? "that name" : "the name {$name}") . ".");
         }
     }
     return true;
 }