dredless 0.7.0 → 1.0.1
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/README.md +22 -58
- package/dist/browser/dredless.global.js +794 -98
- package/dist/browser/dredless.global.js.map +4 -4
- package/docs/ACCOUNT.md +146 -0
- package/docs/API_REFERENCE.md +63 -2563
- package/docs/BROWSER_API.md +151 -70
- package/docs/CLIENT.md +183 -0
- package/docs/EVENTS.md +136 -0
- package/docs/GETTING_STARTED.md +135 -0
- package/docs/MACHINES.md +351 -0
- package/docs/MANAGEMENT.md +285 -0
- package/docs/NODE_API.md +120 -318
- package/docs/PLAYER_INVENTORY.md +235 -0
- package/docs/PROTOCOL.md +227 -0
- package/docs/README.md +44 -0
- package/docs/TROUBLESHOOTING.md +91 -0
- package/docs/WORLD_STATE.md +183 -0
- package/package.json +1 -2
- package/src/browser.d.ts +31 -1
- package/src/browser.js +10 -0
- package/src/client/core.js +302 -15
- package/src/client/domains/index.js +57 -7
- package/src/client/index.d.ts +1 -1
- package/src/index.d.ts +299 -13
- package/src/index.js +10 -0
- package/src/network/account.js +182 -0
- package/src/network/disconnect.d.ts +2 -0
- package/src/network/disconnect.js +53 -0
- package/src/network/index.d.ts +1 -0
- package/src/network/index.js +1 -0
- package/src/network/invites.d.ts +0 -3
- package/src/network/invites.js +3 -40
- package/src/network/session.d.ts +2 -0
- package/src/network/session.js +21 -0
- package/src/protocol/outbound/ship-management.d.ts +66 -1
- package/src/protocol/outbound/ship-management.js +83 -0
- package/src/state/model/decoder.js +70 -10
- package/src/state/model/index.d.ts +4 -0
- package/src/state/model/state.js +22 -7
- package/src/state/world/index.js +27 -1
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# World and entity reads
|
|
2
|
+
|
|
3
|
+
[Documentation index](README.md) · [Machines](MACHINES.md) · [Events](EVENTS.md)
|
|
4
|
+
|
|
5
|
+
## Contents
|
|
6
|
+
|
|
7
|
+
- [Choose a world](#choose-a-world)
|
|
8
|
+
- [Entities and features](#entities-and-features)
|
|
9
|
+
- [Machine and other collections](#machine-and-other-collections)
|
|
10
|
+
- [Nearby ships](#nearby-ships)
|
|
11
|
+
- [Live reads and snapshots](#live-reads-and-snapshots)
|
|
12
|
+
- [Coordinates and incomplete data](#coordinates-and-incomplete-data)
|
|
13
|
+
|
|
14
|
+
## Choose a world
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
client.currentShip(): ShipDomain | null;
|
|
18
|
+
client.ship(): ShipDomain | null; // Alias of currentShip().
|
|
19
|
+
client.overworld(): OverworldDomain | null;
|
|
20
|
+
client.world(id: number): WorldDomain | null;
|
|
21
|
+
client.currentPlayerEntity(): EntityHandle | null;
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The ship world describes its interior. The overworld contains ship entities and surrounding objects. Nearby ships may be
|
|
25
|
+
represented in the overworld without their interiors being decoded. An entity ID is meaningful only together with its
|
|
26
|
+
world.
|
|
27
|
+
|
|
28
|
+
A `WorldDomain` exposes `id`, `exists()`, `entities`, `machines`, `players`, `blocks`, and `materials`, plus
|
|
29
|
+
`snapshot(options?)`. A `ShipDomain` adds `metadata`, `entity()`, and `overworldEntity`. These refer to the ship's
|
|
30
|
+
associated overworld entity when available, not its local player.
|
|
31
|
+
|
|
32
|
+
**Fragment:** read what is available now:
|
|
33
|
+
|
|
34
|
+
```js
|
|
35
|
+
const ship = client.currentShip();
|
|
36
|
+
if (ship) {
|
|
37
|
+
console.log(ship.id, ship.metadata);
|
|
38
|
+
console.log(ship.players.all());
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
World domains capture a scope. Reacquire a current-ship domain when changing ships rather than assuming an old handle
|
|
43
|
+
follows every future world transition.
|
|
44
|
+
|
|
45
|
+
## Entities and features
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
world.entities.all(): EntityHandle[];
|
|
49
|
+
world.entities.get(entity: EntityRef): EntityHandle;
|
|
50
|
+
world.entities.snapshots(): EntitySnapshot[];
|
|
51
|
+
world.entities.states(): EntitySnapshot[]; // Alias of snapshots().
|
|
52
|
+
|
|
53
|
+
type EntityRef = number | EntityHandle | EntitySummary | EntityDebugSummary;
|
|
54
|
+
|
|
55
|
+
entity.exists(): boolean;
|
|
56
|
+
entity.snapshot(): EntitySnapshot | null;
|
|
57
|
+
entity.is(type: string): boolean;
|
|
58
|
+
entity.has(feature: string): boolean;
|
|
59
|
+
entity.feature(feature: string): unknown | null;
|
|
60
|
+
entity.as(type: string): MachineHandle | null;
|
|
61
|
+
entity.openTips(options?: TipOptions): Promise<TipList>;
|
|
62
|
+
entity.use(options?: {invSlot?: number; hold?: boolean}, command?: Command): DredlessClient;
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`get()` constructs a lightweight live handle; it does not validate existence. Reads such as `id`, `type`, `position`,
|
|
66
|
+
`health`, and `features` resolve against currently decoded state. `entity.entity` is a deprecated alias for `id`.
|
|
67
|
+
|
|
68
|
+
Use feature checks for generic behavior, or narrow to machine-specific handles with `asLoader()`, `asPusher()`,
|
|
69
|
+
`asLauncher()`, `asNavigationUnit()`, `as("fabricator")`, `asCommsStation()`, `asSign()`, `asGenerator()`,
|
|
70
|
+
`asCargoHatch()`, `asCargoEjector()`, `asCannon()`, `asThruster()`, `asHelm()`, `asDoor()`, `asSpawnPoint()`,
|
|
71
|
+
`asShieldProjector()`, `asFluidTank()`, or `asExpandoBox()`.
|
|
72
|
+
|
|
73
|
+
**Fragment:** inspect an actual decoded entity instead of assuming a particular ID exists:
|
|
74
|
+
|
|
75
|
+
```js
|
|
76
|
+
const entity = client.currentShip()?.entities.all().find((item) => item.has("loader"));
|
|
77
|
+
const loader = entity?.asLoader();
|
|
78
|
+
if (loader) console.log(loader.id, loader.state);
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`EntitySnapshot` includes `id`, `entity`, `type`, `features`, `position`, `rotation`, and methods `is`, `has`, and
|
|
82
|
+
`feature`. Component data is available through `feature()`. Generic summaries contain `transform`, footprint/label/kind
|
|
83
|
+
metadata, and typed components. See `EntitySummary`, `EntityContentsSummary`, and component summary types in
|
|
84
|
+
the [declarations](../src/index.d.ts).
|
|
85
|
+
|
|
86
|
+
## Machine and other collections
|
|
87
|
+
|
|
88
|
+
`world.machines` is the typed entrypoint for machines. [Machine reference](MACHINES.md#find-a-machine) lists every
|
|
89
|
+
collection and special lookup behavior.
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
world.machines.state(): MachineSummary;
|
|
93
|
+
world.machines.raw(): MachineSummary; // Alias of state().
|
|
94
|
+
world.players.all(): PlayerSummary[];
|
|
95
|
+
world.players.current(): PlayerSummary | null;
|
|
96
|
+
world.blocks.all(): BlockSummary[];
|
|
97
|
+
world.blocks.at(x: number, y: number): BlockSummary | null;
|
|
98
|
+
world.materials.all(): MaterialSummary[];
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`MachineSummary` groups arrays such as `loaders`, `pushers`, `pusherBeams`, `launchers`, `cannons`, and `doors`. Use it
|
|
102
|
+
for bulk display; use handles for actions. Raw/summary objects should be treated as read-only even when JavaScript does
|
|
103
|
+
not freeze them.
|
|
104
|
+
|
|
105
|
+
Materials summarize decoded blocks; they are not an authoritative ship inventory. A missing collection or component can
|
|
106
|
+
reflect incomplete decoding, not an absent server object.
|
|
107
|
+
|
|
108
|
+
## Nearby ships
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
client.overworld()?.ships(options?: ShipReadOptions): ShipHandle[];
|
|
112
|
+
client.overworld()?.shipByHex(hexCode: string, options?: ShipReadOptions): ShipHandle | null;
|
|
113
|
+
client.overworld()?.shipByEntity(entity: EntityRef, options?: ShipReadOptions): ShipHandle | null;
|
|
114
|
+
|
|
115
|
+
interface ShipReadOptions {
|
|
116
|
+
includeWorld?: boolean; // true
|
|
117
|
+
includeTiles?: boolean; // false
|
|
118
|
+
includeModel?: boolean; // false
|
|
119
|
+
includeBlocks?: boolean; // false
|
|
120
|
+
sort?: "distance" | null;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
shipHandle.snapshot(): ShipReadSummary;
|
|
124
|
+
shipHandle.world(): WorldDomain | null;
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
A ship handle exposes `entity`, `name`, `hexCode`, `distance`, `worldId`, and `hasWorldData`. Its summary includes
|
|
128
|
+
position, thrust, shield, warp, control data, and optionally a decoded `world`. Distance is measured between available
|
|
129
|
+
overworld transforms; it is `null` when those positions are missing.
|
|
130
|
+
|
|
131
|
+
**Fragment:**
|
|
132
|
+
|
|
133
|
+
```js
|
|
134
|
+
const ships = client.overworld()?.ships({includeWorld: false, sort: "distance"}) ?? [];
|
|
135
|
+
for (const ship of ships) console.log(ship.hexCode, ship.name, ship.distance);
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
`includeWorld` includes data already in the client; it does not fetch another ship's interior. `hasWorldData` describes
|
|
139
|
+
the returned summary with the chosen options. Ship read handles hold a summary from the read that created them; re-query
|
|
140
|
+
for a fresh list/summary after updates.
|
|
141
|
+
|
|
142
|
+
## Live reads and snapshots
|
|
143
|
+
|
|
144
|
+
| API | Semantics |
|
|
145
|
+
|--------------------------------------------------|-------------------------------------------------------------------------------|
|
|
146
|
+
| Entity/machine handle properties | Resolve against current decoded state |
|
|
147
|
+
| `entity.snapshot()`, `entities.snapshots()` | Cloned, frozen entity snapshots, cached by source-summary identity |
|
|
148
|
+
| Machine `.state`, collection `.state()`/`.raw()` | Summary reads; no universal immutability guarantee |
|
|
149
|
+
| `shipHandle.snapshot()` | Returns the summary held by that ship read handle |
|
|
150
|
+
| `world.snapshot()` / `client.state()` | Aggregate snapshots with some copied arrays and some shared nested references |
|
|
151
|
+
|
|
152
|
+
Do not mutate returned state to configure the server. Use action/configuration methods. For historical records, select
|
|
153
|
+
the serializable fields you need and clone those fields yourself. Client/world snapshots are not a promise of deep
|
|
154
|
+
immutability.
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
world.snapshot(options?: {
|
|
158
|
+
includeTiles?: boolean;
|
|
159
|
+
includeModel?: boolean;
|
|
160
|
+
includeBlocks?: boolean;
|
|
161
|
+
}): WorldSnapshot | null;
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Tiles, raw model tables, and block materialization are opt-in because they can be large. `includeModel` includes raw
|
|
165
|
+
tables; it does not mean ordinary entity/machine summaries were otherwise missing. For direct model snapshots, the
|
|
166
|
+
corresponding raw-table option is `includeTables`.
|
|
167
|
+
|
|
168
|
+
The client also retains compatibility reads such as `client.entities(scope?)`, `client.entity(id, scope?)`, and
|
|
169
|
+
`client.shipWorld(options?)`. Prefer scoped domains for new code. Scopes are `"ship"`, `"current"`, `"overworld"`, or a
|
|
170
|
+
numeric world ID.
|
|
171
|
+
|
|
172
|
+
## Coordinates and incomplete data
|
|
173
|
+
|
|
174
|
+
Positions and distances are game/world coordinates, not browser pixels. A ship interior and the overworld are different
|
|
175
|
+
coordinate spaces. Raw transform `q*` fields are decoder internals; read normalized transforms and the explicitly named
|
|
176
|
+
angle fields instead.
|
|
177
|
+
|
|
178
|
+
Angle inputs/outputs are not uniform across all APIs: cannon outputs are radians, launcher setters take degrees, and
|
|
179
|
+
discrete direction enums have operation-specific wire mappings. [Machines](MACHINES.md) documents each one.
|
|
180
|
+
|
|
181
|
+
Readiness does not guarantee all component tables, a local player, a panel, or another ship's interior. Watch `model`/
|
|
182
|
+
`world` events, tolerate missing fields, and inspect [decode errors](PROTOCOL.md#debug-domains-and-state-classes) when
|
|
183
|
+
apparently present objects cannot be read.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dredless",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "A fully-featured and from-scratch headless drednot.io client implementation written in pure js.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/certainhuman/dredless#readme",
|
|
@@ -152,7 +152,6 @@
|
|
|
152
152
|
}
|
|
153
153
|
},
|
|
154
154
|
"dependencies": {
|
|
155
|
-
"sharp": "^0.35.4",
|
|
156
155
|
"ws": "^8.18.0"
|
|
157
156
|
},
|
|
158
157
|
"files": [
|
package/src/browser.d.ts
CHANGED
|
@@ -26,15 +26,23 @@ export {
|
|
|
26
26
|
normalizeInventoryEvent,
|
|
27
27
|
EquipmentSlot,
|
|
28
28
|
buildBanPlayerMessage,
|
|
29
|
+
buildUnbanPlayerMessage,
|
|
29
30
|
buildDemoteSelfMessage,
|
|
30
31
|
buildInviteResetMessage,
|
|
31
32
|
buildKickPlayerMessage,
|
|
32
33
|
buildPlayerListMessage,
|
|
34
|
+
buildShipRenameRequestMessage,
|
|
35
|
+
buildShipRenameCommitMessage,
|
|
33
36
|
buildShipManagementMessage,
|
|
34
37
|
buildSetPlayerRankMessage,
|
|
35
38
|
buildShipPrivacyMessage,
|
|
39
|
+
buildShipGravityMessage,
|
|
40
|
+
buildSetPatronPerksMessage,
|
|
41
|
+
GravityDirection,
|
|
42
|
+
normalizeGravityDirection,
|
|
36
43
|
buildStarterRecoveryMessage,
|
|
37
44
|
normalizeCaptainSubrank,
|
|
45
|
+
normalizeCrewLog,
|
|
38
46
|
normalizeShipPlayerList,
|
|
39
47
|
normalizePlayerRank,
|
|
40
48
|
normalizePrivacy,
|
|
@@ -82,6 +90,15 @@ export {
|
|
|
82
90
|
} from "./index.js";
|
|
83
91
|
|
|
84
92
|
export type {
|
|
93
|
+
RenameShipOptions,
|
|
94
|
+
ShipManagementOptions,
|
|
95
|
+
StarterRecoveryOptions,
|
|
96
|
+
StarterRecoveryResult,
|
|
97
|
+
CrewLog,
|
|
98
|
+
CrewLogEntry,
|
|
99
|
+
ShipGravityDirection,
|
|
100
|
+
ShipPatronPerk,
|
|
101
|
+
PatronPerksResponse,
|
|
85
102
|
TipDomain,
|
|
86
103
|
TipList,
|
|
87
104
|
TipOptions,
|
|
@@ -93,6 +110,9 @@ export type {
|
|
|
93
110
|
ServerRef,
|
|
94
111
|
SessionSnapshot,
|
|
95
112
|
Account,
|
|
113
|
+
AccountDetails,
|
|
114
|
+
AccountPerkShip,
|
|
115
|
+
ClanTagDetails,
|
|
96
116
|
ConnectionSnapshot,
|
|
97
117
|
BlueprintPlacement,
|
|
98
118
|
BlueprintPlacementMessage,
|
|
@@ -105,7 +125,7 @@ export type {
|
|
|
105
125
|
ReadWorldScope
|
|
106
126
|
} from "./index.js";
|
|
107
127
|
|
|
108
|
-
import type {Connection, DredlessClient, Server, ServerRef, SessionSnapshot, Ship, ShipList, ShipRef} from "./index.js";
|
|
128
|
+
import type {AccountDetails, AccountPerkShip, ClanTagDetails, Connection, DredlessClient, Server, ServerRef, SessionSnapshot, Ship, ShipList, ShipRef} from "./index.js";
|
|
109
129
|
|
|
110
130
|
|
|
111
131
|
export class BrowserSession {
|
|
@@ -139,6 +159,16 @@ export class BrowserSession {
|
|
|
139
159
|
|
|
140
160
|
fetchAccountStatus(): Promise<unknown>;
|
|
141
161
|
|
|
162
|
+
/** Scrape the authenticated account page; does not update account/status or session serialization. */
|
|
163
|
+
fetchAccountDetails(): Promise<AccountDetails>;
|
|
164
|
+
fetchClanTag(): Promise<ClanTagDetails>;
|
|
165
|
+
/** Submit the form and confirm the stored tag on the account page. */
|
|
166
|
+
setClanTag(tag: string): Promise<ClanTagDetails>;
|
|
167
|
+
clearClanTag(): Promise<ClanTagDetails>;
|
|
168
|
+
/** Remove this account's perks and return the confirmed remaining applied ships. */
|
|
169
|
+
removeShipPerks(shipId: string | number): Promise<AccountPerkShip[]>;
|
|
170
|
+
|
|
171
|
+
|
|
142
172
|
fetchShips(server: ServerRef): Promise<Ship[]>;
|
|
143
173
|
|
|
144
174
|
fetchShipList(server: ServerRef): Promise<ShipList>;
|
package/src/browser.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export {Connection} from "./network/connection.js";
|
|
2
|
+
export {DropReason, DisconnectError, normalizeDisconnect} from "./network/disconnect.js";
|
|
2
3
|
export {DredlessClient, WrenchMode, TurretMode} from "./client/index.js";
|
|
3
4
|
export {WorldStore, WorldState} from "./state/world/index.js";
|
|
4
5
|
export {FabricatorType, ModelState, decodeModelData} from "./state/model/index.js";
|
|
@@ -18,15 +19,24 @@ export {
|
|
|
18
19
|
} from "./protocol/outbound/inventory.js";
|
|
19
20
|
export {
|
|
20
21
|
buildBanPlayerMessage,
|
|
22
|
+
buildUnbanPlayerMessage,
|
|
21
23
|
buildDemoteSelfMessage,
|
|
22
24
|
buildInviteResetMessage,
|
|
23
25
|
buildKickPlayerMessage,
|
|
24
26
|
buildPlayerListMessage,
|
|
27
|
+
buildSaveShipMessage,
|
|
28
|
+
buildShipRenameRequestMessage,
|
|
29
|
+
buildShipRenameCommitMessage,
|
|
25
30
|
buildShipManagementMessage,
|
|
26
31
|
buildSetPlayerRankMessage,
|
|
27
32
|
buildShipPrivacyMessage,
|
|
33
|
+
buildShipGravityMessage,
|
|
34
|
+
buildSetPatronPerksMessage,
|
|
35
|
+
GravityDirection,
|
|
36
|
+
normalizeGravityDirection,
|
|
28
37
|
buildStarterRecoveryMessage,
|
|
29
38
|
normalizeCaptainSubrank,
|
|
39
|
+
normalizeCrewLog,
|
|
30
40
|
normalizeShipPlayerList,
|
|
31
41
|
normalizePlayerRank,
|
|
32
42
|
normalizePrivacy,
|