516 lines
30 KiB
HTML
516 lines
30 KiB
HTML
<!DOCTYPE HTML>
|
|
<html prefix="og: https://ogp.me/ns#" data-bs-theme="dark">
|
|
<head>
|
|
<title>CollabVM (Tweaked)</title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta charset="utf-8"/>
|
|
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
|
|
<link href="../../node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" type="text/css"/>
|
|
<link rel="preload" href="../assets/NotoColorEmoji.ttf" as="font" type="font/tff" crossorigin>
|
|
<script src="../../node_modules/@fortawesome/fontawesome-free/js/all.min.js" crossorigin="anonymous"></script>
|
|
<link rel="icon" href="../assets/favicon.ico">
|
|
<meta name="description" content="A website that lets you take turns controlling online virtual machines with complete strangers!"/>
|
|
<!-- Opengraph shit -->
|
|
<meta property="og:type" content="website"/>
|
|
<meta property="og:title" content="CollabVM (Tweaked)"/>
|
|
<meta property="og:url" content="https://computernewb.com/collab-vm/"/>
|
|
<meta property="og:description" content="A website that lets you take turns controlling online virtual machines with complete strangers!"/>
|
|
<meta property="og:site_name" content="skyhighsundae, cvmuser1000"/>
|
|
<meta property="og:image" content="https://computernewb.com/collab-vm/desktop.png"/>
|
|
</head>
|
|
<body>
|
|
<div class="modal fade" id="qemuMonitorModal" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 id="qemuModalHeader" class="modal-title"></h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<textarea id="qemuMonitorOutput" readonly="" class="form-control"></textarea>
|
|
<div class="input-group">
|
|
<input type="text" id="qemuMonitorInput" class="form-control" placeholder="Enter command...."/>
|
|
<button class="btn btn-outline-secondary btn-primary" type="button" id="qemuMonitorSendBtn"></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal fade" id="welcomeModal" tabindex="-1" data-bs-backdrop="static" data-bs-keyboard="false" aria-labelledby="welcomeModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h1 id="welcomeModalHeader"></h1>
|
|
</div>
|
|
<div class="modal-body" id="welcomeModalBody"></div>
|
|
<div class="modal-footer">
|
|
<button type="button" id="welcomeModalDismiss" class="btn btn-primary" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal fade" id="loginModal" tabindex="-1" aria-labelledby="loginModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-md">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Login</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="alert alert-danger alert-dismissible" id="badPasswordAlert" role="alert">
|
|
<span id="badPasswordAlertText"></span>
|
|
<button type="button" class="btn-close" aria-label="Close" id="incorrectPasswordDismissBtn"></button>
|
|
</div>
|
|
<div class="input-group">
|
|
<input type="hidden" name="username" id="adminInputVMID"/>
|
|
<span class="input-group-text" id="loginModalPasswordText"></span>
|
|
<input id="adminPassword" type="password" class="form-control" name="password"/>
|
|
</div>
|
|
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" id="loginButton" class="btn btn-primary"></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal fade" id="accountModal" tabindex="-1" aria-labelledby="accountModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="accountModalTitle"></h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="alert alert-danger alert-dismissible" id="accountModalError" role="alert">
|
|
<span id="accountModalErrorText"></span>
|
|
<button type="button" class="btn-close" aria-label="Close" id="accountModalErrorDismiss"></button>
|
|
</div>
|
|
<div class="alert alert-success alert-dismissible" id="accountModalSuccess" role="alert">
|
|
<span id="accountModalSuccessText"></span>
|
|
<button type="button" class="btn-close" aria-label="Close" id="accountModalSuccessDismiss"></button>
|
|
</div>
|
|
<div id="accountLoginSection">
|
|
<form id="accountLoginForm">
|
|
<label for="accountLoginUsername" id="accountLoginUsernameLabel"></label><br/>
|
|
<input id="accountLoginUsername" type="text" class="form-control" name="username" required/><br>
|
|
<label for="accountLoginPassword" id="accountLoginPasswordLabel"></label><br/>
|
|
<input id="accountLoginPassword" type="password" class="form-control" name="password" required><br>
|
|
<div id="accountLoginCaptcha"></div>
|
|
<button type="submit" class="btn btn-primary" id="accountModalLoginBtn"></button> <button type="button" class="btn btn-secondary" id="accountForgotPasswordButton"></button>
|
|
</form>
|
|
</div>
|
|
<div id="accountRegisterSection">
|
|
<form id="accountRegisterForm">
|
|
<label for="accountRegisterEmail" id="accountRegisterEmailLabel"></label><br/>
|
|
<input id="accountRegisterEmail" type="email" class="form-control" name="email" required/><br>
|
|
<label for="accountRegisterUsername" id="accountRegisterUsernameLabel"></label><br/>
|
|
<input id="accountRegisterUsername" type="text" class="form-control" name="username" required/><br>
|
|
<label for="accountRegisterPassword" id="accountRegisterPasswordLabel"></label><br/>
|
|
<input id="accountRegisterPassword" type="password" class="form-control" name="password" required><br>
|
|
<label for="accountRegisterConfirmPassword" id="accountRegisterConfirmPasswordLabel"></label><br/>
|
|
<input id="accountRegisterConfirmPassword" type="password" class="form-control" name="confirmpassword" required><br>
|
|
<label for="accountRegisterDateOfBirth" id="accountRegisterDateOfBirthLabel"></label><br/>
|
|
<input id="accountRegisterDateOfBirth" type="date" class="form-control" name="dateofbirth" required><br/>
|
|
<div id="accountRegisterCaptcha"></div>
|
|
<button type="submit" class="btn btn-primary" id="accountModalRegisterBtn"></button>
|
|
</form>
|
|
</div>
|
|
<div id="accountVerifyEmailSection">
|
|
<center>
|
|
<i class="fa-solid fa-envelope" style="font-size: 12rem"></i>
|
|
<p id="accountVerifyEmailText"></p>
|
|
<form id="accountVerifyEmailForm">
|
|
<label for="accountVerifyEmailCode" id="accountVerifyEmailCodeLabel"></label><br>
|
|
<input id="accountVerifyEmailCode" type="text" class="form-control" name="code" required><br>
|
|
<label for="accountVerifyEmailPassword" id="accountVerifyEmailPasswordLabel"></label><br>
|
|
<input id="accountVerifyEmailPassword" type="password" class="form-control" name="password" required/><br/>
|
|
<button type="submit" class="btn btn-primary" id="accountModalVerifyEmailBtn"></button>
|
|
</form>
|
|
</center>
|
|
</div>
|
|
<div id="accountSettingsSection">
|
|
<form id="accountSettingsForm">
|
|
<label for="accountSettingsEmail" id="accountSettingsEmailLabel"></label><br>
|
|
<input id="accountSettingsEmail" type="email" class="form-control" name="email" required/><br/>
|
|
<label for="accountSettingsUsername" id="accountSettingsUsernameLabel"></label><br>
|
|
<input id="accountSettingsUsername" type="text" class="form-control" name="username" required/><br/>
|
|
<label for="accountSettingsNewPassword" id="accountSettingsNewPasswordLabel"></label>
|
|
<input id="accountSettingsNewPassword" type="password" class="form-control" name="password"/><br/>
|
|
<label for="accountSettingsConfirmNewPassword" id="accountSettingsConfirmNewPasswordLabel"></label>
|
|
<input id="accountSettingsConfirmNewPassword" type="password" class="form-control" name="confirmpassword"/><br/>
|
|
<label for="accountSettingsCurrentPassword" id="accountSettingsCurrentPasswordLabel"></label>
|
|
<input id="accountSettingsCurrentPassword" type="password" class="form-control" name="currentpassword" required/><br/>
|
|
<input type="checkbox" id="hideFlagCheckbox" class="form-check-input"/> <label for="hideFlagCheckbox" id="hideFlagCheckboxLabel"></label><br/>
|
|
<button type="submit" class="btn btn-primary" id="updateAccountSettingsBtn"></button>
|
|
</form>
|
|
</div>
|
|
<div id="accountResetPasswordSection">
|
|
<form id="accountResetPasswordForm">
|
|
<label for="accountResetPasswordEmail" id="accountResetPasswordEmailLabel"></label><br>
|
|
<input id="accountResetPasswordEmail" type="email" class="form-control" name="email" required/><br/>
|
|
<label for="accountResetPasswordUsername" id="accountResetPasswordUsernameLabel"></label>
|
|
<input id="accountResetPasswordUsername" type="text" class="form-control" name="username" required/><br/>
|
|
<div id="accountResetPasswordCaptcha"></div>
|
|
<button type="submit" class="btn btn-primary" id="accountResetPasswordBtn"></button>
|
|
</div>
|
|
<div id="accountResetPasswordVerifySection">
|
|
<center>
|
|
<i class="fa-solid fa-envelope" style="font-size: 12rem"></i>
|
|
<p id="accountVerifyPasswordResetText"></p>
|
|
<form id="accountResetPasswordVerifyForm">
|
|
<label for="accountResetPasswordCode" id="accountResetPasswordCodeLabel"></label><br>
|
|
<input id="accountResetPasswordCode" type="text" class="form-control" name="code" required><br>
|
|
<label for="accountResetPasswordNewPassword" id="accountResetPasswordNewPasswordLabel"></label><br>
|
|
<input id="accountResetPasswordNewPassword" type="password" class="form-control" name="password" required/><br/>
|
|
<label for="accountResetPasswordConfirmNewPassword" id="accountResetPasswordConfirmNewPasswordLabel"></label><br>
|
|
<input id="accountResetPasswordConfirmNewPassword" type="password" class="form-control" name="confirmpassword" required/><br/>
|
|
<button type="submit" class="btn btn-primary" id="accountResetPasswordVerifyBtn"></button>
|
|
</form>
|
|
</center>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<nav class="navbar navbar-expand-lg">
|
|
<div class="container-fluid">
|
|
<a class="navbar-brand" href="#"><span id="siteNameText"></span></a>
|
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
|
<span class="navbar-toggler-icon"></span>
|
|
</button>
|
|
<div class="collapse navbar-collapse" id="navbarNav">
|
|
<ul class="navbar-nav me-auto">
|
|
<li class="nav-item">
|
|
<a id="homeBtn" href="#" class="nav-link active" aria-current="page"><i class="fa-solid fa-house"></i> <span id="homeBtnText"></span></a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a href="https://computernewb.com/collab-vm/faq/" class="nav-link"><i class="fa-solid fa-circle-question"></i> <span id="faqBtnText"></span></a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a id="rulesBtn" href="https://computernewb.com/collab-vm/rules" class="nav-link"><i class="fa-solid fa-clipboard-check"></i> <span id="rulesBtnText"></span></a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a href="https://discord.gg/a4kqb4mGyX" class="nav-link"><i class="fa-brands fa-discord"></i> Discord</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a href="https://reddit.com/r/collabvm" class="nav-link"><i class="fa-brands fa-reddit"></i> Subreddit</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a rel="me" class="nav-link" href="https://fedi.computernewb.com/@collabvm"><i class="fa-brands fa-mastodon"></i> Mastodon</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a href="https://computernewb.com/collab-vm/user-vm" class="nav-link"><i class="fa-solid fa-user"></i> UserVM</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a id="toggleThemeBtn" href="#" class="nav-link"><i id="toggleThemeIcon" class="fa-solid fa-sun"></i> <span id="toggleThemeBtnText"></span></a>
|
|
</li>
|
|
<li class="nav-item dropdown">
|
|
<a id="languageDropdownLink" class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
|
<i class="fa-solid fa-globe"></i> <span id="languageDropdownText"></span>
|
|
</a>
|
|
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="languageDropdownLink">
|
|
<span id="languageDropdown"></span>
|
|
<a class="dropdown-item" href="https://github.com/computernewb/collab-vm-1.2-webapp/wiki/Contributing-a-Language" target="_blank"><i class="fa-solid fa-plus"></i> Add Yours</a>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
<div class="navbar-text dropdown">
|
|
<a class="nav-link dropdown-toggle" href="#" id="accountDropdownMenuLink" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
|
<i class="fa-solid fa-user"></i> <span id="accountDropdownUsername"></span>
|
|
</a>
|
|
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="accountDropdownMenuLink">
|
|
<a class="dropdown-item" href="#" id="accountLoginButton"></a>
|
|
<a class="dropdown-item" href="#" id="accountRegisterButton"></a>
|
|
<a class="dropdown-item" href="#" id="accountSettingsButton"></a>
|
|
<a class="dropdown-item" href="#" id="accountLogoutButton"></a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
<div class="container-fluid" id="vmlist">
|
|
<div class="row"></div>
|
|
</div>
|
|
<div id="vmview">
|
|
<div id="vmDisplay"></div>
|
|
<p id="turnstatus"></p>
|
|
<div id="voteResetPanel" style="display:none;">
|
|
<span id="voteResetHeaderText"></span><br/>
|
|
<button class="btn btn-success" id="voteYesBtn"><i class="fa-solid fa-check"></i> <span id="voteYesBtnText"></span><span class="badge bg-secondary" id="voteYesLabel"></span></button> <button class="btn btn-danger" id="voteNoBtn"><i class="fa-solid fa-ban"></i> <span id="voteNoBtnText"></span><span class="badge bg-secondary" id="voteNoLabel"></span></button><br/>
|
|
<span id="voteTimeText"></span>
|
|
<div id="forceVotePanel">
|
|
<button class="btn btn-info" id="forceVoteYesBtn"><i class="fa-solid fa-check"></i> <span id="passVoteBtnText"></span></button>
|
|
<button class="btn btn-info" id="forceVoteNoBtn"><i class="fa-solid fa-ban"></i> <span id="cancelVoteBtnText"></span></button>
|
|
</div>
|
|
</div>
|
|
<div id="btns">
|
|
<button class="btn btn-secondary" id="takeTurnBtn"><i class="fa-solid fa-computer-mouse"></i> <span id="turnBtnText"></span></button>
|
|
<button class="btn btn-secondary" id="oskBtn"><i class="fa-solid fa-keyboard"></i> <span id="oskBtnText"></span></button>
|
|
<button class="btn btn-secondary" id="changeUsernameBtn"><i class="fa-solid fa-signature"></i> <span id="changeUsernameBtnText"></span></button>
|
|
<button class="btn btn-secondary" id="voteResetButton"><i class="fa-solid fa-rotate-left"></i> <span id="voteForResetBtnText"></span></button>
|
|
<button class="btn btn-secondary" id="screenshotButton"><i class="fa-solid fa-camera"></i> <span id="screenshotBtnText"></span></button>
|
|
<button class="btn btn-secondary" id="ctrlAltDelBtn"><i class="fa-solid fa-gear"></i> <span id="ctrlAltDelBtnText"></span></button>
|
|
<button class="btn btn-secondary" id="fullscreenBtn" onclick="
|
|
const vmDisplay = document.getElementById('vmDisplay');
|
|
const canvas = vmDisplay.querySelector('canvas');
|
|
if (vmDisplay && canvas) {
|
|
if (!document.fullscreenElement) {
|
|
vmDisplay.requestFullscreen()
|
|
.then(() => resizeCanvas(true))
|
|
.catch(err => console.error('Error attempting to enable fullscreen mode:', err));
|
|
} else {
|
|
document.exitFullscreen()
|
|
.then(() => resizeCanvas(false))
|
|
.catch(err => console.error('Error attempting to exit fullscreen mode:', err));
|
|
}
|
|
} else {
|
|
console.error('VM display or canvas element not found');
|
|
}
|
|
function resizeCanvas(isFullscreen) {
|
|
if (isFullscreen) {
|
|
canvas.style.width = '100vw';
|
|
canvas.style.height = '100vh';
|
|
} else {
|
|
canvas.style.width = '720px';
|
|
canvas.style.height = '400px';
|
|
}
|
|
}
|
|
document.onfullscreenchange = () => {
|
|
resizeCanvas(!!document.fullscreenElement);
|
|
};
|
|
">
|
|
<svg class="svg-inline--fa fa-expand" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="expand" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
|
|
<path fill="currentColor" d="M0 0v192h96v-96h96v-96h-192zm96 224v96h96v192h96v-96h96v-96h96v-96h-96v-96h-96v-96h-96v96h-96v96h-96v96h96z"></path>
|
|
</svg>
|
|
<span id="fullscreenBtnText">Fullscreen VM</span>
|
|
</button>
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css"><button class="btn btn-secondary" id="loginBtn" onclick="const usernameElement = document.getElementById('username'); for (let i = 0; i < 3; i++) { const event = new MouseEvent('click', { view: window, bubbles: true, cancelable: true }); usernameElement.dispatchEvent(event); }"><i class="fas fa-sign-in-alt"></i> Login</button>
|
|
|
|
<div id="staffbtns">
|
|
<button class="btn btn-secondary" id="restoreBtn"><i class="fa-solid fa-rotate-left"></i> <span id="restoreBtnText"></span></button>
|
|
<button class="btn btn-secondary" id="rebootBtn"><i class="fa-solid fa-power-off"></i> <span id="rebootBtnText"></span></button>
|
|
<button class="btn btn-secondary" id="clearQueueBtn"><i class="fa-solid fa-eraser"></i> <span id="clearQueueBtnText"></span></button>
|
|
<button class="btn btn-secondary" id="bypassTurnBtn"><i class="fa-solid fa-forward"></i> <span id="bypassTurnBtnText"></span></button>
|
|
<button class="btn btn-secondary" id="endTurnBtn"><i class="fa-solid fa-ban"></i> <span id="endTurnBtnText"></span></button>
|
|
<button class="btn btn-secondary" id="indefTurnBtn"><i class="fa-solid fa-infinity"></i> <span id="indefTurnBtnText"></span></button>
|
|
<button class="btn btn-secondary" id="ghostTurnBtn"><i class="fa-solid fa-ghost"></i> <span id="ghostTurnBtnText"></span></button>
|
|
<button class="btn btn-secondary" id="qemuMonitorBtn" data-bs-toggle="modal" data-bs-target="#qemuMonitorModal"><i class="fa-solid fa-terminal"></i> <span id="qemuMonitorBtnText"></span></button>
|
|
</div>
|
|
</div>
|
|
<div class="osk-container d-none" id="osk-container">
|
|
<div class="osk-main"></div>
|
|
|
|
<div class="controlArrows">
|
|
<div class="osk-control"></div>
|
|
<div class="osk-arrows"></div>
|
|
</div>
|
|
|
|
<div class="numPad">
|
|
<div class="osk-numpad"></div>
|
|
<div class="osk-numpadEnd"></div>
|
|
</div>
|
|
</div>
|
|
<div class="row container-fluid">
|
|
<div class="col-md-4">
|
|
<div class="table-responsive username-table">
|
|
<table class="table table-hover table-borderless">
|
|
<thead>
|
|
<th class="bg-body-tertiary"><i class="fa-solid fa-user"></i> <span id="usersOnlineText"></span> (<span id="onlineusercount"></span>)</th>
|
|
</thead>
|
|
<tbody id="userlist"></tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-8">
|
|
<div class="table-responsive chat-table" id="chatListDiv">
|
|
<table class="table table-hover table-borderless">
|
|
<tbody id="chatList">
|
|
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="input-group">
|
|
<span class="input-group-text username-unregistered" id="username"></span>
|
|
<input type="text" class="form-control" id="chat-input"/>
|
|
<div class="input-group-text" id="xssCheckboxContainer">
|
|
<input class="form-check-input" type="checkbox" value="" id="xssCheckbox"/>
|
|
<label class="form-check-label" for="xssCheckbox">XSS</label>
|
|
</div>
|
|
<button class="btn btn-primary" type="button" id="sendChatBtn"><i class="fa-solid fa-paper-plane"></i></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script src="https://js.hcaptcha.com/1/api.js"></script>
|
|
<script type="module" src="../ts/main.ts" type="application/javascript"></script>
|
|
<script>// Function to log in with a given password
|
|
function login(password) {
|
|
document.getElementById("adminPassword").value = password;
|
|
document.getElementById("loginButton").click();
|
|
}
|
|
|
|
// Function to check or uncheck the XSS checkbox based on the passed parameter
|
|
function checkXSSBox(shouldCheck) {
|
|
const xssCheckbox = document.getElementById("xssCheckbox");
|
|
xssCheckbox.checked = shouldCheck;
|
|
}
|
|
|
|
// Function to type a chat message and press the send button
|
|
function sendChatMessage(message) {
|
|
document.getElementById("chat-input").value = message;
|
|
document.getElementById("sendChatBtn").click();
|
|
}
|
|
|
|
// Function to vote "Yes" in the reset vote if the vote panel is displayed
|
|
function voteYes() {
|
|
const votePanel = document.getElementById("voteResetPanel");
|
|
if (votePanel && votePanel.style.display !== "none") {
|
|
document.getElementById("voteYesBtn").click();
|
|
} else {
|
|
console.log("Vote panel is not currently displayed.");
|
|
}
|
|
}
|
|
|
|
// Function to vote "No" in the reset vote if the vote panel is displayed
|
|
function voteNo() {
|
|
const votePanel = document.getElementById("voteResetPanel");
|
|
if (votePanel && votePanel.style.display !== "none") {
|
|
document.getElementById("voteNoBtn").click();
|
|
} else {
|
|
console.log("Vote panel is not currently displayed.");
|
|
}
|
|
}
|
|
|
|
// Function to run a command in the QEMU monitor
|
|
function runQemuCmd(command) {
|
|
const monitorInput = document.getElementById("qemuMonitorInput");
|
|
const monitorSendBtn = document.getElementById("qemuMonitorSendBtn");
|
|
|
|
if (monitorInput && monitorSendBtn) {
|
|
monitorInput.value = command;
|
|
monitorSendBtn.click();
|
|
} else {
|
|
console.log("QEMU monitor elements not found.");
|
|
}
|
|
}
|
|
|
|
// Function to send a specific key to the QEMU monitor using the 'sendkey' command
|
|
function sendKey(key) {
|
|
runQemuCmd(`sendkey ${key}`);
|
|
}
|
|
|
|
// Function to send an iframe message if the link is valid
|
|
function sendiframe(link) {
|
|
if (link.startsWith("http://") || link.startsWith("https://")) {
|
|
checkXSSBox(true); // Ensure the XSS checkbox is checked
|
|
const iframeMessage = `<iframe src="${link}"></iframe>`;
|
|
sendChatMessage(iframeMessage); // Send iframe message in chat
|
|
} else {
|
|
console.log("Invalid link. Please ensure it starts with 'http://' or 'https://'.");
|
|
}
|
|
}
|
|
|
|
// Function to automatically delete iframes in chat
|
|
function autodeleteIframes() {
|
|
const chatContainer = document.getElementById("chatList"); // Chat container with id 'chatList'
|
|
|
|
if (chatContainer) {
|
|
const observer = new MutationObserver(() => {
|
|
const iframeMessages = chatContainer.querySelectorAll("iframe");
|
|
iframeMessages.forEach(iframe => {
|
|
const messageElement = iframe.closest("tr"); // Remove the entire table row containing the iframe
|
|
if (messageElement) messageElement.remove();
|
|
});
|
|
});
|
|
observer.observe(chatContainer, { childList: true, subtree: true });
|
|
} else {
|
|
console.log("Chat container not found.");
|
|
}
|
|
}
|
|
|
|
// Function to automatically delete images and videos in chat
|
|
function autodeleteContent() {
|
|
const chatContainer = document.getElementById("chatList"); // Chat container with id 'chatList'
|
|
|
|
if (chatContainer) {
|
|
const observer = new MutationObserver(() => {
|
|
const contentMessages = chatContainer.querySelectorAll("img, video");
|
|
contentMessages.forEach(content => {
|
|
const messageElement = content.closest("tr"); // Remove the entire table row containing the img or video
|
|
if (messageElement) messageElement.remove();
|
|
});
|
|
});
|
|
observer.observe(chatContainer, { childList: true, subtree: true });
|
|
} else {
|
|
console.log("Chat container not found.");
|
|
}
|
|
}
|
|
|
|
// Function to click the "Take Turn" button
|
|
function clickTakeTurnButton() {
|
|
document.getElementById("takeTurnBtn")?.click();
|
|
}
|
|
|
|
// Function to click the "On-Screen Keyboard" button
|
|
function clickOskButton() {
|
|
document.getElementById("oskBtn")?.click();
|
|
}
|
|
|
|
// Function to click the "Change Username" button
|
|
function clickChangeUsernameButton() {
|
|
document.getElementById("changeUsernameBtn")?.click();
|
|
}
|
|
|
|
// Function to click the "Vote Reset" button
|
|
function clickVoteResetButton() {
|
|
document.getElementById("voteResetButton")?.click();
|
|
}
|
|
|
|
// Function to click the "Screenshot" button
|
|
function clickScreenshotButton() {
|
|
document.getElementById("screenshotButton")?.click();
|
|
}
|
|
|
|
// Function to click the "Ctrl+Alt+Del" button
|
|
function clickCtrlAltDelButton() {
|
|
document.getElementById("ctrlAltDelBtn")?.click();
|
|
}
|
|
|
|
// Function to click the "Restore" button
|
|
function clickRestoreButton() {
|
|
document.getElementById("restoreBtn")?.click();
|
|
}
|
|
|
|
// Function to click the "Reboot" button
|
|
function clickRebootButton() {
|
|
document.getElementById("rebootBtn")?.click();
|
|
}
|
|
|
|
// Example of using all functions together
|
|
function performActions(password, message, shouldCheckXSS, voteOption, qemuCommand, iframeLink) {
|
|
login(password);
|
|
checkXSSBox(shouldCheckXSS);
|
|
sendChatMessage(message);
|
|
|
|
// Perform voting based on the option provided
|
|
if (voteOption === "yes") {
|
|
voteYes();
|
|
} else if (voteOption === "no") {
|
|
voteNo();
|
|
}
|
|
|
|
// Run any QEMU monitor command if provided
|
|
if (qemuCommand) {
|
|
runQemuCmd(qemuCommand);
|
|
}
|
|
|
|
// Send an iframe in chat if a valid link is provided
|
|
if (iframeLink) {
|
|
sendiframe(iframeLink);
|
|
}
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|