HOLY CRAP IT ACTUALLY WORKS

This commit is contained in:
Haroon 2024-07-03 00:01:43 +01:00
parent e6aacd6897
commit 09e0d89ffa

200
index.ts
View file

@ -23,123 +23,6 @@ const app = new App({
} }
}); });
/// GENERATED ///
type Room = {
id: number;
name: string;
category: string;
type: string;
user_id: number;
starts_at: string;
ends_at: string | null;
max_attempts: number | null;
participant_count: number;
channel_id: number;
active: boolean;
has_password: boolean;
queue_mode: string;
auto_skip: boolean;
current_playlist_item: {
id: number;
room_id: number;
beatmap_id: number;
ruleset_id: number;
allowed_mods: any[];
required_mods: {
acronym: string;
settings: Record<string, unknown>;
}[];
expired: boolean;
owner_id: number;
playlist_order: number | null;
played_at: string | null;
beatmap: {
beatmapset_id: number;
difficulty_rating: number;
id: number;
mode: string;
status: string;
total_length: number;
user_id: number;
version: string;
beatmapset: {
artist: string;
artist_unicode: string;
covers: {
cover: string;
cover2x: string;
card: string;
card2x: string;
list: string;
list2x: string;
slimcover: string;
slimcover2x: string;
};
creator: string;
favourite_count: number;
hype: number | null;
id: number;
nsfw: boolean;
offset: number;
play_count: number;
preview_url: string;
source: string;
spotlight: boolean;
status: string;
title: string;
title_unicode: string;
track_id: number | null;
user_id: number;
video: boolean;
};
};
};
difficulty_range: {
max: number;
min: number;
};
host: {
avatar_url: string;
country_code: string;
default_group: string;
id: number;
is_active: boolean;
is_bot: boolean;
is_deleted: boolean;
is_online: boolean;
is_supporter: boolean;
last_visit: string;
pm_friends_only: boolean;
profile_colour: string | null;
username: string;
country: {
code: string;
name: string;
};
};
playlist_item_stats: {
count_active: number;
count_total: number;
ruleset_ids: number[];
};
recent_participants: {
avatar_url: string;
country_code: string;
default_group: string;
id: number;
is_active: boolean;
is_bot: boolean;
is_deleted: boolean;
is_online: boolean;
is_supporter: boolean;
last_visit: string;
pm_friends_only: boolean;
profile_colour: string | null;
username: string;
}[];
};
/// GENERATED ///
const states = new Map(); const states = new Map();
app.command("/osu-link", async (ctx) => { app.command("/osu-link", async (ctx) => {
@ -209,7 +92,7 @@ receiver.router.get("/osu/callback", async (req, res) => {
const state = req.query.state as string; const state = req.query.state as string;
let _userId let _userId
try { try {
const [userId, hash] = state.split(':'); const [userId, hash] = state.split(':');
@ -289,7 +172,7 @@ async function getAccessToken(slack_id: string): Promise<string> {
body: `client_id=33126&client_secret=${encodeURIComponent(process.env.CLIENT_SECRET!)}&grant_type=refresh_token&refresh_token=${user[0].refresh_token}&scope=public` body: `client_id=33126&client_secret=${encodeURIComponent(process.env.CLIENT_SECRET!)}&grant_type=refresh_token&refresh_token=${user[0].refresh_token}&scope=public`
}).then(res => res.json()); }).then(res => res.json());
sql`UPDATE links SET refresh_token = ${data.refresh_token} WHERE slack_id = ${slack_id}`; await sql`UPDATE links SET refresh_token = ${data.refresh_token} WHERE slack_id = ${slack_id}`;
return data.access_token; return data.access_token;
} }
@ -328,7 +211,7 @@ const cache: {
} }
}[] = [] }[] = []
const multiplayerRoundCache: Room[] = []; const multiplayerRoundCache: any[] = [];
async function cacheStuff(): Promise<void> { async function cacheStuff(): Promise<void> {
const token = await getTemporaryToken(); const token = await getTemporaryToken();
@ -376,9 +259,11 @@ async function cacheStuff(): Promise<void> {
multiplayerRoundCache.length = 0; multiplayerRoundCache.length = 0;
const tohken = await getAccessToken("U06TBP41C3E");
const rooms = await fetch(`https://osu.ppy.sh/api/v2/rooms?category=realtime`, { const rooms = await fetch(`https://osu.ppy.sh/api/v2/rooms?category=realtime`, {
headers: { headers: {
'Authorization': `Bearer ${await getAccessToken("U06TBP41C3E")}` 'Authorization': `Bearer ${tohken}`
} }
}).then(res => res.json()); }).then(res => res.json());
@ -815,23 +700,78 @@ app.command("/osu-multiplayer-invite", async (ctx) => {
}); });
} }
const ownedRoom = multiplayerRoundCache.find(room => room.host.id == me.id); const ownedRoom = multiplayerRoundCache.find(room => room.host.id == me.id && room.active);
if (!me) { if (!ownedRoom) {
return ctx.respond({ return ctx.respond({
response_type: 'ephemeral', response_type: 'ephemeral',
text: `Hey <@${ctx.context.userId}>, you aren't in a multiplayer room. If you are, make sure you're the host of the room, and you're on osu!lazer.`, text: `Hey <@${ctx.context.userId}>, you aren't in a multiplayer room. If you are, make sure you're the host of the room, and you're on osu!lazer. If this is still happening, my cache may need reloading. Wait about a minute before running the command again.`,
blocks: [ blocks: [
{ {
type: 'section', type: 'section',
text: { text: {
type: 'mrkdwn', type: 'mrkdwn',
text: `Hey <@${ctx.context.userId}>, you aren't in a multiplayer room. If you are, make sure you're the host of the room, and you're on osu!lazer.`, text: `Hey <@${ctx.context.userId}>, you aren't in a multiplayer room. If you are, make sure you're the host of the room, and you're on osu!lazer. If this is still happening, my cache may need reloading. Wait about a minute before running the command again.`,
} }
} }
] ]
}); });
} }
const ratings = ownedRoom.playlist.map((x: any) => x.beatmap.difficulty_rating);
const min = Math.min(...ratings);
const max = Math.max(...ratings);
const currentSong = ownedRoom.playlist.find((x: any) => !x.expired)
const ruleset = [":osu-standard: osu!standard", ":osu-taiko: osu!taiko", ":osu-catch: osu!catch", ":osu-mania: osu!mania"][ownedRoom.playlist[0].ruleset_id]
return ctx.respond({
response_type: 'in_channel',
"blocks": [
{
"type": "context",
"elements": [
{
"type": "mrkdwn",
"text": `<@${ctx.context.userId}> ran \`/osu-multiplayer-invite\` | ${ruleset}${ownedRoom.has_password ? " | Password required" : ""}`
}
]
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": `*Room*: ${ownedRoom.name}\n*Star Rating*: ${min} - ${max}\n\n*Currently playing:* <https://osu.ppy.sh/beatmapsets/${currentSong.beatmap.beatmapset_id}#osu/${currentSong.beatmap.id}|${currentSong.beatmap.beatmapset.title_unicode} - ${currentSong.beatmap.beatmapset.artist_unicode} (${currentSong.beatmap.difficulty_rating})>`
},
"accessory": {
"type": "image",
"image_url": ownedRoom.host.avatar_url,
"alt_text": `${ownedRoom.host.username}'s osu profile picture`
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "Join this lobby:"
},
"accessory": {
"type": "button",
"text": {
"type": "plain_text",
"text": "Join",
"emoji": true
},
"value": "link",
"url": `osu://mp/${ownedRoom.id}`,
"action_id": "link"
}
}
]
})
}) })
receiver.router.get('/osu/news.rss', async (req, res) => { receiver.router.get('/osu/news.rss', async (req, res) => {
@ -854,16 +794,16 @@ receiver.router.get('/osu/news.rss', async (req, res) => {
<link>https://osu.haroon.hackclub.app/home/news</link> <link>https://osu.haroon.hackclub.app/home/news</link>
</image> </image>
${posts.map((post: any) => ${posts.map((post: any) =>
`<item> `<item>
<title>${post.title}</title> <title>${post.title}</title>
<link>https://osu.haroon.hackclub.app/home/news/${post.slug}</link> <link>https://osu.haroon.hackclub.app/home/news/${post.slug}</link>
<guid isPermaLink="false">${post.id}</guid> <guid isPermaLink="false">${post.id}</guid>
<pubDate>${new Date(post.published_at).toLocaleString('en-GB', {timeZone: 'UTC',hour12: false,weekday: 'short',year: 'numeric',month: 'short',day: '2-digit',hour: '2-digit',minute: '2-digit',second: '2-digit',}).replace(/(?:(\d),)/, '$1') + ' GMT'}</pubDate> <pubDate>${new Date(post.published_at).toLocaleString('en-GB', { timeZone: 'UTC', hour12: false, weekday: 'short', year: 'numeric', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', }).replace(/(?:(\d),)/, '$1') + ' GMT'}</pubDate>
<description>${post.preview}</description> <description>${post.preview}</description>
<enclosure url="${post.first_image}" type="image/jpg"/> <enclosure url="${post.first_image}" type="image/jpg"/>
</item>` </item>`
).join('\n ')} ).join('\n ')}
</channel> </channel>
</rss>`; </rss>`;