allow brackets in names

This commit is contained in:
Evan
2025-02-09 11:16:08 -08:00
parent 8d690c0130
commit 963daefdeb
4 changed files with 37 additions and 47 deletions
+14 -24
View File
@@ -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;
+2 -2
View File
@@ -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()
+20 -20
View File
@@ -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<TileRef>,
borderTiles: ReadonlySet<TileRef>
): { min: Cell; max: Cell } {
let minX = Infinity,
minY = Infinity,
@@ -163,18 +163,18 @@ export function calculateBoundingBox(
export function calculateBoundingBoxCenter(
gm: GameMap,
borderTiles: ReadonlySet<TileRef>,
borderTiles: ReadonlySet<TileRef>
): 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>): 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(
/<img/g,
'<img style="height: 1.2em; width: 1.2em; vertical-align: -0.2em; margin: 0 0.05em 0 0.1em;"',
'<img style="height: 1.2em; width: 1.2em; vertical-align: -0.2em; margin: 0 0.05em 0 0.1em;"'
);
// Sanitize the final HTML, allowing styles and specific attributes
@@ -262,7 +262,7 @@ export function CreateGameRecord(
turns: Turn[],
start: number,
end: number,
winner: ClientID | null,
winner: ClientID | null
): GameRecord {
const record: GameRecord = {
id: id,
@@ -289,7 +289,7 @@ export function CreateGameRecord(
}
record.players = players;
record.durationSeconds = Math.floor(
(record.endTimestampMS - record.startTimestampMS) / 1000,
(record.endTimestampMS - record.startTimestampMS) / 1000
);
record.num_turns = turns.length;
record.winner = winner;
@@ -303,7 +303,7 @@ export function assertNever(x: never): never {
export function generateID(): GameID {
const nanoid = customAlphabet(
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
8,
8
);
return nanoid();
}
+1 -1
View File
@@ -13,7 +13,7 @@ const matcher = new RegExpMatcher({
export const MIN_USERNAME_LENGTH = 3;
export const MAX_USERNAME_LENGTH = 20;
const validPattern = /^[a-zA-Z0-9_ ]+$/;
const validPattern = /^[a-zA-Z0-9_\[\] ]+$/;
const shadowNames = [
"NicePeopleOnly",