Skip to content

Commit

Permalink
fix fuzzy search of nicknames
Browse files Browse the repository at this point in the history
  • Loading branch information
reaby committed Jun 28, 2019
1 parent 8d490dd commit 8fd3e73
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 28 deletions.
1 change: 1 addition & 0 deletions composer.json
Expand Up @@ -3,6 +3,7 @@
"php" : "^7.2",
"ext-json" : "*",
"ext-simplexml" : "*",
"ext-mbstring" : "*",
"maniaplanet/dedicated-server-api": "^5.0",
"illuminate/database" : "^5.5",
"symfony/console" : "^4.0",
Expand Down
2 changes: 1 addition & 1 deletion core/Commands/AddAdmin.php
Expand Up @@ -80,7 +80,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$server = Connection::factory(
config('server.ip'),
config('server.port'),
5,
2,
config('server.rpc.login'),
config('server.rpc.password')
);
Expand Down
92 changes: 65 additions & 27 deletions core/Controllers/PlayerController.php
Expand Up @@ -30,6 +30,9 @@ class PlayerController implements ControllerInterface
*/
private static $players;

/** @var int */
private static $stringEditDistanceThreshold = 8;

/**
* Initialize PlayerController
*/
Expand Down Expand Up @@ -64,9 +67,9 @@ public static function init()
}

/**
* @param Player $player
* @param string $cmd
* @param string $pw
* @param Player $player
* @param string $cmd
* @param string $pw
*/
public static function setServerPassword(Player $player, $cmd, $pw)
{
Expand All @@ -75,15 +78,15 @@ public static function setServerPassword(Player $player, $cmd, $pw)
infoMessage($player, ' cleared the server password.')->sendAll();
} else {
infoMessage($player, ' set a server password.')->sendAll();
infoMessage($player, ' set a server password to "' . $pw . '".')->sendAdmin();
infoMessage($player, ' set a server password to "'.$pw.'".')->sendAdmin();
}
}
}

/**
* Called on PlayerConnect
*
* @param Player $player
* @param Player $player
*
* @throws \Exception
*/
Expand Down Expand Up @@ -123,7 +126,7 @@ public static function playerConnect(Player $player)
/**
* Called on PlayerDisconnect
*
* @param Player $player
* @param Player $player
*
* @throws \Exception
*/
Expand All @@ -132,7 +135,7 @@ public static function playerDisconnect(Player $player)
$diff = $player->last_visit->diffForHumans();
$playtime = substr($diff, 0, -4);
Log::logAddLine('PlayerController',
$player . " [" . $player->Login . "] left the server after $playtime playtime.");
$player." [".$player->Login."] left the server after $playtime playtime.");
$message = infoMessage($player, ' left the server after ', secondary($playtime), ' playtime.')->setIcon('');

