Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions routes/avatar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// routes/avatar.js
const express = require("express");
const router = express.Router();

// GET /v1/avatar/fortnite/ids
router.get("/v1/avatar/fortnite/ids", (req, res) => {
const ids = req.query.accountIds?.split(",") || [];

const avatars = ids.map(id => ({
accountId: id,
avatarUrl: "https://fortnite-public-service-prod11.ol.epicgames.com/fortnite/api/game/v2/profile/avatar/default"
}));

res.json(avatars);
});

module.exports = router;
22 changes: 22 additions & 0 deletions routes/contentControls.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const express = require("express");
const router = express.Router();

// GET /content-controls/:accountId/rules/namespaces/fn
router.get("/content-controls/:accountId/rules/namespaces/fn", (req, res) => {
const { accountId } = req.params;

console.log(`[CONTENT-CONTROLS] Rules requested for ${accountId}`);

return res.json({
accountId: accountId,
namespaces: {
fn: {
restrictions: [],
version: 1
}
},
updatedAt: new Date().toISOString()
});
});

module.exports = router;
26 changes: 26 additions & 0 deletions routes/contentRules.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const express = require("express");
const router = express.Router();

// POST /content-controls/{accountId}/rules/namespaces/fn
router.post("/content-controls/:accountId/rules/namespaces/fn", (req, res) => {
console.log(`[CONTENT RULES] Request for ${req.params.accountId}`);

res.json({
namespace: "fn",
rules: {
"ageRating": {
enabled: false,
value: "UNRESTRICTED"
},
"chat": {
enabled: true
},
"ugc": {
enabled: true
}
},
updatedAt: new Date().toISOString()
});
});

module.exports = router;
17 changes: 17 additions & 0 deletions routes/favouriteCreativeMaps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const express = require("express");
const router = express.Router();

// GET /fortnite/api/game/v2/creative/favorites/:accountId
router.get("/fortnite/api/game/v2/creative/favorites/:accountId", (req, res) => {
const { accountId } = req.params;
const { limit } = req.query;

console.log(`[CREATIVE] Favorites request for ${accountId}, limit=${limit}`);

// Fortnite empty listet is elfogad
return res.json({
favorites: []
});
});

module.exports = router;
48 changes: 48 additions & 0 deletions routes/fixUsersApi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
const express = require("express");
const router = express.Router();

/*
|--------------------------------------------------------------------------
| LINKS HISTORY
|--------------------------------------------------------------------------
| GET /api/v1/links/history/:accountId?limit=30
*/
router.get("/api/v1/links/history/:accountId", (req, res) => {
res.json({
links: [],
accountId: req.params.accountId,
limit: Number(req.query.limit) || 30
});
});

/*
|--------------------------------------------------------------------------
| LFG SETTINGS
|--------------------------------------------------------------------------
| PATCH /api/v1/lfg/Fortnite/users/:accountId/settings
*/
router.patch("/api/v1/lfg/Fortnite/users/:accountId/settings", (req, res) => {
res.json({
accountId: req.params.accountId,
settings: req.body || {},
updated: true
});
});

/*
|--------------------------------------------------------------------------
| BR INVENTORY (VERY IMPORTANT STUB)
|--------------------------------------------------------------------------
| GET /fortnite/api/game/v2/br-inventory/account/:accountId
*/
router.get("/fortnite/api/game/v2/br-inventory/account/:accountId", (req, res) => {
res.json({
accountId: req.params.accountId,
inventory: {
currency: [],
items: []
}
});
});

module.exports = router;
133 changes: 133 additions & 0 deletions routes/fixes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
const express = require("express");
const app = express.Router();

/**
* Helper: empty OK responses
*/
const ok = (req, res) => res.status(200).json({});
const noContent = (req, res) => res.sendStatus(204);
const accepted = (req, res) => res.sendStatus(202);

/* =========================
DATAROUTER / TELEMETRY
========================= */

// basic datarouter
app.post("/datarouter/api/v1/public/data", accepted);

// FN client event stream
app.post("/datarouter/api/v1/public/data/clients", accepted);

// EOS / SDK telemetry (note the /telemetry/data prefix)
app.post("/telemetry/data/datarouter/api/v1/public/data", accepted);

/* =========================
HOTCONFIG / CONTENT
========================= */

app.get("/hotconfigs/v2/livefn.json", (req, res) => {
res.json({
version: 1,
configs: {}
});
});

app.get("/api/content/v2/launch-data", ok);

/* =========================
PROFILE / USER PREFS
========================= */

app.put("/profile/play_region", noContent);
app.put("/profile/languages", noContent);
app.put("/profile/privacy_settings", noContent);

/* =========================
SOCIAL / FRIENDS
========================= */

