Skip to content

Commit

Permalink
feat: variants progress
Browse files Browse the repository at this point in the history
  • Loading branch information
Zielak committed May 16, 2024
1 parent f20e94b commit 33c784e
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 8 deletions.
15 changes: 13 additions & 2 deletions packages/server/src/messages/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { logs } from "../logs.js"
import { Player } from "../player/player.js"
import type { Room } from "../room/base.js"
import type { State } from "../state/state.js"
import { variantParser } from "../utils/variantParser.js"

/**
* @param this
Expand Down Expand Up @@ -42,9 +43,19 @@ export function start(
return
}
if (variantData) {
if (variantsConfig.parse) {
variantData = variantsConfig.parse(variantData)
try {
if (variantsConfig.parse) {
variantData = variantsConfig.parse(variantData)
} else {
variantData = variantParser(variantData)
}
} catch (e) {
client?.send("gameError", {
data: "Game room setup config parsing failed. " + e.message,
})
return
}

const validationResults = variantsConfig.validate?.(variantData)

if (validationResults !== true) {
Expand Down
1 change: 0 additions & 1 deletion packages/server/src/room/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import type { Player, ServerPlayerMessage, Bot } from "../player/index.js"
import { State } from "../state/state.js"
import { debugRoomMessage } from "../utils/debugRoomMessage.js"

import { VariantsConfig } from "./gameVariants.js"
import type { RoomDefinition } from "./roomType.js"

type BroadcastOptions = IBroadcastOptions & {
Expand Down
1 change: 0 additions & 1 deletion packages/server/src/room/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export { defineRoom, RoomConstructor } from "./defineRoom.js"
export { Room } from "./base.js"
export { RoomDefinition } from "./roomType.js"
export { VariantsConfig } from "./gameVariants.js"
1 change: 0 additions & 1 deletion packages/server/src/room/roomType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import type { Player } from "../player/index.js"
import type { State } from "../state/state.js"

import type { Room } from "./base.js"
import { VariantsConfig } from "./gameVariants.js"

/**
* Extracted from colyseus room, and suggesting.
Expand Down
1 change: 0 additions & 1 deletion packages/server/src/state/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { containsChildren } from "../annotations/containsChildren.js"
import { type } from "../annotations/type.js"
import { Player } from "../player/player.js"
import { PlayerViewPosition } from "../playerViewPosition.js"
import { VariantsConfig } from "../room/gameVariants.js"
import { applyTraitsMixins, Entity } from "../traits/entity.js"
import { IdentityTrait } from "../traits/identity.js"
import { LabelTrait } from "../traits/label.js"
Expand Down
17 changes: 17 additions & 0 deletions packages/server/src/utils/__test__/variantParset.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { variantParser } from "../variantParser.js"

describe("deep object", () => {
it("parses single deep field", () => {
const data = {
"foo.bar": true,
"card.suit": "S",
"card.rank": "A",
first: 1,
}
const result = variantParser(data)
expect(result["foo"]["bar"]).toBe(true)
expect(result["card"]["suit"]).toBe("S")
expect(result["card"]["rank"]).toBe("A")
expect(result["first"]).toBe(1)
})
})
49 changes: 49 additions & 0 deletions packages/server/src/utils/variantParser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
function deepAssign(
object: Record<string, any>,
path: string[],
value: unknown,
): void {
if (path.length === 1) {
// as deep as it gets, set
object[path[0]] = value
return
}

const key = path.shift()

if (object[key] === undefined) {
object[key] = {}
} else if (typeof object[key] !== "object") {
throw new Error(
`Expected to access "${path.join(".")} but it's of type ${typeof object[
key
]}"`,
)
}

deepAssign(object[key], path, value)
}

export const variantParser = <T extends Record<string, unknown>>(
value: unknown,
): T => {
// Expected flat object of props. Possible sub objects with dot notation

if (typeof value !== "object") {
throw new Error("Variant data not an object, cannot parse")
}

const result = {}

Object.keys(value).forEach((key) => {
const isPath = key.includes("$")

if (!isPath) {
result[key] = value[key]
} else {
deepAssign(result, key.split("$"), value[key])
}
})

return result as T
}
1 change: 1 addition & 0 deletions packages/types/src/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/// <reference path="cards.d.ts" />
/// <reference path="messages.d.ts" />
/// <reference path="utils.d.ts" />
/// <reference path="variants.d.ts" />

interface RoomCreateOptions {
[key: string]: unknown
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
type VariantPreset<T> = {
type VariantPreset<
T extends Record<string, unknown> = Record<string, unknown>,
> = {
name: string
data: DeepPartial<T>
/** Should this preset be merging with the defaults or not? */
includesDefaults?: boolean
}

export type VariantsConfig<T> = {
type VariantsConfig<
T extends Record<string, unknown> = Record<string, unknown>,
> = {
defaults: Required<T>
/**
* Decide how you want to send variant data from the client
Expand Down

0 comments on commit 33c784e

Please sign in to comment.