if (config('server.echoes.leave')) {
Expand All @@ -152,7 +155,7 @@ public static function playerDisconnect(Player $player)
/**
* Reset player ids on begin map
*
* @param Map $map
* @param Map $map
*/
public static function beginMap(Map $map)
{
Expand All @@ -165,19 +168,29 @@ public static function beginMap(Map $map)
/**
* Gets a player by nickname or login.
*
* @param Player $callee
* @param string $nick
* @param Player $callee
* @param string $nick
*
* @return Player|null
*/
public static function findPlayerByName(Player $callee, $nick): ?Player
{
$players = onlinePlayers()->filter(function (Player $player) use ($nick) {
if ($player->Login == $nick) {
$online = onlinePlayers();
$nicknamesByLogin = [];

foreach ($online->all() as $player) {
$nicknamesByLogin[$player->Login] = stripAll($player->NickName);
};

$fuzzyLogin = self::findClosestMatchingString($nick, $nicknamesByLogin);
Log::getOutput()->writeln(print_r($nicknamesByLogin, true));

$players = $online->filter(function (Player $player) use ($nick, $fuzzyLogin) {
if ($player->Login == $nick || ($fuzzyLogin !== null && $player->Login == $fuzzyLogin)) {
return true;
}

return strpos(stripAll(strtolower($player)), strtolower($nick)) !== false;
return false;
});


Expand All @@ -188,7 +201,7 @@ public static function findPlayerByName(Player $callee, $nick): ?Player
}

if ($players->count() > 1) {
warningMessage('Found more than one person (' . $players->pluck('NickName')->implode(', ') . '), please be more specific or use login.')->send($callee);
warningMessage('Found more than one person ('.$players->pluck('NickName')->implode(', ').'), please be more specific or use login.')->send($callee);

return null;
}
Expand All @@ -199,10 +212,10 @@ public static function findPlayerByName(Player $callee, $nick): ?Player
/**
* Kick a player.
*
* @param Player $player
* @param Player $player
* @param $cmd
* @param $nick
* @param mixed ...$message
* @param mixed ...$message
*/
public static function kickPlayer(Player $player, $cmd, $nick, ...$message)
{
Expand All @@ -218,17 +231,17 @@ public static function kickPlayer(Player $player, $cmd, $nick, ...$message)
warningMessage($player, ' kicked ', $playerToBeKicked, '. Reason: ',
secondary($reason))->setIcon('')->sendAll();
} catch (InvalidArgumentException $e) {
Log::logAddLine('PlayerController', 'Failed to kick player: ' . $e->getMessage(), true);
Log::logAddLine('PlayerController', '' . $e->getTraceAsString(), false);
Log::logAddLine('PlayerController', 'Failed to kick player: '.$e->getMessage(), true);
Log::logAddLine('PlayerController', ''.$e->getTraceAsString(), false);
}
}

/**
* ManiaLinkEvent: kick player
*
* @param Player $player
* @param string $login
* @param string $reason
* @param Player $player
* @param string $login
* @param string $reason
*/
public static function kickPlayerEvent(Player $player, $login, $reason = "")
{
Expand All @@ -250,7 +263,7 @@ public static function kickPlayerEvent(Player $player, $login, $reason = "")

if (strlen($reason) > 0) {
warningMessage($player, ' kicked ', secondary($toBeKicked),
secondary(' Reason: ' . $reason))->setIcon('')->sendAll();
secondary(' Reason: '.$reason))->setIcon('')->sendAll();
} else {
warningMessage($player, ' kicked ', secondary($toBeKicked))->setIcon('')->sendAll();
}
Expand All @@ -259,7 +272,7 @@ public static function kickPlayerEvent(Player $player, $login, $reason = "")
/**
* Called on players finish
*
* @param Player $player
* @param Player $player
* @param $score
*/
public static function playerFinish(Player $player, $score)
Expand All @@ -275,7 +288,7 @@ public static function playerFinish(Player $player, $score)
if ($score > 0) {
$player->Score = $score;
$player->save();
Log::info($player . " finished with time ($score) " . $player->getTime());
Log::info($player." finished with time ($score) ".$player->getTime());
}
}

Expand All @@ -288,7 +301,7 @@ public static function getPlayers(): Collection
}

/**
* @param string $login
* @param string $login
*
* @return bool
*/
Expand All @@ -298,7 +311,7 @@ public static function hasPlayer(string $login)
}

/**
* @param string $login
* @param string $login
*
* @return Player
*/
Expand All @@ -308,12 +321,37 @@ public static function getPlayer(string $login): Player
}

/**
* @param Player $player
* @param Player $player
*
* @return Collection
*/
public static function addPlayer(Player $player)
{
return self::$players->put($player->Login, $player);
}


private static function findClosestMatchingString(string $search, array $array)
{
$closestDistanceThusFar = self::$stringEditDistanceThreshold + 1;
$closestMatchValue = null;

foreach ($array as $key => $value) {
$editDistance = levenshtein($value, $search);

Log::getOutput()->writeln($editDistance);

// exact match
if ($editDistance == 0) {
return $key;

} elseif ($editDistance <= $closestDistanceThusFar) {
$closestDistanceThusFar = $editDistance;
$closestMatchValue = $key;
}
}

return $closestMatchValue; // possible to return null if threshold hasn't been met
}

}

0 comments on commit 8fd3e73

Please sign in to comment.