@shipload/sdk 1.0.0-next.24 → 1.0.0-next.26
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/lib/shipload.d.ts +114 -40
- package/lib/shipload.js +2204 -654
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +2206 -655
- package/lib/shipload.m.js.map +1 -1
- package/lib/testing.d.ts +27 -13
- package/lib/testing.js +80 -15
- package/lib/testing.js.map +1 -1
- package/lib/testing.m.js +80 -15
- package/lib/testing.m.js.map +1 -1
- package/package.json +1 -1
- package/src/capabilities/crafting.test.ts +7 -0
- package/src/capabilities/crafting.ts +3 -3
- package/src/capabilities/index.ts +0 -1
- package/src/contracts/platform.ts +21 -1
- package/src/contracts/server.ts +83 -43
- package/src/derivation/capabilities.ts +4 -3
- package/src/entities/slot-multiplier.ts +2 -0
- package/src/index-module.ts +1 -0
- package/src/managers/actions.ts +71 -20
- package/src/managers/base.ts +4 -0
- package/src/managers/construction-types.ts +12 -1
- package/src/managers/construction.ts +105 -2
- package/src/managers/context.ts +2 -1
- package/src/managers/index.ts +1 -0
- package/src/managers/plot.ts +9 -5
- package/src/nft/atomicassets.abi.json +1342 -0
- package/src/nft/atomicassets.ts +9 -3
- package/src/scheduling/schedule.ts +6 -1
- package/src/shipload.ts +11 -1
- package/src/types.ts +1 -0
- package/src/capabilities/loading.ts +0 -8
package/src/managers/actions.ts
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
import {BaseManager} from './base'
|
|
18
18
|
import type {CoordinatesType} from '../types'
|
|
19
19
|
import {ServerContract} from '../contracts'
|
|
20
|
+
import {ATOMICASSETS_ABI, SHIPLOAD_COLLECTION} from '../nft/atomicassets'
|
|
20
21
|
|
|
21
22
|
export type EntityRefInput = {
|
|
22
23
|
entityType: NameType
|
|
@@ -206,14 +207,27 @@ export class ActionsManager extends BaseManager {
|
|
|
206
207
|
})
|
|
207
208
|
}
|
|
208
209
|
|
|
210
|
+
swapmodule(
|
|
211
|
+
entityId: UInt64Type,
|
|
212
|
+
moduleIndex: number,
|
|
213
|
+
moduleRef: ServerContract.ActionParams.Type.cargo_ref
|
|
214
|
+
): Action {
|
|
215
|
+
return this.server.action('swapmodule', {
|
|
216
|
+
entity_id: UInt64.from(entityId),
|
|
217
|
+
module_index: moduleIndex,
|
|
218
|
+
module_ref: moduleRef,
|
|
219
|
+
})
|
|
220
|
+
}
|
|
221
|
+
|
|
209
222
|
async wrap(
|
|
210
223
|
owner: NameType,
|
|
211
224
|
entityId: UInt64Type,
|
|
212
225
|
nexusId: UInt64Type,
|
|
213
226
|
cargoId: UInt64Type,
|
|
214
|
-
quantity: UInt64Type
|
|
227
|
+
quantity: UInt64Type,
|
|
228
|
+
opts: {claimRam?: boolean} = {}
|
|
215
229
|
): Promise<Action[]> {
|
|
216
|
-
|
|
230
|
+
const actions: Action[] = [
|
|
217
231
|
this.platform.action('wrapcargo', {
|
|
218
232
|
game: this.server.account,
|
|
219
233
|
owner: Name.from(owner),
|
|
@@ -223,6 +237,12 @@ export class ActionsManager extends BaseManager {
|
|
|
223
237
|
quantity: UInt64.from(quantity),
|
|
224
238
|
}),
|
|
225
239
|
]
|
|
240
|
+
const claimRam =
|
|
241
|
+
opts.claimRam ?? (this.atomicAssetsAccount ?? 'atomicassets') !== 'atomicassets'
|
|
242
|
+
if (claimRam) {
|
|
243
|
+
actions.push(this.setLastPayer(owner, SHIPLOAD_COLLECTION))
|
|
244
|
+
}
|
|
245
|
+
return actions
|
|
226
246
|
}
|
|
227
247
|
|
|
228
248
|
undeploy(hostId: UInt64Type, targetId: UInt64Type): Action {
|
|
@@ -232,12 +252,19 @@ export class ActionsManager extends BaseManager {
|
|
|
232
252
|
})
|
|
233
253
|
}
|
|
234
254
|
|
|
255
|
+
claimStarter(owner: NameType): Action {
|
|
256
|
+
return this.server.action('claimstarter', {
|
|
257
|
+
owner: Name.from(owner),
|
|
258
|
+
})
|
|
259
|
+
}
|
|
260
|
+
|
|
235
261
|
async wrapEntity(
|
|
236
262
|
owner: NameType,
|
|
237
263
|
entityId: UInt64Type,
|
|
238
|
-
nexusId: UInt64Type
|
|
264
|
+
nexusId: UInt64Type,
|
|
265
|
+
opts: {claimRam?: boolean} = {}
|
|
239
266
|
): Promise<Action[]> {
|
|
240
|
-
|
|
267
|
+
const actions: Action[] = [
|
|
241
268
|
this.platform.action('wrapentity', {
|
|
242
269
|
game: this.server.account,
|
|
243
270
|
owner: Name.from(owner),
|
|
@@ -245,6 +272,12 @@ export class ActionsManager extends BaseManager {
|
|
|
245
272
|
nexus_id: UInt64.from(nexusId),
|
|
246
273
|
}),
|
|
247
274
|
]
|
|
275
|
+
const claimRam =
|
|
276
|
+
opts.claimRam ?? (this.atomicAssetsAccount ?? 'atomicassets') !== 'atomicassets'
|
|
277
|
+
if (claimRam) {
|
|
278
|
+
actions.push(this.setLastPayer(owner, SHIPLOAD_COLLECTION))
|
|
279
|
+
}
|
|
280
|
+
return actions
|
|
248
281
|
}
|
|
249
282
|
|
|
250
283
|
placecargo(owner: NameType, hostId: UInt64Type, assetId: UInt64Type): Action {
|
|
@@ -264,17 +297,20 @@ export class ActionsManager extends BaseManager {
|
|
|
264
297
|
}
|
|
265
298
|
|
|
266
299
|
transferForUnwrap(owner: NameType, assetId: UInt64Type): Action {
|
|
267
|
-
return Action.from(
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
300
|
+
return Action.from(
|
|
301
|
+
{
|
|
302
|
+
account: this.atomicAssetsAccount,
|
|
303
|
+
name: 'transfer',
|
|
304
|
+
authorization: [{actor: Name.from(owner), permission: 'active'}],
|
|
305
|
+
data: {
|
|
306
|
+
from: Name.from(owner),
|
|
307
|
+
to: this.platform.account,
|
|
308
|
+
asset_ids: [UInt64.from(assetId)],
|
|
309
|
+
memo: 'unwrap',
|
|
310
|
+
},
|
|
276
311
|
},
|
|
277
|
-
|
|
312
|
+
ATOMICASSETS_ABI
|
|
313
|
+
)
|
|
278
314
|
}
|
|
279
315
|
|
|
280
316
|
// Two top-level actions the wallet signs to unwrap an NFT into a host's cargo.
|
|
@@ -291,12 +327,27 @@ export class ActionsManager extends BaseManager {
|
|
|
291
327
|
}
|
|
292
328
|
|
|
293
329
|
setRamPayer(newPayer: NameType, assetId: UInt64Type): Action {
|
|
294
|
-
return Action.from(
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
330
|
+
return Action.from(
|
|
331
|
+
{
|
|
332
|
+
account: this.atomicAssetsAccount,
|
|
333
|
+
name: 'setrampayer',
|
|
334
|
+
authorization: [{actor: Name.from(newPayer), permission: 'active'}],
|
|
335
|
+
data: {new_payer: Name.from(newPayer), asset_id: UInt64.from(assetId)},
|
|
336
|
+
},
|
|
337
|
+
ATOMICASSETS_ABI
|
|
338
|
+
)
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
setLastPayer(owner: NameType, collectionName: NameType): Action {
|
|
342
|
+
return Action.from(
|
|
343
|
+
{
|
|
344
|
+
account: this.atomicAssetsAccount,
|
|
345
|
+
name: 'setlastpayer',
|
|
346
|
+
authorization: [{actor: Name.from(owner), permission: 'active'}],
|
|
347
|
+
data: {owner: Name.from(owner), collection_name: Name.from(collectionName)},
|
|
348
|
+
},
|
|
349
|
+
ATOMICASSETS_ABI
|
|
350
|
+
)
|
|
300
351
|
}
|
|
301
352
|
|
|
302
353
|
demolish(entityId: UInt64Type): Action {
|
package/src/managers/base.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type {Item} from '../types'
|
|
|
4
4
|
import type {Recipe} from '../data/recipes-runtime'
|
|
5
5
|
import type {PlotProgress} from './plot'
|
|
6
6
|
|
|
7
|
-
export type BuildState = 'initializing' | 'accepting' | 'ready' | 'finalizing'
|
|
7
|
+
export type BuildState = 'initializing' | 'accepting' | 'ready' | 'scheduled' | 'finalizing'
|
|
8
8
|
|
|
9
9
|
export type FinalizerCapability = 'crafter'
|
|
10
10
|
|
|
@@ -20,6 +20,7 @@ export interface BuildableTarget {
|
|
|
20
20
|
finalizeAction: Name
|
|
21
21
|
finalizerCapability: FinalizerCapability
|
|
22
22
|
activeTask?: ServerContract.Types.task
|
|
23
|
+
scheduledBuild?: ScheduledBuild
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
export interface SourceEntityRef {
|
|
@@ -60,6 +61,16 @@ export interface InboundTransfer {
|
|
|
60
61
|
etaSeconds: number
|
|
61
62
|
}
|
|
62
63
|
|
|
64
|
+
export interface ScheduledBuild {
|
|
65
|
+
shipId: UInt64
|
|
66
|
+
shipName: string
|
|
67
|
+
hasStarted: boolean
|
|
68
|
+
startsAt: number
|
|
69
|
+
completesAt: number
|
|
70
|
+
cancelable: boolean
|
|
71
|
+
blockingTaskCount: number
|
|
72
|
+
}
|
|
73
|
+
|
|
63
74
|
export interface Reservation {
|
|
64
75
|
targetEntityId: UInt64
|
|
65
76
|
targetEntityType: Name
|
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
FinalizerEntityRef,
|
|
11
11
|
InboundTransfer,
|
|
12
12
|
Reservation,
|
|
13
|
+
ScheduledBuild,
|
|
13
14
|
SourceCargoStack,
|
|
14
15
|
SourceEntityRef,
|
|
15
16
|
} from './construction-types'
|
|
@@ -22,11 +23,12 @@ export class ConstructionManager extends BaseManager {
|
|
|
22
23
|
getTarget(
|
|
23
24
|
entity: ServerContract.Types.entity_row,
|
|
24
25
|
cargo: ServerContract.Types.cargo_row[],
|
|
25
|
-
activeTask?: ServerContract.Types.task
|
|
26
|
+
activeTask?: ServerContract.Types.task,
|
|
27
|
+
scheduledBuild?: ScheduledBuild
|
|
26
28
|
): BuildableTarget | null {
|
|
27
29
|
const kind = entity.kind.toString()
|
|
28
30
|
if (kind === 'plot') {
|
|
29
|
-
return this.plot.buildableTarget(entity, cargo, activeTask)
|
|
31
|
+
return this.plot.buildableTarget(entity, cargo, activeTask, scheduledBuild)
|
|
30
32
|
}
|
|
31
33
|
return null
|
|
32
34
|
}
|
|
@@ -140,6 +142,107 @@ export class ConstructionManager extends BaseManager {
|
|
|
140
142
|
return out
|
|
141
143
|
}
|
|
142
144
|
|
|
145
|
+
private plotReservation(
|
|
146
|
+
plot: ServerContract.Types.entity_info,
|
|
147
|
+
now: Date
|
|
148
|
+
): {
|
|
149
|
+
builderId: UInt64
|
|
150
|
+
group?: UInt64
|
|
151
|
+
startsAt: number
|
|
152
|
+
completesAt: number
|
|
153
|
+
hasStarted: boolean
|
|
154
|
+
} | null {
|
|
155
|
+
const schedule = plot.schedule
|
|
156
|
+
if (!schedule) return null
|
|
157
|
+
const tasks = schedule.tasks
|
|
158
|
+
const startedMs = schedule.started.toDate().getTime()
|
|
159
|
+
let startSec = 0
|
|
160
|
+
for (const task of tasks) {
|
|
161
|
+
if (task.type.toNumber() === TaskType.RESERVED) {
|
|
162
|
+
if (!task.entitytarget) return null
|
|
163
|
+
const startsAt = startedMs + startSec * 1000
|
|
164
|
+
const completesAt = startsAt + task.duration.toNumber() * 1000
|
|
165
|
+
return {
|
|
166
|
+
builderId: task.entitytarget.entity_id,
|
|
167
|
+
group: task.entitygroup ?? undefined,
|
|
168
|
+
startsAt,
|
|
169
|
+
completesAt,
|
|
170
|
+
hasStarted: startsAt <= now.getTime(),
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
startSec += task.duration.toNumber()
|
|
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?.schedule || group === undefined) {
|
|
183
|
+
return {cancelable: false, blockingTaskCount: 0}
|
|
184
|
+
}
|
|
185
|
+
const tasks = builder.schedule.tasks
|
|
186
|
+
const buildIdx = tasks.findIndex(
|
|
187
|
+
(t) =>
|
|
188
|
+
t.type.toNumber() === TaskType.BUILDPLOT &&
|
|
189
|
+
t.entitygroup !== undefined &&
|
|
190
|
+
t.entitygroup.equals(group)
|
|
191
|
+
)
|
|
192
|
+
if (buildIdx < 0) return {cancelable: false, blockingTaskCount: 0}
|
|
193
|
+
const trailing = tasks.length - 1 - buildIdx
|
|
194
|
+
return {cancelable: trailing === 0, blockingTaskCount: trailing}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
private buildFromReservation(
|
|
198
|
+
res: {
|
|
199
|
+
builderId: UInt64
|
|
200
|
+
group?: UInt64
|
|
201
|
+
startsAt: number
|
|
202
|
+
completesAt: number
|
|
203
|
+
hasStarted: boolean
|
|
204
|
+
},
|
|
205
|
+
builder: ServerContract.Types.entity_info | undefined
|
|
206
|
+
): ScheduledBuild {
|
|
207
|
+
const {cancelable, blockingTaskCount} = this.builderCancelability(builder, res.group)
|
|
208
|
+
return {
|
|
209
|
+
shipId: res.builderId,
|
|
210
|
+
shipName: builder?.entity_name || res.builderId.toString(),
|
|
211
|
+
hasStarted: res.hasStarted,
|
|
212
|
+
startsAt: res.startsAt,
|
|
213
|
+
completesAt: res.completesAt,
|
|
214
|
+
cancelable,
|
|
215
|
+
blockingTaskCount,
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
scheduledBuildFor(
|
|
220
|
+
plot: ServerContract.Types.entity_info,
|
|
221
|
+
entities: ServerContract.Types.entity_info[],
|
|
222
|
+
now: Date
|
|
223
|
+
): ScheduledBuild | null {
|
|
224
|
+
const res = this.plotReservation(plot, now)
|
|
225
|
+
if (!res) return null
|
|
226
|
+
const builder = entities.find((e) => e.id.equals(res.builderId))
|
|
227
|
+
return this.buildFromReservation(res, builder)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
scheduledBuildsByTarget(
|
|
231
|
+
entities: ServerContract.Types.entity_info[],
|
|
232
|
+
now: Date
|
|
233
|
+
): Map<string, ScheduledBuild> {
|
|
234
|
+
const byId = new Map(entities.map((e) => [e.id.toString(), e]))
|
|
235
|
+
const out = new Map<string, ScheduledBuild>()
|
|
236
|
+
for (const entity of entities) {
|
|
237
|
+
if (entity.type.toString() !== 'plot') continue
|
|
238
|
+
const res = this.plotReservation(entity, now)
|
|
239
|
+
if (!res) continue
|
|
240
|
+
const builder = byId.get(res.builderId.toString())
|
|
241
|
+
out.set(entity.id.toString(), this.buildFromReservation(res, builder))
|
|
242
|
+
}
|
|
243
|
+
return out
|
|
244
|
+
}
|
|
245
|
+
|
|
143
246
|
reservationsFrom(
|
|
144
247
|
sourceEntityId: UInt64,
|
|
145
248
|
entities: ServerContract.Types.entity_info[]
|
package/src/managers/context.ts
CHANGED
|
@@ -27,7 +27,8 @@ export class GameContext {
|
|
|
27
27
|
constructor(
|
|
28
28
|
public readonly client: APIClient,
|
|
29
29
|
public readonly server: Contract,
|
|
30
|
-
public readonly platform: Contract
|
|
30
|
+
public readonly platform: Contract,
|
|
31
|
+
public readonly atomicAssetsAccount: string = 'atomicassets'
|
|
31
32
|
) {}
|
|
32
33
|
|
|
33
34
|
get entities(): EntitiesManager {
|
package/src/managers/index.ts
CHANGED
package/src/managers/plot.ts
CHANGED
|
@@ -6,7 +6,7 @@ import {calc_craft_duration} from '../capabilities/crafting'
|
|
|
6
6
|
import {TaskType} from '../types'
|
|
7
7
|
import {BaseManager} from './base'
|
|
8
8
|
import type {ServerContract} from '../contracts'
|
|
9
|
-
import type {BuildableTarget} from './construction-types'
|
|
9
|
+
import type {BuildableTarget, ScheduledBuild} from './construction-types'
|
|
10
10
|
|
|
11
11
|
export interface PlotProgressInputRow {
|
|
12
12
|
itemId: number
|
|
@@ -67,7 +67,8 @@ export class PlotManager extends BaseManager {
|
|
|
67
67
|
buildableTarget(
|
|
68
68
|
plot: ServerContract.Types.entity_row,
|
|
69
69
|
cargo: ServerContract.Types.cargo_row[],
|
|
70
|
-
activeTask?: ServerContract.Types.task
|
|
70
|
+
activeTask?: ServerContract.Types.task,
|
|
71
|
+
scheduledBuild?: ScheduledBuild
|
|
71
72
|
): BuildableTarget {
|
|
72
73
|
const progress = this.progress(plot, cargo)
|
|
73
74
|
const targetItemId = Number(plot.item_id.toString())
|
|
@@ -79,10 +80,12 @@ export class PlotManager extends BaseManager {
|
|
|
79
80
|
|
|
80
81
|
let state: BuildableTarget['state']
|
|
81
82
|
const taskType = activeTask?.type.toNumber()
|
|
82
|
-
if (
|
|
83
|
-
state = 'initializing'
|
|
84
|
-
} else if (taskType === TaskType.BUILDPLOT) {
|
|
83
|
+
if (scheduledBuild?.hasStarted) {
|
|
85
84
|
state = 'finalizing'
|
|
85
|
+
} else if (scheduledBuild) {
|
|
86
|
+
state = 'scheduled'
|
|
87
|
+
} else if (taskType === TaskType.CLAIMPLOT) {
|
|
88
|
+
state = 'initializing'
|
|
86
89
|
} else if (progress.isComplete) {
|
|
87
90
|
state = 'ready'
|
|
88
91
|
} else {
|
|
@@ -101,6 +104,7 @@ export class PlotManager extends BaseManager {
|
|
|
101
104
|
finalizeAction: Name.from('buildplot'),
|
|
102
105
|
finalizerCapability: 'crafter',
|
|
103
106
|
activeTask,
|
|
107
|
+
scheduledBuild,
|
|
104
108
|
}
|
|
105
109
|
}
|
|
106
110
|
|