new game stuff, analytics

This commit is contained in:
sky
2026-02-07 14:45:30 -05:00
parent 49e542b3e9
commit 71f377ac18
20 changed files with 144 additions and 562 deletions

View File

@ -271,7 +271,7 @@ async function generateAccountPage(name, cookie, admin) {
}
let modifiedHTML = rawProfileHTML;
console.log(userData.music);
// console.log(userData.music);
let songData = JSON.parse(userData.music) || false;
modifiedHTML = modifiedHTML.replaceAll("{{ name }}", sanitizeHtml(userData.name, allowNone));
modifiedHTML = modifiedHTML.replaceAll("{{ join_date }}", dayjs(userData.createdAt).fromNow());

12
ai.js
View File

@ -1,21 +1,23 @@
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
import { generateText } from 'ai';
import { generateText, streamText } from 'ai';
const model = createOpenAICompatible({
name: 'model',
apiKey: process.env.OPENAI_API_KEY,
baseURL: process.env.OPENAI_BASE_URL,
includeUsage: true, // Include usage information in streaming responses
includeUsage: true,
});
async function callAI(chatHistory) {
console.log("call ai called")
let { text } = await generateText({
// TODO: add proper checking for chat
// realistically, just trust whats given, just make sure that the only roles are user and assistant
let { text } = streamText({
model: model(process.env.OPENAI_MODEL),
system: "You are Zen, a helpful AI assistant built by Selenite. Your response should be accurate without hallucination." +
"Over the course of conversation, adapt to the user's tone and preferences. Try to match the user's vibe, tone, and generally how they are speaking. You want the conversation to feel natural. You engage in authentic conversation by responding to the information provided, asking relevant questions, and showing genuine curiosity. If natural, use information you know about the user to personalize your responses and ask a follow up question.",
messages: chatHistory
});
console.log(text);
return text.toTextStreamResponse();
}
export { callAI };

View File

@ -6,12 +6,14 @@ if(!await (Bun.file(process.env.DATA_PATH)).exists()) {
}
const accs = new Database(`${process.env.DATA_PATH}/accounts.sqlite`, { create: true });
const top = new Database(`${process.env.DATA_PATH}/games.sqlite`, { create: true });
// const infdb = new Database(`${process.env.DATA_PATH}/infinitecraft.sqlite`);
// const friends = new Database(`${process.env.DATA_PATH}/friends.sqlite`);
// const polytrack = new Database(`${process.env.DATA_PATH}/polytrack.sqlite`);
// const ai_chats = new Database(`${process.env.DATA_PATH}/ai_chats.sqlite`);
accs.exec("PRAGMA journal_mode = WAL;");
top.exec("PRAGMA journal_mode = WAL;");
// infdb.exec("PRAGMA journal_mode = WAL;");
// friends.exec("PRAGMA journal_mode = WAL;");
// polytrack.exec("PRAGMA journal_mode = WAL;");
@ -46,5 +48,11 @@ createAccountQuery+=`)`
// console.log(createAccountQuery)
accs.query(createAccountQuery).run();
let topGamesQuery = `CREATE TABLE IF NOT EXISTS "stats" (
"game" TEXT PRIMARY KEY,
"plays" INTEGER DEFAULT 0
);`
top.query(topGamesQuery).run();
// export { accs, infdb, friends, polytrack, ai_chats };
export { accs };
export { accs, top };

View File

@ -1,192 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Open Learning Hub - Your gateway to free educational resources for coding, science, math, humanities, languages, and more.">
<meta name="keywords" content="education, free learning, online courses, coding, science, math, humanities, languages, study tools">
<meta name="author" content="Open Learning Hub">
<meta property="og:title" content="Open Learning Hub">
<meta property="og:description" content="Discover free educational resources and daily learning tips.">
<meta property="og:type" content="website">
<title>Open Learning Hub</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<div class="container">
<h1>Open Learning Hub</h1>
<p>Your gateway to free educational resources across the web.</p>
</div>
</header>
<main class="container">
<section id="tip-section">
<h2>💡 Tip of the Day</h2>
<p id="daily-tip">Loading tip...</p>
<button id="new-tip-btn">Get Another Tip</button>
</section>
<section id="resources">
<h2>Educational Resources</h2>
<div class="filter-controls">
<button class="filter-btn active" data-filter="all">All</button>
<button class="filter-btn" data-filter="coding">Coding</button>
<button class="filter-btn" data-filter="science">Science</button>
<button class="filter-btn" data-filter="math">Math</button>
<button class="filter-btn" data-filter="humanities">Humanities</button>
<button class="filter-btn" data-filter="languages">Languages</button>
<button class="filter-btn" data-filter="courses">Online Courses</button>
<button class="filter-btn" data-filter="tools">Study Tools</button>
</div>
<div class="resource-grid">
<!-- Coding -->
<article class="card" data-category="coding">
<h3>freeCodeCamp</h3>
<p>Learn to code for free with interactive lessons and projects.</p>
<a href="https://www.freecodecamp.org" target="_blank">Visit Site</a>
</article>
<article class="card" data-category="coding">
<h3>MDN Web Docs</h3>
<p>Resources for developers, by developers. The bible of web dev.</p>
<a href="https://developer.mozilla.org" target="_blank">Visit Site</a>
</article>
<article class="card" data-category="coding">
<h3>GitHub</h3>
<p>The world's largest platform for software development and version control.</p>
<a href="https://github.com" target="_blank">Visit Site</a>
</article>
<article class="card" data-category="coding">
<h3>The Odin Project</h3>
<p>A full stack curriculum that is free and supported by a passionate open source community.</p>
<a href="https://www.theodinproject.com/" target="_blank">Visit Site</a>
</article>
<!-- Science -->
<article class="card" data-category="science">
<h3>NASA</h3>
<p>Explore the universe with images, videos, and news from NASA.</p>
<a href="https://www.nasa.gov" target="_blank">Visit Site</a>
</article>
<article class="card" data-category="science">
<h3>National Geographic</h3>
<p>World leader in geography, cartography and exploration.</p>
<a href="https://www.nationalgeographic.com" target="_blank">Visit Site</a>
</article>
<article class="card" data-category="science">
<h3>Nature</h3>
<p>Leading international weekly journal of science.</p>
<a href="https://www.nature.com" target="_blank">Visit Site</a>
</article>
<!-- Math -->
<article class="card" data-category="math">
<h3>Khan Academy</h3>
<p>Free, world-class education for anyone, anywhere.</p>
<a href="https://www.khanacademy.org" target="_blank">Visit Site</a>
</article>
<article class="card" data-category="math">
<h3>Wolfram MathWorld</h3>
<p>The web's most extensive mathematics resource.</p>
<a href="https://mathworld.wolfram.com" target="_blank">Visit Site</a>
</article>
<article class="card" data-category="math">
<h3>Desmos</h3>
<p>Beautiful, free online graphing calculator.</p>
<a href="https://www.desmos.com" target="_blank">Visit Site</a>
</article>
<!-- Humanities -->
<article class="card" data-category="humanities">
<h3>Project Gutenberg</h3>
<p>A library of over 60,000 free eBooks.</p>
<a href="https://www.gutenberg.org" target="_blank">Visit Site</a>
</article>
<article class="card" data-category="humanities">
<h3>Smithsonian</h3>
<p>Official website of the Smithsonian Institution.</p>
<a href="https://www.si.edu" target="_blank">Visit Site</a>
</article>
<article class="card" data-category="humanities">
<h3>Internet Archive</h3>
<p>Non-profit library of millions of free books, movies, software, and music.</p>
<a href="https://archive.org" target="_blank">Visit Site</a>
</article>
<!-- Languages -->
<article class="card" data-category="languages">
<h3>Duolingo</h3>
<p>The world's most popular way to learn a language. It's 100% free.</p>
<a href="https://www.duolingo.com" target="_blank">Visit Site</a>
</article>
<article class="card" data-category="languages">
<h3>BBC Languages</h3>
<p>Archived but excellent resources for learning 40 languages.</p>
<a href="https://www.bbc.co.uk/languages/" target="_blank">Visit Site</a>
</article>
<!-- Online Courses -->
<article class="card" data-category="courses">
<h3>Coursera</h3>
<p>Build skills with courses, certificates, and degrees online from world-class universities.</p>
<a href="https://www.coursera.org" target="_blank">Visit Site</a>
</article>
<article class="card" data-category="courses">
<h3>edX</h3>
<p>Access 2000+ free online courses from 140 leading institutions worldwide.</p>
<a href="https://www.edx.org" target="_blank">Visit Site</a>
</article>
<article class="card" data-category="courses">
<h3>MIT OpenCourseWare</h3>
<p>A web-based publication of virtually all MIT course content.</p>
<a href="https://ocw.mit.edu" target="_blank">Visit Site</a>
</article>
<!-- Study Tools -->
<article class="card" data-category="tools">
<h3>Anki</h3>
<p>Powerful, intelligent flashcards. Remembering things just became much easier.</p>
<a href="https://apps.ankiweb.net/" target="_blank">Visit Site</a>
</article>
<article class="card" data-category="tools">
<h3>Notion</h3>
<p>The all-in-one workspace for your notes, tasks, wikis, and databases.</p>
<a href="https://www.notion.so/" target="_blank">Visit Site</a>
</article>
<article class="card" data-category="tools">
<h3>Pomofocus</h3>
<p>A customizable Pomodoro timer that works on desktop & mobile browser.</p>
<a href="https://pomofocus.io/" target="_blank">Visit Site</a>
</article>
</div>
</section>
<section id="learning-paths">
<h2>🚀 Learning Paths</h2>
<div class="paths-container">
<div class="path-card">
<h3>For Beginners</h3>
<p>Start with <strong>Khan Academy</strong> to build a strong foundation in Math and Science. Then, try <strong>Duolingo</strong> for a new language.</p>
</div>
<div class="path-card">
<h3>For Career Switchers</h3>
<p>Dive into <strong>freeCodeCamp</strong> or <strong>The Odin Project</strong> (add this!) to learn web development. Supplement with <strong>CS50</strong> on edX.</p>
</div>
<div class="path-card">
<h3>For Lifelong Learners</h3>
<p>Explore <strong>Project Gutenberg</strong> for classics, <strong>TED Talks</strong> for inspiration, and <strong>Coursera</strong> for specific interests.</p>
</div>
</div>
</section>
</main>
<footer>
<div class="container">
<p>&copy; 2025 Open Learning Hub.</p>
</div>
</footer>
<script src="script.js"></script>
</body>
</html>

View File

@ -1,65 +0,0 @@
document.addEventListener('DOMContentLoaded', () => {
// --- Tip of the Day Logic ---
const tips = [
"Spaced repetition is a learning technique that incorporates increasing intervals of time between subsequent review of previously learned material.",
"The Pomodoro Technique uses a timer to break down work into intervals, traditionally 25 minutes in length, separated by short breaks.",
"Teaching someone else is one of the best ways to learn a new concept (The Feynman Technique).",
"Sleep is crucial for memory consolidation. Pulling an all-nighter is often counterproductive.",
"Active recall (testing yourself) is far more effective than passive re-reading.",
"Interleaving practice (mixing different subjects or topics) improves long-term retention compared to blocked practice.",
"Exercise increases blood flow to the brain and can improve cognitive performance.",
"Setting specific, measurable goals (SMART goals) helps maintain motivation.",
"Taking handwritten notes can improve conceptual understanding better than typing.",
"Mnemonic devices like acronyms or rhymes can help encode information into long-term memory."
];
const tipElement = document.getElementById('daily-tip');
const newTipBtn = document.getElementById('new-tip-btn');
function showRandomTip() {
const randomIndex = Math.floor(Math.random() * tips.length);
tipElement.textContent = tips[randomIndex];
// Add a subtle animation effect
tipElement.style.opacity = 0;
setTimeout(() => {
tipElement.style.opacity = 1;
}, 50);
}
if (newTipBtn) {
newTipBtn.addEventListener('click', showRandomTip);
}
// Show initial tip
if (tipElement) {
showRandomTip();
tipElement.style.transition = "opacity 0.5s ease-in-out";
}
// --- Filtering Logic ---
const filterBtns = document.querySelectorAll('.filter-btn');
const cards = document.querySelectorAll('.card');
filterBtns.forEach(btn => {
btn.addEventListener('click', () => {
// Remove active class from all buttons
filterBtns.forEach(b => b.classList.remove('active'));
// Add active class to clicked button
btn.classList.add('active');
const filterValue = btn.getAttribute('data-filter');
cards.forEach(card => {
if (filterValue === 'all' || card.getAttribute('data-category') === filterValue) {
card.style.display = 'flex';
// Add animation for appearing elements
card.style.animation = 'fadeIn 0.5s ease-in-out';
} else {
card.style.display = 'none';
}
});
});
});
});

View File

@ -1,185 +0,0 @@
:root {
--primary-color: #2c3e50;
--secondary-color: #3498db;
--accent-color: #e74c3c;
--bg-color: #f4f4f4;
--card-bg: #ffffff;
--text-color: #333;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
line-height: 1.6;
background-color: var(--bg-color);
color: var(--text-color);
}
.container {
max-width: 1100px;
margin: 0 auto;
padding: 0 20px;
}
header {
background-color: var(--primary-color);
color: white;
padding: 2rem 0;
text-align: center;
margin-bottom: 2rem;
}
header h1 {
font-size: 2.5rem;
margin-bottom: 0.5rem;
}
section {
margin-bottom: 3rem;
}
h2 {
color: var(--primary-color);
border-bottom: 2px solid var(--secondary-color);
padding-bottom: 0.5rem;
margin-bottom: 1.5rem;
display: inline-block;
}
/* Tip Section */
#tip-section {
background-color: var(--card-bg);
padding: 1.5rem;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
border-left: 5px solid var(--accent-color);
}
#new-tip-btn {
background-color: var(--secondary-color);
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
margin-top: 1rem;
transition: background 0.3s;
}
#new-tip-btn:hover {
background-color: #2980b9;
}
/* Filter Controls */
.filter-controls {
margin-bottom: 1.5rem;
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.filter-btn {
background: transparent;
border: 2px solid var(--secondary-color);
color: var(--secondary-color);
padding: 6px 12px;
border-radius: 20px;
cursor: pointer;
font-weight: bold;
transition: all 0.3s;
}
.filter-btn:hover, .filter-btn.active {
background-color: var(--secondary-color);
color: white;
}
/* Resource Grid */
.resource-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px;
}
.card {
background-color: var(--card-bg);
padding: 1.5rem;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
transition: transform 0.2s;
display: flex;
flex-direction: column;
}
.card:hover {
transform: translateY(-5px);
}
.card h3 {
margin-bottom: 0.5rem;
color: var(--primary-color);
}
.card p {
flex-grow: 1;
margin-bottom: 1rem;
color: #666;
}
.card a {
display: inline-block;
text-decoration: none;
color: var(--secondary-color);
font-weight: bold;
}
.card a:hover {
text-decoration: underline;
}
footer {
text-align: center;
padding: 2rem 0;
margin-top: 2rem;
color: #777;
border-top: 1px solid #ddd;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
@media (max-width: 600px) {
header h1 {
font-size: 2rem;
}
.resource-grid {
grid-template-columns: 1fr;
}
}
/* Learning Paths */
.paths-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
.path-card {
background-color: #e8f4f8;
padding: 1.5rem;
border-radius: 8px;
border-left: 4px solid var(--secondary-color);
}
.path-card h3 {
color: var(--primary-color);
margin-bottom: 0.5rem;
}

2
games/flashpoint.js Normal file
View File

@ -0,0 +1,2 @@
let searchURL = function(query) {return `https://db-api.unstable.life/search?filter=true&fields=id,title,developer,publisher,platform,library,tags,originalDescription,dateAdded,dateModified&smartSearch=${query}`}
let imagesURL = function(uuid) {return `https://infinity.unstable.life/images/Logos/c2/af/${uuid}.png?type=jpg`}

13
games/osu.js Normal file
View File

@ -0,0 +1,13 @@
async function minoProxy(req, res) {
let baseurl = ((req.url.startsWith("/api") && !req.url.startsWith("/api/v2")) || req.url.includes(".ttf") || req.url.startsWith("/skin/")) ? "https://webosumania.com" : "https://catboy.best"
let data = await fetch(baseurl + req.url);
res.status(data.status);
res.setHeader("Content-Type", data.headers.get("content-type"));
for await (const chunk of data.body) {
res.write(chunk)
}
res.end();
}
export { minoProxy };

View File

@ -5,60 +5,46 @@
https://coolors.co/10002b-240046-3c096c-5a189a-7b2cbf-9d4edd-c77dff-e0aaff -->
<!-- initialize externals -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
<script src=" https://cdn.jsdelivr.net/npm/js-cookie@3.0.5/dist/js.cookie.min.js "></script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "Selenite",
"alternateName": "selenite.cc",
"url": "https://selenite.cc",
"logo": "https://selenite.cc/favicon.png",
"sameAs": [
"https://github.com/selenite-cc",
"https://youtube.com/@selenitecc",
"https://tiktok.com/@selenitecc",
"https://selenite.cc",
]
}
</script>
<!-- initialize my stuff -->
<script src="/js/all.min.js"></script>
<script src="/js/all.js"></script>
<script src="/js/main.js"></script>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.1.6/purify.min.js" integrity="sha512-jB0TkTBeQC9ZSkBqDhdmfTv1qdfbWpGE72yJ/01Srq6hEzZIz2xkz1e57p9ai7IeHMwEG7HpzG6NdptChif5Pg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="/style.css" />
<link rel="stylesheet" href="/css/main.css" />
<link rel="stylesheet" href="/css/pages.css" />
<link rel="manifest" href="/manifest.json" />
<!-- seo + other things -->
<title>AI | Selenite</title>
<title>Selenite</title>
<link rel="icon" href="/favicon.ico" />
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3415518411898563" crossorigin="anonymous"></script>
<script>
function sendMessage() {
let message = prompt("message");
fetch("/api/ai/send")
}
</script>
</head>
<alerts> </alerts>
<body id="noscroll">
<header>
<a href="/index.html">Home</a>
<a href="/bookmarklets.html">Bookmarklets</a>
<a href="/projects.html">Games</a>
<a href="/apps.html">Apps</a>
<a href="/settings.html">Settings</a>
<a id="blank" href="#">Open Blank</a>
<a href="/u/" class="usericon"><img src="/img/user.svg" /></a>
</header>
<script></script>
<main>
<h1>AI Chat Bot</h1>
<p>Powered by <a href="https://groq.com">Groq</a>.</p>
<p class="evensmaller">Messages are logged for quality assurance. Don't type any personal information.</p>
<select id="models">
<option>Select a model:</option>
<option value="average">Average (Recommended)</option>
<option value="dumb">Dumb (but fast)</option>
<option value="genius">Genius (but slow)</option>
</select>
<div id="chat">
<div id="messages">
</div>
<div class="messagebox">
<input type="text" placeholder="Send a message..." id="chatbox" />
</div>
</div>
</main>
<footer class="noscroll">
<a href="https://gitlab.com/skysthelimit.dev/selenite">Source</a>
<a href="https://discord.gg/7jyufnwJNf">Discord</a>
<a href="/suggest.html">Suggestions & Bugs</a>
<a href="/contact.html">Contact</a>
<a href="/support.html">Donate</a>
<a href="/about.html">About</a>
</footer>
<body>
<h1 class="title">ai</h1>
<button onclick="sendMessage()">send message</button>
<h1 id="response"></h1>
</body>
</html>

View File

@ -7,7 +7,7 @@
<!-- initialize externals -->
<!-- initialize my stuff -->
<script src="/js/all.min.js"></script>
<script src="/js/all.min.js" async></script>
<script src="/js/main.js"></script>
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
@ -41,11 +41,11 @@
})
).json();
if (data.success == true) {
console.log("Token: ", data.token);
// console.log("Token: ", data.token);
document.cookie = `token=${data.token}; expires=${new Date(new Date().setMonth(new Date().getMonth() + 6)).toUTCString()}; path=/;`;
location.href = "/u/";
} else {
console.log("Error: ", data.reason);
// console.log("Error: ", data.reason);
document.getElementById("title").innerText = "Failed to login";
document.getElementById("reason").innerText = data.reason;
document.getElementById("popup").style.display = "flex";

View File

@ -24,7 +24,7 @@
</script>
<!-- initialize my stuff -->
<script src="/js/all.min.js"></script>
<script src="/js/all.min.js" async></script>
<script src="/js/main.js"></script>
<link rel="stylesheet" href="/css/main.css" />

View File

@ -13,7 +13,7 @@
<!-- initialize my stuff -->
<script src="/js/all.min.js"></script>
<script src="/js/all.min.js" async></script>
<script src="/js/main.js"></script>
<script src="/js/widget.js"></script>
<script src="/js/themes.js"></script>

View File

@ -13,7 +13,7 @@
<script src=" https://cdn.jsdelivr.net/npm/js-cookie@3.0.5/dist/js.cookie.min.js "></script>
<!-- initialize my stuff -->
<script src="/js/all.min.js"></script>
<script src="/js/all.min.js" async></script>
<script src="/js/main.js"></script>
<link rel="stylesheet" href="/style.css" />

View File

@ -24,7 +24,7 @@
</script>
<!-- initialize my stuff -->
<script src="/js/all.min.js"></script>
<script src="/js/all.min.js" async></script>
<script src="/js/main.js"></script>
<link rel="stylesheet" href="/css/main.css" />

View File

@ -9,7 +9,7 @@
<script src=" https://cdn.jsdelivr.net/npm/js-cookie@3.0.5/dist/js.cookie.min.js "></script>
<!-- initialize my stuff -->
<script src="/js/all.min.js"></script>
<script src="/js/all.min.js" async></script>
<script src="/js/main.js"></script>
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>

View File

@ -7,7 +7,7 @@
<!-- initialize externals -->
<!-- initialize my stuff -->
<script src="/js/all.min.js"></script>
<script src="/js/all.min.js" async></script>
<script src="/js/main.js"></script>
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>

View File

@ -24,7 +24,7 @@
</script>
<!-- initialize my stuff -->
<script src="/js/all.min.js"></script>
<script src="/js/all.min.js" async></script>
<script src="/js/main.js"></script>
<!-- <script src="/js/widget.js"></script> -->
<script>
@ -115,9 +115,9 @@
<link rel="icon" href="/favicon.ico" />
</head>
<alerts> </alerts>
<body>
<h1 class="title">users</h1>
<input type="text" id="search" placeholder="click enter to search..." style="width: 30%">
<div id="users"></div>
<div id="pages"></div>
</body>

View File

@ -9,7 +9,7 @@
<script src=" https://cdn.jsdelivr.net/npm/js-cookie@3.0.5/dist/js.cookie.min.js "></script>
<!-- initialize my stuff -->
<script src="/js/all.min.js"></script>
<script src="/js/all.min.js" async></script>
<script src="/js/main.js"></script>
<script src="/js/widget.js"></script>
<script src="/js/themes.js"></script>

View File

@ -8,9 +8,10 @@ import path, { dirname } from "node:path";
import mime from "mime-types";
import compression from "compression";
// import { accs, infdb, polytrack } from "./database.js";
import { accs } from "./database.js";
import { accs, top } from "./database.js";
import { } from "./accounts/friend.js";
import { findClientID, search, download } from "./accounts/music.js";
import { minoProxy } from "./games/osu.js";
import { banUser, removeAccount, verifyCookie, getUserFromCookie, createAccount, resetPassword, loginAccount, addBadge } from "./accounts/manage.js";
import { } from "./accounts/misc.js";
import { getRawData, generateAccountPage, editProfile, saveData, getUsers, isAdmin, retrieveData } from "./accounts/profile.js";
@ -21,18 +22,6 @@ import chokidar from 'chokidar';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
let recatters = JSON.parse(await fs.readFile("./data/recats.json"));
const watcher = chokidar.watch('./data/recats.json', {
persistent: true,
awaitWriteFinish: {
stabilityThreshold: 500,
pollInterval: 100
}
});
watcher.on('change', async (event, filePath) => {
recatters = JSON.parse(await fs.readFile("./data/recats.json"));
});
await findClientID();
setInterval(async () => {
await findClientID();
@ -42,14 +31,6 @@ const port = process.env.PORT || 3000;
const app = express();
let recatFolder = express.static("./edu", { extensions: ["html"] });
app.use((req, res, next) => {
if(recatters.includes(req.hostname)) {
return recatFolder(req, res, next);
}
next();
});
// why the fuck does this have to exist?
app.use("/resources/semag/hotline-miami/", (req,res,next) => {
if(req.method == "HEAD") {
@ -57,6 +38,9 @@ app.use("/resources/semag/hotline-miami/", (req,res,next) => {
}
next();
});
app.use("/osu/", await minoProxy)
app.use("/resources/semag/portal/", (req,res,next) => {
res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
@ -193,6 +177,22 @@ app.post("/api/account/upload", async (req, res, next) => {
}
});
app.post("/api/analytics/game", async (req, res) => {
if(req.body && req.body.path.length < 16) {
const query = top.prepare(`
INSERT INTO stats (game, plays)
VALUES ($id, 1)
ON CONFLICT(game) DO UPDATE SET plays = plays + 1
RETURNING *
`);
query.get({ $id: req.body.path });
res.send(200);
return;
}
res.send(400);
return;
})
app.post("/api/ai/sendMessage", async (req, res) => {
// take in chat id and message
// stream back reply
@ -284,7 +284,7 @@ app.use("/api/account/load", async (req, res, next) => {
});
app.use("/api/getUsers", async (req, res, next) => {
console.log(req.query)
// console.log(req.query)
let status = await getUsers(req.query.page, req.query.query);
res.status(200).send(status);
});

81
package-lock.json generated
View File

@ -637,23 +637,27 @@
}
},
"node_modules/body-parser": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
"integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz",
"integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==",
"license": "MIT",
"dependencies": {
"bytes": "^3.1.2",
"content-type": "^1.0.5",
"debug": "^4.4.0",
"debug": "^4.4.3",
"http-errors": "^2.0.0",
"iconv-lite": "^0.6.3",
"iconv-lite": "^0.7.0",
"on-finished": "^2.4.1",
"qs": "^6.14.0",
"raw-body": "^3.0.0",
"type-is": "^2.0.0"
"qs": "^6.14.1",
"raw-body": "^3.0.1",
"type-is": "^2.0.1"
},
"engines": {
"node": ">=18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/body-parser/node_modules/debug": {
@ -1477,31 +1481,39 @@
}
},
"node_modules/http-errors": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
"integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
"license": "MIT",
"dependencies": {
"depd": "2.0.0",
"inherits": "2.0.4",
"setprototypeof": "1.2.0",
"statuses": "2.0.1",
"toidentifier": "1.0.1"
"depd": "~2.0.0",
"inherits": "~2.0.4",
"setprototypeof": "~1.2.0",
"statuses": "~2.0.2",
"toidentifier": "~1.0.1"
},
"engines": {
"node": ">= 0.8"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
"integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">=0.10.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/ieee754": {
@ -1881,9 +1893,9 @@
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"node_modules/qs": {
"version": "6.14.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
"integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
"version": "6.14.1",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz",
"integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==",
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.1.0"
@ -1914,18 +1926,18 @@
}
},
"node_modules/raw-body": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
"integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz",
"integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==",
"license": "MIT",
"dependencies": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
"iconv-lite": "0.6.3",
"unpipe": "1.0.0"
"bytes": "~3.1.2",
"http-errors": "~2.0.1",
"iconv-lite": "~0.7.0",
"unpipe": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
"node": ">= 0.10"
}
},
"node_modules/readdirp": {
@ -2007,7 +2019,8 @@
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"license": "MIT"
},
"node_modules/sanitize-html": {
"version": "2.17.0",
@ -2250,9 +2263,9 @@
}
},
"node_modules/statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
"license": "MIT",
"engines": {
"node": ">= 0.8"