app.get("/epic/friends/v1/:accountId/blocklist", (req, res) => {
res.json({ blocked: [] });
});

app.get("/content-controls/:accountId", ok);

app.get("/party/api/v1/Fortnite/user/:accountId/settings/privacy", ok);

/* =========================
INTERACTIONS (SOCIAL FEED)
========================= */

app.get("/api/v2/interactions/latest/Fortnite/:accountId", (req, res) => {
res.json({ entries: [] });
});

app.get("/api/v2/interactions/aggregated/Fortnite/:accountId", (req, res) => {
res.json({ stats: {} });
});

/* =========================
LFG
========================= */

app.get("/api/v1/lfg/Fortnite/users/:accountId/settings", ok);

/* =========================
ACCOUNTS (PUBLIC LOOKUPS)
========================= */

app.get("/api/v1/public/accounts", (req, res) => {
const ids = [].concat(req.query.accountId || []);
res.json(
ids.map(id => ({
id,
displayName: "Player",
externalAuths: {}
}))
);
});

/* =========================
OAUTH MISC
========================= */

app.post("/epic/oauth/v2/tokenInfo", ok);

/* =========================
FEEDBACK / LOG UPLOADS
========================= */

app.get("/api/v1/access/fortnite/client-feedback/*", noContent);
app.post("/fortnite/api/feedback/*", noContent);

/* =========================
LINKS / LOCK STATUS
========================= */

app.post("/api/v1/links/lock-status/:accountId/check", (req, res) => {
res.json({ locked: false });
});

/* =========================
MOTD SURFACES
========================= */

app.post("/api/v1/fortnite-br/surfaces/:surface/target", (req, res) => {
res.json({
entries: []
});
});

/* =========================
APP / REGION
========================= */

app.get("/app_installation/status", ok);

app.get("/region", (req, res) => {
res.json({
region: "EU"
});
});

module.exports = app;
20 changes: 20 additions & 0 deletions routes/fnCrewEULA.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const express = require("express");
const router = express.Router();

// GET /eulatracking/api/shared/agreements/fn-crew-terms
router.get("/eulatracking/api/shared/agreements/fn-crew-terms", (req, res) => {
console.log("[EULA] Crew terms requested");

const locale = req.query.locale || "en";

return res.json({
key: "fn-crew-terms",
version: 1,
locale: locale,
content: "By using this Fortnite private backend, you agree to nothing. This is a fake EULA for private server use.",
accepted: true,
acceptedDate: new Date().toISOString()
});
});

module.exports = router;
16 changes: 16 additions & 0 deletions routes/friendsRecent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// routes/friendsRecent.js
const express = require("express");
const router = express.Router();

// GET /friends/api/v1/:accountId/recent/fortnite
router.get("/friends/api/v1/:accountId/recent/fortnite", (req, res) => {
const accountId = req.params.accountId;

// Dummy recent players lista (üresen is működik)
res.json({
accountId: accountId,
recentPlayers: []
});
});

module.exports = router;
22 changes: 22 additions & 0 deletions routes/legacyUnlock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const express = require("express");
const router = express.Router();

// ================================
// LEGACY UNLOCK STUB
// ================================
router.delete("/api/v1/links/legacy-unlock/:accountId", (req, res) => {
const { accountId } = req.params;

// Csak logoljuk, de nem végzünk tényleges unlockot
console.log(`[LegacyUnlock] DELETE called for account: ${accountId}`);

// Visszaadjuk, hogy sikeres volt
res.json({
accountId: accountId,
unlocked: true, // mindig sikeres
serverTime: new Date().toISOString(),
responseVersion: 1
});
});

module.exports = router;
61 changes: 61 additions & 0 deletions routes/missingfixes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
const express = require("express");
const router = express.Router();

/* helpers */
const ok = (req, res) => res.status(200).json({});
const noContent = (req, res) => res.sendStatus(204);

/* =========================
CLIENT FEEDBACK / LOG UPLOAD
(urlencoded path miatt wildcard!)
========================= */

router.get(
"/api/v1/access/fortnite/client-feedback*",
noContent
);

/* =========================
PROFILES (PUT /profiles)
========================= */

router.put("/profiles", noContent);

/* =========================
FORTNITE TRACKS
========================= */

router.get(
"/api/v1/games/fortnite/tracks/query",
(req, res) => {
res.json({
tracks: []
});
}
);

/* =========================
TAGS
========================= */

router.get("/api/v1/public/tags", (req, res) => {
res.json({
tags: []
});
});

/* =========================
BLURL FILES (dynamic hash path)
========================= */

router.get("/:hash/master.blurl", noContent);
router.get("/:hash/main.blurl", noContent);

/* =========================
SAFETY NET (optional)
only for weird FN GETs
========================= */

// router.get("*", noContent);

module.exports = router;
Loading