mirror of
https://github.com/ApfelTeeSaft/SolarisServer.git
synced 2026-08-27 03:43:29 +00:00
250 lines
8.6 KiB
JavaScript
250 lines
8.6 KiB
JavaScript
const Express = require("express");
|
|
const express = Express.Router();
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
const iniparser = require("ini");
|
|
const config = iniparser.parse(fs.readFileSync(path.join(__dirname, "..", "Config", "config.ini")).toString());
|
|
const functions = require("./functions.js");
|
|
const WebSocket = require('ws');
|
|
|
|
let latestServerInfo = null;
|
|
|
|
const activeConnections = new Set();
|
|
|
|
express.post("/api/v1/server-info", async (req, res) => {
|
|
try {
|
|
if (!req.body.serverAddress || !req.body.serverPort) {
|
|
return res.status(400).json({ error: "Missing required server address or port" });
|
|
}
|
|
|
|
const { serverAddress, serverPort, sessionId, matchId, region, playlistName } = req.body;
|
|
|
|
latestServerInfo = {
|
|
serverAddress,
|
|
serverPort: Number(serverPort),
|
|
matchId: matchId || functions.MakeID().replace(/-/ig, ""),
|
|
sessionId: sessionId || functions.MakeID().replace(/-/ig, ""),
|
|
region: region || "EU",
|
|
playlistName: playlistName || "Playlist_DefaultSolo",
|
|
timestamp: Date.now()
|
|
};
|
|
|
|
console.log(`[ServerInfo] Received new server info: ${serverAddress}:${serverPort}`);
|
|
|
|
broadcastToAllConnections();
|
|
|
|
return res.status(200).json({ success: true });
|
|
} catch (error) {
|
|
console.error("Error processing server info:", error);
|
|
return res.status(500).json({ error: "Internal server error" });
|
|
}
|
|
});
|
|
|
|
function broadcastToAllConnections() {
|
|
if (!latestServerInfo) {
|
|
console.log("[Matchmaking] No server info available to broadcast");
|
|
return;
|
|
}
|
|
|
|
console.log(`[Matchmaking] Broadcasting to ${activeConnections.size} active connections`);
|
|
|
|
const broadcastMatchId = functions.MakeID().replace(/-/ig, "");
|
|
const broadcastSessionId = broadcastMatchId;
|
|
|
|
activeConnections.forEach(ws => {
|
|
if (ws.readyState === WebSocket.OPEN) {
|
|
try {
|
|
console.log(`[Matchmaking] Sending SessionAssignment to client`);
|
|
|
|
ws.send(
|
|
JSON.stringify({
|
|
payload: {
|
|
matchId: broadcastMatchId,
|
|
sessionId: broadcastSessionId,
|
|
state: "SessionAssignment",
|
|
},
|
|
name: "StatusUpdate",
|
|
})
|
|
);
|
|
|
|
ws.sessionId = broadcastSessionId;
|
|
ws.matchId = broadcastMatchId;
|
|
} catch (err) {
|
|
console.error("[Matchmaking] Error sending SessionAssignment:", err);
|
|
}
|
|
}
|
|
});
|
|
|
|
setTimeout(() => {
|
|
activeConnections.forEach(ws => {
|
|
if (ws.readyState === WebSocket.OPEN) {
|
|
try {
|
|
console.log(`[Matchmaking] Sending Play message to client`);
|
|
|
|
ws.send(
|
|
JSON.stringify({
|
|
payload: {
|
|
matchId: broadcastMatchId,
|
|
sessionId: broadcastSessionId,
|
|
joinDelaySec: 1,
|
|
},
|
|
name: "Play",
|
|
})
|
|
);
|
|
} catch (err) {
|
|
console.error("[Matchmaking] Error sending Play message:", err);
|
|
}
|
|
}
|
|
});
|
|
}, 2000);
|
|
}
|
|
|
|
function registerConnection(ws) {
|
|
activeConnections.add(ws);
|
|
console.log(`[Matchmaking] New connection registered, total: ${activeConnections.size}`);
|
|
|
|
if (latestServerInfo && latestServerInfo.timestamp > Date.now() - (5 * 60 * 1000)) {
|
|
console.log("[Matchmaking] Server info already available, sending to new connection");
|
|
|
|
const newMatchId = functions.MakeID().replace(/-/ig, "");
|
|
const newSessionId = newMatchId;
|
|
|
|
setTimeout(() => {
|
|
if (ws.readyState === WebSocket.OPEN) {
|
|
ws.send(
|
|
JSON.stringify({
|
|
payload: {
|
|
matchId: newMatchId,
|
|
sessionId: newSessionId,
|
|
state: "SessionAssignment",
|
|
},
|
|
name: "StatusUpdate",
|
|
})
|
|
);
|
|
|
|
ws.sessionId = newSessionId;
|
|
ws.matchId = newMatchId;
|
|
|
|
setTimeout(() => {
|
|
if (ws.readyState === WebSocket.OPEN) {
|
|
ws.send(
|
|
JSON.stringify({
|
|
payload: {
|
|
matchId: newMatchId,
|
|
sessionId: newSessionId,
|
|
joinDelaySec: 1,
|
|
},
|
|
name: "Play",
|
|
})
|
|
);
|
|
}
|
|
}, 2000);
|
|
}
|
|
}, 3000);
|
|
}
|
|
}
|
|
|
|
function unregisterConnection(ws) {
|
|
activeConnections.delete(ws);
|
|
console.log(`[Matchmaking] Connection closed, total: ${activeConnections.size}`);
|
|
}
|
|
|
|
global.matchmakingFunctions = {
|
|
registerConnection,
|
|
unregisterConnection
|
|
};
|
|
|
|
express.get("/fortnite/api/matchmaking/session/findPlayer/*", async (req, res) => {
|
|
res.status(200);
|
|
res.end();
|
|
})
|
|
|
|
express.get("/fortnite/api/game/v2/matchmakingservice/ticket/player/*", async (req, res) => {
|
|
res.cookie("currentbuildUniqueId", req.query.bucketId.split(":")[0]);
|
|
|
|
res.json({
|
|
"serviceUrl": `ws://${config.MatchmakerIP || "26.36.134.252"}`,
|
|
"ticketType": "mms-player",
|
|
"payload": "69=",
|
|
"signature": "420="
|
|
})
|
|
res.end();
|
|
})
|
|
|
|
express.get("/fortnite/api/game/v2/matchmaking/account/:accountId/session/:sessionId", async (req, res) => {
|
|
res.json({
|
|
"accountId": req.params.accountId,
|
|
"sessionId": req.params.sessionId,
|
|
"key": "AOJEv8uTFmUh7XM2328kq9rlAzeQ5xzWzPIiyKn2s7s="
|
|
})
|
|
})
|
|
|
|
express.get("/fortnite/api/matchmaking/session/:session_id", async (req, res) => {
|
|
let serverAddress = config.GameServer.ip;
|
|
let serverPort = Number(config.GameServer.port);
|
|
let playlistName = "Playlist_DefaultSolo";
|
|
let region = "EU";
|
|
|
|
if (latestServerInfo) {
|
|
console.log(`[Matchmaking] Using latest server info: ${latestServerInfo.serverAddress}:${latestServerInfo.serverPort}`);
|
|
serverAddress = latestServerInfo.serverAddress;
|
|
serverPort = latestServerInfo.serverPort;
|
|
playlistName = latestServerInfo.playlistName;
|
|
region = latestServerInfo.region;
|
|
} else {
|
|
console.log(`[Matchmaking] No server info available, using defaults`);
|
|
}
|
|
|
|
res.json({
|
|
"id": req.params.session_id,
|
|
"ownerId": functions.MakeID().replace(/-/ig, "").toUpperCase(),
|
|
"ownerName": "[DS]fortnite-liveeugcec1c2e30ubrcore0a-z8hj-1968",
|
|
"serverName": "[DS]fortnite-liveeugcec1c2e30ubrcore0a-z8hj-1968",
|
|
"serverAddress": serverAddress,
|
|
"serverPort": serverPort,
|
|
"maxPublicPlayers": 220,
|
|
"openPublicPlayers": 175,
|
|
"maxPrivatePlayers": 0,
|
|
"openPrivatePlayers": 0,
|
|
"attributes": {
|
|
"REGION_s": region,
|
|
"GAMEMODE_s": "FORTATHENA",
|
|
"ALLOWBROADCASTING_b": true,
|
|
"SUBREGION_s": "GB",
|
|
"DCID_s": "FORTNITE-LIVEEUGCEC1C2E30UBRCORE0A-14840880",
|
|
"tenant_s": "Fortnite",
|
|
"MATCHMAKINGPOOL_s": "Any",
|
|
"STORMSHIELDDEFENSETYPE_i": 0,
|
|
"HOTFIXVERSION_i": 0,
|
|
"PLAYLISTNAME_s": playlistName,
|
|
"SESSIONKEY_s": functions.MakeID().replace(/-/ig, "").toUpperCase(),
|
|
"TENANT_s": "Fortnite",
|
|
"BEACONPORT_i": 15009
|
|
},
|
|
"publicPlayers": [],
|
|
"privatePlayers": [],
|
|
"totalPlayers": 45,
|
|
"allowJoinInProgress": false,
|
|
"shouldAdvertise": false,
|
|
"isDedicated": false,
|
|
"usesStats": false,
|
|
"allowInvites": false,
|
|
"usesPresence": false,
|
|
"allowJoinViaPresence": true,
|
|
"allowJoinViaPresenceFriendsOnly": false,
|
|
"buildUniqueId": req.cookies.currentbuildUniqueId || "0",
|
|
"lastUpdated": new Date().toISOString(),
|
|
"started": false
|
|
})
|
|
})
|
|
|
|
express.post("/fortnite/api/matchmaking/session/*/join", async (req, res) => {
|
|
res.status(204);
|
|
res.end();
|
|
})
|
|
|
|
express.post("/fortnite/api/matchmaking/session/matchMakingRequest", async (req, res) => {
|
|
res.json([])
|
|
})
|
|
|
|
module.exports = express; |