restructure project

This commit is contained in:
Merijn Hendriks 2021-12-26 17:20:59 +01:00
parent 20bbfd4239
commit 7cfe244127
100 changed files with 461 additions and 4428 deletions

23
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,23 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch",
"runtimeExecutable": "npm",
"runtimeArgs": [
"run-script",
"launch"
],
"cwd": "${workspaceFolder}",
"outFiles": [
"${workspaceFolder}/out/**/*.js"
],
"skipFiles": [
"**/node_modules/**"
]
}
]
}

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"window.title": "Natsu Project",
}

8
.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,8 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "something"
}
]
}

57
launcher/package.json Normal file
View File

@ -0,0 +1,57 @@
{
"name": "haru-launcher",
"author": "senko-san",
"version": "1.0.0",
"license": "NCSA",
"main": "src/main.js",
"scripts": {
"lint:fix": "npx eslint --fix \"./src/**/*.ts\"",
"lint:check": "npx eslint \"./src/**/*.ts\"",
"build:ts": "npx babel src --extensions \".ts\" --out-dir obj/babel",
"build:bundle": "npx browserify --debug --node obj/babel/main.js > obj/bundle.js",
"launch:node": "node --trace-warnings obj/bundle.js",
"launch": "npm run build:ts && npm run build:bundle && npm run launch:node"
},
"dependencies": {
"source-map-support": "^0.5.0"
},
"devDependencies": {
"@babel/cli": "^7.16.0",
"@babel/core": "^7.16.0",
"@babel/eslint-parser": "^7.16.0",
"@babel/plugin-transform-runtime": "^7.16.0",
"@babel/preset-env": "^7.16.0",
"@babel/preset-typescript": "^7.16.0",
"@types/node": "^14.0.0",
"babel-plugin-source-map-support": "^2.1.0",
"browserify": "^17.0.0",
"core-js": "^3.20.0",
"eslint": "^8.5.0",
"typescript": "^4.5.0"
},
"babel": {
"presets": [
[ "@babel/env", { "targets": { "node": "14.0.0" }, "useBuiltIns": "usage", "corejs": "3.20.0" } ],
"@babel/preset-typescript"
],
"plugins": [
"@babel/plugin-transform-runtime",
"@babel/plugin-transform-typescript",
"source-map-support"
],
"sourceMaps": "inline"
},
"eslintConfig": {
"parser": "@babel/eslint-parser",
"extends": "eslint:recommended",
"rules": {
"brace-style": [ "error", "allman" ],
"indent": [ "error", 4, { "VariableDeclarator": 0, "SwitchCase": 1 } ],
"quotes": [ "error", "double" ],
"semi": [ "error", "always" ],
"no-var": "error",
"no-unused-vars": "off",
"no-undef": "off"
}
}
}

View File

@ -0,0 +1,92 @@
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
export class Json
{
public static deserialize<T>(s: string): T
{
return JSON.parse(s);
}
public static serialize<T>(o: T, indent: boolean = false): string
{
return (indent) ? JSON.stringify(o, null, 2) : JSON.stringify(o);
}
}
export class Vfs
{
public static getExtension(filepath: string): string
{
return filepath.split(".").pop() || "";
}
public static exists(filepath: string): boolean
{
return existsSync(filepath);
}
public static createDirectory(filepath: string): void
{
const path = filepath.substring(0, filepath.lastIndexOf("/"));
mkdirSync(path, { "recursive": true });
}
public static readFile(filepath: string): any
{
return readFileSync(filepath);
}
public static writeFile(filepath: string, data: Buffer | string, append: boolean = false): void
{
if (!Vfs.exists(filepath))
{
Vfs.createDirectory(filepath);
}
return writeFileSync(filepath, data, { "flag": (append) ? "a" : "w" });
}
}
export class Log
{
private static filepath: string;
public static init(filepath: string)
{
Log.filepath = filepath;
// clear existing log
if (Vfs.exists(Log.filepath))
{
Vfs.writeFile(Log.filepath, "");
}
// log exceptions
process.on("uncaughtException", (error, promise) =>
{
Log.error("Trace:");
Log.write(error.toString());
});
}
public static write(text: string): void
{
console.log(text);
Vfs.writeFile(Log.filepath, `${text}\n`, true);
}
public static info(text: string): void
{
Log.write(`[INFO] ${text}`);
}
public static warn(text: string): void
{
Log.write(`[WARN] ${text}`);
}
public static error(text: string): void
{
Log.write(`[ERROR] ${text}`);
}
}

14
launcher/src/Haru.ts Normal file
View File

@ -0,0 +1,14 @@
import { Log } from "./Haru.Utils";
export class Program
{
public static main(args: string[])
{
Log.init("./Logs/Haru.log");
for (const command of args)
{
Log.info(command);
}
}
}

View File

@ -1,3 +1,3 @@
import { Program } from "./Haru"; import { Program } from "./Haru";
Program.main(process.argv); Program.main(process.argv);

