diff --git a/apps/tools/ksp-bridge/src/krpc-adapter.ts b/apps/tools/ksp-bridge/src/krpc-adapter.ts index c71ee74..6f58100 100644 --- a/apps/tools/ksp-bridge/src/krpc-adapter.ts +++ b/apps/tools/ksp-bridge/src/krpc-adapter.ts @@ -73,6 +73,9 @@ export class KRPCAdapter { // If anything goes wrong decoding that, surface a clear // error instead of the buried protobufjs TypeError. const msg = e instanceof Error ? e.message : String(e); + const stack = e instanceof Error ? e.stack : ''; + // eslint-disable-next-line no-console + console.error('[ksp-bridge] loadServices stack:', stack); throw new Error(`kRPC loadServices (GetServices decode) failed: ${msg}`); } } diff --git a/packages/krpc-client/src/schema.ts b/packages/krpc-client/src/schema.ts index 5953eb7..51f0310 100644 --- a/packages/krpc-client/src/schema.ts +++ b/packages/krpc-client/src/schema.ts @@ -161,12 +161,33 @@ const schemaJson = { }, }, Procedure: { + // The kRPC server sends `game_scenes` (a repeated + // GameScene enum, field 6) on every Procedure. The + // GameScene enum is nested inside Procedure. We model + // it as a repeated uint32 to dodge the protobufjs + // nested-enum default-value bug, same as Type.code and + // ConnectionResponse.status. We don't actually use this + // field on the client side; it's just here so the + // decoder doesn't choke on the wire bytes. fields: { name: { type: 'string', id: 1 }, parameters: { rule: 'repeated', type: 'Parameter', id: 2 }, returnType: { type: 'Type', id: 3 }, returnIsNullable: { type: 'bool', id: 4 }, documentation: { type: 'string', id: 5 }, + gameScenes: { rule: 'repeated', type: 'uint32', id: 6 }, + }, + nested: { + GameScene: { + values: { + SPACE_CENTER: 0, + FLIGHT: 1, + TRACKING_STATION: 2, + EDITOR_VAB: 3, + EDITOR_SPH: 4, + MISSION_BUILDER: 5, + }, + }, }, }, Parameter: {