@hytopia.com/server-protocol 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +25 -0
- package/packets/PacketTypes.ts +67 -0
- package/packets/inbound/Heartbeat.ts +11 -0
- package/packets/inbound/Input.ts +11 -0
- package/packets/index.ts +26 -0
- package/packets/outbound/Block.ts +11 -0
- package/packets/outbound/BlockRegistry.ts +11 -0
- package/packets/outbound/BlockType.ts +11 -0
- package/packets/outbound/Chunk.ts +11 -0
- package/packets/outbound/Entity.ts +11 -0
- package/packets/outbound/PhysicsDebugRender.ts +11 -0
- package/schemas/Block.ts +20 -0
- package/schemas/BlockRegistry.ts +21 -0
- package/schemas/BlockType.ts +28 -0
- package/schemas/Chunk.ts +29 -0
- package/schemas/Collider.ts +16 -0
- package/schemas/ColliderDesc.ts +47 -0
- package/schemas/Entity.ts +30 -0
- package/schemas/Heartbeat.ts +8 -0
- package/schemas/Input.ts +35 -0
- package/schemas/PhysicsDebugRender.ts +18 -0
- package/schemas/Quaternion.ts +20 -0
- package/schemas/RigidBody.ts +16 -0
- package/schemas/RigidBodyDesc.ts +47 -0
- package/schemas/Shape.ts +23 -0
- package/schemas/Vector.ts +18 -0
- package/schemas/VectorBoolean.ts +18 -0
- package/shared/Ajv.ts +8 -0
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hytopia.com/server-protocol",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "index.js",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
7
|
+
},
|
|
8
|
+
"author": "",
|
|
9
|
+
"license": "ISC",
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"quicktype": "^23.0.170"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"ajv": "^8.17.1"
|
|
15
|
+
},
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/hytopiagg/server-protocol.git"
|
|
19
|
+
},
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/hytopiagg/server-protocol/issues"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://github.com/hytopiagg/server-protocol#readme",
|
|
24
|
+
"description": ""
|
|
25
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import Ajv from '../shared/Ajv';
|
|
2
|
+
import type { JSONSchemaType, ValidateFunction } from 'ajv';
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* Packet types are numerically ordered relative to their use.
|
|
6
|
+
*
|
|
7
|
+
* Standard inbound/outbound packets must be within the id
|
|
8
|
+
* range of 0-127 to allow their numerical representation in
|
|
9
|
+
* msgpack'd format to be 1 byte - these packets are the most
|
|
10
|
+
* frequent and thus should be optimized for the smallest
|
|
11
|
+
* representation.
|
|
12
|
+
*
|
|
13
|
+
* Debug packets must be within the id range of 128-255 to
|
|
14
|
+
* allow their msgpack'd format to be 2 bytes - these packets
|
|
15
|
+
* are not packets used in typical or frequent gameplay and
|
|
16
|
+
* are acceptable to be represented with an additional byte
|
|
17
|
+
* in encoded format.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
export enum PacketType {
|
|
21
|
+
// Standard Inbound Packet Types: 0 - 31 range
|
|
22
|
+
HEARTBEAT = 0,
|
|
23
|
+
INPUT = 1,
|
|
24
|
+
|
|
25
|
+
// Standard Outbound Packet Types: 32 - 127 range
|
|
26
|
+
BLOCK = 32,
|
|
27
|
+
BLOCK_REGISTRY = 33,
|
|
28
|
+
BLOCK_TYPE = 34,
|
|
29
|
+
CHUNK = 35,
|
|
30
|
+
ENTITY = 36,
|
|
31
|
+
|
|
32
|
+
// Debug Inbound Packet Types: 128 - 191 range
|
|
33
|
+
// NONE atm, start at 128
|
|
34
|
+
|
|
35
|
+
// Debug Outbound Packet Types: 192 - 255 range
|
|
36
|
+
PHYSICS_DEBUG_RENDER = 192
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/*
|
|
40
|
+
* Generators for packet definitions and validators.
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
export interface IPacketDefinition<TId extends PacketType, TPayload> {
|
|
44
|
+
id: TId;
|
|
45
|
+
schema: JSONSchemaType<TPayload>;
|
|
46
|
+
validate: ValidateFunction<TPayload>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface IPacket<TId extends PacketType, TPayload> {
|
|
50
|
+
id: TId;
|
|
51
|
+
payload: TPayload;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const definePacket = <TId extends PacketType, TPayload>(
|
|
55
|
+
id: TId,
|
|
56
|
+
schema: JSONSchemaType<TPayload>,
|
|
57
|
+
): IPacketDefinition<TId, TPayload> => ({
|
|
58
|
+
id,
|
|
59
|
+
schema,
|
|
60
|
+
validate: Ajv.instance.compile(schema),
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Represents any packet type
|
|
64
|
+
export type AnyPacket = IPacket<PacketType, unknown>;
|
|
65
|
+
|
|
66
|
+
// Represents any packet definition type
|
|
67
|
+
export type AnyPacketDefinition = IPacketDefinition<number, unknown>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { definePacket, PacketType } from '../PacketTypes';
|
|
2
|
+
import type { IPacket } from '../PacketTypes';
|
|
3
|
+
import { heartbeatSchema } from '../../schemas/Heartbeat';
|
|
4
|
+
import type { Heartbeat } from '../../schemas/Heartbeat';
|
|
5
|
+
|
|
6
|
+
export type HeartbeatPacket = IPacket<typeof PacketType.HEARTBEAT, Heartbeat>;
|
|
7
|
+
|
|
8
|
+
export const heartbeatPacketDefinition = definePacket(
|
|
9
|
+
PacketType.HEARTBEAT,
|
|
10
|
+
heartbeatSchema
|
|
11
|
+
);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { definePacket, PacketType } from '../PacketTypes';
|
|
2
|
+
import type { IPacket } from '../PacketTypes';
|
|
3
|
+
import { inputSchema } from '../../schemas/Input';
|
|
4
|
+
import type { Input } from '../../schemas/Input';
|
|
5
|
+
|
|
6
|
+
export type InputPacket = IPacket<typeof PacketType.INPUT, Input>;
|
|
7
|
+
|
|
8
|
+
export const inputPacketDefinition = definePacket(
|
|
9
|
+
PacketType.INPUT,
|
|
10
|
+
inputSchema
|
|
11
|
+
);
|
package/packets/index.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
|
|
4
|
+
const inboundPackets: Record<string, any> = {};
|
|
5
|
+
const outboundPackets: Record<string, any> = {};
|
|
6
|
+
|
|
7
|
+
const importPackets = async () => {
|
|
8
|
+
for (const directory of ['inbound', 'outbound']) {
|
|
9
|
+
const directoryPath = path.join(__dirname, directory);
|
|
10
|
+
const files = fs.readdirSync(directoryPath);
|
|
11
|
+
|
|
12
|
+
for (const file of files) {
|
|
13
|
+
if (file.endsWith('.ts')) {
|
|
14
|
+
const name = path.basename(file, '.ts');
|
|
15
|
+
const module = await import(`./${directory}/${name}`);
|
|
16
|
+
const typePackets = directory === 'inbound' ? inboundPackets : outboundPackets;
|
|
17
|
+
const lcfName = name.charAt(0).toLowerCase() + name.slice(1);
|
|
18
|
+
typePackets[`${lcfName}PacketDefinition`] = module[`${lcfName}PacketDefinition`];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
await importPackets();
|
|
25
|
+
|
|
26
|
+
export default { inboundPackets, outboundPackets };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { definePacket, PacketType } from '../PacketTypes';
|
|
2
|
+
import type { IPacket } from '../PacketTypes';
|
|
3
|
+
import { blockSchema } from '../../schemas/Block';
|
|
4
|
+
import type { Block } from '../../schemas/Block';
|
|
5
|
+
|
|
6
|
+
export type BlockPacket = IPacket<typeof PacketType.BLOCK, Block>;
|
|
7
|
+
|
|
8
|
+
export const blockPacketDefinition = definePacket(
|
|
9
|
+
PacketType.BLOCK,
|
|
10
|
+
blockSchema,
|
|
11
|
+
);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { definePacket, PacketType } from '../PacketTypes';
|
|
2
|
+
import type { IPacket } from '../PacketTypes';
|
|
3
|
+
import { blockRegistrySchema } from '../../schemas/BlockRegistry';
|
|
4
|
+
import type { BlockRegistry } from '../../schemas/BlockRegistry';
|
|
5
|
+
|
|
6
|
+
export type BlockRegistryPacket = IPacket<typeof PacketType.BLOCK_REGISTRY, BlockRegistry>;
|
|
7
|
+
|
|
8
|
+
export const blockRegistryPacketDefinition = definePacket(
|
|
9
|
+
PacketType.BLOCK_REGISTRY,
|
|
10
|
+
blockRegistrySchema,
|
|
11
|
+
);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { definePacket, PacketType } from '../PacketTypes';
|
|
2
|
+
import type { IPacket } from '../PacketTypes';
|
|
3
|
+
import { blockTypeSchema } from '../../schemas/BlockType';
|
|
4
|
+
import type { BlockType } from '../../schemas/BlockType';
|
|
5
|
+
|
|
6
|
+
export type BlockTypePacket = IPacket<typeof PacketType.BLOCK_TYPE, BlockType>;
|
|
7
|
+
|
|
8
|
+
export const blockTypePacketDefinition = definePacket(
|
|
9
|
+
PacketType.BLOCK_TYPE,
|
|
10
|
+
blockTypeSchema,
|
|
11
|
+
);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { definePacket, PacketType } from '../PacketTypes';
|
|
2
|
+
import type { IPacket } from '../PacketTypes';
|
|
3
|
+
import { chunkSchema } from '../../schemas/Chunk';
|
|
4
|
+
import type { Chunk } from '../../schemas/Chunk';
|
|
5
|
+
|
|
6
|
+
export type ChunkPacket = IPacket<typeof PacketType.CHUNK, Chunk>;
|
|
7
|
+
|
|
8
|
+
export const chunkPacketDefinition = definePacket(
|
|
9
|
+
PacketType.CHUNK,
|
|
10
|
+
chunkSchema,
|
|
11
|
+
);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { definePacket, PacketType } from '../PacketTypes';
|
|
2
|
+
import type { IPacket } from '../PacketTypes';
|
|
3
|
+
import { entitySchema } from '../../schemas/Entity';
|
|
4
|
+
import type { Entity } from '../../schemas/Entity';
|
|
5
|
+
|
|
6
|
+
export type EntityPacket = IPacket<typeof PacketType.ENTITY, Entity>;
|
|
7
|
+
|
|
8
|
+
export const entityPacketDefinition = definePacket(
|
|
9
|
+
PacketType.ENTITY,
|
|
10
|
+
entitySchema,
|
|
11
|
+
);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { definePacket, PacketType } from '../PacketTypes';
|
|
2
|
+
import type { IPacket } from '../PacketTypes';
|
|
3
|
+
import { physicsDebugRenderSchema } from '../../schemas/PhysicsDebugRender';
|
|
4
|
+
import type { PhysicsDebugRender } from '../../schemas/PhysicsDebugRender';
|
|
5
|
+
|
|
6
|
+
export type PhysicsDebugRenderPacket = IPacket<typeof PacketType.PHYSICS_DEBUG_RENDER, PhysicsDebugRender>;
|
|
7
|
+
|
|
8
|
+
export const physicsDebugRenderPacketDefinition = definePacket(
|
|
9
|
+
PacketType.PHYSICS_DEBUG_RENDER,
|
|
10
|
+
physicsDebugRenderSchema,
|
|
11
|
+
);
|
package/schemas/Block.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { vectorSchema } from './Vector';
|
|
2
|
+
import type { JSONSchemaType } from 'ajv';
|
|
3
|
+
import type { Vector } from './Vector';
|
|
4
|
+
|
|
5
|
+
export type Block = {
|
|
6
|
+
wi: string; // world id
|
|
7
|
+
i: number; // block id
|
|
8
|
+
c: Vector; // coordinate
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const blockSchema: JSONSchemaType<Block> = {
|
|
12
|
+
type: 'object',
|
|
13
|
+
properties: {
|
|
14
|
+
wi: { type: 'string' },
|
|
15
|
+
i: { type: 'number' },
|
|
16
|
+
c: vectorSchema,
|
|
17
|
+
},
|
|
18
|
+
required: [ 'wi', 'i', 'c' ],
|
|
19
|
+
additionalProperties: false,
|
|
20
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { blockTypeSchema } from './BlockType';
|
|
2
|
+
import type { JSONSchemaType } from 'ajv';
|
|
3
|
+
import type { BlockType } from './BlockType';
|
|
4
|
+
|
|
5
|
+
export type BlockRegistry = {
|
|
6
|
+
wi: string; // world id
|
|
7
|
+
b: BlockType[]; // block types
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const blockRegistrySchema: JSONSchemaType<BlockRegistry> = {
|
|
11
|
+
type: 'object',
|
|
12
|
+
properties: {
|
|
13
|
+
wi: { type: 'string' },
|
|
14
|
+
b: {
|
|
15
|
+
type: 'array',
|
|
16
|
+
items: blockTypeSchema,
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
required: [ 'wi', 'b' ],
|
|
20
|
+
additionalProperties: false,
|
|
21
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { colliderDescSchema } from './ColliderDesc';
|
|
2
|
+
import type { JSONSchemaType } from 'ajv';
|
|
3
|
+
import type { ColliderDesc } from './ColliderDesc';
|
|
4
|
+
|
|
5
|
+
export type BlockType = {
|
|
6
|
+
wi: string; // world id
|
|
7
|
+
i: number; // block type id
|
|
8
|
+
d: boolean; // delta
|
|
9
|
+
t?: string; // textureUri
|
|
10
|
+
n?: string; // name
|
|
11
|
+
c?: ColliderDesc; // collider desc
|
|
12
|
+
s?: boolean; // is solid
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const blockTypeSchema: JSONSchemaType<BlockType> = {
|
|
16
|
+
type: 'object',
|
|
17
|
+
properties: {
|
|
18
|
+
wi: { type: 'string' },
|
|
19
|
+
i: { type: 'number' },
|
|
20
|
+
d: { type: 'boolean' },
|
|
21
|
+
t: { type: 'string', nullable: true },
|
|
22
|
+
n: { type: 'string', nullable: true },
|
|
23
|
+
c: { ...colliderDescSchema, nullable: true },
|
|
24
|
+
s: { type: 'boolean', nullable: true },
|
|
25
|
+
},
|
|
26
|
+
required: [ 'wi', 'i', 'd' ],
|
|
27
|
+
additionalProperties: false,
|
|
28
|
+
}
|
package/schemas/Chunk.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { vectorSchema } from './Vector';
|
|
2
|
+
import type { JSONSchemaType } from 'ajv';
|
|
3
|
+
import type { Vector } from './Vector';
|
|
4
|
+
|
|
5
|
+
export type Chunk = {
|
|
6
|
+
wi: string; // world id
|
|
7
|
+
c: Vector; // chunk coordinate [ 16n, 16n, 16n ]
|
|
8
|
+
b: Uint8Array | number[]; // block ids in chunk, 16^3 entries, registry block ids 1-255, 0 = none
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const chunkSchema: JSONSchemaType<Chunk> = {
|
|
12
|
+
type: 'object',
|
|
13
|
+
properties: {
|
|
14
|
+
wi: { type: 'string' },
|
|
15
|
+
c: vectorSchema,
|
|
16
|
+
b: {
|
|
17
|
+
type: 'array',
|
|
18
|
+
items: {
|
|
19
|
+
type: 'number',
|
|
20
|
+
minimum: 0,
|
|
21
|
+
maximum: 255
|
|
22
|
+
},
|
|
23
|
+
minItems: 4096,
|
|
24
|
+
maxItems: 4096
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
required: [ 'wi', 'c', 'b' ],
|
|
28
|
+
additionalProperties: false,
|
|
29
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { colliderDescSchema } from './ColliderDesc';
|
|
2
|
+
import type { JSONSchemaType } from 'ajv';
|
|
3
|
+
import type { ColliderDesc } from './ColliderDesc';
|
|
4
|
+
|
|
5
|
+
export type Collider = {
|
|
6
|
+
h?: number; // collider handle for rapier
|
|
7
|
+
} & ColliderDesc;
|
|
8
|
+
|
|
9
|
+
export const colliderSchema: JSONSchemaType<Collider> = {
|
|
10
|
+
type: 'object',
|
|
11
|
+
properties: {
|
|
12
|
+
h: { type: 'number', nullable: true },
|
|
13
|
+
...colliderDescSchema.properties
|
|
14
|
+
},
|
|
15
|
+
additionalProperties: false,
|
|
16
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { shapeSchema } from './Shape';
|
|
2
|
+
import { quaternionSchema } from './Quaternion';
|
|
3
|
+
import { vectorSchema } from './Vector';
|
|
4
|
+
import type { JSONSchemaType } from 'ajv';
|
|
5
|
+
import type { Shape } from './Shape';
|
|
6
|
+
import type { Quaternion } from './Quaternion';
|
|
7
|
+
import type { Vector } from './Vector';
|
|
8
|
+
|
|
9
|
+
export type ColliderDesc = {
|
|
10
|
+
at?: number; // active collision types
|
|
11
|
+
cg?: number; // collision groups
|
|
12
|
+
cs?: number; // contact skin
|
|
13
|
+
d?: number; // density
|
|
14
|
+
f?: number; // friction
|
|
15
|
+
fr?: number; // friction combine rule
|
|
16
|
+
en?: boolean; // enabled
|
|
17
|
+
sn?: boolean; // sensor
|
|
18
|
+
m?: number; // mass
|
|
19
|
+
re?: number; // restitution
|
|
20
|
+
rer?: number; // restitution combine rule
|
|
21
|
+
r?: Quaternion; // rotation
|
|
22
|
+
s?: Shape; // shape
|
|
23
|
+
sg?: number; // solver groups
|
|
24
|
+
t?: Vector; // translation
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const colliderDescSchema: JSONSchemaType<ColliderDesc> = {
|
|
28
|
+
type: 'object',
|
|
29
|
+
properties: {
|
|
30
|
+
at: { type: 'number', nullable: true },
|
|
31
|
+
cg: { type: 'number', nullable: true },
|
|
32
|
+
cs: { type: 'number', nullable: true },
|
|
33
|
+
d: { type: 'number', nullable: true },
|
|
34
|
+
f: { type: 'number', nullable: true },
|
|
35
|
+
fr: { type: 'number', nullable: true },
|
|
36
|
+
en: { type: 'boolean', nullable: true },
|
|
37
|
+
sn: { type: 'boolean', nullable: true },
|
|
38
|
+
m: { type: 'number', nullable: true },
|
|
39
|
+
re: { type: 'number', nullable: true },
|
|
40
|
+
rer: { type: 'number', nullable: true },
|
|
41
|
+
r: { ...quaternionSchema, nullable: true },
|
|
42
|
+
s: { ...shapeSchema, nullable: true },
|
|
43
|
+
sg: { type: 'number', nullable: true },
|
|
44
|
+
t: { ...vectorSchema, nullable: true },
|
|
45
|
+
},
|
|
46
|
+
additionalProperties: false,
|
|
47
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { rigidBodySchema } from './RigidBody';
|
|
2
|
+
import type { JSONSchemaType } from 'ajv';
|
|
3
|
+
import type { RigidBody } from './RigidBody';
|
|
4
|
+
|
|
5
|
+
export type Entity = {
|
|
6
|
+
wi: string; // world id
|
|
7
|
+
i: number; // entity id
|
|
8
|
+
d: boolean; // delta
|
|
9
|
+
f?: boolean; // focused
|
|
10
|
+
n?: string; // name
|
|
11
|
+
m?: string; // model uri
|
|
12
|
+
t?: string; // texture uri
|
|
13
|
+
r?: RigidBody; // rigid body
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const entitySchema: JSONSchemaType<Entity> = {
|
|
17
|
+
type: 'object',
|
|
18
|
+
properties: {
|
|
19
|
+
wi: { type: 'string' },
|
|
20
|
+
i: { type: 'number' },
|
|
21
|
+
d: { type: 'boolean' },
|
|
22
|
+
f: { type: 'boolean', nullable: true },
|
|
23
|
+
n: { type: 'string', nullable: true },
|
|
24
|
+
m: { type: 'string', nullable: true },
|
|
25
|
+
t: { type: 'string', nullable: true },
|
|
26
|
+
r: { ...rigidBodySchema, nullable: true },
|
|
27
|
+
},
|
|
28
|
+
required: [ 'wi', 'i', 'd' ],
|
|
29
|
+
additionalProperties: false,
|
|
30
|
+
}
|
package/schemas/Input.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { JSONSchemaType } from 'ajv';
|
|
2
|
+
|
|
3
|
+
export type Input = {
|
|
4
|
+
w?: boolean; // w key pressed
|
|
5
|
+
a?: boolean; // a key pressed
|
|
6
|
+
s?: boolean; // s key pressed
|
|
7
|
+
d?: boolean; // d key pressed
|
|
8
|
+
sp?: boolean; // space key pressed
|
|
9
|
+
sh?: boolean; // shift key pressed
|
|
10
|
+
ct?: boolean; // ctrl key pressed
|
|
11
|
+
tb?: boolean; // tab key pressed
|
|
12
|
+
ml?: boolean; // mouse left pressed
|
|
13
|
+
mr?: boolean; // mouse right pressed
|
|
14
|
+
cp?: number; // camera pitch radians
|
|
15
|
+
cy?: number; // camera yaw radians
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const inputSchema: JSONSchemaType<Input> = {
|
|
19
|
+
type: 'object',
|
|
20
|
+
properties: {
|
|
21
|
+
w: { type: 'boolean', nullable: true },
|
|
22
|
+
a: { type: 'boolean', nullable: true },
|
|
23
|
+
s: { type: 'boolean', nullable: true },
|
|
24
|
+
d: { type: 'boolean', nullable: true },
|
|
25
|
+
sp: { type: 'boolean', nullable: true },
|
|
26
|
+
sh: { type: 'boolean', nullable: true },
|
|
27
|
+
ct: { type: 'boolean', nullable: true },
|
|
28
|
+
tb: { type: 'boolean', nullable: true },
|
|
29
|
+
ml: { type: 'boolean', nullable: true },
|
|
30
|
+
mr: { type: 'boolean', nullable: true },
|
|
31
|
+
cp: { type: 'number', nullable: true },
|
|
32
|
+
cy: { type: 'number', nullable: true },
|
|
33
|
+
},
|
|
34
|
+
additionalProperties: false,
|
|
35
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { JSONSchemaType } from 'ajv';
|
|
2
|
+
|
|
3
|
+
export type PhysicsDebugRender = {
|
|
4
|
+
wi: number; // world id
|
|
5
|
+
v: number[]; // rapier debug render vertices
|
|
6
|
+
c: number[]; // rapier debug render colors
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const physicsDebugRenderSchema: JSONSchemaType<PhysicsDebugRender> = {
|
|
10
|
+
type: 'object',
|
|
11
|
+
properties: {
|
|
12
|
+
wi: { type: 'number' },
|
|
13
|
+
v: { type: 'array', items: { type: 'number' } },
|
|
14
|
+
c: { type: 'array', items: { type: 'number' } },
|
|
15
|
+
},
|
|
16
|
+
required: [ 'wi', 'v', 'c' ],
|
|
17
|
+
additionalProperties: false,
|
|
18
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { JSONSchemaType } from 'ajv';
|
|
2
|
+
|
|
3
|
+
export type Quaternion = [
|
|
4
|
+
number, // x
|
|
5
|
+
number, // y
|
|
6
|
+
number, // z
|
|
7
|
+
number, // w
|
|
8
|
+
];
|
|
9
|
+
|
|
10
|
+
export const quaternionSchema: JSONSchemaType<Quaternion> = {
|
|
11
|
+
type: 'array',
|
|
12
|
+
items: [
|
|
13
|
+
{ type: 'number' },
|
|
14
|
+
{ type: 'number' },
|
|
15
|
+
{ type: 'number' },
|
|
16
|
+
{ type: 'number' }
|
|
17
|
+
],
|
|
18
|
+
minItems: 4,
|
|
19
|
+
maxItems: 4
|
|
20
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { rigidBodyDescSchema } from './RigidBodyDesc';
|
|
2
|
+
import type { JSONSchemaType } from 'ajv';
|
|
3
|
+
import { RigidBodyDesc } from './RigidBodyDesc';
|
|
4
|
+
|
|
5
|
+
export type RigidBody = {
|
|
6
|
+
h?: number; // rigid body handle for rapier
|
|
7
|
+
} & RigidBodyDesc;
|
|
8
|
+
|
|
9
|
+
export const rigidBodySchema: JSONSchemaType<RigidBody> = {
|
|
10
|
+
type: 'object',
|
|
11
|
+
properties: {
|
|
12
|
+
handle: { type: 'number', nullable: true },
|
|
13
|
+
...rigidBodyDescSchema.properties,
|
|
14
|
+
},
|
|
15
|
+
additionalProperties: false,
|
|
16
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { colliderSchema } from './Collider';
|
|
2
|
+
import { vectorSchema } from './Vector';
|
|
3
|
+
import { vectorBooleanSchema } from './VectorBoolean'
|
|
4
|
+
import type { JSONSchemaType } from 'ajv';
|
|
5
|
+
import type { Collider } from './Collider';
|
|
6
|
+
import type { Vector } from './Vector';
|
|
7
|
+
import type { VectorBoolean } from './VectorBoolean';
|
|
8
|
+
|
|
9
|
+
export type RigidBodyDesc = {
|
|
10
|
+
ad?: number; // angular dampening
|
|
11
|
+
av?: Vector; // angular velocity
|
|
12
|
+
b?: number; // body type
|
|
13
|
+
c?: Collider[]; // colliders
|
|
14
|
+
d?: number; // dominance group
|
|
15
|
+
ce?: boolean; // ccd enabled
|
|
16
|
+
en?: boolean; // enabled
|
|
17
|
+
er?: VectorBoolean; // enabled rotations
|
|
18
|
+
et?: VectorBoolean; // enabled translations
|
|
19
|
+
g?: number; // gravity scaling
|
|
20
|
+
ld?: number; // linear damping
|
|
21
|
+
lv?: Vector; // linear velocity
|
|
22
|
+
sl?: boolean; // sleeping
|
|
23
|
+
scp?: number; // soft ccd prediction
|
|
24
|
+
t?: Vector; // translation
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const rigidBodyDescSchema: JSONSchemaType<RigidBodyDesc> = {
|
|
28
|
+
type: 'object',
|
|
29
|
+
properties: {
|
|
30
|
+
ad: { type: 'number', nullable: true },
|
|
31
|
+
av: { ...vectorSchema, nullable: true },
|
|
32
|
+
b: { type: 'number', nullable: true },
|
|
33
|
+
c: { type: 'array', items: colliderSchema, nullable: true },
|
|
34
|
+
d: { type: 'number', nullable: true },
|
|
35
|
+
ce: { type: 'boolean', nullable: true },
|
|
36
|
+
en: { type: 'boolean', nullable: true },
|
|
37
|
+
er: { ...vectorBooleanSchema, nullable: true },
|
|
38
|
+
et: { ...vectorBooleanSchema, nullable: true },
|
|
39
|
+
g: { type: 'number', nullable: true },
|
|
40
|
+
ld: { type: 'number', nullable: true },
|
|
41
|
+
lv: { ...vectorSchema, nullable: true },
|
|
42
|
+
sl: { type: 'boolean', nullable: true },
|
|
43
|
+
scp: { type: 'number', nullable: true },
|
|
44
|
+
t: { ...vectorSchema, nullable: true },
|
|
45
|
+
},
|
|
46
|
+
additionalProperties: false,
|
|
47
|
+
}
|
package/schemas/Shape.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { JSONSchemaType } from 'ajv';
|
|
2
|
+
import { vectorSchema } from './Vector';
|
|
3
|
+
import type { Vector } from './Vector';
|
|
4
|
+
|
|
5
|
+
export type Shape = {
|
|
6
|
+
t?: number; // type
|
|
7
|
+
b?: number; // border radius
|
|
8
|
+
r?: number; // radius
|
|
9
|
+
hx?: Vector; // half extends
|
|
10
|
+
hh?: number; // half height
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const shapeSchema: JSONSchemaType<Shape> = {
|
|
14
|
+
type: 'object',
|
|
15
|
+
properties: {
|
|
16
|
+
t: { type: 'number', nullable: true },
|
|
17
|
+
b: { type: 'number', nullable: true },
|
|
18
|
+
r: { type: 'number', nullable: true },
|
|
19
|
+
hx: { ...vectorSchema, nullable: true },
|
|
20
|
+
hh: { type: 'number', nullable: true },
|
|
21
|
+
},
|
|
22
|
+
additionalProperties: false,
|
|
23
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { JSONSchemaType } from 'ajv';
|
|
2
|
+
|
|
3
|
+
export type Vector = [
|
|
4
|
+
number, // x
|
|
5
|
+
number, // y
|
|
6
|
+
number, // z
|
|
7
|
+
];
|
|
8
|
+
|
|
9
|
+
export const vectorSchema: JSONSchemaType<Vector> = {
|
|
10
|
+
type: 'array',
|
|
11
|
+
items: [
|
|
12
|
+
{ type: 'number' },
|
|
13
|
+
{ type: 'number' },
|
|
14
|
+
{ type: 'number' }
|
|
15
|
+
],
|
|
16
|
+
minItems: 3,
|
|
17
|
+
maxItems: 3
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { JSONSchemaType } from 'ajv';
|
|
2
|
+
|
|
3
|
+
export type VectorBoolean = [
|
|
4
|
+
boolean, // x
|
|
5
|
+
boolean, // y
|
|
6
|
+
boolean, // z
|
|
7
|
+
];
|
|
8
|
+
|
|
9
|
+
export const vectorBooleanSchema: JSONSchemaType<VectorBoolean> = {
|
|
10
|
+
type: 'array',
|
|
11
|
+
items: [
|
|
12
|
+
{ type: 'boolean' },
|
|
13
|
+
{ type: 'boolean' },
|
|
14
|
+
{ type: 'boolean' }
|
|
15
|
+
],
|
|
16
|
+
minItems: 3,
|
|
17
|
+
maxItems: 3
|
|
18
|
+
}
|
package/shared/Ajv.ts
ADDED