From 9d60b440738757f41b16af22303ef405336c9ab5 Mon Sep 17 00:00:00 2001 From: Elijah R Date: Tue, 9 Apr 2024 15:06:10 -0400 Subject: [PATCH] Fully implement i18n --- src/html/index.html | 158 +++++++++++--------------- src/ts/fallbackLanguage.ts | 101 +++++++++++++++++ src/ts/i18n.ts | 221 ++++++++++++++++++++++++++++--------- src/ts/main.ts | 22 ++-- static/lang/en-us.json | 41 ++++++- 5 files changed, 388 insertions(+), 155 deletions(-) create mode 100644 src/ts/fallbackLanguage.ts diff --git a/src/html/index.html b/src/html/index.html index 44ca50d..1b273ba 100644 --- a/src/html/index.html +++ b/src/html/index.html @@ -22,14 +22,14 @@ @@ -101,7 +77,7 @@
- + - +
- - - - + + + + - - + +
@@ -307,7 +283,7 @@
- Username +
diff --git a/src/ts/fallbackLanguage.ts b/src/ts/fallbackLanguage.ts new file mode 100644 index 0000000..01dcff3 --- /dev/null +++ b/src/ts/fallbackLanguage.ts @@ -0,0 +1,101 @@ +import { Language } from "./i18n.js"; + +const fallbackLanguage : Language = { + "languageName": "English (US)", + "translatedLanguageName": "English (US)", + "flag": "🇺🇸", + "author": "Computernewb", + + "stringKeys": { + "kGeneric_CollabVM": "CollabVM", + "kGeneric_Yes": "Yes", + "kGeneric_No": "No", + "kGeneric_Ok": "OK", + "kGeneric_Cancel": "Cancel", + "kGeneric_Send": "Send", + "kGeneric_Understood": "Understood", + "kGeneric_Username": "Username", + "kGeneric_Password": "Password", + "kGeneric_Login": "Log in", + "kGeneric_Register": "Register", + "kGeneric_EMail": "E-Mail", + "kGeneric_DateOfBirth": "Date of Birth", + "kGeneric_VerificationCode": "Verification Code", + "kGeneric_Verify": "Verify", + "kGeneric_Update": "Update", + "kGeneric_Logout": "Log out", + + "kWelcomeModal_Header": "Welcome to CollabVM", + "kWelcomeModal_Body": "

Before continuing, please familiarize yourself with our rules:

R1. Don't break the law.

Do not use CollabVM or CollabVM's network to violate United States federal law, New York state law, or international law. If CollabVM becomes aware a crime has been committed through its service, you will be immediately banned, and your activities may be reported to the authorities if necessary.

CollabVM is required by law to notify law enforcement agencies if it becomes aware of the presence of child pornography on, or being transmitted through its network.

COPPA is also enforced, please do not use CollabVM if you are under the age of 13 years old.

R2. No running DoS/DDoS tools.

Do not use CollabVM to DoS/DDoS an indivdiual, business, company, or anyone else.

R3. No spam distribution.

Do not spam any emails using this service or push spam in general.

R4. Do not abuse any exploits.

Do not abuse any exploits, additionally if you see someone abusing exploits or you need to report one, please contact me at: computernewbab@gmail.com

R5. Don't impersonate other users.

Do not impersonate other members of CollabVM. If caught, you'll be temporarily disconnected, and banned if necessary.

R6. One vote per person.

Do not use any methods or tools to bypass the vote restriction. Only one vote per person is allowed, no matter what. Anybody who is caught doing this will be banned.

R7. No Remote Administration Tools.

Do not use any remote administration tools (ex: DarkComet, NanoCore, Anydesk, TeamViewer, Orcus, etc.)

R8. No bypassing CollabNet.

Do not attempt to bypass the blocking provided by CollabNet, especially if it is being used to break Rule 1, Rule 2, or Rule 7 (or run stupid over-used things).

R9. No performing destructive actions constantly.

Any user may not destroy the VM (rendering it unusable constantly), install/reinstall the operating system (except on VM7 or VM8), or run bots that do such. This includes bots that spam massive amounts of keyboard/mouse input (\"kitting\").

R10. No Cryptomining

Attempting to mine cryptocurrency on the VMs will result in a kick, and then a permanent ban if you keep attempting. Besides, it's not like you're gonna make any money off it.

NSFW Warning

Please note that NSFW content is allowed on our anarchy VM (VM0b0t), and is viewed regularly. In addition, while we give a good effort to keep NSFW off the main VMs, people will occasionally slip it through.", + + "kSiteButtons_Home": "Home", + "kSiteButtons_FAQ": "FAQ", + "kSiteButtons_Rules": "Rules", + "kSiteButtons_DarkMode": "Dark Mode", + "kSiteButtons_LightMode": "Light Mode", + + "kVM_UsersOnlineText": "Users Online:", + + "kVM_TurnTimeTimer": "Turn expires in {0} seconds.", + "kVM_WaitingTurnTimer": "Waiting for turn in {0} seconds.", + "kVM_VoteCooldownTimer": "Please wait {0} seconds before starting another vote.", + + "kVM_VoteForResetTitle": "Do you want to reset the VM?", + "kVM_VoteForResetTimer": "Vote ends in {0} seconds", + + "kVMButtons_TakeTurn": "Take Turn", + "kVMButtons_EndTurn": "End Turn", + "kVMButtons_ChangeUsername": "Change Username", + "kVMButtons_Keyboard": "Keyboard", + "KVMButtons_CtrlAltDel": "Ctrl+Alt+Del", + + "kVMButtons_VoteForReset": "Vote For Reset", + "kVMButtons_Screenshot": "Screenshot", + + "kQEMUMonitor": "QEMU Monitor", + "kAdminVMButtons_PassVote": "Pass Vote", + "kAdminVMButtons_CancelVote": "Cancel Vote", + + "kAdminVMButtons_Restore": "Restore", + "kAdminVMButtons_Reboot": "Reboot", + "kAdminVMButtons_ClearTurnQueue": "Clear Turn Queue", + "kAdminVMButtons_BypassTurn": "Bypass Turn", + "kAdminVMButtons_IndefiniteTurn": "Indefinite Turn", + + "kAdminVMButtons_Ban": "Ban", + "kAdminVMButtons_Kick": "Kick", + "kAdminVMButtons_TempMute": "Temporary Mute", + "kAdminVMButtons_IndefMute": "Indefinite Mute", + "kAdminVMButtons_Unmute": "Unmute", + "kAdminVMButtons_GetIP": "Get IP", + + "kVMPrompts_AdminChangeUsernamePrompt": "Enter new username for {0}:", + "kVMPrompts_AdminRestoreVMPrompt": "Are you sure you want to restore the VM?", + "kVMPrompts_EnterNewUsernamePrompt": "Enter a new username, or leave the field blank to be assigned a guest username", + + "kError_UnexpectedDisconnection": "You have been disconnected from the server.", + "kError_UsernameTaken": "That username is already taken", + "kError_UsernameInvalid": "Usernames can contain only numbers, letters, spaces, dashes, underscores, and dots, and it must be between 3 and 20 characters.", + "kError_UsernameBlacklisted": "That username has been blacklisted.", + "kError_IncorrectPassword": "Incorrect password.", + + "kAccountModal_Verify": "Verify E-Mail", + "kAccountModal_AccountSettings": "Account Settings", + "kAccountModal_ResetPassword": "Reset Password", + + "kAccountModal_NewPassword": "New Password", + "kAccountModal_ConfirmNewPassword": "Confirm New Password", + "kAccountModal_CurrentPassword": "Current Password", + "kAccountModal_ConfirmPassword": "Confirm Password", + + "kMissingCaptcha": "Please fill out the captcha.", + "kPasswordsMustMatch": "Passwords must match.", + "kAccountModal_VerifyText": "We sent an E-Mail to {0}. To verify your account, please enter the 8-digit code from the E-Mail below.", + "kAccountModal_VerifyPasswordResetText": "We sent an E-Mail to {0}. To reset your password, please enter the 8-digit code from the E-Mail below.", + "kAccountModal_PasswordResetSuccess": "Your password has been changed successfully. You can now log in with your new password.", + + "kNotLoggedIn": "Not Logged in" + } +} + +export default fallbackLanguage; \ No newline at end of file diff --git a/src/ts/i18n.ts b/src/ts/i18n.ts index 20bcba6..55d1ce2 100644 --- a/src/ts/i18n.ts +++ b/src/ts/i18n.ts @@ -9,6 +9,21 @@ export enum I18nStringKey { kGeneric_No = 'kGeneric_No', kGeneric_Ok = 'kGeneric_Ok', kGeneric_Cancel = 'kGeneric_Cancel', + kGeneric_Send = 'kGeneric_Send', + kGeneric_Understood = 'kGeneric_Understood', + kGeneric_Username = 'kGeneric_Username', + kGeneric_Password = 'kGeneric_Password', + kGeneric_Login = 'kGeneric_Login', + kGeneric_Register = 'kGeneric_Register', + kGeneric_EMail = 'kGeneric_EMail', + kGeneric_DateOfBirth = 'kGeneric_DateOfBirth', + kGeneric_VerificationCode = 'kGeneric_VerificationCode', + kGeneric_Verify = 'kGeneric_Verify', + kGeneric_Update = 'kGeneric_Update', + kGeneric_Logout = 'kGeneric_Logout', + + kWelcomeModal_Header = 'kWelcomeModal_Header', + kWelcomeModal_Body = 'kWelcomeModal_Body', kSiteButtons_Home = 'kSiteButtons_Home', kSiteButtons_FAQ = 'kSiteButtons_FAQ', @@ -28,15 +43,33 @@ export enum I18nStringKey { kVMButtons_TakeTurn = 'kVMButtons_TakeTurn', kVMButtons_EndTurn = 'kVMButtons_EndTurn', kVMButtons_ChangeUsername = 'kVMButtons_ChangeUsername', + kVMButtons_Keyboard = 'kVMButtons_Keyboard', + KVMButtons_CtrlAltDel = 'KVMButtons_CtrlAltDel', kVMButtons_VoteForReset = 'kVMButtons_VoteForReset', kVMButtons_Screenshot = 'kVMButtons_Screenshot', // Admin VM buttons + kQEMUMonitor = 'kQEMUMonitor', kAdminVMButtons_PassVote = 'kAdminVMButtons_PassVote', kAdminVMButtons_CancelVote = 'kAdminVMButtons_CancelVote', + kAdminVMButtons_Restore = 'kAdminVMButtons_Restore', + kAdminVMButtons_Reboot = 'kAdminVMButtons_Reboot', + kAdminVMButtons_ClearTurnQueue = 'kAdminVMButtons_ClearTurnQueue', + kAdminVMButtons_BypassTurn = 'kAdminVMButtons_BypassTurn', + kAdminVMButtons_IndefiniteTurn = 'kAdminVMButtons_IndefiniteTurn', + + kAdminVMButtons_Ban = 'kAdminVMButtons_Ban', + kAdminVMButtons_Kick = 'kAdminVMButtons_Kick', + kAdminVMButtons_TempMute = 'kAdminVMButtons_TempMute', + kAdminVMButtons_IndefMute = 'kAdminVMButtons_IndefMute', + kAdminVMButtons_Unmute = 'kAdminVMButtons_Unmute', + kAdminVMButtons_GetIP = 'kAdminVMButtons_GetIP', + // prompts + kVMPrompts_AdminChangeUsernamePrompt = 'kVMPrompts_AdminChangeUsernamePrompt', + kVMPrompts_AdminRestoreVMPrompt = 'kVMPrompts_AdminRestoreVMPrompt', kVMPrompts_EnterNewUsernamePrompt = 'kVMPrompts_EnterNewUsernamePrompt', // error messages @@ -45,14 +78,18 @@ export enum I18nStringKey { kError_UsernameTaken = 'kError_UsernameTaken', kError_UsernameInvalid = 'kError_UsernameInvalid', kError_UsernameBlacklisted = 'kError_UsernameBlacklisted', + kError_IncorrectPassword = 'kError_IncorrectPassword', // Auth - kAccountModal_Login = 'kAccountModal_Login', - kAccountModal_Register = 'kAccountModal_Register', kAccountModal_Verify = 'kAccountModal_Verify', kAccountModal_AccountSettings = 'kAccountModal_AccountSettings', kAccountModal_ResetPassword = 'kAccountModal_ResetPassword', + kAccountModal_NewPassword = 'kAccountModal_NewPassword', + kAccountModal_ConfirmNewPassword = 'kAccountModal_ConfirmNewPassword', + kAccountModal_CurrentPassword = 'kAccountModal_CurrentPassword', + kAccountModal_ConfirmPassword = 'kAccountModal_ConfirmPassword', + kAccountModal_VerifyText = 'kAccountModal_VerifyText', kAccountModal_VerifyPasswordResetText = 'kAccountModal_VerifyPasswordResetText', kAccountModal_PasswordResetSuccess = 'kAccountModal_PasswordResetSuccess', @@ -63,7 +100,7 @@ export enum I18nStringKey { } // This models the JSON structure. -type Language = { +export type Language = { languageName: string; translatedLanguageName: string; flag: string; // country flag, can be blank if not applicable. will be displayed in language dropdown @@ -91,50 +128,7 @@ type LanguagesJson = { const fallbackId = '!!fallback'; // This language is provided in the webapp itself just in case language stuff fails -const fallbackLanguage: Language = { - languageName: 'Fallback', - translatedLanguageName: 'Fallback', - flag: 'no', - author: 'Computernewb', - - stringKeys: { - kGeneric_CollabVM: 'CollabVM', - kGeneric_Yes: 'Yes', - kGeneric_No: 'No', - kGeneric_Ok: 'OK', - kGeneric_Cancel: 'Cancel', - - kSiteButtons_Home: 'Home', - kSiteButtons_FAQ: 'FAQ', - kSiteButtons_Rules: 'Rules', - - kVM_UsersOnlineText: 'Users Online:', - - kVM_TurnTimeTimer: 'Turn expires in {0} seconds.', - kVM_WaitingTurnTimer: 'Waiting for turn in {0} seconds.', - kVM_VoteCooldownTimer: 'Please wait {0} seconds before starting another vote.', - - kVM_VoteForResetTitle: 'Do you want to reset the VM?', - kVM_VoteForResetTimer: 'Vote ends in {0} seconds', - - kVMButtons_TakeTurn: 'Take Turn', - kVMButtons_EndTurn: 'End Turn', - kVMButtons_ChangeUsername: 'Change Username', - - kVMButtons_VoteForReset: 'Vote For Reset', - kVMButtons_Screenshot: 'Screenshot', - - kAdminVMButtons_PassVoteButton: 'Pass Vote', - kAdminVMButtons_CancelVoteButton: 'Cancel Vote', - - kVMPrompts_EnterNewUsernamePrompt: 'Enter a new username, or leave the field blank to be assigned a guest username', - - kError_UnexpectedDisconnection: 'You have been disconnected from the server.', - kError_UsernameTaken: 'That username is already taken', - kError_UsernameInvalid: 'Usernames can contain only numbers, letters, spaces, dashes, underscores, and dots, and it must be between 3 and 20 characters.', - kError_UsernameBlacklisted: 'That username has been blacklisted.' - } -}; +import fallbackLanguage from './fallbackLanguage.js'; interface StringKeyMap { [k: string]: I18nStringKey; @@ -216,7 +210,15 @@ export class I18n { homeBtnText: I18nStringKey.kSiteButtons_Home, faqBtnText: I18nStringKey.kSiteButtons_FAQ, rulesBtnText: I18nStringKey.kSiteButtons_Rules, + accountDropdownUsername: I18nStringKey.kNotLoggedIn, + accountLoginButton: I18nStringKey.kGeneric_Login, + accountRegisterButton: I18nStringKey.kGeneric_Register, + accountSettingsButton: I18nStringKey.kAccountModal_AccountSettings, + accountLogoutButton: I18nStringKey.kGeneric_Logout, + welcomeModalHeader: I18nStringKey.kWelcomeModal_Header, + welcomeModalBody: I18nStringKey.kWelcomeModal_Body, + welcomeModalDismiss: I18nStringKey.kGeneric_Understood, usersOnlineText: I18nStringKey.kVM_UsersOnlineText, @@ -225,19 +227,121 @@ export class I18n { voteNoBtnText: I18nStringKey.kGeneric_No, changeUsernameBtnText: I18nStringKey.kVMButtons_ChangeUsername, + oskBtnText: I18nStringKey.kVMButtons_Keyboard, + ctrlAltDelBtnText: I18nStringKey.KVMButtons_CtrlAltDel, voteForResetBtnText: I18nStringKey.kVMButtons_VoteForReset, screenshotBtnText: I18nStringKey.kVMButtons_Screenshot, // admin stuff + badPasswordAlertText: I18nStringKey.kError_IncorrectPassword, + loginModalPasswordText: I18nStringKey.kGeneric_Password, + loginButton: I18nStringKey.kGeneric_Login, passVoteBtnText: I18nStringKey.kAdminVMButtons_PassVote, cancelVoteBtnText: I18nStringKey.kAdminVMButtons_CancelVote, - endTurnBtnText: I18nStringKey.kVMButtons_EndTurn + endTurnBtnText: I18nStringKey.kVMButtons_EndTurn, + qemuMonitorBtnText: I18nStringKey.kQEMUMonitor, + qemuModalHeader: I18nStringKey.kQEMUMonitor, + qemuMonitorSendBtn: I18nStringKey.kGeneric_Send, + + restoreBtnText: I18nStringKey.kAdminVMButtons_Restore, + rebootBtnText: I18nStringKey.kAdminVMButtons_Reboot, + clearQueueBtnText: I18nStringKey.kAdminVMButtons_ClearTurnQueue, + bypassTurnBtnText: I18nStringKey.kAdminVMButtons_BypassTurn, + indefTurnBtnText: I18nStringKey.kAdminVMButtons_IndefiniteTurn, + + // Account modal + accountLoginUsernameLabel: I18nStringKey.kGeneric_Username, + accountLoginPasswordLabel: I18nStringKey.kGeneric_Password, + accountModalLoginBtn: I18nStringKey.kGeneric_Login, + accountForgotPasswordButton: I18nStringKey.kAccountModal_ResetPassword, + accountRegisterEmailLabel: I18nStringKey.kGeneric_EMail, + accountRegisterUsernameLabel: I18nStringKey.kGeneric_Username, + accountRegisterPasswordLabel: I18nStringKey.kGeneric_Password, + accountRegisterConfirmPasswordLabel: I18nStringKey.kAccountModal_ConfirmPassword, + accountRegisterDateOfBirthLabel: I18nStringKey.kGeneric_DateOfBirth, + accountModalRegisterBtn: I18nStringKey.kGeneric_Register, + accountVerifyEmailCodeLabel: I18nStringKey.kGeneric_VerificationCode, + accountVerifyEmailPasswordLabel: I18nStringKey.kGeneric_Password, + accountModalVerifyEmailBtn: I18nStringKey.kGeneric_Verify, + accountSettingsEmailLabel: I18nStringKey.kGeneric_EMail, + accountSettingsUsernameLabel: I18nStringKey.kGeneric_Username, + accountSettingsNewPasswordLabel: I18nStringKey.kAccountModal_NewPassword, + accountSettingsConfirmNewPasswordLabel: I18nStringKey.kAccountModal_ConfirmNewPassword, + accountSettingsCurrentPasswordLabel: I18nStringKey.kAccountModal_CurrentPassword, + updateAccountSettingsBtn: I18nStringKey.kGeneric_Update, + accountResetPasswordEmailLabel: I18nStringKey.kGeneric_EMail, + accountResetPasswordUsernameLabel: I18nStringKey.kGeneric_Username, + accountResetPasswordBtn: I18nStringKey.kAccountModal_ResetPassword, + accountResetPasswordCodeLabel: I18nStringKey.kGeneric_VerificationCode, + accountResetPasswordNewPasswordLabel: I18nStringKey.kAccountModal_NewPassword, + accountResetPasswordConfirmNewPasswordLabel: I18nStringKey.kAccountModal_ConfirmNewPassword, + accountResetPasswordVerifyBtn: I18nStringKey.kAccountModal_ResetPassword, + }; + + const kDomAttributeToStringMap = { + adminPassword: { + placeholder: I18nStringKey.kGeneric_Password, + }, + accountLoginUsername: { + placeholder: I18nStringKey.kGeneric_Username, + }, + accountLoginPassword: { + placeholder: I18nStringKey.kGeneric_Password, + }, + accountRegisterEmail: { + placeholder: I18nStringKey.kGeneric_EMail, + }, + accountRegisterUsername: { + placeholder: I18nStringKey.kGeneric_Username, + }, + accountRegisterPassword: { + placeholder: I18nStringKey.kGeneric_Password, + }, + accountRegisterConfirmPassword: { + placeholder: I18nStringKey.kAccountModal_ConfirmPassword, + }, + accountVerifyEmailCode: { + placeholder: I18nStringKey.kGeneric_VerificationCode, + }, + accountVerifyEmailPassword: { + placeholder: I18nStringKey.kGeneric_Password, + }, + accountSettingsEmail: { + placeholder: I18nStringKey.kGeneric_EMail, + }, + accountSettingsUsername: { + placeholder: I18nStringKey.kGeneric_Username, + }, + accountSettingsNewPassword: { + placeholder: I18nStringKey.kAccountModal_NewPassword, + }, + accountSettingsConfirmNewPassword: { + placeholder: I18nStringKey.kAccountModal_ConfirmNewPassword, + }, + accountSettingsCurrentPassword: { + placeholder: I18nStringKey.kAccountModal_CurrentPassword, + }, + accountResetPasswordEmail: { + placeholder: I18nStringKey.kGeneric_EMail, + }, + accountResetPasswordUsername: { + placeholder: I18nStringKey.kGeneric_Username, + }, + accountResetPasswordCode: { + placeholder: I18nStringKey.kGeneric_VerificationCode, + }, + accountResetPasswordNewPassword: { + placeholder: I18nStringKey.kAccountModal_NewPassword, + }, + accountResetPasswordConfirmNewPassword: { + placeholder: I18nStringKey.kAccountModal_ConfirmNewPassword, + }, }; for (let domId of Object.keys(kDomIdtoStringMap)) { let element = document.getElementById(domId); if (element == null) { - alert('Uhh!! THIS SHOULD NOT BE SEEN!! IF YOU DO YELL LOUDLY'); + alert(`Error: Could not find element with ID ${domId} in the DOM! Please tell a site admin this happened.`); return; } @@ -245,7 +349,22 @@ export class I18n { // N.B: For now, we assume all strings in this map are not formatted. // If this assumption changes, then we should just use GetString() again // and maybe include arguments, but for now this is okay - element.innerText = this.GetStringRaw(kDomIdtoStringMap[domId]); + element.innerHTML = this.GetStringRaw(kDomIdtoStringMap[domId]); + } + + for (let domId of Object.keys(kDomAttributeToStringMap)) { + let element = document.getElementById(domId); + if (element == null) { + alert(`Error: Could not find element with ID ${domId} in the DOM! Please tell a site admin this happened.`); + return; + } + + // TODO: Figure out if we can get rid of this ts-ignore + // @ts-ignore + let attributes = kDomAttributeToStringMap[domId]; + for (let attr of Object.keys(attributes)) { + element.setAttribute(attr, this.GetStringRaw(attributes[attr] as I18nStringKey)); + } } } @@ -271,4 +390,4 @@ export class I18n { } } -export let TheI18n = new I18n(); +export let TheI18n = new I18n(); \ No newline at end of file diff --git a/src/ts/main.ts b/src/ts/main.ts index fcff312..6eb7278 100644 --- a/src/ts/main.ts +++ b/src/ts/main.ts @@ -826,21 +826,21 @@ function userModOptions(user: { user: User; element: HTMLTableRowElement }) { let ul = document.createElement('ul'); ul.classList.add('dropdown-menu', 'dropdown-menu-dark', 'table-dark', 'text-light'); if (perms.bypassturn) addUserDropdownItem(ul, TheI18n.GetString(I18nStringKey.kVMButtons_EndTurn), () => VM!.endTurn(user.user.username)); - if (perms.ban) addUserDropdownItem(ul, 'Ban', () => VM!.ban(user.user.username)); - if (perms.kick) addUserDropdownItem(ul, 'Kick', () => VM!.kick(user.user.username)); + if (perms.ban) addUserDropdownItem(ul, TheI18n.GetString(I18nStringKey.kAdminVMButtons_Ban), () => VM!.ban(user.user.username)); + if (perms.kick) addUserDropdownItem(ul, TheI18n.GetString(I18nStringKey.kAdminVMButtons_Kick), () => VM!.kick(user.user.username)); if (perms.rename) - addUserDropdownItem(ul, 'Rename', () => { - let newname = prompt(`Enter new username for ${user.user.username}`); + addUserDropdownItem(ul, TheI18n.GetString(I18nStringKey.kVMButtons_ChangeUsername), () => { + let newname = prompt(TheI18n.GetString(I18nStringKey.kVMPrompts_AdminChangeUsernamePrompt, user.user.username)); if (!newname) return; VM!.renameUser(user.user.username, newname); }); if (perms.mute) { - addUserDropdownItem(ul, 'Temporary Mute', () => VM!.mute(user.user.username, MuteState.Temp)); - addUserDropdownItem(ul, 'Indefinite Mute', () => VM!.mute(user.user.username, MuteState.Perma)); - addUserDropdownItem(ul, 'Unmute', () => VM!.mute(user.user.username, MuteState.Unmuted)); + addUserDropdownItem(ul, TheI18n.GetString(I18nStringKey.kAdminVMButtons_TempMute), () => VM!.mute(user.user.username, MuteState.Temp)); + addUserDropdownItem(ul, TheI18n.GetString(I18nStringKey.kAdminVMButtons_IndefMute), () => VM!.mute(user.user.username, MuteState.Perma)); + addUserDropdownItem(ul, TheI18n.GetString(I18nStringKey.kAdminVMButtons_Unmute), () => VM!.mute(user.user.username, MuteState.Unmuted)); } if (perms.grabip) - addUserDropdownItem(ul, 'Get IP', async () => { + addUserDropdownItem(ul, TheI18n.GetString(I18nStringKey.kAdminVMButtons_GetIP), async () => { let ip = await VM!.getip(user.user.username); alert(ip); }); @@ -859,7 +859,7 @@ function addUserDropdownItem(ul: HTMLUListElement, text: string, func: () => voi } // Admin buttons -elements.restoreBtn.addEventListener('click', () => window.confirm('Are you sure you want to restore the VM?') && VM?.restore()); +elements.restoreBtn.addEventListener('click', () => window.confirm(TheI18n.GetString(I18nStringKey.kVMPrompts_AdminRestoreVMPrompt)) && VM?.restore()); elements.rebootBtn.addEventListener('click', () => VM?.reboot()); elements.clearQueueBtn.addEventListener('click', () => VM?.clearQueue()); elements.bypassTurnBtn.addEventListener('click', () => VM?.bypassTurn()); @@ -929,7 +929,7 @@ const accountModal = new bootstrap.Modal(elements.accountModal); elements.accountModalErrorDismiss.addEventListener('click', () => elements.accountModalError.style.display = "none"); elements.accountModalSuccessDismiss.addEventListener('click', () => elements.accountModalSuccess.style.display = "none"); elements.accountLoginButton.addEventListener("click", () => { - elements.accountModalTitle.innerText = TheI18n.GetString(I18nStringKey.kAccountModal_Login); + elements.accountModalTitle.innerText = TheI18n.GetString(I18nStringKey.kGeneric_Login); elements.accountRegisterSection.style.display = "none"; elements.accountVerifyEmailSection.style.display = "none"; elements.accountLoginSection.style.display = "block"; @@ -939,7 +939,7 @@ elements.accountLoginButton.addEventListener("click", () => { accountModal.show(); }); elements.accountRegisterButton.addEventListener("click", () => { - elements.accountModalTitle.innerText = TheI18n.GetString(I18nStringKey.kAccountModal_Register); + elements.accountModalTitle.innerText = TheI18n.GetString(I18nStringKey.kGeneric_Register); elements.accountRegisterSection.style.display = "block"; elements.accountVerifyEmailSection.style.display = "none"; elements.accountLoginSection.style.display = "none"; diff --git a/static/lang/en-us.json b/static/lang/en-us.json index 2449d88..aeca950 100644 --- a/static/lang/en-us.json +++ b/static/lang/en-us.json @@ -10,6 +10,21 @@ "kGeneric_No": "No", "kGeneric_Ok": "OK", "kGeneric_Cancel": "Cancel", + "kGeneric_Send": "Send", + "kGeneric_Understood": "Understood", + "kGeneric_Username": "Username", + "kGeneric_Password": "Password", + "kGeneric_Login": "Log in", + "kGeneric_Register": "Register", + "kGeneric_EMail": "E-Mail", + "kGeneric_DateOfBirth": "Date of Birth", + "kGeneric_VerificationCode": "Verification Code", + "kGeneric_Verify": "Verify", + "kGeneric_Update": "Update", + "kGeneric_Logout": "Log out", + + "kWelcomeModal_Header": "Welcome to CollabVM", + "kWelcomeModal_Body": "

Before continuing, please familiarize yourself with our rules:

R1. Don't break the law.

Do not use CollabVM or CollabVM's network to violate United States federal law, New York state law, or international law. If CollabVM becomes aware a crime has been committed through its service, you will be immediately banned, and your activities may be reported to the authorities if necessary.

CollabVM is required by law to notify law enforcement agencies if it becomes aware of the presence of child pornography on, or being transmitted through its network.

COPPA is also enforced, please do not use CollabVM if you are under the age of 13 years old.

R2. No running DoS/DDoS tools.

Do not use CollabVM to DoS/DDoS an indivdiual, business, company, or anyone else.

R3. No spam distribution.

Do not spam any emails using this service or push spam in general.

R4. Do not abuse any exploits.

Do not abuse any exploits, additionally if you see someone abusing exploits or you need to report one, please contact me at: computernewbab@gmail.com

R5. Don't impersonate other users.

Do not impersonate other members of CollabVM. If caught, you'll be temporarily disconnected, and banned if necessary.

R6. One vote per person.

Do not use any methods or tools to bypass the vote restriction. Only one vote per person is allowed, no matter what. Anybody who is caught doing this will be banned.

R7. No Remote Administration Tools.

Do not use any remote administration tools (ex: DarkComet, NanoCore, Anydesk, TeamViewer, Orcus, etc.)

R8. No bypassing CollabNet.

Do not attempt to bypass the blocking provided by CollabNet, especially if it is being used to break Rule 1, Rule 2, or Rule 7 (or run stupid over-used things).

R9. No performing destructive actions constantly.

Any user may not destroy the VM (rendering it unusable constantly), install/reinstall the operating system (except on VM7 or VM8), or run bots that do such. This includes bots that spam massive amounts of keyboard/mouse input (\"kitting\").

R10. No Cryptomining

Attempting to mine cryptocurrency on the VMs will result in a kick, and then a permanent ban if you keep attempting. Besides, it's not like you're gonna make any money off it.

NSFW Warning

Please note that NSFW content is allowed on our anarchy VM (VM0b0t), and is viewed regularly. In addition, while we give a good effort to keep NSFW off the main VMs, people will occasionally slip it through.", "kSiteButtons_Home": "Home", "kSiteButtons_FAQ": "FAQ", @@ -29,26 +44,48 @@ "kVMButtons_TakeTurn": "Take Turn", "kVMButtons_EndTurn": "End Turn", "kVMButtons_ChangeUsername": "Change Username", + "kVMButtons_Keyboard": "Keyboard", + "KVMButtons_CtrlAltDel": "Ctrl+Alt+Del", "kVMButtons_VoteForReset": "Vote For Reset", "kVMButtons_Screenshot": "Screenshot", + "kQEMUMonitor": "QEMU Monitor", "kAdminVMButtons_PassVote": "Pass Vote", "kAdminVMButtons_CancelVote": "Cancel Vote", + "kAdminVMButtons_Restore": "Restore", + "kAdminVMButtons_Reboot": "Reboot", + "kAdminVMButtons_ClearTurnQueue": "Clear Turn Queue", + "kAdminVMButtons_BypassTurn": "Bypass Turn", + "kAdminVMButtons_IndefiniteTurn": "Indefinite Turn", + + "kAdminVMButtons_Ban": "Ban", + "kAdminVMButtons_Kick": "Kick", + "kAdminVMButtons_TempMute": "Temporary Mute", + "kAdminVMButtons_IndefMute": "Indefinite Mute", + "kAdminVMButtons_Unmute": "Unmute", + "kAdminVMButtons_GetIP": "Get IP", + + "kVMPrompts_AdminChangeUsernamePrompt": "Enter new username for {0}:", + "kVMPrompts_AdminRestoreVMPrompt": "Are you sure you want to restore the VM?", "kVMPrompts_EnterNewUsernamePrompt": "Enter a new username, or leave the field blank to be assigned a guest username", "kError_UnexpectedDisconnection": "You have been disconnected from the server.", "kError_UsernameTaken": "That username is already taken", "kError_UsernameInvalid": "Usernames can contain only numbers, letters, spaces, dashes, underscores, and dots, and it must be between 3 and 20 characters.", "kError_UsernameBlacklisted": "That username has been blacklisted.", + "kError_IncorrectPassword": "Incorrect password.", - "kAccountModal_Login": "Login", - "kAccountModal_Register": "Register", "kAccountModal_Verify": "Verify E-Mail", "kAccountModal_AccountSettings": "Account Settings", "kAccountModal_ResetPassword": "Reset Password", + "kAccountModal_NewPassword": "New Password", + "kAccountModal_ConfirmNewPassword": "Confirm New Password", + "kAccountModal_CurrentPassword": "Current Password", + "kAccountModal_ConfirmPassword": "Confirm Password", + "kMissingCaptcha": "Please fill out the captcha.", "kPasswordsMustMatch": "Passwords must match.", "kAccountModal_VerifyText": "We sent an E-Mail to {0}. To verify your account, please enter the 8-digit code from the E-Mail below.",