burnrate 0.1.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/LICENSE +21 -0
- package/README.md +507 -0
- package/dist/cli/format.d.ts +13 -0
- package/dist/cli/format.js +319 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.js +1121 -0
- package/dist/cli/setup.d.ts +8 -0
- package/dist/cli/setup.js +143 -0
- package/dist/core/async-engine.d.ts +411 -0
- package/dist/core/async-engine.js +2274 -0
- package/dist/core/async-worldgen.d.ts +19 -0
- package/dist/core/async-worldgen.js +221 -0
- package/dist/core/engine.d.ts +154 -0
- package/dist/core/engine.js +1104 -0
- package/dist/core/pathfinding.d.ts +38 -0
- package/dist/core/pathfinding.js +146 -0
- package/dist/core/types.d.ts +489 -0
- package/dist/core/types.js +359 -0
- package/dist/core/worldgen.d.ts +22 -0
- package/dist/core/worldgen.js +292 -0
- package/dist/db/database.d.ts +83 -0
- package/dist/db/database.js +829 -0
- package/dist/db/turso-database.d.ts +177 -0
- package/dist/db/turso-database.js +1586 -0
- package/dist/mcp/server.d.ts +7 -0
- package/dist/mcp/server.js +1877 -0
- package/dist/server/api.d.ts +8 -0
- package/dist/server/api.js +1234 -0
- package/dist/server/async-tick-server.d.ts +5 -0
- package/dist/server/async-tick-server.js +63 -0
- package/dist/server/errors.d.ts +78 -0
- package/dist/server/errors.js +156 -0
- package/dist/server/rate-limit.d.ts +22 -0
- package/dist/server/rate-limit.js +134 -0
- package/dist/server/tick-server.d.ts +9 -0
- package/dist/server/tick-server.js +114 -0
- package/dist/server/validation.d.ts +194 -0
- package/dist/server/validation.js +114 -0
- package/package.json +65 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* BURNRATE Setup CLI
|
|
4
|
+
* Configures Claude Code MCP settings for BURNRATE
|
|
5
|
+
*
|
|
6
|
+
* Usage: npx burnrate setup
|
|
7
|
+
*/
|
|
8
|
+
import fs from 'fs';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
import os from 'os';
|
|
11
|
+
import readline from 'readline';
|
|
12
|
+
const rl = readline.createInterface({
|
|
13
|
+
input: process.stdin,
|
|
14
|
+
output: process.stdout
|
|
15
|
+
});
|
|
16
|
+
function ask(question, defaultValue) {
|
|
17
|
+
const prompt = defaultValue ? `${question} [${defaultValue}]: ` : `${question}: `;
|
|
18
|
+
return new Promise((resolve) => {
|
|
19
|
+
rl.question(prompt, (answer) => {
|
|
20
|
+
resolve(answer.trim() || defaultValue || '');
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
async function main() {
|
|
25
|
+
console.log(`
|
|
26
|
+
╔══════════════════════════════════════════════════════════════╗
|
|
27
|
+
║ BURNRATE SETUP ║
|
|
28
|
+
║ The front doesn't feed itself. ║
|
|
29
|
+
╚══════════════════════════════════════════════════════════════╝
|
|
30
|
+
`);
|
|
31
|
+
// 1. Get API URL
|
|
32
|
+
const apiUrl = await ask('API server URL', 'https://api.burnrate.cc');
|
|
33
|
+
// 2. Get API key (optional — can join later)
|
|
34
|
+
const apiKey = await ask('API key (press Enter to skip — you can join in-game later)', '');
|
|
35
|
+
// 3. Validate connection
|
|
36
|
+
console.log(`\nTesting connection to ${apiUrl}...`);
|
|
37
|
+
try {
|
|
38
|
+
const response = await fetch(`${apiUrl}/health`);
|
|
39
|
+
const data = await response.json();
|
|
40
|
+
if (data.status === 'ok') {
|
|
41
|
+
console.log(` ✓ Server is online (tick ${data.tick})`);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
console.log(` ⚠ Server responded but may have issues: ${JSON.stringify(data)}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.log(` ✗ Could not reach ${apiUrl}`);
|
|
49
|
+
console.log(` Make sure the server is running and the URL is correct.`);
|
|
50
|
+
const proceed = await ask('Continue anyway? (y/n)', 'n');
|
|
51
|
+
if (proceed.toLowerCase() !== 'y') {
|
|
52
|
+
rl.close();
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// 4. If we have an API key, validate it
|
|
57
|
+
if (apiKey) {
|
|
58
|
+
console.log('\nValidating API key...');
|
|
59
|
+
try {
|
|
60
|
+
const response = await fetch(`${apiUrl}/me`, {
|
|
61
|
+
headers: { 'X-API-Key': apiKey }
|
|
62
|
+
});
|
|
63
|
+
if (response.ok) {
|
|
64
|
+
const data = await response.json();
|
|
65
|
+
console.log(` ✓ Authenticated as ${data.name} (${data.tier} tier, ${data.reputation} rep)`);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
console.log(' ✗ Invalid API key. You can set it later in your MCP config.');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
console.log(' ⚠ Could not validate key (server unreachable).');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// 5. Find MCP server path
|
|
76
|
+
// When installed via npm, the MCP server is in the package's dist/ folder
|
|
77
|
+
// When running from source, it's relative to this file
|
|
78
|
+
let mcpServerPath;
|
|
79
|
+
// Check if we're running from an npm install (dist/cli/setup.js)
|
|
80
|
+
const distPath = path.resolve(path.dirname(new URL(import.meta.url).pathname), '..', 'mcp', 'server.js');
|
|
81
|
+
if (fs.existsSync(distPath)) {
|
|
82
|
+
mcpServerPath = distPath;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
// Fallback: ask the user
|
|
86
|
+
mcpServerPath = await ask('Path to MCP server (dist/mcp/server.js)', path.join(process.cwd(), 'dist', 'mcp', 'server.js'));
|
|
87
|
+
}
|
|
88
|
+
console.log(`\nMCP server path: ${mcpServerPath}`);
|
|
89
|
+
// 6. Write Claude Code settings
|
|
90
|
+
const claudeSettingsDir = path.join(os.homedir(), '.claude');
|
|
91
|
+
const claudeSettingsPath = path.join(claudeSettingsDir, 'settings.json');
|
|
92
|
+
let settings = {};
|
|
93
|
+
if (fs.existsSync(claudeSettingsPath)) {
|
|
94
|
+
try {
|
|
95
|
+
settings = JSON.parse(fs.readFileSync(claudeSettingsPath, 'utf-8'));
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
console.log(' ⚠ Could not parse existing settings.json, creating new one.');
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (!settings.mcpServers) {
|
|
102
|
+
settings.mcpServers = {};
|
|
103
|
+
}
|
|
104
|
+
const env = {
|
|
105
|
+
BURNRATE_API_URL: apiUrl
|
|
106
|
+
};
|
|
107
|
+
if (apiKey) {
|
|
108
|
+
env.BURNRATE_API_KEY = apiKey;
|
|
109
|
+
}
|
|
110
|
+
settings.mcpServers.burnrate = {
|
|
111
|
+
command: 'node',
|
|
112
|
+
args: [mcpServerPath],
|
|
113
|
+
env
|
|
114
|
+
};
|
|
115
|
+
// Ensure directory exists
|
|
116
|
+
if (!fs.existsSync(claudeSettingsDir)) {
|
|
117
|
+
fs.mkdirSync(claudeSettingsDir, { recursive: true });
|
|
118
|
+
}
|
|
119
|
+
fs.writeFileSync(claudeSettingsPath, JSON.stringify(settings, null, 2));
|
|
120
|
+
console.log(`\n✓ Claude Code MCP settings written to ${claudeSettingsPath}`);
|
|
121
|
+
// 7. Summary
|
|
122
|
+
console.log(`
|
|
123
|
+
╔══════════════════════════════════════════════════════════════╗
|
|
124
|
+
║ SETUP COMPLETE ║
|
|
125
|
+
╠══════════════════════════════════════════════════════════════╣
|
|
126
|
+
║ ║
|
|
127
|
+
║ Restart Claude Code to load the MCP server. ║
|
|
128
|
+
║ ║
|
|
129
|
+
║ Then ask Claude: ║
|
|
130
|
+
║ "Use burnrate_join to create a character named MyName" ║
|
|
131
|
+
║ ║
|
|
132
|
+
║ Or if you already have an API key: ║
|
|
133
|
+
║ "Use burnrate_status to see my inventory" ║
|
|
134
|
+
║ ║
|
|
135
|
+
╚══════════════════════════════════════════════════════════════╝
|
|
136
|
+
`);
|
|
137
|
+
rl.close();
|
|
138
|
+
}
|
|
139
|
+
main().catch((err) => {
|
|
140
|
+
console.error('Setup failed:', err);
|
|
141
|
+
rl.close();
|
|
142
|
+
process.exit(1);
|
|
143
|
+
});
|
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BURNRATE Async Game Engine
|
|
3
|
+
* Multiplayer-ready engine using TursoDatabase
|
|
4
|
+
*/
|
|
5
|
+
import { TursoDatabase } from '../db/turso-database.js';
|
|
6
|
+
import { Player, Shipment, Unit, MarketOrder, Contract, GameEvent, getZoneEfficiency, Inventory, Resource, IntelReportWithFreshness, ContractType, FactionRank, Faction, ShipmentType, LICENSE_REQUIREMENTS, SeasonScore, TUTORIAL_CONTRACTS } from './types.js';
|
|
7
|
+
export declare class AsyncGameEngine {
|
|
8
|
+
private db;
|
|
9
|
+
constructor(db: TursoDatabase);
|
|
10
|
+
processTick(): Promise<{
|
|
11
|
+
tick: number;
|
|
12
|
+
events: GameEvent[];
|
|
13
|
+
}>;
|
|
14
|
+
private processSupplyBurn;
|
|
15
|
+
private processShipments;
|
|
16
|
+
private completeShipment;
|
|
17
|
+
private checkInterception;
|
|
18
|
+
private getRaidersOnRoute;
|
|
19
|
+
private interceptShipment;
|
|
20
|
+
private processUnitMaintenance;
|
|
21
|
+
private processContractExpiration;
|
|
22
|
+
private resetDailyActions;
|
|
23
|
+
private processFieldRegeneration;
|
|
24
|
+
private processStockpileDecay;
|
|
25
|
+
canPlayerAct(playerId: string): Promise<{
|
|
26
|
+
allowed: boolean;
|
|
27
|
+
reason?: string;
|
|
28
|
+
}>;
|
|
29
|
+
recordPlayerAction(playerId: string): Promise<void>;
|
|
30
|
+
createShipmentWithPath(playerId: string, type: 'courier' | 'freight' | 'convoy', path: string[], cargo: Partial<Inventory>): Promise<{
|
|
31
|
+
success: boolean;
|
|
32
|
+
shipment?: Shipment;
|
|
33
|
+
error?: string;
|
|
34
|
+
}>;
|
|
35
|
+
placeOrder(playerId: string, zoneId: string, resource: Resource, side: 'buy' | 'sell', price: number, quantity: number): Promise<{
|
|
36
|
+
success: boolean;
|
|
37
|
+
order?: MarketOrder;
|
|
38
|
+
error?: string;
|
|
39
|
+
}>;
|
|
40
|
+
private matchOrders;
|
|
41
|
+
private executeTrade;
|
|
42
|
+
depositSU(playerId: string, zoneId: string, amount: number): Promise<{
|
|
43
|
+
success: boolean;
|
|
44
|
+
error?: string;
|
|
45
|
+
}>;
|
|
46
|
+
depositStockpile(playerId: string, zoneId: string, resource: 'medkits' | 'comms', amount: number): Promise<{
|
|
47
|
+
success: boolean;
|
|
48
|
+
error?: string;
|
|
49
|
+
}>;
|
|
50
|
+
getZoneEfficiency(zoneId: string): Promise<{
|
|
51
|
+
success: boolean;
|
|
52
|
+
efficiency?: ReturnType<typeof getZoneEfficiency>;
|
|
53
|
+
error?: string;
|
|
54
|
+
}>;
|
|
55
|
+
scan(playerId: string, targetType: 'zone' | 'route', targetId: string): Promise<{
|
|
56
|
+
success: boolean;
|
|
57
|
+
intel?: any;
|
|
58
|
+
error?: string;
|
|
59
|
+
}>;
|
|
60
|
+
produce(playerId: string, output: string, quantity: number): Promise<{
|
|
61
|
+
success: boolean;
|
|
62
|
+
produced?: number;
|
|
63
|
+
units?: Unit[];
|
|
64
|
+
error?: string;
|
|
65
|
+
}>;
|
|
66
|
+
extract(playerId: string, quantity: number): Promise<{
|
|
67
|
+
success: boolean;
|
|
68
|
+
extracted?: {
|
|
69
|
+
resource: string;
|
|
70
|
+
amount: number;
|
|
71
|
+
};
|
|
72
|
+
error?: string;
|
|
73
|
+
}>;
|
|
74
|
+
captureZone(playerId: string, zoneId: string): Promise<{
|
|
75
|
+
success: boolean;
|
|
76
|
+
error?: string;
|
|
77
|
+
}>;
|
|
78
|
+
assignEscort(playerId: string, unitId: string, shipmentId: string): Promise<{
|
|
79
|
+
success: boolean;
|
|
80
|
+
error?: string;
|
|
81
|
+
}>;
|
|
82
|
+
listUnitForSale(playerId: string, unitId: string, price: number): Promise<{
|
|
83
|
+
success: boolean;
|
|
84
|
+
error?: string;
|
|
85
|
+
}>;
|
|
86
|
+
unlistUnit(playerId: string, unitId: string): Promise<{
|
|
87
|
+
success: boolean;
|
|
88
|
+
error?: string;
|
|
89
|
+
}>;
|
|
90
|
+
hireUnit(playerId: string, unitId: string): Promise<{
|
|
91
|
+
success: boolean;
|
|
92
|
+
unit?: Unit;
|
|
93
|
+
error?: string;
|
|
94
|
+
}>;
|
|
95
|
+
deployRaider(playerId: string, unitId: string, routeId: string): Promise<{
|
|
96
|
+
success: boolean;
|
|
97
|
+
error?: string;
|
|
98
|
+
}>;
|
|
99
|
+
createFaction(playerId: string, name: string, tag: string): Promise<{
|
|
100
|
+
success: boolean;
|
|
101
|
+
faction?: any;
|
|
102
|
+
error?: string;
|
|
103
|
+
}>;
|
|
104
|
+
joinFaction(playerId: string, factionId: string): Promise<{
|
|
105
|
+
success: boolean;
|
|
106
|
+
error?: string;
|
|
107
|
+
}>;
|
|
108
|
+
leaveFaction(playerId: string): Promise<{
|
|
109
|
+
success: boolean;
|
|
110
|
+
error?: string;
|
|
111
|
+
}>;
|
|
112
|
+
getFactionIntel(playerId: string): Promise<{
|
|
113
|
+
success: boolean;
|
|
114
|
+
intel?: IntelReportWithFreshness[];
|
|
115
|
+
error?: string;
|
|
116
|
+
}>;
|
|
117
|
+
/**
|
|
118
|
+
* Promote a faction member to a higher rank
|
|
119
|
+
*/
|
|
120
|
+
promoteFactionMember(playerId: string, targetPlayerId: string, newRank: FactionRank): Promise<{
|
|
121
|
+
success: boolean;
|
|
122
|
+
error?: string;
|
|
123
|
+
}>;
|
|
124
|
+
/**
|
|
125
|
+
* Demote a faction member to a lower rank
|
|
126
|
+
*/
|
|
127
|
+
demoteFactionMember(playerId: string, targetPlayerId: string, newRank: FactionRank): Promise<{
|
|
128
|
+
success: boolean;
|
|
129
|
+
error?: string;
|
|
130
|
+
}>;
|
|
131
|
+
/**
|
|
132
|
+
* Kick a member from the faction
|
|
133
|
+
*/
|
|
134
|
+
kickFactionMember(playerId: string, targetPlayerId: string): Promise<{
|
|
135
|
+
success: boolean;
|
|
136
|
+
error?: string;
|
|
137
|
+
}>;
|
|
138
|
+
/**
|
|
139
|
+
* Transfer faction leadership to another member
|
|
140
|
+
*/
|
|
141
|
+
transferFactionLeadership(playerId: string, targetPlayerId: string): Promise<{
|
|
142
|
+
success: boolean;
|
|
143
|
+
error?: string;
|
|
144
|
+
}>;
|
|
145
|
+
/**
|
|
146
|
+
* Deposit resources to faction treasury
|
|
147
|
+
*/
|
|
148
|
+
depositToTreasury(playerId: string, resources: Partial<Record<keyof Inventory, number>>): Promise<{
|
|
149
|
+
success: boolean;
|
|
150
|
+
error?: string;
|
|
151
|
+
}>;
|
|
152
|
+
/**
|
|
153
|
+
* Withdraw resources from faction treasury
|
|
154
|
+
*/
|
|
155
|
+
withdrawFromTreasury(playerId: string, resources: Partial<Record<keyof Inventory, number>>): Promise<{
|
|
156
|
+
success: boolean;
|
|
157
|
+
error?: string;
|
|
158
|
+
}>;
|
|
159
|
+
/**
|
|
160
|
+
* Get faction details (for members)
|
|
161
|
+
*/
|
|
162
|
+
getFactionDetails(playerId: string): Promise<{
|
|
163
|
+
success: boolean;
|
|
164
|
+
faction?: Faction;
|
|
165
|
+
myRank?: FactionRank;
|
|
166
|
+
error?: string;
|
|
167
|
+
}>;
|
|
168
|
+
/**
|
|
169
|
+
* Get available licenses and their requirements
|
|
170
|
+
*/
|
|
171
|
+
getLicenseStatus(playerId: string): Promise<{
|
|
172
|
+
success: boolean;
|
|
173
|
+
licenses?: {
|
|
174
|
+
type: ShipmentType;
|
|
175
|
+
unlocked: boolean;
|
|
176
|
+
requirements: typeof LICENSE_REQUIREMENTS[ShipmentType];
|
|
177
|
+
canUnlock: boolean;
|
|
178
|
+
}[];
|
|
179
|
+
error?: string;
|
|
180
|
+
}>;
|
|
181
|
+
/**
|
|
182
|
+
* Award reputation to a player (can be positive or negative)
|
|
183
|
+
*/
|
|
184
|
+
private awardReputation;
|
|
185
|
+
/**
|
|
186
|
+
* Get player reputation details
|
|
187
|
+
*/
|
|
188
|
+
/**
|
|
189
|
+
* Get current season information
|
|
190
|
+
*/
|
|
191
|
+
getSeasonStatus(): Promise<{
|
|
192
|
+
seasonNumber: number;
|
|
193
|
+
week: number;
|
|
194
|
+
ticksUntilWeekEnd: number;
|
|
195
|
+
ticksUntilSeasonEnd: number;
|
|
196
|
+
}>;
|
|
197
|
+
/**
|
|
198
|
+
* Get season leaderboard
|
|
199
|
+
*/
|
|
200
|
+
getLeaderboard(seasonNumber?: number, entityType?: 'player' | 'faction', limit?: number): Promise<{
|
|
201
|
+
success: boolean;
|
|
202
|
+
leaderboard?: SeasonScore[];
|
|
203
|
+
season?: number;
|
|
204
|
+
error?: string;
|
|
205
|
+
}>;
|
|
206
|
+
/**
|
|
207
|
+
* Get a player's season score
|
|
208
|
+
*/
|
|
209
|
+
getPlayerSeasonScore(playerId: string, seasonNumber?: number): Promise<{
|
|
210
|
+
success: boolean;
|
|
211
|
+
score?: SeasonScore | null;
|
|
212
|
+
rank?: number;
|
|
213
|
+
error?: string;
|
|
214
|
+
}>;
|
|
215
|
+
getReputationDetails(playerId: string): Promise<{
|
|
216
|
+
success: boolean;
|
|
217
|
+
reputation?: number;
|
|
218
|
+
title?: string;
|
|
219
|
+
nextTitle?: {
|
|
220
|
+
title: string;
|
|
221
|
+
threshold: number;
|
|
222
|
+
remaining: number;
|
|
223
|
+
} | null;
|
|
224
|
+
error?: string;
|
|
225
|
+
}>;
|
|
226
|
+
/**
|
|
227
|
+
* Unlock a license for a player
|
|
228
|
+
*/
|
|
229
|
+
unlockLicense(playerId: string, licenseType: ShipmentType): Promise<{
|
|
230
|
+
success: boolean;
|
|
231
|
+
error?: string;
|
|
232
|
+
}>;
|
|
233
|
+
/**
|
|
234
|
+
* Get a player's personal intel with freshness decay applied
|
|
235
|
+
*/
|
|
236
|
+
getPlayerIntel(playerId: string, limit?: number): Promise<{
|
|
237
|
+
success: boolean;
|
|
238
|
+
intel?: IntelReportWithFreshness[];
|
|
239
|
+
error?: string;
|
|
240
|
+
}>;
|
|
241
|
+
/**
|
|
242
|
+
* Get the most recent intel on a specific target
|
|
243
|
+
*/
|
|
244
|
+
getTargetIntel(playerId: string, targetType: 'zone' | 'route', targetId: string): Promise<{
|
|
245
|
+
success: boolean;
|
|
246
|
+
intel?: IntelReportWithFreshness | null;
|
|
247
|
+
error?: string;
|
|
248
|
+
}>;
|
|
249
|
+
/**
|
|
250
|
+
* Create a new contract
|
|
251
|
+
*/
|
|
252
|
+
createContract(playerId: string, type: ContractType, details: {
|
|
253
|
+
fromZoneId?: string;
|
|
254
|
+
toZoneId?: string;
|
|
255
|
+
resource?: Resource;
|
|
256
|
+
quantity?: number;
|
|
257
|
+
targetType?: 'zone' | 'route';
|
|
258
|
+
targetId?: string;
|
|
259
|
+
}, reward: number, deadline: number, bonus?: {
|
|
260
|
+
deadline: number;
|
|
261
|
+
credits: number;
|
|
262
|
+
}): Promise<{
|
|
263
|
+
success: boolean;
|
|
264
|
+
contract?: Contract;
|
|
265
|
+
error?: string;
|
|
266
|
+
}>;
|
|
267
|
+
/**
|
|
268
|
+
* Accept a contract
|
|
269
|
+
*/
|
|
270
|
+
acceptContract(playerId: string, contractId: string): Promise<{
|
|
271
|
+
success: boolean;
|
|
272
|
+
error?: string;
|
|
273
|
+
}>;
|
|
274
|
+
/**
|
|
275
|
+
* Complete a contract (called when conditions are met)
|
|
276
|
+
*/
|
|
277
|
+
completeContract(playerId: string, contractId: string): Promise<{
|
|
278
|
+
success: boolean;
|
|
279
|
+
reward?: {
|
|
280
|
+
credits: number;
|
|
281
|
+
reputation: number;
|
|
282
|
+
};
|
|
283
|
+
bonus?: boolean;
|
|
284
|
+
error?: string;
|
|
285
|
+
}>;
|
|
286
|
+
/**
|
|
287
|
+
* Cancel a contract (poster only, before acceptance)
|
|
288
|
+
*/
|
|
289
|
+
cancelContract(playerId: string, contractId: string): Promise<{
|
|
290
|
+
success: boolean;
|
|
291
|
+
error?: string;
|
|
292
|
+
}>;
|
|
293
|
+
/**
|
|
294
|
+
* Get contracts related to a player
|
|
295
|
+
*/
|
|
296
|
+
getMyContracts(playerId: string): Promise<{
|
|
297
|
+
success: boolean;
|
|
298
|
+
contracts?: Contract[];
|
|
299
|
+
error?: string;
|
|
300
|
+
}>;
|
|
301
|
+
/**
|
|
302
|
+
* Verify if a contract's conditions have been met
|
|
303
|
+
*/
|
|
304
|
+
private verifyContractCompletion;
|
|
305
|
+
travel(playerId: string, toZoneId: string): Promise<{
|
|
306
|
+
success: boolean;
|
|
307
|
+
error?: string;
|
|
308
|
+
}>;
|
|
309
|
+
private findRoute;
|
|
310
|
+
private recordEvent;
|
|
311
|
+
getTutorialStatus(playerId: string): Promise<{
|
|
312
|
+
success: boolean;
|
|
313
|
+
step?: number;
|
|
314
|
+
total?: number;
|
|
315
|
+
currentContract?: typeof TUTORIAL_CONTRACTS[number] | null;
|
|
316
|
+
error?: string;
|
|
317
|
+
}>;
|
|
318
|
+
completeTutorialStep(playerId: string, step: number): Promise<{
|
|
319
|
+
success: boolean;
|
|
320
|
+
step?: number;
|
|
321
|
+
reward?: {
|
|
322
|
+
credits: number;
|
|
323
|
+
reputation: number;
|
|
324
|
+
};
|
|
325
|
+
error?: string;
|
|
326
|
+
}>;
|
|
327
|
+
ensureStarterFaction(): Promise<void>;
|
|
328
|
+
createDoctrine(playerId: string, title: string, content: string): Promise<{
|
|
329
|
+
success: boolean;
|
|
330
|
+
doctrine?: any;
|
|
331
|
+
error?: string;
|
|
332
|
+
}>;
|
|
333
|
+
getFactionDoctrines(playerId: string): Promise<{
|
|
334
|
+
success: boolean;
|
|
335
|
+
doctrines?: any[];
|
|
336
|
+
error?: string;
|
|
337
|
+
}>;
|
|
338
|
+
updateDoctrine(playerId: string, doctrineId: string, content: string): Promise<{
|
|
339
|
+
success: boolean;
|
|
340
|
+
error?: string;
|
|
341
|
+
}>;
|
|
342
|
+
deleteDoctrine(playerId: string, doctrineId: string): Promise<{
|
|
343
|
+
success: boolean;
|
|
344
|
+
error?: string;
|
|
345
|
+
}>;
|
|
346
|
+
createConditionalOrder(playerId: string, zoneId: string, resource: string, side: string, triggerPrice: number, quantity: number, condition: string): Promise<{
|
|
347
|
+
success: boolean;
|
|
348
|
+
order?: any;
|
|
349
|
+
error?: string;
|
|
350
|
+
}>;
|
|
351
|
+
createTimeWeightedOrder(playerId: string, zoneId: string, resource: string, side: string, price: number, totalQuantity: number, quantityPerTick: number): Promise<{
|
|
352
|
+
success: boolean;
|
|
353
|
+
order?: any;
|
|
354
|
+
error?: string;
|
|
355
|
+
}>;
|
|
356
|
+
processConditionalOrders(tick: number): Promise<void>;
|
|
357
|
+
processTimeWeightedOrders(tick: number): Promise<void>;
|
|
358
|
+
private processAdvancedOrders;
|
|
359
|
+
registerWebhook(playerId: string, url: string, events: string[]): Promise<{
|
|
360
|
+
success: boolean;
|
|
361
|
+
webhook?: any;
|
|
362
|
+
error?: string;
|
|
363
|
+
}>;
|
|
364
|
+
getWebhooks(playerId: string): Promise<{
|
|
365
|
+
success: boolean;
|
|
366
|
+
webhooks?: any[];
|
|
367
|
+
error?: string;
|
|
368
|
+
}>;
|
|
369
|
+
deleteWebhook(playerId: string, webhookId: string): Promise<{
|
|
370
|
+
success: boolean;
|
|
371
|
+
error?: string;
|
|
372
|
+
}>;
|
|
373
|
+
triggerWebhooks(eventType: string, data: any): Promise<void>;
|
|
374
|
+
exportPlayerData(playerId: string): Promise<{
|
|
375
|
+
success: boolean;
|
|
376
|
+
data?: {
|
|
377
|
+
player: Player;
|
|
378
|
+
units: Unit[];
|
|
379
|
+
shipments: Shipment[];
|
|
380
|
+
contracts: Contract[];
|
|
381
|
+
intel: IntelReportWithFreshness[];
|
|
382
|
+
events: GameEvent[];
|
|
383
|
+
};
|
|
384
|
+
error?: string;
|
|
385
|
+
}>;
|
|
386
|
+
executeBatch(playerId: string, operations: Array<{
|
|
387
|
+
action: string;
|
|
388
|
+
params: any;
|
|
389
|
+
}>): Promise<{
|
|
390
|
+
success: boolean;
|
|
391
|
+
results?: Array<{
|
|
392
|
+
action: string;
|
|
393
|
+
result: any;
|
|
394
|
+
}>;
|
|
395
|
+
error?: string;
|
|
396
|
+
}>;
|
|
397
|
+
getFactionAnalytics(playerId: string): Promise<{
|
|
398
|
+
success: boolean;
|
|
399
|
+
analytics?: {
|
|
400
|
+
members: any[];
|
|
401
|
+
zones: any[];
|
|
402
|
+
activity: any[];
|
|
403
|
+
};
|
|
404
|
+
error?: string;
|
|
405
|
+
}>;
|
|
406
|
+
getFactionAuditLogs(playerId: string, limit?: number): Promise<{
|
|
407
|
+
success: boolean;
|
|
408
|
+
logs?: any[];
|
|
409
|
+
error?: string;
|
|
410
|
+
}>;
|
|
411
|
+
}
|