mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-02 12:58:09 +00:00
support for unlockable flags (#3479)
## Description: Add support for purchasable/gated flags. * Create a new "Store" modal that renders both skins & flags * move all store related logic out of TerritoryPatternsModal * use nation:code for existing nation flags & flag:key for gated flags * check if user has the appropriate flags before purchasing ## 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 ## Please put your Discord username so you can be contacted if a bug or regression is found: evan
This commit is contained in:
+30
-8
@@ -9,10 +9,11 @@ import {
|
||||
skipNonAlphabeticTransformer,
|
||||
toAsciiLowerCaseTransformer,
|
||||
} from "obscenity";
|
||||
import countries from "resources/countries.json";
|
||||
|
||||
import { Cosmetics } from "../core/CosmeticSchemas";
|
||||
import { decodePatternData } from "../core/PatternDecoder";
|
||||
import {
|
||||
FlagSchema,
|
||||
PlayerColor,
|
||||
PlayerCosmeticRefs,
|
||||
PlayerCosmetics,
|
||||
@@ -20,6 +21,8 @@ import {
|
||||
} from "../core/Schemas";
|
||||
import { getClanTagOriginalCase, simpleHash } from "../core/Util";
|
||||
|
||||
const countryCodes = countries.filter((c) => !c.restricted).map((c) => c.code);
|
||||
|
||||
export const shadowNames = [
|
||||
"UnhuggedToday",
|
||||
"DaddysLilChamp",
|
||||
@@ -153,14 +156,11 @@ export class PrivilegeCheckerImpl implements PrivilegeChecker {
|
||||
}
|
||||
}
|
||||
if (refs.flag) {
|
||||
const result = FlagSchema.safeParse(refs.flag);
|
||||
if (!result.success) {
|
||||
return {
|
||||
type: "forbidden",
|
||||
reason: "invalid flag: " + result.error.message,
|
||||
};
|
||||
try {
|
||||
cosmetics.flag = this.isFlagAllowed(flares, refs.flag);
|
||||
} catch (e) {
|
||||
return { type: "forbidden", reason: "invalid flag: " + e.message };
|
||||
}
|
||||
cosmetics.flag = result.data;
|
||||
}
|
||||
|
||||
return { type: "allowed", cosmetics };
|
||||
@@ -207,6 +207,28 @@ export class PrivilegeCheckerImpl implements PrivilegeChecker {
|
||||
}
|
||||
}
|
||||
|
||||
isFlagAllowed(flares: string[], flagRef: string): string {
|
||||
if (flagRef.startsWith("flag:")) {
|
||||
const key = flagRef.slice("flag:".length);
|
||||
const found = this.cosmetics.flags[key];
|
||||
if (!found) throw new Error(`Flag ${key} not found`);
|
||||
|
||||
if (flares.includes("flag:*") || flares.includes(`flag:${found.name}`)) {
|
||||
return found.url;
|
||||
}
|
||||
|
||||
throw new Error(`No flares for flag ${key}`);
|
||||
} else if (flagRef.startsWith("country:")) {
|
||||
const code = flagRef.slice("country:".length);
|
||||
if (!countryCodes.includes(code)) {
|
||||
throw new Error(`invalid country code`);
|
||||
}
|
||||
return `/flags/${code}.svg`;
|
||||
} else {
|
||||
throw new Error(`invalid flag prefix`);
|
||||
}
|
||||
}
|
||||
|
||||
isColorAllowed(flares: string[], color: string): PlayerColor {
|
||||
const allowedColors = flares
|
||||
.filter((flare) => flare.startsWith("color:"))
|
||||
|
||||
Reference in New Issue
Block a user