Initial codebase
This commit is contained in:
commit
e09210f3e0
47 changed files with 2645 additions and 0 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
save.json
|
||||||
1209
package-lock.json
generated
Normal file
1209
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
25
package.json
Normal file
25
package.json
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"name": "tech-tycoon-server",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"build": "npx tsc",
|
||||||
|
"start": "npx tsc && node dist/index.js"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"cors": "^2.8.5",
|
||||||
|
"express": "^5.1.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/cors": "^2.8.19",
|
||||||
|
"@types/express": "^5.0.5",
|
||||||
|
"@types/node": "^24.10.1",
|
||||||
|
"ts-node": "^10.9.2",
|
||||||
|
"typescript": "^5.9.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
4
src/config.json
Normal file
4
src/config.json
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"port": 2142,
|
||||||
|
"savepath": "save.json"
|
||||||
|
}
|
||||||
3
src/consts.ts
Normal file
3
src/consts.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
const WORKBENCH_SIZE = 999;
|
||||||
|
|
||||||
|
export { WORKBENCH_SIZE };
|
||||||
20
src/controllers/admin/admin.ts
Normal file
20
src/controllers/admin/admin.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { Router, type Request, type Response } from "express";
|
||||||
|
|
||||||
|
import type { ISetTimeRequest } from "./types.js";
|
||||||
|
|
||||||
|
import state from "../../state/state.js";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
router.post("/settime", (req: Request, res: Response) => {
|
||||||
|
console.log(req.body);
|
||||||
|
let request: ISetTimeRequest = req.body;
|
||||||
|
|
||||||
|
state.time = request.time;
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
message: "ok",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
||||||
5
src/controllers/admin/types.ts
Normal file
5
src/controllers/admin/types.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
interface ISetTimeRequest {
|
||||||
|
time: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { type ISetTimeRequest };
|
||||||
15
src/controllers/game/game.ts
Normal file
15
src/controllers/game/game.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { Router, type Request, type Response } from "express";
|
||||||
|
|
||||||
|
import state from "../../state/state.js";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
router.get("/time", (req: Request, res: Response) => {
|
||||||
|
res.json(state.time);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get("/player", (req: Request, res: Response) => {
|
||||||
|
res.json(state.player);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
||||||
13
src/controllers/internet/internet.ts
Normal file
13
src/controllers/internet/internet.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
import { Router, type Request, type Response } from "express";
|
||||||
|
|
||||||
|
import websites from "../../data/websites.js";
|
||||||
|
|
||||||
|
import state from "../../state/state.js";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
router.get("/websites", (req: Request, res: Response) => {
|
||||||
|
res.json(websites);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
||||||
39
src/controllers/inventory/inventory.ts
Normal file
39
src/controllers/inventory/inventory.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { Router, type Request, type Response } from "express";
|
||||||
|
|
||||||
|
import state from "../../state/state.js";
|
||||||
|
import type { MoveParams, MoveRequest } from "./types.js";
|
||||||
|
import { MoveInventory } from "../../services/inventory/inventory.js";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
router.get("/player", (req: Request, res: Response) => {
|
||||||
|
res.json(state.player.inventory);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get("/car", (req: Request, res: Response) => {
|
||||||
|
res.json(state.car.inventory);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get("/home", (req: Request, res: Response) => {
|
||||||
|
res.json(state.home.inventory);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post("/move/:id", (req: Request<MoveParams>, res: Response) => {
|
||||||
|
const id = req.params.id;
|
||||||
|
const request = req.body as MoveRequest;
|
||||||
|
|
||||||
|
const error = MoveInventory(id, request.source, request.destination, state);
|
||||||
|
if (error) {
|
||||||
|
res.json({
|
||||||
|
message: "error",
|
||||||
|
error: error,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
message: "ok",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
||||||
10
src/controllers/inventory/types.ts
Normal file
10
src/controllers/inventory/types.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
interface MoveParams {
|
||||||
|
id: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MoveRequest {
|
||||||
|
source: "player" | "car" | "home";
|
||||||
|
destination: "player" | "car" | "home" | "workbench";
|
||||||
|
}
|
||||||
|
|
||||||
|
export { type MoveParams, type MoveRequest };
|
||||||
26
src/controllers/shop/shop.ts
Normal file
26
src/controllers/shop/shop.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { Router, type Request, type Response } from "express";
|
||||||
|
|
||||||
|
import state from "../../state/state.js";
|
||||||
|
import type { IdParams } from "./types.js";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
router.get("/", (req: Request, res: Response) => {
|
||||||
|
res.json(state.shops);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get("/:id", (req: Request<IdParams>, res: Response) => {
|
||||||
|
let shop = state.shops[req.params.id];
|
||||||
|
|
||||||
|
if (shop !== undefined) {
|
||||||
|
res.json(shop);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
message: "error",
|
||||||
|
error: `shop with id ${req.params.id} doesn't exist`,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
||||||
5
src/controllers/shop/types.ts
Normal file
5
src/controllers/shop/types.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
interface IdParams {
|
||||||
|
id: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { type IdParams };
|
||||||
62
src/controllers/state/state.ts
Normal file
62
src/controllers/state/state.ts
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
import { Router, type Request, type Response } from "express";
|
||||||
|
import { readFile, writeFile } from "fs";
|
||||||
|
|
||||||
|
import { game } from "../../state/state.js";
|
||||||
|
|
||||||
|
import config from "../../config.json" with { type: "json" };
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
router.get("/load", (req: Request, res: Response) => {
|
||||||
|
readFile(config.savepath, "utf8", (err, data) => {
|
||||||
|
if (err) {
|
||||||
|
res.json({
|
||||||
|
message: "error",
|
||||||
|
error: err.message,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(game.state, JSON.parse(data));
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
message: "ok",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get("/save", (req: Request, res: Response) => {
|
||||||
|
writeFile(config.savepath, JSON.stringify(game.state), "utf8", (err) => {
|
||||||
|
if (err) {
|
||||||
|
res.json({
|
||||||
|
message: "error",
|
||||||
|
error: err.message,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
message: "ok",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get("/stop", (req: Request, res: Response) => {
|
||||||
|
writeFile(config.savepath, JSON.stringify(game.state), "utf8", (err) => {
|
||||||
|
if (err) {
|
||||||
|
res.json({
|
||||||
|
message: "error",
|
||||||
|
error: err.message,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
message: "ok",
|
||||||
|
});
|
||||||
|
|
||||||
|
process.exit(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
||||||
22
src/controllers/test/test.ts
Normal file
22
src/controllers/test/test.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { Router, type Request, type Response } from "express";
|
||||||
|
|
||||||
|
import state from "../../state/state.js";
|
||||||
|
import cpus from "../../data/items/cpus.js";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
router.get("/ping", (req: Request, res: Response) => {
|
||||||
|
res.json({ message: "pong!" });
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get("/test", (req: Request, res: Response) => {
|
||||||
|
let testItem = cpus[0];
|
||||||
|
|
||||||
|
if (testItem !== undefined) {
|
||||||
|
state.home.inventory.items.push(testItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json({ message: "test" });
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
||||||
10
src/controllers/workbench/types.ts
Normal file
10
src/controllers/workbench/types.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
interface InstallMotherboardParams {
|
||||||
|
motherboardId: number;
|
||||||
|
caseId: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RemoveMotherboardParams {
|
||||||
|
caseId: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { type InstallMotherboardParams, type RemoveMotherboardParams };
|
||||||
60
src/controllers/workbench/workbench.ts
Normal file
60
src/controllers/workbench/workbench.ts
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
import { Router, type Request, type Response } from "express";
|
||||||
|
|
||||||
|
import state from "../../state/state.js";
|
||||||
|
import type {
|
||||||
|
InstallMotherboardParams,
|
||||||
|
RemoveMotherboardParams,
|
||||||
|
} from "./types.js";
|
||||||
|
import {
|
||||||
|
InstallMotherboard,
|
||||||
|
RemoveMotherboard,
|
||||||
|
} from "../../services/workbench/workbench.js";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
router.get("/devices", (req: Request, res: Response) => {
|
||||||
|
res.json(state.home.workbench.devices);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post(
|
||||||
|
"/install/motherboard/:motherboardId/:caseId",
|
||||||
|
(req: Request<InstallMotherboardParams>, res: Response) => {
|
||||||
|
const motherboardId = req.params.motherboardId;
|
||||||
|
const caseId = req.params.caseId;
|
||||||
|
|
||||||
|
const error = InstallMotherboard(motherboardId, caseId, state);
|
||||||
|
if (error) {
|
||||||
|
res.json({
|
||||||
|
message: "error",
|
||||||
|
error: error,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
message: "ok",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
router.post(
|
||||||
|
"/remove/motherboard/:caseId",
|
||||||
|
(req: Request<RemoveMotherboardParams>, res: Response) => {
|
||||||
|
const caseId = req.params.caseId;
|
||||||
|
|
||||||
|
const error = RemoveMotherboard(caseId, state);
|
||||||
|
if (error) {
|
||||||
|
res.json({
|
||||||
|
message: "error",
|
||||||
|
error: error,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
message: "ok",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export default router;
|
||||||
7
src/data/items.ts
Normal file
7
src/data/items.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { type IItem } from "../state/item.js";
|
||||||
|
|
||||||
|
import cpus from "./items/cpus.js";
|
||||||
|
import gpus from "./items/gpus.js";
|
||||||
|
import other from "./items/other.js";
|
||||||
|
|
||||||
|
export default [...cpus, ...gpus, ...other] as IItem[];
|
||||||
15
src/data/items/cases.ts
Normal file
15
src/data/items/cases.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { FormFactorType, ItemType, type ICase } from "../../state/item.js";
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
type: ItemType.CASE,
|
||||||
|
name: "DIY Case",
|
||||||
|
formFactor: FormFactorType.E_ATX,
|
||||||
|
width: 60,
|
||||||
|
height: 70,
|
||||||
|
depth: 20,
|
||||||
|
installedDevices: [],
|
||||||
|
manufacturer: "Player",
|
||||||
|
durability: 100,
|
||||||
|
},
|
||||||
|
] as ICase[];
|
||||||
31
src/data/items/cpus.ts
Normal file
31
src/data/items/cpus.ts
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { SocketType } from "../../state/cpu.js";
|
||||||
|
import { ItemType, type ICPU } from "../../state/item.js";
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
name: "Intel Core i3-3220",
|
||||||
|
type: ItemType.CPU,
|
||||||
|
durability: 98,
|
||||||
|
cores: [
|
||||||
|
{
|
||||||
|
clockSpeed: 3400,
|
||||||
|
originalClockSpeed: 3400,
|
||||||
|
threads: 2,
|
||||||
|
cacheL1: 2000,
|
||||||
|
cacheL2: 8000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
clockSpeed: 3400,
|
||||||
|
originalClockSpeed: 3400,
|
||||||
|
threads: 2,
|
||||||
|
cacheL1: 2000,
|
||||||
|
cacheL2: 8000,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
cacheL3: 4000000,
|
||||||
|
socket: SocketType.INTEL_LGA_1155,
|
||||||
|
process: 22,
|
||||||
|
tdp: 80,
|
||||||
|
price: 200,
|
||||||
|
},
|
||||||
|
] as ICPU[];
|
||||||
3
src/data/items/gpus.ts
Normal file
3
src/data/items/gpus.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
import { ItemType, type IGPU } from "../../state/item.js";
|
||||||
|
|
||||||
|
export default [] as IGPU[];
|
||||||
25
src/data/items/motherboards.ts
Normal file
25
src/data/items/motherboards.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { SocketType } from "../../state/cpu.js";
|
||||||
|
import {
|
||||||
|
FormFactorType,
|
||||||
|
ItemType,
|
||||||
|
type IMotherboard,
|
||||||
|
} from "../../state/item.js";
|
||||||
|
import { MemoryType } from "../../state/memory.js";
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
type: ItemType.MOTHERBOARD,
|
||||||
|
name: "Generic Motherboard",
|
||||||
|
formFactor: FormFactorType.ATX,
|
||||||
|
socketCount: 1,
|
||||||
|
socket: SocketType.INTEL_LGA_1155,
|
||||||
|
memoryType: MemoryType.DDR3,
|
||||||
|
memorySlots: 2,
|
||||||
|
installedCPUs: [],
|
||||||
|
installedRAMs: [],
|
||||||
|
installedDevices: [],
|
||||||
|
connectors: [],
|
||||||
|
durability: 100,
|
||||||
|
canFitInComputerCase: true,
|
||||||
|
},
|
||||||
|
] as IMotherboard[];
|
||||||
11
src/data/items/other.ts
Normal file
11
src/data/items/other.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { ItemType, type IItem, type IScrewdriver } from "../../state/item.js";
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
type: ItemType.SCREWDRIVER,
|
||||||
|
name: "Basic screwdriver",
|
||||||
|
quality: 1,
|
||||||
|
durability: 100,
|
||||||
|
price: 5,
|
||||||
|
} as IScrewdriver,
|
||||||
|
] as IItem[];
|
||||||
22
src/data/items/psus.ts
Normal file
22
src/data/items/psus.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { ConnectorType } from "../../state/connector.js";
|
||||||
|
import { FormFactorType, ItemType, type IPSU } from "../../state/item.js";
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
type: ItemType.PSU,
|
||||||
|
name: "Generic PSU",
|
||||||
|
formFactor: FormFactorType.ATX,
|
||||||
|
connectors: [
|
||||||
|
ConnectorType.SATA_POWER,
|
||||||
|
ConnectorType.SATA_POWER,
|
||||||
|
ConnectorType.PCI_POWER_4,
|
||||||
|
ConnectorType.PCI_POWER_4,
|
||||||
|
ConnectorType.PCI_POWER_6,
|
||||||
|
],
|
||||||
|
width: 15,
|
||||||
|
height: 10,
|
||||||
|
depth: 15,
|
||||||
|
wattage: 300,
|
||||||
|
durability: 100,
|
||||||
|
},
|
||||||
|
] as IPSU[];
|
||||||
15
src/data/items/rams.ts
Normal file
15
src/data/items/rams.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { ItemType, type IRAMModule } from "../../state/item.js";
|
||||||
|
import { MemoryType } from "../../state/memory.js";
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
type: ItemType.RAM_MODULE,
|
||||||
|
name: "Generic RAM",
|
||||||
|
memoryType: MemoryType.DDR3,
|
||||||
|
originalClockSpeed: 1600,
|
||||||
|
clockSpeed: 1800,
|
||||||
|
capacity: 2,
|
||||||
|
tdp: 5,
|
||||||
|
durability: 100,
|
||||||
|
},
|
||||||
|
] as IRAMModule[];
|
||||||
8
src/data/shops.ts
Normal file
8
src/data/shops.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
import type { IShop } from "../state/types.js";
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
name: "General Store",
|
||||||
|
items: [],
|
||||||
|
},
|
||||||
|
] as IShop[];
|
||||||
5
src/data/software.ts
Normal file
5
src/data/software.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { type ISoftware } from "../state/software.js";
|
||||||
|
|
||||||
|
import os from "./software/os.js";
|
||||||
|
|
||||||
|
export default [...os] as ISoftware[];
|
||||||
11
src/data/software/os.ts
Normal file
11
src/data/software/os.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { SoftwareType, type ISoftware } from "../../state/software.js";
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
type: SoftwareType.OS,
|
||||||
|
name: "Fedora 42",
|
||||||
|
cpuUsage: 200000000,
|
||||||
|
memoryUsage: 1000000000,
|
||||||
|
storageUsage: 10000000000,
|
||||||
|
},
|
||||||
|
] as ISoftware[];
|
||||||
12
src/data/websites.ts
Normal file
12
src/data/websites.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { readFileSync } from "fs";
|
||||||
|
|
||||||
|
import type { IWebsite } from "../state/types.js";
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
name: "Portal",
|
||||||
|
ip: "123.123.123.123",
|
||||||
|
domain: "portal.org",
|
||||||
|
html: readFileSync("src/data/websites/portal.org.html").toString(),
|
||||||
|
},
|
||||||
|
] as IWebsite[];
|
||||||
12
src/data/websites/portal.org.html
Normal file
12
src/data/websites/portal.org.html
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Portal</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>Portal</h2>
|
||||||
|
<ul>
|
||||||
|
<li><a href="portal.org">Portal</a></li>
|
||||||
|
<li><a href="">ShopCenter</a></li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
137
src/helpers.ts
Normal file
137
src/helpers.ts
Normal file
|
|
@ -0,0 +1,137 @@
|
||||||
|
import { WORKBENCH_SIZE } from "./consts.js";
|
||||||
|
import { ItemType, type IItem, type IScrewdriver } from "./state/item.js";
|
||||||
|
import type { IInventory, IState, IWorkbench } from "./state/types.js";
|
||||||
|
|
||||||
|
type AllInventories = "player" | "car" | "home" | "workbench";
|
||||||
|
|
||||||
|
interface ItemContainer<T> {
|
||||||
|
index: number;
|
||||||
|
item: T;
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetItemsAsInventory = (items: IItem[]): IInventory => {
|
||||||
|
return {
|
||||||
|
size: -1,
|
||||||
|
items: items,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const GetWorkbenchAsInventory = (workbench: IWorkbench): IInventory => {
|
||||||
|
return {
|
||||||
|
size: WORKBENCH_SIZE,
|
||||||
|
items: workbench.devices,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const GetInventory = (name: AllInventories, state: IState): IInventory => {
|
||||||
|
let inventory: IInventory;
|
||||||
|
|
||||||
|
switch (name) {
|
||||||
|
case "player":
|
||||||
|
inventory = state.player.inventory;
|
||||||
|
break;
|
||||||
|
case "car":
|
||||||
|
inventory = state.car.inventory;
|
||||||
|
break;
|
||||||
|
case "home":
|
||||||
|
inventory = state.home.inventory;
|
||||||
|
break;
|
||||||
|
case "workbench":
|
||||||
|
inventory = GetWorkbenchAsInventory(state.home.workbench);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return inventory;
|
||||||
|
};
|
||||||
|
|
||||||
|
const GetItemsOfType = <T>(
|
||||||
|
itemType: ItemType,
|
||||||
|
inventories: IInventory[],
|
||||||
|
): T[] => {
|
||||||
|
const items: T[] = [];
|
||||||
|
|
||||||
|
inventories.forEach((inventory) => {
|
||||||
|
items.push(
|
||||||
|
...(inventory.items.filter(
|
||||||
|
(item) => item.type === itemType,
|
||||||
|
) as T[]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return items;
|
||||||
|
};
|
||||||
|
|
||||||
|
const GetItemOfType = <T>(
|
||||||
|
itemType: ItemType,
|
||||||
|
inventories: IInventory[],
|
||||||
|
): T | undefined => {
|
||||||
|
let item: T | undefined;
|
||||||
|
|
||||||
|
inventories.forEach((inventory) => {
|
||||||
|
const found = inventory.items.find(
|
||||||
|
(_item) => _item.type === itemType,
|
||||||
|
) as T;
|
||||||
|
if (found) {
|
||||||
|
item = found;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return item;
|
||||||
|
};
|
||||||
|
|
||||||
|
const GetItemContainerOfType = <T>(
|
||||||
|
itemType: ItemType,
|
||||||
|
inventories: IInventory[],
|
||||||
|
): ItemContainer<T> | undefined => {
|
||||||
|
let container: ItemContainer<T> | undefined;
|
||||||
|
|
||||||
|
inventories.forEach((inventory) => {
|
||||||
|
const found = inventory.items.find(
|
||||||
|
(_item) => _item.type === itemType,
|
||||||
|
) as T;
|
||||||
|
const foundIndex = inventory.items.findIndex(
|
||||||
|
(_item) => _item.type === itemType,
|
||||||
|
);
|
||||||
|
if (found && foundIndex) {
|
||||||
|
container = {
|
||||||
|
index: foundIndex,
|
||||||
|
item: found,
|
||||||
|
};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return container;
|
||||||
|
};
|
||||||
|
|
||||||
|
const GetBestScrewdriver = (
|
||||||
|
inventories: IInventory[],
|
||||||
|
): IScrewdriver | undefined => {
|
||||||
|
const screwdrivers = GetItemsOfType(
|
||||||
|
ItemType.SCREWDRIVER,
|
||||||
|
inventories,
|
||||||
|
) as IScrewdriver[];
|
||||||
|
|
||||||
|
let bestScrewdriver: IScrewdriver | undefined;
|
||||||
|
let bestQuality = -1;
|
||||||
|
|
||||||
|
screwdrivers.forEach((screwdriver) => {
|
||||||
|
if (screwdriver.quality > bestQuality) {
|
||||||
|
bestScrewdriver = screwdriver;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return bestScrewdriver;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { type AllInventories, type ItemContainer };
|
||||||
|
export {
|
||||||
|
GetItemsAsInventory,
|
||||||
|
GetWorkbenchAsInventory,
|
||||||
|
GetInventory,
|
||||||
|
GetItemsOfType,
|
||||||
|
GetItemOfType,
|
||||||
|
GetItemContainerOfType,
|
||||||
|
GetBestScrewdriver,
|
||||||
|
};
|
||||||
31
src/index.ts
Normal file
31
src/index.ts
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
import express from "express";
|
||||||
|
import cors from "cors";
|
||||||
|
|
||||||
|
import config from "./config.json" with { type: "json" };
|
||||||
|
|
||||||
|
import testRoute from "./controllers/test/test.js";
|
||||||
|
import adminRoute from "./controllers/admin/admin.js";
|
||||||
|
import stateRoute from "./controllers/state/state.js";
|
||||||
|
import gameRoute from "./controllers/game/game.js";
|
||||||
|
import inventoryRoute from "./controllers/inventory/inventory.js";
|
||||||
|
import shopRoute from "./controllers/shop/shop.js";
|
||||||
|
import workbenchRoute from "./controllers/workbench/workbench.js";
|
||||||
|
import internetRoute from "./controllers/internet/internet.js";
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
|
||||||
|
app.use(express.json());
|
||||||
|
app.use(cors());
|
||||||
|
|
||||||
|
app.use("/test", testRoute);
|
||||||
|
app.use("/admin", adminRoute);
|
||||||
|
app.use("/state", stateRoute);
|
||||||
|
app.use("/game", gameRoute);
|
||||||
|
app.use("/inventory", inventoryRoute);
|
||||||
|
app.use("/shop", shopRoute);
|
||||||
|
app.use("/workbench", workbenchRoute);
|
||||||
|
app.use("/internet", internetRoute);
|
||||||
|
|
||||||
|
app.listen(config.port, () => {
|
||||||
|
console.log(`Server running at http://localhost:${config.port}`);
|
||||||
|
});
|
||||||
25
src/services/inventory/inventory.ts
Normal file
25
src/services/inventory/inventory.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { GetInventory, type AllInventories } from "../../helpers.js";
|
||||||
|
import type { IState } from "../../state/types.js";
|
||||||
|
|
||||||
|
const MoveInventory = (
|
||||||
|
id: number,
|
||||||
|
sourceName: AllInventories,
|
||||||
|
destinationName: AllInventories,
|
||||||
|
state: IState,
|
||||||
|
): string | undefined => {
|
||||||
|
const source = GetInventory(sourceName, state);
|
||||||
|
const destination = GetInventory(destinationName, state);
|
||||||
|
|
||||||
|
if (source.items[id] === undefined) {
|
||||||
|
return "source item doesn't exist";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (destination.items.length >= destination.size) {
|
||||||
|
return "destination full";
|
||||||
|
}
|
||||||
|
|
||||||
|
destination.items.push(source.items[id]);
|
||||||
|
source.items.splice(id, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { MoveInventory };
|
||||||
87
src/services/workbench/workbench.ts
Normal file
87
src/services/workbench/workbench.ts
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
import {
|
||||||
|
GetBestScrewdriver,
|
||||||
|
GetItemContainerOfType,
|
||||||
|
GetItemOfType,
|
||||||
|
GetItemsAsInventory,
|
||||||
|
GetItemsOfType,
|
||||||
|
GetWorkbenchAsInventory,
|
||||||
|
} from "../../helpers.js";
|
||||||
|
import { ItemType, type ICase, type IMotherboard } from "../../state/item.js";
|
||||||
|
import type { IState } from "../../state/types.js";
|
||||||
|
|
||||||
|
const InstallMotherboard = (
|
||||||
|
motherboardId: number,
|
||||||
|
caseId: number,
|
||||||
|
state: IState,
|
||||||
|
): string | undefined => {
|
||||||
|
const workbench = state.home.workbench;
|
||||||
|
|
||||||
|
const screwdriver = GetBestScrewdriver([
|
||||||
|
GetWorkbenchAsInventory(workbench),
|
||||||
|
state.player.inventory,
|
||||||
|
]);
|
||||||
|
if (!screwdriver) {
|
||||||
|
return "a screwdriver is required";
|
||||||
|
}
|
||||||
|
|
||||||
|
const itemCase = workbench.devices[caseId];
|
||||||
|
if (!itemCase || itemCase.type !== ItemType.CASE) {
|
||||||
|
return "there is no case in that inventory slot";
|
||||||
|
}
|
||||||
|
const pcCase = itemCase as ICase;
|
||||||
|
|
||||||
|
const itemMotherboard = workbench.devices[motherboardId];
|
||||||
|
if (!itemMotherboard || itemMotherboard.type !== ItemType.MOTHERBOARD) {
|
||||||
|
return "there is no motherboard in that inventory slot";
|
||||||
|
}
|
||||||
|
const motherboard = itemMotherboard as IMotherboard;
|
||||||
|
|
||||||
|
const existingMotherboard = GetItemOfType<IMotherboard>(
|
||||||
|
ItemType.MOTHERBOARD,
|
||||||
|
[GetItemsAsInventory(pcCase.installedDevices)],
|
||||||
|
);
|
||||||
|
if (existingMotherboard) {
|
||||||
|
return "there is already a motherboard installed in that case";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!motherboard.canFitInComputerCase) {
|
||||||
|
return "this item cannot fit inside a pc case";
|
||||||
|
}
|
||||||
|
|
||||||
|
pcCase.installedDevices.push(motherboard);
|
||||||
|
workbench.devices.splice(motherboardId, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
const RemoveMotherboard = (
|
||||||
|
caseId: number,
|
||||||
|
state: IState,
|
||||||
|
): string | undefined => {
|
||||||
|
const workbench = state.home.workbench;
|
||||||
|
|
||||||
|
const screwdriver = GetBestScrewdriver([
|
||||||
|
GetWorkbenchAsInventory(workbench),
|
||||||
|
state.player.inventory,
|
||||||
|
]);
|
||||||
|
if (!screwdriver) {
|
||||||
|
return "a screwdriver is required";
|
||||||
|
}
|
||||||
|
|
||||||
|
const itemCase = workbench.devices[caseId];
|
||||||
|
if (!itemCase || itemCase.type !== ItemType.CASE) {
|
||||||
|
return "there is no case in that inventory slot";
|
||||||
|
}
|
||||||
|
const pcCase = itemCase as ICase;
|
||||||
|
|
||||||
|
const motherboard = GetItemContainerOfType<IMotherboard>(
|
||||||
|
ItemType.MOTHERBOARD,
|
||||||
|
[GetItemsAsInventory(pcCase.installedDevices)],
|
||||||
|
);
|
||||||
|
if (!motherboard) {
|
||||||
|
return "there is no motherboard installed in that case";
|
||||||
|
}
|
||||||
|
|
||||||
|
workbench.devices.push(motherboard.item);
|
||||||
|
pcCase.installedDevices.splice(motherboard.index, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { InstallMotherboard, RemoveMotherboard };
|
||||||
57
src/state/company.ts
Normal file
57
src/state/company.ts
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
export enum Company {
|
||||||
|
Intel,
|
||||||
|
AMD,
|
||||||
|
Nvidia,
|
||||||
|
Seagate,
|
||||||
|
WD,
|
||||||
|
GSkill,
|
||||||
|
NZXT,
|
||||||
|
EK,
|
||||||
|
Alphacool,
|
||||||
|
EVGA,
|
||||||
|
Kingston,
|
||||||
|
Motorola,
|
||||||
|
Nikon,
|
||||||
|
Canon,
|
||||||
|
Qualcomm,
|
||||||
|
TSMC,
|
||||||
|
Samsung,
|
||||||
|
Apple,
|
||||||
|
Microsoft,
|
||||||
|
Canonical,
|
||||||
|
Amazon,
|
||||||
|
Meta,
|
||||||
|
Google,
|
||||||
|
HP,
|
||||||
|
Lenovo,
|
||||||
|
Vivo,
|
||||||
|
Huawei,
|
||||||
|
Cisco,
|
||||||
|
Asus,
|
||||||
|
Acer,
|
||||||
|
Sony,
|
||||||
|
LG,
|
||||||
|
HTC,
|
||||||
|
OnePlus,
|
||||||
|
Xiaomi,
|
||||||
|
Gigabyte,
|
||||||
|
Nokia,
|
||||||
|
HMD,
|
||||||
|
DELL,
|
||||||
|
FrameWork,
|
||||||
|
Tencent,
|
||||||
|
RODE,
|
||||||
|
RME,
|
||||||
|
Fiio,
|
||||||
|
Sennheiser,
|
||||||
|
Beyerdynamic,
|
||||||
|
Audeze,
|
||||||
|
Pine64,
|
||||||
|
Nintendo,
|
||||||
|
Nubia,
|
||||||
|
ZTE,
|
||||||
|
Nothing,
|
||||||
|
Essential,
|
||||||
|
Fairphone,
|
||||||
|
Razer,
|
||||||
|
}
|
||||||
29
src/state/connector.ts
Normal file
29
src/state/connector.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
export enum ConnectorType {
|
||||||
|
USB1,
|
||||||
|
USB2,
|
||||||
|
USB3,
|
||||||
|
USB4,
|
||||||
|
USBC1,
|
||||||
|
USBC2,
|
||||||
|
USBC3,
|
||||||
|
USBC4,
|
||||||
|
MOLEX,
|
||||||
|
SATA_POWER,
|
||||||
|
SATA1,
|
||||||
|
SATA2,
|
||||||
|
SATA3,
|
||||||
|
AGP,
|
||||||
|
PCI_POWER_4,
|
||||||
|
PCI_POWER_6,
|
||||||
|
PCI_POWER_8,
|
||||||
|
PCI,
|
||||||
|
PCIE,
|
||||||
|
PCIE2,
|
||||||
|
PCIE3,
|
||||||
|
PCIE4,
|
||||||
|
PCIE5,
|
||||||
|
PCIE6,
|
||||||
|
PCIE7,
|
||||||
|
PCIE8,
|
||||||
|
PCIE9,
|
||||||
|
}
|
||||||
32
src/state/cpu.ts
Normal file
32
src/state/cpu.ts
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
export enum CPUArchitecture {
|
||||||
|
M_6502,
|
||||||
|
M_6800,
|
||||||
|
M_6809,
|
||||||
|
M_680X0,
|
||||||
|
I_8080,
|
||||||
|
I_8051,
|
||||||
|
Z80,
|
||||||
|
SPARC,
|
||||||
|
MIPS,
|
||||||
|
POWER_PC,
|
||||||
|
x86,
|
||||||
|
x86_64,
|
||||||
|
Itanium,
|
||||||
|
ARMv7,
|
||||||
|
ARMv8,
|
||||||
|
ARMv9,
|
||||||
|
RISC_V,
|
||||||
|
LoongArch,
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum CPUFeatures {
|
||||||
|
AVX,
|
||||||
|
AVX2,
|
||||||
|
AVX512,
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum SocketType {
|
||||||
|
INTEL_LGA_1155,
|
||||||
|
INTEL_LGA_1156,
|
||||||
|
INTEL_LGA_2011,
|
||||||
|
}
|
||||||
37
src/state/gpu.ts
Normal file
37
src/state/gpu.ts
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
export enum GPUArchitecture {
|
||||||
|
Fahrenheit,
|
||||||
|
Celsius,
|
||||||
|
Kelvin,
|
||||||
|
Rankine,
|
||||||
|
Curie,
|
||||||
|
Tesla,
|
||||||
|
Fermi,
|
||||||
|
Kepler,
|
||||||
|
Maxwell,
|
||||||
|
Maxwell2,
|
||||||
|
Pascal,
|
||||||
|
Turing,
|
||||||
|
Volta,
|
||||||
|
Ampere,
|
||||||
|
Lovelace,
|
||||||
|
Hopper,
|
||||||
|
Blackwell,
|
||||||
|
Rubin,
|
||||||
|
TeraScale,
|
||||||
|
TeraScale2,
|
||||||
|
TeraScale3,
|
||||||
|
CGN,
|
||||||
|
CGN2,
|
||||||
|
CGN3,
|
||||||
|
CGN4,
|
||||||
|
CGN5,
|
||||||
|
RDNA,
|
||||||
|
RDNA2,
|
||||||
|
RDNA3,
|
||||||
|
RDNA3_5,
|
||||||
|
RDNA4,
|
||||||
|
CDNA,
|
||||||
|
CDNA2,
|
||||||
|
CDNA3,
|
||||||
|
UDNA,
|
||||||
|
}
|
||||||
212
src/state/item.ts
Normal file
212
src/state/item.ts
Normal file
|
|
@ -0,0 +1,212 @@
|
||||||
|
import type { Company } from "./company.js";
|
||||||
|
import type { ConnectorType } from "./connector.js";
|
||||||
|
import type { SocketType } from "./cpu.js";
|
||||||
|
import type { MemoryType } from "./memory.js";
|
||||||
|
import type { DiscType, DiskType, IStorage } from "./storage.js";
|
||||||
|
import type { INet } from "./types.js";
|
||||||
|
|
||||||
|
export enum ItemType {
|
||||||
|
SCREWDRIVER,
|
||||||
|
CPU,
|
||||||
|
GRAPHIC_CARD,
|
||||||
|
RAM_MODULE,
|
||||||
|
DISK,
|
||||||
|
DISC,
|
||||||
|
TAPE,
|
||||||
|
VHS,
|
||||||
|
DISKETTE,
|
||||||
|
CASE,
|
||||||
|
PSU,
|
||||||
|
MOTHERBOARD,
|
||||||
|
FAN,
|
||||||
|
CPU_COOLER,
|
||||||
|
GPU_COOLER,
|
||||||
|
NETWORK_CARD,
|
||||||
|
SOUND_CARD,
|
||||||
|
NETWORK_SWITCH,
|
||||||
|
WIFI_AP,
|
||||||
|
ROUTER,
|
||||||
|
MODEM,
|
||||||
|
MONITOR,
|
||||||
|
KEYBOARD,
|
||||||
|
MOUSE,
|
||||||
|
JOYSTICK,
|
||||||
|
HEADPHONES,
|
||||||
|
DAC,
|
||||||
|
MICROPHONE,
|
||||||
|
CAMERA,
|
||||||
|
PHONE,
|
||||||
|
LAPTOP,
|
||||||
|
COMPUTER,
|
||||||
|
SECURITY_KEY,
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum FormFactorType {
|
||||||
|
M_ATX,
|
||||||
|
ATX,
|
||||||
|
E_ATX,
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IItem {
|
||||||
|
type: ItemType;
|
||||||
|
name: string;
|
||||||
|
durability: number;
|
||||||
|
manufacturer?: Company | "Player";
|
||||||
|
availability?: number;
|
||||||
|
rarity?: number;
|
||||||
|
price?: number;
|
||||||
|
canFitInComputerCase?: boolean;
|
||||||
|
canFitInLaptopCase?: boolean;
|
||||||
|
canFitInMobileCase?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IConnectedDevice extends IItem {
|
||||||
|
connector: ConnectorType;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IScrewdriver extends IItem {
|
||||||
|
quality: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ICPUCore {
|
||||||
|
originalClockSpeed: number;
|
||||||
|
clockSpeed: number;
|
||||||
|
threads: number;
|
||||||
|
cacheL1?: number;
|
||||||
|
cacheL2?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ICPU extends IItem {
|
||||||
|
cores: ICPUCore[];
|
||||||
|
cacheL3?: number;
|
||||||
|
cacheL4?: number;
|
||||||
|
gpu?: IGPU;
|
||||||
|
npu?: INPU;
|
||||||
|
tdp: number;
|
||||||
|
process: number;
|
||||||
|
socket: SocketType;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IGPU extends IItem {
|
||||||
|
originalClockSpeed: number;
|
||||||
|
clockSpeed: number;
|
||||||
|
coreCount: number;
|
||||||
|
shadingUnitCount: number;
|
||||||
|
tmuCount: number;
|
||||||
|
ropCount: number;
|
||||||
|
tensorCoreCount: number;
|
||||||
|
rtCoreCount: number;
|
||||||
|
cacheL0?: number;
|
||||||
|
cacheL1?: number;
|
||||||
|
cacheL2?: number;
|
||||||
|
cacheL3?: number;
|
||||||
|
tops: number;
|
||||||
|
pixelRate: number;
|
||||||
|
textureRate: number;
|
||||||
|
fp16flops: number;
|
||||||
|
fp32flops: number;
|
||||||
|
fp64flops: number;
|
||||||
|
features: IGPUFeatures;
|
||||||
|
process: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface INPU extends IItem {
|
||||||
|
tops: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IGPUFeatures {
|
||||||
|
directxVersion?: number;
|
||||||
|
openglVersion?: number;
|
||||||
|
openclVersion?: number;
|
||||||
|
vulkanVersion?: number;
|
||||||
|
cudaVersion?: number;
|
||||||
|
shaderModel?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IGraphicsCard extends IConnectedDevice {
|
||||||
|
gpu: IGPU;
|
||||||
|
memory: IGraphicsCardMemory;
|
||||||
|
tdp: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IGraphicsCardMemory {
|
||||||
|
type: MemoryType;
|
||||||
|
originalClockSpeed: number;
|
||||||
|
clockSpeed: number;
|
||||||
|
busWidth: number;
|
||||||
|
bandwidth: number;
|
||||||
|
capacity: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IRAMModule extends IItem {
|
||||||
|
memoryType: MemoryType;
|
||||||
|
originalClockSpeed: number;
|
||||||
|
clockSpeed: number;
|
||||||
|
capacity: number;
|
||||||
|
tdp: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IDisk extends IConnectedDevice {
|
||||||
|
diskType: DiskType;
|
||||||
|
bandwidth: number;
|
||||||
|
capacity: number;
|
||||||
|
tdp: number;
|
||||||
|
storage: IStorage;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IDisc extends IItem {
|
||||||
|
discType: DiscType;
|
||||||
|
bandwidth: number;
|
||||||
|
capacity: number;
|
||||||
|
storage: IStorage;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ICase extends IItem {
|
||||||
|
formFactor: FormFactorType;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
depth: number;
|
||||||
|
installedDevices: IItem[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IPSU extends IItem {
|
||||||
|
formFactor: FormFactorType;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
depth: number;
|
||||||
|
wattage: number;
|
||||||
|
connectors: ConnectorType[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IMotherboard extends IItem {
|
||||||
|
formFactor: FormFactorType;
|
||||||
|
connectors: ConnectorType[];
|
||||||
|
socket: SocketType;
|
||||||
|
socketCount: number;
|
||||||
|
memoryType: MemoryType;
|
||||||
|
memorySlots: number;
|
||||||
|
installedCPUs: ICPU[];
|
||||||
|
installedRAMs: IRAMModule[];
|
||||||
|
installedDevices: IConnectedDevice[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IModem extends IItem {
|
||||||
|
bandwidth: number;
|
||||||
|
net: INet;
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
type IItem,
|
||||||
|
type IConnectedDevice,
|
||||||
|
type IScrewdriver,
|
||||||
|
type ICPU,
|
||||||
|
type IGPU,
|
||||||
|
type IGraphicsCard,
|
||||||
|
type IRAMModule,
|
||||||
|
type IDisk,
|
||||||
|
type IDisc,
|
||||||
|
type ICase,
|
||||||
|
type IPSU,
|
||||||
|
type IMotherboard,
|
||||||
|
type IModem,
|
||||||
|
};
|
||||||
4
src/state/location.ts
Normal file
4
src/state/location.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
export enum Location {
|
||||||
|
PLAYER_HOME,
|
||||||
|
LOCAL_STORE,
|
||||||
|
}
|
||||||
51
src/state/memory.ts
Normal file
51
src/state/memory.ts
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
export enum MemoryType {
|
||||||
|
DDR,
|
||||||
|
LPDDR,
|
||||||
|
LPDDRX,
|
||||||
|
DDR2,
|
||||||
|
LPDDR2,
|
||||||
|
LPDDR2X,
|
||||||
|
DDR3,
|
||||||
|
LPDDR3,
|
||||||
|
LPDDR3X,
|
||||||
|
DDR4,
|
||||||
|
LPDDR4,
|
||||||
|
LPDDR4X,
|
||||||
|
DDR5,
|
||||||
|
LPDDR5,
|
||||||
|
LPDDR5X,
|
||||||
|
DDR6,
|
||||||
|
LPDDR6,
|
||||||
|
LPDDR6X,
|
||||||
|
DDR7,
|
||||||
|
LPDDR7,
|
||||||
|
LPDDR7X,
|
||||||
|
DDR8,
|
||||||
|
LPDDR8,
|
||||||
|
LPDDR8X,
|
||||||
|
DDR9,
|
||||||
|
LPDDR9,
|
||||||
|
LPDDR9X,
|
||||||
|
GDDR1,
|
||||||
|
GDDR1X,
|
||||||
|
GDDR2,
|
||||||
|
GDDR2X,
|
||||||
|
GDDR3,
|
||||||
|
GDDR3X,
|
||||||
|
GDDR4,
|
||||||
|
GDDR4X,
|
||||||
|
GDDR5,
|
||||||
|
GDDR5X,
|
||||||
|
GDDR6,
|
||||||
|
GDDR6X,
|
||||||
|
GDDR7,
|
||||||
|
GDDR7X,
|
||||||
|
GDDR8,
|
||||||
|
GDDR8X,
|
||||||
|
GDDR9,
|
||||||
|
GDDR9X,
|
||||||
|
HBM,
|
||||||
|
HBM2,
|
||||||
|
HBM3,
|
||||||
|
HBM4,
|
||||||
|
}
|
||||||
4
src/state/motherboard.ts
Normal file
4
src/state/motherboard.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
export enum MotherboardFeatures {
|
||||||
|
BIOS,
|
||||||
|
UEFI,
|
||||||
|
}
|
||||||
11
src/state/software.ts
Normal file
11
src/state/software.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
export enum SoftwareType {
|
||||||
|
OS,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ISoftware {
|
||||||
|
type: SoftwareType;
|
||||||
|
name: string;
|
||||||
|
cpuUsage: number;
|
||||||
|
memoryUsage: number;
|
||||||
|
storageUsage: number;
|
||||||
|
}
|
||||||
49
src/state/state.ts
Normal file
49
src/state/state.ts
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
import { Location } from "./location.js";
|
||||||
|
import shops from "../data/shops.js";
|
||||||
|
import type { IGame } from "./types.js";
|
||||||
|
import cpus from "../data/items/cpus.js";
|
||||||
|
import rams from "../data/items/rams.js";
|
||||||
|
import psus from "../data/items/psus.js";
|
||||||
|
import cases from "../data/items/cases.js";
|
||||||
|
import motherboards from "../data/items/motherboards.js";
|
||||||
|
import other from "../data/items/other.js";
|
||||||
|
|
||||||
|
const game: IGame = {
|
||||||
|
state: {
|
||||||
|
time: 0,
|
||||||
|
player: {
|
||||||
|
name: "Aslan",
|
||||||
|
inventory: {
|
||||||
|
size: 2,
|
||||||
|
items: [],
|
||||||
|
},
|
||||||
|
location: Location.PLAYER_HOME,
|
||||||
|
},
|
||||||
|
car: {
|
||||||
|
inventory: {
|
||||||
|
size: 8,
|
||||||
|
items: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
home: {
|
||||||
|
inventory: {
|
||||||
|
size: 100,
|
||||||
|
items: [
|
||||||
|
...cpus,
|
||||||
|
...rams,
|
||||||
|
...psus,
|
||||||
|
...motherboards,
|
||||||
|
...cases,
|
||||||
|
...other,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
workbench: {
|
||||||
|
devices: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
shops: shops,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export { game };
|
||||||
|
export default game.state;
|
||||||
57
src/state/storage.ts
Normal file
57
src/state/storage.ts
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
import type { ISoftware } from "./software.js";
|
||||||
|
|
||||||
|
enum DiskType {
|
||||||
|
HDD,
|
||||||
|
SSD,
|
||||||
|
Flash,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum DiscType {
|
||||||
|
LaserDisc,
|
||||||
|
CD,
|
||||||
|
DVD,
|
||||||
|
BluRay,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum FilesystemType {
|
||||||
|
EXT,
|
||||||
|
EXT2,
|
||||||
|
EXT3,
|
||||||
|
EXT4,
|
||||||
|
FAT16,
|
||||||
|
FAT32,
|
||||||
|
NTFS,
|
||||||
|
EXFAT,
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IStorage {
|
||||||
|
filesystem: IFileSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IFileSystem {
|
||||||
|
type: FilesystemType;
|
||||||
|
rootDirectory: IDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IDirectory {
|
||||||
|
name: string;
|
||||||
|
directories: IDirectory[];
|
||||||
|
files: IFile[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IFile {
|
||||||
|
name: string;
|
||||||
|
size: string;
|
||||||
|
isSoftware: boolean;
|
||||||
|
contents: string | ISoftware;
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
DiskType,
|
||||||
|
DiscType,
|
||||||
|
FilesystemType,
|
||||||
|
type IStorage,
|
||||||
|
type IFileSystem,
|
||||||
|
type IDirectory,
|
||||||
|
type IFile,
|
||||||
|
};
|
||||||
68
src/state/types.ts
Normal file
68
src/state/types.ts
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
import type { IItem, IModem } from "./item.js";
|
||||||
|
import type { Location } from "./location.js";
|
||||||
|
|
||||||
|
interface IGame {
|
||||||
|
state: IState;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IState {
|
||||||
|
time: number;
|
||||||
|
player: IPlayer;
|
||||||
|
car: ICar;
|
||||||
|
home: IHome;
|
||||||
|
shops: IShop[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IPlayer {
|
||||||
|
name: string;
|
||||||
|
inventory: IInventory;
|
||||||
|
location: Location;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ICar {
|
||||||
|
inventory: IInventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IHome {
|
||||||
|
inventory: IInventory;
|
||||||
|
workbench: IWorkbench;
|
||||||
|
modem?: IModem;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IInventory {
|
||||||
|
size: number;
|
||||||
|
items: IItem[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IWorkbench {
|
||||||
|
devices: IItem[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IWebsite {
|
||||||
|
name: string;
|
||||||
|
ip: string;
|
||||||
|
domain: string;
|
||||||
|
html: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface INet {
|
||||||
|
ip?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IShop {
|
||||||
|
name: string;
|
||||||
|
items: IItem[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
type IGame,
|
||||||
|
type IState,
|
||||||
|
type IPlayer,
|
||||||
|
type ICar,
|
||||||
|
type IHome,
|
||||||
|
type IInventory,
|
||||||
|
type IWorkbench,
|
||||||
|
type IWebsite,
|
||||||
|
type INet,
|
||||||
|
type IShop,
|
||||||
|
};
|
||||||
46
tsconfig.json
Normal file
46
tsconfig.json
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
{
|
||||||
|
// Visit https://aka.ms/tsconfig to read more about this file
|
||||||
|
"compilerOptions": {
|
||||||
|
// File Layout
|
||||||
|
"rootDir": "./src",
|
||||||
|
"outDir": "./dist",
|
||||||
|
|
||||||
|
// Environment Settings
|
||||||
|
// See also https://aka.ms/tsconfig/module
|
||||||
|
"module": "nodenext",
|
||||||
|
"target": "esnext",
|
||||||
|
"types": [],
|
||||||
|
// For nodejs:
|
||||||
|
// "lib": ["esnext"],
|
||||||
|
// "types": ["node"],
|
||||||
|
// and npm install -D @types/node
|
||||||
|
|
||||||
|
// Other Outputs
|
||||||
|
"sourceMap": true,
|
||||||
|
"declaration": true,
|
||||||
|
"declarationMap": true,
|
||||||
|
|
||||||
|
// Stricter Typechecking Options
|
||||||
|
"noUncheckedIndexedAccess": true,
|
||||||
|
"exactOptionalPropertyTypes": true,
|
||||||
|
|
||||||
|
// Style Options
|
||||||
|
// "noImplicitReturns": true,
|
||||||
|
// "noImplicitOverride": true,
|
||||||
|
// "noUnusedLocals": true,
|
||||||
|
// "noUnusedParameters": true,
|
||||||
|
// "noFallthroughCasesInSwitch": true,
|
||||||
|
// "noPropertyAccessFromIndexSignature": true,
|
||||||
|
|
||||||
|
// Recommended Options
|
||||||
|
"strict": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"noUncheckedSideEffectImports": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"esModuleInterop": true
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue