mirror of
https://github.com/ibratabian17/OpenParty.git
synced 2026-01-15 14:22:54 -03:00
231 lines
8.5 KiB
JavaScript
231 lines
8.5 KiB
JavaScript
const axios = require('axios');
|
|
const { v4: uuidv4 } = require('uuid');
|
|
const core = {
|
|
main: require('../var').main,
|
|
CloneObject: require('../helper').CloneObject,
|
|
generateCarousel: require('../carousel/carousel').generateCarousel,
|
|
generateSweatCarousel: require('../carousel/carousel').generateSweatCarousel,
|
|
generateCoopCarousel: require('../carousel/carousel').generateCoopCarousel,
|
|
updateMostPlayed: require('../carousel/carousel').updateMostPlayed,
|
|
signer: require('../lib/signUrl'),
|
|
ipResolver: require('../lib/ipResolver'),
|
|
};
|
|
const { addUserId, updateUserTicket, getUserData, updateUser } = require('./account');
|
|
const settings = require('../../settings.json');
|
|
const cachedTicket = {};
|
|
const ipCache = {}; // Cache untuk menyimpan ticket berdasarkan IP
|
|
|
|
const prodwsurl = "https://public-ubiservices.ubi.com/";
|
|
|
|
// Replace placeholders in the object
|
|
const replaceDomainPlaceholder = (obj, domain) => {
|
|
if (typeof obj === 'string') {
|
|
return obj.replace('{SettingServerDomainVarOJDP}', domain);
|
|
} else if (Array.isArray(obj)) {
|
|
return obj.map(item => replaceDomainPlaceholder(item, domain));
|
|
} else if (obj && typeof obj === 'object') {
|
|
return Object.keys(obj).reduce((acc, key) => {
|
|
acc[key] = replaceDomainPlaceholder(obj[key], domain);
|
|
return acc;
|
|
}, {});
|
|
}
|
|
return obj;
|
|
};
|
|
|
|
// Get client IP from request
|
|
const getClientIp = (req) => core.ipResolver.getClientIp(req);
|
|
|
|
// Placeholder function for getting the country based on IP
|
|
const getCountryFromIp = (ip) => 'US';
|
|
|
|
// Generate a fake ticket for fallback
|
|
const generateFalseTicket = () => {
|
|
const start = "ew0KIC";
|
|
const end = "KfQ==";
|
|
const middleLength = 60;
|
|
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
let middle = '';
|
|
|
|
for (let i = 0; i < middleLength; i++) {
|
|
middle += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
}
|
|
|
|
return start + middle + end;
|
|
};
|
|
|
|
|
|
const atob = (base64) => Buffer.from(base64, 'base64').toString('utf-8');
|
|
const parseCustomAuthHeader = (authorization) => {
|
|
const [method, encoded] = authorization.split(" ");
|
|
if (method !== "uplaypc_v1" || !encoded.includes("t=")) {
|
|
return null;
|
|
}
|
|
|
|
// Ambil bagian setelah "t=" pertama saja
|
|
const encodedPart = encoded.substring(encoded.indexOf("t=") + 2);
|
|
|
|
// Decode Base64 setelah "t="
|
|
const decoded = atob(encodedPart);
|
|
const [tag, encodedProfileId, profileId, username, email, encodedPassword] = decoded.split(":");
|
|
|
|
if (tag !== "JDParty") return null;
|
|
|
|
return {
|
|
profileId,
|
|
username,
|
|
email,
|
|
password: atob(encodedPassword),
|
|
};
|
|
};
|
|
|
|
// Initialize routes
|
|
exports.initroute = (app, express, server) => {
|
|
|
|
// Serve application configuration
|
|
app.get('/:version/applications/:appId/configuration', (req, res) => {
|
|
res.send(core.main.configuration);
|
|
});
|
|
|
|
// Serve alternative application configuration
|
|
app.get('/:version/applications/:appId', (req, res) => {
|
|
res.send(core.main.configurationnx);
|
|
});
|
|
|
|
// Handle session creation
|
|
app.post("/v3/profiles/sessions", async (req, res) => {
|
|
const clientIp = getClientIp(req);
|
|
const clientIpCountry = getCountryFromIp(clientIp);
|
|
|
|
// Helper to generate session data
|
|
const generateSessionData = (profileId, username, clientIp, clientIpCountry, ticket) => {
|
|
const now = new Date();
|
|
const expiration = new Date(now.getTime() + 3 * 60 * 60 * 1000); // 3 hours
|
|
|
|
const data = {
|
|
platformType: "uplay",
|
|
ticket,
|
|
twoFactorAuthenticationTicket: null,
|
|
profileId,
|
|
userId: profileId,
|
|
nameOnPlatform: username,
|
|
environment: "Prod",
|
|
expiration: expiration.toISOString(),
|
|
spaceId: uuidv4(),
|
|
clientIp,
|
|
clientIpCountry,
|
|
serverTime: now.toISOString(),
|
|
sessionId: uuidv4(),
|
|
sessionKey: "TqCz5+J0w9e8qpLp/PLr9BCfAc30hKlEJbN0Xr+mbZa=",
|
|
rememberMeTicket: null,
|
|
};
|
|
return data;
|
|
};
|
|
|
|
// Remove Host header
|
|
const headers = { ...req.headers };
|
|
delete headers.host;
|
|
|
|
const customAuthData = parseCustomAuthHeader(headers.authorization);
|
|
|
|
if (customAuthData) {
|
|
console.log("[ACC] CustomAuth detected, verifying...");
|
|
|
|
const { profileId, username, email, password } = customAuthData;
|
|
const userData = getUserData(profileId);
|
|
const ticket = `CustomAuth${headers.authorization.split(" t=")[1]}`
|
|
|
|
if (userData && userData.password && userData.email && userData.password === password) {
|
|
console.log("[ACC] CustomAuth login: ", atob(username));
|
|
updateUser(profileId, { username: atob(username), nickname: atob(username), email, password, userId: profileId, ticket: `Ubi_v1 ${ticket}` });
|
|
const sessionData = generateSessionData(profileId, username, clientIp, clientIpCountry, ticket)
|
|
res.send(sessionData);
|
|
return;
|
|
} else if (!userData || !userData.password || !userData.email) {
|
|
console.log("[ACC] CustomAuth register: ", atob(username));
|
|
updateUser(profileId, { username: atob(username), nickname: atob(username), email, password, userId: profileId, ticket: `Ubi_v1 ${ticket}` });
|
|
res.send(generateSessionData(profileId, atob(username), clientIp, clientIpCountry, ticket));
|
|
return;
|
|
} else {
|
|
console.log("[ACC] CustomAuth login, Invalid Credentials: ", atob(username));
|
|
}
|
|
}
|
|
|
|
try {
|
|
console.log("[ACC] Fetching Ticket From Official Server");
|
|
const response = await axios.post(`${prodwsurl}/v3/profiles/sessions`, req.body, { headers });
|
|
|
|
res.send(response.data);
|
|
console.log("[ACC] Using Official Ticket");
|
|
|
|
// Update user mappings
|
|
addUserId(response.data.profileId, response.data.userId);
|
|
updateUserTicket(response.data.profileId, `Ubi_v1 ${response.data.ticket}`);
|
|
} catch (error) {
|
|
console.log("[ACC] Error fetching from Ubisoft services", error.message);
|
|
|
|
if (ipCache[clientIp]) {
|
|
console.log(`[ACC] Returning cached session for IP ${clientIp}`);
|
|
return res.send(ipCache[clientIp]);
|
|
}
|
|
|
|
const profileId = uuidv4();
|
|
const userTicket = generateFalseTicket();
|
|
cachedTicket[userTicket] = profileId;
|
|
|
|
console.log("[ACC] Generating Fake Session for", profileId);
|
|
|
|
const fakeSession = generateSessionData(profileId, "NintendoSwitch", clientIp, clientIpCountry, userTicket);
|
|
ipCache[clientIp] = fakeSession;
|
|
|
|
res.send(fakeSession);
|
|
}
|
|
});
|
|
|
|
|
|
// Handle session deletion
|
|
app.delete("/v3/profiles/sessions", (req, res) => {
|
|
res.send();
|
|
});
|
|
|
|
// Retrieve profiles based on query parameters
|
|
app.get("/v3/profiles", (req, res) => {
|
|
const profileId = `${cachedTicket[req.header('Authorization')] || 'UnknownTicket'}/userId/${req.query.idOnPlatform}`;
|
|
res.send({
|
|
profiles: [{
|
|
profileId,
|
|
userId: profileId,
|
|
platformType: "uplay",
|
|
idOnPlatform: profileId,
|
|
nameOnPlatform: "Ryujinx"
|
|
}]
|
|
});
|
|
});
|
|
|
|
// Serve population data
|
|
app.get("/v1/profiles/me/populations", (req, res) => {
|
|
const spaceId = req.query.spaceIds || uuidv4();
|
|
res.send({
|
|
spaceId,
|
|
data: {
|
|
US_SDK_APPLICATION_BUILD_ID: "202007232022",
|
|
US_SDK_DURABLES: []
|
|
}
|
|
});
|
|
});
|
|
|
|
// Serve application parameters for JD22
|
|
app.get("/v1/applications/34ad0f04-b141-4793-bdd4-985a9175e70d/parameters", (req, res) => {
|
|
res.send(replaceDomainPlaceholder(require("../../database/v1/parameters.json"), settings.server.domain));
|
|
});
|
|
|
|
// Serve application parameters for JD18
|
|
app.get("/v1/spaces/041c03fa-1735-4ea7-b5fc-c16546d092ca/parameters", (req, res) => {
|
|
res.send(replaceDomainPlaceholder(require("../../database/v1/parameters2.json"), settings.server.domain));
|
|
});
|
|
|
|
// Handle user-related requests (stubbed for now)
|
|
app.post("/v3/users/:user", (req, res) => {
|
|
res.send();
|
|
});
|
|
};
|