4157
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
{ {
"name": "haru", "name": "haru-server",
"author": "senko-san", "author": "senko-san",
"version": "1.0.0", "version": "1.0.0",
"license": "NCSA", "license": "NCSA",
@ -37,16 +37,7 @@
}, },
"babel": { "babel": {
"presets": [ "presets": [
[ [ "@babel/env", { "targets": { "node": "14.0.0" }, "useBuiltIns": "usage", "corejs": "3.20.0" } ],
"@babel/env",
{
"targets": {
"node": "14.0.0"
},
"useBuiltIns": "usage",
"corejs": "3.20.0"
}
],
"@babel/preset-typescript" "@babel/preset-typescript"
], ],
"plugins": [ "plugins": [
@ -60,26 +51,10 @@
"parser": "@babel/eslint-parser", "parser": "@babel/eslint-parser",
"extends": "eslint:recommended", "extends": "eslint:recommended",
"rules": { "rules": {
"brace-style": [ "brace-style": [ "error", "allman" ],
"error", "indent": [ "error", 4, { "VariableDeclarator": 0, "SwitchCase": 1 } ],
"allman" "quotes": [ "error", "double" ],
], "semi": [ "error", "always" ],
"indent": [
"error",
4,
{
"VariableDeclarator": 0,
"SwitchCase": 1
}
],
"quotes": [
"error",
"double"
],
"semi": [
"error",
"always"
],
"no-var": "error", "no-var": "error",
"no-unused-vars": "off", "no-unused-vars": "off",
"no-undef": "off" "no-undef": "off"

View File

@ -1,118 +1,118 @@
export class ResponseBody<T> export class ResponseBody<T>
{ {
public err: number; public err: number;
public errcode: string | null; public errcode: string | null;
public data: T; public data: T;
public constructor(data: T, err: number = 0, errcode: string | null = null) public constructor(data: T, err: number = 0, errcode: string | null = null)
{ {
this.err = err; this.err = err;
this.errcode = errcode; this.errcode = errcode;
this.data = data; this.data = data;
} }
} }
export class LogoutResponse export class LogoutResponse
{ {
public status: string; public status: string;
public constructor() public constructor()
{ {
this.status = "ok"; this.status = "ok";
} }
} }
export class KeepAliveResponse export class KeepAliveResponse
{ {
public msg: string; public msg: string;
public utc_time: number; public utc_time: number;
public constructor() public constructor()
{ {
this.msg = "OK"; this.msg = "OK";
// todo: implement this // todo: implement this
// value: unix timestamp // value: unix timestamp
this.utc_time = 0; this.utc_time = 0;
} }
} }
export class ServerInfo export class ServerInfo
{ {
public ip: string; public ip: string;
public port: number; public port: number;
public constructor(ip: string = "127.0.0.1", port: number = 8000) public constructor(ip: string = "127.0.0.1", port: number = 8000)
{ {
this.ip = ip; this.ip = ip;
this.port = port; this.port = port;
} }
} }
export class PingNotification export class PingNotification
{ {
public type: string; public type: string;
public eventId: string; public eventId: string;
public constructor() public constructor()
{ {
this.type = "ping"; this.type = "ping";
this.eventId = "ping"; this.eventId = "ping";
} }
} }
// todo: implement this // todo: implement this
export class CheckVersionResponse export class CheckVersionResponse
{ {
public isValid: boolean; public isValid: boolean;
public latestVersion: string; public latestVersion: string;
public constructor() public constructor()
{ {
this.isValid = true; this.isValid = true;
this.latestVersion = ""; this.latestVersion = "";
} }
} }
export class MiniInfo export class MiniInfo
{ {
public Nickname: string; public Nickname: string;
public Side: string; public Side: string;
public Level: number; public Level: number;
public MemberCategory: number; public MemberCategory: number;
public constructor(nickname: string, side: string, level: number, memberCategory: number) public constructor(nickname: string, side: string, level: number, memberCategory: number)
{ {
this.Nickname = nickname; this.Nickname = nickname;
this.Side = side; this.Side = side;
this.Level = level; this.Level = level;
this.MemberCategory = memberCategory; this.MemberCategory = memberCategory;
} }
} }
export class MiniProfile export class MiniProfile
{ {
public _id: string; public _id: string;
public Info: MiniInfo; public Info: MiniInfo;
public constructor(id: string, info: MiniInfo) public constructor(id: string, info: MiniInfo)
{ {
this._id = id; this._id = id;
this.Info = info; this.Info = info;
} }
} }
export class FriendList export class FriendList
{ {
public Friends: MiniProfile[]; public Friends: MiniProfile[];
public Ignore: string[]; public Ignore: string[];
public InIgnoreList: string[]; public InIgnoreList: string[];
public constructor() public constructor()
{ {
// todo: implement this // todo: implement this
this.Friends = []; this.Friends = [];
this.Ignore = []; this.Ignore = [];
this.InIgnoreList = []; this.InIgnoreList = [];
} }
} }

View File

@ -1,111 +1,111 @@
import { PingNotification } from "./Haru.Eft.Models"; import { PingNotification } from "./Haru.Eft.Models";
import { CachedResponseService, CachedResponseHelper, FileResponseHelper, FileService } from "./Haru.Eft.Services"; import { CachedResponseService, CachedResponseHelper, FileResponseHelper, FileService } from "./Haru.Eft.Services";
import { HttpServer, WsServer, IServer } from "./Haru.Http"; import { HttpServer, WsServer, IServer } from "./Haru.Http";
import { Json } from "./Haru.Utils"; import { Json } from "./Haru.Utils";
export class ServerCluster export class ServerCluster
{ {
private readonly servers: IServer[]; private readonly servers: IServer[];
public constructor() public constructor()
{ {
this.servers = [ this.servers = [
new GeneralServer(), new GeneralServer(),
new NotificationServer() new NotificationServer()
]; ];
} }
public start(): void public start(): void
{ {
for (const server of this.servers) for (const server of this.servers)
{ {
server.start(); server.start();
} }
} }
public stop(): void public stop(): void
{ {
for (const server of this.servers) for (const server of this.servers)
{ {
server.stop(); server.stop();
} }
} }
} }
export class GeneralServer implements IServer export class GeneralServer implements IServer
{ {
private readonly server: HttpServer; private readonly server: HttpServer;
public constructor() public constructor()
{ {
this.server = new HttpServer("localhost", 8000); this.server = new HttpServer("localhost", 8000);
// add cached responses // add cached responses
const cachedResponseService = new CachedResponseService(); const cachedResponseService = new CachedResponseService();
for (const url in CachedResponseHelper.responses) for (const url in CachedResponseHelper.responses)
{ {
this.server.addService(url, cachedResponseService); this.server.addService(url, cachedResponseService);
} }
// add file responses // add file responses
const fileService = new FileService() const fileService = new FileService()
for (const url in FileResponseHelper.files) for (const url in FileResponseHelper.files)
{ {
this.server.addService(url, fileService); this.server.addService(url, fileService);
} }
} }
public start(): void public start(): void
{ {
this.server.start(); this.server.start();
} }
public stop(): void public stop(): void
{ {
this.server.stop(); this.server.stop();
} }
public isListening(): boolean public isListening(): boolean
{ {
return this.server.isListening(); return this.server.isListening();
} }
} }
export class NotificationServer implements IServer export class NotificationServer implements IServer
{ {
private readonly httpServer: HttpServer; private readonly httpServer: HttpServer;
private readonly wsServer: WsServer; private readonly wsServer: WsServer;
public constructor() public constructor()
{ {
const message = Json.serialize(new PingNotification()); const message = Json.serialize(new PingNotification());
this.httpServer = new HttpServer("localhost", 8001); this.httpServer = new HttpServer("localhost", 8001);
this.wsServer = new WsServer(this.httpServer, message); this.wsServer = new WsServer(this.httpServer, message);
} }
public start(): void public start(): void
{ {
this.httpServer.start(); this.httpServer.start();
this.wsServer.start(); this.wsServer.start();
} }
public stop(): void public stop(): void
{ {
this.httpServer.stop(); this.httpServer.stop();
this.wsServer.stop(); this.wsServer.stop();
} }
public isListening(): boolean public isListening(): boolean
{ {
return this.httpServer.isListening() || this.wsServer.isListening(); return this.httpServer.isListening() || this.wsServer.isListening();
} }
public canSendMessage(sessionId: string): boolean public canSendMessage(sessionId: string): boolean
{ {
// TODO: use actual url // TODO: use actual url
const url: string = sessionId; const url: string = sessionId;
return this.wsServer.canSendMessage(url); return this.wsServer.canSendMessage(url);
} }
} }

View File

@ -1,11 +1,11 @@
import { ServerCluster } from "./Haru.Eft.Servers"; import { ServerCluster } from "./Haru.Eft.Servers";
import { Log } from "./Haru.Utils"; import { Log } from "./Haru.Utils";
export class Program export class Program
{ {
public static main(args: string[]) public static main(args: string[])
{ {
Log.init("./Logs/Haru.log"); Log.init("./Logs/Haru.log");
new ServerCluster().start(); new ServerCluster().start();
} }
} }

3
server/src/main.ts Normal file
View File

@ -0,0 +1,3 @@
import { Program } from "./Haru";
Program.main(process.argv);

15
server/tsconfig.json Normal file
View File

@ -0,0 +1,15 @@
{
"compilerOptions": {
"target": "es2020",
"module": "es2020",
"moduleResolution": "node",
"inlineSourceMap": true,
"inlineSources": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"outDir": "./obj/ts"
},
"include": [
"./src"
]
}