rele: 0.7.2

This commit is contained in:
dvelo 2024-08-07 21:15:13 -05:00
parent 2771fce1b0
commit 435e80165d
8 changed files with 180 additions and 148 deletions

@ -27,7 +27,6 @@ First, you must supply the following services with API keys:
- [Clerk](https://clerk.com): Create an app and put the respective keys in `.env.local`
- MongoDB: Create a database, can be anywhere, and put the location to connect in `.env.local` for the key `MONGO_DB` (this isn't required by any means, but if you want to store any short term or historical data, use this.)
- Inngest: Inngest is a smaller library, but runs the `cron` jobs which will make servers automaticly get added to the database.
_This project uses `yarn` as the main package manager. If `package-lock.json` is present, your pull request will get denied._
Second, run `yarn` and `yarn build`. To start the app, run `yarn start`.

@ -21,11 +21,14 @@ export default function AfterServerView({ server }: { server: string }) {
return (
<div className="grid sm:grid-cols-4 pl-4 pr-4 gap-3.5">
{description != "" && (
<Card className="sm:col-span-3">
<CardDescription className="p-4 prose dark:prose-invert">
<Markdown disallowedElements={["img"]}>{description}</Markdown>
</CardDescription>
</Card>
)}
{discord != "" && (
<Card>
<CardHeader>
<CardTitle>Discord Server</CardTitle>
@ -40,6 +43,8 @@ export default function AfterServerView({ server }: { server: string }) {
</CardDescription>
</CardHeader>
</Card>
)}
<br />
</div>
);

@ -2,22 +2,36 @@
import { getCustomization } from "@/lib/api";
import { useEffect, useState } from "react";
import { Spinner } from "./ui/spinner";
export default function Banner({ server }: { server: string }) {
const [bannerURL, setBannerURL] = useState("");
const [loading, setLoading] = useState(true);
useEffect(() => {
getCustomization(server).then((c) => {
setBannerURL(c.banner == null ? "" : c.banner);
setLoading(false);
setBannerURL(c.banner == undefined ? "" : c.banner);
});
}, [server]);
if (loading) {
return (
<>
<img
src={"https://i.imgur.com/" + bannerURL}
className="rounded align-middle block ml-auto mr-auto w-[50%] max-h-[150px]"
/>
<Spinner className="flex items-center" />
<br />
</>
);
}
return (
<>
{bannerURL != "" && (
<img
src={"https://i.imgur.com/" + bannerURL}
className="rounded align-middle block ml-auto mr-auto w-[50%] max-h-[150px]"
/>
)}
<br />
</>
);

@ -1,124 +0,0 @@
// inngest in mh-stats provides information periodicly. like every 30 minutes for historical data.
// its fully automatic
import Favorites from "@/app/account/favorites/page";
import { OnlineServer } from "@/lib/types/server";
import { Inngest } from "inngest";
import { serve } from "inngest/next";
import { MongoClient } from "mongodb";
import { Noto_Sans_Mahajani } from "next/font/google";
// Create a client to send and receive events
export const inngest = new Inngest({ id: "my-app" });
// Create an API that serves zero functions
export default serve({
client: inngest,
functions: [
inngest.createFunction(
{ id: "every-30-min" },
[{ cron: "*/30 * * * *" }, { event: "test/30-min" }],
async ({ event, step }) => {
const mongo = new MongoClient(process.env.MONGO_DB as string);
try {
const mh = await (
await fetch("https://api.minehut.com/servers", {
headers: {
accept: "*/*",
"accept-language": Math.random().toString(),
priority: "u=1, i",
"sec-ch-ua": '"Not/A)Brand";v="8", "Chromium";v="126"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"macOS"',
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "cross-site",
Referer: "http://localhost:3000/",
"Referrer-Policy": "strict-origin-when-cross-origin",
},
body: null,
method: "GET",
})
).json();
const mha = mongo.db("mhsf").collection("mh");
const meta = mongo.db("mhsf").collection("meta");
const dbl = mongo.db("mhsf").collection("history");
mha.insertOne({
total_players: mh.total_players,
total_servers: mh.total_servers,
unix: Date.now(),
});
mh.servers.forEach(async (server: OnlineServer, i: number) => {
const favorites = (async () => {
const result = await meta.find({ server: server.name }).toArray();
if (result.length == 0) {
return 0;
}
return result[0].favorites;
})();
const result = await favorites;
dbl.insertOne({
player_count: server.playerData.playerCount,
favorites: result,
server: server.name,
time: Date.now(),
});
if (i == mh.servers.length) {
mongo.close();
return {
event,
body: "Finished adding " + mh.servers.length + " servers.",
};
}
});
} catch (e) {
mongo.close();
return { event, body: "Cloudflare.. aborting " + e };
}
}
),
inngest.createFunction(
{ id: "every-two-months" },
[{ cron: "0 0 1 */2 *" }],
async ({ event, step }) => {
const mongo = new MongoClient(process.env.MONGO_DB as string);
const meta = mongo.db("mhsf").collection("history");
const historical = mongo.db("mhsf").collection("historical");
const array = await meta.find().toArray();
const result: any = {};
array.forEach((c) => {
if (result[c.server] == undefined) {
result[c.server] = {
server: c.server,
player_count: [c.player_count],
favorites: [c.favorites],
time: Date.now(),
};
} else {
result[c.server] = {
server: c.server,
player_count: [...result[c.server]?.player_count, c.player_count],
favorites: [...result[c.server]?.favorites, c.favorites],
time: c.time,
};
}
});
historical.insertMany(Object.values(result));
meta.drop();
mongo.close();
return {
event,
body: "Dropped database. ",
};
}
),
],
});

@ -0,0 +1,44 @@
import { OnlineServer } from "@/lib/types/server";
import { MongoClient } from "mongodb";
import { NextApiRequest, NextApiResponse } from "next";
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.headers.Authorization !== `Bearer ${process.env.CRON_SECRET}`) {
return res.status(401).end("Unauthorized");
}
const mongo = new MongoClient(process.env.MONGO_DB as string);
const meta = mongo.db("mhsf").collection("history");
const historical = mongo.db("mhsf").collection("historical");
const array = await meta.find().toArray();
const result: any = {};
array.forEach((c) => {
if (result[c.server] == undefined) {
result[c.server] = {
server: c.server,
player_count: [c.player_count],
favorites: [c.favorites],
time: Date.now(),
};
} else {
result[c.server] = {
server: c.server,
player_count: [...result[c.server]?.player_count, c.player_count],
favorites: [...result[c.server]?.favorites, c.favorites],
time: c.time,
};
}
});
historical.insertMany(Object.values(result));
meta.drop();
mongo.close();
return res.send({
body: "Dropped database. ",
});
}

@ -0,0 +1,74 @@
import { OnlineServer } from "@/lib/types/server";
import { MongoClient } from "mongodb";
import { NextApiRequest, NextApiResponse } from "next";
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.headers.Authorization !== `Bearer ${process.env.CRON_SECRET}`) {
return res.status(401).end("Unauthorized");
}
const mongo = new MongoClient(process.env.MONGO_DB as string);
try {
const mh = await (
await fetch("https://api.minehut.com/servers", {
headers: {
accept: "*/*",
"accept-language": Math.random().toString(),
priority: "u=1, i",
"sec-ch-ua": '"Not/A)Brand";v="8", "Chromium";v="126"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"macOS"',
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "cross-site",
Referer: "http://localhost:3000/",
"Referrer-Policy": "strict-origin-when-cross-origin",
},
body: null,
method: "GET",
})
).json();
const mha = mongo.db("mhsf").collection("mh");
const meta = mongo.db("mhsf").collection("meta");
const dbl = mongo.db("mhsf").collection("history");
mha.insertOne({
total_players: mh.total_players,
total_servers: mh.total_servers,
unix: Date.now(),
});
mh.servers.forEach(async (server: OnlineServer, i: number) => {
const favorites = (async () => {
const result = await meta.find({ server: server.name }).toArray();
if (result.length == 0) {
return 0;
}
return result[0].favorites;
})();
const result = await favorites;
dbl.insertOne({
player_count: server.playerData.playerCount,
favorites: result,
server: server.name,
time: Date.now(),
});
if (i == mh.servers.length) {
mongo.close();
return res.send({
body: "Finished adding " + mh.servers.length + " servers.",
});
}
});
} catch (e) {
mongo.close();
return res.send({
body: "Cloudflare interferred",
});
}
}

@ -1,4 +1,4 @@
export const version = "b-0.7.0";
export const version = "b-0.7.2";
const User = ({ user }: { user: string }) => (
<span className="cursor-pointer bg-[rgba(255,165,0,0.25);] rounded p-[2.5px]">
@ -8,6 +8,17 @@ const User = ({ user }: { user: string }) => (
export const Changelog = () => (
<>
<div>
<strong className="flex items-center">
Version b-0.7.2 (August 7th 2024)
</strong>
<ul>
<li> Adding new spinners to pages that needed it</li>
<li> Fixed lots of bugs</li>
<li> Moved from Inngest to Vercel Cron</li>
</ul>
</div>
<br />
<div>
<strong className="flex items-center">
Version b-0.7.0 (August 7th 2024)

9
vercel.json Normal file

@ -0,0 +1,9 @@
{
"crons": [
{
"path": "/api/v1/cron/periodic-st",
"schedule": "*/30 * * * *"
},
{ "path": "/api/v1/cron/data-cleanup", "schedule": "0 0 1 */2 *" }
]
}