Compare commits

..

80 Commits

Author SHA1 Message Date
beu
8e632d5057 change default message 2025-03-31 15:35:06 +02:00
beu
7a6fdebc67 fix setteampoints command 2025-03-31 15:34:41 +02:00
beu
ea877c9cae add eCM plugin 2025-03-27 15:33:58 +01:00
beu
a8069ad874 add Fast Kick plugin 2025-03-21 11:55:27 +01:00
beu
9fda8274b4 prevent sending data when sheetname is empty 2025-03-20 22:43:56 +01:00
beu
5d92ce5900 fix loading and removing configs 2025-03-20 18:05:50 +01:00
beu
986db202d8 fix description 2025-03-17 23:40:37 +01:00
beu
c2b5f1bfec fix error when getting listener class on php 7 2025-03-17 23:30:38 +01:00
beu
b82dbe771b remove colorize property 2025-03-17 22:45:12 +01:00
beu
971238ed8b bump version 2025-03-16 16:39:55 +01:00
beu
a7e40750f4 use chatprefix function from match manager core 2025-03-16 16:36:13 +01:00
beu
365d2ffbce remove debug log 2025-03-16 10:52:45 +01:00
beu
08faf3157d change z-index 2025-03-15 23:46:42 +01:00
beu
f538c31d8e fix double callback when player join 2025-03-15 23:46:01 +01:00
beu
9b4073f456 improve custom gamemode settings detection 2025-03-15 23:44:25 +01:00
beu
0e47b75e3d fix missing break 2025-03-15 22:00:39 +01:00
beu
66cd4a8430 prevent to trigger pause twice 2025-03-15 14:10:48 +01:00
beu
ab36a5b20e fix permission check 2025-03-15 13:15:19 +01:00
beu
d44aa97759 Add TMWT Duo Integration 2025-03-15 13:14:43 +01:00
beu
44bc21f3d1 separate setpoints command for teams 2025-03-15 13:13:43 +01:00
beu
46c26d70a5 completely rework Admin UI plugin 2025-03-15 13:00:53 +01:00
beu
ac76a326bf remove log 2025-03-15 12:31:52 +01:00
beu
abe85dc9e8 remove log 2025-03-15 12:31:32 +01:00
beu
30474b32e7 fix variable name 2025-03-15 12:31:25 +01:00
beu
b2fbbb1f98 use new chatprefix command 2025-03-15 12:19:24 +01:00
beu
18ea56e1c0 add code in query parameter 2025-03-15 12:18:34 +01:00
beu
3cda510834 improve error logging 2025-03-15 12:18:23 +01:00
beu
fb48d5f661 add canStartMatch function and callables 2025-03-14 22:58:10 +01:00
beu
d604c3f3fc add getChatPrefix function 2025-03-14 22:57:02 +01:00
beu
58dd834c9b remove skipround property 2025-03-13 15:58:57 +01:00
beu
9a9122ed0e change default parameter for the linter 2025-03-13 15:58:24 +01:00
beu
fe1f9b9c8b change default pause timer 2025-03-13 15:57:51 +01:00
beu
3eee022618 add markers comments 2025-03-13 15:57:39 +01:00
beu
d116abc4dc fix variable name 2025-02-22 00:19:21 +01:00
beu
f42e12e7a2 fix missing argument in the callback 2025-02-21 23:17:16 +01:00
beu
3bddeb2308 add support of map points and round points 2025-02-21 22:59:18 +01:00
beu
6a2b384648 add guestlist info commands 2025-02-21 22:43:15 +01:00
beu
293d5cf88f Big refactoring of the plugin:
- Add better command aliases
- Add setting to automatically add admins
- Add setting to automatically kick non-guestlisted players
2025-02-18 09:41:55 +01:00
beu
1532b6e04a fix crash when no spec slot available 2025-02-17 11:29:04 +01:00
beu
ddc2ec7725 add automatic map switcher 2024-11-08 11:37:45 +01:00
beu
04c7b9ba29 fix permission for map vote 2024-08-17 15:23:24 +02:00
beu
53e67eb0e1 Add support of EndMatch Callback for scores 2024-07-27 13:31:27 +02:00
beu
01be9cc45f add getConfig function 2024-06-21 11:56:21 +02:00
beu
748ebb20ae add phpdoc 2024-06-21 11:28:06 +02:00
beu
67a7552871 fix admin ui display when manually enabled 2024-06-19 11:50:17 +02:00
beu
cfa24ff67f Add possibility to save config from other plugin 2024-06-16 17:04:52 +02:00
beu
0420d6b08e remove pause at end of match 2024-06-16 17:04:15 +02:00
beu
e2b4b29d41 use afterinit callback instead of waiting one sec 2024-06-16 17:03:55 +02:00
beu
edbe75c39e update visibility when receiving callback from MatchManagerCore 2024-06-06 11:20:08 +02:00
beu
4f18b51cba change matchStarted variable sooner when match end 2024-06-06 11:18:59 +02:00
beu
09480c14eb disable ToggleUIFeature for the widget 2024-06-06 10:48:23 +02:00
beu
53637d3c8e check if spreadsheet id is empty before doing requests 2024-06-06 10:47:51 +02:00
beu
48478fad26 Replace db queries by prepared statements 2024-05-27 14:08:04 +02:00
beu
4d949982f9 add OpenplanetDetector 2024-05-15 01:34:30 +02:00
Beu
65e8fb2454 bump version to bypass site issue 2024-03-13 16:40:38 +01:00
Beu
8520ee7b9e fix shuffle maps 2024-03-13 16:38:04 +01:00
Beu
e3edcfa47f Add map shuffle seed 2024-03-04 14:24:36 +01:00
Beu
2f38ecd669 add player name in results 2024-03-04 11:26:41 +01:00
Beu
ca7a07ac2a add function to know if a a match is running 2024-01-04 16:00:54 +01:00
Beu
fb3bf97bfc fix small warning for undefined variable 2023-12-23 12:47:23 +01:00
Beu
96757006a1 fix score not sent when S_RoundsPerMap = 0 2023-12-23 12:46:51 +01:00
Beu
45e4417f97 fix using the wrong method 2023-12-15 11:14:23 +01:00
Beu
740cde761a Add blacklist manager 2023-12-14 23:07:42 +01:00
Beu
9428fc3a64 add BeuCustomConfig 2023-12-14 18:18:40 +01:00
Beu
a1cdbe93e2 fix race condition of the nbround and the nbmaps 2023-10-16 22:54:25 +02:00
Beu
89ce4f0d61 fix once again the nbround 2023-10-16 22:53:47 +02:00
Beu
c664cc08ce rework how is managed nbrounds 2023-10-16 22:32:24 +02:00
Beu
fa8fbd3c32 update how to compute nbrounds 2023-10-16 14:13:50 +02:00
Beu
b54bd41de8 bump version 2023-10-09 10:20:33 +02:00
Beu
9b85fd0b26 add S_DisableGiveUp & S_LoadingScreenImageUrl settings 2023-10-09 09:57:49 +02:00
Beu
f82ca8254b limit records to not reach the manialink size limit 2023-10-02 23:37:08 +02:00
Beu
52f0dd3dfc remove var_dump 2023-09-29 13:10:08 +02:00
Beu
0c3c7b88a9 add TMWC2023 game mode 2023-09-27 17:56:07 +02:00
Beu
065a2c6db5 fix query for the WR 2023-09-27 11:02:26 +02:00
Beu
70db771f9b fix SQL query 2023-09-26 19:00:54 +02:00
Beu
f359fe1ba9 Add new plugin 2023-09-25 10:54:19 +02:00
Beu
83a05de5c6 reset manialink cache if WR is beaten 2023-09-25 10:54:00 +02:00
Beu
5f3495b2a8 manage when a player join the server 2023-09-08 19:58:41 +02:00
Beu
36cf818731 Manage when player finish the map 2023-09-08 19:58:16 +02:00
Beu
676c03847a add ClimbTheMap plugin 2023-09-08 17:39:56 +02:00
19 changed files with 4368 additions and 912 deletions

13
.gitignore vendored
View File

@ -6,11 +6,18 @@
!MatchManagerSuite/*
!Beu
!Beu/AFKNotifier.php
!Beu/AutomaticMapSwitcher.php
!Beu/BeuCustomConfig.php
!Beu/BeuDonationButton.php
!Beu/BlacklistManager.php
!Beu/ChatAdminColorer.php
!Beu/ReloadDevTool.php
!Beu/ClimbTheMap.php
!Beu/GameModeLoader.php
!Beu/GuestlistManager.php
!Beu/MoreModesTools.php
!Beu/OpenplanetDetector.php
!Beu/ReloadDevTool.php
!Beu/SimpleChatColorer.php
!Beu/SimpleSkinsRemover.php
!Beu/BeuDonationButton.php
!Beu/GameModeLoader.php
!Beu/SmallTextOverlay.php
!Beu/FastKick.php

View File

@ -0,0 +1,144 @@
<?php
namespace Beu;
use ManiaControl\ManiaControl;
use ManiaControl\Callbacks\CallbackListener;
use ManiaControl\Callbacks\TimerListener;
use ManiaControl\Logger;
use ManiaControl\Plugins\Plugin;
/**
* GSheetRecords
*
* @author Beu
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
*/
class AutomaticMapSwitcher implements TimerListener, CallbackListener, Plugin {
/*
* Constants
*/
const PLUGIN_ID = 208;
const PLUGIN_VERSION = 1;
const PLUGIN_NAME = 'AutomaticMapSwitcher';
const PLUGIN_AUTHOR = 'Beu';
const SETTING_SCHEDULE = 'Map schedule';
const SETTING_DEBOUCEMAPCHANGEDELAY = 'Debounce map change delay';
/*
* Private properties
*/
private ManiaControl $maniaControl;
private int $debounceMapChangeTime = 0;
/**
* @param \ManiaControl\ManiaControl $maniaControl
* @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 'Automatic change map based on timestamp';
}
/**
* @param \ManiaControl\ManiaControl $maniaControl
* @return bool
* @see \ManiaControl\Plugins\Plugin::load()
*/
public function load(ManiaControl $maniaControl) {
$this->maniaControl = $maniaControl;
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_SCHEDULE, '', 'format: "timestamp:mapuid,timestamp:mapuid"');
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_DEBOUCEMAPCHANGEDELAY, 30, 'delay between 2 map change requests', 110);
$this->maniaControl->getTimerManager()->registerTimerListening($this, 'handle1Second', 1000);
}
/**
* @see \ManiaControl\Plugins\Plugin::unload()
*/
public function unload() {
}
/**
* handle1Second
* @return void
*/
public function handle1Second() {
$now = time();
if ($this->debounceMapChangeTime > $now) return;
$schedule = trim($this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_SCHEDULE));
if ($schedule === '') return;
$matchingTimestamp = -1;
$matchingMapUid = '';
foreach (explode(',', $schedule) as $pair) {
list($timestampText, $mapuid) = explode(':', $pair);
if (!is_numeric($timestampText)) {
$this->maniaControl->getChat()->sendErrorToAdmins('invalid timestamp in pair: '. $pair);
Logger::logWarning('invalid timestamp in pair: '. $pair);
continue;
}
$timestamp = intval($timestampText);
if ($this->maniaControl->getMapManager()->getMapByUid($mapuid) === null) {
$this->maniaControl->getChat()->sendErrorToAdmins('map not loaded in pair: '. $pair);
Logger::logWarning('map not loaded in pair: '. $pair);
continue;
}
if ($matchingTimestamp < $timestamp && $now > $timestamp) {
$matchingTimestamp = $timestamp;
$matchingMapUid = $mapuid;
}
}
if ($matchingMapUid !== '' && $matchingMapUid !== $this->maniaControl->getMapManager()->getCurrentMap()->uid) {
$this->debounceMapChangeTime = time() + $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_DEBOUCEMAPCHANGEDELAY);
$nextmap = $this->maniaControl->getMapManager()->getMapByUid($matchingMapUid);
$this->maniaControl->getChat()->sendSuccess('Automatic switching to map: $z'. $nextmap->name);
Logger::logWarning('Automatic switching to map: '. $matchingMapUid);
$this->maniaControl->getMapManager()->getMapActions()->skipToMapByUid($matchingMapUid);
}
}
}

163
Beu/BeuCustomConfig.php Normal file
View File

@ -0,0 +1,163 @@
<?php
namespace Beu;
use ManiaControl\ManiaControl;
use ManiaControl\Plugins\Plugin;
use ManiaControl\Players\PlayerManager;
use ManiaControl\Callbacks\CallbackListener;
use ManiaControl\Settings\Setting;
use ManiaControl\Settings\SettingManager;
use FML\Controls\Quads\Quad_BgsPlayerCard;
use ManiaControl\Admin\AuthenticationManager;
use ManiaControl\Configurator\Configurator;
use ManiaControl\Manialinks\StyleManager;
use ManiaControl\Maps\MapManager;
use ManiaControl\Maps\MapQueue;
use ManiaControl\Plugins\PluginMenu;
use ManiaControl\Server\UsageReporter;
use ManiaControl\Update\UpdateManager;
use Maniaplanet\DedicatedServer\Structures\VoteRatio;
/**
* BeuCustomConfig
*
* @author Beu
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
*/
class BeuCustomConfig implements CallbackListener, Plugin {
/*
* Constants
*/
const PLUGIN_ID = 193;
const PLUGIN_VERSION = 1.2;
const PLUGIN_NAME = 'BeuCustomConfig';
const PLUGIN_AUTHOR = 'Beu';
/*
* Private properties
*/
/** @var ManiaControl $maniaControl */
private $maniaControl = null;
/**
* @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 "Default config for event servers";
}
/**
* @see \ManiaControl\Plugins\Plugin::load()
*/
public function load(ManiaControl $maniaControl) {
$this->maniaControl = $maniaControl;
$this->maniaControl->getCallbackManager()->registerCallbackListener(SettingManager::CB_SETTING_CHANGED, $this, 'updateSettings');
$this->changeManiacontrolSettings();
}
private function changeManiacontrolSettings() {
$settingstochange = [
AuthenticationManager::class => [
MapQueue::SETTING_PERMISSION_ADD_TO_QUEUE => AuthenticationManager::AUTH_NAME_ADMIN
],
UpdateManager::class => [
UpdateManager::SETTING_ENABLE_UPDATECHECK => false
],
UsageReporter::class => [
UsageReporter::SETTING_REPORT_USAGE => false
],
MapManager::class => [
MapManager::SETTING_AUTOSAVE_MAPLIST => false,
MapManager::SETTING_ENABLE_MX => false
],
PlayerManager::class => [
PlayerManager::SETTING_VERSION_JOIN_MESSAGE => false
],
PluginMenu::class => [
PluginMenu::SETTING_CHECK_UPDATE_WHEN_OPENING => false
],
Configurator::class => [
Configurator::SETTING_MENU_HEIGHT => 120,
Configurator::SETTING_MENU_WIDTH => 220,
],
StyleManager::class => [
StyleManager::SETTING_LIST_WIDGETS_HEIGHT => 120,
StyleManager::SETTING_LIST_WIDGETS_WIDTH => 220,
StyleManager::SETTING_LABEL_DEFAULT_STYLE => "TextClock",
StyleManager::SETTING_QUAD_DEFAULT_STYLE => Quad_BgsPlayerCard::STYLE,
StyleManager::SETTING_QUAD_DEFAULT_SUBSTYLE => Quad_BgsPlayerCard::SUBSTYLE_BgPlayerName
]
];
foreach ($settingstochange as $classname => $settings) {
foreach ($settings as $settingname => $value) {
$setting = $this->maniaControl->getSettingManager()->getSettingObject($classname, $settingname);
$setting->value = $value;
$this->maniaControl->getSettingManager()->saveSetting($setting);
}
}
// Disable all votes
$this->maniaControl->getClient()->setCallVoteRatios([
new VoteRatio(VoteRatio::COMMAND_DEFAULT, -1.),
new VoteRatio(VoteRatio::COMMAND_SCRIPT_SETTINGS, -1.),
new VoteRatio(VoteRatio::COMMAND_JUMP_MAP, -1.),
new VoteRatio(VoteRatio::COMMAND_SET_NEXT_MAP, -1.),
new VoteRatio(VoteRatio::COMMAND_KICK, -1.),
new VoteRatio(VoteRatio::COMMAND_RESTART_MAP, -1.),
new VoteRatio(VoteRatio::COMMAND_TEAM_BALANCE, -1.),
new VoteRatio(VoteRatio::COMMAND_NEXT_MAP, -1.),
new VoteRatio(VoteRatio::COMMAND_BAN, -1.)
]);
}
public function updateSettings(Setting $setting = null) {
if ($setting !== null && $setting->belongsToClass($this)) {
$this->changeManiacontrolSettings();
}
}
/**
* Unload the plugin and its Resources
*/
public function unload() {
}
}

230
Beu/BlacklistManager.php Normal file
View File

@ -0,0 +1,230 @@
<?php
namespace Beu;
use ManiaControl\Commands\CommandListener;
use ManiaControl\Logger;
use ManiaControl\Players\Player;
use ManiaControl\Players\PlayerManager;
use ManiaControl\Plugins\Plugin;
use ManiaControl\ManiaControl;
/**
* Plugin Description
*
* @author Beu
* @version 1.0
*/
class BlacklistManager implements CommandListener, Plugin {
/*
* Constants
*/
const PLUGIN_ID = 200;
const PLUGIN_VERSION = 1.0;
const PLUGIN_NAME = 'Blacklist Manager';
const PLUGIN_AUTHOR = 'Beu';
const SETTING_BLACKLIST_FILE = 'Blacklist file';
/**
* Private Properties
*/
/** @var ManiaControl $maniaControl */
private $maniaControl = null;
/**
* @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 \Man$this->maniaControl = $maniaControl;iaControl\Plugins\Plugin::getAuthor()
*/
public static function getAuthor() {
return self::PLUGIN_AUTHOR;
}
/**
* @see \ManiaControl\Plugins\Plugin::getDescription()
*/
public static function getDescription() {
return 'Tool to manage the Blacklist';
}
/**
* @see \ManiaControl\Plugins\Plugin::load()
*/
public function load(ManiaControl $maniaControl) {
$this->maniaControl = $maniaControl;
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_BLACKLIST_FILE, "blacklist.txt", 'blacklist file');
$this->maniaControl->getCommandManager()->registerCommandListener('addtobl', $this, 'doaddtobl', true, 'Add someone to the blacklist');
$this->maniaControl->getCommandManager()->registerCommandListener('savebl', $this, 'dosavebl', true, 'Save the blacklist');
$this->maniaControl->getCommandManager()->registerCommandListener('loadbl', $this, 'doloadbl', true, 'Load the blacklist');
$this->maniaControl->getCommandManager()->registerCommandListener('cleanbl', $this, 'docleanbl', true, 'Clean the blacklist');
$blacklist = $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_BLACKLIST_FILE);
if ($blacklist === "" || is_file($this->maniaControl->getServer()->getDirectory()->getUserDataFolder() . DIRECTORY_SEPARATOR . "Config" . DIRECTORY_SEPARATOR . $blacklist)) {
$this->maniaControl->getClient()->loadBlackList($blacklist);
}
}
/**
* @see \ManiaControl\Plugins\Plugin::unload()
*/
public function unload() {
}
/**
* Add players to the blacklist
*
* @param array $chat
* @param \ManiaControl\Players\Player $player
*/
public function doaddtobl(Array $chat, Player $player) {
$command = explode(" ", $chat[1][2]);
$peopletoadd = $command[1];
if (empty($peopletoadd)) {
$this->maniaControl->getChat()->sendError("You must set the nickname as argument", $player);
} else {
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
$query = 'SELECT login FROM `' . PlayerManager::TABLE_PLAYERS . '` WHERE nickname LIKE "' . $peopletoadd . '"';
$result = $mysqli->query($query);
$array = mysqli_fetch_array($result);
if (isset($array[0])) {
$login = $array[0];
} elseif (strlen($peopletoadd) == 22) {
$login = $peopletoadd ;
}
if ($mysqli->error) {
trigger_error($mysqli->error, E_USER_ERROR);
}
if (!isset($login)) {
$this->maniaControl->getChat()->sendError( "Login not found. FYI The player must be connected" , $player);
} else {
if ($this->addLoginToBL($login)) {
$this->maniaControl->getChat()->sendSuccess( "Player " . $peopletoadd . " added to the Blacklist" , $player);
} else {
$this->maniaControl->getChat()->sendSuccess( "Player " . $peopletoadd . " already in the Blacklist" , $player);
}
}
}
}
/**
* Add login to the blacklist
*
* @param string $login
* @param array $blacklist
*/
public function addLoginToBL(String $login, array $blacklist = []) {
if (empty($blacklist)) {
$blacklist = $this->maniaControl->getClient()->getBlackList();
}
$logintoadd = "";
$logintoadd = array_search($login ,array_column($blacklist, 'login'));
if (strlen($logintoadd) == 0) {
$this->maniaControl->getClient()->blackList($login);
return true;
} else {
return false;
}
}
/**
* load from the blacklist file
*
* @param array $chat
* @param \ManiaControl\Players\Player $player
*/
public function doloadbl(Array $chat, Player $player) {
$text = explode(" ",$chat[1][2]);
if (count($text) > 1 && $text[1] != "") {
$blacklist = $text[1];
if (substr($blacklist , -4) != ".txt" && substr($blacklist , -4) != ".xml") {
$blacklist .= ".txt";
}
} else {
$blacklist = $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_BLACKLIST_FILE);
}
if ($blacklist === "" || is_file($this->maniaControl->getServer()->getDirectory()->getUserDataFolder() . DIRECTORY_SEPARATOR . "Config" . DIRECTORY_SEPARATOR . $blacklist)) {
$this->maniaControl->getClient()->loadBlackList($blacklist);
$this->maniaControl->getChat()->sendSuccess( "Blacklist loaded!" , $player);
} else {
$this->maniaControl->getChat()->sendError("Impossible to load the blacklist file" , $player);
}
}
/**
* save to the blacklist file
*
* @param array $chat
* @param \ManiaControl\Players\Player $player
*/
public function dosavebl(Array $chat, Player $player) {
try {
$blacklist = $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_BLACKLIST_FILE);
if ($blacklist !== "") {
$filepath = $this->maniaControl->getServer()->getDirectory()->getUserDataFolder() . DIRECTORY_SEPARATOR . "Config" . DIRECTORY_SEPARATOR . $blacklist;
if (!is_file($filepath)) {
file_put_contents($filepath, '<?xml version="1.0" encoding="utf-8" ?><blacklist></blacklist>');
}
}
// Workaround when the file was never loaded by the server
$currentblacklist = $this->maniaControl->getClient()->getBlackList();
$this->maniaControl->getClient()->loadBlackList($blacklist);
$this->maniaControl->getClient()->cleanBlackList();
foreach ($currentblacklist as $guest) {
$this->maniaControl->getClient()->addGuest($guest->login);
}
$this->maniaControl->getClient()->saveBlackList($blacklist);
$this->maniaControl->getChat()->sendSuccess("Blacklist saved!" , $player);
} catch (\Exception $e) {
Logger::logError("Impossible to save blacklist: " . $e->getMessage());
$this->maniaControl->getChat()->sendError("Impossible to save blacklist: " . $e->getMessage(), $player);
}
}
/**
* clean the blacklist
*
* @param array $chat
* @param \ManiaControl\Players\Player $player
*/
public function docleanbl(Array $chat, Player $player) {
$this->maniaControl->getClient()->cleanBlackList();
$this->maniaControl->getChat()->sendSuccess( "Blacklist cleaned!" , $player);
}
}

420
Beu/ClimbTheMap.php Normal file
View File

