Add toggle for ghost turning

This commit is contained in:
Elijah R 2024-06-16 13:50:44 -04:00
parent 00da6db08d
commit f0c09b2e1b
6 changed files with 38 additions and 7 deletions

View File

@ -257,6 +257,7 @@
<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>

View File

@ -61,6 +61,8 @@ const fallbackLanguage : Language = {
"kAdminVMButtons_ClearTurnQueue": "Clear Turn Queue",
"kAdminVMButtons_BypassTurn": "Bypass Turn",
"kAdminVMButtons_IndefiniteTurn": "Indefinite Turn",
"kAdminVMButtons_GhostTurnOn": "Ghost Turn (On)",
"kAdminVMButtons_GhostTurnOff": "Ghost Turn (Off)",
"kAdminVMButtons_Ban": "Ban",
"kAdminVMButtons_Kick": "Kick",

View File

@ -62,6 +62,8 @@ export enum I18nStringKey {
kAdminVMButtons_ClearTurnQueue = 'kAdminVMButtons_ClearTurnQueue',
kAdminVMButtons_BypassTurn = 'kAdminVMButtons_BypassTurn',
kAdminVMButtons_IndefiniteTurn = 'kAdminVMButtons_IndefiniteTurn',
kAdminVMButtons_GhostTurnOn = 'kAdminVMButtons_GhostTurnOn',
kAdminVMButtons_GhostTurnOff = 'kAdminVMButtons_GhostTurnOff',
kAdminVMButtons_Ban = 'kAdminVMButtons_Ban',
kAdminVMButtons_Kick = 'kAdminVMButtons_Kick',
@ -272,6 +274,7 @@ export class I18n {
clearQueueBtnText: I18nStringKey.kAdminVMButtons_ClearTurnQueue,
bypassTurnBtnText: I18nStringKey.kAdminVMButtons_BypassTurn,
indefTurnBtnText: I18nStringKey.kAdminVMButtons_IndefiniteTurn,
ghostTurnBtnText: I18nStringKey.kAdminVMButtons_GhostTurnOff,
// Account modal
accountLoginUsernameLabel: I18nStringKey.kGeneric_Username,

View File

@ -70,6 +70,8 @@ const elements = {
forceVoteYesBtn: document.getElementById('forceVoteYesBtn') as HTMLButtonElement,
forceVoteNoBtn: document.getElementById('forceVoteNoBtn') as HTMLButtonElement,
indefTurnBtn: document.getElementById('indefTurnBtn') as HTMLButtonElement,
ghostTurnBtn: document.getElementById('ghostTurnBtn') as HTMLButtonElement,
ghostTurnBtnText: document.getElementById('ghostTurnBtnText') as HTMLSpanElement,
qemuMonitorInput: document.getElementById('qemuMonitorInput') as HTMLInputElement,
qemuMonitorSendBtn: document.getElementById('qemuMonitorSendBtn') as HTMLButtonElement,
qemuMonitorOutput: document.getElementById('qemuMonitorOutput') as HTMLTextAreaElement,
@ -482,6 +484,7 @@ function closeVM() {
elements.clearQueueBtn.style.display = 'none';
elements.qemuMonitorBtn.style.display = 'none';
elements.indefTurnBtn.style.display = 'none';
elements.ghostTurnBtn.style.display = 'none';
elements.xssCheckboxContainer.style.display = 'none';
elements.forceVotePanel.style.display = 'none';
elements.voteResetPanel.style.display = 'none';
@ -813,6 +816,7 @@ function onLogin(_rank: Rank, _perms: Permissions) {
if (_rank === Rank.Admin) {
elements.qemuMonitorBtn.style.display = 'inline-block';
elements.indefTurnBtn.style.display = 'inline-block';
elements.ghostTurnBtn.style.display = 'inline-block';
}
if (_perms.xss) elements.xssCheckboxContainer.style.display = 'inline-block';
if (_perms.forcevote) elements.forceVotePanel.style.display = 'block';
@ -876,6 +880,15 @@ elements.forceVoteNoBtn.addEventListener('click', () => VM?.forceVote(false));
elements.forceVoteYesBtn.addEventListener('click', () => VM?.forceVote(true));
elements.indefTurnBtn.addEventListener('click', () => VM?.indefiniteTurn());
elements.ghostTurnBtn.addEventListener('click', () => {
w.collabvm.ghostTurn = !w.collabvm.ghostTurn;
if (w.collabvm.ghostTurn)
elements.ghostTurnBtnText.innerText = TheI18n.GetString(I18nStringKey.kAdminVMButtons_GhostTurnOn);
else
elements.ghostTurnBtnText.innerText = TheI18n.GetString(I18nStringKey.kAdminVMButtons_GhostTurnOff);
});
async function sendQEMUCommand() {
if (!elements.qemuMonitorInput.value) return;
let cmd = elements.qemuMonitorInput.value;
@ -1212,7 +1225,8 @@ w.collabvm = {
closeVM: closeVM,
loadList: loadList,
multicollab: multicollab,
getVM: () => VM
getVM: () => VM,
ghostTurn: false,
};
// Multicollab will stay in the global scope for backwards compatibility
w.multicollab = multicollab;
@ -1276,6 +1290,10 @@ document.addEventListener('DOMContentLoaded', async () => {
if (darkTheme) elements.toggleThemeBtnText.innerHTML = TheI18n.GetString(I18nStringKey.kSiteButtons_LightMode);
else elements.toggleThemeBtnText.innerHTML = TheI18n.GetString(I18nStringKey.kSiteButtons_DarkMode);
if (w.collabvm.ghostTurn)
elements.ghostTurnBtnText.innerText = TheI18n.GetString(I18nStringKey.kAdminVMButtons_GhostTurnOn);
else
elements.ghostTurnBtnText.innerText = TheI18n.GetString(I18nStringKey.kAdminVMButtons_GhostTurnOff);
});
// Load theme
var _darktheme : boolean;

View File

@ -9,6 +9,7 @@ import GetKeysym from '../keyboard.js';
import VoteStatus from './VoteStatus.js';
import MuteState from './MuteState.js';
import { StringLike } from '../StringLike.js';
const w = window as any;
export interface CollabVMClientEvents {
//open: () => void;
@ -98,7 +99,7 @@ export default class CollabVMClient {
this.canvas.addEventListener(
'mousedown',
(e: MouseEvent) => {
if (this.users.find((u) => u.username === this.username)?.turn === -1 && this.rank !== Rank.Admin) return;
if (!this.shouldSendInput()) return;
this.mouse.initFromMouseEvent(e);
this.sendmouse(this.mouse.x, this.mouse.y, this.mouse.makeMask());
},
@ -110,7 +111,7 @@ export default class CollabVMClient {
this.canvas.addEventListener(
'mouseup',
(e: MouseEvent) => {
if (this.users.find((u) => u.username === this.username)?.turn === -1 && this.rank !== Rank.Admin) return;
if (!this.shouldSendInput()) return;
this.mouse.initFromMouseEvent(e);
this.sendmouse(this.mouse.x, this.mouse.y, this.mouse.makeMask());
},
@ -122,7 +123,7 @@ export default class CollabVMClient {
this.canvas.addEventListener(
'mousemove',
(e: MouseEvent) => {
if (this.users.find((u) => u.username === this.username)?.turn === -1 && this.rank !== Rank.Admin) return;
if (!this.shouldSendInput()) return;
this.mouse.initFromMouseEvent(e);
this.sendmouse(this.mouse.x, this.mouse.y, this.mouse.makeMask());
},
@ -135,7 +136,7 @@ export default class CollabVMClient {
'keydown',
(e: KeyboardEvent) => {
e.preventDefault();
if (this.users.find((u) => u.username === this.username)?.turn === -1 && this.rank !== Rank.Admin) return;
if (!this.shouldSendInput()) return;
let keysym = GetKeysym(e.keyCode, e.key, e.location);
if (keysym === null) return;
this.key(keysym, true);
@ -149,7 +150,7 @@ export default class CollabVMClient {
'keyup',
(e: KeyboardEvent) => {
e.preventDefault();
if (this.users.find((u) => u.username === this.username)?.turn === -1 && this.rank !== Rank.Admin) return;
if (!this.shouldSendInput()) return;
let keysym = GetKeysym(e.keyCode, e.key, e.location);
if (keysym === null) return;
this.key(keysym, false);
@ -163,7 +164,7 @@ export default class CollabVMClient {
'wheel',
(ev: WheelEvent) => {
ev.preventDefault();
if (this.users.find((u) => u.username === this.username)?.turn === -1 && this.rank !== Rank.Admin) return;
if (!this.shouldSendInput()) return;
this.mouse.initFromWheelEvent(ev);
this.sendmouse(this.mouse.x, this.mouse.y, this.mouse.makeMask());
@ -677,6 +678,10 @@ export default class CollabVMClient {
return this.internalEmitter.on(event, callback);
}
private shouldSendInput() {
return this.users.find(u => u.username === this.username)?.turn === 0 || (w.collabvm.ghostTurn && this.rank === Rank.Admin);
}
on<E extends keyof CollabVMClientEvents>(event: E, callback: CollabVMClientEvents[E]): Unsubscribe {
let unsub = this.publicEmitter.on(event, callback);
this.unsubscribeCallbacks.push(unsub);

View File

@ -60,6 +60,8 @@
"kAdminVMButtons_ClearTurnQueue": "Clear Turn Queue",
"kAdminVMButtons_BypassTurn": "Bypass Turn",
"kAdminVMButtons_IndefiniteTurn": "Indefinite Turn",
"kAdminVMButtons_GhostTurnOn": "Ghost Turn (On)",
"kAdminVMButtons_GhostTurnOff": "Ghost Turn (Off)",
"kAdminVMButtons_Ban": "Ban",
"kAdminVMButtons_Kick": "Kick",