mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-15 15:24:52 +09:00
Create lobbies on demand and only list servers on the player's version
When a player connects with a Factorio version and set of built in mods no lobby runs, the lobby plugin now creates one on a connected host that has the version installed or can download it, with a mod pack matching the player's built in mods. This lets a cluster accept players on several Factorio versions on the same port without any setup. It can be turned off with lobby.auto_create. To pick the mod pack the proxy now waits for the whole connection confirm before routing and passes the mods listed in it to the playerProxyRoute hook. Hosts answer the new HostFactorioVersionsRequest with the versions they have installed. The server list in lobbies only shows instances on the Factorio version of the lobby, with a checkbox to also show the others greyed out.
This commit is contained in:
14 files changed
+582
-39
No files matched your search
@@ -267,6 +267,54 @@ export function parseConnectionRequestReplyConfirm(buffer: Buffer): ConnectionRe
|
||||
return { clientRequestId, serverRequestId, serverRequestIdOffset, username };
|
||||
}
|
||||
|
||||
/** Mod enabled in a Factorio client */
|
||||
export interface ModId {
|
||||
name: string;
|
||||
version: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Join the payloads of the fragments of a message
|
||||
*
|
||||
* @param fragments -
|
||||
* Fragments of the message in order of fragment number, or the message
|
||||
* if it's not fragmented.
|
||||
* @returns the payload of the message.
|
||||
*/
|
||||
export function joinPayload(fragments: Buffer[]) {
|
||||
return Buffer.concat(fragments.map(fragment => fragment.subarray(parseHeader(fragment).payloadOffset)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the mods enabled in the client from a ConnectionRequestReplyConfirm
|
||||
*
|
||||
* @param payload - Complete payload of the message, see {@link joinPayload}.
|
||||
* @returns name and version of each mod.
|
||||
*/
|
||||
export function parseConfirmMods(payload: Buffer): ModId[] {
|
||||
const reader = new BufferReader(payload);
|
||||
reader.readUInt32LE(); // connectionRequestIDGeneratedOnClient
|
||||
reader.readUInt32LE(); // connectionRequestIDGeneratedOnServer
|
||||
reader.readUInt32LE(); // instanceID
|
||||
reader.readString(); // username
|
||||
reader.readString(); // password
|
||||
reader.readString(); // serverKey
|
||||
reader.readString(); // serverKeyTimestamp
|
||||
reader.readUInt32LE(); // coreChecksum
|
||||
reader.readUInt32LE(); // prototypeListChecksum
|
||||
const count = reader.readSpaceOptimizedUInt32();
|
||||
const mods: ModId[] = [];
|
||||
for (let i = 0; i < count; i++) {
|
||||
const name = reader.readString();
|
||||
const version = [
|
||||
reader.readSpaceOptimizedUInt16(), reader.readSpaceOptimizedUInt16(), reader.readSpaceOptimizedUInt16(),
|
||||
].join(".");
|
||||
reader.readUInt32LE(); // crc
|
||||
mods.push({ name, version });
|
||||
}
|
||||
return mods;
|
||||
}
|
||||
|
||||
export function encodeConnectionRequest(version: ApplicationVersion, clientRequestId: number, messageId = 0) {
|
||||
const writer = new BufferWriter();
|
||||
writer.writeUInt8(MessageType.ConnectionRequest);
|
||||
|
||||
Reference in new issue
Block a user