diff --git a/src/client/CrazyGamesSDK.ts b/src/client/CrazyGamesSDK.ts index b00cfe7de..1933074ec 100644 --- a/src/client/CrazyGamesSDK.ts +++ b/src/client/CrazyGamesSDK.ts @@ -3,6 +3,28 @@ declare global { CrazyGames?: { SDK: { init: () => Promise; + user: { + getUser(): Promise<{ + username: string; + } | null>; + addAuthListener: ( + listener: ( + user: { + username: string; + } | null, + ) => void, + ) => void; + }; + ad: { + requestAd: ( + adType: string, + callbacks: { + adStarted: () => void; + adFinished: () => void; + adError: (error: any) => void; + }, + ) => void; + }; game: { gameplayStart: () => Promise; gameplayStop: () => Promise; @@ -14,7 +36,9 @@ declare global { [key: string]: string | number; }) => string; hideInviteButton: () => void; + inviteLink: (params: { [key: string]: string | number }) => string; getInviteParam: (paramName: string) => string | null; + isInstantMultiplayer?: boolean; }; }; }; @@ -24,6 +48,24 @@ declare global { export class CrazyGamesSDK { private initialized = false; private isGameplayActive = false; + private readyPromise: Promise; + private resolveReady!: () => void; + + constructor() { + this.readyPromise = new Promise((resolve) => { + this.resolveReady = resolve; + }); + } + + async ready(): Promise { + const timeout = new Promise((resolve) => { + setTimeout(() => resolve(false), 3000); + }); + + const ready = this.readyPromise.then(() => true); + + return Promise.race([ready, timeout]); + } isOnCrazyGames(): boolean { try { @@ -34,9 +76,17 @@ export class CrazyGamesSDK { } return false; } catch (e) { + console.log("[CrazyGames]: ", e); // If we get a cross-origin error, we're definitely iframed // Check our own referrer as fallback - return document.referrer.includes("crazygames"); + const isCrazyGames = document.referrer.includes("crazygames"); + console.log("[CrazyGames], contains referrer: ", isCrazyGames); + if (isCrazyGames) { + return true; + } + + // Fallback: on safari private we can't get referrer, so just assume we are in crazygames if in iframe + return window.self !== window.top; } } @@ -70,12 +120,63 @@ export class CrazyGamesSDK { try { await window.CrazyGames.SDK.init(); this.initialized = true; + this.resolveReady(); console.log("CrazyGames SDK initialized"); } catch (error) { console.error("Failed to initialize CrazyGames SDK:", error); } } + async getUsername(): Promise { + const isReady = await this.ready(); + if (!isReady) { + return null; + } + try { + return (await window.CrazyGames!.SDK.user.getUser())?.username ?? null; + } catch (e) { + console.log("error getting CrazyGames username: ", e); + return null; + } + } + + async addAuthListener( + listener: ( + user: { + username: string; + } | null, + ) => void, + ): Promise { + if (!(await this.ready())) { + return; + } + + try { + console.log("registering CrazyGames auth listener"); + window.CrazyGames!.SDK.user.addAuthListener(listener); + } catch (error) { + console.error("Failed to add auth listener:", error); + } + } + + async isInstantMultiplayer(): Promise { + const isReady = await this.ready(); + if (!isReady) { + return false; + } + const gameId = await this.getInviteGameId(); + if (gameId !== null) { + // Game id exists, meaning we are joining the game, not hosting it. + return false; + } + try { + return window.CrazyGames!.SDK.game.isInstantMultiplayer ?? false; + } catch (e) { + console.log("Error getting instant multiplayer: ", e); + return false; + } + } + async gameplayStart(): Promise { if (!this.isReady()) { return; @@ -156,7 +257,6 @@ export class CrazyGamesSDK { if (!this.isReady()) { return null; } - try { const options: { gameId: string | number; @@ -165,6 +265,9 @@ export class CrazyGamesSDK { gameId, }; const link = window.CrazyGames!.SDK.game.showInviteButton(options); + // Store the game so we know that we are host. This way when player refreshes page, + // It won't show up as "joining" a game we created. + localStorage.setItem(gameId, "true"); console.log("CrazyGames: invite button shown, link:", link); return link; } catch (error) { @@ -186,20 +289,66 @@ export class CrazyGamesSDK { } } - getInviteGameId(): string | null { + createInviteLink(gameId: string): string | null { if (!this.isReady()) { + console.warn("CrazyGames SDK not ready, cannot create invite link"); return null; } try { - const value = window.CrazyGames!.SDK.game.getInviteParam("gameId"); - console.log(`CrazyGames: got invite gameId:`, value); - return value; + const link = window.CrazyGames!.SDK.game.inviteLink({ gameId }); + console.log("CrazyGames: created invite link:", link); + return link; + } catch (error) { + console.error("Failed to create invite link:", error); + return null; + } + } + + async getInviteGameId(): Promise { + if (!(await this.ready())) { + return null; + } + try { + const gameId = window.CrazyGames!.SDK.game.getInviteParam("gameId"); + if (gameId) { + console.log("[CrazyGames] found invite link", gameId); + // We already created this game, can't join a game we created. + return localStorage.getItem(gameId) === "true" ? null : gameId; + } + return null; } catch (error) { console.error(`Failed to get invite gameId:`, error); return null; } } + + requestMidgameAd(): Promise { + return new Promise((resolve) => { + if (!this.isReady()) { + resolve(); + return; + } + + try { + const callbacks = { + adFinished: () => { + console.log("End midgame ad"); + resolve(); + }, + adError: (error: any) => { + console.log("Error midgame ad", error); + resolve(); + }, + adStarted: () => console.log("Start midgame ad"), + }; + window.CrazyGames!.SDK.ad.requestAd("midgame", callbacks); + } catch (error) { + console.error("Failed to request midgame ad:", error); + resolve(); + } + }); + } } export const crazyGamesSDK = new CrazyGamesSDK(); diff --git a/src/client/HostLobbyModal.ts b/src/client/HostLobbyModal.ts index 03e0a6ed0..cd49edf11 100644 --- a/src/client/HostLobbyModal.ts +++ b/src/client/HostLobbyModal.ts @@ -113,6 +113,12 @@ export class HostLobbyModal extends BaseModal { } private async buildLobbyUrl(): Promise { + if (crazyGamesSDK.isOnCrazyGames()) { + const link = crazyGamesSDK.createInviteLink(this.lobbyId); + if (link !== null) { + return link; + } + } const config = await getServerConfigFromClient(); return `${window.location.origin}/${config.workerPath(this.lobbyId)}/game/${this.lobbyId}?lobby&s=${encodeURIComponent(this.lobbyUrlSuffix)}`; } @@ -123,7 +129,9 @@ export class HostLobbyModal extends BaseModal { } private updateHistory(url: string): void { - history.replaceState(null, "", url); + if (!crazyGamesSDK.isOnCrazyGames()) { + history.replaceState(null, "", url); + } } render() { diff --git a/src/client/LangSelector.ts b/src/client/LangSelector.ts index 3097ea7a8..f80415d06 100644 --- a/src/client/LangSelector.ts +++ b/src/client/LangSelector.ts @@ -228,6 +228,7 @@ export class LangSelector extends LitElement { "stats-modal", "flag-input-modal", "flag-input", + "matchmaking-button", "token-login", ]; diff --git a/src/client/Main.ts b/src/client/Main.ts index 57644d6b8..2cfe82ad3 100644 --- a/src/client/Main.ts +++ b/src/client/Main.ts @@ -7,7 +7,7 @@ import { getServerConfigFromClient } from "../core/configuration/ConfigLoader"; import { GameType } from "../core/game/Game"; import { UserSettings } from "../core/game/UserSettings"; import "./AccountModal"; -import { getUserMe, hasLinkedAccount } from "./Api"; +import { getUserMe } from "./Api"; import { userAuth } from "./Auth"; import { joinLobby } from "./ClientGameRunner"; import { fetchCosmetics } from "./Cosmetics"; @@ -43,7 +43,7 @@ import { } from "./Transport"; import { UserSettingModal } from "./UserSettingModal"; import "./UsernameInput"; -import { UsernameInput } from "./UsernameInput"; +import { genAnonUsername, UsernameInput } from "./UsernameInput"; import { getDiscordAvatarUrl, incrementGamesPlayed, @@ -209,6 +209,7 @@ class Client { private usernameInput: UsernameInput | null = null; private flagInput: FlagInput | null = null; + private hostModal: HostPrivateLobbyModal; private joinModal: JoinPrivateLobbyModal; private publicLobby: PublicLobby; private userSettings: UserSettings = new UserSettings(); @@ -426,56 +427,14 @@ class Client { ) { console.warn("Matchmaking modal element not found"); } - const matchmakingButton = document.getElementById("matchmaking-button"); - const matchmakingButtonLoggedOut = document.getElementById( - "matchmaking-button-logged-out", - ); - - const updateMatchmakingButton = (loggedIn: boolean) => { - if (!loggedIn) { - matchmakingButton?.classList.add("hidden"); - matchmakingButtonLoggedOut?.classList.remove("hidden"); - } else { - matchmakingButton?.classList.remove("hidden"); - matchmakingButtonLoggedOut?.classList.add("hidden"); - } - }; - - if (matchmakingButton) { - matchmakingButton.addEventListener("click", () => { - if (this.usernameInput?.isValid()) { - window.showPage?.("page-matchmaking"); - this.publicLobby.leaveLobby(); - } else { - window.dispatchEvent( - new CustomEvent("show-message", { - detail: { - message: this.usernameInput?.validationError, - color: "red", - duration: 3000, - }, - }), - ); - } - }); - } - - if (matchmakingButtonLoggedOut) { - matchmakingButtonLoggedOut.addEventListener("click", () => { - window.showPage?.("page-account"); - }); - } const onUserMe = async (userMeResponse: UserMeResponse | false) => { - // Check if user has actual authentication (discord or email), not just a publicId - const isLinked: boolean = hasLinkedAccount(userMeResponse); - updateMatchmakingButton(isLinked); updateAccountNavButton(userMeResponse); - const adsEnabled = + const hasLinkedAccount = !crazyGamesSDK.isOnCrazyGames() && - ((userMeResponse || null)?.player?.flares?.length ?? 0) === 0; - console.log("ads enabled: ", adsEnabled); - window.adsEnabled = adsEnabled; + ((userMeResponse || null)?.player?.flares?.length ?? 0) > 0; + console.log("ads enabled: ", hasLinkedAccount); + window.adsEnabled = !hasLinkedAccount && !crazyGamesSDK.isOnCrazyGames(); document.dispatchEvent( new CustomEvent("userMeResponse", { detail: userMeResponse, @@ -516,10 +475,10 @@ class Client { } }); - const hostModal = document.querySelector( + this.hostModal = document.querySelector( "host-lobby-modal", ) as HostPrivateLobbyModal; - if (!hostModal || !(hostModal instanceof HostPrivateLobbyModal)) { + if (!this.hostModal || !(this.hostModal instanceof HostPrivateLobbyModal)) { console.warn("Host private lobby modal element not found"); } const hostLobbyButton = document.getElementById("host-lobby-button"); @@ -575,7 +534,11 @@ class Client { } // Attempt to join lobby - this.handleUrl(); + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", () => this.handleUrl()); + } else { + this.handleUrl(); + } const onHashUpdate = () => { // Reset the UI to its initial state @@ -647,17 +610,36 @@ class Client { }); } - private handleUrl() { + private async handleUrl() { + // Wait for modal custom elements to be defined + await Promise.all([ + customElements.whenDefined("join-private-lobby-modal"), + customElements.whenDefined("host-lobby-modal"), + ]); + // Check if CrazyGames SDK is enabled first (no hash needed in CrazyGames) if (crazyGamesSDK.isOnCrazyGames()) { - const lobbyId = crazyGamesSDK.getInviteGameId(); + const lobbyId = await crazyGamesSDK.getInviteGameId(); + console.log("got game id", lobbyId); if (lobbyId && GAME_ID_REGEX.test(lobbyId)) { + console.log("game parsed successfully"); + // Wait 2 seconds to ensure all elements are actually loaded, + // On low end-chromebooks the join modal was not registered in time. + await new Promise((resolve) => setTimeout(resolve, 2000)); window.showPage?.("page-join-private-lobby"); this.joinModal?.open(lobbyId); console.log(`CrazyGames: joining lobby ${lobbyId} from invite param`); return; } } + crazyGamesSDK.isInstantMultiplayer().then((isInstant) => { + if (isInstant) { + console.log( + `CrazyGames: joining instant multiplayer lobby from CrazyGames`, + ); + this.hostModal.open(); + } + }); const strip = () => history.replaceState( @@ -780,7 +762,8 @@ class Client { : this.flagInput.getCurrentFlag(), }, turnstileToken: await this.getTurnstileToken(lobby), - playerName: this.usernameInput?.getCurrentUsername() ?? "", + playerName: + this.usernameInput?.getCurrentUsername() ?? genAnonUsername(), clientID: lobby.clientID, gameStartInfo: lobby.gameStartInfo ?? lobby.gameRecord?.info, gameRecord: lobby.gameRecord, @@ -926,7 +909,8 @@ class Client { return null; } - if (this.turnstileTokenPromise === null) { + // Always request a new token on crazygames. + if (this.turnstileTokenPromise === null || crazyGamesSDK.isOnCrazyGames()) { console.log("No prefetched turnstile token, getting new token"); return (await getTurnstileToken())?.token ?? null; } @@ -942,6 +926,7 @@ class Client { const tokenTTL = 3 * 60 * 1000; if (Date.now() < token.createdAt + tokenTTL) { console.log("Prefetched turnstile token is valid"); + return token.token; } else { console.log("Turnstile token expired, getting new token"); @@ -950,11 +935,27 @@ class Client { } } +// Hide elements with no-crazygames class if on CrazyGames +const hideCrazyGamesElements = () => { + if (crazyGamesSDK.isOnCrazyGames()) { + document.querySelectorAll(".no-crazygames").forEach((el) => { + (el as HTMLElement).style.display = "none"; + }); + } +}; + // Initialize the client when the DOM is loaded const bootstrap = () => { initLayout(); new Client().initialize(); initNavigation(); + + // Hide elements immediately + hideCrazyGamesElements(); + + // Also hide elements after a short delay to catch late-rendered components + setTimeout(hideCrazyGamesElements, 100); + setTimeout(hideCrazyGamesElements, 500); }; if (document.readyState === "loading") { diff --git a/src/client/Matchmaking.ts b/src/client/Matchmaking.ts index 73307d15d..0c4b634f0 100644 --- a/src/client/Matchmaking.ts +++ b/src/client/Matchmaking.ts @@ -3,7 +3,7 @@ import { customElement, query, state } from "lit/decorators.js"; import { UserMeResponse } from "../core/ApiSchemas"; import { getServerConfigFromClient } from "../core/configuration/ConfigLoader"; import { generateID } from "../core/Util"; -import { getUserMe } from "./Api"; +import { getUserMe, hasLinkedAccount } from "./Api"; import { getPlayToken } from "./Auth"; import { BaseModal } from "./components/BaseModal"; import "./components/Difficulties"; @@ -240,6 +240,7 @@ export class MatchmakingModal extends BaseModal { @customElement("matchmaking-button") export class MatchmakingButton extends LitElement { @query("matchmaking-modal") private matchmakingModal?: MatchmakingModal; + @state() private isLoggedIn = false; constructor() { super(); @@ -247,6 +248,14 @@ export class MatchmakingButton extends LitElement { async connectedCallback() { super.connectedCallback(); + // Listen for user authentication changes + document.addEventListener("userMeResponse", (event: Event) => { + const customEvent = event as CustomEvent; + if (customEvent.detail) { + const userMeResponse = customEvent.detail as UserMeResponse | false; + this.isLoggedIn = hasLinkedAccount(userMeResponse); + } + }); } createRenderRoot() { @@ -254,19 +263,65 @@ export class MatchmakingButton extends LitElement { } render() { + if (this.isLoggedIn) { + return html` + + + + `; + } + return html` -
- -
+ + `; } + private handleLoggedInClick() { + const usernameInput = document.querySelector("username-input") as any; + const publicLobby = document.querySelector("public-lobby") as any; + + if (usernameInput?.isValid()) { + this.open(); + publicLobby?.leaveLobby(); + } else { + window.dispatchEvent( + new CustomEvent("show-message", { + detail: { + message: usernameInput?.validationError, + color: "red", + duration: 3000, + }, + }), + ); + } + } + + private handleLoggedOutClick() { + window.showPage?.("page-account"); + } + private open() { this.matchmakingModal?.open(); } diff --git a/src/client/PatternInput.ts b/src/client/PatternInput.ts index 755c7c834..483bef75c 100644 --- a/src/client/PatternInput.ts +++ b/src/client/PatternInput.ts @@ -5,6 +5,7 @@ import { UserSettings } from "../core/game/UserSettings"; import { PlayerPattern } from "../core/Schemas"; import { renderPatternPreview } from "./components/PatternButton"; import { fetchCosmetics } from "./Cosmetics"; +import { crazyGamesSDK } from "./CrazyGamesSDK"; import { translateText } from "./Utils"; @customElement("pattern-input") @@ -73,6 +74,10 @@ export class PatternInput extends LitElement { } render() { + if (crazyGamesSDK.isOnCrazyGames()) { + return html``; + } + const isDefault = this.pattern === null && this.selectedColor === null; const showSelect = this.showSelectLabel && isDefault; const buttonTitle = translateText("territory_patterns.title"); diff --git a/src/client/SinglePlayerModal.ts b/src/client/SinglePlayerModal.ts index c34dfe268..440d1948a 100644 --- a/src/client/SinglePlayerModal.ts +++ b/src/client/SinglePlayerModal.ts @@ -27,6 +27,7 @@ import "./components/FluentSlider"; import "./components/Maps"; import { modalHeader } from "./components/ui/ModalHeader"; import { fetchCosmetics } from "./Cosmetics"; +import { crazyGamesSDK } from "./CrazyGamesSDK"; import { FlagInput } from "./FlagInput"; import { JoinLobbyEvent } from "./Main"; import { UsernameInput } from "./UsernameInput"; @@ -89,6 +90,9 @@ export class SinglePlayerModal extends BaseModal { }; private renderNotLoggedInBanner(): TemplateResult { + if (crazyGamesSDK.isOnCrazyGames()) { + return html``; + } return html`
@@ -1057,6 +1061,8 @@ export class SinglePlayerModal extends BaseModal { const selectedColor = this.userSettings.getSelectedColor(); + await crazyGamesSDK.requestMidgameAd(); + this.dispatchEvent( new CustomEvent("join-lobby", { detail: { diff --git a/src/client/UsernameInput.ts b/src/client/UsernameInput.ts index 20b2bb372..0434f4674 100644 --- a/src/client/UsernameInput.ts +++ b/src/client/UsernameInput.ts @@ -8,6 +8,7 @@ import { MIN_USERNAME_LENGTH, validateUsername, } from "../core/validations/username"; +import { crazyGamesSDK } from "./CrazyGamesSDK"; const usernameKey: string = "username"; @@ -39,8 +40,18 @@ export class UsernameInput extends LitElement { connectedCallback() { super.connectedCallback(); - const stored = this.getStoredUsername(); + const stored = this.getUsername(); this.parseAndSetUsername(stored); + crazyGamesSDK.getUsername().then((username) => { + this.parseAndSetUsername(username ?? genAnonUsername()); + this.requestUpdate(); + }); + crazyGamesSDK.addAuthListener((user) => { + if (user) { + this.parseAndSetUsername(user?.username); + } + this.requestUpdate(); + }); } private parseAndSetUsername(fullUsername: string) { @@ -52,6 +63,8 @@ export class UsernameInput extends LitElement { this.clanTag = ""; this.baseUsername = fullUsername; } + + this.validateAndStore(); } render() { @@ -161,7 +174,7 @@ export class UsernameInput extends LitElement { } } - private getStoredUsername(): string { + private getUsername(): string { const storedUsername = localStorage.getItem(usernameKey); if (storedUsername) { return storedUsername; @@ -176,20 +189,20 @@ export class UsernameInput extends LitElement { } private generateNewUsername(): string { - const newUsername = "Anon" + this.uuidToThreeDigits(); + const newUsername = genAnonUsername(); this.storeUsername(newUsername); return newUsername; } - private uuidToThreeDigits(): string { - const uuid = uuidv4(); - const cleanUuid = uuid.replace(/-/g, "").toLowerCase(); - const decimal = BigInt(`0x${cleanUuid}`); - const threeDigits = decimal % 1000n; - return threeDigits.toString().padStart(3, "0"); - } - public isValid(): boolean { return this._isValid; } } + +export function genAnonUsername(): string { + const uuid = uuidv4(); + const cleanUuid = uuid.replace(/-/g, "").toLowerCase(); + const decimal = BigInt(`0x${cleanUuid}`); + const threeDigits = decimal % 1000n; + return "Anon" + threeDigits.toString().padStart(3, "0"); +} diff --git a/src/client/components/CopyButton.ts b/src/client/components/CopyButton.ts index 13742cc58..5a7b7fbec 100644 --- a/src/client/components/CopyButton.ts +++ b/src/client/components/CopyButton.ts @@ -2,6 +2,7 @@ import { LitElement, html } from "lit"; import { customElement, property, state } from "lit/decorators.js"; import { getServerConfigFromClient } from "../../core/configuration/ConfigLoader"; import { UserSettings } from "../../core/game/UserSettings"; +import { crazyGamesSDK } from "../CrazyGamesSDK"; import { copyToClipboard, translateText } from "../Utils"; @customElement("copy-button") @@ -73,15 +74,21 @@ export class CopyButton extends LitElement { return url; } - private async resolveCopyText(): Promise { + private async resolveCopyText(): Promise { if (this.copyText) return this.copyText; + if (crazyGamesSDK.isOnCrazyGames()) { + return crazyGamesSDK.createInviteLink(this.lobbyId); + } if (!this.lobbyId) return ""; return await this.buildCopyUrl(); } private async handleCopy() { const text = await this.resolveCopyText(); - if (!text) return; + if (!text) { + alert("Error copying game id"); + return; + } await copyToClipboard( text, () => (this.copySuccess = true), diff --git a/src/client/components/DesktopNavBar.ts b/src/client/components/DesktopNavBar.ts index 74ea1b498..b6b67b435 100644 --- a/src/client/components/DesktopNavBar.ts +++ b/src/client/components/DesktopNavBar.ts @@ -105,7 +105,7 @@ export class DesktopNavBar extends LitElement { data-i18n="main.news" > @@ -127,14 +127,14 @@ export class DesktopNavBar extends LitElement { @@ -135,7 +135,7 @@ export class MobileNavBar extends LitElement { data-i18n="main.settings" > diff --git a/src/client/components/PatternButton.ts b/src/client/components/PatternButton.ts index 037dc4743..6d6b94b18 100644 --- a/src/client/components/PatternButton.ts +++ b/src/client/components/PatternButton.ts @@ -72,7 +72,7 @@ export class PatternButton extends LitElement { return html`
- - - - - +
diff --git a/src/client/graphics/layers/GameRightSidebar.ts b/src/client/graphics/layers/GameRightSidebar.ts index e86317a7c..2ee9ee276 100644 --- a/src/client/graphics/layers/GameRightSidebar.ts +++ b/src/client/graphics/layers/GameRightSidebar.ts @@ -105,10 +105,15 @@ export class GameRightSidebar extends LitElement implements Layer { private onPauseButtonClick() { this.isPaused = !this.isPaused; + if (this.isPaused) { + crazyGamesSDK.gameplayStop(); + } else { + crazyGamesSDK.gameplayStart(); + } this.eventBus.emit(new PauseGameIntentEvent(this.isPaused)); } - private onExitButtonClick() { + private async onExitButtonClick() { const isAlive = this.game.myPlayer()?.isAlive(); if (isAlive) { const isConfirmed = confirm( @@ -116,10 +121,10 @@ export class GameRightSidebar extends LitElement implements Layer { ); if (!isConfirmed) return; } - crazyGamesSDK.gameplayStop().then(() => { - // redirect to the home page - window.location.href = "/"; - }); + await crazyGamesSDK.requestMidgameAd(); + await crazyGamesSDK.gameplayStop(); + // redirect to the home page + window.location.href = "/"; } private onSettingsButtonClick() { diff --git a/src/client/graphics/layers/SettingsModal.ts b/src/client/graphics/layers/SettingsModal.ts index 92d8f1fe4..0a5b184bf 100644 --- a/src/client/graphics/layers/SettingsModal.ts +++ b/src/client/graphics/layers/SettingsModal.ts @@ -1,9 +1,10 @@ import { html, LitElement } from "lit"; import { customElement, property, query, state } from "lit/decorators.js"; +import { crazyGamesSDK } from "src/client/CrazyGamesSDK"; +import { PauseGameIntentEvent } from "src/client/Transport"; import { EventBus } from "../../../core/EventBus"; import { UserSettings } from "../../../core/game/UserSettings"; import { AlternateViewEvent, RefreshGraphicsEvent } from "../../InputHandler"; -import { PauseGameIntentEvent } from "../../Transport"; import { translateText } from "../../Utils"; import SoundManager from "../../sound/SoundManager"; import { Layer } from "./Layer"; @@ -105,8 +106,14 @@ export class SettingsModal extends LitElement implements Layer { } private pauseGame(pause: boolean) { - if (this.shouldPause && !this.wasPausedWhenOpened) + if (this.shouldPause && !this.wasPausedWhenOpened) { + if (pause) { + crazyGamesSDK.gameplayStop(); + } else { + crazyGamesSDK.gameplayStart(); + } this.eventBus.emit(new PauseGameIntentEvent(pause)); + } } private onTerrainButtonClick() { diff --git a/src/client/graphics/layers/UnitDisplay.ts b/src/client/graphics/layers/UnitDisplay.ts index 4b9a5d60c..c08bcb183 100644 --- a/src/client/graphics/layers/UnitDisplay.ts +++ b/src/client/graphics/layers/UnitDisplay.ts @@ -130,7 +130,7 @@ export class UnitDisplay extends LitElement implements Layer { return html`