mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-14 07:24:52 +09:00
No reason to duplicate this in both the instance and host connection if the implementation is identical in both.
115 lines
3.9 KiB
TypeScript
115 lines
3.9 KiB
TypeScript
import path from "path";
|
|
import fs from "fs-extra";
|
|
|
|
import type Controller from "./Controller";
|
|
import type WsServerConnector from "./WsServerConnector";
|
|
|
|
import * as lib from "@clusterio/lib";
|
|
const { logger } = lib;
|
|
import * as routes from "./routes";
|
|
|
|
|
|
/**
|
|
* Base class for controller connections
|
|
*
|
|
* @extends module:lib.Link
|
|
* @alias module:controller/src/BaseConnection
|
|
*/
|
|
export default class BaseConnection extends lib.Link {
|
|
declare "connector": WsServerConnector;
|
|
|
|
constructor(
|
|
connector: lib.WebSocketBaseConnector,
|
|
public _controller: Controller
|
|
) {
|
|
super(connector);
|
|
this.router = _controller.router;
|
|
for (let [Request, handler] of this._controller._registeredRequests) { this.handle(Request, handler); }
|
|
for (let [Request, handler] of this._controller._fallbackedRequests) { this.fallbackRequest(Request, handler); }
|
|
for (let [Event, handler] of this._controller._registeredEvents) { this.handle(Event, handler); }
|
|
for (let [Event, handler] of this._controller._snoopedEvents) { this.snoopEvent(Event, handler); }
|
|
|
|
this.handle(lib.ModPackGetRequest, this.handleModPackGetRequest.bind(this));
|
|
this.handle(lib.ModPackGetDefaultRequest, this.handleModPackGetDefaultRequest.bind(this));
|
|
this.handle(lib.ModDownloadRequest, this.handleModDownloadRequest.bind(this));
|
|
this.handle(lib.FactorioVersionsRequest, this.handleFactorioVersionsRequest.bind(this));
|
|
|
|
this.handle(lib.SubscriptionRequest, this.handleSubscriptionRequest.bind(this));
|
|
this.connector.on("close", () => {
|
|
this._controller.subscriptions.unsubscribeLink(this);
|
|
});
|
|
}
|
|
|
|
async disconnect(code: number, reason: string) {
|
|
try {
|
|
await this.connector.disconnect(code, reason);
|
|
} catch (err: any) {
|
|
if (!(err instanceof lib.SessionLost)) {
|
|
logger.error(`"Unexpected error preparing disconnect:\n${err.stack}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* True if the link is connected, not in the dropped state and not in
|
|
* the process of disconnecting.
|
|
*/
|
|
get connected(): boolean {
|
|
return this.connector.connected;
|
|
}
|
|
|
|
async handleModPackGetRequest(request: lib.ModPackGetRequest): Promise<lib.ModPack> {
|
|
let { id } = request;
|
|
let modPack = this._controller.modPacks.get(id);
|
|
if (!modPack) {
|
|
throw new lib.RequestError(`Mod pack with ID ${id} does not exist`);
|
|
}
|
|
return modPack;
|
|
}
|
|
|
|
async handleModPackGetDefaultRequest(): Promise<lib.ModPack> {
|
|
let id = this._controller.config.get("controller.default_mod_pack_id");
|
|
if (id === null) {
|
|
throw new lib.RequestError("Default mod pack not set on controller");
|
|
}
|
|
let modPack = this._controller.modPacks.get(id);
|
|
if (!modPack) {
|
|
throw new lib.RequestError(`Default mod pack configured (${id}) does not exist`);
|
|
}
|
|
return modPack;
|
|
}
|
|
|
|
getMod(mod: { name: string, version: lib.FullVersion, sha1?: string }) {
|
|
let filename = lib.ModInfo.filename(mod.name, mod.version);
|
|
let modInfo = this._controller.modStore.files.get(filename);
|
|
if (!modInfo) {
|
|
throw new lib.RequestError(`Mod ${filename} does not exist on controller`);
|
|
}
|
|
if (mod.sha1 && mod.sha1 !== modInfo.sha1) {
|
|
throw new lib.RequestError(`Mod ${filename} checksum does not match controller's checksum`);
|
|
}
|
|
return modInfo;
|
|
}
|
|
|
|
async handleModDownloadRequest(request: lib.ModDownloadRequest) {
|
|
let mod = this.getMod(request);
|
|
let modPath = path.join(this._controller.config.get("controller.mods_directory"), mod.filename);
|
|
|
|
let stream = await routes.createProxyStream(this._controller.app);
|
|
stream.filename = mod.filename;
|
|
stream.source = fs.createReadStream(modPath);
|
|
stream.mime = "application/zip";
|
|
stream.size = String(mod.size);
|
|
|
|
return stream.id;
|
|
}
|
|
|
|
async handleSubscriptionRequest(request: lib.SubscriptionRequest, src: lib.Address, dst: lib.Address) {
|
|
return await this._controller.subscriptions.handleRequest(this, request, src, dst);
|
|
}
|
|
|
|
async handleFactorioVersionsRequest(request: lib.FactorioVersionsRequest) {
|
|
return await this._controller.factorioVersions.get(request.maxAgeMs);
|
|
}
|
|
}
|