:3
This commit is contained in:
		
						commit
						8d63eb270b
					
				
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| 
						 | 
					@ -1,2 +1 @@
 | 
				
			||||||
/node_modules
 | 
					/.venv
 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,32 +0,0 @@
 | 
				
			||||||
"use strict";
 | 
					 | 
				
			||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
 | 
					 | 
				
			||||||
    return (mod && mod.__esModule) ? mod : { "default": mod };
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
Object.defineProperty(exports, "__esModule", { value: true });
 | 
					 | 
				
			||||||
const express_1 = __importDefault(require("express"));
 | 
					 | 
				
			||||||
const routes_1 = __importDefault(require("./routes"));
 | 
					 | 
				
			||||||
const http_1 = __importDefault(require("http"));
 | 
					 | 
				
			||||||
const websocket_1 = __importDefault(require("./websocket"));
 | 
					 | 
				
			||||||
const express_winston_1 = __importDefault(require("express-winston"));
 | 
					 | 
				
			||||||
const winston_1 = __importDefault(require("winston"));
 | 
					 | 
				
			||||||
class Api {
 | 
					 | 
				
			||||||
    constructor(port) {
 | 
					 | 
				
			||||||
        this.app = (0, express_1.default)();
 | 
					 | 
				
			||||||
        this.app.use(express_winston_1.default.logger({
 | 
					 | 
				
			||||||
            transports: [
 | 
					 | 
				
			||||||
                new winston_1.default.transports.Console()
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            format: winston_1.default.format.combine(winston_1.default.format.colorize(), winston_1.default.format.cli()),
 | 
					 | 
				
			||||||
            meta: true,
 | 
					 | 
				
			||||||
            msg: "HTTP {{req.method}} {{req.url}}",
 | 
					 | 
				
			||||||
            expressFormat: true,
 | 
					 | 
				
			||||||
            colorize: true,
 | 
					 | 
				
			||||||
            // ignoreRoute: function (req, res) { return false; } // optional: allows to skip some log messages based on request and/or response
 | 
					 | 
				
			||||||
        }));
 | 
					 | 
				
			||||||
        this.app.use("/api", routes_1.default);
 | 
					 | 
				
			||||||
        this.server = http_1.default.createServer(this.app);
 | 
					 | 
				
			||||||
        this.server.listen(port);
 | 
					 | 
				
			||||||
        this.wss = new websocket_1.default(this.server);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
exports.default = Api;
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,8 +0,0 @@
 | 
				
			||||||
"use strict";
 | 
					 | 
				
			||||||
Object.defineProperty(exports, "__esModule", { value: true });
 | 
					 | 
				
			||||||
const express_1 = require("express");
 | 
					 | 
				
			||||||
const router = (0, express_1.Router)();
 | 
					 | 
				
			||||||
router.get("/", function (req, res) {
 | 
					 | 
				
			||||||
    res.send("Hewo :3");
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
exports.default = router;
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,12 +0,0 @@
 | 
				
			||||||
"use strict";
 | 
					 | 
				
			||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
 | 
					 | 
				
			||||||
    return (mod && mod.__esModule) ? mod : { "default": mod };
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
Object.defineProperty(exports, "__esModule", { value: true });
 | 
					 | 
				
			||||||
const ws_1 = __importDefault(require("ws"));
 | 
					 | 
				
			||||||
class Websocket {
 | 
					 | 
				
			||||||
    constructor(server) {
 | 
					 | 
				
			||||||
        this.wss = new ws_1.default.WebSocketServer({ path: "/ws", server });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
exports.default = Websocket;
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,11 +0,0 @@
 | 
				
			||||||
"use strict";
 | 
					 | 
				
			||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
 | 
					 | 
				
			||||||
    return (mod && mod.__esModule) ? mod : { "default": mod };
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
Object.defineProperty(exports, "__esModule", { value: true });
 | 
					 | 
				
			||||||
const api_1 = __importDefault(require("./api"));
 | 
					 | 
				
			||||||
function main() {
 | 
					 | 
				
			||||||
    console.log("Starting");
 | 
					 | 
				
			||||||
    const api = new api_1.default(8080);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
main();
 | 
					 | 
				
			||||||
							
								
								
									
										1876
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1876
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										27
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								package.json
									
									
									
									
									
								
							| 
						 | 
					@ -1,27 +0,0 @@
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  "name": "rtmc-be",
 | 
					 | 
				
			||||||
  "version": "1.0.0",
 | 
					 | 
				
			||||||
  "main": "build/index.js",
 | 
					 | 
				
			||||||
  "scripts": {
 | 
					 | 
				
			||||||
    "test": "echo \"Error: no test specified\" && exit 1"
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  "author": "",
 | 
					 | 
				
			||||||
  "license": "ISC",
 | 
					 | 
				
			||||||
  "description": "",
 | 
					 | 
				
			||||||
  "devDependencies": {
 | 
					 | 
				
			||||||
    "@types/express": "^4.17.21",
 | 
					 | 
				
			||||||
    "@types/http-server": "^0.12.4",
 | 
					 | 
				
			||||||
    "@types/knex": "^0.15.2",
 | 
					 | 
				
			||||||
    "@types/node": "^22.5.0",
 | 
					 | 
				
			||||||
    "@types/ws": "^8.5.12",
 | 
					 | 
				
			||||||
    "typescript": "^5.5.4"
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  "dependencies": {
 | 
					 | 
				
			||||||
    "express": "^4.19.2",
 | 
					 | 
				
			||||||
    "express-winston": "^4.2.0",
 | 
					 | 
				
			||||||
    "knex": "^3.1.0",
 | 
					 | 
				
			||||||
    "pug": "^3.0.3",
 | 
					 | 
				
			||||||
    "winston": "^3.14.2",
 | 
					 | 
				
			||||||
    "ws": "^8.18.0"
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										8
									
								
								pyproject.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								pyproject.toml
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					[tool.pylint.'MESSAGES CONTROL']
 | 
				
			||||||
 | 
					disable = [
 | 
				
			||||||
 | 
					    "line-too-long",
 | 
				
			||||||
 | 
					    "unnecessary-semicolon",
 | 
				
			||||||
 | 
					    "trailing-newlines",
 | 
				
			||||||
 | 
					    "missing-docstring"
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										98
									
								
								server.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								server.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,98 @@
 | 
				
			||||||
 | 
					import asyncio
 | 
				
			||||||
 | 
					import string
 | 
				
			||||||
 | 
					import secrets
 | 
				
			||||||
 | 
					import json
 | 
				
			||||||
 | 
					import websockets
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					clients = {
 | 
				
			||||||
 | 
					    "FD3ZJFHQ7r": {
 | 
				
			||||||
 | 
					        "doorOpen": False,
 | 
				
			||||||
 | 
					        "lockdown": False,
 | 
				
			||||||
 | 
					        "lastOpened": 1, #unix timestamp
 | 
				
			||||||
 | 
					        "secLevel": 1,
 | 
				
			||||||
 | 
					        "openedBy": "user"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def rand_id():
 | 
				
			||||||
 | 
					    return ''.join(secrets.choice(string.ascii_letters + string.digits) for _ in range(16))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class WsClient:
 | 
				
			||||||
 | 
					    def __init__(self, ws):
 | 
				
			||||||
 | 
					        self.ws = ws
 | 
				
			||||||
 | 
					        self.module_info = {}
 | 
				
			||||||
 | 
					        self.pcid = None
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def send(self, message):
 | 
				
			||||||
 | 
					        self.ws.send(json.dumps(message))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class WebSocketHandler:
 | 
				
			||||||
 | 
					    def __init__(self):
 | 
				
			||||||
 | 
					        self.clients = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def on_message(self, client, message):
 | 
				
			||||||
 | 
					        message_type = message.get('type')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Route messages based on type using match-case
 | 
				
			||||||
 | 
					        match message_type:
 | 
				
			||||||
 | 
					            case "CAuth":
 | 
				
			||||||
 | 
					                client.pcid = message["pcid"]
 | 
				
			||||||
 | 
					            case "CLog":
 | 
				
			||||||
 | 
					                print(f"[CC] [{message["level"]}] {message["msg"]}")
 | 
				
			||||||
 | 
					            case "CModule":
 | 
				
			||||||
 | 
					                match message["module"]:
 | 
				
			||||||
 | 
					                    case "keypad":
 | 
				
			||||||
 | 
					                        self.handle_keypad_msg(client, message["message"]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def handle_keypad_msg(self, client: WsClient, message):
 | 
				
			||||||
 | 
					        match message["type"]:
 | 
				
			||||||
 | 
					            case "CDoorOpened":
 | 
				
			||||||
 | 
					                print(f"[CC][KEYPAD] Door was opened on {message["time"]} {"manually" if message["manual"] else ""}")
 | 
				
			||||||
 | 
					            case "CGetUserStat":
 | 
				
			||||||
 | 
					                client.send({
 | 
				
			||||||
 | 
					                    "type": "SUserStat",
 | 
				
			||||||
 | 
					                    # user info
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					            case "CGetDoorStat":
 | 
				
			||||||
 | 
					                stats = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                for pc in self.clients:
 | 
				
			||||||
 | 
					                    i = pc.module_info["keypad"]
 | 
				
			||||||
 | 
					                    stats[pc.uid] = i if i else {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                client.send({
 | 
				
			||||||
 | 
					                    "type": "CDoorStat",
 | 
				
			||||||
 | 
					                    "stats": stats
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def new_client(self, ws):
 | 
				
			||||||
 | 
					        uid = rand_id()
 | 
				
			||||||
 | 
					        self.clients[uid] = WsClient(ws)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.clients[uid].send({
 | 
				
			||||||
 | 
					            "type" : "SAuthReq"
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        async for msg_t in ws:
 | 
				
			||||||
 | 
					            msg = json.loads(msg_t)
 | 
				
			||||||
 | 
					            self.on_message(self.clients[uid], msg) 
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def stop(self):
 | 
				
			||||||
 | 
					        for c in self.clients:
 | 
				
			||||||
 | 
					            c.ws.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async def main():
 | 
				
			||||||
 | 
					    wsh = WebSocketHandler()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async with websockets.serve(wsh.new_client, "localhost", 8765):
 | 
				
			||||||
 | 
					        await asyncio.get_running_loop().create_future()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					asyncio.run(main())
 | 
				
			||||||
| 
						 | 
					@ -1,34 +0,0 @@
 | 
				
			||||||
import express from "express";
 | 
					 | 
				
			||||||
import { assert } from "console";
 | 
					 | 
				
			||||||
import routes from "./routes";
 | 
					 | 
				
			||||||
import http from "http";
 | 
					 | 
				
			||||||
import Websocket from "./websocket";
 | 
					 | 
				
			||||||
import expressWinston from "express-winston";
 | 
					 | 
				
			||||||
import winston from "winston";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default class Api {
 | 
					 | 
				
			||||||
    declare app: express.Application;
 | 
					 | 
				
			||||||
    declare server: http.Server;
 | 
					 | 
				
			||||||
    declare wss: Websocket; 
 | 
					 | 
				
			||||||
    constructor(port: number) {
 | 
					 | 
				
			||||||
        this.app = express();
 | 
					 | 
				
			||||||
        this.app.use(expressWinston.logger({
 | 
					 | 
				
			||||||
            transports: [
 | 
					 | 
				
			||||||
                new winston.transports.Console()
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            format: winston.format.combine(
 | 
					 | 
				
			||||||
                winston.format.colorize(),
 | 
					 | 
				
			||||||
                winston.format.cli(),
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            meta: true,
 | 
					 | 
				
			||||||
            msg: "HTTP {{req.method}} {{req.url}}",
 | 
					 | 
				
			||||||
            expressFormat: true, 
 | 
					 | 
				
			||||||
            colorize: true,
 | 
					 | 
				
			||||||
            // ignoreRoute: function (req, res) { return false; } // optional: allows to skip some log messages based on request and/or response
 | 
					 | 
				
			||||||
        }));
 | 
					 | 
				
			||||||
        this.app.use("/api", routes);
 | 
					 | 
				
			||||||
        this.server = http.createServer(this.app);
 | 
					 | 
				
			||||||
        this.server.listen(port);
 | 
					 | 
				
			||||||
        this.wss = new Websocket(this.server);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,12 +0,0 @@
 | 
				
			||||||
import { Router, Request, Response } from "express";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const router = Router();
 | 
					 | 
				
			||||||
router.get("/", function (req: Request, res: Response) {
 | 
					 | 
				
			||||||
    res.send("Hewo :333");
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
router.get("/:uuid/keypad/get_code", (req: Request, res: Response) {
 | 
					 | 
				
			||||||
    res.send("Hewo :333");
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default router;
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,10 +0,0 @@
 | 
				
			||||||
import { Router, Request, Response } from "express";
 | 
					 | 
				
			||||||
import cc from "./cc";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const router = Router();
 | 
					 | 
				
			||||||
router.get("/", function (req: Request, res: Response) {
 | 
					 | 
				
			||||||
    res.send("Hewo :3");
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
router.use("/cc", cc);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default router;
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,10 +0,0 @@
 | 
				
			||||||
import http from "http";
 | 
					 | 
				
			||||||
import ws from "ws";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default class Websocket {
 | 
					 | 
				
			||||||
    declare wss: ws.WebSocketServer;
 | 
					 | 
				
			||||||
    constructor(server: http.Server) {
 | 
					 | 
				
			||||||
        this.wss = new ws.WebSocketServer({ path: "/ws", server })
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										31
									
								
								src/index.ts
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								src/index.ts
									
									
									
									
									
								
							| 
						 | 
					@ -1,31 +0,0 @@
 | 
				
			||||||
import Api from "./api";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function main() {
 | 
					 | 
				
			||||||
    console.log("Starting");
 | 
					 | 
				
			||||||
    const api = new Api(8080);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
main();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,21 +0,0 @@
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    "$schema": "http://json.schemastore.org/tsconfig",
 | 
					 | 
				
			||||||
    "compilerOptions": {
 | 
					 | 
				
			||||||
        "typeRoots": ["./node_modules/@types", "./src/types"],
 | 
					 | 
				
			||||||
        "strict": true,
 | 
					 | 
				
			||||||
        "target": "ESNext",
 | 
					 | 
				
			||||||
        "module": "CommonJS",
 | 
					 | 
				
			||||||
        "moduleResolution": "node",
 | 
					 | 
				
			||||||
        "allowSyntheticDefaultImports": true,
 | 
					 | 
				
			||||||
        "esModuleInterop": true,
 | 
					 | 
				
			||||||
        "types": [""],
 | 
					 | 
				
			||||||
        "isolatedModules": true,
 | 
					 | 
				
			||||||
        "noImplicitAny": true,
 | 
					 | 
				
			||||||
        "alwaysStrict": true,
 | 
					 | 
				
			||||||
        "outDir": "./build/",
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "include": [
 | 
					 | 
				
			||||||
        "src/**/*.ts",
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user