crazygames

This commit is contained in:
evanpelle
2026-01-05 15:34:33 -08:00
parent 5220d8a030
commit f9ce40811a
9 changed files with 127 additions and 13 deletions
+79
View File
@@ -3,6 +3,22 @@ declare global {
CrazyGames?: {
SDK: {
init: () => Promise<void>;
user: {
getUser(): Promise<{
username: string;
profilePictureUrl: string;
} | null>;
};
ad: {
requestAd: (
adType: string,
callbacks: {
adStarted: () => void;
adFinished: () => void;
adError: (error: any) => void;
},
) => void;
};
game: {
gameplayStart: () => Promise<void>;
gameplayStop: () => Promise<void>;
@@ -15,6 +31,7 @@ declare global {
}) => string;
hideInviteButton: () => void;
getInviteParam: (paramName: string) => string | null;
isInstantMultiplayer?: boolean;
};
};
};
@@ -24,6 +41,24 @@ declare global {
export class CrazyGamesSDK {
private initialized = false;
private isGameplayActive = false;
private readyPromise: Promise<void>;
private resolveReady!: () => void;
constructor() {
this.readyPromise = new Promise((resolve) => {
this.resolveReady = resolve;
});
}
async ready(): Promise<boolean> {
const timeout = new Promise<boolean>((resolve) => {
setTimeout(() => resolve(false), 3000);
});
const ready = this.readyPromise.then(() => true);
return Promise.race([ready, timeout]);
}
isOnCrazyGames(): boolean {
try {
@@ -70,12 +105,29 @@ 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<string | null> {
const isReady = await this.ready();
if (!isReady) {
return null;
}
return (await window.CrazyGames!.SDK.user.getUser())?.username ?? null;
}
async isInstantMultiplayer(): Promise<boolean> {
const isReady = await this.ready();
if (!isReady) {
return false;
}
return window.CrazyGames!.SDK.game.isInstantMultiplayer ?? false;
}
async gameplayStart(): Promise<void> {
if (!this.isReady()) {
return;
@@ -200,6 +252,33 @@ export class CrazyGamesSDK {
return null;
}
}
requestMidgameAd(): Promise<void> {
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();
+12 -3
View File
@@ -103,6 +103,7 @@ class Client {
private patternsModal: TerritoryPatternsModal;
private tokenLoginModal: TokenLoginModal;
private matchmakingModal: MatchmakingModal;
private hostModal: HostPrivateLobbyModal;
private gutterAds: GutterAds;
@@ -305,17 +306,17 @@ class Client {
settingsModal.open();
});
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");
if (hostLobbyButton === null) throw new Error("Missing host-lobby-button");
hostLobbyButton.addEventListener("click", () => {
if (this.usernameInput?.isValid()) {
hostModal.open();
this.hostModal.open();
this.publicLobby.leaveLobby();
}
});
@@ -390,6 +391,14 @@ class Client {
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 = () =>
+3
View File
@@ -23,6 +23,7 @@ import "./components/baseComponents/Modal";
import "./components/Difficulties";
import "./components/Maps";
import { fetchCosmetics } from "./Cosmetics";
import { crazyGamesSDK } from "./CrazyGamesSDK";
import { FlagInput } from "./FlagInput";
import { JoinLobbyEvent } from "./Main";
import { UsernameInput } from "./UsernameInput";
@@ -547,6 +548,8 @@ export class SinglePlayerModal extends LitElement {
const selectedColor = this.userSettings.getSelectedColor();
await crazyGamesSDK.requestMidgameAd();
this.dispatchEvent(
new CustomEvent("join-lobby", {
detail: {
+10 -2
View File
@@ -6,6 +6,7 @@ import {
MAX_USERNAME_LENGTH,
validateUsername,
} from "../core/validations/username";
import { crazyGamesSDK } from "./CrazyGamesSDK";
const usernameKey: string = "username";
@@ -28,7 +29,7 @@ export class UsernameInput extends LitElement {
connectedCallback() {
super.connectedCallback();
this.username = this.getStoredUsername();
this.username = this.getUsername();
}
render() {
@@ -66,7 +67,14 @@ export class UsernameInput extends LitElement {
}
}
private getStoredUsername(): string {
private getUsername(): string {
crazyGamesSDK.getUsername().then((username) => {
if (username) {
this.username = username;
this.requestUpdate();
}
return null;
});
const storedUsername = localStorage.getItem(usernameKey);
if (storedUsername) {
return storedUsername;
+10 -5
View File
@@ -96,10 +96,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 PauseGameEvent(this.isPaused));
}
private onExitButtonClick() {
private async onExitButtonClick() {
const isAlive = this.game.myPlayer()?.isAlive();
if (isAlive) {
const isConfirmed = confirm(
@@ -107,10 +112,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() {
+8 -1
View File
@@ -13,6 +13,7 @@ import treeIcon from "../../../../resources/images/TreeIconWhite.svg";
import musicIcon from "../../../../resources/images/music.svg";
import { EventBus } from "../../../core/EventBus";
import { UserSettings } from "../../../core/game/UserSettings";
import { crazyGamesSDK } from "../../CrazyGamesSDK";
import { AlternateViewEvent, RefreshGraphicsEvent } from "../../InputHandler";
import { PauseGameEvent } from "../../Transport";
import { translateText } from "../../Utils";
@@ -106,8 +107,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 PauseGameEvent(pause));
}
}
private onTerrainButtonClick() {
+1 -1
View File
@@ -130,7 +130,7 @@ export class UnitDisplay extends LitElement implements Layer {
return html`
<div
class="hidden 2xl:flex lg:flex fixed bottom-4 left-1/2 transform -translate-x-1/2 z-[1100] 2xl:flex-row xl:flex-col lg:flex-col 2xl:gap-5 xl:gap-2 lg:gap-2 justify-center items-center"
class="hidden min-[1200px]:flex fixed bottom-4 left-1/2 transform -translate-x-1/2 z-[1100] 2xl:flex-row xl:flex-col min-[1200px]:flex-col 2xl:gap-5 xl:gap-2 min-[1200px]:gap-2 justify-center items-center"
>
<div class="bg-gray-800/70 backdrop-blur-sm rounded-lg p-0.5">
<div class="grid grid-rows-1 auto-cols-max grid-flow-col gap-1 w-fit">
+3
View File
@@ -302,6 +302,7 @@ export class WinModal extends LitElement implements Layer {
this.isWin = false;
}
this.show();
crazyGamesSDK.gameplayStop();
} else {
const winner = this.game.playerByClientID(wu.winner[1]);
if (!winner?.isPlayer()) return;
@@ -318,6 +319,7 @@ export class WinModal extends LitElement implements Layer {
this._title = translateText("win_modal.you_won");
this.isWin = true;
crazyGamesSDK.happytime();
crazyGamesSDK.gameplayStop();
} else {
this._title = translateText("win_modal.other_won", {
player: winner.name(),
@@ -325,6 +327,7 @@ export class WinModal extends LitElement implements Layer {
this.isWin = false;
}
this.show();
crazyGamesSDK.gameplayStop();
}
});
}
+1 -1
View File
@@ -86,7 +86,7 @@ export CLOUDFLARE_TUNNEL_TOKEN=${TUNNEL_TOKEN}
# Start supervisord
if [ "$DOMAIN" = openfront.dev ] && [ "$SUBDOMAIN" != main ]; then
exec timeout 18h /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
else
exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
fi