From 963daefdebb88ce69e0298110a7573426fdb4d00 Mon Sep 17 00:00:00 2001 From: Evan Date: Sun, 9 Feb 2025 11:16:08 -0800 Subject: [PATCH] allow brackets in names --- src/client/graphics/layers/NameLayer.ts | 38 +++++++++-------------- src/core/Schemas.ts | 4 +-- src/core/Util.ts | 40 ++++++++++++------------- src/core/validations/username.ts | 2 +- 4 files changed, 37 insertions(+), 47 deletions(-) diff --git a/src/client/graphics/layers/NameLayer.ts b/src/client/graphics/layers/NameLayer.ts index 45ff67ed6..2161ff4be 100644 --- a/src/client/graphics/layers/NameLayer.ts +++ b/src/client/graphics/layers/NameLayer.ts @@ -25,7 +25,7 @@ class RenderInfo { public lastRenderCalc: number, public location: Cell, public fontSize: number, - public element: HTMLElement, + public element: HTMLElement ) {} } @@ -49,7 +49,7 @@ export class NameLayer implements Layer { private game: GameView, private theme: Theme, private transformHandler: TransformHandler, - private clientID: ClientID, + private clientID: ClientID ) { this.traitorIconImage = new Image(); this.traitorIconImage.src = traitorIcon; @@ -100,13 +100,7 @@ export class NameLayer implements Layer { if (!this.seenPlayers.has(player)) { this.seenPlayers.add(player); this.renders.push( - new RenderInfo( - player, - 0, - null, - 0, - this.createPlayerElement(player), - ), + new RenderInfo(player, 0, null, 0, this.createPlayerElement(player)) ); } } @@ -115,11 +109,11 @@ export class NameLayer implements Layer { public renderLayer(mainContex: CanvasRenderingContext2D) { const screenPosOld = this.transformHandler.worldToScreenCoordinates( - new Cell(0, 0), + new Cell(0, 0) ); const screenPos = new Cell( screenPosOld.x - window.innerWidth / 2, - screenPosOld.y - window.innerHeight / 2, + screenPosOld.y - window.innerHeight / 2 ); this.container.style.transform = `translate(${screenPos.x}px, ${screenPos.y}px) scale(${this.transformHandler.scale})`; @@ -136,7 +130,7 @@ export class NameLayer implements Layer { 0, 0, mainContex.canvas.width, - mainContex.canvas.height, + mainContex.canvas.height ); } @@ -191,7 +185,7 @@ export class NameLayer implements Layer { const oldLocation = render.location; render.location = new Cell( render.player.nameLocation().x, - render.player.nameLocation().y, + render.player.nameLocation().y ); // Calculate base size and scale @@ -230,7 +224,7 @@ export class NameLayer implements Layer { if (render.player === this.firstPlace) { if (!existingCrown) { iconsDiv.appendChild( - this.createIconElement(this.crownIconImage.src, iconSize, "crown"), + this.createIconElement(this.crownIconImage.src, iconSize, "crown") ); } } else if (existingCrown) { @@ -242,11 +236,7 @@ export class NameLayer implements Layer { if (render.player.isTraitor()) { if (!existingTraitor) { iconsDiv.appendChild( - this.createIconElement( - this.traitorIconImage.src, - iconSize, - "traitor", - ), + this.createIconElement(this.traitorIconImage.src, iconSize, "traitor") ); } } else if (existingTraitor) { @@ -261,8 +251,8 @@ export class NameLayer implements Layer { this.createIconElement( this.allianceIconImage.src, iconSize, - "alliance", - ), + "alliance" + ) ); } } else if (existingAlliance) { @@ -277,7 +267,7 @@ export class NameLayer implements Layer { ) { if (!existingTarget) { iconsDiv.appendChild( - this.createIconElement(this.targetIconImage.src, iconSize, "target"), + this.createIconElement(this.targetIconImage.src, iconSize, "target") ); } } else if (existingTarget) { @@ -291,7 +281,7 @@ export class NameLayer implements Layer { .filter( (emoji) => emoji.recipientID == AllPlayers || - emoji.recipientID == myPlayer?.smallID(), + emoji.recipientID == myPlayer?.smallID() ); if (emojis.length > 0) { @@ -324,7 +314,7 @@ export class NameLayer implements Layer { private createIconElement( src: string, size: number, - id: string, + id: string ): HTMLImageElement { const icon = document.createElement("img"); icon.src = src; diff --git a/src/core/Schemas.ts b/src/core/Schemas.ts index 9abd1f3e4..c5ad90aca 100644 --- a/src/core/Schemas.ts +++ b/src/core/Schemas.ts @@ -96,7 +96,7 @@ const GameConfigSchema = z.object({ const SafeString = z .string() // Remove common dangerous characters and patterns - .regex(/^[a-zA-Z0-9\s.,!?@#$%&*()-_+=[\]{}|;:"'\/]+$/) + .regex(/^[a-zA-Z0-9\s.,!?@#$%&*()-_+=\[\]{}|;:"'\/]+$/) // Reasonable max length to prevent DOS .max(1000); @@ -106,7 +106,7 @@ const EmojiSchema = z.string().refine( }, { message: "Must contain at least one emoji character", - }, + } ); const ID = z .string() diff --git a/src/core/Util.ts b/src/core/Util.ts index 109c9d770..a31bdb7f5 100644 --- a/src/core/Util.ts +++ b/src/core/Util.ts @@ -16,7 +16,7 @@ import { andFN, GameMap, manhattanDistFN, TileRef } from "./game/GameMap"; export function manhattanDistWrapped( c1: Cell, c2: Cell, - width: number, + width: number ): number { // Calculate x distance let dx = Math.abs(c1.x - c2.x); @@ -36,7 +36,7 @@ export function within(value: number, min: number, max: number): number { export function distSort( gm: GameMap, - target: TileRef, + target: TileRef ): (a: TileRef, b: TileRef) => number { return (a: TileRef, b: TileRef) => { return gm.manhattanDist(a, target) - gm.manhattanDist(b, target); @@ -45,7 +45,7 @@ export function distSort( export function distSortUnit( gm: GameMap, - target: Unit | TileRef, + target: Unit | TileRef ): (a: Unit, b: Unit) => number { const targetRef = typeof target === "number" ? target : target.tile(); @@ -61,7 +61,7 @@ export function distSortUnit( export function sourceDstOceanShore( gm: Game, src: Player, - tile: TileRef, + tile: TileRef ): [TileRef | null, TileRef | null] { const dst = gm.owner(tile); let srcTile = closestOceanShoreFromPlayer(gm, src, tile); @@ -88,10 +88,10 @@ export function targetTransportTile(gm: Game, tile: TileRef): TileRef | null { export function closestOceanShoreFromPlayer( gm: GameMap, player: Player, - target: TileRef, + target: TileRef ): TileRef | null { const shoreTiles = Array.from(player.borderTiles()).filter((t) => - gm.isOceanShore(t), + gm.isOceanShore(t) ); if (shoreTiles.length == 0) { return null; @@ -101,12 +101,12 @@ export function closestOceanShoreFromPlayer( const closestDistance = manhattanDistWrapped( gm.cell(target), gm.cell(closest), - gm.width(), + gm.width() ); const currentDistance = manhattanDistWrapped( gm.cell(target), gm.cell(current), - gm.width(), + gm.width() ); return currentDistance < closestDistance ? current : closest; }); @@ -115,13 +115,13 @@ export function closestOceanShoreFromPlayer( function closestOceanShoreTN( gm: GameMap, tile: TileRef, - searchDist: number, + searchDist: number ): TileRef { const tn = Array.from( gm.bfs( tile, - andFN((_, t) => !gm.hasOwner(t), manhattanDistFN(tile, searchDist)), - ), + andFN((_, t) => !gm.hasOwner(t), manhattanDistFN(tile, searchDist)) + ) ) .filter((t) => gm.isOceanShore(t)) .sort((a, b) => gm.manhattanDist(tile, a) - gm.manhattanDist(tile, b)); @@ -143,7 +143,7 @@ export function simpleHash(str: string): number { export function calculateBoundingBox( gm: GameMap, - borderTiles: ReadonlySet, + borderTiles: ReadonlySet ): { min: Cell; max: Cell } { let minX = Infinity, minY = Infinity, @@ -163,18 +163,18 @@ export function calculateBoundingBox( export function calculateBoundingBoxCenter( gm: GameMap, - borderTiles: ReadonlySet, + borderTiles: ReadonlySet ): Cell { const { min, max } = calculateBoundingBox(gm, borderTiles); return new Cell( min.x + Math.floor((max.x - min.x) / 2), - min.y + Math.floor((max.y - min.y) / 2), + min.y + Math.floor((max.y - min.y) / 2) ); } export function inscribed( outer: { min: Cell; max: Cell }, - inner: { min: Cell; max: Cell }, + inner: { min: Cell; max: Cell } ): boolean { return ( outer.min.x <= inner.min.x && @@ -208,7 +208,7 @@ export function getMode(list: Set): number { export function sanitize(name: string): string { return Array.from(name) .join("") - .replace(/[^\p{L}\p{N}\s\p{Emoji}\p{Emoji_Component}]/gu, ""); + .replace(/[^\p{L}\p{N}\s\p{Emoji}\p{Emoji_Component}\[\]]/gu, ""); } export function processName(name: string): string { @@ -238,7 +238,7 @@ export function processName(name: string): string { // Add CSS for the emoji images const withEmojiStyles = styledHTML.replace( /