@hotbunny/hackhub-content-sdk 0.9.4 → 0.9.5

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 (3) hide show
  1. package/README.md +19 -6
  2. package/index.d.ts +16 -11
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -39,13 +39,18 @@ export default class MyMod extends Bootstrap {
39
39
 
40
40
  ## Quests
41
41
 
42
- Quests use `CreateData()` to initialize data once when the quest is first claimed. After that, access the data via `this.Data`:
42
+ Quests use a generic type parameter for type-safe data. `CreateData()` initializes the data once when the quest is first claimed. After that, access via `this.Data` and update via `this.SetData()`:
43
43
 
44
44
  ```typescript
45
45
  import { Quest, Events, Network, RegisterQuest } from "@hotbunny/hackhub-content-sdk";
46
46
 
47
+ interface InfiltrationData {
48
+ targetIp: string;
49
+ attempts: number;
50
+ }
51
+
47
52
  @RegisterQuest
48
- class InfiltrationQuest extends Quest {
53
+ class InfiltrationQuest extends Quest<InfiltrationData> {
49
54
  Name = "Infiltration";
50
55
  Title = "Server Infiltration";
51
56
  Description = "Hack into the target server and download the data.";
@@ -60,15 +65,16 @@ class InfiltrationQuest extends Quest {
60
65
  },
61
66
  ];
62
67
 
63
- CreateData() {
68
+ CreateData(): InfiltrationData {
64
69
  return {
65
70
  targetIp: Network.randomIp(),
71
+ attempts: 0,
66
72
  };
67
73
  }
68
74
 
69
75
  OnStart() {
70
76
  Network.createSubnetNetwork({
71
- ip: this.Data.targetIp,
77
+ ip: this.Data.targetIp, // fully typed
72
78
  type: "ROUTER",
73
79
  ports: [{ external: 22, internal: 22, active: true, service: "ssh" }],
74
80
  users: [Network.createUser({ username: "admin", password: "secret123" })],
@@ -76,7 +82,10 @@ class InfiltrationQuest extends Quest {
76
82
  });
77
83
 
78
84
  Events.on("Terminal.NmapScan", (data) => {
79
- if (data.ip === this.Data.targetIp) this.completeObjective("scan");
85
+ if (data.ip === this.Data.targetIp) {
86
+ this.SetData("attempts", this.Data.attempts + 1); // type-safe key & value
87
+ this.completeObjective("scan");
88
+ }
80
89
  });
81
90
 
82
91
  Events.on("Terminal.SSH.Connected", (data) => {
@@ -96,11 +105,15 @@ Quests can send in-game emails and start phone call dialogs:
96
105
 
97
106
  ```typescript
98
107
  @RegisterQuest
99
- class StoryQuest extends Quest {
108
+ class StoryQuest extends Quest<{ contacted: boolean }> {
100
109
  Name = "StoryQuest";
101
110
  Title = "Story Quest";
102
111
  Objectives = [{ name: "start", description: "Begin the mission" }];
103
112
 
113
+ CreateData() {
114
+ return { contacted: false };
115
+ }
116
+
104
117
  Mails = [
105
118
  { title: "Mission Briefing", content: "Your target is ready. Good luck." },
106
119
  ];
package/index.d.ts CHANGED
@@ -1078,31 +1078,32 @@ export declare abstract class Bootstrap {
1078
1078
  OnModPackageUnloaded(): void;
1079
1079
  }
1080
1080
  /**
1081
- * Base class for mod quests. Mod authors extend this to create custom quests.
1081
+ * Base class for mod quests. Extend with a generic type for type-safe quest data.
1082
1082
  *
1083
1083
  * @example
1084
1084
  * ```ts
1085
- * import { Quest, RegisterQuest } from "@hotbunny/hackhub-content-sdk";
1085
+ * interface MyData { targetIp: string; attempts: number; }
1086
1086
  *
1087
1087
  * @RegisterQuest
1088
- * export class HackThePlanet extends Quest {
1088
+ * export class HackThePlanet extends Quest<MyData> {
1089
1089
  * Name = "HackThePlanet";
1090
1090
  * Title = "Hack the Planet";
1091
- * Rewards = { money: 5000 };
1092
1091
  * Objectives = [
1093
1092
  * { name: "scan", description: "Scan the target with nmap" },
1094
- * { name: "exploit", description: "Exploit the vulnerability", unlocksAfter: ["scan"] },
1095
1093
  * ];
1096
1094
  *
1095
+ * CreateData() {
1096
+ * return { targetIp: "192.168.1.50", attempts: 0 };
1097
+ * }
1098
+ *
1097
1099
  * OnStart() {
1098
- * Events.on("Terminal.NmapScan", (data) => {
1099
- * if (data.ip === "192.168.1.50") this.completeObjective("scan");
1100
- * });
1100
+ * console.log(this.Data.targetIp); // fully typed
1101
+ * this.SetData("attempts", 1); // type-safe key & value
1101
1102
  * }
1102
1103
  * }
1103
1104
  * ```
1104
1105
  */
1105
- export declare abstract class Quest {
1106
+ export declare abstract class Quest<T extends Record<string, any> = Record<string, any>> {
1106
1107
  abstract Name: string;
1107
1108
  abstract Title: string;
1108
1109
  abstract Objectives: QuestObjectiveDefinition[];
@@ -1130,7 +1131,7 @@ export declare abstract class Quest {
1130
1131
  /** Phone-call dialog tree for this quest. Use this.createDialog(branch) to start. */
1131
1132
  Dialog?: QuestDialogDefinition;
1132
1133
  /** Quest data created by CreateData(). Populated at runtime by the game engine. */
1133
- Data: any;
1134
+ Data: T;
1134
1135
  /**
1135
1136
  * Called when the quest is first claimed/started.
1136
1137
  * Use this to set up event listeners for objective completion.
@@ -1143,15 +1144,19 @@ export declare abstract class Quest {
1143
1144
  /** Called when the quest's objectives listener starts (e.g. after game load). */
1144
1145
  OnObjectivesStart(): void;
1145
1146
  /** Return initial quest data. Override to provide custom data storage. */
1146
- CreateData(): any;
1147
+ CreateData(): T;
1148
+ /** Update a single key in the quest data and persist it. */
1149
+ SetData<K extends keyof T>(key: K, value: T[K]): void;
1147
1150
  /** Complete an objective by its name. */
1148
1151
  completeObjective(name: string): void;
1149
1152
  /** Send a mail from the Mails array by index. */
1150
1153
  sendMail(index: number, from?: string, to?: string): void;
1151
1154
  /** Start a phone-call dialog. Defaults to "default" branch. */
1152
1155
  createDialog(branch?: string, startIndex?: number): void;
1156
+ /** @internal */ _completeObjectiveInternal?: (index: number) => void;
1153
1157
  /** @internal */ _sendMailInternal?: (index: number, from?: string, to?: string) => void;
1154
1158
  /** @internal */ _createDialogInternal?: (branch: string, startIndex: number) => void;
1159
+ /** @internal */ _saveDataInternal?: () => void;
1155
1160
  }
1156
1161
  /**
1157
1162
  * Base class for mod websites. Mod authors extend this to create
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hotbunny/hackhub-content-sdk",
3
- "version": "0.9.4",
3
+ "version": "0.9.5",
4
4
  "description": "Official modding SDK for HackHub - Ultimate Hacker Simulator on Steam. Create custom quests, websites, terminal commands, and desktop apps.",
5
5
  "types": "index.d.ts",
6
6
  "exports": {