where('port', $port) ->get(); $vars = [ 'backups' => array_map(fn($backup) => get_object_vars($backup), iterator_to_array($backups)), ]; // Handle backup actions if (!empty($_GET['custom'])) { $action = $_GET['custom']; $backupId = (int)($_GET['backupid'] ?? 0); switch ($action) { case 'create': $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 is offline or does not exist'); } $getsid = $tsAdmin->serverIdGetByPort($port); $snapshot = $tsAdmin->serverSnapshotCreate(); if (!$tsAdmin->getElement('success', $snapshot)) { throw new Exception('Failed to create backup snapshot'); } $snapshotData = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", ltrim($snapshot['data'])); Capsule::table('modwhmcs_teamspeak_backups')->insert([ 'sid' => $getsid['data']['server_id'], 'port' => $port, 'data' => $snapshotData, 'date' => date("Y-m-d H:i:s"), ]); break; case 'download': if (!$backupId) { throw new Exception('Backup ID not specified'); } $data = Capsule::table('modwhmcs_teamspeak_backups') ->where('id', $backupId) ->value('data'); if (!$data) { throw new Exception('Backup not found'); } header('Content-Type: text/plain; charset=utf-8'); header('Content-Disposition: attachment; filename="backup_' . date("Y-m-d_His") . '.txt"'); echo $data; exit; case 'restore': if (!$backupId) { throw new Exception('Backup ID not specified'); } $backup = Capsule::table('modwhmcs_teamspeak_backups') ->where('id', $backupId) ->value('data'); if (!$backup) { throw new Exception('Backup 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.'); } if (!$tsAdmin->getElement('success', $tsAdmin->selectServer($port))) { throw new Exception('Server is offline or does not exist'); } if (!$tsAdmin->getElement('success', $tsAdmin->serverSnapshotDeploy($backup))) { throw new Exception('Backup could not be restored'); } break; case 'delete': if (!$backupId) { throw new Exception('Backup ID not specified'); } Capsule::table('modwhmcs_teamspeak_backups') ->where('id', $backupId) ->delete(); break; default: throw new Exception('Invalid action'); } return 'success'; } return [ 'templatefile' => 'templates/backups', 'vars' => $vars, ]; } catch (Exception $e) { logModuleCall( 'teamspeak', __FUNCTION__, $params, $e->getMessage(), $e->getTraceAsString() ); return $e->getMessage(); } } /** * Token/Privileges management */ function teamspeak_tokens(array $params) { 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 is offline or does not exist'); } // Get token list $response = $tsAdmin->tokenList(); $tokens = $response['data'] ?? []; // Get server group list $serverglist = $tsAdmin->serverGroupList(); $sglist = []; if (isset($serverglist['data'])) { foreach ($serverglist['data'] as $sg) { if (($sg['type'] ?? 0) == 1) { $sglist[] = $sg; } } } $vars = [ 'tokens' => $tokens, 'sglist' => $sglist, ]; // Handle token actions if (!empty($_GET['custom'])) { $action = $_GET['custom']; switch ($action) { case 'create': $groupId = (int)($_GET['groupid'] ?? 0); $description = $_GET['desc'] ?? ''; if (!$groupId) { throw new Exception('Group ID not specified'); } if (!$tsAdmin->getElement('success', $tsAdmin->tokenAdd(0, $groupId, 0, $description))) { throw new Exception('Unable to create token. Please contact support.'); } break; case 'delete': $token = $_GET['token'] ?? ''; if (!$token) { throw new Exception('Token not specified'); } if (!$tsAdmin->getElement('success', $tsAdmin->tokenDelete($token))) { throw new Exception('Unable to delete token. Please contact support.'); } break; default: throw new Exception('Invalid action'); } return 'success'; } return [ 'templatefile' => 'templates/tokens', 'vars' => $vars, ]; } catch (Exception $e) { logModuleCall( 'teamspeak', __FUNCTION__, $params, $e->getMessage(), $e->getTraceAsString() ); return $e->getMessage(); } } /** * Ban management */ function teamspeak_bans(array $params) { 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 is offline or does not exist'); } // Get ban list $response = $tsAdmin->banList(); $bans = $response['data'] ?? []; $vars = [ 'bans' => $bans, ]; // Handle ban actions if (!empty($_GET['custom'])) { $action = $_GET['custom']; switch ($action) { case 'create': $banType = $_GET['bantype'] ?? ''; $input = $_GET['inu'] ?? ''; $reason = $_GET['reason'] ?? ''; if (!$banType || !$input) { throw new Exception('Ban type and input are required'); } switch ($banType) { case 'ip': if (filter_var($input, FILTER_VALIDATE_IP) === false) { throw new Exception('Invalid IP address'); } if (!$tsAdmin->getElement('success', $tsAdmin->banAddByIp($input, 0, $reason))) { throw new Exception('Unable to create IP ban. Please contact support.'); } break; case 'name': if (!$tsAdmin->getElement('success', $tsAdmin->banAddByName($input, 0, $reason))) { throw new Exception('Unable to create name ban. Please contact support.'); } break; case 'uid': if (!$tsAdmin->getElement('success', $tsAdmin->banAddByUid($input, 0, $reason))) { throw new Exception('Unable to create UID ban. Please contact support.'); } break; default: throw new Exception('Invalid ban type'); } break; case 'delete': $banId = (int)($_GET['banid'] ?? 0); if (!$banId) { throw new Exception('Ban ID not specified'); } if (!$tsAdmin->getElement('success', $tsAdmin->banDelete($banId))) { throw new Exception('Unable to delete ban. Please contact support.'); } break; default: throw new Exception('Invalid action'); } return 'success'; } return [ 'templatefile' => 'templates/bans', 'vars' => $vars, ]; } catch (Exception $e) { logModuleCall( 'teamspeak', __FUNCTION__, $params, $e->getMessage(), $e->getTraceAsString() ); return $e->getMessage(); } } /** * Server settings management */ function teamspeak_settings(array $params) { 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); } $serverinfo = $tsAdmin->serverInfo(); if (!$tsAdmin->getElement('success', $serverinfo)) { throw new Exception('Could not retrieve server information'); } $vars = [ 'serverinfo' => $serverinfo['data'] ?? [], ]; // Handle settings save if (isset($_GET['custom']) && $_GET['custom'] === 'save') { $password = $_GET['pw'] ?? ''; $confirmPassword = $_GET['confirmpw'] ?? ''; $hostname = $_GET['hostname'] ?? ''; $welcomeMessage = $_GET['welcomemessage'] ?? ''; if ($password !== $confirmPassword) { throw new Exception('The passwords entered do not match'); } $data = [ 'virtualserver_name' => $hostname, 'virtualserver_welcomemessage' => $welcomeMessage, ]; // Only update password if provided if (!empty($password)) { $data['virtualserver_password'] = $password; } if (!$tsAdmin->getElement('success', $tsAdmin->serverEdit($data))) { throw new Exception('Failed to update server settings. Please contact support.'); } return 'success'; } return [ 'templatefile' => 'templates/settings', 'vars' => $vars, ]; } catch (Exception $e) { logModuleCall( 'teamspeak', __FUNCTION__, $params, $e->getMessage(), $e->getTraceAsString() ); return $e->getMessage(); } } /** * TSDNS zone management continuation */ 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'); } if (!$settings) { throw new Exception('TSDNS settings not found'); } $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(); } } /** * 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; }