@ -0,0 +1,420 @@
<?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\Callbacks\Structures\TrackMania\OnWayPointEventStructure;
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;
use ManiaControl\Utils\Formatter;
/**
* 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.4;
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';
const CB_REQUESTPB = 'Trackmania.ClimbTheMap.RequestPB';
// 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;
private $wrtime = 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 records for the ClimbTheMap game mode";
}
/**
* @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(Callbacks::TM_ONFINISHLINE, $this, 'handleFinishCallback');
$this->maniaControl->getCallbackManager()->registerScriptCallbackListener(self::CB_UPDATEPBS, $this, 'handleUpdatePBs');
$this->maniaControl->getCallbackManager()->registerScriptCallbackListener(self::CB_REQUESTPB, $this, 'handleRequestPB');
$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` int(11) DEFAULT -1,
`date` 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();
}
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->wrtime = $wr[2];
$this->maniaControl->getClient()->triggerModeScriptEvent(self::M_SETWR, [$wr[0], strval($wr[1]), strval($wr[2])]);
} else {
$this->wraltitude = 0;
}
}
public function handleFinishCallback(OnWayPointEventStructure $structure) {
$map = $this->maniaControl->getMapManager()->getCurrentMap();
if ($map === null) return;
$mapIndex = $map->index;
$login = $structure->getLogin();
$time = $structure->getRaceTime();
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
$stmt = $mysqli->prepare("INSERT INTO `" . self::DB_CLIMBTHEMAP . "` (`mapIndex`, `login`, `time`, `altitude`)
VALUES (?, ?, ?, -1) ON DUPLICATE KEY UPDATE
`time` = IF(`time` < 0 OR `time` > VALUES(`time`),
VALUES(`time`),
`time`);");
$stmt->bind_param('isi', $mapIndex, $login, $time);
$stmt->execute();
// Reset manialink cache
$this->manialink = "";
}
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();
}
$mysqli->commit();
// Reset manialink cache
$this->manialink = "";
}
}
/**
* Handle when a player connects
* Can't use the C++ Callback because the it's received by Maniacontrol before that the Maniascript initialized the Player
*
* @param Player $player
*/
public function handleRequestPB(array $data) {
$login = $data[1][0];
$map = $this->maniaControl->getMapManager()->getCurrentMap();
if ($map === null) return;
// Send PB
$pbs = $this->getPlayersPB($map->index, [$login]);
if (count($pbs) > 0) {
$this->maniaControl->getClient()->triggerModeScriptEvent(self::M_SETPLAYERSPB, [json_encode($pbs)]);
}
}
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->wrtime !== $wr[2])) {
$this->wraltitude = $wr[1];
$this->wrtime = $wr[2];
$this->maniaControl->getClient()->triggerModeScriptEvent(self::M_SETWR, [$wr[0], strval($wr[1]), strval($wr[2])]);
// Reset manialink cache
$this->manialink = "";
}
}
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`,`time` FROM `' . self::DB_CLIMBTHEMAP . '`
WHERE `mapIndex` = ?
ORDER BY (CASE WHEN `time` > 0 THEN `time` ELSE 9999999999 END) ASC,
`altitude` DESC,
`date` 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"], $data["time"]];
}
}
}
return null;
}
public function getRecords(Map $map) {
if ($map === null) return [];
$mapIndex = $map->index;
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
$query = 'SELECT ctm.index,ctm.login,p.nickname,ctm.altitude,ctm.time,ctm.date FROM `' . self::DB_CLIMBTHEMAP . '` ctm
LEFT JOIN `' . PlayerManager::TABLE_PLAYERS . '` p
ON ctm.login = p.login
WHERE `mapIndex` = ?
ORDER BY (CASE WHEN `time` > 0 THEN `time` ELSE 9999999999 END) ASC,
`altitude` DESC,
`date` ASC
LIMIT 500';
$stmt = $mysqli->prepare($query );
$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.5);
$labelLine->addLabelEntryText('Time', $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.5, 31);
if ($record["time"] > 0) {
$labelLine->addLabelEntryText(Formatter::formatTime($record["time"]), $posX + $width * 0.6, 30);
}
$labelLine->addLabelEntryText($record["date"], $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() {
}
}

239
Beu/FastKick.php Normal file
View File

@ -0,0 +1,239 @@
<?php
namespace Beu;
use ManiaControl\Logger;
use ManiaControl\ManiaControl;
use ManiaControl\Manialinks\ManialinkPageAnswerListener;
use ManiaControl\Players\Player;
use ManiaControl\Players\PlayerActions;
use ManiaControl\Plugins\Plugin;
use ManiaControl\Commands\CommandListener;
use FML\Controls\Frame;
use FML\Controls\Label;
use FML\Controls\Quad;
use FML\Controls\Quads\Quad_Icons64x64_1;
use FML\ManiaLink;
/**
* Beu Donation Button
*
* @author Beu
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
*/
class FastKick implements ManialinkPageAnswerListener, CommandListener, Plugin {
/*
* MARK: Constants
*/
const PLUGIN_ID = 212;
const PLUGIN_VERSION = 1.0;
const PLUGIN_NAME = 'Fast Kick';
const PLUGIN_AUTHOR = 'Beu';
const MANIALINK_ID = 'FastKick::MainWindow';
const ACTION_CLOSE = 'FastKick::close';
const ACTION_KICK = 'FastKick::kick';
/*
* MARK: Private properties
*/
private ManiaControl $maniaControl;
/*
* MARK: Functions
*/
/**
* @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 "Quick plugin to kick player easily using //fk command by matching the nearest name";
}
/**
* @see \ManiaControl\Plugins\Plugin::load()
*/
public function load(ManiaControl $maniaControl) {
$this->maniaControl = $maniaControl;
$this->maniaControl->getCommandManager()->registerCommandListener(['fkick', 'fk', 'fastkick'], $this, 'handleFastKick', true);
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerListener(self::ACTION_CLOSE, $this, 'handleClose');
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerRegexListener('/^'. self::ACTION_KICK .'/', $this, 'handleKick');
}
/**
* handle Fast Kick command
*
* @param array $structure
* @param Player $adminPlayer
* @return void
*/
public function handleFastKick(array $structure, Player $adminPlayer) {
if (!$this->maniaControl->getAuthenticationManager()->checkPermission($adminPlayer, PlayerActions::SETTING_PERMISSION_KICK_PLAYER)) {
$this->maniaControl->getAuthenticationManager()->sendNotAllowed($adminPlayer);
return;
}
$params = explode(' ', $structure[1][2], 3);
if (count($params) <= 1 || $params[1] === '') {
$message = $this->maniaControl->getChat()->formatMessage(
'No player name given! Example: %s',
$params[0] .' <player name>'
);
$this->maniaControl->getChat()->sendUsageInfo($message, $adminPlayer);
return;
}
$target = $params[1];
$players = $this->maniaControl->getPlayerManager()->getPlayers();
$indexedList = [];
foreach ($players as $player) {
similar_text($target, $player->nickname, $percent);
$indexedList[intval($percent)][] = $player;
}
krsort($indexedList);
$manialink = new ManiaLink(self::MANIALINK_ID);
$parentFrame = new Frame();
$manialink->addChild($parentFrame);
$parentFrame->setPosition(-150., -35., 100.);
$background = new Quad();
$parentFrame->addChild($background);
$background->setHorizontalAlign(Quad::LEFT);
$background->setVerticalAlign(Quad::TOP);
$background->setBackgroundColor('000000');
$background->setOpacity(0.7);
$background->setSize(60., 25.);
$background->setZ(-1.);
$closeButton = new Quad_Icons64x64_1();
$parentFrame->addChild($closeButton);
$closeButton->setPosition(58., -2.);
$closeButton->setSize(6, 6);
$closeButton->setSubStyle($closeButton::SUBSTYLE_QuitRace);
$closeButton->setAction(self::ACTION_CLOSE);
$headerName = new Label();
$parentFrame->addChild($headerName);
$headerName->setPosition(1., -3);
$headerName->setHorizontalAlign($headerName::LEFT);
$headerName->setTextFont('GameFontExtraBold');
$headerName->setTextColor('ffffff');
$headerName->setTextSize(1.5);
$headerName->setText('Player Name');
$headerMatching = new Label();
$parentFrame->addChild($headerMatching);
$headerMatching->setPosition(40., -3);
$headerMatching->setHorizontalAlign($headerMatching::CENTER);
$headerMatching->setTextFont('GameFontExtraBold');
$headerMatching->setTextColor('ffffff');
$headerMatching->setTextSize(1.5);
$headerMatching->setText('Matching');
$count = 1;
$posY = -7.;
foreach ($indexedList as $percent => $players) {
foreach ($players as $player) {
$frame = new Frame();
$parentFrame->addChild($frame);
$frame->setY($posY);
$name = new Label();
$frame->addChild($name);
$name->setX(1.5);
$name->setSize(30., 3.5);
$name->setHorizontalAlign($name::LEFT);
$name->setTextFont('GameFontSemiBold');
$name->setTextColor('ffffff');
$name->setTextSize(1.2);
$name->setText($player->nickname);
$matching = new Label();
$frame->addChild($matching);
$matching->setX(40.);
$matching->setHorizontalAlign($name::CENTER);
$matching->setTextFont('GameFontSemiBold');
$matching->setTextColor('ffffff');
$matching->setTextSize(1.2);
$matching->setText($percent . '%');
$kickButton = new Quad();
$frame->addChild($kickButton);
$kickButton->setX(57.);
$kickButton->setSize(4, 4);
$kickButton->setStyle('UICommon64_2');
$kickButton->setSubStyle('UserDelete_light');
$kickButton->setAction(self::ACTION_KICK . '.' . $player->login);
$posY += -3.8;
$count++;
if ($count > 5) break 2;
}
}
$this->maniaControl->getManialinkManager()->sendManialink($manialink, $adminPlayer, ToggleUIFeature: false);
}
public function handleClose(array $structure, Player $adminPlayer) {
$this->maniaControl->getManialinkManager()->hideManialink(self::MANIALINK_ID, $adminPlayer);
}
public function handleKick(array $structure, Player $adminPlayer) {
if (!$this->maniaControl->getAuthenticationManager()->checkPermission($adminPlayer, PlayerActions::SETTING_PERMISSION_KICK_PLAYER)) {
$this->maniaControl->getAuthenticationManager()->sendNotAllowed($adminPlayer);
return;
}
$targetLogin = explode('.', $structure[1][2])[1];
$targetPlayer = $this->maniaControl->getPlayerManager()->getPlayer($targetLogin);
Logger::log("========================= Fast kick info: ====");
Logger::log(json_encode($targetPlayer));
Logger::log(json_encode($this->maniaControl->getClient()->getNetworkStats()));
$this->maniaControl->getPlayerManager()->getPlayerActions()->kickPlayer($adminPlayer, $targetLogin);
$this->maniaControl->getManialinkManager()->hideManialink(self::MANIALINK_ID, $adminPlayer);
}
/**
* Unload the plugin and its Resources
*/
public function unload() {}
}

View File

@ -2,35 +2,43 @@
namespace Beu;
use ManiaControl\Commands\CommandListener;
use ManiaControl\ManiaControl;
use ManiaControl\Logger;
use ManiaControl\Admin\AuthenticationManager;
use ManiaControl\Callbacks\CallbackListener;
use ManiaControl\Callbacks\TimerListener;
use ManiaControl\Commands\CommandListener;
use ManiaControl\Players\Player;
use ManiaControl\Players\PlayerManager;
use ManiaControl\Plugins\Plugin;
use ManiaControl\ManiaControl;
use ManiaControl\Settings\SettingManager;
/**
* Plugin Description
*
* @author Beu
* @version 1.1
*/
class GuestlistManager implements CommandListener, Plugin {
class GuestlistManager implements CommandListener, CallbackListener, TimerListener, Plugin {
/*
* Constants
*/
const PLUGIN_ID = 154;
const PLUGIN_VERSION = 1.3;
const PLUGIN_VERSION = 2.3;
const PLUGIN_NAME = 'Guestlist Manager';
const PLUGIN_AUTHOR = 'Beu';
const SETTING_GUESTLIST_FILE = 'Guestlist file';
const SETTING_LOAD_AT_START = 'Load Guestlist at Maniacontrol start';
const SETTING_ADD_ADMINS = 'Automatically add admins to the guestlist';
const SETTING_ADMIN_LEVEL = 'Minimum Admin level to automatically add admin to the guestlist';
const SETTING_ENFORCE_GUESTLIST = 'Kick all non-guestlisted players';
/**
* Private Properties
*/
/** @var ManiaControl $maniaControl */
private $maniaControl = null;
private $checkNonGuestlistedPlayers = true;
/**
* @see \ManiaControl\Plugins\Plugin::prepare()
@ -79,17 +87,43 @@ class GuestlistManager implements CommandListener, Plugin {
public function load(ManiaControl $maniaControl) {
$this->maniaControl = $maniaControl;
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_GUESTLIST_FILE, "guestlist.txt", 'guestlist file');
$this->maniaControl->getCommandManager()->registerCommandListener('addalltogl', $this, 'doaddalltogl', true, 'Add all connected players to the guestlist');
$this->maniaControl->getCommandManager()->registerCommandListener('addtogl', $this, 'doaddtogl', true, 'Add someone to the guestlist');
$this->maniaControl->getCommandManager()->registerCommandListener('savegl', $this, 'dosavegl', true, 'Save the guestlist');
$this->maniaControl->getCommandManager()->registerCommandListener('loadgl', $this, 'doloadgl', true, 'Load the guestlist');
$this->maniaControl->getCommandManager()->registerCommandListener('cleangl', $this, 'docleangl', true, 'Clean the guestlist');
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_GUESTLIST_FILE, "guestlist.txt", 'guestlist file', 10);
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_LOAD_AT_START, false, 'Load guestlist file at maniacontrol start', 20);
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_ADD_ADMINS, false, 'Due to a bug, player can join a server without being guestlisted. This setting is to prevent this.', 90);
$this->maniaControl->getAuthenticationManager()->definePluginPermissionLevel($this, self::SETTING_ADMIN_LEVEL, AuthenticationManager::AUTH_LEVEL_MODERATOR);
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_ENFORCE_GUESTLIST, false, 'Due to a bug, player can join a server without being guestlisted. This setting is to prevent this.', 110);
$this->maniaControl->getCommandManager()->registerCommandListener(['gladdall', 'addalltogl'], $this, 'handleAddAll', true, 'Add all connected players to the guestlist');
$this->maniaControl->getCommandManager()->registerCommandListener(['gladd', 'addtogl'], $this, 'handleAdd', true, 'Add player to the guestlist');
$this->maniaControl->getCommandManager()->registerCommandListener(['glremove', 'gldelete', 'removefromgl', 'deletefromgl'], $this, 'handleRemove', true, 'Remove player to the guestlist');
$this->maniaControl->getCommandManager()->registerCommandListener(['glsave', 'savegl'], $this, 'handleSave', true, 'Save the guestlist file');
$this->maniaControl->getCommandManager()->registerCommandListener(['glload', 'loadgl'], $this, 'handleLoad', true, 'Load the guestlist file');
$this->maniaControl->getCommandManager()->registerCommandListener(['glclear', 'glclean', 'cleangl'], $this, 'handleClear', true, 'Clear the guestlist');
$this->maniaControl->getCommandManager()->registerCommandListener(['glkickall'], $this, 'handleKickAll', true, 'Kick non-guestlisted players');
$this->maniaControl->getCommandManager()->registerCommandListener(['glinfo'], $this, 'handleInfo', true, 'Get guestlist info');
$this->maniaControl->getCommandManager()->registerCommandListener(['gllist'], $this, 'handleList', true, 'List all guestlisted players');
$guestlist = $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_GUESTLIST_FILE);
if ($guestlist === "" || is_file($this->maniaControl->getServer()->getDirectory()->getUserDataFolder() . DIRECTORY_SEPARATOR . "Config" . DIRECTORY_SEPARATOR . $guestlist)) {
$this->maniaControl->getClient()->loadGuestList($guestlist);
$this->maniaControl->getCallbackManager()->registerCallbackListener(AuthenticationManager::CB_AUTH_LEVEL_CHANGED, $this, 'handleAuthLevelChanged');
$this->maniaControl->getCallbackManager()->registerCallbackListener(PlayerManager::CB_PLAYERCONNECT, $this, 'handlePlayerConnect');
$this->maniaControl->getCallbackManager()->registerCallbackListener(SettingManager::CB_SETTING_CHANGED, $this, 'handleSettingChanged');
if ($this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_LOAD_AT_START)) {
$guestlist = $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_GUESTLIST_FILE);
if ($guestlist === "" || is_file($this->maniaControl->getServer()->getDirectory()->getUserDataFolder() . DIRECTORY_SEPARATOR . "Config" . DIRECTORY_SEPARATOR . $guestlist)) {
$this->maniaControl->getClient()->loadGuestList($guestlist);
}
}
$this->addAdminsToGuestlist();
$this->maniaControl->getTimerManager()->registerTimerListening($this, function () {
if (!$this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_ENFORCE_GUESTLIST)) return;
if (!$this->checkNonGuestlistedPlayers) return;
$this->checkNonGuestlistedPlayers = false;
$this->kickNonGuestlistedPlayers();
}, 1000);
}
/**
@ -99,12 +133,12 @@ class GuestlistManager implements CommandListener, Plugin {
}
/**
* Add all connected players to the guestlist
* handle Add All to GL command
*
* @param array $chat
* @param \ManiaControl\Players\Player $player
*/
public function doaddalltogl(Array $chat, Player $player) {
*/
public function handleAddAll(Array $chat, Player $player) {
$players = $this->maniaControl->getPlayerManager()->getPlayers();
$guestlist = $this->maniaControl->getClient()->getGuestList();
$i = 0;
@ -113,44 +147,48 @@ class GuestlistManager implements CommandListener, Plugin {
$i++;
}
}
$this->maniaControl->getChat()->sendSuccess( "All connected players have been added to the Guestlist");
Logger::log('Adding all connected players to the guestlist by '. $player->nickname);
$this->maniaControl->getChat()->sendSuccess("All connected players have been added to the Guestlist");
$this->maniaControl->getChat()->sendSuccess( "Added: " . $i . "/" . count($players), $player);
}
/**
* Add players to the guestlist
* handle Add GL command
*
* @param array $chat
* @param \ManiaControl\Players\Player $player
*/
public function doaddtogl(Array $chat, Player $player) {
*/
public function handleAdd(Array $chat, Player $player) {
$command = explode(" ", $chat[1][2]);
$peopletoadd = $command[1];
$playerToAdd = $command[1];
if (empty($peopletoadd)) {
$this->maniaControl->getChat()->sendError("You must set the nickname as argument", $player);
if (empty($playerToAdd)) {
$this->maniaControl->getChat()->sendError("You must set the login or the nickname as argument", $player);
} else {
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
$query = 'SELECT login FROM `' . PlayerManager::TABLE_PLAYERS . '` WHERE nickname LIKE "' . $peopletoadd . '"';
$result = $mysqli->query($query);
$stmt = $mysqli->prepare('SELECT `login` FROM `' . PlayerManager::TABLE_PLAYERS . '` WHERE nickname LIKE ? LIMIT 1;');
$stmt->bind_param('s', $playerToAdd);
$stmt->execute();
$result = $stmt->get_result();
$array = mysqli_fetch_array($result);
if (isset($array[0])) {
$login = $array[0];
} elseif (strlen($peopletoadd) == 22) {
$login = $peopletoadd ;
} elseif (strlen($playerToAdd) == 22) {
$login = $playerToAdd;
}
if ($mysqli->error) {
trigger_error($mysqli->error, E_USER_ERROR);
}
if (!isset($login)) {
$this->maniaControl->getChat()->sendError( "Login not found. FYI The player must be connected" , $player);
$this->maniaControl->getChat()->sendError("Player not found. Use the nickname of already connected player or just their login", $player);
} else {
if ($this->addLoginToGL($login)) {
$this->maniaControl->getChat()->sendSuccess( "Player " . $peopletoadd . " added to the Guestlist" , $player);
Logger::log('Player "'. $playerToAdd .'" added to the guestlist by '. $player->nickname);
$this->maniaControl->getChat()->sendSuccess('Player "' . $playerToAdd . '" added to the Guestlist', $player);
} else {
$this->maniaControl->getChat()->sendSuccess( "Player " . $peopletoadd . " already in the Guestlist" , $player);
$this->maniaControl->getChat()->sendSuccess('Player "' . $playerToAdd . '" already in the Guestlist', $player);
}
}
}
@ -161,15 +199,16 @@ class GuestlistManager implements CommandListener, Plugin {
*
* @param string $login
* @param array $guestlist
*/
public function addLoginToGL(String $login, array $guestlist = []) {
if (empty($guestlist)) {
*/
public function addLoginToGL(String $login, ?array $guestlist = null) {
if ($guestlist === null) {
$guestlist = $this->maniaControl->getClient()->getGuestList();
}
$logintoadd = "";
$logintoadd = array_search($login ,array_column($guestlist, 'login'));
if (strlen($logintoadd) == 0) {
if (!in_array($login, array_column($guestlist, 'login'))) {
Logger::log('Player "'. $login .'" added to the guestlist');
$this->maniaControl->getClient()->addGuest($login);
$this->checkNonGuestlistedPlayers = true;
return true;
} else {
return false;
@ -177,12 +216,78 @@ class GuestlistManager implements CommandListener, Plugin {
}
/**
* load from the guestlist file
* handle Remove from GL command
*
* @param array $chat
* @param Player $player
* @return void
*/
public function handleRemove(Array $chat, Player $player) {
$command = explode(" ", $chat[1][2]);
$playerToRemove = $command[1];
if (empty($playerToRemove)) {
$this->maniaControl->getChat()->sendError("You must set the login or the nickname as argument", $player);
} else {
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
$stmt = $mysqli->prepare('SELECT `login` FROM `' . PlayerManager::TABLE_PLAYERS . '` WHERE nickname LIKE ? LIMIT 1;');
$stmt->bind_param('s', $playerToRemove);
$stmt->execute();
$result = $stmt->get_result();
$array = mysqli_fetch_array($result);
if (isset($array[0])) {
$login = $array[0];
} elseif (strlen($playerToRemove) == 22) {
$login = $playerToRemove;
}
if ($mysqli->error) {
trigger_error($mysqli->error, E_USER_ERROR);
}
if (!isset($login)) {
$this->maniaControl->getChat()->sendError('Player not found. Use the nickname of already connected player or just their login', $player);
} else {
if ($this->removeLoginFromGL($login)) {
Logger::log('Player "'. $playerToRemove .'" removed from the guestlist by '. $player->nickname);
$this->maniaControl->getChat()->sendSuccess('Player "' . $playerToRemove . '" removed to the Guestlist', $player);
} else {
$this->maniaControl->getChat()->sendSuccess('Player "' . $playerToRemove . '" not in the Guestlist', $player);
}
}
}
}
/**
* Remove login from the guestlist
*
* @param string $login
* @param array $guestlist
*/
public function removeLoginFromGL(String $login, ?array $guestlist = null) {
if ($guestlist === null) {
$guestlist = $this->maniaControl->getClient()->getGuestList();
}
if (in_array($login, array_column($guestlist, 'login'))) {
Logger::log('Player "'. $login .'" removed from the guestlist');
$this->maniaControl->getClient()->removeGuest($login);
$this->checkNonGuestlistedPlayers = true;
return true;
} else {
return false;
}
}
/**
* hangle Load GL command
*
* @param array $chat
* @param \ManiaControl\Players\Player $player
*/
public function doloadgl(Array $chat, Player $player) {
*/
public function handleLoad(Array $chat, Player $player) {
$guestlist = '';
$text = explode(" ",$chat[1][2]);
if (count($text) > 1 && $text[1] != "") {
$guestlist = $text[1];
@ -193,30 +298,69 @@ class GuestlistManager implements CommandListener, Plugin {
} else {
$guestlist = $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_GUESTLIST_FILE);
}
if ($guestlist === "" || is_file($this->maniaControl->getServer()->getDirectory()->getUserDataFolder() . DIRECTORY_SEPARATOR . "Config" . DIRECTORY_SEPARATOR . $guestlist)) {
$this->maniaControl->getClient()->loadGuestList($guestlist);
$this->maniaControl->getChat()->sendSuccess( "Guestlist loaded!" , $player);
} else {
$this->maniaControl->getChat()->sendError("Impossible to load the guestlist file" , $player);
try {
if ($guestlist === "") {
Logger::log('Player "'. $player->nickname .'" loaded default guestlist');
$this->maniaControl->getClient()->loadGuestList();
$this->checkNonGuestlistedPlayers = true;
} else {
$filepath = $this->maniaControl->getServer()->getDirectory()->getUserDataFolder() . DIRECTORY_SEPARATOR . "Config" . DIRECTORY_SEPARATOR . $guestlist;
if (is_file($filepath)) {
Logger::log('Player "'. $player->nickname .'" loaded guestlist file: '. $guestlist);
$this->maniaControl->getClient()->loadGuestList($guestlist);
$this->checkNonGuestlistedPlayers = true;
} else {
$this->maniaControl->getChat()->sendError("No guestlist file: ". $filepath, $player);
Logger::logError("Can't load guestlist, no file: ". $filepath);
}
}
$this->maniaControl->getChat()->sendSuccess("Guestlist loaded!", $player);
} catch (\Throwable $th) {
$this->maniaControl->getChat()->sendError("Can't load guestlist: ". $th->getMessage(), $player);
Logger::logError("Can't load guestlist: ". $th->getMessage());
}
}
/**
* save to the guestlist file
* handle Save GL command
*
* @param array $chat
* @param \ManiaControl\Players\Player $player
*/
public function dosavegl(Array $chat, Player $player) {
try {
$guestlist = $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_GUESTLIST_FILE);
if ($guestlist !== "") {
$filepath = $this->maniaControl->getServer()->getDirectory()->getUserDataFolder() . DIRECTORY_SEPARATOR . "Config" . DIRECTORY_SEPARATOR . $guestlist;
*/
public function handleSave(Array $chat, Player $player) {
$guestlist = '';
$text = explode(" ",$chat[1][2]);
if (count($text) > 1 && $text[1] != "") {
$guestlist = $text[1];
if (!is_file($filepath)) {
file_put_contents($filepath, '<?xml version="1.0" encoding="utf-8" ?><guestlist></guestlist>');
}
if (substr($guestlist , -4) != ".txt" && substr($guestlist , -4) != ".xml") {
$guestlist .= ".txt";
}
} else {
$guestlist = $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_GUESTLIST_FILE);
}
if ($guestlist === "") {
$this->maniaControl->getChat()->sendError('No guestlist file provided');
return;
}
try {
$filepath = $this->maniaControl->getServer()->getDirectory()->getUserDataFolder() . DIRECTORY_SEPARATOR . "Config" . DIRECTORY_SEPARATOR . $guestlist;
$directory = dirname($filepath);
/**
* The server can't save a file if it was not loaded before: https://forum.nadeo.com/viewtopic.php?p=11976
* this is a workaround
*/
if (!is_dir($directory)) {
mkdir($directory, 0755, true);
}
if (!is_file($filepath)) {
file_put_contents($filepath, '<?xml version="1.0" encoding="utf-8" ?><guestlist></guestlist>');
}
// Workaround when the file was never loaded by the server
@ -228,9 +372,11 @@ class GuestlistManager implements CommandListener, Plugin {
$this->maniaControl->getClient()->addGuest($guest->login);
}
Logger::log('Player "'. $player->nickname .'" saved guestlist file: '. $guestlist);
$this->maniaControl->getClient()->saveGuestList($guestlist);
$this->checkNonGuestlistedPlayers = true;
$this->maniaControl->getChat()->sendSuccess("Guestlist saved!" , $player);
$this->maniaControl->getChat()->sendSuccess("Guestlist saved!", $player);
} catch (\Exception $e) {
Logger::logError("Impossible to save guestlist: " . $e->getMessage());
$this->maniaControl->getChat()->sendError("Impossible to save guestlist: " . $e->getMessage(), $player);
@ -238,13 +384,222 @@ class GuestlistManager implements CommandListener, Plugin {
}
/**
* clean the guestlist
* handle Clear GL command
*
* @param array $chat
* @param \ManiaControl\Players\Player $player
*/
public function docleangl(Array $chat, Player $player) {
*/
public function handleClear(Array $chat, Player $player) {
Logger::log('Guestlist cleared by '. $player->nickname);
$this->maniaControl->getClient()->cleanGuestList();
$this->maniaControl->getChat()->sendSuccess( "Guestlist cleaned!" , $player);
$this->checkNonGuestlistedPlayers = true;
$this->maniaControl->getChat()->sendSuccess("Guestlist cleaned!", $player);
if ($this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_ADD_ADMINS)) {
$this->maniaControl->getChat()->sendSuccess("Re-adding admins to the guestlist", $player);
$this->addAdminsToGuestlist();
}
}
/**
* handle Kick non-guestlisted players command
*
* @param array $chat
* @param \ManiaControl\Players\Player $player
*/
public function handleKickAll(Array $chat, Player $player) {
Logger::log('All non-guestlisted players kicked by '. $player->nickname);
$kicked = $this->kickNonGuestlistedPlayers();
$this->maniaControl->getChat()->sendSuccess($kicked . ' players kicked', $player);
}
/**
* handle Info command
*
* @param array $chat
* @param \ManiaControl\Players\Player $adminplayer
*/
public function handleInfo(Array $chat, Player $adminplayer) {
$guests = array_column($this->maniaControl->getClient()->getGuestList(), 'login');
$players = $this->maniaControl->getPlayerManager()->getPlayers(true);
$spectators = $this->maniaControl->getPlayerManager()->getSpectators();
$nbPlayersConnected = 0;
$nbSpectatorsConnected = 0;
$nbSpectatorsConnected = 0;
$nbPerRole[0] = 0;
$nbPerRoleConnected[0] = 0;
foreach ($guests as $login) {
$player = $this->maniaControl->getPlayerManager()->getPlayer($login);
if ($player === null) {
$nbPerRole[0]++;
} else {
$players = array_filter($players, function($obj) use ($player) {
return $obj !== $player;
});
$spectators = array_filter($spectators, function($obj) use ($player) {
return $obj !== $player;
});
if (!array_key_exists($player->authLevel, $nbPerRole)) {
$nbPerRole[$player->authLevel] = 0;
$nbPerRoleConnected[$player->authLevel] = 0;
}
$nbPerRole[$player->authLevel]++;
if ($player->isConnected) {
$nbPerRoleConnected[$player->authLevel]++;
if ($player->isSpectator) $nbSpectatorsConnected++;
else $nbPlayersConnected++;
}
}
}
$message = '================ Guestlist info ================';
$message .= PHP_EOL . '$<$ee0' . count($guests) . '$> guests in the guestlist. Type //gllist to get the list';
$message .= PHP_EOL . '====== Connected on the server:';
$message .= PHP_EOL . 'Guestlisted: $<$ee0'. $nbPlayersConnected . '$> players - $<$ee0'. $nbSpectatorsConnected .'$> spectators';
$message .= PHP_EOL . 'Not guestlisted: $<$ee0'. count($players) . '$> players - $<$ee0'. count($spectators) .'$> spectators';
$message .= PHP_EOL . '====== Per role:';
ksort($nbPerRole);
ksort($nbPerRoleConnected);
$part1 = PHP_EOL . 'Connected: ';
$part2 = PHP_EOL . 'Disconnected: ';
foreach ($nbPerRole as $authLevel => $count) {
$part1 .= '$<$ee0'. $nbPerRoleConnected[$authLevel] .'$> '. $this->maniaControl->getAuthenticationManager()->getAuthLevelName($authLevel) .'s - ';
$part2 .= '$<$ee0'. $count - $nbPerRoleConnected[$authLevel] .'$> '. $this->maniaControl->getAuthenticationManager()->getAuthLevelName($authLevel) .'s - ';
}
$message .= substr($part1, 0, -3) . substr($part2, 0, -3);
$this->maniaControl->getChat()->sendSuccess($message, $adminplayer);
}
/**
* handle List command
*
* @param array $chat
* @param \ManiaControl\Players\Player $adminplayer
*/
public function handleList(Array $chat, Player $adminplayer) {
$guests = array_column($this->maniaControl->getClient()->getGuestList(), 'login');
$logins = [];
$names = [];
$connectedNames = [];
foreach ($guests as $login) {
$player = $this->maniaControl->getPlayerManager()->getPlayer($login);
if ($player === null || $player->nickname === '') {
$logins[] = $login;
} else {
$names[] = $player->nickname;
if ($player->isConnected) {
$connectedNames[] = $player->nickname;
}
}
}
natcasesort($logins);
natcasesort($names);
$message = '================ Guestlist list ================'. PHP_EOL;
$message .= '====== Known players:'. PHP_EOL;
foreach ($names as $name) {
if (in_array($name, $connectedNames)) {
$message .= '$<$1c0' . $name . '$> ';
} else {
$message .= '$<$c00' . $name . '$> ';
}
}
$message .= PHP_EOL .'====== Unknown players:'. PHP_EOL;
foreach ($logins as $login) {
$message .= '$<$c00' . $login . '$> ';
}
$this->maniaControl->getChat()->sendSuccess($message, $adminplayer);
}
/**
* Kick non-guestlist players from the server
*
* @return int
*/
private function kickNonGuestlistedPlayers() {
$kicked = 0;
$guests = array_column($this->maniaControl->getClient()->getGuestList(), 'login');
foreach ($this->maniaControl->getPlayerManager()->getPlayers() as $player) {
if (!in_array($player->login, $guests)) {
try {
Logger::log('Player "'. $player->nickname .'" kicked from the server as not guestlisted');
$this->maniaControl->getClient()->kick($player->nickname, "You are not guestlisted on the server");
$kicked++;
} catch (\Throwable $th) {
Logger::logError("Can't kick ". $player->nickname .": ". $th->getMessage());
}
}
}
return $kicked;
}
/**
* add Admins to GL
*
* @param \ManiaControl\Players\Player $player
*/
private function addAdminsToGuestlist() {
if (!$this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_ADD_ADMINS)) return;
$guestlist = $this->maniaControl->getClient()->getGuestList();
$authLevel = $this->maniaControl->getAuthenticationManager()->getAuthLevelInt($this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_ADMIN_LEVEL));
$admins = $this->maniaControl->getAuthenticationManager()->getAdmins($authLevel);
foreach ($admins as $admin) {
$this->addLoginToGL($admin->login, $guestlist);
}
}
/**
* handle Auth Level changed callback
*
* @param \ManiaControl\Players\Player $player
*/
public function handleAuthLevelChanged(Player $player) {
if (!$this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_ADD_ADMINS)) return;
$guestlist = $this->maniaControl->getClient()->getGuestList();
$isGuestlisted = in_array($player->login, array_column($guestlist, 'login'));
$authLevel = $this->maniaControl->getAuthenticationManager()->getAuthLevelInt($this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_ADMIN_LEVEL));
$isAdmin = $this->maniaControl->getAuthenticationManager()->checkRight($player, $authLevel);
if (!$isGuestlisted && $isAdmin) {
$this->addLoginToGL($player->login, $guestlist);
$this->maniaControl->getChat()->sendSuccessToAdmins('New admin "'. $player->nickname . '" automatically added to the guestlist');
Logger::log('New admin "'. $player->nickname . '" automatically added to the guestlist');
} else if ($isGuestlisted && !$isAdmin) {
$this->maniaControl->getChat()->sendErrorToAdmins('Non-admin "'. $player->nickname . '" is still in the guestlist. Remove them manually if needed');
}
}
/**
* handle Player connect callback
*/
public function handlePlayerConnect() {
if (!$this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_ENFORCE_GUESTLIST)) return;
$this->checkNonGuestlistedPlayers = true;
}
/**
* handle Setting changed callback
*/
public function handleSettingChanged() {
if (!$this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_ENFORCE_GUESTLIST)) return;
$this->checkNonGuestlistedPlayers = true;
}
}

View File

@ -20,7 +20,7 @@ class MoreModesTools implements CommandListener, Plugin {
* Constants
*/
const PLUGIN_ID = 164;
const PLUGIN_VERSION = 1.1;
const PLUGIN_VERSION = 1.3;
const PLUGIN_NAME = 'MoreModesTools';
const PLUGIN_AUTHOR = 'Beu';
@ -82,7 +82,8 @@ class MoreModesTools implements CommandListener, Plugin {
$this->maniaControl->getCommandManager()->registerCommandListener('endround', $this, 'onCommandEndRound', true, 'End the round');
$this->maniaControl->getCommandManager()->registerCommandListener(['endwu', 'endwarmup'], $this, 'onCommandEndWarmUp', true, 'End the WarmUp');
$this->maniaControl->getCommandManager()->registerCommandListener(['extendwu', 'extendwarmup'], $this, 'onCommandExtendWarmUp', true, 'If the warm up has a time limit, increase it');
$this->maniaControl->getCommandManager()->registerCommandListener('setpoints', $this, 'onCommandSetPoints', true, 'Set Points for a player or a team');
$this->maniaControl->getCommandManager()->registerCommandListener('setpoints', $this, 'onCommandSetPoints', true, 'Set Points for a player');
$this->maniaControl->getCommandManager()->registerCommandListener('setteampoints', $this, 'onCommandSetTeamPoints', true, 'Set Points for a team');
return true;
}
@ -147,7 +148,6 @@ class MoreModesTools implements CommandListener, Plugin {
$text = $chat[1][2];
$text = explode(" ", $text);
if (is_numeric($text[1])) {
var_dump($text[1]);
$this->maniaControl->getModeScriptEventManager()->triggerModeScriptEvent("Trackmania.WarmUp.Extend", [ strval(intval($text[1]) * 1000)]);
$this->maniaControl->getChat()->sendSuccessToAdmins('Extend Warmup Sent');
} else {
@ -156,60 +156,131 @@ class MoreModesTools implements CommandListener, Plugin {
}
/**
* Send SetPoints
* Command //setpoints for admin
*
* @param array $chat
* @param array $chatCallback
* @param \ManiaControl\Players\Player $player
*/
public function onCommandSetPoints(Array $chat, Player $player) {
$text = $chat[1][2];
public function onCommandSetPoints(array $chatCallback, Player $adminplayer) {
$text = $chatCallback[1][2];
$text = explode(" ", $text);
if (isset($text[1]) && isset($text[2]) && is_numeric($text[2]) && $text[2] >= 0 ) {
if (strcasecmp($text[1], "Blue") == 0 || $text[1] == "0") {
$this->maniaControl->getModeScriptEventManager()->setTrackmaniaTeamPoints("0", "", $text[2], $text[2]);
$this->maniaControl->getChat()->sendSuccess('$<$00fBlue$> Team now has $<$ff0' . $text[2] . '$> points!');
} elseif (strcasecmp($text[1], "Red") == 0 || $text[1] == "1") {
$this->maniaControl->getModeScriptEventManager()->setTrackmaniaTeamPoints("1", "", $text[2] , $text[2]);
$this->maniaControl->getChat()->sendSuccess('$<$f00Red$> Team now has $<$ff0' . $text[2] . '$> points!');
} elseif (is_numeric($text[1])) {//TODO: add support of name of teams (need update from NADEO)
$this->maniaControl->getModeScriptEventManager()->setTrackmaniaTeamPoints($text[1], "", $text[2] , $text[2]);
$this->maniaControl->getChat()->sendSuccess('Team ' . $text[1] . ' now has $<$ff0' . $text[2] . '$> points!');
if (count($text) < 3) {
$this->maniaControl->getChat()->sendError('Missing parameters. Eg: //setpoints <Player Name or Login> <Match points> <Map Points (optional)> <Round Points (optional)>', $adminplayer);
return;
}
$target = $text[1];
$matchpoints = $text[2];
$mappoints = '';
$roundpoints = '';
if (!is_numeric($matchpoints)) {
$this->maniaControl->getChat()->sendError('Invalid argument: Match points', $adminplayer);
return;
}
if (isset($text[3])) {
$mappoints = $text[3];
if (!is_numeric($mappoints)) {
$this->maniaControl->getChat()->sendError('Invalid argument: Map points', $adminplayer);
return;
}
}
if (isset($text[4])) {
$roundpoints = $text[4];
if (!is_numeric($roundpoints)) {
$this->maniaControl->getChat()->sendError('Invalid argument: Round points', $adminplayer);
return;
}
}
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
$stmt = $mysqli->prepare('SELECT login FROM `' . PlayerManager::TABLE_PLAYERS . '` WHERE nickname LIKE ?');
$stmt->bind_param('s', $target);
if (!$stmt->execute()) {
Logger::logError('Error executing MySQL query: '. $stmt->error);
}
$result = $stmt->get_result();
$array = mysqli_fetch_array($result);
if (isset($array[0])) {
$login = $array[0];
} elseif (strlen($target) == 22) {
$login = $target;
}
if ($mysqli->error) {
trigger_error($mysqli->error, E_USER_ERROR);
}
if (isset($login)) {
$player = $this->maniaControl->getPlayerManager()->getPlayer($login,true);
if ($player) {
$this->maniaControl->getModeScriptEventManager()->setTrackmaniaPlayerPoints($player, $roundpoints, $mappoints, $matchpoints);
$this->maniaControl->getChat()->sendSuccess('Player $<$ff0' . $player->nickname . '$> now has $<$ff0' . $matchpoints . '$> points!');
} else {
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
$query = $mysqli->prepare('SELECT login FROM `' . PlayerManager::TABLE_PLAYERS . '` WHERE nickname LIKE ?');
$query->bind_param('s', $text[1]);
if (!$query->execute()) {
trigger_error('Error executing MySQL query: ' . $query->error);
return;
}
$result = $query->get_result();
$array = mysqli_fetch_array($result);
if (isset($array[0])) {
$login = $array[0];
} elseif (strlen($text[1]) == 22) {
$login = $text[1];
}
if ($mysqli->error) {
trigger_error($mysqli->error, E_USER_ERROR);
}
if (isset($login)) {
$playerpoints = $this->maniaControl->getPlayerManager()->getPlayer($login, true);
if ($player) {
$this->maniaControl->getModeScriptEventManager()->setTrackmaniaPlayerPoints($playerpoints, "", "", $text[2]);
$this->maniaControl->getChat()->sendSuccess('Player $<$ff0' . $playerpoints->nickname . '$> now has $<$ff0' . $text[2] . '$> points!');
} else {
$this->maniaControl->getChat()->sendError('Player ' . $text[1] . " isn't connected", $player);
}
} else {
$this->maniaControl->getChat()->sendError('Player ' . $text[1] . " doesn't exist", $player);
}
$this->maniaControl->getChat()->sendError('Player ' . $target . " isn't connected", $adminplayer);
}
} else {
$this->maniaControl->getChat()->sendError($this->chatprefix . 'Missing or invalid parameters', $player);
$this->maniaControl->getChat()->sendError('Player ' . $target . " doesn't exist", $adminplayer);
}
}
/**
* Command //setteampoints for admin
*
* @param array $chatCallback
* @param Player $adminplayer
*/
public function onCommandSetTeamPoints(array $chatCallback, Player $adminplayer) {
$text = $chatCallback[1][2];
$text = explode(" ", $text);
if (count($text) < 3) {
$this->maniaControl->getChat()->sendError('Missing parameters. Eg: //setteampoints <Team Name or Id> <Match points> <Map Points (optional)> <Round Points (optional)>', $adminplayer);
return;
}
$target = $text[1];
$matchpoints = $text[2];
$mappoints = '';
$roundpoints = '';
if (!is_numeric($matchpoints)) {
$this->maniaControl->getChat()->sendError('Invalid argument: Match points', $adminplayer);
return;
}
if (isset($text[3])) {
$mappoints = $text[3];
if (!is_numeric($mappoints)) {
$this->maniaControl->getChat()->sendError('Invalid argument: Map points', $adminplayer);
return;
}
}
if (isset($text[4])) {
$roundpoints = $text[4];
if (!is_numeric($roundpoints)) {
$this->maniaControl->getChat()->sendError('Invalid argument: Round points', $adminplayer);
return;
}
}
if (strcasecmp($target, "Blue") == 0 || $target == "0") {
$this->maniaControl->getModeScriptEventManager()->setTrackmaniaTeamPoints("0", $roundpoints, $mappoints, $matchpoints);
$this->maniaControl->getChat()->sendSuccess('$<$00fBlue$> Team now has $<$ff0' . $matchpoints . '$> points!');
} elseif (strcasecmp($target, "Red") == 0 || $target == "1") {
$this->maniaControl->getModeScriptEventManager()->setTrackmaniaTeamPoints("1", $roundpoints, $mappoints, $matchpoints);
$this->maniaControl->getChat()->sendSuccess('$<$f00Red$> Team now has $<$ff0' . $matchpoints . '$> points!');
} elseif (is_numeric($target)) { //TODO: add support of name of teams (need update from NADEO)
$this->maniaControl->getModeScriptEventManager()->setTrackmaniaTeamPoints($target, $roundpoints, $mappoints, $matchpoints);
$this->maniaControl->getChat()->sendSuccess('Team ' . $target . ' now has $<$ff0' . $matchpoints . '$> points!');
} else {
$this->maniaControl->getChat()->sendError('Can\'t find team: ' . $target, $adminplayer);
}
}
}

216
Beu/OpenplanetDetector.php Normal file
View File

@ -0,0 +1,216 @@
<?php
namespace Beu;
use Exception;
use ManiaControl\ManiaControl;
use ManiaControl\Plugins\Plugin;
use ManiaControl\Logger;
use ManiaControl\Callbacks\CallbackListener;
use ManiaControl\Manialinks\ManialinkPageAnswerListener;
use ManiaControl\Players\Player;
use ManiaControl\Players\PlayerManager;
use Maniaplanet\DedicatedServer\InvalidArgumentException;
/**
* OpenplanetDetector
*
* @author Beu
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
*/
class OpenplanetDetector implements ManialinkPageAnswerListener, CallbackListener, Plugin {
/*
* Constants
*/
const PLUGIN_ID = 203;
const PLUGIN_VERSION = 1.1;
const PLUGIN_NAME = 'Openplanet Detector';
const PLUGIN_AUTHOR = 'Beu';
const SETTING_SIGNATURE_BLACKLIST = 'Openplanet Signature blacklist';
const SETTING_SIGNATURE_WHITELIST = 'Openplanet Signature whitelist';
const SETTING_ACTION = 'Action for player';
const ACTION_KICK = 'kick';
const ACTION_FORCE_AS_SPEC = 'force as spec';
/*
* Private properties
*/
/** @var ManiaControl $maniaControl */
private $maniaControl = null;
private $manialink = null;
/**
* @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 "Detect Openplanet and allow to force as spec and kick players";
}
/**
* @see \ManiaControl\Plugins\Plugin::load()
*/
public function load(ManiaControl $maniaControl) {
$this->maniaControl = $maniaControl;
$this->manialink = $this->getManialink();
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_SIGNATURE_BLACKLIST, "DEVMODE", "Comma separated signature banned (Only used is whitelist is empty)");
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_SIGNATURE_WHITELIST, "", "Comma separated signature allowed.");
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_ACTION, [self::ACTION_FORCE_AS_SPEC, self::ACTION_KICK], "");
$this->maniaControl->getCallbackManager()->registerCallbackListener(PlayerManager::CB_PLAYERCONNECT, $this, 'handlePlayerConnect');
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerRegexListener('/^Maniacontrol.OpenplanetDetector:/', $this, 'handleOpenplanetSignature');
$this->maniaControl->getManialinkManager()->sendManialink($this->manialink);
}
/**
* handleOpenplanetSignature
*
* @param array $callback
* @param Player $player
* @return void
*/
public function handleOpenplanetSignature(array $callback, Player $player) {
$whitelist = array_filter(explode(',', $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_SIGNATURE_WHITELIST)));
$signature = explode(':', $callback[1][2])[1];
if ($signature === "") $signature = "REGULAR";
if (count($whitelist) > 0) {
if (!in_array($signature, $whitelist)) {
$this->triggerAction($player, $signature);
}
} else {
$blacklist = array_filter(explode(',', $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_SIGNATURE_BLACKLIST)));
if (in_array($signature, $blacklist)) {
$this->triggerAction($player, $signature);
}
}
}
/**
* triggerAction
*
* @param Player $player
* @param string $signature
* @return void
* @throws InvalidArgumentException
*/
private function triggerAction(Player $player, string $signature) {
$this->maniaControl->getChat()->sendInformationToAdmins("Player ". $player->nickname ." has the wrong Openplanet Signature: " . $signature);
Logger::log("Player ". $player->nickname ." has the wrong Openplanet Signature: " . $signature);
try {
switch ($this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_ACTION)) {
case self::ACTION_FORCE_AS_SPEC:
$this->maniaControl->getClient()->forceSpectator($player->login, 1);
$this->maniaControl->getChat()->sendInformation("Your Openplanet signature is not allowed. Change it and try to re-join the server", $player->login);
break;
case self::ACTION_KICK:
$this->maniaControl->getClient()->kick($player->login, "Your Openplanet signature is not allowed. Change it and try to re-join the server");
break;
}
} catch (\Throwable $th) {
$this->maniaControl->getChat()->sendErrorToAdmins("Can't apply action on ". $player->nickname .": " . $th->getMessage());
Logger::logError("Can't apply action on ". $player->nickname .": " . $th->getMessage());
}
}
/**
* Handle when a player connects
*
* @param Player $player
*/
public function handlePlayerConnect(Player $player) {
$this->maniaControl->getManialinkManager()->sendManialink($this->manialink, $player->login);
}
/**
* Unload the plugin and its Resources
*/
public function unload() {}
/**
* getManialink
*
* @return string
*/
private function getManialink() {
return <<<'EOD'
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<manialink version="3" id="Maniacontrol.OpenplanetDetector" name="Maniacontrol.OpenplanetDetector">
<script><!--
#Include "TextLib" as TL
Boolean GetOpenplanet() {
return (TL::RegexFind("^Openplanet ", System.ExtraTool_Info, "").count > 0);
}
Text GetOpenplanetSignature() {
if (GetOpenplanet()) {
declare Text[] SignatureMode = TL::RegexMatch(" \\[([A-Z]*)\\]$", System.ExtraTool_Info, "");
if (SignatureMode.count >= 2) {
return SignatureMode[1];
}
}
return "";
}
main () {
log("Init Maniacontrol.OpenplanetDetector");
wait(InputPlayer != Null);
declare Text Last_ExtraTool_Info;
while (True) {
yield;
if (Last_ExtraTool_Info != System.ExtraTool_Info) {
Last_ExtraTool_Info = System.ExtraTool_Info;
if (GetOpenplanet()) {
TriggerPageAction("Maniacontrol.OpenplanetDetector:" ^ GetOpenplanetSignature());
}
}
}
}
--></script>
</manialink>
EOD;
}
}

176
Beu/SmallTextOverlay.php Normal file
View File

@ -0,0 +1,176 @@
<?php
namespace Beu;
use FML\Controls\Control;
use FML\Controls\Frame;
use FML\Controls\Label;
use FML\ManiaLink;
use ManiaControl\ManiaControl;
use ManiaControl\Plugins\Plugin;
use ManiaControl\Players\PlayerManager;
use ManiaControl\Callbacks\CallbackListener;
use ManiaControl\Callbacks\TimerListener;
use ManiaControl\Players\Player;
use ManiaControl\Settings\Setting;
use ManiaControl\Settings\SettingManager;
/**
* SmallTextOverlay
*
* @author Beu
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
*/
class SmallTextOverlay implements TimerListener, CallbackListener, Plugin {
/*
* Constants
*/
const PLUGIN_ID = 195;
const PLUGIN_VERSION = 1.0;
const PLUGIN_NAME = 'SmallTextOverlay';
const PLUGIN_AUTHOR = 'Beu';
const SETTING_PRIMARY_TEXT = "Primary Text";
const SETTING_SECONDARY_TEXT = "Secondary Text";
const MLID_SMALLTEXTAD = "SmallTextOverlay";
/*
* Private properties
*/
/** @var ManiaControl $maniaControl */
private $maniaControl = null;
private $manialink = null;
/**
* @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 "Just add 2 text value on the bottom right of the screen, with settings as value";
}
/**
* @see \ManiaControl\Plugins\Plugin::load()
*/
public function load(ManiaControl $maniaControl) {
$this->maniaControl = $maniaControl;
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_PRIMARY_TEXT, "Primary Text");
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_SECONDARY_TEXT, "Secondary Text");
$this->maniaControl->getCallbackManager()->registerCallbackListener(PlayerManager::CB_PLAYERCONNECT, $this, 'handlePlayerConnect');
$this->maniaControl->getCallbackManager()->registerCallbackListener(SettingManager::CB_SETTING_CHANGED, $this, 'updateSettings');
$this->generateManialink();
$this->maniaControl->getManialinkManager()->sendManialink($this->manialink);
$this->maniaControl->getTimerManager()->registerTimerListening($this, 'handle5Minutes', 300000);
}
/**
* Handle when a player connects
*
* @param Player $player
*/
public function handlePlayerConnect(Player $player) {
$this->maniaControl->getManialinkManager()->sendManialink($this->manialink, $player->login);
}
/**
* updateSettings
*
* @param Setting $setting
* @return void
*/
public function updateSettings(Setting $setting = null) {
if ($setting !== null && !$setting->belongsToClass($this)) {
return;
}
$this->generateManialink();
$this->maniaControl->getManialinkManager()->sendManialink($this->manialink);
}
/**
* handle5Minutes
*
* @return void
*/
public function handle5Minutes() {
// update UI if updated by an another
$this->generateManialink();
$this->maniaControl->getManialinkManager()->sendManialink($this->manialink);
}
/**
* generateManialink
*
* @return void
*/
private function generateManialink() {
$manialink = new ManiaLink(self::MLID_SMALLTEXTAD);
$frame = new Frame();
$manialink->addChild($frame);
$frame->setX(159.);
$frame->setY(-60.);
$primaryLabel = new Label();
$frame->addChild($primaryLabel);
$primaryLabel->setTextSize(3.5);
$primaryLabel->setTextFont("GameFontExtraBold");
$primaryLabel->setTextEmboss(true);
$primaryLabel->setHorizontalAlign(Control::RIGHT);
$primaryLabel->setText($this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_PRIMARY_TEXT));
$secondaryLabel = new Label();
$frame->addChild($secondaryLabel);
$secondaryLabel->setY(-6.);
$secondaryLabel->setTextSize(2.5);
$secondaryLabel->setTextFont("GameFontExtraBold");
$secondaryLabel->setTextEmboss(true);
$secondaryLabel->setHorizontalAlign(Control::RIGHT);
$secondaryLabel->setText($this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_SECONDARY_TEXT));
$this->manialink = $manialink;
}
/**
* Unload the plugin and its Resources
*/
public function unload() {
$this->maniaControl->getManialinkManager()->hideManialink(self::MLID_SMALLTEXTAD);
}
}

View File

@ -6,34 +6,20 @@ use FML\Controls\Frame;
use FML\Controls\Label;
use FML\Controls\Quad;
use FML\ManiaLink;
use ManiaControl\Admin\AuthenticationManager;
use ManiaControl\Manialinks\ManialinkManager;
use ManiaControl\Manialinks\ManialinkPageAnswerListener;
use ManiaControl\Callbacks\CallbackListener;
use ManiaControl\Logger;
use ManiaControl\ManiaControl;
use ManiaControl\Plugins\Plugin;
use ManiaControl\Plugins\PluginManager;
use ManiaControl\Plugins\PluginMenu;
use ManiaControl\Settings\Setting;
use ManiaControl\Settings\SettingManager;
use ManiaControl\Callbacks\TimerListener;
use ManiaControl\Callbacks\Callbacks;
use ManiaControl\Callbacks\CallbackManager;
use ManiaControl\Players\Player;
use ManiaControl\Players\PlayerManager;
use ManiaControl\Script\InvokeScriptCallback;
if (!class_exists('MatchManagerSuite\MatchManagerCore')) {
$this->maniaControl->getChat()->sendErrorToAdmins('MatchManager Core is required to use one of MatchManager plugin. Install it and restart Maniacontrol');
Logger::logError('MatchManager Core is required to use one of MatchManager plugin. Install it and restart Maniacontrol');
return false;
}
/**
* MatchManager Admin UI
*
@ -45,38 +31,29 @@ class MatchManagerAdminUI implements CallbackListener, ManialinkPageAnswerListen
* Constants
*/
const PLUGIN_ID = 174;
const PLUGIN_VERSION = 1;
const PLUGIN_VERSION = 2.1;
const PLUGIN_NAME = 'MatchManager Admin UI';
const PLUGIN_AUTHOR = 'Beu';
const MLID_ADMINUI_SIDEMENU = 'Matchmanager.AdminUI';
const ML_ACTION_CORE_MANAGESETTINGS = 'MatchManager.AdminUI.ManageSettings';
const ML_ACTION_CORE_STOPMATCH = 'MatchManager.AdminUI.StopMatch';
const ML_ACTION_CORE_PAUSEMATCH = 'MatchManager.AdminUI.PauseMatch';
const ML_ACTION_CORE_SKIPROUND = 'MatchManager.AdminUI.SkipRound';
const ML_ACTION_CORE_STARTMATCH = 'MatchManager.AdminUI.StartMatch';
const ML_ACTION_MULTIPLECONFIGMANAGER_OPENCONFIGMANAGER = 'MatchManager.AdminUI.OpenConfigManager';
const ML_ACTION_GSHEET_MANAGESETTINGS = 'MatchManager.AdminUI.ManageGSheet';
const SETTING_POSX = 'Position X of the plugin';
const SETTING_POSY = 'Position Y of the plugin';
const SETTING_ADMIN_LEVEL = 'Minimum Admin level to see the Admin UI';
// MatchManagerWidget Properties
const MATCHMANAGERCORE_PLUGIN = 'MatchManagerSuite\MatchManagerCore';
const MATCHMANAGERGSHEET_PLUGIN = 'MatchManagerSuite\MatchManagerGSheet';
const MATCHMANAGERMULTIPLECONFIGMANAGER_PLUGIN = 'MatchManagerSuite\MatchManagerMultipleConfigManager';
const ML_ITEM_SIZE = 6.;
/*
* Private properties
*/
/** @var ManiaControl $maniaControl */
private $maniaControl = null;
/** @var \MatchManagerSuite\MatchManagerCore */
private $MatchManagerCore = null;
private $manialink = null;
private $updateManialink = true;
/** @var MatchManagerAdminUI_MenuItem[] */
private $menuItems = [];
/**
* @param \ManiaControl\ManiaControl $maniaControl
@ -128,40 +105,14 @@ class MatchManagerAdminUI implements CallbackListener, ManialinkPageAnswerListen
public function load(ManiaControl $maniaControl) {
// Init plugin
$this->maniaControl = $maniaControl;
if (!$this->maniaControl->getPluginManager()->getSavedPluginStatus(self::MATCHMANAGERCORE_PLUGIN)) {
throw new \Exception('MatchManager Core is needed to use ' . self::PLUGIN_NAME);
}
if ($this->maniaControl->getPluginManager()->getSavedPluginStatus(self::MATCHMANAGERCORE_PLUGIN)) {
// plugin are loaded in alphabetic order, just wait 1 sec before trying to load MatchManager Core
$this->maniaControl->getTimerManager()->registerOneTimeListening($this, function () {
$this->MatchManagerCore = $this->maniaControl->getPluginManager()->getPlugin(self::MATCHMANAGERCORE_PLUGIN);
if ($this->MatchManagerCore === null) {
$this->maniaControl->getChat()->sendErrorToAdmins('MatchManager Core is needed to use ' . self::PLUGIN_NAME . ' plugin.');
$this->maniaControl->getPluginManager()->deactivatePlugin((get_class()));
} else {
$this->generateManialink();
$this->displayManialink();
}
}, 1000);
} else {
throw new \Exception('MatchManager Core is needed to use ' . self::PLUGIN_NAME);
}
$this->maniaControl->getCallbackManager()->registerCallbackListener(PluginManager::CB_PLUGIN_LOADED, $this, 'handlePluginLoaded');
$this->maniaControl->getCallbackManager()->registerCallbackListener(PluginManager::CB_PLUGIN_UNLOADED, $this, 'handlePluginUnloaded');
$this->maniaControl->getCallbackManager()->registerCallbackListener(Callbacks::AFTERLOOP, $this, 'handleAfterLoop');
$this->maniaControl->getCallbackManager()->registerCallbackListener(SettingManager::CB_SETTING_CHANGED, $this, 'updateSettings');
$this->maniaControl->getCallbackManager()->registerCallbackListener(PlayerManager::CB_PLAYERCONNECT, $this, 'handlePlayerConnect');
$this->maniaControl->getCallbackManager()->registerCallbackListener(Callbacks::MP_STARTMATCHSTART, $this, 'generateManialink');
$this->maniaControl->getCallbackManager()->registerCallbackListener(MatchManagerCore::CB_MATCHMANAGER_STARTMATCH, $this, 'generateManialink');
$this->maniaControl->getCallbackManager()->registerCallbackListener(MatchManagerCore::CB_MATCHMANAGER_ENDMATCH, $this, 'generateManialink');
$this->maniaControl->getCallbackManager()->registerCallbackListener(MatchManagerCore::CB_MATCHMANAGER_STOPMATCH, $this, 'generateManialink');
$this->maniaControl->getCallbackManager()->registerCallbackListener(CallbackManager::CB_MP_PLAYERMANIALINKPAGEANSWER, $this, 'handleManialinkPageAnswer');
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_POSX, 156., "");
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_POSY, 24., "");
$this->maniaControl->getAuthenticationManager()->definePluginPermissionLevel($this, self::SETTING_ADMIN_LEVEL, AuthenticationManager::AUTH_LEVEL_ADMIN);
return true;
}
@ -173,6 +124,18 @@ class MatchManagerAdminUI implements CallbackListener, ManialinkPageAnswerListen
$this->maniaControl->getManialinkManager()->hideManialink(self::MLID_ADMINUI_SIDEMENU);
}
/**
* afterPluginInit
*
* @return void
*/
public function handleAfterLoop() {
if ($this->updateManialink) {
$this->updateManialink = false;
$this->generateManialink();
}
}
/**
* Update Widgets on Setting Changes
*
@ -180,7 +143,7 @@ class MatchManagerAdminUI implements CallbackListener, ManialinkPageAnswerListen
*/
public function updateSettings(Setting $setting) {
if ($setting->belongsToClass($this)) {
$this->generateManialink();
$this->updateManialink = true;
}
}
@ -190,8 +153,9 @@ class MatchManagerAdminUI implements CallbackListener, ManialinkPageAnswerListen
* @param Player $player
*/
public function handlePlayerConnect(Player $player) {
if ($player->authLevel > 0) {
$this->maniaControl->getManialinkManager()->sendManialink($this->manialink,$player->login);
$authLevel = $this->maniaControl->getAuthenticationManager()->getAuthLevelInt($this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_ADMIN_LEVEL));
if ($this->maniaControl->getAuthenticationManager()->checkRight($player, $authLevel)) {
$this->maniaControl->getManialinkManager()->sendManialink($this->manialink, $player->login);
}
}
@ -201,73 +165,12 @@ class MatchManagerAdminUI implements CallbackListener, ManialinkPageAnswerListen
* @return void
*/
private function displayManialink() {
$admins = $this->maniaControl->getAuthenticationManager()->getAdmins();
if (!empty($admins)) {
$authLevel = $this->maniaControl->getAuthenticationManager()->getAuthLevelInt($this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_ADMIN_LEVEL));
$admins = $this->maniaControl->getAuthenticationManager()->getAdmins($authLevel);
if (count($admins) > 0) {
$this->maniaControl->getManialinkManager()->sendManialink($this->manialink, $admins);
}
}
/**
* handleManialinkPageAnswer
*
* @param array $callback
* @return void
*/
public function handleManialinkPageAnswer(array $callback) {
$actionId = $callback[1][2];
$actionArray = explode('.', $actionId);
if ($actionArray[0] != "MatchManager" || $actionArray[1] != "AdminUI") {
return;
}
$login = $callback[1][1];
$player = $this->maniaControl->getPlayerManager()->getPlayer($login);
if ($player->authLevel <= 0) {
return;
}
switch ($actionId) {
case self::ML_ACTION_CORE_MANAGESETTINGS:
$pluginMenu = $this->maniaControl->getPluginManager()->getPluginMenu();
if (defined("\ManiaControl\ManiaControl::ISTRACKMANIACONTROL")) {
$player->setCache($pluginMenu, PluginMenu::CACHE_SETTING_CLASS, "PluginMenu.Settings." . self::MATCHMANAGERCORE_PLUGIN);
} else {
$player->setCache($pluginMenu, PluginMenu::CACHE_SETTING_CLASS, self::MATCHMANAGERCORE_PLUGIN);
}
$this->maniaControl->getConfigurator()->showMenu($player, $pluginMenu);
break;
case self::ML_ACTION_CORE_STOPMATCH:
$this->MatchManagerCore->MatchStop();
break;
case self::ML_ACTION_CORE_PAUSEMATCH:
$this->MatchManagerCore->setNadeoPause();
break;
case self::ML_ACTION_CORE_SKIPROUND:
$this->MatchManagerCore->onCommandMatchEndWU(array(), $player);
$this->MatchManagerCore->onCommandUnsetPause(array(), $player);
$this->MatchManagerCore->onCommandMatchEndRound(array(), $player);
break;
case self::ML_ACTION_CORE_STARTMATCH:
$this->MatchManagerCore->MatchStart();
break;
case self::ML_ACTION_MULTIPLECONFIGMANAGER_OPENCONFIGMANAGER:
/** @var \MatchManagerSuite\MatchManagerMultipleConfigManager */
$MatchManagerMultipleConfigManager = $this->maniaControl->getPluginManager()->getPlugin(self::MATCHMANAGERMULTIPLECONFIGMANAGER_PLUGIN);
if ($MatchManagerMultipleConfigManager !== null) {
$MatchManagerMultipleConfigManager->showConfigListUI(array(), $player);
}
break;
case self::ML_ACTION_GSHEET_MANAGESETTINGS:
$pluginMenu = $this->maniaControl->getPluginManager()->getPluginMenu();
if (defined("\ManiaControl\ManiaControl::ISTRACKMANIACONTROL")) {
$player->setCache($pluginMenu, PluginMenu::CACHE_SETTING_CLASS, "PluginMenu.Settings." . self::MATCHMANAGERGSHEET_PLUGIN);
} else {
$player->setCache($pluginMenu, PluginMenu::CACHE_SETTING_CLASS, self::MATCHMANAGERGSHEET_PLUGIN);
}
$this->maniaControl->getConfigurator()->showMenu($player, $pluginMenu);
break;
}
}
/**
* generate, store and automatically send it to the admin
@ -275,8 +178,6 @@ class MatchManagerAdminUI implements CallbackListener, ManialinkPageAnswerListen
* @return void
*/
public function generateManialink() {
if ($this->MatchManagerCore === null) return;
$itemSize = 6.;
$quadStyle = $this->maniaControl->getManialinkManager()->getStyleManager()->getDefaultQuadStyle();
$quadSubstyle = $this->maniaControl->getManialinkManager()->getStyleManager()->getDefaultQuadSubstyle();
$itemMarginFactorX = 1.3;
@ -290,172 +191,174 @@ class MatchManagerAdminUI implements CallbackListener, ManialinkPageAnswerListen
$posX = $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_POSX);
$posY = $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_POSY);
// Admin Menu Icon Frame
$iconFrame = new Frame();
$frame->addChild($iconFrame);
$iconFrame->setPosition($posX, $posY);
if (count($this->menuItems) > 0) {
// Admin Menu Icon Frame
$iconFrame = new Frame();
$frame->addChild($iconFrame);
$iconFrame->setPosition($posX, $posY);
$backgroundQuad = new Quad();
$iconFrame->addChild($backgroundQuad);
$backgroundQuad->setSize($itemSize * $itemMarginFactorX, $itemSize * $itemMarginFactorY);
$backgroundQuad->setStyles($quadStyle, $quadSubstyle);
$backgroundQuad->setZ(-1.);
$backgroundQuad = new Quad();
$iconFrame->addChild($backgroundQuad);
$backgroundQuad->setSize(self::ML_ITEM_SIZE * $itemMarginFactorX, self::ML_ITEM_SIZE * $itemMarginFactorY);
$backgroundQuad->setStyles($quadStyle, $quadSubstyle);
$backgroundQuad->setZ(-1.);
$itemQuad = new Label();
$iconFrame->addChild($itemQuad);
$itemQuad->setText('$fc3$w🏆$m');
$itemQuad->setSize($itemSize, $itemSize);
$itemQuad->setAreaFocusColor("00000000");
$itemQuad->setAreaColor("00000000");
$itemQuad = new Label();
$iconFrame->addChild($itemQuad);
$itemQuad->setText('$fc3$w🏆$m');
$itemQuad->setSize(self::ML_ITEM_SIZE, self::ML_ITEM_SIZE);
$itemQuad->setAreaFocusColor("00000000");
$itemQuad->setAreaColor("00000000");
// Admin Menu Description
$descriptionLabel = new Label();
$frame->addChild($descriptionLabel);
$descriptionLabel->setAlign($descriptionLabel::RIGHT, $descriptionLabel::TOP);
$descriptionLabel->setSize(40, 4);
$descriptionLabel->setTextSize(1);
$descriptionLabel->setTextColor('fff');
$descriptionLabel->setTextPrefix('$s');
// Admin Menu Description
$descriptionLabel = new Label();
$frame->addChild($descriptionLabel);
$descriptionLabel->setAlign(Label::RIGHT, Label::TOP);
$descriptionLabel->setSize(40, 4);
$descriptionLabel->setTextSize(1);
$descriptionLabel->setTextColor('fff');
$descriptionLabel->setTextPrefix('$s');
// Admin Menu
$popoutFrame = new Frame();
$frame->addChild($popoutFrame);
$popoutFrame->setPosition($posX - $itemSize * 0.5, $posY);
$popoutFrame->setHorizontalAlign($popoutFrame::RIGHT);
$popoutFrame->setVisible(false);
// Admin Menu
$popoutFrame = new Frame();
$frame->addChild($popoutFrame);
$popoutFrame->setPosition($posX - self::ML_ITEM_SIZE * 0.5, $posY);
$popoutFrame->setHorizontalAlign($popoutFrame::RIGHT);
$popoutFrame->setVisible(false);
$backgroundQuad = new Quad();
$popoutFrame->addChild($backgroundQuad);
$backgroundQuad->setHorizontalAlign($backgroundQuad::RIGHT);
$backgroundQuad->setStyles($quadStyle, $quadSubstyle);
$backgroundQuad = new Quad();
$popoutFrame->addChild($backgroundQuad);
$backgroundQuad->setHorizontalAlign($backgroundQuad::RIGHT);
$backgroundQuad->setStyles($quadStyle, $quadSubstyle);
$backgroundQuad->setZ(-1.);
$backgroundQuad->setZ(-1.);
$itemQuad->addToggleFeature($popoutFrame);
$itemQuad->addToggleFeature($popoutFrame);
// Add items
$itemPosX = -4.;
// Add items
$itemPosX = -1;
// sort by Order desc
usort($this->menuItems, function($a, $b) {
return $b->getOrder() <=> $a->getOrder();
});
// Settings:
$menuQuad = new Quad();
$popoutFrame->addChild($menuQuad);
$menuQuad->setStyle("UICommon64_1");
$menuQuad->setSubStyle("Settings_light");
$menuQuad->setSize($itemSize, $itemSize);
$menuQuad->setX($itemPosX);
$menuQuad->setHorizontalAlign($menuQuad::RIGHT);
$itemPosX -= $itemSize * 1.05;
$menuQuad->addTooltipLabelFeature($descriptionLabel, "Manage Core Settings");
$menuQuad->setAction(self::ML_ACTION_CORE_MANAGESETTINGS);
foreach ($this->menuItems as $menuItem) {
$menuItem->buildControl($popoutFrame, $descriptionLabel, $itemPosX);
$itemPosX -= self::ML_ITEM_SIZE * 1.05;
}
$MatchManagerMultipleConfigManager = $this->maniaControl->getPluginManager()->getPlugin(self::MATCHMANAGERMULTIPLECONFIGMANAGER_PLUGIN);
if ($MatchManagerMultipleConfigManager !== null) {
$menuQuad = new Quad();
$popoutFrame->addChild($menuQuad);
$menuQuad->setStyle("UICommon64_2");
$menuQuad->setSubStyle("Plugin_light");
$menuQuad->setSize($itemSize, $itemSize);
$menuQuad->setX($itemPosX);
$menuQuad->setHorizontalAlign($menuQuad::RIGHT);
$itemPosX -= $itemSize * 1.05;
$menuQuad->addTooltipLabelFeature($descriptionLabel, "Manage Multiple Configs");
$menuQuad->setAction(self::ML_ACTION_MULTIPLECONFIGMANAGER_OPENCONFIGMANAGER);
$descriptionLabel->setPosition($posX - (count($popoutFrame->getChildren()) - 1) * self::ML_ITEM_SIZE * 1.05 - 5, $posY);
$backgroundQuad->setSize((count($popoutFrame->getChildren()) - 1) * self::ML_ITEM_SIZE * 1.05 + 2, self::ML_ITEM_SIZE * $itemMarginFactorY);
}
$MatchManagerGsheet = $this->maniaControl->getPluginManager()->getPlugin(self::MATCHMANAGERGSHEET_PLUGIN);
if ($MatchManagerGsheet !== null) {
$menuQuad = new Quad();
$popoutFrame->addChild($menuQuad);
$menuQuad->setStyle("UICommon64_2");
$menuQuad->setSubStyle("DisplayIcons_light");
$menuQuad->setSize($itemSize, $itemSize);
$menuQuad->setX($itemPosX);
$menuQuad->setHorizontalAlign($menuQuad::RIGHT);
$itemPosX -= $itemSize * 1.05;
$menuQuad->addTooltipLabelFeature($descriptionLabel, "Manage Google Sheet config");
$menuQuad->setAction(self::ML_ACTION_GSHEET_MANAGESETTINGS);
}
if ($this->MatchManagerCore->getMatchStatus()) {
$menuQuad = new Quad();
$popoutFrame->addChild($menuQuad);
$menuQuad->setStyle("UICommon64_1");
$menuQuad->setSubStyle("Stop_light");
$menuQuad->setSize($itemSize, $itemSize);
$menuQuad->setX($itemPosX);
$menuQuad->setHorizontalAlign($menuQuad::RIGHT);
$itemPosX -= $itemSize * 1.05;
$menuQuad->addTooltipLabelFeature($descriptionLabel, "Stop the match");
$menuQuad->setAction(self::ML_ACTION_CORE_STOPMATCH);
$menuQuad = new Quad();
$popoutFrame->addChild($menuQuad);
$menuQuad->setStyle("UICommon64_1");
$menuQuad->setSubStyle("Pause_light");
$menuQuad->setSize($itemSize, $itemSize);
$menuQuad->setX($itemPosX);
$menuQuad->setHorizontalAlign($menuQuad::RIGHT);
$itemPosX -= $itemSize * 1.05;
$menuQuad->addTooltipLabelFeature($descriptionLabel, "Pause the match");
$menuQuad->setAction(self::ML_ACTION_CORE_PAUSEMATCH);
$menuQuad = new Quad();
$popoutFrame->addChild($menuQuad);
$menuQuad->setStyle("UICommon64_1");
$menuQuad->setSubStyle("Cross_light");
$menuQuad->setSize($itemSize, $itemSize);
$menuQuad->setX($itemPosX);
$menuQuad->setHorizontalAlign($menuQuad::RIGHT);
$itemPosX -= $itemSize * 1.05;
$menuQuad->addTooltipLabelFeature($descriptionLabel, "Skip the round / Warmup / Pause");
$menuQuad->setAction(self::ML_ACTION_CORE_SKIPROUND);
} else {
$menuQuad = new Quad();
$popoutFrame->addChild($menuQuad);
$menuQuad->setStyle("UICommon64_1");
$menuQuad->setSubStyle("Play_light");
$menuQuad->setSize($itemSize, $itemSize);
$menuQuad->setX($itemPosX);
$menuQuad->setHorizontalAlign($menuQuad::RIGHT);
$itemPosX -= $itemSize * 1.05;
$menuQuad->addTooltipLabelFeature($descriptionLabel, "Start the match");
$menuQuad->setAction(self::ML_ACTION_CORE_STARTMATCH);
}
$descriptionLabel->setPosition($posX - (count($popoutFrame->getChildren()) - 1) * $itemSize * 1.05 - 5, $posY);
$backgroundQuad->setSize((count($popoutFrame->getChildren()) - 1) * $itemSize * 1.05 + 2, $itemSize * $itemMarginFactorY);
$this->manialink = $maniaLink;
$this->displayManialink();
}
/**
* handlePluginUnloaded
*
* @param string $pluginClass
* @param Plugin $plugin
* @return void
*/
public function handlePluginUnloaded(string $pluginClass, Plugin $plugin) {
if ($pluginClass == self::MATCHMANAGERCORE_PLUGIN) {
$this->maniaControl->getChat()->sendErrorToAdmins(self::PLUGIN_NAME . " disabled because MatchManager Core is now disabled");
$this->maniaControl->getPluginManager()->deactivatePlugin((get_class()));
}
if (strstr($pluginClass, "MatchManagerSuite")) {
$this->generateManialink();
}
public function addMenuItem(MatchManagerAdminUI_MenuItem $menuItem) {
$this->removeMenuItem($menuItem->getActionId());
$this->menuItems[] = $menuItem;
$this->updateManialink = true;
}
/**
* handlePluginLoaded
*
* @param string $pluginClass
* @param Plugin $plugin
* @return void
*/
public function handlePluginLoaded(string $pluginClass, Plugin $plugin) {
if (strstr($pluginClass, "MatchManagerSuite")) {
$this->generateManialink();
public function removeMenuItem(string $actionId) {
$this->menuItems = array_filter($this->menuItems, function($menuItem) use ($actionId) {
return $menuItem->getActionId() !== $actionId;
});
$this->updateManialink = true;
}
}
class MatchManagerAdminUI_MenuItem {
private string $actionId ;
private int $order = 100;
private string $description = '';
private string $text = '';
private string $imageUrl = '';
private string $style = '';
private string $subStyle = '';
private float $size = MatchManagerAdminUI::ML_ITEM_SIZE;
public function getActionId() {
return $this->actionId;
}
public function setActionId(string $actionId) {
$this->actionId = $actionId;
return $this;
}
public function getOrder() {
return $this->order;
}
public function setOrder(int $order) {
$this->order = $order;
return $this;
}
public function getDescription() {
return $this->description;
}
public function setDescription(string $description) {
$this->description = $description;
return $this;
}
public function getImageUrl() {
return $this->imageUrl;
}
public function setImageUrl(string $imageUrl) {
$this->imageUrl = $imageUrl;
return $this;
}
public function getSize() {
return $this->size;
}
public function setSize(float $size) {
$this->size = $size;
return $this;
}
public function getStyle() {
return $this->imageUrl;
}
public function setStyle(string $style) {
$this->style = $style;
return $this;
}
public function getSubStyle() {
return $this->imageUrl;
}
public function setSubStyle(string $subStyle) {
$this->subStyle = $subStyle;
return $this;
}
public function buildControl(Frame $parent, Label $descriptionLabel, float $posX) {
$control = null;
if ($this->text !== '') {
$control = new Label();
$control->setText($this->text);
} else {
$control = new Quad();
if ($this->imageUrl !== '') {
$control->setImageUrl($this->imageUrl);
$control->setKeepRatio('fit');
} else if ($this->style !== '') {
$control->setStyles($this->style, $this->subStyle);
} else {
$control->setBackgroundColor('cccccc');
}
}
$parent->addChild($control);
$control->setSize($this->size, $this->size);
$control->setX($posX);
$control->setHorizontalAlign(Quad::CENTER);
$control->addTooltipLabelFeature($descriptionLabel, $this->description);
$control->setAction($this->actionId);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,338 @@
<?php
namespace MatchManagerSuite;
use ManiaControl\ManiaControl;
use ManiaControl\Plugins\Plugin;
use ManiaControl\Logger;
use ManiaControl\Callbacks\CallbackListener;
use ManiaControl\Callbacks\Callbacks;
use ManiaControl\Callbacks\Structures\ManiaPlanet\StartEndStructure;
use ManiaControl\Callbacks\Structures\TrackMania\OnScoresStructure;
use ManiaControl\Files\AsyncHttpRequest;
use ManiaControl\Callbacks\Structures\TrackMania\OnWayPointEventStructure;
use ManiaControl\Callbacks\TimerListener;
use ManiaControl\Manialinks\ManialinkPageAnswerListener;
use ManiaControl\Players\Player;
use ManiaControl\Plugins\PluginMenu;
if (!class_exists('MatchManagerSuite\MatchManagerCore')) {
$this->maniaControl->getChat()->sendErrorToAdmins('MatchManager Core is required to use MatchManagerECircuitMania plugin. Install it and restart Maniacontrol');
Logger::logError('MatchManager Core is required to use MatchManagerECircuitMania plugin. Install it and restart Maniacontrol');
return false;
}
/**
* MatchManagerECircuitMania
*
* @author Beu
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
*/
class MatchManagerECircuitMania implements CallbackListener, ManialinkPageAnswerListener, TimerListener, Plugin {
/*
* Constants
*/
const PLUGIN_ID = 213;
const PLUGIN_VERSION = 1.0;
const PLUGIN_NAME = 'MatchManager eCircuitMania';
const PLUGIN_AUTHOR = 'Beu';
const MATCHMANAGERCORE_PLUGIN = 'MatchManagerSuite\MatchManagerCore';
const MATCHMANAGERADMINUI_PLUGIN = 'MatchManagerSuite\MatchManagerAdminUI';
const ML_ACTION_OPENSETTINGS = 'MatchManagerSuite\MatchManagerECircuitMania.OpenSettings';
const SETTING_URL = 'API URL';
const SETTING_MATCH_API_KEY = 'Match API Key';
const SETTING_WITHMATCHMANAGER = 'Only send data when a Match Manager match is running';
const CB_STARTMAP = 'Maniaplanet.StartMap_Start';
/*
* Private properties
*/
private ManiaControl $maniaControl;
private \MatchManagerSuite\MatchManagerCore $MatchManagerCore;
private int $trackNum = 0;
private int $roundNum = 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 "Plugin to send match data to eCM";
}
/**
* @see \ManiaControl\Plugins\Plugin::load()
*/
public function load(ManiaControl $maniaControl) {
$this->maniaControl = $maniaControl;
if ($this->maniaControl->getPluginManager()->getSavedPluginStatus(self::MATCHMANAGERCORE_PLUGIN)) {
$this->maniaControl->getTimerManager()->registerOneTimeListening($this, function () {
$this->MatchManagerCore = $this->maniaControl->getPluginManager()->getPlugin(self::MATCHMANAGERCORE_PLUGIN);
if ($this->MatchManagerCore === null) {
$this->maniaControl->getChat()->sendErrorToAdmins('MatchManager Core is needed to use ' . self::PLUGIN_NAME . ' plugin.');
$this->maniaControl->getPluginManager()->deactivatePlugin((get_class()));
return;
}
$this->maniaControl->getCallbackManager()->registerScriptCallbackListener(self::CB_STARTMAP, $this, 'handleStartMap');
$this->maniaControl->getCallbackManager()->registerCallbackListener(Callbacks::MP_STARTROUNDSTART, $this, 'handleStartRound');
$this->maniaControl->getCallbackManager()->registerCallbackListener(Callbacks::TM_ONWAYPOINT, $this, 'handleOnWaypoint');
$this->maniaControl->getCallbackManager()->registerCallbackListener(Callbacks::TM_SCORES, $this, 'handleTrackmaniaScores');
$this->maniaControl->getCallbackManager()->registerCallbackListener(Callbacks::MP_ENDROUNDEND, $this, 'handleEndRound');
$this->updateAdminUIMenuItems();
}, 1);
} else {
throw new \Exception('MatchManager Core is needed to use ' . self::PLUGIN_NAME);
}
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_MATCH_API_KEY, "", "", 5);
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_URL, "https://us-central1-fantasy-trackmania.cloudfunctions.net", "", 10);
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerListener(self::ML_ACTION_OPENSETTINGS, $this, 'handleActionOpenSettings');
}
/**
* handle Plugin Loaded
*
* @param string $pluginClass
*/
public function handlePluginLoaded(string $pluginClass) {
if ($pluginClass === self::MATCHMANAGERADMINUI_PLUGIN) {
$this->updateAdminUIMenuItems();
}
}
/**
* Add items in AdminUI plugin
*/
public function updateAdminUIMenuItems() {
/** @var \MatchManagerSuite\MatchManagerAdminUI|null */
$adminUIPlugin = $this->maniaControl->getPluginManager()->getPlugin(self::MATCHMANAGERADMINUI_PLUGIN);
if ($adminUIPlugin === null) return;
$adminUIPlugin->removeMenuItem(self::ML_ACTION_OPENSETTINGS);
$menuItem = new \MatchManagerSuite\MatchManagerAdminUI_MenuItem();
$menuItem->setActionId(self::ML_ACTION_OPENSETTINGS)
->setOrder(60)
->setImageUrl('https://ecircuitmania.com/favicon.png')
->setSize(4.)
->setDescription('Open eCM Settings');
$adminUIPlugin->addMenuItem($menuItem);
}
/**
* handle Open settings manialink action
*
* @param array $callback
* @param Player $player
*/
public function handleActionOpenSettings(array $callback, Player $player) {
if ($player->authLevel <= 0) return;
$pluginMenu = $this->maniaControl->getPluginManager()->getPluginMenu();
if (defined("\ManiaControl\ManiaControl::ISTRACKMANIACONTROL")) {
$player->setCache($pluginMenu, PluginMenu::CACHE_SETTING_CLASS, "PluginMenu.Settings." . self::class);
} else {
$player->setCache($pluginMenu, PluginMenu::CACHE_SETTING_CLASS, self::class);
}
$this->maniaControl->getConfigurator()->showMenu($player, $pluginMenu);
}
public function handleStartMap(array $structure) {
if (!$this->MatchManagerCore->getMatchIsRunning()) return;
$data = json_decode($structure[1][0]);
$this->trackNum = $data->valid;
$this->roundNum = 0;
}
public function handleStartRound(StartEndStructure $structure) {
if (!$this->MatchManagerCore->getMatchIsRunning()) return;
$this->roundNum = $structure->getValidRoundCount();
}
public function handleOnWaypoint(OnWayPointEventStructure $structure) {
if (!$this->MatchManagerCore->getMatchIsRunning()) return;
if (!$structure->getIsEndRace()) return;
if ($this->roundNum <= 0) return; // probably during the WU
$mapuid = "";
$map = $this->maniaControl->getMapManager()->getCurrentMap();
if ($map !== null) {
$mapuid = $map->uid;
}
$payload = json_encode([
"ubisoftUid" => $structure->getPlayer()->getAccountId(),
"finishTime" => $structure->getRaceTime(),
"mapId" => $mapuid,
"trackNum" => $this->trackNum,
"roundNum" => $this->roundNum
]);
$request = $this->getAPIRequest("/match-addRoundTime");
if ($request !== null) {
$request->setContent($payload)->setCallable(function ($content, $error, $headers) use ($payload) {
if ($content !== "Created" || $error !== null) {
Logger::logWarning("Error on the 'addRoundTime' request. answer: " . $content . " / error: " . $error . " / payload: " . $payload);
}
})->postData();
}
}
public function handleTrackmaniaScores(OnScoresStructure $structure) {
if (!$this->MatchManagerCore->getMatchIsRunning()) return;
if ($structure->getSection() !== "PreEndRound") return;
$scores = [];
foreach ($structure->getPlayerScores() as $playerscore) {
if ($playerscore->getMatchPoints() <= -2000) continue;
$scores[] = $playerscore;
}
/** @var \ManiaControl\Callbacks\Structures\TrackMania\Models\PlayerScore[] $scores */
usort($scores, function ($a, $b) {
if ($a->getPrevRaceTime() === -1 && $b->getPrevRaceTime() === -1) {
return $b->getRoundPoints() - $a->getRoundPoints();
}
if ($a->getPrevRaceTime() === -1) return 1;
if ($b->getPrevRaceTime() === -1) return -1;
if ($a->getPrevRaceTime() === $b->getPrevRaceTime()) {
$acheckpoints = $a->getPrevRaceCheckpoints();
$bcheckpoints = $b->getPrevRaceCheckpoints();
while (end($acheckpoints) === end($bcheckpoints)) {
if (count($acheckpoints) === 0 || count($bcheckpoints) === 0) return 0;
array_pop($acheckpoints);
array_pop($bcheckpoints);
}
return end($acheckpoints) - end($bcheckpoints);
}
return $a->getPrevRaceTime() - $b->getPrevRaceTime();
});
$players = [];
$rank = 1;
foreach ($scores as $playerscore) {
/** @var \ManiaControl\Callbacks\Structures\TrackMania\Models\PlayerScore $playerscore */
if ($playerscore->getPlayer()->isSpectator) continue;
$players[] = [
"ubisoftUid" => $playerscore->getPlayer()->getAccountId(),
"finishTime" => $playerscore->getPrevRaceTime(),
"position" => $rank
];
$rank++;
}
$mapuid = "";
$map = $this->maniaControl->getMapManager()->getCurrentMap();
if ($map !== null) {
$mapuid = $map->uid;
}
$payload = json_encode([
"players" => $players,
"mapId" => $mapuid,
"trackNum" => $this->trackNum,
"roundNum" => $this->roundNum
]);
$request = $this->getAPIRequest("/match-addRound");
if ($request !== null) {
$request->setContent($payload)->setCallable(function ($content, $error, $headers) use ($payload) {
if ($content !== "Created" || $error !== null) {
Logger::logWarning("Error on the 'addRound' request. answer: " . $content . " / error: " . $error . " / payload: " . $payload);
}
})->postData();
}
}
public function handleEndRound(StartEndStructure $structure) {
if (!$this->MatchManagerCore->getMatchIsRunning()) return;
$json = $structure->getPlainJsonObject();
if (!property_exists($json, 'isvalid') || $json->isvalid) return;
$payload = json_encode([
"trackNum" => $this->trackNum,
"roundNum" => $this->roundNum
]);
$request = $this->getAPIRequest("/match-removeRound");
if ($request !== null) {
$request->setContent($payload)->setCallable(function ($content, $error, $headers) use ($payload) {
if ($content !== "Created" || $error !== null) {
Logger::logWarning("Error on the 'removeRound' request. answer: " . $content . " / error: " . $error . " / payload: " . $payload);
}
})->postData();
}
}
private function getAPIRequest(string $url) : ?AsyncHttpRequest {
$baseurl = $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_URL);
$matchapikey = $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_MATCH_API_KEY);
$array = explode("_", $matchapikey);
if (count($array) !== 2) return null;
$matchid = $array[0];
$token = $array[1];
if ($baseurl === "") return null;
if ($token === "") return null;
if ($matchid === "") return null;
$asyncHttpRequest = new AsyncHttpRequest($this->maniaControl, $baseurl . $url . "?matchId=" . $matchid);
$asyncHttpRequest->setContentType("application/json");
$asyncHttpRequest->setHeaders(["Authorization: " . $token]);
return $asyncHttpRequest;
}
/**
* Unload the plugin and its Resources
*/
public function unload() {}
}

View File

@ -13,7 +13,11 @@ use ManiaControl\Settings\SettingManager;
use ManiaControl\Files\AsyncHttpRequest;
use ManiaControl\Commands\CommandListener;
use ManiaControl\Admin\AuthenticationManager;
use ManiaControl\Callbacks\Callbacks;
use ManiaControl\Callbacks\TimerListener;
use ManiaControl\Manialinks\ManialinkPageAnswerListener;
use ManiaControl\Players\PlayerManager;
use ManiaControl\Plugins\PluginMenu;
use ManiaControl\Utils\WebReader;
if (!class_exists('MatchManagerSuite\MatchManagerCore')) {
@ -30,15 +34,21 @@ use MatchManagerSuite\MatchManagerCore;
* @author Beu
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
*/
class MatchManagerGSheet implements CallbackListener, TimerListener, CommandListener, Plugin {
class MatchManagerGSheet implements CallbackListener, TimerListener, CommandListener, ManialinkPageAnswerListener, Plugin {
/*
* Constants
*/
const PLUGIN_ID = 156;
const PLUGIN_VERSION = 1.5;
const PLUGIN_VERSION = 2.3;
const PLUGIN_NAME = 'MatchManager GSheet';
const PLUGIN_AUTHOR = 'Beu';
// Other MatchManager plugin
const MATCHMANAGERADMINUI_PLUGIN = 'MatchManagerSuite\MatchManagerAdminUI';
// Actions
const ML_ACTION_OPENSETTINGS = 'MatchManagerSuite\MatchManagerGSheet.OpenSettings';
// MatchManagerGSheet Properties
const DB_GSHEETSECRETSETTINGS = 'MatchManagerGSheet_SecretSettings';
@ -53,36 +63,36 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
const MODE_SPECIFICS_SETTINGS = [
"Last Round Only" => [
"ScoreTable_endColumnIndex" => 15,
"TeamsScoreTable_startColumnIndex" => 16,
"TeamsScoreTable_endColumnIndex" => 22,
"ScoreTable_endColumnIndex" => 16,
"TeamsScoreTable_startColumnIndex" => 17,
"TeamsScoreTable_endColumnIndex" => 23,
"ScoreTable_BeginLetter" => "D",
"ScoreTable_EndLetter" => "O",
"TeamsScoreTable_BeginLetter" => "Q",
"TeamsScoreTable_EndLetter" => "V",
"ScoreTable_Labels" => ["Rank","Login", "MatchPoints", "MapPoints", "RoundPoints","BestRaceTime","BestRaceCheckpoints","BestLaptime","BestLapCheckpoints","PrevRaceTime","PrevRaceCheckpoints","Team"],
"ScoreTable_EndLetter" => "P",
"TeamsScoreTable_BeginLetter" => "R",
"TeamsScoreTable_EndLetter" => "W",
"ScoreTable_Labels" => ["Rank","Login", "Name", "MatchPoints", "MapPoints", "RoundPoints","BestRaceTime","BestRaceCheckpoints","BestLaptime","BestLapCheckpoints","PrevRaceTime","PrevRaceCheckpoints","Team"],
"TeamsScoreTable_Labels" => ["Rank","Team ID", "Name", "MatchPoints", "MapPoints", "RoundPoints"]
],
"All Rounds Data" => [
"ScoreTable_endColumnIndex" => 17,
"TeamsScoreTable_startColumnIndex" => 18,
"TeamsScoreTable_endColumnIndex" => 26,
"ScoreTable_endColumnIndex" => 18,
"TeamsScoreTable_startColumnIndex" => 19,
"TeamsScoreTable_endColumnIndex" => 27,
"ScoreTable_BeginLetter" => "D",
"ScoreTable_EndLetter" => "Q",
"TeamsScoreTable_BeginLetter" => "S",
"TeamsScoreTable_EndLetter" => "X",
"ScoreTable_Labels" => ["Map", "Round", "Rank","Login", "MatchPoints", "MapPoints", "RoundPoints","BestRaceTime","BestRaceCheckpoints","BestLaptime","BestLapCheckpoints","PrevRaceTime","PrevRaceCheckpoints","Team"],
"ScoreTable_EndLetter" => "R",
"TeamsScoreTable_BeginLetter" => "T",
"TeamsScoreTable_EndLetter" => "Y",
"ScoreTable_Labels" => ["Map", "Round", "Rank", "Login", "Name", "MatchPoints", "MapPoints", "RoundPoints","BestRaceTime","BestRaceCheckpoints","BestLaptime","BestLapCheckpoints","PrevRaceTime","PrevRaceCheckpoints","Team"],
"TeamsScoreTable_Labels" => ["Map", "Round", "Rank","Team ID", "Name", "MatchPoints", "MapPoints", "RoundPoints"]
],
"End Match Only" => [
"ScoreTable_endColumnIndex" => 15,
"TeamsScoreTable_startColumnIndex" => 16,
"TeamsScoreTable_endColumnIndex" => 22,
"ScoreTable_endColumnIndex" => 16,
"TeamsScoreTable_startColumnIndex" => 17,
"TeamsScoreTable_endColumnIndex" => 23,
"ScoreTable_BeginLetter" => "D",
"ScoreTable_EndLetter" => "O",
"TeamsScoreTable_BeginLetter" => "Q",
"TeamsScoreTable_EndLetter" => "V",
"ScoreTable_Labels" => ["Rank","Login", "MatchPoints", "MapPoints", "RoundPoints","BestRaceTime","BestRaceCheckpoints","BestLaptime","BestLapCheckpoints","PrevRaceTime","PrevRaceCheckpoints","Team"],
"ScoreTable_EndLetter" => "P",
"TeamsScoreTable_BeginLetter" => "R",
"TeamsScoreTable_EndLetter" => "W",
"ScoreTable_Labels" => ["Rank","Login", "Name", "MatchPoints", "MapPoints", "RoundPoints","BestRaceTime","BestRaceCheckpoints","BestLaptime","BestLapCheckpoints","PrevRaceTime","PrevRaceCheckpoints","Team"],
"TeamsScoreTable_Labels" => ["Rank","Team ID", "Name", "MatchPoints", "MapPoints", "RoundPoints"]
]
];
@ -93,6 +103,7 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
*/
/** @var ManiaControl $maniaControl */
private $maniaControl = null;
/** @var MatchManagerCore */
private $MatchManagerCore = null;
private $matchstatus = "";
private $device_code = "";
@ -159,6 +170,10 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
}
// Callbacks
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerListener(self::ML_ACTION_OPENSETTINGS, $this, 'handleActionOpenSettings');
$this->maniaControl->getCallbackManager()->registerCallbackListener(Callbacks::AFTERINIT, $this, 'handleAfterInit');
$this->maniaControl->getCallbackManager()->registerCallbackListener(PluginManager::CB_PLUGIN_LOADED, $this, 'handlePluginLoaded');
$this->maniaControl->getCallbackManager()->registerCallbackListener(PlayerManager::CB_PLAYERCONNECT, $this, 'handlePlayerConnect');
$this->maniaControl->getCallbackManager()->registerCallbackListener(PluginManager::CB_PLUGIN_UNLOADED, $this, 'handlePluginUnloaded');
$this->maniaControl->getCallbackManager()->registerCallbackListener(SettingManager::CB_SETTING_CHANGED, $this, 'updateSettings');
$this->maniaControl->getCallbackManager()->registerCallbackListener(MatchManagerCore::CB_MATCHMANAGER_STARTMATCH, $this, 'CheckAndPrepareSheet');
@ -179,6 +194,10 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
$this->access_token = $this->getSecretSetting("access_token");
$this->maniaControl->getChat()->sendErrorToAdmins('To use the MatchManagerGSheet plugin, $<$l[https://github.com/AmazingBeu/ManiacontrolPlugins/wiki/MatchManager-GSheet]check the doc$>');
$this->maniaControl->getChat()->sendErrorToAdmins('Since MatchManagerGSheet 2.0, Player names are in the results and no more in a separated list');
$this->updateAdminUIMenuItems();
return true;
}
@ -187,6 +206,31 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
* @see \ManiaControl\Plugins\Plugin::unload()
*/
public function unload() {
/** @var \MatchManagerSuite\MatchManagerAdminUI|null */
$adminUIPlugin = $this->maniaControl->getPluginManager()->getPlugin(self::MATCHMANAGERADMINUI_PLUGIN);
if ($adminUIPlugin !== null) {
$adminUIPlugin->removeMenuItem(self::ML_ACTION_OPENSETTINGS);
}
}
/**
* handle Plugin Loaded
*
* @param string $pluginClass
*/
public function handleAfterInit() {
$this->updateAdminUIMenuItems();
}
/**
* handle Plugin Loaded
*
* @param string $pluginClass
*/
public function handlePluginLoaded(string $pluginClass) {
if ($pluginClass === self::MATCHMANAGERADMINUI_PLUGIN) {
$this->updateAdminUIMenuItems();
}
}
/**
@ -241,11 +285,50 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
if (($this->matchstatus == "running" || $this->matchstatus == "starting") && $setting->setting == self::SETTING_MATCHMANAGERGSHEET_DATA_MODE && $setting->value != $this->currentdatamode) {
$setting->value = $this->currentdatamode;
$this->maniaControl->getSettingManager()->saveSetting($setting);
$this->maniaControl->getChat()->sendErrorToAdmins($this->chatprefix . 'You can\'t change data mode during a Match');
$this->maniaControl->getChat()->sendErrorToAdmins($this->MatchManagerCore->getChatPrefix() . 'You can\'t change data mode during a Match');
}
}
}
public function handlePlayerConnect(Player $player) {
if ($this->maniaControl->getAuthenticationManager()->checkRight($player, AuthenticationManager::AUTH_LEVEL_ADMIN)) {
$this->maniaControl->getChat()->sendError('Since MatchManagerGSheet 2.0, Player names are in the results and no more in a separated list', $player->login);
}
}
/**
* handle Open settings manialink action
*
* @param array $callback
* @param Player $player
*/
public function handleActionOpenSettings(array $callback, Player $player) {
if ($player->authLevel <= 0) return;
$pluginMenu = $this->maniaControl->getPluginManager()->getPluginMenu();
if (defined("\ManiaControl\ManiaControl::ISTRACKMANIACONTROL")) {
$player->setCache($pluginMenu, PluginMenu::CACHE_SETTING_CLASS, "PluginMenu.Settings." . self::class);
} else {
$player->setCache($pluginMenu, PluginMenu::CACHE_SETTING_CLASS, self::class);
}
$this->maniaControl->getConfigurator()->showMenu($player, $pluginMenu);
}
/**
* Add items in AdminUI plugin
*/
public function updateAdminUIMenuItems() {
/** @var \MatchManagerSuite\MatchManagerAdminUI|null */
$adminUIPlugin = $this->maniaControl->getPluginManager()->getPlugin(self::MATCHMANAGERADMINUI_PLUGIN);
if ($adminUIPlugin === null) return;
$adminUIPlugin->removeMenuItem(self::ML_ACTION_OPENSETTINGS);
$menuItem = new \MatchManagerSuite\MatchManagerAdminUI_MenuItem();
$menuItem->setActionId(self::ML_ACTION_OPENSETTINGS)->setOrder(100)->setStyle('UICommon64_2')->setSubStyle('DisplayIcons_light')->setDescription('Open Gsheet Settings');
$adminUIPlugin->addMenuItem($menuItem);
}
public function onCommandMatchGSheet(array $chatCallback, Player $player) {
$authLevel = $this->maniaControl->getSettingManager()->getSettingValue($this->MatchManagerCore, MatchManagerCore::SETTING_MATCH_AUTHLEVEL);
if (!$this->maniaControl->getAuthenticationManager()->checkRight($player, AuthenticationManager::getAuthLevel($authLevel))) {
@ -289,9 +372,14 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
$this->maniaControl->getChat()->sendError('Json parse error: ' . $json, $player);
return;
}
if (property_exists($data, "error")) {
Logger::logError('Request error: ' . $data->error->code . " ". $data->error->message);
$this->maniaControl->getChat()->sendErrorToAdmins('Request error: ' . $data->error->code . " ". $data->error->message);
return;
}
if (isset($data->device_code)) {
$this->device_code = $data->device_code;
$this->maniaControl->getChat()->sendSuccess('Open $<$l['. $data->verification_url . ']this link$> and type this code: "' . $data->user_code .'"' , $player);
$this->maniaControl->getChat()->sendSuccess('Open $<$l['. $data->verification_url .'?user_code=' . $data->user_code . ']this link$> and type this code: "' . $data->user_code .'"' , $player);
$this->maniaControl->getChat()->sendSuccess('After have validate the App, type the commande "//matchgsheet step2"' , $player);
} elseif (isset($data->error_code)) {
$this->maniaControl->getChat()->sendError('Google refused the request: ' . $data->error_code, $player);
@ -339,6 +427,12 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
$this->maniaControl->getChat()->sendError('Json parse error: ' . $json, $player);
return;
}
if (property_exists($data, "error")) {
Logger::logError('Request error: ' . $data->error->code . " ". $data->error->message);
$this->maniaControl->getChat()->sendErrorToAdmins('Request error: ' . $data->error->code . " ". $data->error->message);
return;
}
if (isset($data->access_token)) {
$this->access_token = $data->access_token;
$this->saveSecretSetting("access_token", $data->access_token);
@ -380,6 +474,12 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
Logger::logError('Json parse error: ' . $json);
return;
}
if (property_exists($data, "error")) {
Logger::logError('Request error: ' . $data->error->code . " ". $data->error->message);
$this->maniaControl->getChat()->sendErrorToAdmins('Request error: ' . $data->error->code . " ". $data->error->message);
return;
}
if (isset($data->access_token)) {
$this->access_token = $data->access_token;
$this->saveSecretSetting("access_token", $data->access_token);
@ -428,8 +528,14 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
}
private function CheckSpeadsheetAccess(Player $player) {
$spreadsheetid = $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_MATCHMANAGERGSHEET_SPREADSHEET);
if ($spreadsheetid === "") {
$this->maniaControl->getChat()->sendError('Empty Spreadsheet Id', $player);
return;
}
if ($this->refreshTokenIfNeeded()) {
$asyncHttpRequest = new AsyncHttpRequest($this->maniaControl, 'https://sheets.googleapis.com/v4/spreadsheets/' . $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_MATCHMANAGERGSHEET_SPREADSHEET));
$asyncHttpRequest = new AsyncHttpRequest($this->maniaControl, 'https://sheets.googleapis.com/v4/spreadsheets/' . $spreadsheetid);
$asyncHttpRequest->setContentType(AsyncHttpRequest::CONTENT_TYPE_JSON);
$asyncHttpRequest->setHeaders(array("Authorization: Bearer " . $this->access_token));
$asyncHttpRequest->setCallable(function ($json, $error) use ($player) {
@ -444,6 +550,12 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
$this->maniaControl->getChat()->sendError('Json parse error: ' . $json, $player);
return;
}
if (property_exists($data, "error")) {
Logger::logError('Request error: ' . $data->error->code . " ". $data->error->message);
$this->maniaControl->getChat()->sendErrorToAdmins('Request error: ' . $data->error->code . " ". $data->error->message);
return;
}
if (isset($data->properties->title)) {
$this->maniaControl->getChat()->sendSuccess('Speadsheet name: ' . $data->properties->title, $player);
} else {
@ -471,12 +583,25 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
}
public function UpdateGSheetData(String $matchid, Array $currentscore, Array $currentteamsscore) {
$matchstatus = $this->matchstatus;
if ($this->currentdatamode === "End Match Only" && $this->matchstatus === "running") return;
if ($this->refreshTokenIfNeeded()) {
$sheetname = $this->getSheetName();
$spreadsheetid = $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_MATCHMANAGERGSHEET_SPREADSHEET);
if ($spreadsheetid === "") return;
$sheetname = $this->getSheetName();
if ($sheetname === "") return;
foreach ($currentscore as $key => $score) {
$name = "~";
$player = $this->maniaControl->getPlayerManager()->getPlayer($score[1]);
if ($player !== null) $name = $player->nickname;
array_splice($score, 2, 0, [$name]);
$currentscore[$key] = $score;
}
$matchstatus = $this->matchstatus;
if ($this->refreshTokenIfNeeded()) {
$data = new \stdClass;
$data->valueInputOption = "RAW";
@ -488,34 +613,24 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
$data->data[0]->values = array(array($matchstatus),array($this->MatchManagerCore->getCountMap()),array($this->MatchManagerCore->getCountRound()),array($this->maniaControl->getPlayerManager()->getPlayerCount()),array($this->maniaControl->getPlayerManager()->getSpectatorCount()));
}
$data->data[1] = new \stdClass;
$data->data[1]->range = "'" . $sheetname . "'!A9";
foreach ($this->maniaControl->getPlayerManager()->getPlayers() as $player) {
$this->playerlist[$player->login] = $player->nickname;
}
$players = [];
foreach ($this->playerlist as $login => $nickname) {
array_push($players,array($login, $nickname));
}
$data->data[1]->values = $players;
if ($this->currentdatamode === "Last Round Only" || $this->currentdatamode === "End Match Only") {
$data->data[2] = new \stdClass;
$data->data[2]->range = "'" . $sheetname . "'!" . self::MODE_SPECIFICS_SETTINGS[$this->currentdatamode]["ScoreTable_BeginLetter"] . "2";
$data->data[2]->values = $currentscore;
$data->data[1] = new \stdClass;
$data->data[1]->range = "'" . $sheetname . "'!" . self::MODE_SPECIFICS_SETTINGS[$this->currentdatamode]["ScoreTable_BeginLetter"] . "2";
$data->data[1]->values = $currentscore;
$data->data[3] = new \stdClass;
$data->data[3]->range = "'" . $sheetname . "'!" . self::MODE_SPECIFICS_SETTINGS[$this->currentdatamode]["TeamsScoreTable_BeginLetter"] . "2";
$data->data[3]->values = $currentteamsscore;
$data->data[2] = new \stdClass;
$data->data[2]->range = "'" . $sheetname . "'!" . self::MODE_SPECIFICS_SETTINGS[$this->currentdatamode]["TeamsScoreTable_BeginLetter"] . "2";
$data->data[2]->values = $currentteamsscore;
}
$asyncHttpRequest = new AsyncHttpRequest($this->maniaControl, 'https://sheets.googleapis.com/v4/spreadsheets/' . $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_MATCHMANAGERGSHEET_SPREADSHEET) . '/values:batchUpdate');
$nbmaps = $this->MatchManagerCore->getMapNumber();
$nbrounds = $this->MatchManagerCore->getRoundNumber();
$asyncHttpRequest = new AsyncHttpRequest($this->maniaControl, 'https://sheets.googleapis.com/v4/spreadsheets/' . $spreadsheetid . '/values:batchUpdate');
$asyncHttpRequest->setContentType(AsyncHttpRequest::CONTENT_TYPE_JSON);
$asyncHttpRequest->setHeaders(array("Authorization: Bearer " . $this->access_token));
$asyncHttpRequest->setContent(json_encode($data));
$asyncHttpRequest->setCallable(function ($json, $error) use ($sheetname, $currentscore, $currentteamsscore, $matchstatus) {
$asyncHttpRequest->setCallable(function ($json, $error) use ($sheetname, $spreadsheetid, $currentscore, $currentteamsscore, $matchstatus, $nbmaps, $nbrounds) {
if (!$json || $error) {
Logger::logError('Error from Google API: ' . $error);
$this->maniaControl->getChat()->sendErrorToAdmins('Error from Google API: ' . $error);
@ -527,11 +642,16 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
$this->maniaControl->getChat()->sendErrorToAdmins('Json parse error: ' . $json);
return;
}
if (property_exists($data, "error")) {
Logger::logError('Request error: ' . $data->error->code . " ". $data->error->message);
$this->maniaControl->getChat()->sendErrorToAdmins('Request error: ' . $data->error->code . " ". $data->error->message);
return;
}
if ($this->currentdatamode == "All Rounds Data" && $matchstatus == "running") {
$newcurrentscore = [];
foreach ($currentscore as $score) {
array_push($newcurrentscore,array_merge([$this->MatchManagerCore->getMapNumber() , $this->MatchManagerCore->getRoundNumber()], $score));
array_push($newcurrentscore, array_merge([$nbmaps, $nbrounds], $score));
}
$data = new \stdClass;
@ -539,11 +659,11 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
$data->majorDimension = "ROWS";
$data->values = $newcurrentscore;
$asyncHttpRequest = new AsyncHttpRequest($this->maniaControl, 'https://sheets.googleapis.com/v4/spreadsheets/' . $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_MATCHMANAGERGSHEET_SPREADSHEET) . '/values/' . urlencode("'". $sheetname . "'") . "!" . self::MODE_SPECIFICS_SETTINGS[$this->currentdatamode]["ScoreTable_BeginLetter"] . "1:" . self::MODE_SPECIFICS_SETTINGS[$this->currentdatamode]["ScoreTable_EndLetter"] . "1:append?valueInputOption=RAW");
$asyncHttpRequest = new AsyncHttpRequest($this->maniaControl, 'https://sheets.googleapis.com/v4/spreadsheets/' . $spreadsheetid . '/values/' . urlencode("'". $sheetname . "'") . "!" . self::MODE_SPECIFICS_SETTINGS[$this->currentdatamode]["ScoreTable_BeginLetter"] . "1:" . self::MODE_SPECIFICS_SETTINGS[$this->currentdatamode]["ScoreTable_EndLetter"] . "1:append?valueInputOption=RAW");
$asyncHttpRequest->setContentType(AsyncHttpRequest::CONTENT_TYPE_JSON);
$asyncHttpRequest->setHeaders(array("Authorization: Bearer " . $this->access_token));
$asyncHttpRequest->setContent(json_encode($data));
$asyncHttpRequest->setCallable(function ($json, $error) use ($sheetname, $currentscore, $currentteamsscore) {
$asyncHttpRequest->setCallable(function ($json, $error) use ($sheetname, $spreadsheetid, $currentteamsscore, $nbmaps, $nbrounds) {
if (!$json || $error) {
Logger::logError('Error from Google API: ' . $error);
$this->maniaControl->getChat()->sendErrorToAdmins('Error from Google API: ' . $error);
@ -555,11 +675,16 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
$this->maniaControl->getChat()->sendErrorToAdmins('Json parse error: ' . $json);
return;
}
if (property_exists($data, "error")) {
Logger::logError('Request error: ' . $data->error->code . " ". $data->error->message);
$this->maniaControl->getChat()->sendErrorToAdmins('Request error: ' . $data->error->code . " ". $data->error->message);
return;
}
if (!empty($currentteamsscore)) {
$newcurrentteamsscore = [];
foreach ($currentteamsscore as $score) {
array_push($newcurrentteamsscore,array_merge([$this->MatchManagerCore->getMapNumber() , $this->MatchManagerCore->getRoundNumber()], $score));
array_push($newcurrentteamsscore,array_merge([$nbmaps, $nbrounds], $score));
}
$data = new \stdClass;
@ -567,7 +692,7 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
$data->majorDimension = "ROWS";
$data->values = $newcurrentteamsscore;
$asyncHttpRequest = new AsyncHttpRequest($this->maniaControl, 'https://sheets.googleapis.com/v4/spreadsheets/' . $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_MATCHMANAGERGSHEET_SPREADSHEET) . '/values/' . urlencode("'". $sheetname . "'") . "!" . self::MODE_SPECIFICS_SETTINGS[$this->currentdatamode]["TeamsScoreTable_BeginLetter"] . "1:" . self::MODE_SPECIFICS_SETTINGS[$this->currentdatamode]["TeamsScoreTable_EndLetter"] . "1:append?valueInputOption=RAW");
$asyncHttpRequest = new AsyncHttpRequest($this->maniaControl, 'https://sheets.googleapis.com/v4/spreadsheets/' . $spreadsheetid . '/values/' . urlencode("'". $sheetname . "'") . "!" . self::MODE_SPECIFICS_SETTINGS[$this->currentdatamode]["TeamsScoreTable_BeginLetter"] . "1:" . self::MODE_SPECIFICS_SETTINGS[$this->currentdatamode]["TeamsScoreTable_EndLetter"] . "1:append?valueInputOption=RAW");
$asyncHttpRequest->setContentType(AsyncHttpRequest::CONTENT_TYPE_JSON);
$asyncHttpRequest->setHeaders(array("Authorization: Bearer " . $this->access_token));
$asyncHttpRequest->setContent(json_encode($data));
@ -583,6 +708,11 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
$this->maniaControl->getChat()->sendErrorToAdmins('Json parse error: ' . $json);
return;
}
if (property_exists($data, "error")) {
Logger::logError('Request error: ' . $data->error->code . " ". $data->error->message);
$this->maniaControl->getChat()->sendErrorToAdmins('Request error: ' . $data->error->code . " ". $data->error->message);
return;
}
});
$asyncHttpRequest->postData(1000);
}
@ -616,12 +746,18 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
}
public function CheckAndPrepareSheet(String $matchid, Array $settings) {
$spreadsheetid = $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_MATCHMANAGERGSHEET_SPREADSHEET);
if ($spreadsheetid === "") return;
$sheetname = $this->getSheetName();
if ($sheetname === "") return;
if ($this->refreshTokenIfNeeded()) {
$this->matchid = $matchid;
$asyncHttpRequest = new AsyncHttpRequest($this->maniaControl, 'https://sheets.googleapis.com/v4/spreadsheets/' . $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_MATCHMANAGERGSHEET_SPREADSHEET));
$asyncHttpRequest = new AsyncHttpRequest($this->maniaControl, 'https://sheets.googleapis.com/v4/spreadsheets/' . $spreadsheetid);
$asyncHttpRequest->setContentType(AsyncHttpRequest::CONTENT_TYPE_JSON);
$asyncHttpRequest->setHeaders(array("Authorization: Bearer " . $this->access_token));
$asyncHttpRequest->setCallable(function ($json, $error) {
$asyncHttpRequest->setCallable(function ($json, $error) use ($sheetname) {
if (!$json || $error) {
Logger::logError('Error from Google API: ' . $error);
$this->maniaControl->getChat()->sendErrorToAdmins('Error from Google API: ' . $error);
@ -633,10 +769,14 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
$this->maniaControl->getChat()->sendErrorToAdmins('Json parse error: ' . $json);
return;
}
if (property_exists($data, "error")) {
Logger::logError('Request error: ' . $data->error->code . " ". $data->error->message);
$this->maniaControl->getChat()->sendErrorToAdmins('Request error: ' . $data->error->code . " ". $data->error->message);
return;
}
if ($data->properties->title) {
$sheetsid = array();
$sheetname = $this->getSheetName();
$sheetexists = false;
foreach($data->sheets as $value) {
if ($value->properties->title == $sheetname) {
@ -661,12 +801,11 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
}
private function PrepareSheet(String $sheetname, bool $sheetexists, Array $sheetsid) {
if ($this->refreshTokenIfNeeded()) {
if ($sheetname === "") return;
$spreadsheetid = $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_MATCHMANAGERGSHEET_SPREADSHEET);
if ($spreadsheetid === "") return;
$this->playerlist = array();
foreach ($this->maniaControl->getPlayerManager()->getPlayers() as $player) {
$this->playerlist[$player->login] = $player->nickname;
}
if ($this->refreshTokenIfNeeded()) {
$data = new \stdClass;
$data->requests = array();
@ -720,26 +859,6 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
$data->requests[$i]->repeatCell->fields = "userEnteredFormat(backgroundColor,textFormat)";
$i++;
//Player list
$data->requests[$i] = new \stdClass;
$data->requests[$i]->repeatCell = new \stdClass;
$data->requests[$i]->repeatCell->range = new \stdClass;
$data->requests[$i]->repeatCell->range->sheetId = $sheetid;
$data->requests[$i]->repeatCell->range->startRowIndex = 7;
$data->requests[$i]->repeatCell->range->endRowIndex = 8;
$data->requests[$i]->repeatCell->range->startColumnIndex = 0;
$data->requests[$i]->repeatCell->range->endColumnIndex = 2;
$data->requests[$i]->repeatCell->cell = new \stdClass;
$data->requests[$i]->repeatCell->cell->userEnteredFormat = new \stdClass;
$data->requests[$i]->repeatCell->cell->userEnteredFormat->backgroundColor = new \stdClass;
$data->requests[$i]->repeatCell->cell->userEnteredFormat->backgroundColor->red = 0.6;
$data->requests[$i]->repeatCell->cell->userEnteredFormat->backgroundColor->green = 0.9;
$data->requests[$i]->repeatCell->cell->userEnteredFormat->backgroundColor->blue = 0.6;
$data->requests[$i]->repeatCell->cell->userEnteredFormat->textFormat = new \stdClass;
$data->requests[$i]->repeatCell->cell->userEnteredFormat->textFormat->bold = true;
$data->requests[$i]->repeatCell->fields = "userEnteredFormat(backgroundColor,textFormat)";
$i++;
//Score Table
$data->requests[$i] = new \stdClass;
$data->requests[$i]->repeatCell = new \stdClass;
@ -782,11 +901,11 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
$data->requests[$i]->repeatCell->fields = "userEnteredFormat(backgroundColor,textFormat,horizontalAlignment)";
$i++;
$asyncHttpRequest = new AsyncHttpRequest($this->maniaControl, 'https://sheets.googleapis.com/v4/spreadsheets/' . $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_MATCHMANAGERGSHEET_SPREADSHEET) . ':batchUpdate');
$asyncHttpRequest = new AsyncHttpRequest($this->maniaControl, 'https://sheets.googleapis.com/v4/spreadsheets/' . $spreadsheetid . ':batchUpdate');
$asyncHttpRequest->setContentType(AsyncHttpRequest::CONTENT_TYPE_JSON);
$asyncHttpRequest->setHeaders(array("Authorization: Bearer " . $this->access_token));
$asyncHttpRequest->setContent(json_encode($data));
$asyncHttpRequest->setCallable(function ($json, $error) use ($sheetname) {
$asyncHttpRequest->setCallable(function ($json, $error) use ($sheetname, $spreadsheetid) {
if (!$json || $error) {
Logger::logError('Error from Google API: ' . $error);
$this->maniaControl->getChat()->sendErrorToAdmins('Error from Google API: ' . $error);
@ -798,10 +917,16 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
$this->maniaControl->getChat()->sendErrorToAdmins('Json parse error: ' . $json);
return;
}
if (property_exists($data, "error")) {
Logger::logError('Request error: ' . $data->error->code . " ". $data->error->message);
$this->maniaControl->getChat()->sendErrorToAdmins('Request error: ' . $data->error->code . " ". $data->error->message);
return;
}
// Clear Scoreboards data
$asyncHttpRequest = new AsyncHttpRequest($this->maniaControl, 'https://sheets.googleapis.com/v4/spreadsheets/' . $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_MATCHMANAGERGSHEET_SPREADSHEET) . '/values/' . urlencode("'". $sheetname . "'") . '!A1:Z300:clear');
$asyncHttpRequest = new AsyncHttpRequest($this->maniaControl, 'https://sheets.googleapis.com/v4/spreadsheets/' . $spreadsheetid . '/values/' . urlencode("'". $sheetname . "'") . '!A1:Z300:clear');
$asyncHttpRequest->setHeaders(array("Authorization: Bearer " . $this->access_token));
$asyncHttpRequest->setCallable(function ($json, $error) use ($sheetname) {
$asyncHttpRequest->setCallable(function ($json, $error) use ($sheetname, $spreadsheetid) {
if (!$json || $error) {
Logger::logError('Error from Google API: ' . $error);
$this->maniaControl->getChat()->sendErrorToAdmins('Error from Google API: ' . $error);
@ -813,13 +938,19 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
$this->maniaControl->getChat()->sendErrorToAdmins('Json parse error: ' . $json);
return;
}
if (property_exists($data, "error")) {
Logger::logError('Request error: ' . $data->error->code . " ". $data->error->message);
$this->maniaControl->getChat()->sendErrorToAdmins('Request error: ' . $data->error->code . " ". $data->error->message);
return;
}
// Add headers data
$data = new \stdClass;
$data->valueInputOption = "RAW";
$data->data[0] = new \stdClass;
$data->data[0]->range = "'" . $sheetname . "'!A1";
$data->data[0]->values = array(array("Informations"),array("Match status:", $this->matchstatus),array("Maps:","0/0"),array("Rounds:","0/0"),array("Players:","0"),array("Spectators:","0"),array(),array("Login:","Nickname:"));
$data->data[0]->values = array(array("Informations"),array("Match status:", $this->matchstatus),array("Maps:","0/0"),array("Rounds:","0/0"),array("Players:","0"),array("Spectators:","0"));
$data->data[1] = new \stdClass;
$data->data[1]->range = "'" . $sheetname . "'!D1";
@ -829,7 +960,7 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
$data->data[2]->range = "'" . $sheetname . "'!" . self::MODE_SPECIFICS_SETTINGS[$this->currentdatamode]["TeamsScoreTable_BeginLetter"] . "1";
$data->data[2]->values = array(self::MODE_SPECIFICS_SETTINGS[$this->currentdatamode]["TeamsScoreTable_Labels"]);
$asyncHttpRequest = new AsyncHttpRequest($this->maniaControl, 'https://sheets.googleapis.com/v4/spreadsheets/' . $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_MATCHMANAGERGSHEET_SPREADSHEET) . '/values:batchUpdate');
$asyncHttpRequest = new AsyncHttpRequest($this->maniaControl, 'https://sheets.googleapis.com/v4/spreadsheets/' . $spreadsheetid . '/values:batchUpdate');
$asyncHttpRequest->setContentType(AsyncHttpRequest::CONTENT_TYPE_JSON);
$asyncHttpRequest->setHeaders(array("Authorization: Bearer " . $this->access_token));
$asyncHttpRequest->setContent(json_encode($data));
@ -845,6 +976,11 @@ class MatchManagerGSheet implements CallbackListener, TimerListener, CommandLis
$this->maniaControl->getChat()->sendErrorToAdmins('Json parse error: ' . $json);
return;
}
if (property_exists($data, "error")) {
Logger::logError('Request error: ' . $data->error->code . " ". $data->error->message);
$this->maniaControl->getChat()->sendErrorToAdmins('Request error: ' . $data->error->code . " ". $data->error->message);
return;
}
});
$asyncHttpRequest->postData(1000);
});

View File

@ -17,12 +17,14 @@ use ManiaControl\Manialinks\ManialinkPageAnswerListener;
use ManiaControl\Callbacks\CallbackListener;
use ManiaControl\Callbacks\CallbackManager;
use ManiaControl\Callbacks\Callbacks;
use ManiaControl\Logger;
use ManiaControl\ManiaControl;
use ManiaControl\Players\Player;
use ManiaControl\Plugins\Plugin;
use ManiaControl\Plugins\PluginManager;
use ManiaControl\Commands\CommandListener;
use ManiaControl\Plugins\PluginMenu;
if (!class_exists('MatchManagerSuite\MatchManagerCore')) {
$this->maniaControl->getChat()->sendErrorToAdmins('MatchManager Core is required to use one of MatchManager plugin. Install it and restart Maniacontrol');
@ -42,21 +44,23 @@ class MatchManagerMultipleConfigManager implements ManialinkPageAnswerListener,
* Constants
*/
const PLUGIN_ID = 171;
const PLUGIN_VERSION = 1.2;
const PLUGIN_VERSION = 1.6;
const PLUGIN_NAME = 'MatchManager Multiple Config Manager';
const PLUGIN_AUTHOR = 'Beu';
// MatchManagerWidget Properties
const MATCHMANAGERCORE_PLUGIN = 'MatchManagerSuite\MatchManagerCore';
const MATCHMANAGERADMINUI_PLUGIN = 'MatchManagerSuite\MatchManagerAdminUI';
const DB_MATCHCONFIG = 'MatchManager_MatchConfigs';
const ML_ID = 'MatchManager.MultiConfigManager.UI';
const ML_ACTION_REMOVE_CONFIG = 'MatchManager.MultiConfigManager.RemoveConfig';
const ML_ACTION_LOAD_CONFIG = 'MatchManager.MultiConfigManager.LoadConfig';
const ML_ACTION_LOAD_CONFIG_PAGE = 'MatchManager.MultiConfigManager.LoadConfigPage';
const ML_ACTION_SAVE_CONFIG = 'MatchManager.MultiConfigManager.SaveConfig';
const ML_ACTION_SAVE_CONFIG_PAGE = 'MatchManager.MultiConfigManager.SaveConfigPage';
const ML_ACTION_OPENSETTINGS = 'MatchManagerSuite\MatchManagerMultipleConfigManager.OpenSettings';
const ML_ACTION_REMOVE_CONFIG = 'MatchManagerSuite\MatchManagerMultipleConfigManager.RemoveConfig';
const ML_ACTION_LOAD_CONFIG = 'MatchManagerSuite\MatchManagerMultipleConfigManager.LoadConfig';
const ML_ACTION_LOAD_CONFIG_PAGE = 'MatchManagerSuite\MatchManagerMultipleConfigManager.LoadConfigPage';
const ML_ACTION_SAVE_CONFIG = 'MatchManagerSuite\MatchManagerMultipleConfigManager.SaveConfig';
const ML_ACTION_SAVE_CONFIG_PAGE = 'MatchManagerSuite\MatchManagerMultipleConfigManager.SaveConfigPage';
const ML_NAME_CONFIGNAME = 'MatchManager.MultiConfigManager.ConfigName';
const CB_LOADCONFIG = 'MatchManager.MultiConfigManager.LoadConfig';
@ -125,13 +129,15 @@ class MatchManagerMultipleConfigManager implements ManialinkPageAnswerListener,
throw new \Exception('MatchManager Core is needed to use MatchManager Players Pause plugin');
}
$this->maniaControl->getCallbackManager()->registerCallbackListener(Callbacks::AFTERINIT, $this, 'handleAfterInit');
$this->maniaControl->getCallbackManager()->registerCallbackListener(PluginManager::CB_PLUGIN_LOADED, $this, 'handlePluginLoaded');
$this->maniaControl->getCallbackManager()->registerCallbackListener(PluginManager::CB_PLUGIN_UNLOADED, $this, 'handlePluginUnloaded');
$this->maniaControl->getCallbackManager()->registerCallbackListener(CallbackManager::CB_MP_PLAYERMANIALINKPAGEANSWER, $this, 'handleManialinkPageAnswer');
$this->maniaControl->getCommandManager()->registerCommandListener('matchconfig', $this, 'showConfigListUI', true, 'Start a match');
$this->initTables();
$this->updateAdminUIMenuItems();
return true;
}
@ -139,6 +145,31 @@ class MatchManagerMultipleConfigManager implements ManialinkPageAnswerListener,
* @see \ManiaControl\Plugins\Plugin::unload()
*/
public function unload() {
/** @var \MatchManagerSuite\MatchManagerAdminUI|null */
$adminUIPlugin = $this->maniaControl->getPluginManager()->getPlugin(self::MATCHMANAGERADMINUI_PLUGIN);
if ($adminUIPlugin !== null) {
$adminUIPlugin->removeMenuItem(self::ML_ACTION_OPENSETTINGS);
}
}
/**
* handle Plugin Loaded
*
* @param string $pluginClass
*/
public function handleAfterInit() {
$this->updateAdminUIMenuItems();
}
/**
* handle Plugin Loaded
*
* @param string $pluginClass
*/
public function handlePluginLoaded(string $pluginClass) {
if ($pluginClass === self::MATCHMANAGERADMINUI_PLUGIN) {
$this->updateAdminUIMenuItems();
}
}
/**
@ -174,6 +205,21 @@ class MatchManagerMultipleConfigManager implements ManialinkPageAnswerListener,
}
}
/**
* Add items in AdminUI plugin
*/
public function updateAdminUIMenuItems() {
/** @var \MatchManagerSuite\MatchManagerAdminUI|null */
$adminUIPlugin = $this->maniaControl->getPluginManager()->getPlugin(self::MATCHMANAGERADMINUI_PLUGIN);
if ($adminUIPlugin === null) return;
$adminUIPlugin->removeMenuItem(self::ML_ACTION_OPENSETTINGS);
$menuItem = new \MatchManagerSuite\MatchManagerAdminUI_MenuItem();
$menuItem->setActionId(self::ML_ACTION_OPENSETTINGS)->setOrder(200)->setStyle('UICommon64_2')->setSubStyle('Plugin_light')->setDescription('Manage Multiple Configs');
$adminUIPlugin->addMenuItem($menuItem);
}
/**
* handleManialinkPageAnswer
*
@ -181,10 +227,10 @@ class MatchManagerMultipleConfigManager implements ManialinkPageAnswerListener,
* @return void
*/
public function handleManialinkPageAnswer(array $callback) {
Logger::log("handleManialinkPageAnswer");
$actionId = $callback[1][2];
$actionArray = explode('.', $actionId);
if ($actionArray[0] != "MatchManager" || $actionArray[1] != "MultiConfigManager") {
if ($actionArray[0] !== self::class) {
return;
}
@ -194,11 +240,14 @@ class MatchManagerMultipleConfigManager implements ManialinkPageAnswerListener,
return;
}
$action = $actionArray[0] . '.' . $actionArray[1] . '.' . $actionArray[2];
$action = $actionArray[0] . "." . $actionArray[1];
switch ($action) {
case self::ML_ACTION_OPENSETTINGS:
$this->showConfigListUI(array(), $player);
break;
case self::ML_ACTION_REMOVE_CONFIG:
$id = intval($actionArray[3]);
$id = intval($actionArray[2]);
Logger::log("[MatchManagerMultipleConfigManager] Removing config: " . $id);
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
@ -213,7 +262,7 @@ class MatchManagerMultipleConfigManager implements ManialinkPageAnswerListener,
$this->showConfigListUI(array(), $player);
break;
case self::ML_ACTION_LOAD_CONFIG:
$id = intval($actionArray[3]);
$id = intval($actionArray[2]);
// Hide loading before because it can take few seconds
$this->maniaControl->getManialinkManager()->hideManialink(ManialinkManager::MAIN_MLID, $login);
$this->loadConfig($id);
@ -224,7 +273,7 @@ class MatchManagerMultipleConfigManager implements ManialinkPageAnswerListener,
case self::ML_ACTION_SAVE_CONFIG:
if ($callback[1][3][0]["Value"]) {
$this->showConfigListUI(array(), $player);
$this->saveConfig($callback[1][3]);
$this->saveCurrentConfig($callback[1][3]);
$this->showConfigListUI(array(), $player);
}
break;
@ -295,12 +344,12 @@ class MatchManagerMultipleConfigManager implements ManialinkPageAnswerListener,
}
/**
* saveConfig
* saveCurrentConfig
*
* @param array $fields
* @return void
*/
public function saveConfig(array $fields) {
public function saveCurrentConfig(array $fields) {
Logger::log("[MatchManagerMultipleConfigManager] Saving current config");
$result = array();
$configname = "";
@ -331,17 +380,13 @@ class MatchManagerMultipleConfigManager implements ManialinkPageAnswerListener,
return;
}
$config = json_encode($result);
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
$query = $mysqli->prepare('INSERT INTO `' . self::DB_MATCHCONFIG . '` (`name`,`gamemodebase`,`config`) VALUES (?, ?, ?);');
$query->bind_param('sss', $configname, $gamemodebase, $config);
if (!$query->execute()) {
trigger_error('Error executing MySQL query: ' . $query->error);
}
$this->maniaControl->getCallbackManager()->triggerCallback(self::CB_LOADCONFIG, $configname);
$this->saveConfig($configname, $gamemodebase, json_encode($result));
}
/**
* getSavedConfigs
* @return array
*/
public function getSavedConfigs() {
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
$query = 'SELECT `id`,`name`,`gamemodebase`,`date` FROM `' . self::DB_MATCHCONFIG . '` ORDER BY id DESC';
@ -353,6 +398,37 @@ class MatchManagerMultipleConfigManager implements ManialinkPageAnswerListener,
return $result->fetch_all(MYSQLI_ASSOC);
}
/**
* saveConfig
* @param string $configname
* @param string $gamemodebase
* @param string $config
* @return void
*/
public function saveConfig(string $configname, string $gamemodebase, string $config) {
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
$query = $mysqli->prepare('INSERT INTO `' . self::DB_MATCHCONFIG . '` (`name`,`gamemodebase`,`config`) VALUES (?, ?, ?);');
$query->bind_param('sss', $configname, $gamemodebase, $config);
if (!$query->execute()) {
trigger_error('Error executing MySQL query: ' . $query->error);
}
$this->maniaControl->getCallbackManager()->triggerCallback(self::CB_SAVECONFIG, $configname);
}
/**
* getConfig
* @param string $name
* @return object|null config
*/
public function getConfig(string $name) {
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
$stmt = $mysqli->prepare('SELECT id FROM `' . self::DB_MATCHCONFIG . '` WHERE `name` = ? LIMIT 1;');
$stmt->bind_param('s', $name);
if (!$stmt->execute()) {
trigger_error('Error executing MySQL query: ' . $stmt->error);
}
return $stmt->get_result()->fetch_object();
}
/**
* Shows a ManiaLink list with the local records.
@ -362,7 +438,6 @@ class MatchManagerMultipleConfigManager implements ManialinkPageAnswerListener,
* @param Player $player
*/
public function showConfigListUI(array $chat, Player $player) {
Logger::log("showConfigListUI");
$width = $this->maniaControl->getManialinkManager()->getStyleManager()->getListWidgetsWidth();
$height = $this->maniaControl->getManialinkManager()->getStyleManager()->getListWidgetsHeight();
@ -464,15 +539,15 @@ class MatchManagerMultipleConfigManager implements ManialinkPageAnswerListener,
$index++;
}
//Search for Map-Name
$mapNameButton = $this->maniaControl->getManialinkManager()->getElementBuilder()->buildRoundTextButton(
// Save config button
$saveConfigButton = $this->maniaControl->getManialinkManager()->getElementBuilder()->buildRoundTextButton(
'Save current config',
35,
5,
self::ML_ACTION_SAVE_CONFIG_PAGE
);
$frame->addChild($mapNameButton);
$mapNameButton->setPosition(-$width / 2 + 110, -36);
$frame->addChild($saveConfigButton);
$saveConfigButton->setPosition(-$width / 2 + 110, -$height / 2 + 6);
// Render and display xml
$this->maniaControl->getManialinkManager()->displayWidget($maniaLink, $player, self::ML_ID);
@ -486,7 +561,6 @@ class MatchManagerMultipleConfigManager implements ManialinkPageAnswerListener,
* @param Player $player
*/
public function showSaveConfigUI(Player $player) {
Logger::log("showConfigListUI");
$width = $this->maniaControl->getManialinkManager()->getStyleManager()->getListWidgetsWidth();
$height = $this->maniaControl->getManialinkManager()->getStyleManager()->getListWidgetsHeight();
@ -580,13 +654,13 @@ class MatchManagerMultipleConfigManager implements ManialinkPageAnswerListener,
self::ML_ACTION_SAVE_CONFIG
);
$frame->addChild($mapNameButton);
$mapNameButton->setPosition(-$width / 2 + 60, -35);
$mapNameButton->setPosition(-$width / 2 + 60, -$height / 2 + 5);
$entry = new Entry();
$frame->addChild($entry);
$entry->setStyle(Label_Text::STYLE_TextValueSmall);
$entry->setHorizontalAlign($entry::LEFT);
$entry->setPosition(-$width / 2 + 80, -35);
$entry->setPosition(-$width / 2 + 80, -$height / 2 + 5);
$entry->setTextSize(1);
$entry->setSize($width * 0.25, 4);
$entry->setName(self::ML_NAME_CONFIGNAME);

View File

@ -38,7 +38,7 @@ class MatchManagerPlayersPause implements ManialinkPageAnswerListener, CommandLi
* Constants
*/
const PLUGIN_ID = 159;
const PLUGIN_VERSION = 1.3;
const PLUGIN_VERSION = 1.5;
const PLUGIN_NAME = 'MatchManager Players Pause';
const PLUGIN_AUTHOR = 'Beu';
@ -59,7 +59,6 @@ class MatchManagerPlayersPause implements ManialinkPageAnswerListener, CommandLi
/** @var ManiaControl $maniaControl */
private $maniaControl = null;
private $MatchManagerCore = null;
private $chatprefix = '$<$fc3$w🏆$m$> '; // Would like to create a setting but MC database doesn't support utf8mb4
private $playerspausestate = array();
@ -138,6 +137,10 @@ class MatchManagerPlayersPause implements ManialinkPageAnswerListener, CommandLi
$this->maniaControl->getCallbackManager()->registerCallbackListener(PlayerManager::CB_PLAYERDISCONNECT, $this, 'handlePlayerDisconnect');
$this->maniaControl->getCallbackManager()->registerCallbackListener(PlayerManager::CB_PLAYERINFOCHANGED, $this, 'displayPauseWidgetIfNeeded');
$this->maniaControl->getCallbackManager()->registerCallbackListener(MatchManagerCore::CB_MATCHMANAGER_STARTMATCH, $this, 'handleMatchManagerCoreCallback');
$this->maniaControl->getCallbackManager()->registerCallbackListener(MatchManagerCore::CB_MATCHMANAGER_ENDMATCH, $this, 'handleMatchManagerCoreCallback');
$this->maniaControl->getCallbackManager()->registerCallbackListener(MatchManagerCore::CB_MATCHMANAGER_STOPMATCH, $this, 'handleMatchManagerCoreCallback');
$this->maniaControl->getCallbackManager()->registerCallbackListener(Callbacks::MP_STARTROUNDSTART, $this, 'handleBeginRoundCallback');
@ -211,11 +214,11 @@ class MatchManagerPlayersPause implements ManialinkPageAnswerListener, CommandLi
Logger::log('Pause requested by players');
if (!$this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_MATCH_PAUSE_WAIT_END_ROUND)) {
if ($this->maniaControl->getSettingManager()->getSettingValue($this->maniaControl, MatchManagerCore::SETTING_MATCH_PAUSE_DURATION) <= 0) {
$this->maniaControl->getChat()->sendInformation($this->chatprefix . 'Ask the admins to resume the match');
$this->maniaControl->getChat()->sendInformation($this->MatchManagerCore->getChatPrefix() . 'Ask the admins to resume the match');
}
$this->MatchManagerCore->setNadeoPause();
} else {
$this->maniaControl->getChat()->sendInformation($this->chatprefix . 'Pause will start at the end of this round');
$this->maniaControl->getChat()->sendInformation($this->MatchManagerCore->getChatPrefix() . 'Pause will start at the end of this round');
$this->LaunchPauseAtTheEnd = true;
}
return;
@ -292,10 +295,10 @@ class MatchManagerPlayersPause implements ManialinkPageAnswerListener, CommandLi
if (isset($this->playerspausestate[$player->login])) {
if ($this->playerspausestate[$player->login] == 0) {
$this->playerspausestate[$player->login] = 1;
$this->maniaControl->getChat()->sendInformation($this->chatprefix . 'Player $<$ff0' . $player->nickname . '$> asks a pause');
$this->maniaControl->getChat()->sendInformation($this->MatchManagerCore->getChatPrefix() . 'Player $<$ff0' . $player->nickname . '$> asks a pause');
} elseif ($this->playerspausestate[$player->login] == 1) {
$this->playerspausestate[$player->login] = 0;
$this->maniaControl->getChat()->sendInformation($this->chatprefix . 'Player $<$ff0' . $player->nickname . '$> no longer asks for a pause');
$this->maniaControl->getChat()->sendInformation($this->MatchManagerCore->getChatPrefix() . 'Player $<$ff0' . $player->nickname . '$> no longer asks for a pause');
}
$this->PauseMatchIfNeeded($player);
}
@ -318,7 +321,7 @@ class MatchManagerPlayersPause implements ManialinkPageAnswerListener, CommandLi
public function handleBeginRoundCallback() {
if ($this->LaunchPauseAtTheEnd) {
if ($this->maniaControl->getSettingManager()->getSettingValue($this->maniaControl, MatchManagerCore::SETTING_MATCH_PAUSE_DURATION) <= 0) {
$this->maniaControl->getChat()->sendInformation($this->chatprefix . 'Ask the admins to resume the match');
$this->maniaControl->getChat()->sendInformation($this->MatchManagerCore->getChatPrefix() . 'Ask the admins to resume the match');
}
$this->LaunchPauseAtTheEnd = false;
@ -328,6 +331,15 @@ class MatchManagerPlayersPause implements ManialinkPageAnswerListener, CommandLi
}
}
/**
* handleMatchManagerCoreCallback
*
* @return void
*/
public function handleMatchManagerCoreCallback() {
$this->displayPauseWidgetIfNeeded();
}
/**
* Generate Manialinks variables
*/

View File

@ -17,7 +17,7 @@ use ManiaControl\Plugins\PluginManager;
use ManiaControl\Settings\Setting;
use ManiaControl\Settings\SettingManager;
use ManiaControl\Commands\CommandListener;
use Maniaplanet\DedicatedServer\InvalidArgumentException;
if (!class_exists('MatchManagerSuite\MatchManagerCore')) {
$this->maniaControl->getChat()->sendErrorToAdmins('MatchManager Core is required to use one of MatchManager plugin. Install it and restart Maniacontrol');
@ -37,7 +37,7 @@ class MatchManagerReadyButton implements ManialinkPageAnswerListener, CommandLis
* Constants
*/
const PLUGIN_ID = 158;
const PLUGIN_VERSION = 1.3;
const PLUGIN_VERSION = 1.5;
const PLUGIN_NAME = 'MatchManager Ready Button';
const PLUGIN_AUTHOR = 'Beu';
@ -58,7 +58,6 @@ class MatchManagerReadyButton implements ManialinkPageAnswerListener, CommandLis
/** @var ManiaControl $maniaControl */
private $maniaControl = null;
private $MatchManagerCore = null;
private $chatprefix = '$<$fc3$w🏆$m$> '; // Would like to create a setting but MC database doesn't support utf8mb4
private $playersreadystate = array();
@ -135,6 +134,10 @@ class MatchManagerReadyButton implements ManialinkPageAnswerListener, CommandLis
$this->maniaControl->getCallbackManager()->registerCallbackListener(PlayerManager::CB_PLAYERDISCONNECT, $this, 'handlePlayerDisconnect');
$this->maniaControl->getCallbackManager()->registerCallbackListener(PlayerManager::CB_PLAYERINFOCHANGED, $this, 'displayReadyWidgetIfNeeded');
$this->maniaControl->getCallbackManager()->registerCallbackListener(MatchManagerCore::CB_MATCHMANAGER_STARTMATCH, $this, 'handleMatchManagerCoreCallback');
$this->maniaControl->getCallbackManager()->registerCallbackListener(MatchManagerCore::CB_MATCHMANAGER_ENDMATCH, $this, 'handleMatchManagerCoreCallback');
$this->maniaControl->getCallbackManager()->registerCallbackListener(MatchManagerCore::CB_MATCHMANAGER_STOPMATCH, $this, 'handleMatchManagerCoreCallback');
// Register ManiaLink Pages
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerListener(self::ACTION_READY, $this, 'handleReady');
@ -230,13 +233,13 @@ class MatchManagerReadyButton implements ManialinkPageAnswerListener, CommandLis
$this->closeReadyWidget($player->login);
} else if (!$player->isSpectator && !isset($this->playersreadystate[$player->login])) {
$this->playersreadystate[$player->login] = 0;
$this->maniaControl->getManialinkManager()->sendManialink($this->MLisNotReady, $player->login);
$this->maniaControl->getChat()->sendSuccess($this->chatprefix . 'You can now set you $<$f00Ready$> by clicking on the button', $player);
$this->maniaControl->getManialinkManager()->sendManialink($this->MLisNotReady, $player->login, ToggleUIFeature: false);
$this->maniaControl->getChat()->sendSuccess($this->MatchManagerCore->getChatPrefix() . 'You can now set you $<$f00Ready$> by clicking on the button', $player);
} else if (!$player->isSpectator && isset($this->playersreadystate[$player->login])) {
if ($this->playersreadystate[$player->login] == 1) {
$this->maniaControl->getManialinkManager()->sendManialink($this->MLisReady, $player->login);
$this->maniaControl->getManialinkManager()->sendManialink($this->MLisReady, $player->login, ToggleUIFeature: false);
} else {
$this->maniaControl->getManialinkManager()->sendManialink($this->MLisNotReady, $player->login);
$this->maniaControl->getManialinkManager()->sendManialink($this->MLisNotReady, $player->login, ToggleUIFeature: false);
}
}
}
@ -279,10 +282,10 @@ class MatchManagerReadyButton implements ManialinkPageAnswerListener, CommandLis
if (isset($this->playersreadystate[$player->login])) {
if ($this->playersreadystate[$player->login] == 0) {
$this->playersreadystate[$player->login] = 1;
$this->maniaControl->getChat()->sendInformation($this->chatprefix . 'Player $<$ff0' . $player->nickname . '$> now is $<$z$0f0ready$>');
$this->maniaControl->getChat()->sendInformation($this->MatchManagerCore->getChatPrefix() . 'Player $<$ff0' . $player->nickname . '$> now is $<$z$0f0ready$>');
} elseif ($this->playersreadystate[$player->login] == 1) {
$this->playersreadystate[$player->login] = 0;
$this->maniaControl->getChat()->sendInformation($this->chatprefix . 'Player $<$ff0' . $player->nickname . '$> now is $<$z$f00not ready$>');
$this->maniaControl->getChat()->sendInformation($this->MatchManagerCore->getChatPrefix() . 'Player $<$ff0' . $player->nickname . '$> now is $<$z$f00not ready$>');
}
$this->StartMatchIfNeeded($player);
}
@ -300,6 +303,14 @@ class MatchManagerReadyButton implements ManialinkPageAnswerListener, CommandLis
}
}
/**
* handleMatchManagerCoreCallback
*
* @return void
*/
public function handleMatchManagerCoreCallback() {
$this->displayReadyWidgetIfNeeded();
}
/**
* Generate Manialinks variables

View File

@ -0,0 +1,466 @@
<?php
namespace MatchManagerSuite;
use ManiaControl\Callbacks\CallbackListener;
use ManiaControl\Callbacks\Callbacks;
use ManiaControl\Callbacks\TimerListener;
use ManiaControl\Commands\CommandListener;
use ManiaControl\Logger;
use ManiaControl\ManiaControl;
use ManiaControl\Manialinks\ManialinkPageAnswerListener;
use ManiaControl\Players\Player;
use ManiaControl\Plugins\Plugin;
use ManiaControl\Plugins\PluginManager;
use ManiaControl\Plugins\PluginMenu;
use ManiaControl\Settings\Setting;
use ManiaControl\Settings\SettingManager;
use ManiaControl\Utils\WebReader;
if (!class_exists('MatchManagerSuite\MatchManagerCore')) {
$this->maniaControl->getChat()->sendErrorToAdmins('MatchManager Core is required to use one of MatchManager plugin. Install it and restart Maniacontrol');
Logger::logError('MatchManager Core is required to use one of MatchManager plugin. Install it and restart Maniacontrol');
return false;
}
use MatchManagerSuite\MatchManagerCore;
/**
* MatchManager TMWT Duo Integration
*
* @author Beu (based on MatchManagerWidget by jonthekiller)
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
*/
class MatchManagerTMWTDuoIntegration implements CallbackListener, ManialinkPageAnswerListener, CommandListener, TimerListener, Plugin {
/*
* Constants
*/
const PLUGIN_ID = 211;
const PLUGIN_VERSION = 1.0;
const PLUGIN_NAME = 'MatchManager TMWT Duo Integration';
const PLUGIN_AUTHOR = 'Beu';
// Other MatchManager plugin
const MATCHMANAGERCORE_PLUGIN = 'MatchManagerSuite\MatchManagerCore';
const MATCHMANAGERADMINUI_PLUGIN = 'MatchManagerSuite\MatchManagerAdminUI';
// Actions
const ML_ACTION_OPENSETTINGS = 'MatchManagerSuite\MatchManagerTMWTDuoIntegration.OpenSettings';
const XMLRPC_CALLBACK_PICKANDBANCOMPLETE = 'PickBan.Complete';
const XMLRPC_CALLBACK_STARTMAP = 'Maniaplanet.StartMap_Start';
const XMLRPC_METHOD_STARTPICKANDBAN = 'PickBan.Start';
const XMLRPC_METHOD_ADDPLAYER = 'Club.Match.AddPlayer';
const XMLRPC_METHOD_REMOVEPLAYER = 'Club.Match.RemovePlayer';
const XMLRPC_METHOD_MATCHSTARTED = 'Club.Match.Start';
const XMLRPC_METHOD_MATCHCOMPLETED = 'Club.Match.Completed';
const SETTING_TEAM1 = 'Team 1 Id';
const SETTING_TEAM2 = 'Team 2 Id';
const SETTING_PICKANDBAN_ENABLE = 'Enable Pick & Ban';
const SETTING_PICKANDBAN_STEPCONFIG = 'Pick & Ban: Step config';
const SETTING_PICKANDBAN_STEPDURATION = 'Pick & Ban: Step duration';
const SETTING_PICKANDBAN_RESULTDURATION = 'Pick & Ban: Result duration';
const STATE_NOTHING = 0;
const STATE_PRESETTING = 1;
const STATE_PREMATCH = 2;
const STATE_MATCH = 3;
/*
* Private properties
*/
/** @var ManiaControl $maniaControl */
private $maniaControl = null;
private $MatchManagerCore = null;
private $state = 0;
/**
* @param \ManiaControl\ManiaControl $maniaControl
* @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 'Integration of TMWT duo teams & pick and ban for MatchManager';
}
/**
* @param \ManiaControl\ManiaControl $maniaControl
* @return bool
* @see \ManiaControl\Plugins\Plugin::load()
*/
public function load(ManiaControl $maniaControl) {
$this->maniaControl = $maniaControl;
/** @var MatchManagerCore */
$this->MatchManagerCore = $this->maniaControl->getPluginManager()->getPlugin(self::MATCHMANAGERCORE_PLUGIN);
if ($this->MatchManagerCore == Null) {
throw new \Exception('MatchManager Core is needed to use ' . self::PLUGIN_NAME);
}
// Settings
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_TEAM1, '', '', 10);
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_TEAM2, '', '', 10);
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_PICKANDBAN_ENABLE, false, '', 20);
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_PICKANDBAN_STEPCONFIG, '', 'Similar syntax as the ofiicial Competition Tool. e.g: b:1,b:0,p:0,p:1,p:1,p:0,b:0,b:1,p:r');
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_PICKANDBAN_STEPDURATION, 60000, 'Each step duration in ms', 110);
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_PICKANDBAN_RESULTDURATION, 10000, 'result duration in ms', 120);
// Callbacks
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerListener(self::ML_ACTION_OPENSETTINGS, $this, 'handleActionOpenSettings');
$this->maniaControl->getCallbackManager()->registerCallbackListener(Callbacks::AFTERINIT, $this, 'handleAfterInit');
$this->maniaControl->getCallbackManager()->registerCallbackListener(PluginManager::CB_PLUGIN_LOADED, $this, 'handlePluginLoaded');
$this->maniaControl->getCallbackManager()->registerCallbackListener($this->MatchManagerCore::CB_MATCHMANAGER_STARTMATCH, $this, 'handleMatchManagerStartMatch');
$this->maniaControl->getCallbackManager()->registerCallbackListener(Callbacks::MP_STARTMATCHSTART, $this, 'handleStartMatchStartCallback');
$this->maniaControl->getCallbackManager()->registerScriptCallbackListener(self::XMLRPC_CALLBACK_STARTMAP, $this, 'handleStartMapStartCallback');
$this->maniaControl->getCallbackManager()->registerCallbackListener($this->MatchManagerCore::CB_MATCHMANAGER_STOPMATCH, $this, 'handleMatchManagerEndMatch');
$this->maniaControl->getCallbackManager()->registerCallbackListener($this->MatchManagerCore::CB_MATCHMANAGER_ENDMATCH, $this, 'handleMatchManagerEndMatch');
$this->maniaControl->getCallbackManager()->registerScriptCallbackListener(self::XMLRPC_CALLBACK_PICKANDBANCOMPLETE, $this, 'handlePickAndBanComplete');
$this->maniaControl->getCallbackManager()->registerCallbackListener(SettingManager::CB_SETTING_CHANGED, $this, 'handleSettingChanged');
$this->MatchManagerCore->addCanStartFunction($this, 'canStartMatch');
$this->updateAdminUIMenuItems();
}
/**
* handle Plugin Loaded
*
* @param string $pluginClass
*/
public function handleAfterInit() {
$this->updateAdminUIMenuItems();
}
/**
* handle Plugin Loaded
*
* @param string $pluginClass
*/
public function handlePluginLoaded(string $pluginClass) {
if ($pluginClass === self::MATCHMANAGERADMINUI_PLUGIN) {
$this->updateAdminUIMenuItems();
}
}
/**
* Add items in AdminUI plugin
*/
public function updateAdminUIMenuItems() {
/** @var \MatchManagerSuite\MatchManagerAdminUI|null */
$adminUIPlugin = $this->maniaControl->getPluginManager()->getPlugin(self::MATCHMANAGERADMINUI_PLUGIN);
if ($adminUIPlugin === null) return;
$adminUIPlugin->removeMenuItem(self::ML_ACTION_OPENSETTINGS);
$menuItem = new \MatchManagerSuite\MatchManagerAdminUI_MenuItem();
$menuItem->setActionId(self::ML_ACTION_OPENSETTINGS)
->setOrder(50)
->setImageUrl('https://files.virtit.fr/TrackMania/Images/Others/TMWT_Logo.dds')
->setSize(4.5)
->setDescription('Open TMWT Integration Settings');
$adminUIPlugin->addMenuItem($menuItem);
}
/**
* handle Open settings manialink action
*
* @param array $callback
* @param Player $player
*/
public function handleActionOpenSettings(array $callback, Player $player) {
if ($player->authLevel <= 0) return;
$pluginMenu = $this->maniaControl->getPluginManager()->getPluginMenu();
if (defined("\ManiaControl\ManiaControl::ISTRACKMANIACONTROL")) {
$player->setCache($pluginMenu, PluginMenu::CACHE_SETTING_CLASS, "PluginMenu.Settings." . self::class);
} else {
$player->setCache($pluginMenu, PluginMenu::CACHE_SETTING_CLASS, self::class);
}
$this->maniaControl->getConfigurator()->showMenu($player, $pluginMenu);
}
/**
* Callback function to check if everything is ok before starting the match
*
* @return bool
*/
public function canStartMatch() {
if ($this->maniaControl->getSettingManager()->getSettingValue($this->MatchManagerCore, 'S_TeamsUrl') === '') {
$this->maniaControl->getChat()->sendErrorToAdmins($this->MatchManagerCore->getChatPrefix() . " S_TeamsUrl must be defined");
return false;
}
if (
$this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_TEAM1) === '' ||
$this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_TEAM2) === ''
) {
$this->maniaControl->getChat()->sendErrorToAdmins($this->MatchManagerCore->getChatPrefix() . " Team Id must be defined");
return false;
}
if ($this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_PICKANDBAN_ENABLE)) {
if ($this->maniaControl->getSettingManager()->getSettingValue($this->MatchManagerCore, $this->MatchManagerCore::SETTING_MATCH_SETTINGS_MODE) !== "All from the plugin") {
$this->maniaControl->getChat()->sendErrorToAdmins('TMWT Pick and bans are only supported in Match Manager Core "All from the plugin" mode');
return false;
}
}
return true;
}
/**
* handle MatchManagerCore StartMatch callback
*
* @return void
*/
public function handleMatchManagerStartMatch() {
$this->state = self::STATE_PRESETTING;
$setting = $this->maniaControl->getSettingManager()->getSettingObject($this->MatchManagerCore, 'S_IsMatchmaking');
if ($setting !== null && !$setting->value) {
$setting->value = true;
$this->maniaControl->getSettingManager()->saveSetting($setting);
Logger::logWarning('Remplacing S_IsMatchmaking setting value in MatchManagerCore for TMWT integration');
$this->maniaControl->getChat()->sendErrorToAdmins('Remplacing S_IsMatchmaking setting value in MatchManagerCore for TMWT integration');
}
if ($this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_PICKANDBAN_ENABLE)) {
$setting = $this->maniaControl->getSettingManager()->getSettingObject($this->MatchManagerCore, 'S_PickAndBan_Enable');
if ($setting !== null && !$setting->value) {
$setting->value = true;
$this->maniaControl->getSettingManager()->saveSetting($setting);
Logger::logWarning('Remplacing S_PickAndBan_Enable setting value in MatchManagerCore for TMWT integration');
$this->maniaControl->getChat()->sendErrorToAdmins('Remplacing S_PickAndBan_Enable setting value in MatchManagerCore for TMWT integration');
}
}
}
/**
* handle MatchManagerCore StopMatch & EndMatch callback
*
* @return void
*/
public function handleMatchManagerEndMatch() {
$this->state = self::STATE_NOTHING;
}
/**
* handle StartMatch_Start script callback
*
* @return void
*/
public function handleStartMatchStartCallback() {
if ($this->MatchManagerCore->getMatchStatus() && $this->state === self::STATE_PREMATCH) {
// reset match state in just in case
$this->maniaControl->getClient()->triggerModeScriptEvent(self::XMLRPC_METHOD_MATCHCOMPLETED, []);
}
}
/**
* handle StartMap_Start script callback
*
* @return void
*/
public function handleStartMapStartCallback() {
if (!$this->MatchManagerCore->getMatchStatus()) return;
if ($this->state === self::STATE_PRESETTING) {
$this->state = self::STATE_PREMATCH;
$this->maniaControl->getClient()->setModeScriptSettings(['S_IsMatchmaking' => true], false);
$this->maniaControl->getClient()->restartMap();
} else if ($this->state === self::STATE_PREMATCH) {
$teamsUrl = $this->maniaControl->getSettingManager()->getSettingValue($this->MatchManagerCore, 'S_TeamsUrl');
if ($teamsUrl !== '') {
$response = WebReader::getUrl($teamsUrl);
$content = $response->getContent();
$json = json_decode($content);
if ($json !== null) {
$team1 = $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_TEAM1);
$team2 = $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_TEAM2);
foreach ($json as $team) {
if ($team->Id === $team1) {
$team1 = null;
foreach ($team->Players as $player) {
Logger::log($player->AccountId ." added to team 1");
$this->maniaControl->getClient()->triggerModeScriptEvent(self::XMLRPC_METHOD_ADDPLAYER, [$player->AccountId, "1"], true);
}
}
if ($team->Id === $team2) {
$team2 = null;
foreach ($team->Players as $player) {
Logger::log($player->AccountId ." added to team 2");
$this->maniaControl->getClient()->triggerModeScriptEvent(self::XMLRPC_METHOD_ADDPLAYER, [$player->AccountId, "2"], true);
}
}
if ($team1 === null && $team2 === null) break;
}
if ($this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_PICKANDBAN_ENABLE)) {
Logger::log('Starting Pick & ban in 10 seconds');
$this->maniaControl->getChat()->sendSuccess('Starting pick & ban in 10 seconds');
$this->maniaControl->getTimerManager()->registerOneTimeListening($this, function () {
$payload = [
'stepDuration' => $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_PICKANDBAN_STEPDURATION),
'resultDuration' => $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_PICKANDBAN_RESULTDURATION),
'steps' => []
];
$stepConfig = $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_PICKANDBAN_STEPCONFIG);
foreach (explode(',', $stepConfig) as $stepRaw) {
$stepPayload = [];
$step = explode(':', $stepRaw);
if ($step[1] === 'r') {
$stepPayload['action'] = 'randompick';
} else {
if ($step[0] === 'p') {
$stepPayload['action'] = 'pick';
} else if ($step[0] === 'b') {
$stepPayload['action'] = 'ban';
}
$stepPayload['team'] = $step[1] + 1;
}
$payload['steps'][] = $stepPayload;
}
$json = json_encode($payload);
Logger::log('Starting Pick & ban: '. $json);
$this->maniaControl->getClient()->triggerModeScriptEvent(self::XMLRPC_METHOD_STARTPICKANDBAN, [$json], true);
}, 5000);
} else {
$this->state = self::STATE_MATCH;
Logger::log('Sending match start callback');
$this->maniaControl->getClient()->triggerModeScriptEvent(self::XMLRPC_METHOD_MATCHSTARTED, [], true);
}
}
}
}
}
/**
* handle Pick & Ban completed script callback
*
* @param array $structure
* @return void
*/
public function handlePickAndBanComplete(array $structure) {
if (!$this->MatchManagerCore->getMatchStatus()) return;
Logger::log('Received picks: '. $structure[1][0]);
$this->maniaControl->getTimerManager()->registerOneTimeListening($this, function () use ($structure) {
try {
$json = json_decode($structure[1][0]);
$mapUids = array_column($json->playlist, 'uid');
$mapList = [];
foreach ($this->maniaControl->getMapManager()->getMaps() as $map) {
$index = array_search($map->uid, $mapUids);
if ($index === false) {
$this->maniaControl->getClient()->removeMap($map->fileName);
} else {
$mapList[$index] = $map->fileName;
}
}
if (count($mapUids) !== count($mapList)) {
Logger::logError("Missing maps: ". implode(' ', array_diff($mapUids, $mapList)));
}
ksort($mapList);
$this->maniaControl->getClient()->chooseNextMapList(array_values($mapList));
} catch (\Throwable $th) {
Logger::logError("Can't apply map list: ". $th->getMessage());
$this->maniaControl->getChat()->sendError("Can't apply map list: ". $th->getMessage());
}
$this->state = self::STATE_MATCH;
Logger::log('Sending match start callback');
$this->maniaControl->getClient()->triggerModeScriptEvent(self::XMLRPC_METHOD_MATCHSTARTED, [], true);
$this->maniaControl->getMapManager()->getMapActions()->skipMap();
}, $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_PICKANDBAN_RESULTDURATION));
}
/**
* handlePluginUnloaded
*
* @param string $pluginClass
* @param Plugin $plugin
* @return void
*/
public function handlePluginUnloaded(string $pluginClass, Plugin $plugin) {
if ($pluginClass == self::MATCHMANAGERCORE_PLUGIN) {
$this->maniaControl->getChat()->sendErrorToAdmins(self::PLUGIN_NAME . " disabled because MatchManager Core is now disabled");
$this->maniaControl->getPluginManager()->deactivatePlugin((get_class()));
}
}
/**
* handle Setting Changed callback
*
* @param Setting $setting
* @return void
*/
public function handleSettingChanged(Setting $setting) {
if ($setting->setting === self::SETTING_PICKANDBAN_ENABLE || $setting->setting === $this->MatchManagerCore::SETTING_MATCH_SETTINGS_MODE) {
if ($this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_PICKANDBAN_ENABLE)) {
if ($this->maniaControl->getSettingManager()->getSettingValue($this->MatchManagerCore, $this->MatchManagerCore::SETTING_MATCH_SETTINGS_MODE) !== "All from the plugin") {
$this->maniaControl->getChat()->sendErrorToAdmins('TMWT Pick and bans are only supported in Match Manager Core "All from the plugin" mode');
}
}
}
}
/**
* @see \ManiaControl\Plugins\Plugin::unload()
*/
public function unload() {
$this->MatchManagerCore->removeCanStartFunction($this, 'canStartMatch');
/** @var \MatchManagerSuite\MatchManagerAdminUI|null */
$adminUIPlugin = $this->maniaControl->getPluginManager()->getPlugin(self::MATCHMANAGERADMINUI_PLUGIN);
if ($adminUIPlugin !== null) {
$adminUIPlugin->removeMenuItem(self::ML_ACTION_OPENSETTINGS);
}
}
}

View File

@ -38,7 +38,7 @@ class MatchManagerWidget implements ManialinkPageAnswerListener, CallbackListene
* Constants
*/
const PLUGIN_ID = 153;
const PLUGIN_VERSION = 1.7;
const PLUGIN_VERSION = 1.8;
const PLUGIN_NAME = 'MatchManager Widget';
const PLUGIN_AUTHOR = 'Beu';
@ -66,8 +66,8 @@ class MatchManagerWidget implements ManialinkPageAnswerListener, CallbackListene
private $maniaControl = null;
private $MatchManagerCore = null;
private $gmbase = "";
private $manialinkData = "";
private $manialinkBackground = "";
private $manialinkData = null;
private $manialinkBackground = null;
private $playerswithML = [];
private $specswithML = [];
@ -519,7 +519,6 @@ class MatchManagerWidget implements ManialinkPageAnswerListener, CallbackListene
$rankLabel->setTextPrefix('$o');
$rankLabel->setText($rank);
$rankLabel->setTextEmboss(true);
$rankLabel->setZ(1);
//Name
$nameLabel = new Label();
@ -529,7 +528,6 @@ class MatchManagerWidget implements ManialinkPageAnswerListener, CallbackListene
$nameLabel->setSize($width * 0.6, 4);
$nameLabel->setTextSize(1);
$nameLabel->setTextEmboss(true);
$nameLabel->setZ(1);
//Points
$pointsLabel = new Label();
@ -540,14 +538,13 @@ class MatchManagerWidget implements ManialinkPageAnswerListener, CallbackListene
$pointsLabel->setTextSize(1);
$pointsLabel->setText('$z' . $points);
$pointsLabel->setTextEmboss(true);
$pointsLabel->setZ(1);
//Background with Spec action
$quad = new Quad();
$recordFrame->addChild($quad);
$quad->setStyles(Quad_Bgs1InRace::STYLE, Quad_Bgs1InRace::SUBSTYLE_BgCardList);
$quad->setSize($width-2, 4);
$quad->setZ(1);
$quad->setZ(-1);
if ($this->gmbase == "Teams") {
$team = $this->maniaControl->getClient()->getTeamInfo($score[1] + 1);