"TeaSpeak Provisioning Server", "APIVersion" => "1.2", "RequiresServer" => true, "DefaultNonSSLPort" => "10101", "ServiceSingleSignOnLabel" => "Login to TeaSpeak Panel", "AdminSingleSignOnLabel" => "Login to TeaSpeak as Admin", ]; } /** * Configuration options */ function teamspeak_ConfigOptions(): array { return []; } /** * Create new TeaSpeak account */ function teamspeak_CreateAccount(array $params): string { try { $settings = Capsule::table("modwhmcs_teamspeak_settings") ->where("id", 1) ->first(); if (!$settings) { throw new Exception( "TeaSpeak module settings not found. Please configure the addon module first.", ); } $slots = (int) ($params["configoptions"]["Slots"] ?? 0); $mbots = (int) ($params["configoptions"]["MBots"] ?? 0); // Validate TSDNS if enabled if ($settings->enabletsdns) { if ( !isset($params["customfields"]["Subdomain"]) || empty($params["customfields"]["Subdomain"]) ) { throw new Exception( 'Custom field "Subdomain" is required but not set', ); } $tsdnsClient = new TSDNS($settings->urlapi, $settings->keyapi); if (!$tsdnsClient) { throw new Exception( "Could not connect to TSDNS server: " . $settings->urlapi, ); } $subdomain = $params["customfields"]["Subdomain"] . "." . $settings->domaintsdns; $request = $tsdnsClient->getZone($subdomain); $zone = json_decode($request->body); if (isset($zone->message) && count($zone->message) > 0) { throw new Exception("Subdomain already exists"); } } // Connect to TeamSpeak server $tsAdmin = new TeamSpeak($params["serverip"], $params["serverport"]); if (!$tsAdmin->getElement("success", $tsAdmin->connect())) { throw new Exception("Could not connect to the TeamSpeak server"); } if ( !$tsAdmin->getElement( "success", $tsAdmin->login( $params["serverusername"], $params["serverpassword"], ), ) ) { throw new Exception("TeamSpeak ServerQuery login failed"); } // Find available port $port = _modwhmcs_findPort( $params, (int) $settings->minport, (int) $settings->maxport, ); if (!$port) { throw new Exception( "No free ports available in the configured range", ); } if (!$slots) { throw new Exception( "Slots parameter not found in configurable options", ); } if (!$mbots) { throw new Exception( "MBots parameter not found in configurable options", ); } // Validate custom fields exist if ( !Capsule::table("tblcustomfields") ->where("fieldname", "Token") ->where("relid", $params["pid"]) ->value("id") ) { throw new Exception('Custom field "Token" does not exist'); } if ( !Capsule::table("tblcustomfields") ->where("fieldname", "Port") ->where("relid", $params["pid"]) ->value("id") ) { throw new Exception('Custom field "Port" does not exist'); } // Prepare server data $data = [ "virtualserver_maxclients" => $slots, "virtualserver_name" => $settings->servername, "virtualserver_autostart" => true, "virtualserver_hostbanner_url" => $settings->bannerlinkurl, "virtualserver_hostbanner_gfx_url" => $settings->bannerimgurl, "virtualserver_hostbanner_mode" => $settings->bannermode, "virtualserver_hostbutton_url" => $settings->buttonlinkurl, "virtualserver_hostbutton_gfx_url" => $settings->buttonimgurl, "virtualserver_hostbutton_tooltip" => $settings->buttontooltip, "virtualserver_hostmessage" => $settings->servermsg, "virtualserver_hostmessage_mode" => $settings->servermsgmode, "virtualserver_welcomemessage" => $settings->servermsgwelcome, "virtualserver_port" => $port, "virtualserver_download_quota" => $settings->downloadquota, "virtualserver_upload_quota" => $settings->uploadquota, "virtualserver_download_total_bandwidth" => $settings->downloadbandwidth, "virtualserver_upload_total_bandwidth" => $settings->uploadbandwidth, "virtualserver_music_bot_limit" => $mbots, ]; $newserver = $tsAdmin->serverCreate($data); if (!$tsAdmin->getElement("success", $newserver)) { throw new Exception("Failed to create TeamSpeak server"); } // Update custom fields $tokenFieldId = Capsule::table("tblcustomfields") ->where("fieldname", "Token") ->where("relid", $params["pid"]) ->value("id"); Capsule::table("tblcustomfieldsvalues") ->where("fieldid", $tokenFieldId) ->where("relid", $params["serviceid"]) ->update(["value" => $newserver["data"]["token"]]); $portFieldId = Capsule::table("tblcustomfields") ->where("fieldname", "Port") ->where("relid", $params["pid"]) ->value("id"); Capsule::table("tblcustomfieldsvalues") ->where("fieldid", $portFieldId) ->where("relid", $params["serviceid"]) ->update(["value" => $newserver["data"]["virtualserver_port"]]); // Register TSDNS if enabled if ($settings->enabletsdns) { $subdomain = $params["customfields"]["Subdomain"] . "." . $settings->domaintsdns; $tsdnsClient->addZone( $subdomain, $params["serverip"] . ":" . $port, ); } return "success"; } catch (Exception $e) { logModuleCall( "teamspeak", __FUNCTION__, $params, $e->getMessage(), $e->getTraceAsString(), ); return $e->getMessage(); } } /** * Suspend TeaSpeak account */ function teamspeak_SuspendAccount(array $params): string { try { $port = $params["customfields"]["Port"] ?? null; if (!$port) { throw new Exception("Port does not exist in custom fields"); } $tsAdmin = new TeamSpeak($params["serverip"], $params["serverport"]); if (!$tsAdmin->getElement("success", $tsAdmin->connect())) { throw new Exception("Could not connect to the TeamSpeak server"); } if ( !$tsAdmin->getElement( "success", $tsAdmin->login( $params["serverusername"], $params["serverpassword"], ), ) ) { throw new Exception("TeamSpeak ServerQuery login failed"); } if (!$tsAdmin->getElement("success", $tsAdmin->selectServer($port))) { throw new Exception("Server not found on port: " . $port); } // Disable autostart $data = ["virtualserver_autostart" => 0]; if (!$tsAdmin->getElement("success", $tsAdmin->serverEdit($data))) { throw new Exception( "Failed to disable autostart for port: " . $port, ); } // Stop server $sid = $tsAdmin->serverIdGetByPort($port); $serverstop = $tsAdmin->serverStop($sid["data"]["server_id"]); if (!$tsAdmin->getElement("success", $serverstop)) { throw new Exception( "Could not stop server: " . ($serverstop["errors"][0] ?? "Unknown error"), ); } return "success"; } catch (Exception $e) { logModuleCall( "teamspeak", __FUNCTION__, $params, $e->getMessage(), $e->getTraceAsString(), ); return $e->getMessage(); } } /** * Unsuspend TeaSpeak account */ function teamspeak_UnsuspendAccount(array $params): string { try { $port = $params["customfields"]["Port"] ?? null; if (!$port) { throw new Exception("Port does not exist in custom fields"); } $tsAdmin = new TeamSpeak($params["serverip"], $params["serverport"]); if (!$tsAdmin->getElement("success", $tsAdmin->connect())) { throw new Exception("Could not connect to the TeamSpeak server"); } if ( !$tsAdmin->getElement( "success", $tsAdmin->login( $params["serverusername"], $params["serverpassword"], ), ) ) { throw new Exception("TeamSpeak ServerQuery login failed"); } // Start server $sid = $tsAdmin->serverIdGetByPort($port); $serverstart = $tsAdmin->serverStart($sid["data"]["server_id"]); if (!$tsAdmin->getElement("success", $serverstart)) { throw new Exception( "Could not start server: " . ($serverstart["errors"][0] ?? "Unknown error"), ); } if (!$tsAdmin->getElement("success", $tsAdmin->selectServer($port))) { throw new Exception("Server not found on port: " . $port); } // Enable autostart $data = ["virtualserver_autostart" => 1]; if (!$tsAdmin->getElement("success", $tsAdmin->serverEdit($data))) { throw new Exception( "Failed to enable autostart for port: " . $port, ); } return "success"; } catch (Exception $e) { logModuleCall( "teamspeak", __FUNCTION__, $params, $e->getMessage(), $e->getTraceAsString(), ); return $e->getMessage(); } } /** * Terminate TeaSpeak account */ function teamspeak_TerminateAccount(array $params): string { try { $settings = Capsule::table("modwhmcs_teamspeak_settings") ->select("enabletsdns", "domaintsdns", "keyapi", "urlapi") ->first(); $port = $params["customfields"]["Port"] ?? null; if (!$port) { throw new Exception("Port does not exist in custom fields"); } $tsAdmin = new TeamSpeak($params["serverip"], $params["serverport"]); if (!$tsAdmin->getElement("success", $tsAdmin->connect())) { throw new Exception("Could not connect to the TeamSpeak server"); } if ( !$tsAdmin->getElement( "success", $tsAdmin->login( $params["serverusername"], $params["serverpassword"], ), ) ) { throw new Exception("TeamSpeak ServerQuery login failed"); } $sid = $tsAdmin->serverIdGetByPort($port); if ( $tsAdmin->getElement( "success", $tsAdmin->serverDelete($sid["data"]["server_id"]), ) ) { // Delete backups Capsule::table("modwhmcs_teamspeak_backups") ->where("port", $port) ->delete(); // Remove TSDNS entry if enabled if ($settings && $settings->enabletsdns) { $tsdnsClient = new TSDNS($settings->urlapi, $settings->keyapi); $subdomain = $params["customfields"]["Subdomain"] . "." . $settings->domaintsdns; $tsdnsClient->deleteZone($subdomain); } } else { throw new Exception("Could not delete TeamSpeak server"); } return "success"; } catch (Exception $e) { logModuleCall( "teamspeak", __FUNCTION__, $params, $e->getMessage(), $e->getTraceAsString(), ); return $e->getMessage(); } } /** * Change package/upgrade */ function teamspeak_ChangePackage(array $params): string { try { $slots = (int) ($params["configoptions"]["Slots"] ?? 0); $mbots = (int) ($params["configoptions"]["MBots"] ?? 0); $port = $params["customfields"]["Port"] ?? null; if (!$port) { throw new Exception("Port does not exist in custom fields"); } if (!$slots) { throw new Exception("Slots parameter not found"); } if (!$mbots) { throw new Exception("MBots parameter not found"); } $tsAdmin = new TeamSpeak($params["serverip"], $params["serverport"]); if (!$tsAdmin->getElement("success", $tsAdmin->connect())) { throw new Exception("Could not connect to the TeamSpeak server"); } if ( !$tsAdmin->getElement( "success", $tsAdmin->login( $params["serverusername"], $params["serverpassword"], ), ) ) { throw new Exception("TeamSpeak ServerQuery login failed"); } if (!$tsAdmin->getElement("success", $tsAdmin->selectServer($port))) { throw new Exception("Server not found on port: " . $port); } $data = [ "virtualserver_maxclients" => $slots, "virtualserver_music_bot_limit" => $mbots, ]; if (!$tsAdmin->getElement("success", $tsAdmin->serverEdit($data))) { throw new Exception( "Failed to update server settings for port: " . $port, ); } return "success"; } catch (Exception $e) { logModuleCall( "teamspeak", __FUNCTION__, $params, $e->getMessage(), $e->getTraceAsString(), ); return $e->getMessage(); } } /** * Test connection to server */ function teamspeak_TestConnection(array $params): array { try { $tsAdmin = new TeamSpeak($params["serverip"], $params["serverport"]); if (!$tsAdmin->getElement("success", $tsAdmin->connect())) { throw new Exception("Could not connect to the TeamSpeak server"); } if ( !$tsAdmin->getElement( "success", $tsAdmin->login( $params["serverusername"], $params["serverpassword"], ), ) ) { throw new Exception("TeamSpeak ServerQuery login failed"); } return [ "success" => true, "error" => "", ]; } catch (Exception $e) { logModuleCall( "teamspeak", __FUNCTION__, $params, $e->getMessage(), $e->getTraceAsString(), ); return [ "success" => false, "error" => $e->getMessage(), ]; } } /** * Admin custom buttons */ function teamspeak_AdminCustomButtonArray(): array { return [ "Start" => "start_server", "Stop" => "stop_server", "Reinstall" => "reinstall_server", "Restore Permissions" => "perm_reset", ]; } /** * Client area custom buttons */ function teamspeak_ClientAreaCustomButtonArray(): array { return [ "Start Server" => "start_server", "Stop Server" => "stop_server", "Reinstall Server" => "reinstall_server", "Restore Permissions" => "perm_reset", "Edit Subdomain" => "tsdns", "Settings" => "settings", "Backups" => "backups", "Privileges" => "tokens", "Prohibitions" => "bans", ]; } /** * Start server action */ function teamspeak_start_server(array $params): string { try { $port = $params["customfields"]["Port"] ?? null; if (!$port) { throw new Exception("Port does not exist in custom fields"); } $tsAdmin = new TeamSpeak($params["serverip"], $params["serverport"]); if (!$tsAdmin->getElement("success", $tsAdmin->connect())) { throw new Exception("Server unavailable. Please contact support."); } if ( !$tsAdmin->getElement( "success", $tsAdmin->login( $params["serverusername"], $params["serverpassword"], ), ) ) { throw new Exception( "Unable to connect to server. Please contact support.", ); } // Check if server is already online $serverlist = $tsAdmin->serverList(); foreach ($serverlist["data"] as $server) { if ( $server["virtualserver_port"] == $port && $server["virtualserver_status"] == "Online" ) { throw new Exception("Server is already online"); } } $getsid = $tsAdmin->serverIdGetByPort($port); if (!$tsAdmin->getElement("success", $getsid)) { throw new Exception( "Server could not be started. Please contact support. (Error: Server ID not found)", ); } if ( !$tsAdmin->getElement( "success", $tsAdmin->serverStart($getsid["data"]["server_id"]), ) ) { throw new Exception( "Server could not be started. Please contact support. (Error: Start command failed)", ); } return "success"; } catch (Exception $e) { logModuleCall( "teamspeak", __FUNCTION__, $params, $e->getMessage(), $e->getTraceAsString(), ); return $e->getMessage(); } } /** * Stop server action */ function teamspeak_stop_server(array $params): string { try { $port = $params["customfields"]["Port"] ?? null; if (!$port) { throw new Exception("Port does not exist in custom fields"); } $tsAdmin = new TeamSpeak($params["serverip"], $params["serverport"]); if (!$tsAdmin->getElement("success", $tsAdmin->connect())) { throw new Exception("Server unavailable. Please contact support."); } if ( !$tsAdmin->getElement( "success", $tsAdmin->login( $params["serverusername"], $params["serverpassword"], ), ) ) { throw new Exception( "Unable to connect to server. Please contact support.", ); } // Check if server is already offline $serverlist = $tsAdmin->serverList(); foreach ($serverlist["data"] as $server) { if ( $server["virtualserver_port"] == $port && $server["virtualserver_status"] == "offline" ) { throw new Exception("Server is already stopped"); } } $getsid = $tsAdmin->serverIdGetByPort($port); if (!$tsAdmin->getElement("success", $getsid)) { throw new Exception( "Server not found. (Error: Server ID not found)", ); } if ( !$tsAdmin->getElement( "success", $tsAdmin->serverStop($getsid["data"]["server_id"]), ) ) { throw new Exception( "Server could not be stopped. Please contact support. (Error: Stop command failed)", ); } return "success"; } catch (Exception $e) { logModuleCall( "teamspeak", __FUNCTION__, $params, $e->getMessage(), $e->getTraceAsString(), ); return $e->getMessage(); } } /** * Reinstall server action */ function teamspeak_reinstall_server(array $params): string { try { $port = $params["customfields"]["Port"] ?? null; $slots = (int) ($params["configoptions"]["Slots"] ?? 0); $mbots = (int) ($params["configoptions"]["MBots"] ?? 0); if (!$port) { throw new Exception("Port does not exist in custom fields"); } if (!$slots) { throw new Exception( "Problem during reinstallation. (Error: Slots parameter not found)", ); } if (!$mbots) { throw new Exception( "Problem during reinstallation. (Error: MBots parameter not found)", ); } $tsAdmin = new TeamSpeak($params["serverip"], $params["serverport"]); if (!$tsAdmin->getElement("success", $tsAdmin->connect())) { throw new Exception("Server unavailable. Please contact support."); } if ( !$tsAdmin->getElement( "success", $tsAdmin->login( $params["serverusername"], $params["serverpassword"], ), ) ) { throw new Exception( "Unable to connect to server. Please contact support.", ); } // Delete old server $getsid = $tsAdmin->serverIdGetByPort($port); if ( !$tsAdmin->getElement("success", $getsid) || !$tsAdmin->getElement( "success", $tsAdmin->serverDelete($getsid["data"]["server_id"]), ) ) { throw new Exception( "Problem during reinstallation. Please contact support. (Error: Delete failed)", ); } // Validate custom fields if (!isset($params["customfields"]["Token"])) { throw new Exception( "Problem during reinstallation. (Error: Token field not found)", ); } if (!isset($params["customfields"]["Port"])) { throw new Exception( "Problem during reinstallation. (Error: Port field not found)", ); } // Get settings $settings = Capsule::table("modwhmcs_teamspeak_settings") ->where("id", 1) ->first(); if (!$settings) { throw new Exception("Module settings not found"); } // Prepare new server data $data = [ "virtualserver_maxclients" => $slots, "virtualserver_name" => $settings->servername, "virtualserver_autostart" => true, "virtualserver_hostbanner_url" => $settings->bannerlinkurl, "virtualserver_hostbanner_gfx_url" => $settings->bannerimgurl, "virtualserver_hostbanner_mode" => $settings->bannermode, "virtualserver_hostbutton_url" => $settings->buttonlinkurl, "virtualserver_hostbutton_gfx_url" => $settings->buttonimgurl, "virtualserver_hostbutton_tooltip" => $settings->buttontooltip, "virtualserver_hostmessage" => $settings->servermsg, "virtualserver_hostmessage_mode" => $settings->servermsgmode, "virtualserver_welcomemessage" => $settings->servermsgwelcome, "virtualserver_port" => $port, "virtualserver_download_quota" => $settings->downloadquota, "virtualserver_upload_quota" => $settings->uploadquota, "virtualserver_download_total_bandwidth" => $settings->downloadbandwidth, "virtualserver_upload_total_bandwidth" => $settings->uploadbandwidth, "virtualserver_music_bot_limit" => $mbots, ]; $newserver = $tsAdmin->serverCreate($data); if (!$tsAdmin->getElement("success", $newserver)) { throw new Exception( "Problem during reinstallation. Please contact support. (Error: Create failed)", ); } // Update token custom field $tokenFieldId = Capsule::table("tblcustomfields") ->where("fieldname", "Token") ->where("relid", $params["pid"]) ->value("id"); Capsule::table("tblcustomfieldsvalues") ->where("fieldid", $tokenFieldId) ->where("relid", $params["serviceid"]) ->update(["value" => $newserver["data"]["token"]]); return "success"; } catch (Exception $e) { logModuleCall( "teamspeak", __FUNCTION__, $params, $e->getMessage(), $e->getTraceAsString(), ); return $e->getMessage(); } } /** * Reset permissions action */ function teamspeak_perm_reset(array $params): string { try { $port = $params["customfields"]["Port"] ?? null; if (!$port) { throw new Exception("Port does not exist in custom fields"); } $tsAdmin = new TeamSpeak($params["serverip"], $params["serverport"]); if (!$tsAdmin->getElement("success", $tsAdmin->connect())) { throw new Exception("Server unavailable. Please contact support."); } if ( !$tsAdmin->getElement( "success", $tsAdmin->login( $params["serverusername"], $params["serverpassword"], ), ) ) { throw new Exception( "Unable to connect to server. Please contact support.", ); } if (!$tsAdmin->getElement("success", $tsAdmin->selectServer($port))) { throw new Exception( "Server offline or unavailable. Please contact support. (Error: Select)", ); } $response = $tsAdmin->permReset(); if (!$tsAdmin->getElement("success", $response)) { throw new Exception( "Could not restore permissions to default. Please contact support. (Error: Restore)", ); } // Update token $tokenFieldId = Capsule::table("tblcustomfields") ->where("fieldname", "Token") ->where("relid", $params["pid"]) ->value("id"); Capsule::table("tblcustomfieldsvalues") ->where("fieldid", $tokenFieldId) ->where("relid", $params["serviceid"]) ->update(["value" => $response["data"]["token"]]); return "success"; } catch (Exception $e) { logModuleCall( "teamspeak", __FUNCTION__, $params, $e->getMessage(), $e->getTraceAsString(), ); return $e->getMessage(); } } /** * Client area output */ function teamspeak_ClientArea(array $params): array { try { // Load language file $clientLang = $params["clientsdetails"]["language"] ?? "english"; $langFilePath = __DIR__ . "/lang.json"; if (!file_exists($langFilePath)) { throw new Exception("Language file not found"); } $langData = json_decode(file_get_contents($langFilePath), true); $lang = $langData[$clientLang] ?? $langData["english"]; $settings = Capsule::table("modwhmcs_teamspeak_settings") ->select("enabletsdns", "domaintsdns", "urlapi", "keyapi") ->first(); $tsAdmin = new TeamSpeak($params["serverip"], $params["serverport"]); $hostteamspeak = ["status" => false]; // Check connection if ( $tsAdmin->getElement("success", $tsAdmin->connect()) && $tsAdmin->getElement( "success", $tsAdmin->login( $params["serverusername"], $params["serverpassword"], ), ) ) { $hostteamspeak["status"] = true; } // Check virtual server status $hostteamspeak["vs"]["status"] = false; $port = $params["customfields"]["Port"] ?? null; if ( $port && $tsAdmin->getElement("success", $tsAdmin->selectServer($port)) && $tsAdmin->getElement("success", $tsAdmin->serverIdGetByPort($port)) ) { $serverinfo = $tsAdmin->serverInfo(); if ( isset($serverinfo["data"]["virtualserver_status"]) && $serverinfo["data"]["virtualserver_status"] === "online" ) { $hostteamspeak["vs"]["status"] = true; } } // Get logs $logs = []; if ($hostteamspeak["status"] && $hostteamspeak["vs"]["status"]) { $logResponse = $tsAdmin->logView(5); if (isset($logResponse["data"])) { foreach ($logResponse["data"] as $key => $log) { $logParts = explode("|", $log["l"]); if (isset($logParts[0])) { $dateParts = explode(".", $logParts[0]); $logParts[0] = $dateParts[0] ?? $logParts[0]; } unset($logParts[2], $logParts[3]); $logs[] = $logParts; } } } return [ "tabOverviewReplacementTemplate" => "templates/overview.tpl", "templateVariables" => [ "settings" => $settings ? get_object_vars($settings) : [], "customfields" => $params["customfields"], "logs" => $logs, "hostteamspeak" => $hostteamspeak, "lang" => $lang, ], ]; } catch (Exception $e) { logModuleCall( "teamspeak", __FUNCTION__, $params, $e->getMessage(), $e->getTraceAsString(), ); return [ "tabOverviewReplacementTemplate" => "templates/error.tpl", "templateVariables" => [ "usefulErrorHelper" => $e->getMessage(), ], ]; } } /** * TSDNS management */ function teamspeak_tsdns(array $params) { try { $settings = Capsule::table("modwhmcs_teamspeak_settings") ->select("enabletsdns", "domaintsdns", "urlapi", "keyapi") ->first(); $vars = [ "settings" => $settings ? get_object_vars($settings) : [], "customfields" => $params["customfields"], ]; // Handle zone edit if (isset($_GET["ma"]) && $_GET["ma"] === "editzone") { $newZone = $_GET["zone"] ?? ""; $oldZone = $_GET["oldzone"] ?? ""; if (empty($newZone)) { throw new Exception("No zone was specified"); } if ($newZone === $oldZone) { throw new Exception("The new zone is the same as the old zone"); } $tsdnsClient = new TSDNS($settings->urlapi, $settings->keyapi); // Check if new zone exists $response = $tsdnsClient->getZone( $newZone . "." . $settings->domaintsdns, ); $result = json_decode($response->body); if (isset($result->message) && count($result->message) > 0) { throw new Exception("The specified zone already exists"); } // Delete old zone and add new one $tsdnsClient->deleteZone($oldZone . "." . $settings->domaintsdns); $response = $tsdnsClient->addZone( $newZone . "." . $settings->domaintsdns, $params["serverip"] . ":" . $params["customfields"]["Port"], ); $result = json_decode($response->body); if (isset($result->message) && count($result->message) > 0) { throw new Exception("The zone could not be updated"); } // Update custom field Capsule::table("tblcustomfieldsvalues") ->where("value", $params["customfields"]["Subdomain"]) ->update(["value" => $newZone]); return "success"; } return [ "templatefile" => "templates/tsdns", "vars" => $vars, ]; } catch (Exception $e) { logModuleCall( "teamspeak", __FUNCTION__, $params, $e->getMessage(), $e->getTraceAsString(), ); return $e->getMessage(); } } // Include additional functions require_once __DIR__ . "/teamspeak_additional.php"; /** * Helper function to find available port */ function _modwhmcs_findPort(array $params, int $startPort, int $endPort): int { $tsAdmin = new TeamSpeak($params["serverip"], $params["serverport"]); if (!$tsAdmin->getElement("success", $tsAdmin->connect())) { return 0; } if ( !$tsAdmin->getElement( "success", $tsAdmin->login( $params["serverusername"], $params["serverpassword"], ), ) ) { return 0; } $currentPort = $startPort; while ($currentPort <= $endPort) { if ( !$tsAdmin->getElement( "success", $tsAdmin->serverIdGetByPort($currentPort), ) ) { return $currentPort; } $currentPort++; } return 0; }