crazygames

This commit is contained in:
evanpelle
2026-01-14 13:24:06 -08:00
parent e1d31ef1ee
commit dfc3b359cf
9 changed files with 125 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();
+11 -2
View File
@@ -214,6 +214,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();
@@ -522,10 +523,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");
@@ -641,6 +642,14 @@ class Client {
return;
}
}
crazyGamesSDK.isInstantMultiplayer().then((isInstant) => {
if (isInstant) {
console.log(
`CrazyGames: joining instant multiplayer lobby from CrazyGames`,
);
this.hostModal.open();
}
});
const strip = () =>
history.replaceState(
+3
View File
@@ -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";
@@ -839,6 +840,8 @@ export class SinglePlayerModal extends BaseModal {
const selectedColor = this.userSettings.getSelectedColor();
await crazyGamesSDK.requestMidgameAd();
this.dispatchEvent(
new CustomEvent("join-lobby", {
detail: {
+10 -2
View File
@@ -8,6 +8,7 @@ import {
MIN_USERNAME_LENGTH,
validateUsername,
} from "../core/validations/username";
import { crazyGamesSDK } from "./CrazyGamesSDK";
const usernameKey: string = "username";
@@ -39,7 +40,7 @@ export class UsernameInput extends LitElement {
connectedCallback() {
super.connectedCallback();
const stored = this.getStoredUsername();
const stored = this.getUsername();
this.parseAndSetUsername(stored);
}
@@ -161,7 +162,14 @@ export class UsernameInput extends LitElement {
}
}
private getStoredUsername(): string {
private getUsername(): string {
crazyGamesSDK.getUsername().then((username) => {
if (username) {
this.baseUsername = username;
this.requestUpdate();
}
return null;
});
const storedUsername = localStorage.getItem(usernameKey);
if (storedUsername) {
return storedUsername;
+10 -5
View File
@@ -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() {
+9 -2
View File
@@ -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() {
+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-xs rounded-lg p-0.5">
<div class="grid grid-rows-1 auto-cols-max grid-flow-col gap-1 w-fit">
+1
View File
@@ -250,6 +250,7 @@ export class WinModal extends LitElement implements Layer {
}
async show() {
crazyGamesSDK.gameplayStop();
await this.loadPatternContent();
this.isVisible = true;
this.requestUpdate();
+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