@shipload/sdk 1.0.0-next.3 → 1.0.0-next.31

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.
Files changed (99) hide show
  1. package/lib/shipload.d.ts +1849 -961
  2. package/lib/shipload.js +9089 -4854
  3. package/lib/shipload.js.map +1 -1
  4. package/lib/shipload.m.js +8958 -4805
  5. package/lib/shipload.m.js.map +1 -1
  6. package/lib/testing.d.ts +856 -0
  7. package/lib/testing.js +3739 -0
  8. package/lib/testing.js.map +1 -0
  9. package/lib/testing.m.js +3733 -0
  10. package/lib/testing.m.js.map +1 -0
  11. package/package.json +15 -2
  12. package/src/capabilities/craftable.ts +51 -0
  13. package/src/capabilities/crafting.test.ts +7 -0
  14. package/src/capabilities/crafting.ts +3 -3
  15. package/src/capabilities/gathering.ts +17 -7
  16. package/src/capabilities/index.ts +0 -1
  17. package/src/capabilities/modules.ts +6 -0
  18. package/src/capabilities/storage.ts +16 -1
  19. package/src/contracts/platform.ts +231 -3
  20. package/src/contracts/server.ts +816 -471
  21. package/src/data/capabilities.ts +14 -329
  22. package/src/data/capability-formulas.ts +76 -0
  23. package/src/data/catalog.ts +0 -5
  24. package/src/data/colors.ts +14 -47
  25. package/src/data/entities.json +46 -10
  26. package/src/data/item-ids.ts +15 -12
  27. package/src/data/items.json +302 -38
  28. package/src/data/kind-registry.json +85 -0
  29. package/src/data/kind-registry.ts +150 -0
  30. package/src/data/metadata.ts +100 -31
  31. package/src/data/recipes-runtime.ts +3 -23
  32. package/src/data/recipes.json +250 -113
  33. package/src/derivation/build-methods.ts +45 -0
  34. package/src/derivation/capabilities.ts +415 -0
  35. package/src/derivation/capability-mappings.ts +117 -0
  36. package/src/derivation/crafting.ts +23 -24
  37. package/src/derivation/index.ts +17 -2
  38. package/src/derivation/reserve-regen.ts +34 -0
  39. package/src/derivation/resources.ts +125 -38
  40. package/src/derivation/stars.test.ts +51 -0
  41. package/src/derivation/stars.ts +15 -0
  42. package/src/derivation/stats.ts +6 -6
  43. package/src/derivation/stratum.ts +15 -19
  44. package/src/derivation/tiers.ts +28 -7
  45. package/src/entities/entity.ts +98 -0
  46. package/src/entities/gamestate.ts +3 -28
  47. package/src/entities/makers.ts +91 -136
  48. package/src/entities/slot-multiplier.ts +39 -0
  49. package/src/errors.ts +10 -15
  50. package/src/format.ts +26 -4
  51. package/src/index-module.ts +189 -47
  52. package/src/managers/actions.ts +252 -83
  53. package/src/managers/base.ts +6 -2
  54. package/src/managers/construction-types.ts +79 -0
  55. package/src/managers/construction.ts +396 -0
  56. package/src/managers/context.ts +11 -1
  57. package/src/managers/entities.ts +18 -66
  58. package/src/managers/epochs.ts +40 -0
  59. package/src/managers/index.ts +17 -1
  60. package/src/managers/locations.ts +25 -29
  61. package/src/managers/nft.ts +28 -0
  62. package/src/managers/plot.ts +127 -0
  63. package/src/nft/atomicassets.abi.json +1342 -0
  64. package/src/nft/atomicassets.ts +237 -0
  65. package/src/nft/atomicdata.ts +130 -0
  66. package/src/nft/buildImmutableData.ts +321 -0
  67. package/src/nft/description.ts +37 -15
  68. package/src/nft/index.ts +3 -0
  69. package/src/resolution/describe-module.ts +5 -8
  70. package/src/resolution/display-name.ts +38 -10
  71. package/src/resolution/resolve-item.ts +22 -20
  72. package/src/scheduling/accessor.ts +68 -22
  73. package/src/scheduling/availability.ts +108 -0
  74. package/src/scheduling/energy.ts +48 -0
  75. package/src/scheduling/lane-core.ts +130 -0
  76. package/src/scheduling/lanes.ts +60 -0
  77. package/src/scheduling/projection.ts +121 -94
  78. package/src/scheduling/schedule.ts +237 -103
  79. package/src/scheduling/task-cargo.ts +46 -0
  80. package/src/shipload.ts +16 -1
  81. package/src/subscriptions/manager.ts +40 -6
  82. package/src/subscriptions/mappers.ts +3 -8
  83. package/src/subscriptions/types.ts +3 -2
  84. package/src/testing/catalog-hash.ts +19 -0
  85. package/src/testing/index.ts +2 -0
  86. package/src/testing/projection-parity.ts +143 -0
  87. package/src/travel/travel.ts +90 -13
  88. package/src/types/capabilities.ts +1 -0
  89. package/src/types/index.ts +0 -1
  90. package/src/types.ts +19 -12
  91. package/src/utils/cargo.ts +27 -0
  92. package/src/utils/display-name.ts +70 -0
  93. package/src/utils/system.ts +25 -24
  94. package/src/capabilities/loading.ts +0 -8
  95. package/src/entities/container.ts +0 -108
  96. package/src/entities/ship-deploy.ts +0 -258
  97. package/src/entities/ship.ts +0 -204
  98. package/src/entities/warehouse.ts +0 -119
  99. package/src/types/entity-traits.ts +0 -69
