store & reference pattern by name (#1766)

## Description:

Store pattern by name instead of value. The worker replaces the pattern
name with it's base64 when joining. This ensures the client & server are
never out of sync after patterns are updated.

* removed resizeObserver on the territory modal, it was causing some
race conditions, and the modal is not resizable so it's unnecessary.

* Moved PatternSchema to CosmeticSchema
## 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 have read and accepted the CLA agreement (only required once).

## Please put your Discord username so you can be contacted if a bug or
regression is found:

evan
This commit is contained in:
evanpelle
2025-08-16 18:08:16 -07:00
committed by GitHub
parent 77fd82b4b4
commit b57a409b8a
12 changed files with 160 additions and 159 deletions
+39 -8
View File
@@ -1,5 +1,11 @@
import { base64url } from "jose";
import { z } from "zod/v4";
import { RequiredPatternSchema } from "./Schemas";
import { PatternDecoder } from "./PatternDecoder";
export type Cosmetics = z.infer<typeof CosmeticsSchema>;
export type Pattern = z.infer<typeof PatternInfoSchema>;
export type PatternName = z.infer<typeof PatternNameSchema>;
export type Product = z.infer<typeof ProductSchema>;
export const ProductSchema = z.object({
productId: z.string(),
@@ -7,15 +13,43 @@ export const ProductSchema = z.object({
price: z.string(),
});
const PatternSchema = z.object({
name: z.string(),
pattern: RequiredPatternSchema,
export const PatternNameSchema = z
.string()
.regex(/^[a-z0-9_]+$/)
.max(32);
export const PatternSchema = z
.string()
.max(1403)
.base64url()
.refine(
(val) => {
try {
new PatternDecoder(val, base64url.decode);
return true;
} catch (e) {
if (e instanceof Error) {
console.error(JSON.stringify(e.message, null, 2));
} else {
console.error(String(e));
}
return false;
}
},
{
message: "Invalid pattern",
},
);
export const PatternInfoSchema = z.object({
name: PatternNameSchema,
pattern: PatternSchema,
product: ProductSchema.nullable(),
});
// Schema for resources/cosmetics/cosmetics.json
export const CosmeticsSchema = z.object({
patterns: z.record(z.string(), PatternSchema),
patterns: z.record(z.string(), PatternInfoSchema),
flag: z
.object({
layers: z.record(
@@ -36,6 +70,3 @@ export const CosmeticsSchema = z.object({
})
.optional(),
});
export type Cosmetics = z.infer<typeof CosmeticsSchema>;
export type Pattern = z.infer<typeof PatternSchema>;
export type Product = z.infer<typeof ProductSchema>;