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
34 changes: 34 additions & 0 deletions actions/fivem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ const WINDOWS_MASTER = "build_server_windows/master";
const WINDOWS_FILE = "server.zip";
const LINUX_MASTER = "build_proot_linux/master";
const LINUX_FILE = "fx.tar.xz";
const FIVEM_CHANGELOG_API_WIN =
"https://changelogs-live.fivem.net/api/changelog/versions/win32/server";
const FIVEM_CHANGELOG_API_LINUX =
"https://changelogs-live.fivem.net/api/changelog/versions/linux/server";

type ReturnType =
| {
Expand Down Expand Up @@ -36,6 +40,36 @@ export function getAllBrokenArtifacts(): { [key: string]: string } {
return brokenArtifacts;
}

export async function getFivemOfficialRecommended(): Promise<{
version: string;
windowsDownload: string | null;
linuxDownload: string | null;
} | null> {
try {
const [winRes, linuxRes] = await Promise.all([
fetch(FIVEM_CHANGELOG_API_WIN, { next: { revalidate: 432000 } }),
fetch(FIVEM_CHANGELOG_API_LINUX, { next: { revalidate: 432000 } }),
]);
if (!winRes.ok) return null;

const winData: { recommended?: string; recommended_download?: string } =
await winRes.json();
if (!winData.recommended) return null;

const linuxData: { recommended_download?: string } = linuxRes.ok
? await linuxRes.json()
: {};

return {
version: winData.recommended,
windowsDownload: winData.recommended_download ?? null,
linuxDownload: linuxData.recommended_download ?? null,
};
} catch {
return null;
}
}

export async function getRecommendedArtifact(): Promise<ReturnType> {
try {
const brokenArtifacts = getAllBrokenArtifacts();
Expand Down
89 changes: 81 additions & 8 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,30 @@
import { getRecommendedArtifact } from "@/actions/fivem";
import {
getFivemOfficialRecommended,
getRecommendedArtifact,
} from "@/actions/fivem";
import BrokenArtifacts from "./brokenArtifacts";

export const revalidate = 432000; // 5 days

export default async function Home() {
const data:
| {
windowsDownloadLink: string;
linuxDownloadLink: string;
recommendedArtifact: string;
}
| false = await getRecommendedArtifact();
const [data, fivemRecommended]: [
(
| {
windowsDownloadLink: string;
linuxDownloadLink: string;
recommendedArtifact: string;
}
| false
),
{
version: string;
windowsDownload: string | null;
linuxDownload: string | null;
} | null,
] = await Promise.all([
getRecommendedArtifact(),
getFivemOfficialRecommended(),
]);

if (!data)
return (
Expand Down Expand Up @@ -70,6 +84,65 @@ export default async function Home() {
short wait period, to allow time for issues to be reported.
</div>

<div className="text-xs my-4 border border-red-900 p-2.5 rounded bg-red-950/40">
<span className="bg-red-500 font-semibold px-0.5 rounded-s-full mr-1 border border-opacity-30 border-zinc-900">
*Important:
</span>
Using the latest artifacts is always risky. Never run the latest
versions on a server that is in active production. Latest builds are
generally not broadly tested and may lead to unknown issues. Always use
FiveM&apos;s officially{" "}
<span className="font-semibold">recommended</span> version
{fivemRecommended ? (
<>
{" "}
(the safest, most stable recommended version:{" "}
{fivemRecommended.windowsDownload ? (
<a
href={fivemRecommended.windowsDownload}
target="_blank"
rel="noopener noreferrer"
className="bg-green-500/90 hover:bg-green-500 px-1.5 py-0.5 rounded font-sans text-white font-bold no-underline"
>
{fivemRecommended.version}
</a>
) : (
<code className="bg-green-500/90 px-1.5 py-0.5 rounded font-sans text-white font-bold">
{fivemRecommended.version}
</code>
)}
{fivemRecommended.windowsDownload || fivemRecommended.linuxDownload
? " — Download: "
: null}
{fivemRecommended.windowsDownload ? (
<a
href={fivemRecommended.windowsDownload}
target="_blank"
rel="noopener noreferrer"
className="text-blue-400 hover:underline"
>
Windows
</a>
) : null}
{fivemRecommended.windowsDownload && fivemRecommended.linuxDownload
? " · "
: null}
{fivemRecommended.linuxDownload ? (
<a
href={fivemRecommended.linuxDownload}
target="_blank"
rel="noopener noreferrer"
className="text-blue-400 hover:underline"
>
Linux
</a>
) : null}
)
</>
) : null}
.
</div>

<div className="flex justify-between mt-10 mb-2 text-xs">
<p className="text-gray-400">Artifacts with reported issues:</p>
<a
Expand Down