mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 14:00:54 +00:00
replaces player names with randomized name (#340)
This PR replaces player names with randomized name The goal is to reduce exposure to inappropriate or offensive names. Additionally, content creators no longer need to worry about displaying other players’ usernames. <img width="1276" alt="スクリーンショット 2025-03-25 23 03 37" src="https://github.com/user-attachments/assets/3d396bb0-336f-41a0-8d56-ff5229fe05f8" /> <img width="1048" alt="スクリーンショット 2025-03-25 23 03 48" src="https://github.com/user-attachments/assets/a72711cf-9743-4879-8f2f-b8187b10a272" /> Use the upper left button (Ninja) to change settings. <img width="1173" alt="スクリーンショット 2025-03-25 23 04 03" src="https://github.com/user-attachments/assets/2d2fcbbd-7342-40b0-97c1-ecc184e5fbb6" /> Fixes #489 --------- Co-authored-by: evanpelle <evanpelle@gmail.com>
This commit is contained in:
@@ -21,6 +21,8 @@ import { LangSelector } from "./LangSelector";
|
||||
import { LanguageModal } from "./LanguageModal";
|
||||
import "./PublicLobby";
|
||||
import { PublicLobby } from "./PublicLobby";
|
||||
import "./RandomNameButton";
|
||||
import { RandomNameButton } from "./RandomNameButton";
|
||||
import { SinglePlayerModal } from "./SinglePlayerModal";
|
||||
import { UserSettingModal } from "./UserSettingModal";
|
||||
import "./UsernameInput";
|
||||
@@ -46,6 +48,7 @@ class Client {
|
||||
private usernameInput: UsernameInput | null = null;
|
||||
private flagInput: FlagInput | null = null;
|
||||
private darkModeButton: DarkModeButton | null = null;
|
||||
private randomNameButton: RandomNameButton | null = null;
|
||||
|
||||
private joinModal: JoinPrivateLobbyModal;
|
||||
private publicLobby: PublicLobby;
|
||||
@@ -80,6 +83,13 @@ class Client {
|
||||
consolex.warn("Dark mode button element not found");
|
||||
}
|
||||
|
||||
this.randomNameButton = document.querySelector(
|
||||
"random-name-button",
|
||||
) as RandomNameButton;
|
||||
if (!this.randomNameButton) {
|
||||
consolex.warn("Random name button element not found");
|
||||
}
|
||||
|
||||
this.usernameInput = document.querySelector(
|
||||
"username-input",
|
||||
) as UsernameInput;
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { LitElement, html } from "lit";
|
||||
import { customElement, state } from "lit/decorators.js";
|
||||
import { UserSettings } from "../core/game/UserSettings";
|
||||
|
||||
@customElement("random-name-button")
|
||||
export class RandomNameButton extends LitElement {
|
||||
private userSettings: UserSettings = new UserSettings();
|
||||
@state() private randomName: boolean = this.userSettings.anonymousNames();
|
||||
|
||||
createRenderRoot() {
|
||||
return this;
|
||||
}
|
||||
|
||||
toggleRandomName() {
|
||||
this.userSettings.toggleRandomName();
|
||||
this.randomName = this.userSettings.anonymousNames();
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<button
|
||||
title="Random Name"
|
||||
class="absolute top-0 left-0 md:top-[10px] md:left-[10px] border-none bg-none cursor-pointer text-2xl"
|
||||
@click=${() => this.toggleRandomName()}
|
||||
>
|
||||
${this.randomName ? "🥷" : "🕵️"}
|
||||
</button>
|
||||
`;
|
||||
}
|
||||
}
|
||||
@@ -195,6 +195,7 @@ export class NameLayer implements Layer {
|
||||
nameDiv.style.alignItems = "center";
|
||||
|
||||
const nameSpan = document.createElement("span");
|
||||
nameSpan.className = "player-name-span";
|
||||
nameSpan.innerHTML = player.name();
|
||||
nameDiv.appendChild(nameSpan);
|
||||
element.appendChild(nameDiv);
|
||||
@@ -262,6 +263,10 @@ export class NameLayer implements Layer {
|
||||
nameDiv.style.fontSize = `${render.fontSize}px`;
|
||||
nameDiv.style.lineHeight = `${render.fontSize}px`;
|
||||
nameDiv.style.color = render.fontColor;
|
||||
const span = nameDiv.querySelector(".player-name-span");
|
||||
if (span) {
|
||||
span.innerHTML = render.player.name();
|
||||
}
|
||||
if (flagDiv) {
|
||||
flagDiv.style.height = `${render.fontSize}px`;
|
||||
}
|
||||
|
||||
@@ -106,6 +106,10 @@ export class OptionsMenu extends LitElement implements Layer {
|
||||
this.eventBus.emit(new RefreshGraphicsEvent());
|
||||
}
|
||||
|
||||
private onToggleRandomNameModeButtonClick() {
|
||||
this.userSettings.toggleRandomName();
|
||||
}
|
||||
|
||||
private onToggleFocusLockedButtonClick() {
|
||||
this.userSettings.toggleFocusLocked();
|
||||
this.requestUpdate();
|
||||
@@ -196,6 +200,12 @@ export class OptionsMenu extends LitElement implements Layer {
|
||||
title: "Dark Mode",
|
||||
children: "🌙: " + (this.userSettings.darkMode() ? "On" : "Off"),
|
||||
})}
|
||||
${button({
|
||||
onClick: this.onToggleRandomNameModeButtonClick,
|
||||
title: "Random name mode",
|
||||
children:
|
||||
"🥷: " + (this.userSettings.anonymousNames() ? "On" : "Off"),
|
||||
})}
|
||||
${button({
|
||||
onClick: this.onToggleLeftClickOpensMenu,
|
||||
title: "Left click",
|
||||
|
||||
@@ -208,6 +208,9 @@
|
||||
</header>
|
||||
<div class="bg-image"></div>
|
||||
|
||||
<random-name-button></random-name-button>
|
||||
|
||||
<dark-mode-button></dark-mode-button>
|
||||
<!-- Main container with responsive padding -->
|
||||
<main class="flex justify-center flex-grow">
|
||||
<div class="container pt-12">
|
||||
|
||||
@@ -13,6 +13,11 @@ import {
|
||||
Turn,
|
||||
} from "./Schemas";
|
||||
|
||||
import {
|
||||
BOT_NAME_PREFIXES,
|
||||
BOT_NAME_SUFFIXES,
|
||||
} from "./execution/utils/BotNames";
|
||||
|
||||
export function manhattanDistWrapped(
|
||||
c1: Cell,
|
||||
c2: Cell,
|
||||
@@ -286,3 +291,19 @@ export function withinInt(num: bigint, min: bigint, max: bigint): bigint {
|
||||
const atLeastMin = maxInt(num, min);
|
||||
return minInt(atLeastMin, max);
|
||||
}
|
||||
|
||||
export function createRandomName(
|
||||
name: string,
|
||||
playerType: string,
|
||||
): string | null {
|
||||
let randomName = null;
|
||||
if (playerType === "HUMAN") {
|
||||
const hash = simpleHash(name);
|
||||
const prefixIndex = hash % BOT_NAME_PREFIXES.length;
|
||||
const suffixIndex =
|
||||
Math.floor(hash / BOT_NAME_PREFIXES.length) % BOT_NAME_SUFFIXES.length;
|
||||
|
||||
randomName = `👤 ${BOT_NAME_PREFIXES[prefixIndex]} ${BOT_NAME_SUFFIXES[suffixIndex]}`;
|
||||
}
|
||||
return randomName;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Config } from "../configuration/Config";
|
||||
import { ClientID, GameID, PlayerStats } from "../Schemas";
|
||||
import { createRandomName } from "../Util";
|
||||
import { WorkerClient } from "../worker/WorkerClient";
|
||||
import {
|
||||
Cell,
|
||||
@@ -123,11 +124,22 @@ export class UnitView {
|
||||
}
|
||||
|
||||
export class PlayerView {
|
||||
public anonymousName: string;
|
||||
|
||||
constructor(
|
||||
private game: GameView,
|
||||
public data: PlayerUpdate,
|
||||
public nameData: NameViewData,
|
||||
) {}
|
||||
) {
|
||||
if (data.clientID == game.myClientID()) {
|
||||
this.anonymousName = this.data.name;
|
||||
} else {
|
||||
this.anonymousName = createRandomName(
|
||||
this.data.name,
|
||||
this.data.playerType,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async actions(tile: TileRef): Promise<PlayerActions> {
|
||||
return this.game.worker.playerInteraction(
|
||||
@@ -166,11 +178,16 @@ export class PlayerView {
|
||||
return this.data.flag;
|
||||
}
|
||||
name(): string {
|
||||
return this.data.name;
|
||||
return userSettings.anonymousNames() && this.anonymousName !== null
|
||||
? this.anonymousName
|
||||
: this.data.name;
|
||||
}
|
||||
displayName(): string {
|
||||
return this.data.displayName;
|
||||
return userSettings.anonymousNames() && this.anonymousName !== null
|
||||
? this.anonymousName
|
||||
: this.data.name;
|
||||
}
|
||||
|
||||
clientID(): ClientID {
|
||||
return this.data.clientID;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@ export class UserSettings {
|
||||
emojis() {
|
||||
return this.get("settings.emojis", true);
|
||||
}
|
||||
anonymousNames() {
|
||||
return this.get("settings.anonymousNames", false);
|
||||
}
|
||||
|
||||
darkMode() {
|
||||
return this.get("settings.darkMode", false);
|
||||
@@ -42,6 +45,10 @@ export class UserSettings {
|
||||
this.set("settings.emojis", !this.emojis());
|
||||
}
|
||||
|
||||
toggleRandomName() {
|
||||
this.set("settings.anonymousNames", !this.anonymousNames());
|
||||
}
|
||||
|
||||
toggleDarkMode() {
|
||||
this.set("settings.darkMode", !this.darkMode());
|
||||
if (this.darkMode()) {
|
||||
|
||||
Reference in New Issue
Block a user