@hotbunny/hackhub-content-sdk 0.9.6 → 0.9.8

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 (2) hide show
  1. package/README.md +98 -18
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -27,6 +27,7 @@ import { Bootstrap, RegisterModPackage } from "@hotbunny/hackhub-content-sdk";
27
27
 
28
28
  @RegisterModPackage
29
29
  export default class MyMod extends Bootstrap {
30
+
30
31
  OnModPackageLoaded() {
31
32
  console.log("Mod loaded!");
32
33
  }
@@ -34,6 +35,7 @@ export default class MyMod extends Bootstrap {
34
35
  OnModPackageUnloaded() {
35
36
  console.log("Mod unloaded");
36
37
  }
38
+
37
39
  }
38
40
  ```
39
41
 
@@ -51,10 +53,10 @@ interface InfiltrationData {
51
53
 
52
54
  @RegisterQuest
53
55
  class InfiltrationQuest extends Quest<InfiltrationData> {
56
+
54
57
  Name = "Infiltration";
55
58
  Title = "Server Infiltration";
56
59
  Description = "Hack into the target server and download the data.";
57
- Employer = { name: "Mr. X", avatar: "mrx" };
58
60
  Rewards = { money: 5000, xp: 200 };
59
61
  Objectives = [
60
62
  { name: "scan", description: "Scan the target server" },
@@ -74,18 +76,16 @@ class InfiltrationQuest extends Quest<InfiltrationData> {
74
76
 
75
77
  OnStart() {
76
78
  Network.createSubnetNetwork({
77
- ip: this.Data.targetIp, // fully typed
79
+ ip: this.Data.targetIp,
78
80
  type: "ROUTER",
79
81
  ports: [{ external: 22, internal: 22, active: true, service: "ssh" }],
80
82
  users: [Network.createUser({ username: "admin", password: "secret123" })],
81
83
  children: [],
82
84
  });
83
85
 
84
- // Use this.Events.on() — listeners are automatically cleaned up
85
- // when the quest completes or is abandoned. No memory leaks!
86
86
  this.Events.on("Terminal.NmapScan", (data) => {
87
87
  if (data.ip === this.Data.targetIp) {
88
- this.SetData("attempts", this.Data.attempts + 1); // type-safe key & value
88
+ this.SetData("attempts", this.Data.attempts + 1);
89
89
  this.completeObjective("scan");
90
90
  }
91
91
  });
@@ -98,6 +98,7 @@ class InfiltrationQuest extends Quest<InfiltrationData> {
98
98
  OnComplete() {
99
99
  Network.destroyNetwork(this.Data.targetIp);
100
100
  }
101
+
101
102
  }
102
103
  ```
103
104
 
@@ -108,14 +109,11 @@ Quests can send in-game emails and start phone call dialogs:
108
109
  ```typescript
109
110
  @RegisterQuest
110
111
  class StoryQuest extends Quest<{ contacted: boolean }> {
112
+
111
113
  Name = "StoryQuest";
112
114
  Title = "Story Quest";
113
115
  Objectives = [{ name: "start", description: "Begin the mission" }];
114
116
 
115
- CreateData() {
116
- return { contacted: false };
117
- }
118
-
119
117
  Mails = [
120
118
  { title: "Mission Briefing", content: "Your target is ready. Good luck." },
121
119
  ];
@@ -132,27 +130,68 @@ class StoryQuest extends Quest<{ contacted: boolean }> {
132
130
  ],
133
131
  };
134
132
 
133
+ CreateData() {
134
+ return { contacted: false };
135
+ }
136
+
135
137
  OnStart() {
136
138
  this.sendMail(0);
137
139
  this.createDialog("default");
138
140
  }
141
+
139
142
  }
140
143
  ```
141
144
 
142
145
  ## Websites
143
146
 
147
+ Websites use a `Pages` array. Each page has a `path`, `title`, and an `html` file rendered inside the in-game browser:
148
+
144
149
  ```typescript
145
150
  import { Website, RegisterWebsite } from "@hotbunny/hackhub-content-sdk";
146
151
 
152
+ @RegisterWebsite
153
+ class HackerForum extends Website {
154
+
155
+ SiteName = "Hacker Forum";
156
+ Host = "hackerforum.net";
157
+ Icon = "./assets/forum-icon.png";
158
+ Pages = [
159
+ { path: "/", title: "Home", html: "pages/home.html" },
160
+ { path: "/about", title: "About", html: "pages/about.html" },
161
+ ];
162
+
163
+ }
164
+ ```
165
+
166
+ You can expose TypeScript functions to your HTML pages via `Exports`:
167
+
168
+ ```typescript
147
169
  @RegisterWebsite
148
170
  class MyWebsite extends Website {
149
- SiteName = "darkforum";
150
- DisplayName = "DarkForum";
151
- Description = "Underground hacking forum";
152
- HTML = "website.html";
171
+
172
+ SiteName = "My Site";
173
+ Host = "mysite.com";
174
+ Icon = "./assets/icon.png";
175
+ Pages = [
176
+ { path: "/", title: "Home", html: "pages/home.html" },
177
+ ];
178
+
179
+ Exports = {
180
+ formatPost: (text: string) => text.toUpperCase(),
181
+ };
182
+
153
183
  }
154
184
  ```
155
185
 
186
+ In your HTML, exported functions are available as globals and SDK APIs via `HackhubSDK`:
187
+
188
+ ```html
189
+ <script>
190
+ const formatted = formatPost("hello");
191
+ HackhubSDK.Mail.send({ to: "user@mail.com", subject: "Hi" });
192
+ </script>
193
+ ```
194
+
156
195
  ## Terminal Commands
157
196
 
158
197
  ```typescript
@@ -160,12 +199,21 @@ import { Command, RegisterCommand } from "@hotbunny/hackhub-content-sdk";
160
199
 
161
200
  @RegisterCommand
162
201
  class PingCommand extends Command {
202
+
163
203
  CommandName = "myping";
164
204
  Description = "Custom ping command";
165
205
 
166
- OnCommand(args: string[], tools: any) {
167
- tools.println(`Pinging ${args[0] || "nowhere"}...`);
206
+ async Run(tools) {
207
+ const args = tools.getArgs();
208
+ if (args.length === 0) {
209
+ tools.printError("Usage: myping <ip>");
210
+ return;
211
+ }
212
+ tools.println(`Pinging ${args[0]}...`);
213
+ await tools.sleep(1000);
214
+ tools.println("Reply received.");
168
215
  }
216
+
169
217
  }
170
218
  ```
171
219
 
@@ -176,11 +224,39 @@ import { App, RegisterApp } from "@hotbunny/hackhub-content-sdk";
176
224
 
177
225
  @RegisterApp
178
226
  class MyApp extends App {
227
+
179
228
  AppName = "mytool";
180
- DisplayName = "My Tool";
181
- Description = "A custom desktop application";
229
+ Title = "My Tool";
230
+ Icon = "./assets/app-icon.png";
231
+ HTML = "app.html";
232
+ DefaultSize = { width: 600, height: 400 };
233
+
234
+ }
235
+ ```
236
+
237
+ Apps can have an App Store listing and expose functions to HTML, just like websites:
238
+
239
+ ```typescript
240
+ @RegisterApp
241
+ class PasswordGen extends App {
242
+
243
+ AppName = "passgen";
244
+ Title = "Password Generator";
245
+ Icon = "./assets/passgen.png";
182
246
  HTML = "app.html";
183
- Size = { width: 600, height: 400 };
247
+ DefaultSize = { width: 400, height: 300 };
248
+ Unlocked = true;
249
+
250
+ Store = {
251
+ title: "Password Generator",
252
+ ratings: 4.5,
253
+ description: "Generate secure passwords",
254
+ };
255
+
256
+ Exports = {
257
+ generate: (length: number) => Random.password(),
258
+ };
259
+
184
260
  }
185
261
  ```
186
262
 
@@ -193,6 +269,7 @@ import { Bootstrap, ModSettingDefinition, ModSettings, RegisterModPackage } from
193
269
 
194
270
  @RegisterModPackage
195
271
  export default class MyMod extends Bootstrap {
272
+
196
273
  Settings: ModSettingDefinition[] = [
197
274
  {
198
275
  key: "difficulty",
@@ -214,6 +291,7 @@ export default class MyMod extends Bootstrap {
214
291
  const hints = ModSettings.get<boolean>("showHints");
215
292
  console.log(`Difficulty: ${difficulty}, Hints: ${hints}`);
216
293
  }
294
+
217
295
  }
218
296
  ```
219
297
 
@@ -224,7 +302,9 @@ For fully custom settings panels, use an HTML file rendered in iframe:
224
302
  ```typescript
225
303
  @RegisterModPackage
226
304
  export default class MyMod extends Bootstrap {
305
+
227
306
  SettingsHTML = "settings.html";
307
+
228
308
  }
229
309
  ```
230
310
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hotbunny/hackhub-content-sdk",
3
- "version": "0.9.6",
3
+ "version": "0.9.8",
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": {