Files
OpenFrontIO/src/client/Main.ts
T
2025-02-01 12:05:11 -08:00

143 lines
4.8 KiB
TypeScript

import { ClientGameRunner, joinLobby } from "./ClientGameRunner";
import backgroundImage from '../../resources/images/TerrainMapFrontPage.png';
import favicon from '../../resources/images/Favicon.svg';
import './PublicLobby';
import './UsernameInput';
import './styles.css';
import { UsernameInput } from "./UsernameInput";
import { SinglePlayerModal } from "./SinglePlayerModal";
import { HostLobbyModal as HostPrivateLobbyModal } from "./HostLobbyModal";
import { JoinPrivateLobbyModal } from "./JoinPrivateLobbyModal";
import { generateID } from "../core/Util";
import { generateCryptoRandomUUID } from "./Utils";
import { consolex } from "../core/Consolex";
class Client {
private gameStop: () => void
private usernameInput: UsernameInput | null = null;
private joinModal: JoinPrivateLobbyModal
constructor() {
}
initialize(): void {
this.usernameInput = document.querySelector('username-input') as UsernameInput;
if (!this.usernameInput) {
consolex.warn('Username input element not found');
}
window.addEventListener('beforeunload', (event) => {
consolex.log('Browser is closing');
if (this.gameStop != null) {
this.gameStop()
}
});
setFavicon()
document.addEventListener('join-lobby', this.handleJoinLobby.bind(this));
document.addEventListener('leave-lobby', this.handleLeaveLobby.bind(this));
document.addEventListener('single-player', this.handleSinglePlayer.bind(this));
const spModal = document.querySelector('single-player-modal') as SinglePlayerModal;
spModal instanceof SinglePlayerModal
document.getElementById('single-player').addEventListener('click', () => {
if (this.usernameInput.isValid()) {
spModal.open();
}
})
const hostModal = document.querySelector('host-lobby-modal') as HostPrivateLobbyModal;
hostModal instanceof HostPrivateLobbyModal
document.getElementById('host-lobby-button').addEventListener('click', () => {
if (this.usernameInput.isValid()) {
hostModal.open();
}
})
this.joinModal = document.querySelector('join-private-lobby-modal') as JoinPrivateLobbyModal;
this.joinModal instanceof JoinPrivateLobbyModal
document.getElementById('join-private-lobby-button').addEventListener('click', () => {
if (this.usernameInput.isValid()) {
this.joinModal.open();
}
})
}
private async handleJoinLobby(event: CustomEvent) {
const lobby = event.detail.lobby
consolex.log(`joining lobby ${lobby.id}`)
if (this.gameStop != null) {
consolex.log('joining lobby, stopping existing game')
this.gameStop()
}
this.gameStop = joinLobby(
{
gameType: event.detail.gameType,
playerName: (): string => this.usernameInput.getCurrentUsername(),
gameID: lobby.id,
persistentID: getPersistentIDFromCookie(),
playerID: generateID(),
clientID: generateID(),
map: event.detail.map,
difficulty: event.detail.difficulty,
},
() => this.joinModal.close()
);
}
private async handleLeaveLobby(event: CustomEvent) {
if (this.gameStop == null) {
return
}
consolex.log('leaving lobby, cancelling game')
this.gameStop()
this.gameStop = null
}
private async handleSinglePlayer(event: CustomEvent) {
alert('coming soon')
}
}
// Initialize the client when the DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
new Client().initialize();
});
document.body.style.backgroundImage = `url(${backgroundImage})`;
function setFavicon(): void {
const link = document.createElement('link');
link.type = 'image/x-icon';
link.rel = 'shortcut icon';
link.href = favicon;
document.head.appendChild(link);
}
// WARNING: DO NOT EXPOSE THIS ID
export function getPersistentIDFromCookie(): string {
const COOKIE_NAME = 'player_persistent_id'
// Try to get existing cookie
const cookies = document.cookie.split(';')
for (let cookie of cookies) {
const [cookieName, cookieValue] = cookie.split('=').map(c => c.trim())
if (cookieName === COOKIE_NAME) {
return cookieValue
}
}
// If no cookie exists, create new ID and set cookie
const newID = generateCryptoRandomUUID()
document.cookie = [
`${COOKIE_NAME}=${newID}`,
`max-age=${5 * 365 * 24 * 60 * 60}`, // 5 years
'path=/',
'SameSite=Strict',
'Secure'
].join(';')
return newID
}