Last active
October 4, 2021 20:30
-
-
Save sminnee/1d4d2bea8d909fb62e7a94c99def79fb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/common/messages/grid.ts b/common/messages/grid.ts | |
index 155e77fd..54ad174c 100644 | |
--- a/common/messages/grid.ts | |
+++ b/common/messages/grid.ts | |
@@ -1,70 +1,86 @@ | |
// Descriptions used in message types | |
+import * as t from 'io-ts' | |
import { TDate } from 'timeago.js' | |
+import { User } from '../../src/user' | |
import { FeatureDescription } from './feature' | |
export type ParcelAuthResult = 'Owner' | 'Collaborator' | 'Sandbox' | 'Moderator' | 'Tower Owner' | false | |
-export enum LightmapStatus { | |
- None = 'None', | |
- Requested = 'Requested', | |
- Baking = 'Baking', | |
- Baked = 'Baked', | |
- Failed = 'Failed', | |
- HashMismatch = 'HashMismatch', | |
-} | |
- | |
-export type ParcelRef = { | |
- id: number | |
- owner: string | |
- name?: string | |
- description?: string | |
- hash?: string | |
- island?: string | |
- suburb?: string | |
- contributors?: string[] | |
- grid?: boolean | |
- sandbox?: boolean | |
- | |
- // todo: please nerf | |
- lightmap_status?: LightmapStatus | |
-} | |
- | |
-export type ParcelGeometry = { | |
- type: 'Polygon' | |
- crs: { | |
- type: 'name' | |
- properties: { | |
- name: string | |
- } | |
- coordinates: number[][][] | |
- } | |
-} | |
+// export enum LightmapStatus { | |
+// None = 'None', | |
+// Requested = 'Requested', | |
+// Baking = 'Baking', | |
+// Baked = 'Baked', | |
+// Failed = 'Failed', | |
+// HashMismatch = 'HashMismatch', | |
+// } | |
+ | |
+export const LightmapStatus = t.union([t.literal('None'), t.literal('Requested'), t.literal('Baking'), t.literal('Baked'), t.literal('Failed'), t.literal('HashMismatch')]) | |
+export type LightmapStatus = t.TypeOf<typeof LightmapStatus> | |
+ | |
+export const ParcelRef = t.intersection([ | |
+ t.type({ | |
+ id: t.number, | |
+ owner: t.string, | |
+ }), | |
+ t.partial({ | |
+ name: t.string, | |
+ description: t.string, | |
+ hash: t.string, | |
+ island: t.string, | |
+ suburb: t.string, | |
+ contributors: t.array(t.string), | |
+ grid: t.boolean, | |
+ sandbox: t.boolean, | |
+ | |
+ // todo: please nerf | |
+ lightmap_status: LightmapStatus, | |
+ }), | |
+]) | |
+export type ParcelRef = t.TypeOf<typeof ParcelRef> | |
+ | |
+export const ParcelGeometry = t.type({ | |
+ type: t.literal('Polygon'), | |
+ crs: t.type({ | |
+ type: t.literal('name'), | |
+ properties: t.type({ | |
+ name: t.string, | |
+ }), | |
+ coordinates: t.array(t.array(t.array(t.number))), | |
+ }), | |
+}) | |
+export type ParcelGeometry = t.TypeOf<typeof ParcelGeometry> | |
// Used in /api/parcels/cached.json | |
-export type ParcelDescription = ParcelRef & { | |
- x1: number | |
- x2: number | |
- y1: number | |
- y2: number | |
- z1: number | |
- z2: number | |
- | |
- address?: string | |
- geometry?: ParcelGeometry | |
- area?: number | |
- height?: number | |
- distance?: number | |
- price?: number | |
- | |
- // unsure | |
- space?: number | |
- scripting?: boolean | |
- voxels?: string | |
- tileset?: string | |
- palette?: string[] | |
- features?: FeatureDescription | |
-} | |
+export const ParcelDescription = t.intersection([ | |
+ ParcelRef, | |
+ t.type({ | |
+ x1: t.number, | |
+ x2: t.number, | |
+ y1: t.number, | |
+ y2: t.number, | |
+ z1: t.number, | |
+ z2: t.number, | |
+ }), | |
+ t.partial({ | |
+ address: t.string, | |
+ geometry: ParcelGeometry, | |
+ area: t.number, | |
+ height: t.number, | |
+ distance: t.number, | |
+ price: t.number, | |
+ | |
+ // unsure | |
+ space: t.number, | |
+ scripting: t.boolean, | |
+ voxels: t.string, | |
+ tileset: t.string, | |
+ palette: t.array(t.string), | |
+ //features: FeatureDescription, | |
+ }), | |
+]) | |
+export type ParcelDescription = t.TypeOf<typeof ParcelDescription> | |
// Messsage types | |
diff --git a/package-lock.json b/package-lock.json | |
index 0eae7159..048cd55f 100644 | |
--- a/package-lock.json | |
+++ b/package-lock.json | |
@@ -59,6 +59,7 @@ | |
"express-http-proxy": "1.6.0", | |
"express-prom-bundle": "^6.3.6", | |
"express-rate-limit": "^5.3.0", | |
+ "fp-ts": "^2.11.4", | |
"genversion": "^3.0.0", | |
"gif.js": "0.2.0", | |
"gifuct-js": "^2.1.1", | |
@@ -69,6 +70,7 @@ | |
"https-browserify": "^1.0.0", | |
"ics": "^2.27.0", | |
"ifdef-loader": "^2.3.0", | |
+ "io-ts": "^2.2.16", | |
"isomorphic-unfetch": "^3.1.0", | |
"js-cookie": "2.2.0", | |
"jsdom": "16.4.0", | |
@@ -8499,6 +8501,11 @@ | |
"node": ">= 0.6" | |
} | |
}, | |
+ "node_modules/fp-ts": { | |
+ "version": "2.11.4", | |
+ "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-2.11.4.tgz", | |
+ "integrity": "sha512-lhV7tGEbs2qoVw4vmqOovChS7CAoIYU0gdiPEF8Vc4bLZct+PAMMeXrCqRyBNEo33XOvwvAmFDEDIrHPWH2/fg==" | |
+ }, | |
"node_modules/fragment-cache": { | |
"version": "0.2.1", | |
"integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", | |
@@ -9579,6 +9586,14 @@ | |
"node": ">=4" | |
} | |
}, | |
+ "node_modules/io-ts": { | |
+ "version": "2.2.16", | |
+ "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-2.2.16.tgz", | |
+ "integrity": "sha512-y5TTSa6VP6le0hhmIyN0dqEXkrZeJLeC5KApJq6VLci3UEKF80lZ+KuoUs02RhBxNWlrqSNxzfI7otLX1Euv8Q==", | |
+ "peerDependencies": { | |
+ "fp-ts": "^2.5.0" | |
+ } | |
+ }, | |
"node_modules/iota-array": { | |
"version": "1.0.0", | |
"integrity": "sha1-ge9X/l0FgUzVjCSDYyqZwwoOgIc=" | |
@@ -25296,6 +25311,11 @@ | |
"version": "0.1.2", | |
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" | |
}, | |
+ "fp-ts": { | |
+ "version": "2.11.4", | |
+ "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-2.11.4.tgz", | |
+ "integrity": "sha512-lhV7tGEbs2qoVw4vmqOovChS7CAoIYU0gdiPEF8Vc4bLZct+PAMMeXrCqRyBNEo33XOvwvAmFDEDIrHPWH2/fg==" | |
+ }, | |
"fragment-cache": { | |
"version": "0.2.1", | |
"integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", | |
@@ -26144,6 +26164,12 @@ | |
"integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", | |
"dev": true | |
}, | |
+ "io-ts": { | |
+ "version": "2.2.16", | |
+ "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-2.2.16.tgz", | |
+ "integrity": "sha512-y5TTSa6VP6le0hhmIyN0dqEXkrZeJLeC5KApJq6VLci3UEKF80lZ+KuoUs02RhBxNWlrqSNxzfI7otLX1Euv8Q==", | |
+ "requires": {} | |
+ }, | |
"iota-array": { | |
"version": "1.0.0", | |
"integrity": "sha1-ge9X/l0FgUzVjCSDYyqZwwoOgIc=" | |
diff --git a/package.json b/package.json | |
index 41566e4d..d61120f4 100644 | |
--- a/package.json | |
+++ b/package.json | |
@@ -113,6 +113,7 @@ | |
"express-http-proxy": "1.6.0", | |
"express-prom-bundle": "^6.3.6", | |
"express-rate-limit": "^5.3.0", | |
+ "fp-ts": "^2.11.4", | |
"genversion": "^3.0.0", | |
"gif.js": "0.2.0", | |
"gifuct-js": "^2.1.1", | |
@@ -123,6 +124,7 @@ | |
"https-browserify": "^1.0.0", | |
"ics": "^2.27.0", | |
"ifdef-loader": "^2.3.0", | |
+ "io-ts": "^2.2.16", | |
"isomorphic-unfetch": "^3.1.0", | |
"js-cookie": "2.2.0", | |
"jsdom": "16.4.0", | |
diff --git a/server/grid-socket.ts b/server/grid-socket.ts | |
index 73a995d8..526a2513 100644 | |
--- a/server/grid-socket.ts | |
+++ b/server/grid-socket.ts | |
@@ -109,7 +109,7 @@ class PatchSet { | |
} | |
// clear out the existing lightmap on change | |
- parcel.lightmap_status = LightmapStatus.None | |
+ parcel.lightmap_status = 'None' | |
// If shouldUpdateParcelScript is already true, no need to re-update it. | |
shouldUpdateParcelScript = shouldUpdateParcelScript ? shouldUpdateParcelScript : hasScript(patch) | |
@@ -547,7 +547,7 @@ export default class GridSocket { | |
return | |
} | |
- const hadLightmap = parcel.lightmap_status !== LightmapStatus.None | |
+ const hadLightmap = parcel.lightmap_status !== 'None' | |
ws.patches.add(msg) | |
@@ -556,7 +556,7 @@ export default class GridSocket { | |
if (hadLightmap) { | |
// Changes to a parcel will invalidate the lightmap, however the user won't know this has happened unless they refresh. | |
// This sends the message out immediately so that all clients (including builder) see the lightmap change immediately. | |
- this.sendLightmapStatus(msg.parcelId, parcel.hash, LightmapStatus.None) | |
+ this.sendLightmapStatus(msg.parcelId, parcel.hash, 'None') | |
} | |
} | |
@@ -625,11 +625,11 @@ export default class GridSocket { | |
if (authResult) { | |
if (msg.requestBake) { | |
- this.updateAndSendLightmapStatus(msg.parcelId, LightmapStatus.Requested) | |
+ this.updateAndSendLightmapStatus(msg.parcelId, 'Requested') | |
parcel.cancelBake() | |
parcel.requestBake() | |
} else if (msg.cancelBake) { | |
- this.updateAndSendLightmapStatus(msg.parcelId, LightmapStatus.None) | |
+ this.updateAndSendLightmapStatus(msg.parcelId, 'None') | |
parcel.cancelBake() | |
} | |
} | |
diff --git a/server/server.ts b/server/server.ts | |
index 853db8de..6c814402 100644 | |
--- a/server/server.ts | |
+++ b/server/server.ts | |
@@ -744,8 +744,8 @@ app.get('/api/jobs/bake', cache(false), async (req: any, res: any) => { | |
await db.query(`update jobs set processed_at = now() where id = $1`, [job.id]) | |
let parcel = await Parcel.load(job.parcel_id) | |
- if (parcel && parcel.lightmap_status !== LightmapStatus.None) { | |
- gridSocket.updateAndSendLightmapStatus(job.parcel_id, LightmapStatus.Baking) | |
+ if (parcel && parcel.lightmap_status !== 'None') { | |
+ gridSocket.updateAndSendLightmapStatus(job.parcel_id, 'Baking') | |
} | |
} | |
@@ -782,18 +782,18 @@ app.post('/api/jobs/baked', async (req: any, res: any) => { | |
if (success !== false) { | |
// only update the bake status if it hasn't been cancelled and not out of date | |
- if (parcel && parcel.lightmap_status === LightmapStatus.Baking && parcel.hash === hash) { | |
- const clientCount = gridSocket.updateAndSendLightmapStatus(parcel_id, LightmapStatus.Baked) | |
+ if (parcel && parcel.lightmap_status === 'Baking' && parcel.hash === hash) { | |
+ const clientCount = gridSocket.updateAndSendLightmapStatus(parcel_id, 'Baked') | |
res.status(200).send({ success: true, message: `Notified ${clientCount} clients` }) | |
- } else if (parcel && parcel.lightmap_status !== LightmapStatus.Baking) { | |
- const clientCount = gridSocket.updateAndSendLightmapStatus(parcel_id, LightmapStatus.Failed) | |
+ } else if (parcel && parcel.lightmap_status !== 'Baking') { | |
+ const clientCount = gridSocket.updateAndSendLightmapStatus(parcel_id, 'Failed') | |
res.status(200).send({ success: true, message: `Parcel bake response discarded due to not being in "baking" state, notified ${clientCount} clients` }) | |
} else if (parcel && parcel.hash !== hash) { | |
- const clientCount = gridSocket.updateAndSendLightmapStatus(parcel_id, LightmapStatus.HashMismatch) | |
+ const clientCount = gridSocket.updateAndSendLightmapStatus(parcel_id, 'HashMismatch') | |
res.status(200).send({ success: true, message: `Parcel bake response discarded due to parcel hash mismatch, notified ${clientCount} clients` }) | |
} | |
} else { | |
- let clientCount = gridSocket.updateAndSendLightmapStatus(parcel_id, LightmapStatus.Failed) | |
+ let clientCount = gridSocket.updateAndSendLightmapStatus(parcel_id, 'Failed') | |
res.status(200).send({ success: true, message: `Notified ${clientCount} clients` }) | |
} | |
}) | |
diff --git a/src/grid.ts b/src/grid.ts | |
index aef94cbe..b1ff4163 100644 | |
--- a/src/grid.ts | |
+++ b/src/grid.ts | |
@@ -314,8 +314,8 @@ export default class Grid extends SocketClient { | |
updateParcelLightmapStatus(parcel: any, status: LightmapStatus) { | |
if (parcel.lightmap_status !== status) { | |
- let wasBaked = parcel.lightmap_status === LightmapStatus.Baked | |
- let hasBake = status === LightmapStatus.Baked | |
+ let wasBaked = parcel.lightmap_status === 'Baked' | |
+ let hasBake = status === 'Baked' | |
parcel.updateLightmapStatus(status as LightmapStatus) | |
if (wasBaked !== hasBake) { | |
parcel.generate() | |
@@ -661,7 +661,7 @@ export default class Grid extends SocketClient { | |
p.loaded = false | |
// do the baked meshing on main thread if parcel has lightmap | |
// fixme: do baked meshing on worker thread | |
- if (p.lightmap_status === LightmapStatus.Baked) { | |
+ if (p.lightmap_status === 'Baked') { | |
p.generate() | |
} | |
}) | |
diff --git a/src/parcel.ts b/src/parcel.ts | |
index cf58ce9f..4baaad26 100644 | |
--- a/src/parcel.ts | |
+++ b/src/parcel.ts | |
@@ -256,15 +256,15 @@ export default class Parcel extends EventEmitter implements VoxelObject { | |
requestBake() { | |
if (this.canEdit) { | |
- this.updateLightmapStatus(LightmapStatus.Requested) | |
+ this.updateLightmapStatus('Requested') | |
this.connector.grid.requestBake(this.id) | |
} | |
} | |
cancelBake() { | |
if (this.canEdit) { | |
- let needsGenerate = this.lightmap_status === LightmapStatus.Baked | |
- this.updateLightmapStatus(LightmapStatus.None) | |
+ let needsGenerate = this.lightmap_status === 'Baked' | |
+ this.updateLightmapStatus('None') | |
this.connector.grid.cancelBake(this.id) | |
if (needsGenerate) { | |
this.generate() | |
@@ -289,7 +289,7 @@ export default class Parcel extends EventEmitter implements VoxelObject { | |
this.contributors = meta.contributors || [] | |
this.grid = meta.grid || false | |
this.sandbox = meta.sandbox || false | |
- this.lightmap_status = meta.lightmap_status || LightmapStatus.None | |
+ this.lightmap_status = meta.lightmap_status || 'None' | |
} | |
receivePatch(patch: any) { | |
@@ -822,7 +822,7 @@ export default class Parcel extends EventEmitter implements VoxelObject { | |
} | |
async populateVoxelField(data: any) { | |
- if (this.lightmap_status !== LightmapStatus.Baked) { | |
+ if (this.lightmap_status !== 'Baked') { | |
// accept the grid-workers mesh only if we don't have an active lightmap | |
await VoxelField.generate(this, data, this.configureVoxelFieldMeshes.bind(this)) | |
this.loaded = true | |
@@ -834,7 +834,7 @@ export default class Parcel extends EventEmitter implements VoxelObject { | |
} | |
async generateVoxelField() { | |
- if (this.lightmap_status !== LightmapStatus.Baked) { | |
+ if (this.lightmap_status !== 'Baked') { | |
// clean up the baked mesh if we are now rendering AO | |
if (this.voxelMesh && this.voxelMesh.name === generateVoxelOpaqueMeshName(this.id)) { | |
this.voxelMesh.dispose() | |
@@ -968,10 +968,10 @@ export default class Parcel extends EventEmitter implements VoxelObject { | |
clearTimeout(this.fieldUpdateTimeout) | |
this.fieldUpdateTimeout = setTimeout(() => { | |
- if (this.lightmap_status !== LightmapStatus.None) { | |
+ if (this.lightmap_status !== 'None') { | |
// force the parcel to become unbaked without waiting for the socket to tell us | |
// this prevents errors being thrown when building in a bake parcel while we wait for the message to come back (latency) | |
- this.updateLightmapStatus(LightmapStatus.None) | |
+ this.updateLightmapStatus('None') | |
} | |
this.voxels = this.field ? getVoxelsFromBuffer(this.field.data.buffer) : undefined | |
this.sendField() | |
diff --git a/src/ui/overlay/edit-tab.tsx b/src/ui/overlay/edit-tab.tsx | |
index fa556eba..8012d111 100644 | |
--- a/src/ui/overlay/edit-tab.tsx | |
+++ b/src/ui/overlay/edit-tab.tsx | |
@@ -26,7 +26,7 @@ export default class EditTab extends Component<Props, any> { | |
this.state = { | |
brightness: props.parcel?.brightness, | |
- lightmapStatus: LightmapStatus.None, | |
+ lightmapStatus: 'None', | |
uploading: false, | |
} | |
} | |
@@ -98,11 +98,11 @@ export default class EditTab extends Component<Props, any> { | |
return <div /> | |
} | |
- let pendingBake = this.state.lightmapStatus === LightmapStatus.Requested || this.state.lightmapStatus === LightmapStatus.Baking | |
- let baked = this.state.lightmapStatus === LightmapStatus.Baked | |
- let bakeStatusText = this.state.lightmapStatus === LightmapStatus.Requested ? 'Waiting in queue...' : 'Baking lightmap...' | |
- let bakeFailed = this.state.lightmapStatus === LightmapStatus.Failed | |
- let bakeHashMismatch = this.state.lightmapStatus === LightmapStatus.HashMismatch | |
+ let pendingBake = this.state.lightmapStatus === 'Requested' || this.state.lightmapStatus === 'Baking' | |
+ let baked = this.state.lightmapStatus === 'Baked' | |
+ let bakeStatusText = this.state.lightmapStatus === 'Requested' ? 'Waiting in queue...' : 'Baking lightmap...' | |
+ let bakeFailed = this.state.lightmapStatus === 'Failed' | |
+ let bakeHashMismatch = this.state.lightmapStatus === 'HashMismatch' | |
return ( | |
<section className="tile-selector"> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment