mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 09:10:42 +00:00
Enable @typescript eslint/prefer nullish coalescing eslint rule (#1420)
## Description: Fixes #952 Enabled @typescript-eslint/prefer-nullish-coalescing rule and worked through every error, introducing ?? and ??= operators or disabling errors with inline comments where appropriate, to the best of my ability. ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced - [x] I understand that submitting code with bugs that could have been caught through manual testing blocks releases and new features for all contributors ## Please put your Discord username so you can be contacted if a bug or regression is found: g_santos_m
This commit is contained in:
@@ -19,6 +19,23 @@ export default [
|
||||
pluginJs.configs.recommended,
|
||||
...tseslint.configs.recommended,
|
||||
eslintConfigPrettier,
|
||||
{
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
projectService: {
|
||||
allowDefaultProject: [
|
||||
"__mocks__/fileMock.js",
|
||||
"eslint.config.js",
|
||||
"jest.config.ts",
|
||||
"postcss.config.js",
|
||||
"tailwind.config.js",
|
||||
"webpack.config.js",
|
||||
],
|
||||
},
|
||||
tsconfigRootDir: import.meta.dirname,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
rules: {
|
||||
// Disable rules that would fail. The failures should be fixed, and the entries here removed.
|
||||
@@ -34,6 +51,7 @@ export default [
|
||||
{
|
||||
rules: {
|
||||
// Enable rules
|
||||
"@typescript-eslint/prefer-nullish-coalescing": "error",
|
||||
eqeqeq: "error",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -99,7 +99,7 @@ export class LangSelector extends LitElement {
|
||||
private async initializeLanguage() {
|
||||
const browserLocale = navigator.language;
|
||||
const savedLang = localStorage.getItem("lang");
|
||||
const userLang = this.getClosestSupportedLang(savedLang || browserLocale);
|
||||
const userLang = this.getClosestSupportedLang(savedLang ?? browserLocale);
|
||||
|
||||
this.defaultTranslations = this.loadLanguage("en");
|
||||
this.translations = this.loadLanguage(userLang);
|
||||
@@ -110,7 +110,7 @@ export class LangSelector extends LitElement {
|
||||
}
|
||||
|
||||
private loadLanguage(lang: string): Record<string, string> {
|
||||
const language = this.languageMap[lang] || {};
|
||||
const language = this.languageMap[lang] ?? {};
|
||||
const flat = flattenTranslations(language);
|
||||
return flat;
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ export class PublicLobby extends LitElement {
|
||||
|
||||
const teamCount =
|
||||
lobby.gameConfig.gameMode === GameMode.Team
|
||||
? lobby.gameConfig.playerTeams || 0
|
||||
? (lobby.gameConfig.playerTeams ?? 0)
|
||||
: null;
|
||||
|
||||
const mapImageSrc = this.mapImages.get(lobby.gameID);
|
||||
|
||||
+8
-10
@@ -245,16 +245,14 @@ export class Transport {
|
||||
}
|
||||
|
||||
private startPing() {
|
||||
if (this.isLocal || this.pingInterval) return;
|
||||
if (this.pingInterval === null) {
|
||||
this.pingInterval = window.setInterval(() => {
|
||||
if (this.socket !== null && this.socket.readyState === WebSocket.OPEN) {
|
||||
this.sendMsg({
|
||||
type: "ping",
|
||||
} satisfies ClientPingMessage);
|
||||
}
|
||||
}, 5 * 1000);
|
||||
}
|
||||
if (this.isLocal) return;
|
||||
this.pingInterval ??= window.setInterval(() => {
|
||||
if (this.socket !== null && this.socket.readyState === WebSocket.OPEN) {
|
||||
this.sendMsg({
|
||||
type: "ping",
|
||||
} satisfies ClientPingMessage);
|
||||
}
|
||||
}, 5 * 1000);
|
||||
}
|
||||
|
||||
private stopPing() {
|
||||
|
||||
+1
-1
@@ -172,7 +172,7 @@ export function getAltKey(): string {
|
||||
|
||||
export function getGamesPlayed(): number {
|
||||
try {
|
||||
return parseInt(localStorage.getItem("gamesPlayed") || "0", 10) || 0;
|
||||
return parseInt(localStorage.getItem("gamesPlayed") ?? "0", 10) || 0;
|
||||
} catch (error) {
|
||||
console.warn("Failed to read games played from localStorage:", error);
|
||||
return 0;
|
||||
|
||||
@@ -91,9 +91,9 @@ const getSpriteForUnit = (unit: UnitView): ImageBitmap | null => {
|
||||
const unitType = unit.type();
|
||||
if (unitType === UnitType.Train) {
|
||||
const trainType = trainTypeToSpriteType(unit);
|
||||
return spriteMap.get(trainType) || null;
|
||||
return spriteMap.get(trainType) ?? null;
|
||||
}
|
||||
return spriteMap.get(unitType) || null;
|
||||
return spriteMap.get(unitType) ?? null;
|
||||
};
|
||||
|
||||
export const isSpriteReady = (unit: UnitView): boolean => {
|
||||
|
||||
@@ -137,7 +137,7 @@ export class EventsDisplay extends LitElement implements Layer {
|
||||
}
|
||||
|
||||
private toggleEventFilter(filterName: MessageCategory) {
|
||||
const currentState = this.eventsFilters.get(filterName) || false;
|
||||
const currentState = this.eventsFilters.get(filterName) ?? false;
|
||||
this.eventsFilters.set(filterName, !currentState);
|
||||
this.requestUpdate();
|
||||
}
|
||||
|
||||
@@ -298,14 +298,14 @@ export class RadialMenu implements Layer {
|
||||
const disabled = this.params === null || d.data.disabled(this.params);
|
||||
const color = disabled
|
||||
? this.config.disabledColor
|
||||
: d.data.color || "#333333";
|
||||
: (d.data.color ?? "#333333");
|
||||
const opacity = disabled ? 0.5 : 0.7;
|
||||
|
||||
if (d.data.id === this.selectedItemId && this.currentLevel > level) {
|
||||
return color;
|
||||
}
|
||||
|
||||
return d3.color(color)?.copy({ opacity: opacity })?.toString() || color;
|
||||
return d3.color(color)?.copy({ opacity: opacity })?.toString() ?? color;
|
||||
})
|
||||
.attr("stroke", "#ffffff")
|
||||
.attr("stroke-width", "2")
|
||||
@@ -341,7 +341,7 @@ export class RadialMenu implements Layer {
|
||||
const color =
|
||||
this.params === null || d.data.disabled(this.params)
|
||||
? this.config.disabledColor
|
||||
: d.data.color || "#333333";
|
||||
: (d.data.color ?? "#333333");
|
||||
path.attr("fill", color);
|
||||
}
|
||||
});
|
||||
@@ -405,11 +405,11 @@ export class RadialMenu implements Layer {
|
||||
path.attr("stroke-width", "2");
|
||||
const color = disabled
|
||||
? this.config.disabledColor
|
||||
: d.data.color || "#333333";
|
||||
: (d.data.color ?? "#333333");
|
||||
const opacity = disabled ? 0.5 : 0.7;
|
||||
path.attr(
|
||||
"fill",
|
||||
d3.color(color)?.copy({ opacity: opacity })?.toString() || color,
|
||||
d3.color(color)?.copy({ opacity: opacity })?.toString() ?? color,
|
||||
);
|
||||
};
|
||||
|
||||
@@ -625,7 +625,7 @@ export class RadialMenu implements Layer {
|
||||
this.selectedItemId = null;
|
||||
}
|
||||
|
||||
this.currentMenuItems = previousItems || [];
|
||||
this.currentMenuItems = previousItems ?? [];
|
||||
|
||||
if (this.currentLevel === 0) {
|
||||
this.updateCenterButtonState("default");
|
||||
@@ -645,11 +645,11 @@ export class RadialMenu implements Layer {
|
||||
const disabled = this.params === null || item.disabled(this.params);
|
||||
const color = disabled
|
||||
? this.config.disabledColor
|
||||
: item.color || "#333333";
|
||||
: (item.color ?? "#333333");
|
||||
const opacity = disabled ? 0.5 : 0.7;
|
||||
selectedPath.attr(
|
||||
"fill",
|
||||
d3.color(color)?.copy({ opacity: opacity })?.toString() || color,
|
||||
d3.color(color)?.copy({ opacity: opacity })?.toString() ?? color,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,9 +352,9 @@ export const buildMenuElement: MenuElement = {
|
||||
: undefined,
|
||||
icon: item.icon,
|
||||
tooltipItems: [
|
||||
{ text: translateText(item.key || ""), className: "title" },
|
||||
{ text: translateText(item.key ?? ""), className: "title" },
|
||||
{
|
||||
text: translateText(item.description || ""),
|
||||
text: translateText(item.description ?? ""),
|
||||
className: "description",
|
||||
},
|
||||
{
|
||||
@@ -401,7 +401,7 @@ export const boatMenuElement: MenuElement = {
|
||||
|
||||
params.playerActionHandler.handleBoatAttack(
|
||||
params.myPlayer,
|
||||
params.selected?.id() || null,
|
||||
params.selected?.id() ?? null,
|
||||
params.tile,
|
||||
spawn !== false ? spawn : null,
|
||||
);
|
||||
|
||||
@@ -52,7 +52,7 @@ export class TeamStats extends LitElement implements Layer {
|
||||
for (const player of players) {
|
||||
const team = player.team();
|
||||
if (team === null) continue;
|
||||
if (!grouped[team]) grouped[team] = [];
|
||||
grouped[team] ??= [];
|
||||
grouped[team].push(player);
|
||||
}
|
||||
|
||||
|
||||
@@ -317,10 +317,16 @@ export class UILayer implements Layer {
|
||||
if (constructionType === undefined) {
|
||||
return 1;
|
||||
}
|
||||
const constDuration =
|
||||
this.game.unitInfo(constructionType).constructionDuration;
|
||||
if (constDuration === undefined) {
|
||||
throw new Error("unit does not have constructionTime");
|
||||
}
|
||||
return (
|
||||
(this.game.ticks() - unit.createdAt()) /
|
||||
(this.game.unitInfo(constructionType).constructionDuration || 1)
|
||||
(constDuration === 0 ? 1 : constDuration)
|
||||
);
|
||||
|
||||
case UnitType.MissileSilo:
|
||||
case UnitType.SAMLauncher:
|
||||
return unit.missileReadinesss();
|
||||
|
||||
+2
-3
@@ -104,9 +104,8 @@ export type IsLoggedInResponse =
|
||||
| false;
|
||||
let __isLoggedIn: IsLoggedInResponse | undefined = undefined;
|
||||
export function isLoggedIn(): IsLoggedInResponse {
|
||||
if (__isLoggedIn === undefined) {
|
||||
__isLoggedIn = _isLoggedIn();
|
||||
}
|
||||
__isLoggedIn ??= _isLoggedIn();
|
||||
|
||||
return __isLoggedIn;
|
||||
}
|
||||
function _isLoggedIn(): IsLoggedInResponse {
|
||||
|
||||
+1
-1
@@ -119,7 +119,7 @@ export function getMode(list: Set<number>): number {
|
||||
// Count occurrences
|
||||
const counts = new Map<number, number>();
|
||||
for (const item of list) {
|
||||
counts.set(item, (counts.get(item) || 0) + 1);
|
||||
counts.set(item, (counts.get(item) ?? 0) + 1);
|
||||
}
|
||||
|
||||
// Find the item with the highest count
|
||||
|
||||
@@ -97,11 +97,9 @@ export class AttackExecution implements Execution {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.startTroops === null) {
|
||||
this.startTroops = this.mg
|
||||
.config()
|
||||
.attackAmount(this._owner, this.target);
|
||||
}
|
||||
this.startTroops ??= this.mg
|
||||
.config()
|
||||
.attackAmount(this._owner, this.target);
|
||||
if (this.removeTroops) {
|
||||
this.startTroops = Math.min(this._owner.troops(), this.startTroops);
|
||||
this._owner.removeTroops(this.startTroops);
|
||||
|
||||
@@ -19,9 +19,7 @@ export class DonateGoldExecution implements Execution {
|
||||
}
|
||||
|
||||
this.recipient = mg.player(this.recipientID);
|
||||
if (this.gold === null) {
|
||||
this.gold = this.sender.gold() / 3n;
|
||||
}
|
||||
this.gold ??= this.sender.gold() / 3n;
|
||||
}
|
||||
|
||||
tick(ticks: number): void {
|
||||
|
||||
@@ -19,9 +19,7 @@ export class DonateTroopsExecution implements Execution {
|
||||
}
|
||||
|
||||
this.recipient = mg.player(this.recipientID);
|
||||
if (this.troops === null) {
|
||||
this.troops = mg.config().defaultDonationAmount(this.sender);
|
||||
}
|
||||
this.troops ??= mg.config().defaultDonationAmount(this.sender);
|
||||
const maxDonation =
|
||||
mg.config().maxPopulation(this.recipient) - this.recipient.population();
|
||||
this.troops = Math.min(this.troops, maxDonation);
|
||||
|
||||
@@ -109,9 +109,7 @@ export class SAMLauncherExecution implements Execution {
|
||||
this.player = this.sam.owner();
|
||||
}
|
||||
|
||||
if (this.pseudoRandom === undefined) {
|
||||
this.pseudoRandom = new PseudoRandom(this.sam.id());
|
||||
}
|
||||
this.pseudoRandom ??= new PseudoRandom(this.sam.id());
|
||||
|
||||
const mirvWarheadTargets = this.mg.nearbyUnits(
|
||||
this.sam.tile(),
|
||||
|
||||
@@ -31,13 +31,11 @@ export class SAMMissileExecution implements Execution {
|
||||
}
|
||||
|
||||
tick(ticks: number): void {
|
||||
if (this.SAMMissile === undefined) {
|
||||
this.SAMMissile = this._owner.buildUnit(
|
||||
UnitType.SAMMissile,
|
||||
this.spawn,
|
||||
{},
|
||||
);
|
||||
}
|
||||
this.SAMMissile ??= this._owner.buildUnit(
|
||||
UnitType.SAMMissile,
|
||||
this.spawn,
|
||||
{},
|
||||
);
|
||||
if (!this.SAMMissile.isActive()) {
|
||||
this.active = false;
|
||||
return;
|
||||
|
||||
@@ -23,9 +23,7 @@ export class ShellExecution implements Execution {
|
||||
}
|
||||
|
||||
tick(ticks: number): void {
|
||||
if (this.shell === undefined) {
|
||||
this.shell = this._owner.buildUnit(UnitType.Shell, this.spawn, {});
|
||||
}
|
||||
this.shell ??= this._owner.buildUnit(UnitType.Shell, this.spawn, {});
|
||||
if (!this.shell.isActive()) {
|
||||
this.active = false;
|
||||
return;
|
||||
|
||||
@@ -89,11 +89,9 @@ export class TransportShipExecution implements Execution {
|
||||
this.target = mg.player(this.targetID);
|
||||
}
|
||||
|
||||
if (this.troops === null) {
|
||||
this.troops = this.mg
|
||||
.config()
|
||||
.boatAttackAmount(this.attacker, this.target);
|
||||
}
|
||||
this.troops ??= this.mg
|
||||
.config()
|
||||
.boatAttackAmount(this.attacker, this.target);
|
||||
|
||||
this.troops = Math.min(this.troops, this.attacker.troops());
|
||||
|
||||
|
||||
@@ -507,9 +507,7 @@ export class GameView implements GameMap {
|
||||
}
|
||||
|
||||
myPlayer(): PlayerView | null {
|
||||
if (this._myPlayer === null) {
|
||||
this._myPlayer = this.playerByClientID(this._myClientID);
|
||||
}
|
||||
this._myPlayer ??= this.playerByClientID(this._myClientID);
|
||||
return this._myPlayer;
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ export class StatsImpl implements Stats {
|
||||
private _addAttack(player: Player, index: number, value: BigIntLike) {
|
||||
const p = this._makePlayerStats(player);
|
||||
if (p === undefined) return;
|
||||
if (p.attacks === undefined) p.attacks = [0n];
|
||||
p.attacks ??= [0n];
|
||||
while (p.attacks.length <= index) p.attacks.push(0n);
|
||||
p.attacks[index] += _bigint(value);
|
||||
}
|
||||
@@ -89,8 +89,8 @@ export class StatsImpl implements Stats {
|
||||
) {
|
||||
const p = this._makePlayerStats(player);
|
||||
if (p === undefined) return;
|
||||
if (p.boats === undefined) p.boats = { [type]: [0n] };
|
||||
if (p.boats[type] === undefined) p.boats[type] = [0n];
|
||||
p.boats ??= { [type]: [0n] };
|
||||
p.boats[type] ??= [0n];
|
||||
while (p.boats[type].length <= index) p.boats[type].push(0n);
|
||||
p.boats[type][index] += _bigint(value);
|
||||
}
|
||||
@@ -104,8 +104,8 @@ export class StatsImpl implements Stats {
|
||||
const type = unitTypeToBombUnit[nukeType];
|
||||
const p = this._makePlayerStats(player);
|
||||
if (p === undefined) return;
|
||||
if (p.bombs === undefined) p.bombs = { [type]: [0n] };
|
||||
if (p.bombs[type] === undefined) p.bombs[type] = [0n];
|
||||
p.bombs ??= { [type]: [0n] };
|
||||
p.bombs[type] ??= [0n];
|
||||
while (p.bombs[type].length <= index) p.bombs[type].push(0n);
|
||||
p.bombs[type][index] += _bigint(value);
|
||||
}
|
||||
@@ -113,7 +113,7 @@ export class StatsImpl implements Stats {
|
||||
private _addGold(player: Player, index: number, value: BigIntLike) {
|
||||
const p = this._makePlayerStats(player);
|
||||
if (p === undefined) return;
|
||||
if (p.gold === undefined) p.gold = [0n];
|
||||
p.gold ??= [0n];
|
||||
while (p.gold.length <= index) p.gold.push(0n);
|
||||
p.gold[index] += _bigint(value);
|
||||
}
|
||||
@@ -127,8 +127,8 @@ export class StatsImpl implements Stats {
|
||||
const type = unitTypeToOtherUnit[otherUnitType];
|
||||
const p = this._makePlayerStats(player);
|
||||
if (p === undefined) return;
|
||||
if (p.units === undefined) p.units = { [type]: [0n] };
|
||||
if (p.units[type] === undefined) p.units[type] = [0n];
|
||||
p.units ??= { [type]: [0n] };
|
||||
p.units[type] ??= [0n];
|
||||
while (p.units[type].length <= index) p.units[type].push(0n);
|
||||
p.units[type][index] += _bigint(value);
|
||||
}
|
||||
|
||||
@@ -26,9 +26,7 @@ class GameMapLoader {
|
||||
private createLazyLoader<T>(importFn: () => Promise<T>): () => Promise<T> {
|
||||
let cache: Promise<T> | null = null;
|
||||
return () => {
|
||||
if (!cache) {
|
||||
cache = importFn();
|
||||
}
|
||||
cache ??= importFn();
|
||||
return cache;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ export async function archive(gameRecord: GameRecord) {
|
||||
}
|
||||
} catch (error) {
|
||||
log.error(`${gameRecord.info.gameID}: Final archive error: ${error}`, {
|
||||
message: error?.message || error,
|
||||
message: error?.message ?? error,
|
||||
stack: error?.stack,
|
||||
name: error?.name,
|
||||
...(error && typeof error === "object" ? error : {}),
|
||||
@@ -70,7 +70,7 @@ async function archiveAnalyticsToR2(gameRecord: GameRecord) {
|
||||
log.info(`${info.gameID}: successfully wrote game analytics to R2`);
|
||||
} catch (error) {
|
||||
log.error(`${info.gameID}: Error writing game analytics to R2: ${error}`, {
|
||||
message: error?.message || error,
|
||||
message: error?.message ?? error,
|
||||
stack: error?.stack,
|
||||
name: error?.name,
|
||||
...(error && typeof error === "object" ? error : {}),
|
||||
@@ -119,7 +119,7 @@ export async function readGameRecord(
|
||||
} catch (error) {
|
||||
// Log the error for monitoring purposes
|
||||
log.error(`${gameId}: Error reading game record from R2: ${error}`, {
|
||||
message: error?.message || error,
|
||||
message: error?.message ?? error,
|
||||
stack: error?.stack,
|
||||
name: error?.name,
|
||||
...(error && typeof error === "object" ? error : {}),
|
||||
@@ -142,7 +142,7 @@ export async function gameRecordExists(gameId: GameID): Promise<boolean> {
|
||||
return false;
|
||||
}
|
||||
log.error(`${gameId}: Error checking archive existence: ${error}`, {
|
||||
message: error?.message || error,
|
||||
message: error?.message ?? error,
|
||||
stack: error?.stack,
|
||||
name: error?.name,
|
||||
...(error && typeof error === "object" ? error : {}),
|
||||
|
||||
@@ -162,7 +162,9 @@ export class Cloudflare {
|
||||
);
|
||||
|
||||
const credentials = {
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
AccountTag: tokenData.a || this.accountId,
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
TunnelID: tokenData.t || tunnelId,
|
||||
TunnelName: tunnelName,
|
||||
TunnelSecret: tokenData.s,
|
||||
|
||||
@@ -694,7 +694,7 @@ export class GameServer {
|
||||
for (const client of this.activeClients) {
|
||||
if (client.hashes.has(turnNumber)) {
|
||||
const clientHash = client.hashes.get(turnNumber)!;
|
||||
counts.set(clientHash, (counts.get(clientHash) || 0) + 1);
|
||||
counts.set(clientHash, (counts.get(clientHash) ?? 0) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -146,8 +146,9 @@ app.get(
|
||||
"/api/env",
|
||||
gatekeeper.httpHandler(LimiterType.Get, async (req, res) => {
|
||||
const envConfig = {
|
||||
game_env: process.env.GAME_ENV || "prod",
|
||||
game_env: process.env.GAME_ENV,
|
||||
};
|
||||
if (!envConfig.game_env) return res.sendStatus(500);
|
||||
res.json(envConfig);
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -29,7 +29,7 @@ import { initWorkerMetrics } from "./WorkerMetrics";
|
||||
|
||||
const config = getServerConfigFromServer();
|
||||
|
||||
const workerId = parseInt(process.env.WORKER_ID || "0");
|
||||
const workerId = parseInt(process.env.WORKER_ID ?? "0");
|
||||
const log = logger.child({ comp: `w_${workerId}` });
|
||||
|
||||
// Worker setup
|
||||
@@ -94,6 +94,7 @@ export function startWorker() {
|
||||
log.warn(`cannot create game, id not found`);
|
||||
return res.status(400).json({ error: "Game ID is required" });
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
const clientIP = req.ip || req.socket.remoteAddress || "unknown";
|
||||
const result = CreateGameInputSchema.safeParse(req.body);
|
||||
if (!result.success) {
|
||||
@@ -140,6 +141,7 @@ export function startWorker() {
|
||||
return;
|
||||
}
|
||||
if (game.isPublic()) {
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
const clientIP = req.ip || req.socket.remoteAddress || "unknown";
|
||||
log.info(
|
||||
`cannot start public game ${game.id}, game is public, ip: ${ipAnonymize(clientIP)}`,
|
||||
@@ -171,6 +173,7 @@ export function startWorker() {
|
||||
return res.status(400).json({ error: "Game not found" });
|
||||
}
|
||||
if (game.isPublic()) {
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
const clientIP = req.ip || req.socket.remoteAddress || "unknown";
|
||||
log.warn(
|
||||
`cannot update public game ${game.id}, ip: ${ipAnonymize(clientIP)}`,
|
||||
@@ -296,7 +299,8 @@ export function startWorker() {
|
||||
const forwarded = req.headers["x-forwarded-for"];
|
||||
const ip = Array.isArray(forwarded)
|
||||
? forwarded[0]
|
||||
: forwarded || req.socket.remoteAddress || "unknown";
|
||||
: // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
forwarded || req.socket.remoteAddress || "unknown";
|
||||
|
||||
try {
|
||||
// Parse and handle client messages
|
||||
|
||||
Reference in New Issue
Block a user