@@ -0,0 +1,396 @@
1
+ import type {UInt64, UInt32} from '@wharfkit/antelope'
2
+ import {BaseManager} from './base'
3
+ import type {ServerContract} from '../contracts'
4
+ import {PlotManager} from './plot'
5
+ import {getItem} from '../data/catalog'
6
+ import {calc_craft_duration} from '../capabilities/crafting'
7
+ import {getLanes, getTasks} from '../scheduling/schedule'
8
+ import {TaskType} from '../types'
9
+ import type {
10
+ BuildableTarget,
11
+ FinalizerEntityRef,
12
+ InboundTransfer,
13
+ Reservation,
14
+ ScheduledBuild,
15
+ SourceCargoStack,
16
+ SourceEntityRef,
17
+ } from './construction-types'
18
+
19
+ const CONSTRUCTION_KINDS = new Set<string>(['plot'])
20
+
21
+ export class ConstructionManager extends BaseManager {
22
+ private readonly plot = new PlotManager(this.context)
23
+
24
+ getTarget(
25
+ entity: ServerContract.Types.entity_row,
26
+ cargo: ServerContract.Types.cargo_row[],
27
+ activeTask?: ServerContract.Types.task,
28
+ scheduledBuild?: ScheduledBuild
29
+ ): BuildableTarget | null {
30
+ const kind = entity.kind.toString()
31
+ if (kind === 'plot') {
32
+ return this.plot.buildableTarget(entity, cargo, activeTask, scheduledBuild)
33
+ }
34
+ return null
35
+ }
36
+
37
+ eligibleSources(
38
+ target: BuildableTarget,
39
+ entities: ServerContract.Types.entity_info[],
40
+ cargo: ServerContract.Types.cargo_row[]
41
+ ): SourceEntityRef[] {
42
+ return partitionSources(target, entities, cargo).eligible
43
+ }
44
+
45
+ unreachableSources(
46
+ target: BuildableTarget,
47
+ entities: ServerContract.Types.entity_info[],
48
+ cargo: ServerContract.Types.cargo_row[]
49
+ ): SourceEntityRef[] {
50
+ return partitionSources(target, entities, cargo).unreachable
51
+ }
52
+
53
+ partitionSources(
54
+ target: BuildableTarget,
55
+ entities: ServerContract.Types.entity_info[],
56
+ cargo: ServerContract.Types.cargo_row[]
57
+ ): {eligible: SourceEntityRef[]; unreachable: SourceEntityRef[]} {
58
+ return partitionSources(target, entities, cargo)
59
+ }
60
+
61
+ eligibleFinalizers(
62
+ target: BuildableTarget,
63
+ entities: ServerContract.Types.entity_info[]
64
+ ): FinalizerEntityRef[] {
65
+ const out: FinalizerEntityRef[] = []
66
+ for (const entity of entities) {
67
+ if (!entity.owner.equals(target.ownerName)) continue
68
+ if (entity.id.equals(target.entityId)) continue
69
+ if (!coordsEqual(entity.coordinates, target.coordinates)) continue
70
+ const speed = entity.crafter?.speed.toNumber()
71
+ if (speed === undefined) continue
72
+ out.push({
73
+ entityId: entity.id,
74
+ name: entity.id.toString(),
75
+ capability: 'crafter',
76
+ crafterSpeed: speed,
77
+ estimatedDuration: this.estimateFinalizeDuration(target, speed),
78
+ })
79
+ }
80
+ return out.sort((a, b) => a.estimatedDuration.value - b.estimatedDuration.value)
81
+ }
82
+
83
+ inboundTransfersTo(
84
+ plotId: UInt64,
85
+ entities: ServerContract.Types.entity_info[],
86
+ now: Date
87
+ ): InboundTransfer[] {
88
+ return this.inboundTransfersByTarget(entities, now).get(plotId.toString()) ?? []
89
+ }
90
+
91
+ inboundTransfersByTarget(
92
+ entities: ServerContract.Types.entity_info[],
93
+ now: Date
94
+ ): Map<string, InboundTransfer[]> {
95
+ const buckets = new Map<string, Map<string, InboundTransfer>>()
96
+ const nowMs = now.getTime()
97
+ for (const entity of entities) {
98
+ const entityIdStr = entity.id.toString()
99
+ const sourceName = entity.entity_name || entityIdStr
100
+ for (const lane of getLanes(entity)) {
101
+ const startedMs = lane.schedule.started.toDate().getTime()
102
+ let cumulativeSec = 0
103
+ for (const task of lane.schedule.tasks) {
104
+ cumulativeSec += task.duration.toNumber()
105
+ if (!isTransferTask(task)) continue
106
+ if (!task.entitytarget) continue
107
+ const projectedEndMs = startedMs + cumulativeSec * 1000
108
+ if (projectedEndMs < nowMs) continue
109
+ const targetIdStr = task.entitytarget.entity_id.toString()
110
+ const etaSeconds = Math.max(0, Math.round((projectedEndMs - nowMs) / 1000))
111
+ let perTarget = buckets.get(targetIdStr)
112
+ if (!perTarget) {
113
+ perTarget = new Map()
114
+ buckets.set(targetIdStr, perTarget)
115
+ }
116
+ for (const c of task.cargo) {
117
+ const itemId = c.item_id.toNumber()
118
+ const quantity = c.quantity.toNumber()
119
+ if (quantity === 0) continue
120
+ const key = `${entityIdStr}#${itemId}`
121
+ const existing = perTarget.get(key)
122
+ if (existing) {
123
+ existing.quantity += quantity
124
+ existing.etaSeconds = Math.min(existing.etaSeconds, etaSeconds)
125
+ } else {
126
+ perTarget.set(key, {
127
+ sourceEntityId: entity.id,
128
+ sourceEntityType: entity.type,
129
+ sourceName,
130
+ itemId,
131
+ quantity,
132
+ etaSeconds,
133
+ })
134
+ }
135
+ }
136
+ }
137
+ }
138
+ }
139
+ const out = new Map<string, InboundTransfer[]>()
140
+ for (const [targetId, perTarget] of buckets) {
141
+ out.set(targetId, Array.from(perTarget.values()))
142
+ }
143
+ return out
144
+ }
145
+
146
+ private plotReservation(
147
+ plot: ServerContract.Types.entity_info,
148
+ now: Date
149
+ ): {
150
+ builderId: UInt64
151
+ group?: UInt64
152
+ startsAt: number
153
+ completesAt: number
154
+ hasStarted: boolean
155
+ } | null {
156
+ for (const lane of getLanes(plot)) {
157
+ const startedMs = lane.schedule.started.toDate().getTime()
158
+ let startSec = 0
159
+ for (const task of lane.schedule.tasks) {
160
+ if (task.type.toNumber() === TaskType.RESERVED) {
161
+ if (!task.entitytarget) return null
162
+ const startsAt = startedMs + startSec * 1000
163
+ const completesAt = startsAt + task.duration.toNumber() * 1000
164
+ return {
165
+ builderId: task.entitytarget.entity_id,
166
+ group: task.entitygroup ?? undefined,
167
+ startsAt,
168
+ completesAt,
169
+ hasStarted: startsAt <= now.getTime(),
170
+ }
171
+ }
172
+ startSec += task.duration.toNumber()
173
+ }
174
+ }
175
+ return null
176
+ }
177
+
178
+ private builderCancelability(
179
+ builder: ServerContract.Types.entity_info | undefined,
180
+ group: UInt64 | undefined
181
+ ): {cancelable: boolean; blockingTaskCount: number} {
182
+ if (!builder || group === undefined) {
183
+ return {cancelable: false, blockingTaskCount: 0}
184
+ }
185
+ for (const lane of getLanes(builder)) {
186
+ const tasks = lane.schedule.tasks
187
+ const buildIdx = tasks.findIndex(
188
+ (t) =>
189
+ t.type.toNumber() === TaskType.BUILDPLOT &&
190
+ t.entitygroup !== undefined &&
191
+ t.entitygroup.equals(group)
192
+ )
193
+ if (buildIdx < 0) continue
194
+ const trailing = tasks.length - 1 - buildIdx
195
+ return {cancelable: trailing === 0, blockingTaskCount: trailing}
196
+ }
197
+ return {cancelable: false, blockingTaskCount: 0}
198
+ }
199
+
200
+ private buildFromReservation(
201
+ res: {
202
+ builderId: UInt64
203
+ group?: UInt64
204
+ startsAt: number
205
+ completesAt: number
206
+ hasStarted: boolean
207
+ },
208
+ builder: ServerContract.Types.entity_info | undefined
209
+ ): ScheduledBuild {
210
+ const {cancelable, blockingTaskCount} = this.builderCancelability(builder, res.group)
211
+ return {
212
+ shipId: res.builderId,
213
+ shipName: builder?.entity_name || res.builderId.toString(),
214
+ hasStarted: res.hasStarted,
215
+ startsAt: res.startsAt,
216
+ completesAt: res.completesAt,
217
+ cancelable,
218
+ blockingTaskCount,
219
+ }
220
+ }
221
+
222
+ scheduledBuildFor(
223
+ plot: ServerContract.Types.entity_info,
224
+ entities: ServerContract.Types.entity_info[],
225
+ now: Date
226
+ ): ScheduledBuild | null {
227
+ const res = this.plotReservation(plot, now)
228
+ if (!res) return null
229
+ const builder = entities.find((e) => e.id.equals(res.builderId))
230
+ return this.buildFromReservation(res, builder)
231
+ }
232
+
233
+ scheduledBuildsByTarget(
234
+ entities: ServerContract.Types.entity_info[],
235
+ now: Date
236
+ ): Map<string, ScheduledBuild> {
237
+ const byId = new Map(entities.map((e) => [e.id.toString(), e]))
238
+ const out = new Map<string, ScheduledBuild>()
239
+ for (const entity of entities) {
240
+ if (entity.type.toString() !== 'plot') continue
241
+ const res = this.plotReservation(entity, now)
242
+ if (!res) continue
243
+ const builder = byId.get(res.builderId.toString())
244
+ out.set(entity.id.toString(), this.buildFromReservation(res, builder))
245
+ }
246
+ return out
247
+ }
248
+
249
+ reservationsFrom(
250
+ sourceEntityId: UInt64,
251
+ entities: ServerContract.Types.entity_info[]
252
+ ): Reservation[] {
253
+ const source = entities.find((e) => e.id.equals(sourceEntityId))
254
+ if (!source) return []
255
+ return reservationsOf(source)
256
+ }
257
+
258
+ estimateFinalizeDuration(target: BuildableTarget, crafterSpeed: number): UInt32 {
259
+ return calc_craft_duration(crafterSpeed, target.progress.massRequired)
260
+ }
261
+
262
+ static isConstructionKind(kind: string): boolean {
263
+ return CONSTRUCTION_KINDS.has(kind)
264
+ }
265
+ }
266
+
267
+ function coordsEqual(
268
+ a: ServerContract.Types.coordinates,
269
+ b: ServerContract.Types.coordinates
270
+ ): boolean {
271
+ return a.x.equals(b.x) && a.y.equals(b.y)
272
+ }
273
+
274
+ function moduleKey(module: ServerContract.Types.module_entry): string {
275
+ const installed = module.installed
276
+ if (!installed) return `${module.type.toNumber()}:empty`
277
+
278
+ return `${module.type.toNumber()}:${installed.item_id.toNumber()}:${installed.stats.toString()}`
279
+ }
280
+
281
+ function sourceStackKey(cargo: ServerContract.Types.cargo_row): string {
282
+ return `${cargo.item_id.toNumber()}#${cargo.stats.toString()}#${(cargo.modules ?? [])
283
+ .map(moduleKey)
284
+ .join(',')}`
285
+ }
286
+
287
+ function matchRelevantCargo(
288
+ entity: ServerContract.Types.entity_info,
289
+ target: BuildableTarget,
290
+ cargo: ServerContract.Types.cargo_row[],
291
+ reservedByItem: Map<number, number>
292
+ ): SourceCargoStack[] {
293
+ const needsByItemId = new Map(
294
+ target.progress.rows.filter((row) => row.missing > 0).map((row) => [row.itemId, row])
295
+ )
296
+ const remainingReserved = new Map(reservedByItem)
297
+ const out: SourceCargoStack[] = []
298
+ for (const c of cargo) {
299
+ if (!c.entity_id.equals(entity.id)) continue
300
+ const itemId = c.item_id.toNumber()
301
+ const need = needsByItemId.get(itemId)
302
+ if (!need) continue
303
+ const gross = c.quantity.toNumber()
304
+ if (gross === 0) continue
305
+ const reservedRemaining = remainingReserved.get(itemId) ?? 0
306
+ const reserved = Math.min(gross, reservedRemaining)
307
+ const available = gross - reserved
308
+ if (reserved > 0) {
309
+ remainingReserved.set(itemId, reservedRemaining - reserved)
310
+ }
311
+ if (available === 0) continue
312
+ out.push({
313
+ key: sourceStackKey(c),
314
+ rowId: c.id,
315
+ itemId,
316
+ item: getItem(itemId),
317
+ stats: c.stats,
318
+ modules: c.modules ?? [],
319
+ available,
320
+ plotNeeds: need.missing,
321
+ reserved,
322
+ })
323
+ }
324
+ return out
325
+ }
326
+
327
+ function partitionSources(
328
+ target: BuildableTarget,
329
+ entities: ServerContract.Types.entity_info[],
330
+ cargo: ServerContract.Types.cargo_row[]
331
+ ): {eligible: SourceEntityRef[]; unreachable: SourceEntityRef[]} {
332
+ const eligible: SourceEntityRef[] = []
333
+ const unreachable: SourceEntityRef[] = []
334
+ for (const entity of entities) {
335
+ if (!entity.owner.equals(target.ownerName)) continue
336
+ if (entity.id.equals(target.entityId)) continue
337
+ if (!coordsEqual(entity.coordinates, target.coordinates)) continue
338
+ const reserved = reservedByItemFor(entity)
339
+ const relevant = matchRelevantCargo(entity, target, cargo, reserved)
340
+ if (relevant.length === 0) continue
341
+ const loaderCount = entity.loaders?.quantity.toNumber() ?? 0
342
+ const loaderTotalMass = entity.loaders?.mass.toNumber() ?? 0
343
+ const ref: SourceEntityRef = {
344
+ entityId: entity.id,
345
+ name: entity.id.toString(),
346
+ hasLoaders: loaderCount > 0,
347
+ loaderCount,
348
+ loaderTotalMass,
349
+ relevantCargo: relevant,
350
+ }
351
+ if (ref.hasLoaders) eligible.push(ref)
352
+ else unreachable.push(ref)
353
+ }
354
+ return {eligible, unreachable}
355
+ }
356
+
357
+ function isTransferTask(task: ServerContract.Types.task): boolean {
358
+ const type = task.type.toNumber()
359
+ return type === TaskType.LOAD || type === TaskType.UNLOAD
360
+ }
361
+
362
+ function reservationsOf(source: ServerContract.Types.entity_info): Reservation[] {
363
+ const out = new Map<string, Reservation>()
364
+ for (const task of getTasks(source)) {
365
+ if (!isTransferTask(task)) continue
366
+ if (!task.entitytarget) continue
367
+ const targetType = task.entitytarget.entity_type
368
+ const targetId = task.entitytarget.entity_id
369
+ for (const c of task.cargo) {
370
+ const itemId = c.item_id.toNumber()
371
+ const quantity = c.quantity.toNumber()
372
+ if (quantity === 0) continue
373
+ const key = `${targetId.toString()}#${itemId}`
374
+ const existing = out.get(key)
375
+ if (existing) {
376
+ existing.quantity += quantity
377
+ } else {
378
+ out.set(key, {
379
+ targetEntityId: targetId,
380
+ targetEntityType: targetType,
381
+ itemId,
382
+ quantity,
383
+ })
384
+ }
385
+ }
386
+ }
387
+ return Array.from(out.values())
388
+ }
389
+
390
+ function reservedByItemFor(source: ServerContract.Types.entity_info): Map<number, number> {
391
+ const out = new Map<number, number>()
392
+ for (const r of reservationsOf(source)) {
393
+ out.set(r.itemId, (out.get(r.itemId) ?? 0) + r.quantity)
394
+ }
395
+ return out
396
+ }
@@ -8,6 +8,7 @@ import {PlayersManager} from './players'
8
8
  import {LocationsManager} from './locations'
