hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/src/app.js
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2025-10-12 15:42:39 +0200
committerhachem <im@hachem.wtf>2025-10-12 15:42:39 +0200
commitace016c0c58abbdafd74f116175a3675a370fce6 (patch)
tree0a2747053af084be7d62b82380bf1bbbb3c99c71 /src/app.js
parent068377ec00b57c359ce66070a0844245cb4e9fa5 (diff)
[finish]: finish
Diffstat (limited to 'src/app.js')
-rw-r--r--src/app.js153
1 files changed, 61 insertions, 92 deletions
diff --git a/src/app.js b/src/app.js
index 2a67f0b..d25b3b6 100644
--- a/src/app.js
+++ b/src/app.js
@@ -2,19 +2,14 @@ const { Client, Events, GatewayIntentBits } = require("discord.js")
const axios = require("axios")
const fs = require("fs-extra")
const path = require("path")
-const config = require("../config.json")
+const config = require("../config/config.json")
+const api = require("../config/api.json")
-const {
- token,
- channel_id,
- minecraft_version,
- modrinth_mods,
-} = config
+const { channel_id, minecraft_version, modrinth_mods } = config
+const { token } = api
const cacheFile = path.join(__dirname, "../cache/mod_versions.json")
-
const client = new Client({ intents: [GatewayIntentBits.Guilds] })
-const strictVersionMatch = true
const LoadCache = async () =>
{
@@ -22,8 +17,7 @@ const LoadCache = async () =>
{
if (await fs.pathExists(cacheFile))
return JSON.parse(await fs.readFile(cacheFile, "utf8"))
- }
- catch (err)
+ } catch (err)
{
console.error("[Cache] Failed to read cache:", err)
}
@@ -36,135 +30,112 @@ const SaveCache = async (cache) =>
{
await fs.ensureDir(path.dirname(cacheFile))
await fs.writeFile(cacheFile, JSON.stringify(cache, null, 2))
- }
- catch (err)
+ } catch (err)
{
console.error("[Cache] Failed to save cache:", err)
}
}
-const GetLatestFabricVersion = async (slug) =>
+const GetCompatibleModVersion = async (slug, targetMinecraftVersion) =>
{
try
{
const res = await axios.get(`https://api.modrinth.com/v2/project/${slug}/version`)
- const versions = res.data.filter(v => v.loaders.includes("fabric"))
- if (versions.length === 0) return null
+ const fabricVersions = res.data.filter(v => v.loaders.includes("fabric"))
+ if (fabricVersions.length === 0)
+ return null
- return versions.sort(
- (a, b) => new Date(b.date_published) - new Date(a.date_published)
+ const compatible = fabricVersions.find(v => v.game_versions.includes(targetMinecraftVersion))
+ const latest = fabricVersions.sort((a, b) =>
+ new Date(b.date_published) - new Date(a.date_published)
)[0]
- }
- catch (err)
+
+ return { latest, compatible: compatible || null }
+ } catch (err)
{
console.error(`[Modrinth] Error fetching ${slug}:`, err.message)
return null
}
}
-const IsVersionCompatible = (modVersionList, targetVersion) =>
-{
- if (strictVersionMatch)
- return modVersionList.includes(targetVersion)
- else
- return modVersionList.some(v => targetVersion.startsWith(v))
-}
-
const CheckModUpdates = async () =>
{
- console.log("[Check] Checking for mod updates...")
+ console.log("[Check] Checking for mod compatibility...")
const cache = await LoadCache()
const newCache = { ...cache }
- const updates = []
- const upToDate = []
+ const compatibleReleased = []
const waitingUpdate = []
+ const newlyCompatible = []
for (const slug of modrinth_mods)
{
- const latest = await GetLatestFabricVersion(slug)
- if (!latest) continue
+ const modData = await GetCompatibleModVersion(slug, minecraft_version)
+ if (!modData) continue
- const compatible = IsVersionCompatible(latest.game_versions, minecraft_version)
+ const { latest, compatible } = modData
const latestId = latest.id
const cachedId = cache[slug]
if (compatible)
{
- if (cachedId !== latestId)
- {
- newCache[slug] = latestId
- updates.push({
- slug,
- version: latest.version_number,
- url: `https://modrinth.com/mod/${slug}/version/${latestId}`,
- })
- }
- else
+ compatibleReleased.push({ slug })
+ newCache[slug] = latestId
+
+ if (!cachedId || cachedId !== latestId)
{
- upToDate.push({
- slug,
- version: latest.version_number,
- url: `https://modrinth.com/mod/${slug}/version/${latestId}`,
- })
- console.log(`[Check] ${slug} is up to date.`)
+ newlyCompatible.push({ slug })
+ console.log(`[Update] ${slug} is now compatible with Minecraft ${minecraft_version}`)
}
- }
- else
+ } else
{
- waitingUpdate.push({
- slug,
- version: latest.version_number,
- url: `https://modrinth.com/mod/${slug}/version/${latestId}`,
- })
- console.log(`[Check] ${slug} waiting for update — not compatible with ${minecraft_version}`)
+ waitingUpdate.push({ slug })
+ console.log(`[Check] ${slug} is waiting for a compatible version`)
}
}
await SaveCache(newCache)
- return { updates, upToDate, waitingUpdate }
+ return { compatibleReleased, waitingUpdate, newlyCompatible }
}
-const SendUpdateMessages = async (channel, updates, upToDate, waitingUpdate) =>
+const SendUpdateMessages = async (channel, compatibleReleased, waitingUpdate, newlyCompatible) =>
{
- if (updates.length === 0)
+ if (!compatibleReleased.length && !waitingUpdate.length)
{
- console.log("[Update]: No new updates.");
- return;
+ console.log("[Update]: No mods to report.")
+ return
}
- let message = ""
- message += `**Mod Update Check — Minecraft ${minecraft_version}**\n\n`
+ let message = `**Mod Compatibility Check — Minecraft ${minecraft_version}**\n\n`
- if (updates.length > 0)
+ if (newlyCompatible.length > 0)
{
- message += `**🟢 Updated Mods:**\n`
- for (const { slug, url } of updates)
- message += `✅ [${slug}](${url}) updated\n`
+ message += `**🎉 Mods Recently Updated:**\n`
+ for (const { slug } of newlyCompatible)
+ message += `✅ ${slug}\n`
message += `\n`
}
- if (upToDate.lengt > 0)
- {
- message += `**⚪ Up-to-Date Mods:**\n`
- for (const { slug, url } of upToDate)
- message += `✅ [${slug}](${url})\n`
+ const stillCompatible = compatibleReleased.filter(
+ m => !newlyCompatible.find(n => n.slug === m.slug)
+ )
+ if (stillCompatible.length > 0)
+ {
+ message += `**🟢 Mods Compatible:**\n`
+ for (const { slug } of stillCompatible)
+ message += `✅ ${slug}\n`
message += `\n`
}
if (waitingUpdate.length > 0)
{
- message += `**⏳ Mods Waiting for Update:**\n`
- for (const { slug, url } of waitingUpdate)
- message += `❌ [${slug}](${url})\n`
+ message += `**⏳ Mods Waiting on Update:**\n`
+ for (const { slug } of waitingUpdate)
+ message += `❌ ${slug}\n`
+ message += `\n`
}
-
- await channel.send(
-{
- content: message,
- allowedMentions: { parse: [] },
- flags: 4
- })
- console.log(`[Discord] Sent update summary (${updates.length} updated, ${upToDate.length} up-to-date, ${waitingUpdate.length} waiting).`)
+
+ await channel.send({ content: message, allowedMentions: { parse: [] }, flags: 4 })
+ console.log(`[Discord] Sent update summary (${newlyCompatible.length} updated, ${stillCompatible.length} compatible, ${waitingUpdate.length} waiting).`)
}
client.once(Events.ClientReady, async readyClient =>
@@ -172,20 +143,18 @@ client.once(Events.ClientReady, async readyClient =>
console.log(`[OK] Logged in as ${readyClient.user.tag}`)
const channel = await client.channels.fetch(channel_id).catch(() => null)
- if (!channel)
- {
+ if (!channel) {
console.error("❌ Could not find channel ID:", channel_id)
return
}
- const { updates, upToDate, waitingUpdate } = await CheckModUpdates()
- await SendUpdateMessages(channel, updates, upToDate, waitingUpdate)
+ const { compatibleReleased, waitingUpdate, newlyCompatible } = await CheckModUpdates()
+ await SendUpdateMessages(channel, compatibleReleased, waitingUpdate, newlyCompatible)
- // ⏰ Check every hour (3600000 ms)
setInterval(async () =>
{
- const { updates, upToDate, waitingUpdate } = await CheckModUpdates()
- await SendUpdateMessages(channel, updates, upToDate, waitingUpdate)
+ const { compatibleReleased, waitingUpdate, newlyCompatible } = await CheckModUpdates()
+ await SendUpdateMessages(channel, compatibleReleased, waitingUpdate, newlyCompatible)
}, 60 * 60 * 1000)
})