add ClimbTheMap plugin
This commit is contained in:
parent
3c79f09c77
commit
676c03847a
7
.gitignore
vendored
7
.gitignore
vendored
@ -6,11 +6,12 @@
|
||||
!MatchManagerSuite/*
|
||||
!Beu
|
||||
!Beu/AFKNotifier.php
|
||||
!Beu/BeuDonationButton.php
|
||||
!Beu/ChatAdminColorer.php
|
||||
!Beu/ReloadDevTool.php
|
||||
!Beu/ClimbTheMap.php
|
||||
!Beu/GameModeLoader.php
|
||||
!Beu/GuestlistManager.php
|
||||
!Beu/MoreModesTools.php
|
||||
!Beu/ReloadDevTool.php
|
||||
!Beu/SimpleChatColorer.php
|
||||
!Beu/SimpleSkinsRemover.php
|
||||
!Beu/BeuDonationButton.php
|
||||
!Beu/GameModeLoader.php
|
374
Beu/ClimbTheMap.php
Normal file
374
Beu/ClimbTheMap.php
Normal file
@ -0,0 +1,374 @@
|
||||
<?php
|
||||
namespace Beu;
|
||||
|
||||
use FML\Controls\Frame;
|
||||
use FML\Controls\Quads\Quad_BgsPlayerCard;
|
||||
use FML\ManiaLink;
|
||||
use FML\Script\Features\Paging;
|
||||
use ManiaControl\ManiaControl;
|
||||
use ManiaControl\Plugins\Plugin;
|
||||
use ManiaControl\Players\PlayerManager;
|
||||
use ManiaControl\Callbacks\CallbackListener;
|
||||
use ManiaControl\Callbacks\Callbacks;
|
||||
use ManiaControl\Commands\CommandListener;
|
||||
use ManiaControl\Manialinks\LabelLine;
|
||||
use ManiaControl\Manialinks\ManialinkManager;
|
||||
use ManiaControl\Players\Player;
|
||||
use ManiaControl\Callbacks\TimerListener;
|
||||
|
||||
|
||||
use ManiaControl\Manialinks\ManialinkPageAnswerListener;
|
||||
use ManiaControl\Maps\Map;
|
||||
|
||||
/**
|
||||
* ClimbTheMap
|
||||
*
|
||||
* @author Beu
|
||||
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
|
||||
*/
|
||||
class ClimbTheMap implements ManialinkPageAnswerListener, TimerListener, CommandListener, CallbackListener, Plugin {
|
||||
/*
|
||||
* Constants
|
||||
*/
|
||||
const PLUGIN_ID = 192;
|
||||
const PLUGIN_VERSION = 1.0;
|
||||
const PLUGIN_NAME = 'ClimbTheMap';
|
||||
const PLUGIN_AUTHOR = 'Beu';
|
||||
|
||||
const DB_CLIMBTHEMAP = "ClimbTheMap";
|
||||
|
||||
const MLID_ALTITUDE_RECORDS = "ClimbTheMap.AltitudeRecords";
|
||||
|
||||
// Callbacks
|
||||
const CB_UPDATEPBS = 'Trackmania.ClimbTheMap.UpdatePBs';
|
||||
|
||||
// Methods
|
||||
const M_SETPLAYERSPB = 'Trackmania.ClimbTheMap.SetPlayersPB';
|
||||
const M_SETWR = 'Trackmania.ClimbTheMap.SetWR';
|
||||
|
||||
// Actions
|
||||
const A_SHOW_ALTITUDE_RECORDS = 'Trackmania.ClimbTheMap.ShowAltitudeRecords';
|
||||
|
||||
|
||||
/*
|
||||
* Private properties
|
||||
*/
|
||||
/** @var ManiaControl $maniaControl */
|
||||
private $maniaControl = null;
|
||||
private $manialink = "";
|
||||
private $wraltitude = 0;
|
||||
|
||||
/**
|
||||
* @see \ManiaControl\Plugins\Plugin::prepare()
|
||||
*/
|
||||
public static function prepare(ManiaControl $maniaControl) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \ManiaControl\Plugins\Plugin::getId()
|
||||
*/
|
||||
public static function getId() {
|
||||
return self::PLUGIN_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \ManiaControl\Plugins\Plugin::getName()
|
||||
*/
|
||||
public static function getName() {
|
||||
return self::PLUGIN_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \ManiaControl\Plugins\Plugin::getVersion()
|
||||
*/
|
||||
public static function getVersion() {
|
||||
return self::PLUGIN_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \ManiaControl\Plugins\Plugin::getAuthor()
|
||||
*/
|
||||
public static function getAuthor() {
|
||||
return self::PLUGIN_AUTHOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \ManiaControl\Plugins\Plugin::getDescription()
|
||||
*/
|
||||
public static function getDescription() {
|
||||
return "[TM2020 only] Used to save the altitude record";
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \ManiaControl\Plugins\Plugin::load()
|
||||
*/
|
||||
public function load(ManiaControl $maniaControl) {
|
||||
$this->maniaControl = $maniaControl;
|
||||
|
||||
$this->initTables();
|
||||
|
||||
$this->maniaControl->getCallbackManager()->registerCallbackListener(Callbacks::AFTERINIT, $this, 'handleAfterInit');
|
||||
$this->maniaControl->getCallbackManager()->registerCallbackListener(Callbacks::MP_STARTROUNDSTART, $this, 'handleStartRound');
|
||||
$this->maniaControl->getCallbackManager()->registerCallbackListener(PlayerManager::CB_PLAYERCONNECT, $this, 'handlePlayerConnect');
|
||||
|
||||
$this->maniaControl->getCallbackManager()->registerScriptCallbackListener(self::CB_UPDATEPBS, $this, 'handleUpdatePBs');
|
||||
|
||||
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerListener(self::A_SHOW_ALTITUDE_RECORDS, $this, 'handleShowAltitudeRecords');
|
||||
$this->maniaControl->getCommandManager()->registerCommandListener('records', $this, 'handleShowAltitudeRecords', false);
|
||||
|
||||
$this->maniaControl->getTimerManager()->registerTimerListening($this, 'handle1Minute', 60000);
|
||||
}
|
||||
|
||||
private function initTables() {
|
||||
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
|
||||
|
||||
$query = 'CREATE TABLE IF NOT EXISTS `' . self::DB_CLIMBTHEMAP . '` (
|
||||
`index` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`mapIndex` INT(11) NOT NULL,
|
||||
`login` varchar(36) NOT NULL,
|
||||
`altitude` INT(11) NOT NULL,
|
||||
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`index`),
|
||||
UNIQUE KEY `map_player` (`mapIndex`,`login`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;';
|
||||
$mysqli->query($query);
|
||||
if ($mysqli->error) {
|
||||
trigger_error($mysqli->error, E_USER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public function handleAfterInit() {
|
||||
$this->handleStartRound();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle when a player connects
|
||||
*
|
||||
* @param Player $player
|
||||
*/
|
||||
public function handlePlayerConnect(Player $player) {
|
||||
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
|
||||
|
||||
}
|
||||
|
||||
public function handleStartRound() {
|
||||
$map = $this->maniaControl->getMapManager()->getCurrentMap();
|
||||
$logins = [];
|
||||
|
||||
foreach ($this->maniaControl->getPlayerManager()->getPlayers() as $player) {
|
||||
$logins[] = $player->login;
|
||||
}
|
||||
|
||||
// Send PB
|
||||
$pbs = $this->getPlayersPB($map->index, $logins);
|
||||
if (count($pbs) > 0) {
|
||||
$this->maniaControl->getClient()->triggerModeScriptEvent(self::M_SETPLAYERSPB, [json_encode($pbs)]);
|
||||
}
|
||||
|
||||
// Send WR
|
||||
$wr = $this->getWR($map->index);
|
||||
if ($wr !== null) {
|
||||
$this->wraltitude = $wr[1];
|
||||
$this->maniaControl->getClient()->triggerModeScriptEvent(self::M_SETWR, [$wr[0], strval($wr[1])]);
|
||||
} else {
|
||||
$this->wraltitude = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public function handleUpdatePBs(array $data) {
|
||||
$json = json_decode($data[1][0]);
|
||||
if ($json !== null) {
|
||||
$map = $this->maniaControl->getMapManager()->getCurrentMap();
|
||||
$mapIndex = -1;
|
||||
if ($map !== null) $mapIndex = $map->index;
|
||||
|
||||
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
|
||||
$mysqli->begin_transaction();
|
||||
|
||||
$stmt = $mysqli->prepare("INSERT INTO `" . self::DB_CLIMBTHEMAP . "` (`mapIndex`, `login`, `altitude`)
|
||||
VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE
|
||||
`altitude` = GREATEST(VALUES(`altitude`), `altitude`);");
|
||||
$stmt->bind_param('iss', $mapIndex, $login, $altitude);
|
||||
foreach ($json as $login => $altitude) {
|
||||
$stmt->execute();
|
||||
|
||||
if ($this->wraltitude < $altitude) {
|
||||
$this->wraltitude = $altitude;
|
||||
}
|
||||
}
|
||||
$mysqli->commit();
|
||||
|
||||
|
||||
|
||||
// Reset manialink cache
|
||||
$this->manialink = "";
|
||||
}
|
||||
}
|
||||
|
||||
public function handle1Minute() {
|
||||
$map = $this->maniaControl->getMapManager()->getCurrentMap();
|
||||
if ($map === null) return;
|
||||
|
||||
$wr = $this->getWR($map->index);
|
||||
|
||||
// Update WR if done on an another server
|
||||
if ($wr !== null && $this->wraltitude < $wr[1]) {
|
||||
$this->wraltitude = $wr[1];
|
||||
$this->maniaControl->getClient()->triggerModeScriptEvent(self::M_SETWR, [$wr[0], strval($wr[1])]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function getPlayersPB(int $mapIndex, array $logins) {
|
||||
if (count($logins) === 0) return;
|
||||
$return = [];
|
||||
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
|
||||
|
||||
$stmt = $mysqli->prepare('SELECT login,altitude FROM `' . self::DB_CLIMBTHEMAP . '` WHERE `mapIndex` = ? and login IN (' . str_repeat('?,', count($logins) - 1) . '?' . ' )');
|
||||
$stmt->bind_param('i' . str_repeat('s', count($logins)), $mapIndex, ...$logins); // bind array at once
|
||||
if (!$stmt->execute()) {
|
||||
trigger_error('Error executing MySQL query: ' . $stmt->error);
|
||||
}
|
||||
$result = $stmt->get_result(); // get the mysqli result
|
||||
if ($result !== false) {
|
||||
foreach ($result->fetch_all(MYSQLI_ASSOC) as $data) {
|
||||
$return[$data["login"]] = $data["altitude"];
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
private function getWR(int $mapIndex) {
|
||||
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
|
||||
|
||||
$stmt = $mysqli->prepare('SELECT login,altitude FROM `' . self::DB_CLIMBTHEMAP . '` WHERE `mapIndex` = ? ORDER BY altitude DESC, time ASC LIMIT 1;');
|
||||
$stmt->bind_param('i', $mapIndex);
|
||||
if (!$stmt->execute()) {
|
||||
trigger_error('Error executing MySQL query: ' . $stmt->error);
|
||||
}
|
||||
$result = $stmt->get_result();
|
||||
if ($result !== false) {
|
||||
$data = $result->fetch_assoc();
|
||||
if ($data !== null) {
|
||||
|
||||
$player = $this->maniaControl->getPlayerManager()->getPlayer($data["login"]);
|
||||
if ($player !== null) {
|
||||
return [$player->nickname, $data["altitude"]];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getRecords(Map $map) {
|
||||
if ($map === null) return [];
|
||||
|
||||
$mapIndex = $map->index;
|
||||
|
||||
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
|
||||
|
||||
$stmt = $mysqli->prepare('SELECT ctm.index,ctm.login,p.nickname,ctm.altitude,ctm.time FROM `' . self::DB_CLIMBTHEMAP . '` ctm
|
||||
LEFT JOIN `' . PlayerManager::TABLE_PLAYERS . '` p
|
||||
ON ctm.login = p.login
|
||||
WHERE `mapIndex` = ?
|
||||
ORDER BY altitude DESC, time ASC;');
|
||||
$stmt->bind_param('i', $mapIndex);
|
||||
if (!$stmt->execute()) {
|
||||
trigger_error('Error executing MySQL query: ' . $stmt->error);
|
||||
}
|
||||
$result = $stmt->get_result(); // get the mysqli result
|
||||
if ($result !== false) {
|
||||
return $result->fetch_all(MYSQLI_ASSOC);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
public function handleShowAltitudeRecords(array $callback, Player $player) {
|
||||
$this->maniaControl->getManialinkManager()->displayWidget($this->getManialink(), $player, self::MLID_ALTITUDE_RECORDS);
|
||||
}
|
||||
|
||||
private function getManialink() {
|
||||
if ($this->manialink !== "") return $this->manialink;
|
||||
|
||||
$width = $this->maniaControl->getManialinkManager()->getStyleManager()->getListWidgetsWidth();
|
||||
$height = $this->maniaControl->getManialinkManager()->getStyleManager()->getListWidgetsHeight();
|
||||
|
||||
// get PlayerList
|
||||
$records = $this->getRecords($this->maniaControl->getMapManager()->getCurrentMap());
|
||||
|
||||
// create manialink
|
||||
$maniaLink = new ManiaLink(ManialinkManager::MAIN_MLID);
|
||||
$script = $maniaLink->getScript();
|
||||
$paging = new Paging();
|
||||
$script->addFeature($paging);
|
||||
|
||||
// Main frame
|
||||
$frame = $this->maniaControl->getManialinkManager()->getStyleManager()->getDefaultListFrame($script, $paging);
|
||||
$maniaLink->addChild($frame);
|
||||
|
||||
// Start offsets
|
||||
$posX = -$width / 2;
|
||||
$posY = $height / 2;
|
||||
|
||||
// Headline
|
||||
$headFrame = new Frame();
|
||||
$frame->addChild($headFrame);
|
||||
$headFrame->setY($posY - 5);
|
||||
|
||||
$labelLine = new LabelLine($headFrame);
|
||||
$labelLine->addLabelEntryText('Rank', $posX + 5);
|
||||
$labelLine->addLabelEntryText('Nickname', $posX + 18);
|
||||
$labelLine->addLabelEntryText('Altitude', $posX + $width * 0.6);
|
||||
$labelLine->addLabelEntryText('Date (UTC)', $posX + $width * 0.75);
|
||||
$labelLine->render();
|
||||
|
||||
$index = 0;
|
||||
$posY = $height / 2 - 10;
|
||||
$pageFrame = null;
|
||||
|
||||
$pageMaxCount = floor(($height - 5 - 10) / 4);
|
||||
|
||||
foreach ($records as $record) {
|
||||
if ($index % $pageMaxCount === 0) {
|
||||
$pageFrame = new Frame();
|
||||
$frame->addChild($pageFrame);
|
||||
$posY = $height / 2 - 10;
|
||||
$paging->addPageControl($pageFrame);
|
||||
}
|
||||
|
||||
$recordFrame = new Frame();
|
||||
$pageFrame->addChild($recordFrame);
|
||||
|
||||
if ($index % 2 === 0) {
|
||||
$lineQuad = new Quad_BgsPlayerCard();
|
||||
$recordFrame->addChild($lineQuad);
|
||||
$lineQuad->setSize($width, 4);
|
||||
$lineQuad->setSubStyle($lineQuad::SUBSTYLE_BgPlayerCardBig);
|
||||
$lineQuad->setZ(-0.001);
|
||||
}
|
||||
|
||||
$labelLine = new LabelLine($recordFrame);
|
||||
$labelLine->addLabelEntryText($index + 1, $posX + 5, 13);
|
||||
$labelLine->addLabelEntryText($record["nickname"], $posX + 18, 52);
|
||||
$labelLine->addLabelEntryText($record["altitude"], $posX + $width * 0.6, 31);
|
||||
$labelLine->addLabelEntryText($record["time"], $posX + $width * 0.75, 30);
|
||||
$labelLine->render();
|
||||
|
||||
$recordFrame->setY($posY);
|
||||
|
||||
$posY -= 4;
|
||||
$index++;
|
||||
}
|
||||
|
||||
$this->manialink = (string) $maniaLink;
|
||||
return $this->manialink;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unload the plugin and its Resources
|
||||
*/
|
||||
public function unload() {
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user