не обрабатываются русские буквы в мкпе. Например пишу /mute test 10 тест причина отображается как будто я ничего не указал. в консоли также.
скриншот?
попробуй на англ причину написать
На английском всё работает
ща
еще такая же ■■■■■ в нике игрока может быть
что за плагин может поделишься кодом? или скинь файлом
<?php
namespace Bans;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\event\Listener;
use pocketmine\event\player\PlayerChatEvent;
use pocketmine\event\player\PlayerMoveEvent;
use pocketmine\event\player\PlayerPreLoginEvent;
use pocketmine\Player;
use pocketmine\plugin\PluginBase;
use pocketmine\scheduler\ClosureTask;
use pocketmine\utils\Config;
use function strlen;
use function strtolower;
use function array_shift;
use function implode;
use function preg_match;
use function time;
use function in_array;
use function substr;
class Main extends PluginBase implements Listener{
private $prefix, $bannedIp;
public $config;
private $banned;
private $muted;
private $freeze = [];
public function onEnable(){
$this->getServer()->getPluginManager()->registerEvents($this, $this);
$this->getScheduler()->scheduleRepeatingTask(new ClosureTask(function(int $currentTick) : void{
$this->cronTask();
}), 20);
@mkdir($this->getDataFolder());
@mkdir($this->getDataFolder() . "data/");
if(!file_exists($this->getDataFolder() . "config.yml")) file_put_contents($this->getDataFolder() . "config.yml", $this->getResource("config.yml"));
$this->muted = new Config($this->getDataFolder() . "data/muted.yml", Config::YAML);
$this->config = new Config($this->getDataFolder() . "config.yml", Config::YAML);
$this->banned = new Config($this->getDataFolder() . "data/banned.yml", Config::YAML);
$this->bannedIp = new Config($this->getDataFolder() . "data/banned-ip.yml", Config::YAML);
$this->prefix = $this->config->get("chat-prefix", "");
}
public function onJoin(PlayerPreLoginEvent $e){
$name = strtolower($e->getPlayer()->getName());
$ip = $e->getPlayer()->getAddress();
if($this->banned->exists($name)){
if($e->getPlayer()->hasPermission("virus.immunity")){
return;
}
$ban = $this->banned->get($name);
$timeLeft = $this->parseTime($ban['time']);
$e->setKickMessage("§fВы §bЗабанены! §fПричина: §c{$ban['reason']}\n§fВас забанил: §e{$ban['banby']} §fБан истекает: §a{$timeLeft}\n§fРазбан §9under.easydonate.ru");
$e->setCancelled(true);
}elseif($this->bannedIp->exists($ip)){
if($e->getPlayer()->hasPermission("virus.immunity")){
return;
}
$ban = $this->bannedIp->get($ip);
$timeLeft = $this->parseTime($ban['time']);
$e->setKickMessage("§fВы §bЗабанены по IP! §fПричина: §c{$ban['reason']}\n§fВас забанил: §e{$ban['banby']} §fБан истекает: §a{$timeLeft}\n§fРазбан §9under.easydonate.ru");
$e->setCancelled(true);
}
}
private function parseFlags(array &$args): array {
$flags = [
'silent' => false,
'sender' => null
];
foreach($args as $key => $arg){
if($arg === '-s'){
$flags['silent'] = true;
unset($args[$key]);
}elseif(strpos($arg, '--sender=') === 0){
$flags['sender'] = substr($arg, 9);
unset($args[$key]);
}
}
$args = array_values($args);
return $flags;
}
public function onCommand(CommandSender $sender, Command $command, $label, array $args){
$flags = $this->parseFlags($args);
switch($label){
case 'ban':
if(!$sender->hasPermission("virus.ban")){
$sender->sendMessage($this->prefix . " §fБан доступен от группы \"§eАдмин§c\" и выше!");
return;
}
if($sender instanceof Player && !$sender->hasPermission("ban.noCooldown")){
$diff = Main::isInCooldown($sender);
if($diff !== false){
$sender->sendMessage($this->prefix . "§cСледующая блокировка будет доступна через §6". $diff);
return;
}
}
if(count($args) < 2 || !preg_match("/^[0-9]+$/", $args[1])){
$sender->sendMessage("§7► §eИспользуйте§8: §b/ban (ник) (время) (причина)");
return;
}
$targetName = $args[0];
$banTime = (int)$args[1];
$pl = $this->getServer()->getPlayer($targetName);
if($pl !== null){
if($pl->hasPermission("virus.immunity")){
$sender->sendMessage($this->prefix . " §fВы не можете забанить игрока с данной группой");
return;
}
if(strtolower($sender->getName()) === $pl->getLowerCaseName()){
$sender->sendMessage($this->prefix . " §fВы не можете забанить самого себя!");
return;
}
}elseif(!$sender->hasPermission("bans.offline.ban")){
$sender->sendMessage($this->prefix ."§cТы не можешь забанить этого игрока, потому что он сейчас не онлайн!");
return;
}
if(!$sender->isOp() && ($banTime == 0 || $banTime > $this->config->get("maxban-time"))){
$sender->sendMessage($this->prefix . " §fНедопустимое время бана");
return;
}
if($sender instanceof Player && strtolower($targetName) == strtolower($sender->getName())){
$sender->sendMessage($this->prefix . " §fВы не можете забанить собственный аккаунт!");
return;
}
$banTime = $banTime != 0 ? time() + $banTime * 60 : 0;
$banBy = $sender instanceof Player ?
($flags['sender'] && $sender->hasPermission("bans.setsender") ? $flags['sender'] : $sender->getName()) :
($flags['sender'] ? $flags['sender'] : "SERVER");
$timeLeft = $this->parseTime($banTime);
if($this->banned->exists(strtolower($targetName))){
$sender->sendMessage($this->prefix . " §fИгрок уже находится в §cбане§r!");
return;
}
$reason = implode(" ", array_slice($args, 2));
$this->banned->set(strtolower($targetName), [
'reason' => $reason,
'time' => $banTime,
'banby' => $banBy
]);
$this->banned->save();
if($pl !== null){
$pl->kick("§fВы §bЗабанены! §fПричина: §c{$reason}\n§fВас забанил: §e{$banBy} §fБан истекает: §a{$timeLeft}\n§fРазбан §9undermarket.mcpetrade.ru", false);
}
if(!$flags['silent'] || $sender->hasPermission("bans.notify.silent")){
$message = $this->prefix . " §fИгрок §3{$targetName} §fбыл §cЗАБАНЕН§f!\n Причина: §e{$reason}\n §fЗабанил: §e{$banBy} \n§fБан истекает: §e{$timeLeft}\n§f{$this->prefix}";
if($flags['silent']){
foreach($this->getServer()->getOnlinePlayers() as $player){
if($player->hasPermission("bans.notify.silent")){
$player->sendMessage($message);
}
}
$this->getServer()->getLogger()->info($message);
}else{
$this->getServer()->broadcastMessage($message);
}
}
if($sender instanceof Player) Main::addCooldown($sender);
break;
case 'banip':
if(!$sender->hasPermission("virus.banip")){
$sender->sendMessage($this->prefix . " §fБан по айпи доступен от группы \"§eОператор§c\" и выше");
return;
}
if($sender instanceof Player && !$sender->hasPermission("ban.noCooldown")){
$diff = Main::isInCooldown($sender);
if($diff !== false){
$sender->sendMessage($this->prefix . "§cСледующая блокировка будет доступна через §6". $diff);
return;
}
}
if(count($args) < 2 || !preg_match("/^[0-9]+$/", $args[1])){
$sender->sendMessage("§7► §eИспользуйте§8: §b/banip (ник) (время) (причина)");
return;
}
$target = $args[0];
$banTime = (int)$args[1];
$pl = $this->getServer()->getPlayer($target);
if($pl !== null){
if($pl->hasPermission("virus.immunity")){
$sender->sendMessage($this->prefix . " §fВы не можете забанить игрока с данной группой!");
return;
}
if(strtolower($sender->getName()) === $pl->getLowerCaseName()){
$sender->sendMessage($this->prefix . " §fВы не можете забанить самого себя!");
return;
}
$ip = $pl->getAddress();
}elseif(preg_match("/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/", $target)){
$ip = $target;
}else{
$sender->sendMessage($this->prefix . " §fИгрока с веденным ником нет на сервере!");
return;
}
if(!$sender->isOp() && ($banTime == 0 || $banTime > $this->config->get("maxban-time"))){
$sender->sendMessage($this->prefix . " §fНедопустимое время бана");
return;
}
if($sender instanceof Player && strtolower($target) == strtolower($sender->getName())){
$sender->sendMessage($this->prefix . " §fВы не можете забанить свобственный аккаунт!");
return;
}
$banTime = $banTime != 0 ? time() + $banTime * 60 : 0;
$banBy = $sender instanceof Player ?
($flags['sender'] && $sender->hasPermission("bans.setsender") ? $flags['sender'] : $sender->getName()) :
($flags['sender'] ? $flags['sender'] : "SERVER");
$timeLeft = $this->parseTime($banTime);
$reason = implode(" ", array_slice($args, 2));
if($this->bannedIp->exists($ip)){
$sender->sendMessage($this->prefix . " §fIP игрока уже находится в бане!");
return;
}
$this->bannedIp->set($ip, [
'reason' => $reason,
'time' => $banTime,
'banby' => $banBy
]);
$this->bannedIp->save();
if($pl !== null){
$pl->kick("§fВы §bЗабанены по IP! §fПричина: §c{$reason}\n§fВас забанил: §e{$banBy} §fБан истекает: §a{$timeLeft}\n§fРазбан §9undermarket.mcpetrade.ru", false);
}
$message = $this->prefix . " §fIP §3{$ip} §fбыл §cЗАБАНЕН§f! §7| Причина: §e{$reason} §7| §fЗабанил: §e{$banBy} §7| §fБан истекает: §e{$timeLeft} ";
if($flags['silent'] && $sender->hasPermission("bans.silent")){
foreach($this->getServer()->getOnlinePlayers() as $player){
if($player->hasPermission("bans.notify.silent")){
$player->sendMessage($message);
}
}
$this->getServer()->getLogger()->info($message);
}else{
$this->getServer()->broadcastMessage($message);
}
if($sender instanceof Player) Main::addCooldown($sender);
break;
case 'unban':
if(!$sender->hasPermission("virus.pardon")){
$sender->sendMessage($this->prefix . " §fРазбан аккаунтов доступен от группы \"§eСоздатель§с\"!");
return;
}
if(count($args) !== 1){
$sender->sendMessage("§7► §eИспользуйте§8: §b/unban (ник) (причина)");
return;
}
$target = strtolower($args[0]);
$by = $sender instanceof Player ? $sender->getName() : "SERVER";
if($this->banned->exists($target)){
$this->banned->remove($target);
$this->banned->save();
$sender->sendMessage($this->prefix . " §fИгрок §3{$args[0]} §fбыл §aразбанен!");
}elseif($this->bannedIp->exists($target)){
$this->bannedIp->remove($target);
$this->bannedIp->save();
$sender->sendMessage($this->prefix . " §fIP §3{$args[0]} §fбыл §aразбанен!");
}else{
$sender->sendMessage($this->prefix . " §fИгрок/IP с веденным ником отсутствует в бан листе!");
}
break;
case 'banlist':
if(!$sender->hasPermission("virus.list")){
$sender->sendMessage($this->prefix . " §fПросмотр забаненых игроков доступен от группы \"§eОператор§c\" и выше");
return;
}
$banned = $this->banned->getAll();
$sender->sendMessage($this->prefix . " §fСписок забаненых");
foreach($banned as $key => $value){
$sender->sendMessage("§c{$key} §fПричина: §3{$value['reason']} §fЗабанил: §3{$value['banby']}");
}
break;
case 'kick':
if(!$sender->hasPermission("virus.kick")){
$sender->sendMessage($this->prefix . " §fКикать игроков доступно от группы \"§eМодератор§c\" и выше");
return;
}
if(count($args) < 2){
$sender->sendMessage("§7► §eИспользуйте§8: §b/kick (ник) (причина)");
return;
}
$targetName = $args[0];
$reason = implode(" ", array_slice($args, 1));
$player = $this->getServer()->getPlayer($targetName);
if($player === null){
$sender->sendMessage($this->prefix . " §fИгрок с веденным ником отсутствует на сервере!");
return;
}
$kickBy = $sender instanceof Player ?
($flags['sender'] && $sender->hasPermission("bans.setsender") ? $flags['sender'] : $sender->getName()) :
($flags['sender'] ? $flags['sender'] : "SERVER");
if($player->hasPermission("virus.immunity")){
$sender->sendMessage($this->prefix . " §fВы не можете кикнуть игрока с данной группой!");
return;
}
if(strtolower($sender->getName()) === $player->getLowerCaseName()){
$sender->sendMessage($this->prefix . " §fВы не можете кикнуть самого себя!");
return;
}
$player->kick($this->prefix . "§fВы §bКикнуты!\n§fПричина: §c{$reason}\n§fВас кикнул: §e{$kickBy}", false);
$message = $this->prefix . " §fИгрок §3{$player->getName()} §fбыл §cКикнут§f! §7| Причина: §e{$reason} §7| §fКикнул: §e{$kickBy}";
if($flags['silent'] && $sender->hasPermission("bans.silent")){
foreach($this->getServer()->getOnlinePlayers() as $p){
if($p->hasPermission("bans.notify.silent")){
$p->sendMessage($message);
}
}
$this->getServer()->getLogger()->info($message);
}else{
$this->getServer()->broadcastMessage($message);
}
break;
case 'mute':
if(!$sender->hasPermission("virus.mute")){
$sender->sendMessage($this->prefix . " §fМутить игроков доступно от группы \"§eМодератор§c\" и выше");
return;
}
if(count($args) < 2 || !preg_match("/^[0-9]+$/", $args[1])){
$sender->sendMessage("§7► §eИспользуйте§8: §b/mute (ник) (время) (причина)");
return;
}
$targetName = $args[0];
$muteTime = (int)$args[1];
$player = $this->getServer()->getPlayer($targetName);
if($player === null && !$sender->hasPermission("bans.offline.mute")){
$sender->sendMessage($this->prefix . " §fЭтот игрок оффлайн!");
return;
}
if($sender instanceof Player && strtolower($targetName) === strtolower($sender->getName())){
$sender->sendMessage($this->prefix . " §fВы не можете замутить самого себя!");
return;
}
$muteBy = $sender instanceof Player ?
($flags['sender'] && $sender->hasPermission("bans.setsender") ? $flags['sender'] : $sender->getName()) :
($flags['sender'] ? $flags['sender'] : "SERVER");
$reason = implode(" ", array_slice($args, 2));
if($muteTime <= 0 || $muteTime > $this->config->get("maxmute-time")){
$sender->sendMessage($this->prefix . " §fНе верно указано время мута!");
return;
}
if($player !== null && $player->hasPermission("virus.immunity")){
$sender->sendMessage($this->prefix . " §fВы не можете выдать мут игроку с данной группой!");
return;
}
$muteTime = time() + $muteTime * 60;
$timeLeft = $this->parseTime($muteTime);
$this->muted->set(strtolower($targetName), [
"time" => $muteTime,
"reason" => $reason,
"muteby" => $muteBy
]);
$this->muted->save();
$message = $this->prefix . " §fИгрок §3{$muteBy} §fзаткнул игрока §a{$targetName}! §f| Причина§6: {$reason} §7| Конец мута§e: {$timeLeft}";
if($flags['silent'] && $sender->hasPermission("bans.silent")){
foreach($this->getServer()->getOnlinePlayers() as $p){
if($p->hasPermission("bans.notify.silent")){
$p->sendMessage($message);
}
}
$this->getServer()->getLogger()->info($message);
}else{
$this->getServer()->broadcastMessage($message);
}
break;
case 'unmute':
if(!$sender->hasPermission("virus.unmute")){
$sender->sendMessage($this->prefix . " §fУ вас нет прав на использование этой комнды!");
return;
}
if(count($args) !== 1){
$sender->sendMessage("§7► §eИспользуйте§8: §b/unmute (ник)");
return;
}
$targetName = strtolower($args[0]);
$by = $sender instanceof Player ? $sender->getName() : "SERVER";
if($this->muted->exists($targetName)){
$this->muted->remove($targetName);
$this->muted->save();
$this->getServer()->broadcastMessage($this->prefix . " §fИгрок: §3{$by} §fудалил мут игрока §3{$args[0]}!");
}else{
$sender->sendMessage($this->prefix . " §fЭтого игрока не затыкали!");
}
break;
}
}
public function onMove(PlayerMoveEvent $ev){
if(in_array(strtolower($ev->getPlayer()->getName()), $this->freeze)){
$ev->setCancelled();
$ev->getPlayer()->sendMessage($this->prefix . "§fВы §cзаморожены");
}
}
public function onMute(PlayerChatEvent $e){
$p = $e->getPlayer();
$name = strtolower($p->getName());
$muted = $this->muted->getAll();
if(isset($muted[$name])){
$e->setCancelled();
$timeLeft = $this->parseTime($muted[$name]['time'] ?? 1);
$p->sendMessage($this->prefix . " §fВаш чат заблокирован! §7| Конец мута: {$timeLeft}");
}
}
private function parseTime($time): string
{
switch($time){
case '0':
return "Никогда";
default:
$now = time();
$left = ($time - $now);
$seconds = $left % 60;
$minutes = (int)($left / 60);
if($minutes >= 60){
$hours = (int)($minutes / 60);
$minutes = $minutes % 60;
}
if(@$hours >= 24){
$days = (int)($hours / 24);
$hours = $hours % 24;
}
$timeLeft = $seconds . "с.";
$timeLeft = $minutes . "м. " . $timeLeft;
if(isset($hours)) $timeLeft = $hours . "ч. " . $timeLeft;
if(isset($days)) $timeLeft = $days . "д. " . $timeLeft;
return "Через " . $timeLeft;
}
}
public function cronTask(): void
{
$banned = $this->banned->getAll();
foreach($banned as $key => $value){
if(time() >= $value['time'] && $value['time'] != 0) $this->banned->remove($key);
}
$this->banned->save();
$bannedIp = $this->bannedIp->getAll();
foreach($bannedIp as $key => $value){
if(time() >= $value['time'] && $value['time'] != 0) $this->bannedIp->remove($key);
}
$this->bannedIp->save();
$muted = $this->muted->getAll();
foreach($muted as $key => $value){
if(time() >= $value['time']) $this->muted->remove($key);
}
$this->muted->save();
}
/** by @mishkashulman */
/** @var int */
const COOLDOWN = 600; //seconds
/** @var array */
private static array $cooldown = [];
/**
* @param Player $player
* @return string|false
*/
public static function isInCooldown(Player $player): bool|string
{
$currentTime = time();
if(isset(self::$cooldown[$playerName = $player->getName()]) && self::$cooldown[$playerName] > $currentTime){
$diff = self::$cooldown[$playerName] - $currentTime;
$timeLeft = function() use ($diff) : string{
$minutes = (int)($diff / 60);
$diff = $diff - $minutes * 60;
$seconds = (int)$diff;
$result = "";
$array = [$minutes => "м.", $seconds => "с."];
foreach($array as $key => $value){
if($key > 0){
$result .= $key . " " . $value . " ";
}
}
return strlen($result) > 0 ? substr($result, 0, -1) : false;
};
return $timeLeft();
}
return false;
}
public static function addCooldown(Player $player): void
{
self::$cooldown[$player->getName()] = time() + Main::COOLDOWN;
}
/** by @mishkashulman */
}
private function parseTime($time): string
{
switch ($time) {
case '0':
return "Никогда";
default:
$now = time();
$left = $time - $now;
$days = floor($left / 86400);
$left %= 86400;
$hours = floor($left / 3600);
$left %= 3600;
$minutes = floor($left / 60);
$seconds = $left % 60;
$parts = [];
if ($days > 0) {
$parts[] = "$days д.";
}
if ($hours > 0) {
$parts[] = "$hours ч.";
}
if ($minutes > 0) {
$parts[] = "$minutes м.";
}
if ($seconds > 0 || empty($parts)) {
$parts[] = "$seconds с.";
}
return "Через " . implode(" ", $parts);
}
}
ничего не понятно
и почему $time передаётся как строка?
расставь var_dump
чтобы проверить $args
. Если там русские напрочь вырезаюся, значит твоё ядро хуuня дранная
Это такой баг на виндусе
Изменено: да ладно я знаю что не баг, я просто даун и так объяснить легче
Да это не баг, а кодировка
Потому что я так посчитал нужным
Я свои ставки ставлю на ядро. Если это был бы бинарик или винда, то весь русский язык бы пошел к чертям. Наверное ядро при обработке команды что-то ломает в процессе (или где-то preg_match
стоит)
Решение простое. Измени кодировку файла на UTF-8, у тебя скорее всего стоит GB18030.
utf-8 стоит
Повторюсь ещё раз. Замени ядро, и напиши, осталось ли проблема.