9
9
  import {EpochsManager} from './epochs'
10
10
  import {ActionsManager} from './actions'
11
+ import {NftManager} from './nft'
11
12
  import {SubscriptionsManager} from '../subscriptions/manager'
12
13
 
13
14
  export class GameContext {
@@ -16,6 +17,7 @@ export class GameContext {
16
17
  private _locations?: LocationsManager
17
18
  private _epochs?: EpochsManager
18
19
  private _actions?: ActionsManager
20
+ private _nft?: NftManager
19
21
  private _subscriptions?: SubscriptionsManager
20
22
  private _subscriptionsUrl?: string
21
23
 
@@ -25,7 +27,8 @@ export class GameContext {
25
27
  constructor(
26
28
  public readonly client: APIClient,
27
29
  public readonly server: Contract,
28
- public readonly platform: Contract
30
+ public readonly platform: Contract,
31
+ public readonly atomicAssetsAccount: string = 'atomicassets'
29
32
  ) {}
30
33
 
31
34
  get entities(): EntitiesManager {
@@ -63,6 +66,13 @@ export class GameContext {
63
66
  return this._actions
64
67
  }
65
68
 
69
+ get nft(): NftManager {
70
+ if (!this._nft) {
71
+ this._nft = new NftManager(this)
72
+ }
73
+ return this._nft
74
+ }
75
+
66
76
  setSubscriptionsUrl(url: string) {
67
77
  this._subscriptionsUrl = url
68
78
  }
@@ -1,99 +1,51 @@
1
1
  import {Name, type NameType, type UInt64Type} from '@wharfkit/antelope'
2
2
  import {BaseManager} from './base'
3
- import {Ship} from '../entities/ship'
4
- import {Warehouse} from '../entities/warehouse'
5
- import {Container} from '../entities/container'
3
+ import {Entity} from '../entities/entity'
4
+ import type {EntityTypeName} from '../data/kind-registry'
6
5
  import type {ServerContract} from '../contracts'
7
6
 
8
- export type EntityType = 'ship' | 'warehouse' | 'container' | 'location'
7
+ export type {EntityTypeName} from '../data/kind-registry'
9
8
 
10
9
  export class EntitiesManager extends BaseManager {
11
- async getEntity(type: EntityType, id: UInt64Type): Promise<Ship | Warehouse | Container> {
10
+ async getEntity(id: UInt64Type): Promise<Entity> {
12
11
  const result = await this.server.readonly('getentity', {
13
- entity_type: Name.from(type),
14
12
  entity_id: id,
15
13
  })
16
- const entityInfo = result as ServerContract.Types.entity_info
17
- return this.wrapEntity(entityInfo)
14
+ return new Entity(result as ServerContract.Types.entity_info)
15
+ }
16
+
17
+ async getProjection(id: UInt64Type, taskCount?: number): Promise<unknown> {
18
+ return this.server.readonly('getprojstate', {
19
+ entity_id: id,
20
+ task_count: taskCount,
21
+ })
18
22
  }
19
23
 
20
24
  async getEntities(
21
25
  owner: NameType | ServerContract.Types.player_row,
22
- type?: EntityType
23
- ): Promise<(Ship | Warehouse | Container)[]> {
26
+ kind?: EntityTypeName
27
+ ): Promise<Entity[]> {
24
28
  const ownerName = this.resolveOwner(owner)
25
29
  const result = await this.server.readonly('getentities', {
26
30
  owner: ownerName,
27
- entity_type: type ? Name.from(type) : null,
31
+ entity_type: kind,
28
32
  })
29
33
  const entities = result as ServerContract.Types.entity_info[]
30
- return entities.map((entity) => this.wrapEntity(entity))
34
+ return entities.map((e) => new Entity(e))
31
35
  }
32
36
 
33
37
  async getSummaries(
34
38
  owner: NameType | ServerContract.Types.player_row,
35
- type?: EntityType
39
+ kind?: EntityTypeName
36
40
  ): Promise<ServerContract.Types.entity_summary[]> {
37
41
  const ownerName = this.resolveOwner(owner)
38
42
  const result = await this.server.readonly('getsummaries', {
39
43
  owner: ownerName,
40
- entity_type: type ? Name.from(type) : null,
44
+ entity_type: kind,
41
45
  })
42
46
  return result as ServerContract.Types.entity_summary[]
43
47
  }
44
48
 
45
- async getShip(id: UInt64Type): Promise<Ship> {
46
- return (await this.getEntity('ship', id)) as Ship
47
- }
48
-
49
- async getWarehouse(id: UInt64Type): Promise<Warehouse> {
50
- return (await this.getEntity('warehouse', id)) as Warehouse
51
- }
52
-
53
- async getContainer(id: UInt64Type): Promise<Container> {
54
- return (await this.getEntity('container', id)) as Container
55
- }
56
-
57
- async getShips(owner: NameType | ServerContract.Types.player_row): Promise<Ship[]> {
58
- return (await this.getEntities(owner, 'ship')) as Ship[]
59
- }
60
-
61
- async getWarehouses(owner: NameType | ServerContract.Types.player_row): Promise<Warehouse[]> {
62
- return (await this.getEntities(owner, 'warehouse')) as Warehouse[]
63
- }
64
-
65
- async getContainers(owner: NameType | ServerContract.Types.player_row): Promise<Container[]> {
66
- return (await this.getEntities(owner, 'container')) as Container[]
67
- }
68
-
69
- async getShipSummaries(
70
- owner: NameType | ServerContract.Types.player_row
71
- ): Promise<ServerContract.Types.entity_summary[]> {
72
- return this.getSummaries(owner, 'ship')
73
- }
74
-
75
- async getWarehouseSummaries(
76
- owner: NameType | ServerContract.Types.player_row
77
- ): Promise<ServerContract.Types.entity_summary[]> {
78
- return this.getSummaries(owner, 'warehouse')
79
- }
80
-
81
- async getContainerSummaries(
82
- owner: NameType | ServerContract.Types.player_row
83
- ): Promise<ServerContract.Types.entity_summary[]> {
84
- return this.getSummaries(owner, 'container')
85
- }
86
-
87
- private wrapEntity(entity: ServerContract.Types.entity_info): Ship | Warehouse | Container {
88
- if (entity.type.equals('ship')) {
89
- return new Ship(entity)
90
- } else if (entity.type.equals('warehouse')) {
91
- return new Warehouse(entity)
92
- } else {
93
- return new Container(entity)
94
- }
95
- }
96
-
97
49
  private resolveOwner(owner: NameType | ServerContract.Types.player_row): Name {
98
50
  if (typeof owner === 'object' && owner !== null && 'owner' in owner) {
99
51
  return owner.owner
@@ -1,6 +1,7 @@
1
1
  import {UInt64, type UInt64Type} from '@wharfkit/antelope'
2
2
  import {BaseManager} from './base'
3
3
  import {type EpochInfo, getCurrentEpoch, getEpochInfo} from '../scheduling/epoch'
4
+ import type {ServerContract} from '../contracts'
4
5
 
5
6
  export class EpochsManager extends BaseManager {
6
7
  async getCurrentHeight(): Promise<UInt64> {
@@ -8,6 +9,11 @@ export class EpochsManager extends BaseManager {
8
9
  return getCurrentEpoch(game)
9
10
  }
10
11
 
12
+ async getFinalizedEpoch(reload = false): Promise<UInt64> {
13
+ const state = await this.getState(reload)
14
+ return state.currentEpoch
15
+ }
16
+
11
17
  async getCurrent(): Promise<EpochInfo> {
12
18
  const game = await this.getGame()
13
19
  const epoch = await this.getCurrentHeight()
@@ -44,4 +50,38 @@ export class EpochsManager extends BaseManager {
44
50
  const remaining = await this.getTimeRemaining()
45
51
  return durationMs <= remaining
46
52
  }
53
+
54
+ async getEpochRow(epoch: UInt64Type): Promise<ServerContract.Types.epoch_row | undefined> {
55
+ const target = UInt64.from(epoch)
56
+ return this.server.table('epoch').get(target)
57
+ }
58
+
59
+ async getActiveEpochInfo(): Promise<ServerContract.Types.epoch_row | undefined> {
60
+ const rows = await this.server.table('epoch').all()
61
+ if (rows.length === 0) {
62
+ return undefined
63
+ }
64
+ return rows[rows.length - 1]
65
+ }
66
+
67
+ async getOracles(): Promise<ServerContract.Types.oracle_row[]> {
68
+ return this.server.table('oracles').all()
69
+ }
70
+
71
+ async getThreshold(): Promise<number> {
72
+ const cfg = await this.server.table('oraclecfg').get()
73
+ return cfg ? Number(cfg.threshold) : 0
74
+ }
75
+
76
+ async getCommitsFor(epoch: UInt64Type): Promise<ServerContract.Types.commit_row[]> {
77
+ const target = UInt64.from(epoch)
78
+ const rows = await this.server.table('commit').all()
79
+ return rows.filter((r) => r.epoch.equals(target))
80
+ }
81
+
82
+ async getRevealsFor(epoch: UInt64Type): Promise<ServerContract.Types.reveal_row[]> {
83
+ const target = UInt64.from(epoch)
84
+ const rows = await this.server.table('reveal').all()
85
+ return rows.filter((r) => r.epoch.equals(target))
86
+ }
47
87
  }
@@ -1,9 +1,25 @@
1
1
  export {GameContext} from './context'
2
2
  export {BaseManager} from './base'
3
3
  export {EntitiesManager} from './entities'
4
- export type {EntityType} from './entities'
4
+ export type {EntityTypeName} from './entities'
5
5
  export {PlayersManager} from './players'
6
6
  export {LocationsManager} from './locations'
7
7
  export type {LocationStratum} from './locations'
8
8
  export {EpochsManager} from './epochs'
9
9
  export {ActionsManager} from './actions'
10
+ export {NftManager} from './nft'
11
+ export type {NftConfigForItem} from './nft'
12
+ export {PlotManager} from './plot'
13
+ export type {PlotProgress, PlotProgressInputRow} from './plot'
14
+ export {ConstructionManager} from './construction'
15
+ export type {
16
+ BuildableTarget,
17
+ BuildState,
18
+ SourceEntityRef,
19
+ SourceCargoStack,
20
+ FinalizerEntityRef,
21
+ FinalizerCapability,
22
+ InboundTransfer,
23
+ ScheduledBuild,
24
+ Reservation,
25
+ } from './construction-types'