Merge pull request 'templated' (#1) from templated into main

Reviewed-on: #1
This commit is contained in:
Alfie King 2025-06-20 08:50:41 +00:00
commit 0115328180
22 changed files with 720 additions and 217 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
.venv
.env
db.sqlite
flask_session

BIN
db.sqlite Normal file

Binary file not shown.

25
dockerfile Normal file
View File

@ -0,0 +1,25 @@
FROM python:alpine
# Set the working directory
WORKDIR /app
# Copy the requirements file into the container
COPY requirements.txt .
# Install the required packages
RUN pip install --no-cache-dir -r requirements.txt
RUN pip install gunicorn
# Copy the rest of the application code into the container
COPY src src
COPY templates templates
COPY static static
# Expose the port the app runs on
EXPOSE 5000
# Set environment variables
ENV FLASK_APP=main.py
# run the application
ENTRYPOINT [ "gunicorn", "-b", ":5000", "--access-logfile", "-", "--error-logfile", "-", "src.main:app" ]

Binary file not shown.

View File

@ -1,201 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Alfie's basement</title>
<link rel="icon" href="/static/content/icon.webp">
<link rel="stylesheet" href="/static/css/index.css">
<meta name="description" content="Alfie's basement">
<meta name="keywords" content="Alfie King, Alfie, King, Alfieking, Alfieking.dev, dev, server">
<meta name="author" content="Alfie King">
<meta name="robots" content="all">
<meta name="theme-color" content="#63de90" data-react-helmet="true">
<meta property="og:site_name" content="Alfieking.dev">
<meta property="og:url" content="https://alfieking.dev">
<meta property="og:title" content="Alfie's basement">
<meta property="og:description" content="server backend survivor">
<meta property="og:image" content="static/content/icon.webp">
</head>
<body>
<div id="furry"></div>
<div id="sidebar">
<nav>
<section>
<h1>Things to see :3</h1>
<ul>
<li><a href="#Home" onclick="alert('ur already here :3')">Home</a></li>
<li><a href="https://git.alfieking.dev/acetheking987">Gitea</a></li>
<li><a href="https://www.last.fm/user/acetheking987">LastFm</a></li>
<li><a href="https://prismic.alfieking.dev">Prismic</a></li>
<li><a href="https://open.spotify.com/user/xz02oolstlvwxqu1pfcua9exz?si=14396e637f284e03">Spotify</a></li>
<li><a href="https://steamcommunity.com/id/acetheking987/">Steam</a></li>
<li><a href="https://www.youtube.com/@acetheking987">YouTube</a></li>
<li><a href="https://acetheking987.tumblr.com/">Tumblr</a></li>
<li><a href="https://www.reddit.com/user/acetheking987">Reddit</a></li>
</ul>
</section>
</nav>
<section>
<h6 class="irken">heya, try typing "furry" and "irken" into this page!</h6>
</section>
<section id="buttons">
<h1>BUTTONS</h1>
<ul>
<li><a href="https://dimden.dev/"><img src="https://dimden.dev/services/images/88x31.gif" alt="dimden"></a></li>
<li><a href="https://ne0nbandit.neocities.org/"><img src="https://ne0nbandit.github.io/assets/img/btn/mine/nbbanner.png" alt="ne0nbandit"></a></li>
<li><a href="https://thinliquid.dev"><img src="https://thinliquid.dev/thnlqd.png" alt="thinliquid"></a></li>
<li><a href="https://nekoweb.org/"><img src="https://nekoweb.org/assets/buttons/button6.gif" alt="nekoweb"></a><!-- button by s1nez.nekoweb.org --></li>
<li><a href="https://s1nez.nekoweb.org/"><img src="https://s1nez.nekoweb.org/BUTTON.gif" alt="s1nez"></a></li>
<li><a href="https://beeps.website"><img src="https://beeps.website/assets/images/88x31-d.gif" alt="beeps"></a></li>
<li><a href="https://itsnotstupid.com"><img src="https://itsnotstupid.com/pics/button1.gif" alt="itsnotstupid"></a></li>
<li><a href='https://blinkies.cafe'><img src='https://blinkies.cafe/b/display/blinkiesCafe-badge.gif' alt='blinkies.cafe | make your own blinkies!'></a></li>
<li><a href="https://eightyeightthirty.one"><img src="https://eightyeightthirty.one/88x31.png" alt="88x31"></a></li>
<li><a href="https://neocities.org"><img src="https://cyber.dabamos.de/88x31/neocities-now.gif" alt="neocities"></a></li>
<li><a href="https://tuxedodragon.art"><img src="https://tuxedodragon.art/tuxedodragon%2088x31.gif" alt="tuxedodragon"></a></li>
</ul>
</section>
<section>
<pre class="vsmoltext"> |\ _,,,---,,_<br>ZZZzz /,`.-'`' -. ;-;;,_<br> |,4- ) )-,_. ,\ ( `'-'<br> '---''(_/--' `-'\_)</pre>
</section>
<img src="static/content/haj.gif" alt="haj" class="haj">
</div>
<main id="main">
<header id="home">
<div class="row">
<img src="/static/content/icon.webp">
<div>
<h1>Alfie King</h1>
<h2 id="typing">server backend survivor</h2>
</div>
</div>
</header>
<nav id="alt-nav">
<ul>
<li><a href="https://git.alfieking.dev/acetheking987">Gitea</a></li>
<li><a href="https://www.last.fm/user/acetheking987">LastFm</a></li>
<li><a href="https://prismic.alfieking.dev">Prismic</a></li>
<li><a href="https://open.spotify.com/user/xz02oolstlvwxqu1pfcua9exz?si=14396e637f284e03">Spotify</a></li>
<li><a href="https://steamcommunity.com/id/acetheking987/">Steam</a></li>
<li><a href="https://www.youtube.com/@acetheking987">YouTube</a></li>
<li><a href="https://acetheking987.tumblr.com/">Tumblr</a></li>
<li><a href="https://www.reddit.com/user/acetheking987">Reddit</a></li>
</ul>
</nav>
<section>
<h1>A lil bit abt me</h1>
<p>
Im not good with writing so dont expect much here. I am a student who is learning c++ and python. I've Done a few projects that i think
are decent enough to show off, so I have put them on this website. I like to mess around with linux and have a few servers that I run. I've
been running a server for a few years now, and I have learned a lot from it. I have also switched to linux on my main computer, which has been
slightly annoying at times (mainly because one of my most played games' anticheat doesn't support on linux atm. Also, the lack of photoshop is
a pain).
<br><br>
I would like to make some more projects in the future, but I am not sure what I want to make yet. I tend to make thing on impulse a lot, and motivation
is "lacking" at times. So the few ideas I do have may never come to fruition. I hope to get better at art so i could hopefully make a game that is somewhat
interesting. But im at a lack of ideas at the moment.
<br><br>
I would also like to have a functional blog on this site, but I bearly talk about much so I dont know what I would write about. I like to ramble on about
random things, but I dont think that would be very interesting to read, and I think that I would forget to update it. I have a tumblr that I have had for a few
years now, but I dont post on it (the social anxiety is too much for me :<). However I hope to get better at that in the future.
</p>
</section>
<section class="blinkies">
<img src="https://adriansblinkiecollection.neocities.org/x45.gif" alt="">
<img src="https://adriansblinkiecollection.neocities.org/t3.gif" alt="">
<img src="https://adriansblinkiecollection.neocities.org/k25.gif" alt="">
<img src="https://s1nez.nekoweb.org/img/52475686_BP77MK3UdnLmIQk.gif" alt="">
<img src="https://s1nez.nekoweb.org/img/hc/hc%20(79).gif" alt="">
<img src="https://dewside.neocities.org/blinkies/bisigns.gif" alt="">
<img src="https://s1nez.nekoweb.org/g/ggg/gg%20(32).gif" alt="">
<img src="https://s1nez.nekoweb.org/img/7dcd20d4.gif" alt="">
</section>
<section class="rowsect">
<a href="" id="spotify-link">
<div id="spotify">
<h1 id="spotify-title"></h1>
<h2 id="spotify-artist"></h2>
</div>
</a>
<div class="stamps">
<img src="https://s1nez.nekoweb.org/img/other/ba4ba47a.png" alt="">
<img src="https://s1nez.nekoweb.org/img/fa02abd7.png" alt="">
<img src="https://s1nez.nekoweb.org/img/hc/hc%20(172).gif" alt="">
<img src="https://gligar.neocities.org/furret2.png" alt="">
<img src="https://gligar.neocities.org/ralsei2.png" alt="">
<img src="https://gligar.neocities.org/tism.png" alt="">
<img src="https://64.media.tumblr.com/11957593416710af9ff049ff6ae7ab63/tumblr_pbb7cd42Ln1xz2nuuo4_100.gif" alt="">
<img src="https://dewside.neocities.org/stamps/dogofwisdom.gif" alt="">
<img src="https://dewside.neocities.org/stamps/kazookid.gif" alt="">
<img src="https://64.media.tumblr.com/3085aeace24ca0c5ddf08aac37cc3ab4/45a30eb92e06a85c-3a/s100x200/b7bfb2e91adbc310f712f4492e668298bd0779de.gif" alt="">
<img src="https://s1nez.nekoweb.org/img/hc/hc%20(27).png" alt="">
<img src="https://s1nez.nekoweb.org/g/ggg/gg%20(13).gif" alt="">
<img src="https://kopawz.neocities.org/stamphoard/stamps2/kriswhere.png" alt="">
<img src="https://adriansblinkiecollection.neocities.org/stamps/g5.gif" alt="">
<img src="https://adriansblinkiecollection.neocities.org/stamps/e40.gif" alt="">
<img src="https://adriansblinkiecollection.neocities.org/stamps/e43.gif" alt="">
</div>
</section>
<section>
<h1>Projects & stuff</h1>
<p>just some projects ive worked on over time</p>
<ul>
<li>
<h2>alfieking.dev</h2>
<p>
This website is a project that I have been working on for a while now. I have made a few versions of it, but I have
never been happy with them. I am quite happy with this version atm since it is more organized and has a design that I
like.
<a href="https://git.alfieking.dev/acetheking987/alfieking.dev">source code</a>
</p>
</li>
<li>
<h2>owo (the terminal command)</h2>
<p>
I made this project as a joke, I can't remember exactly what I baised it off other than the fact that it was somthing
similar to this but in a different language. I originally made it in python, but I have since rewritten it in c++ so
that it would be faster and so that I could learn c++.
<a href="https://git.alfieking.dev/acetheking987/term-owo-cpp">source code</a>
</p>
</li>
<li>
<h2>prismic</h2>
<p>
Prismic is a basic message board that I made, it was mainly made to learn how to use templating and more backend
web development. it uses flask for the web framework and uses a sqlite database to store the messages. I have thought
about remaking it in c++ since I found a c++ web framework that I would like to try out.
<a href="https://prismic.alfieking.dev">Primic</a> | <a href="https://git.alfieking.dev/acetheking987/prismic">source code</a>
</p>
</li>
</ul>
</section>
<section>
<h1>The button collection™</h1>
<div id="button-collection">
</div>
</section>
<section>
<h1>Some News</h1>
<h6>(dont expect this to be updated often tho :P)</h6>
<ul>
<li>
<h2>18-06-2025</h2>
<p>
I plan on updating the site soon, I have a few ideas that I want to implement. I want to make it more
interactive and fun to use. I also want to add a blog section so that I can write about random things that I find interesting. I also
want to add a few more projects that I have been working on. Annoyingly I think it would be a good idea to remake this site with some sort of
framework so i can use templating, however this kinda bothers me since I like the simplicity of this site. And prefer to keep it as a static site
that i can just throw at nginx.
</p>
</li>
</ul>
</section>
<section>
<footer>
<p>legal stuff idk :3 | icba to &copy; this :P | made with &hearts; and caffine</p>
</footer>
</section>
</main>
<script src="/static/js/index.js"></script>
</body>
</html>

4
requirements.txt Normal file
View File

@ -0,0 +1,4 @@
python-dotenv
flask-session
requests
flask

Binary file not shown.

42
src/database.py Normal file
View File

@ -0,0 +1,42 @@
import sqlite3
class Database:
def __init__(self, db_name='db.sqlite'):
self.connection = sqlite3.connect(db_name, check_same_thread=False)
self.cursor = self.connection.cursor()
self.create_snake_table()
def create_snake_table(self):
self.cursor.execute('''
CREATE TABLE IF NOT EXISTS snake (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
score INTEGER NOT NULL
)
''')
self.connection.commit()
def insert_snake(self, name, score):
old_score = self.get_snake_score(name)
print(f"Old score for {name}: {old_score}")
print(f"New score for {name}: {score}")
if old_score is not None and score <= old_score:
return
self.cursor.execute('''
INSERT INTO snake (name, score)
VALUES (?, ?)
''', (name, score))
self.connection.commit()
def get_snake_score(self, name):
self.cursor.execute('SELECT score FROM snake WHERE name = ? ORDER BY score DESC LIMIT 1', (name,))
result = self.cursor.fetchone()
return result[0] if result else None
def get_snake_scores(self):
self.cursor.execute('SELECT * FROM snake ORDER BY score DESC')
return self.cursor.fetchall()
def close(self):
self.connection.close()

110
src/main.py Normal file
View File

@ -0,0 +1,110 @@
from flask import Flask, request, render_template, send_from_directory
from flask_session import Session
from dotenv import load_dotenv
from os import getenv as env
import logging, requests
try:
import src.database as database
except ImportError:
import database
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
load_dotenv()
app = Flask(
__name__,
template_folder=env('TEMPLATE_FOLDER', default='../templates'),
static_folder=env('STATIC_FOLDER', default='../static'),
static_url_path=env('STATIC_URL_PATH', default='/static')
)
app.config["SESSION_PERMANENT"] = True
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
db = database.Database(db_name=env('DB_NAME', default='db.sqlite'))
@app.route('/')
def index():
logging.info("Rendering index page")
return render_template('index.html')
@app.route('/robots.txt')
@app.route('/sitemap.xml')
@app.route('/favicon.ico')
def web_stuffs():
return send_from_directory(
app.static_folder,
request.path[1:],
)
@app.route('/404')
@app.errorhandler(404)
def not_found():
unformatted_scores = db.get_snake_scores()
scores = [{'position': i + 1, 'name': score[1], 'score': score[2]} for i, score in enumerate(unformatted_scores)]
return render_template('404.html', scores=scores)
@app.route('/404/submit', methods=['POST'])
def snake_submit():
unformatted_scores = db.get_snake_scores()
scores = [{'position': i + 1, 'name': score[1], 'score': score[2]} for i, score in enumerate(unformatted_scores)]
data = request.form
username = data.get('username', '').strip()
score = data.get('snake-score', '').strip()
token = data.get('cap-token', '').strip()
if not username or not score or not token:
logging.error("Missing required fields: username=%s, score=%s, token=%s", username, score, token)
return render_template('404.html', scores=scores, error='Missing required fields'), 400
try:
score = int(score)
except ValueError:
logging.error("Invalid score value: %s", score)
return render_template('404.html', scores=scores, error='Invalid score value'), 400
if score <= 0 or score > 10000 or len(username) < 3 or len(username) > 20:
logging.error("Invalid score or username length: score=%s, username=%s", score, username)
return render_template('404.html', scores=scores, error='Invalid score or username length'), 400
cap_response = requests.post(
env('CAP_VERIFY_URL', default='https://<instance_url>/<key_id>/siteverify'),
json={
'secret': env('CAP_SECRET', default=''),
'response': token,
}
)
if cap_response.status_code != 200 or not cap_response.json().get('success', "false") != "true":
logging.error("Captcha verification failed: %s", cap_response.json())
return render_template('404.html', scores=scores, error='Captcha verification failed'), 400
db.insert_snake(name=username, score=int(score))
logging.info("Snake submitted: name=%s, score=%d", username, score)
unformatted_scores = db.get_snake_scores()
scores = [{'position': i + 1, 'name': score[1], 'score': score[2]} for i, score in enumerate(unformatted_scores)]
return render_template('404.html', scores=scores, success='Score submitted successfully!')
@app.route('/500')
@app.errorhandler(500)
def internal_error(error="An internal server error occurred."):
logging.error("Internal server error: %s", error)
return render_template('500.html'), 500
if __name__ == '__main__':
app.run(
host=env('HOST', default='0.0.0.0'),
port=env('PORT', default=5000),
debug=env('DEBUG', default=False).lower() == 'true'
)

113
static/css/404.css Normal file
View File

@ -0,0 +1,113 @@
canvas#snakeCanvas {
margin: 15px;
box-sizing: border-box;
border: 2px solid var(--secondary-background-color);
border-radius: 10px;
}
form {
display: flex;
flex-direction: column;
width: min-content;
gap: 1rem;
padding: 15px;
}
form input[type="text"] {
padding: 10px;
box-sizing: border-box;
border: 1px solid var(--secondary-background-color);
border-radius: 6px;
background-color: var(--secondary-background-color-but-slightly-transparent);
color: var(--text-color);
}
form button[type="submit"] {
padding: 10px;
box-sizing: border-box;
border: 1px solid var(--secondary-background-color);
border-radius: 6px;
background-color: var(--secondary-background-color-but-slightly-transparent);
color: var(--text-color);
font-weight: bold;
cursor: pointer;
}
.flex-row {
display: flex;
flex-direction: row;
gap: 1rem;
}
.min-width {
width: min-content;
}
.max-width {
width: 100%;
}
#snakeLeaderboardSection {
display: flex;
flex-direction: column;
align-items: center;
padding: 0;
max-height: 272px ;
}
#snakeLeaderboard {
display: flex;
flex-direction: column;
list-style: none;
padding: 0;
margin: 0;
width: 100%;
overflow-y: scroll;
}
#snakeLeaderboard li {
padding: 5px 20px;
background-color: var(--secondary-background-color-but-slightly-transparent);
color: var(--text-color);
font-size: 1rem;
display: flex;
justify-content: space-between;
align-items: center;
}
#snakeLeaderboard li:nth-child(even) {
background-color: var(--secondary-background-color);
}
dialog {
width: 90%;
max-width: 500px;
padding: 20px;
background-color: var(--background-color);
color: var(--text-color);
border: 2px solid var(--secondary-background-color);
border-radius: 8px;
}
dialog button {
padding: 10px;
width: 100%;
box-sizing: border-box;
border: 2px solid var(--secondary-background-color);
border-radius: 6px;
background-color: var(--secondary-background-color-but-slightly-transparent);
color: var(--text-color);
font-weight: bold;
cursor: pointer;
margin-top: 10px;
}
dialog h2 {
margin: 0;
font-size: 1.5rem;
}
dialog p {
margin: 0;
font-size: 1rem;
}

8
static/css/500.css Normal file
View File

@ -0,0 +1,8 @@
.bluescreen {
background-color: #0077D6;
color: #fff;
padding:40px;
display: flex;
flex-direction: column;
gap: 20px;
}

21
static/css/cap.css Normal file
View File

@ -0,0 +1,21 @@
cap-widget {
--cap-background: var(--secondary-background-color-but-slightly-transparent);
--cap-border-color: var(--secondary-background-color);
--cap-border-radius: 14px;
--cap-widget-height: 30px;
--cap-widget-width: 230px;
--cap-widget-padding: 14px;
--cap-gap: 15px;
--cap-color: var(--text-color);
--cap-checkbox-size: 25px;
--cap-checkbox-border: 1px solid var(--secondary-background-color);
--cap-checkbox-border-radius: 6px;
--cap-checkbox-background: none;
--cap-checkbox-margin: 2px;
--cap-font: "Space Mono", "serif";
--cap-spinner-color: var(--primary-color);
--cap-spinner-background-color: var(--secondary-background-color-but-slightly-transparent);
--cap-spinner-thickness: 5px;
--cap-credits-font-size: 12px;
--cap-opacity-hover: 0.8;
}

BIN
static/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

View File

@ -1,5 +1,3 @@
// TYPERWRITER
const values = [
"Web developer",
"Pc games enjoyer",

174
static/js/snake.js Normal file
View File

@ -0,0 +1,174 @@
const canvas = document.getElementById('snakeCanvas');
const ctx = canvas.getContext('2d');
const gridSize = 20;
const tileSize = 100;
const snakeSize = 60;
const foodSize = 80;
canvas.width = gridSize * tileSize;
canvas.height = gridSize * tileSize;
let snake = [{ x: 10, y: 10 }, { x: 10, y: 11 }, { x: 10, y: 12 }];
let direction = { x: 0, y: 0 };
let food = { x: Math.floor(Math.random() * gridSize), y: Math.floor(Math.random() * gridSize) };
let score = 0;
let gameOver = false;
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// draw grid of checkerboard pattern
for (let x = 0; x < gridSize; x++) {
for (let y = 0; y < gridSize; y++) {
ctx.fillStyle = (x + y) % 2 === 0 ?
getComputedStyle(document.documentElement).getPropertyValue('--background-color') :
getComputedStyle(document.documentElement).getPropertyValue('--secondary-background-color');
ctx.fillRect(x * tileSize, y * tileSize, tileSize, tileSize);
}
}
// Draw snake
snake.forEach(segment => {
let nextVec = { x: 0, y: 0 };
// if there is a segment after the current segment
if (snake.indexOf(segment) < snake.length - 1) {
const nextSegment = snake[snake.indexOf(segment) + 1];
nextVec.x = nextSegment.x - segment.x;
nextVec.y = nextSegment.y - segment.y;
}
ctx.fillStyle = getComputedStyle(document.documentElement).getPropertyValue('--primary-color');
if (nextVec.x === 0 && nextVec.y === 0) {
ctx.fillRect(
segment.x * tileSize + (tileSize - snakeSize) / 2,
segment.y * tileSize + (tileSize - snakeSize) / 2,
snakeSize,
snakeSize
);
} else if (nextVec.x > 0 || nextVec.y > 0) {
ctx.fillRect(
segment.x * tileSize + (tileSize - snakeSize) / 2,
segment.y * tileSize + (tileSize - snakeSize) / 2,
snakeSize + nextVec.x * (tileSize - snakeSize),
snakeSize + nextVec.y * (tileSize - snakeSize)
);
} else {
ctx.fillRect(
segment.x * tileSize + (tileSize - snakeSize) / 2 + nextVec.x * (tileSize - snakeSize),
segment.y * tileSize + (tileSize - snakeSize) / 2 + nextVec.y * (tileSize - snakeSize),
snakeSize + Math.abs(nextVec.x) * (tileSize - snakeSize),
snakeSize + Math.abs(nextVec.y) * (tileSize - snakeSize)
);
}
});
// Draw food
ctx.fillStyle = '#ff4d4d';
ctx.fillRect(
food.x * tileSize + (tileSize - foodSize) / 2,
food.y * tileSize + (tileSize - foodSize) / 2,
foodSize,
foodSize
);
}
function update() {
if (gameOver) return;
// Move snake
const head = { x: snake[0].x + direction.x, y: snake[0].y + direction.y };
// Add new head
snake.unshift(head);
// Check for food collision
if (head.x === food.x && head.y === food.y) {
score += 10; // Increase score
placeFood();
} else {
snake.pop(); // Remove tail if no food eaten
}
// Check for wall collision
if (head.x < 0 || head.x >= gridSize || head.y < 0 || head.y >= gridSize) {
gameOver = true;
return;
}
// Check for self collision
for (let i = 1; i < snake.length; i++) {
if (head.x === snake[i].x && head.y === snake[i].y) {
gameOver = true;
return;
}
}
}
function placeFood() {
do {
food.x = Math.floor(Math.random() * gridSize);
food.y = Math.floor(Math.random() * gridSize);
} while (snake.some(segment => segment.x === food.x && segment.y === food.y));
}
function changeDirection(event) {
switch (event.key) {
case 'w':
if (direction.y === 0) direction = { x: 0, y: -1 };
break;
case 's':
if (direction.y === 0) direction = { x: 0, y: 1 };
break;
case 'a':
if (direction.x === 0) direction = { x: -1, y: 0 };
break;
case 'd':
if (direction.x === 0) direction = { x: 1, y: 0 };
break;
}
}
// Menu to start the game
function menu() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = getComputedStyle(document.documentElement).getPropertyValue('--background-color');
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.textAlign = 'center';
ctx.fillStyle = getComputedStyle(document.documentElement).getPropertyValue('--text-color');
ctx.font = '200px Arial';
ctx.fillText('Snake Game', canvas.width / 2, canvas.height / 2);
ctx.font = '100px Arial';
ctx.fillText('Press W/A/S/D to move', canvas.width / 2, canvas.height / 2 + 100);
ctx.fillText('Click to start', canvas.width / 2, canvas.height / 2 + 200);
canvas.addEventListener('click', startGame);
}
function gameLoop() {
if (!gameOver) {
update();
draw();
setTimeout(gameLoop, 100);
} else {
document.removeEventListener('keydown', changeDirection);
document.getElementById('snake-score').value = score;
alert(`Game Over! Your score: ${score}`);
menu();
}
}
function startGame() {
snake = [{ x: 10, y: 10 }, { x: 10, y: 11 }, { x: 10, y: 12 }];
direction = { x: 1, y: 0 };
food = { x: Math.floor(Math.random() * gridSize), y: Math.floor(Math.random() * gridSize) };
score = 0;
gameOver = false;
canvas.removeEventListener('click', startGame);
document.addEventListener('keydown', changeDirection);
gameLoop();
}
menu();

62
templates/404.html Normal file
View File

@ -0,0 +1,62 @@
{% extends "base.html" %}
{% block title %}404 - Not Found{% endblock %}
{% block description %}The page you are looking for does not exist.{% endblock %}
{% block head %}
<link rel="stylesheet" href="/static/css/404.css">
<link rel="stylesheet" href="/static/css/cap.css">
{% endblock %}
{% block content %}
<section>
<h1>404</h1>
<p>
It seems like the thing you are looking for is not here :[
<br><br>
while you're here, why not play some snake?
</p>
<canvas id="snakeCanvas"></canvas>
</section>
<section class="flex-row">
<section class="min-width">
<h2>Submit score</h2>
<form action="/404/submit" method="POST" id="snakeForm">
<input type="text" id="username" name="username" placeholder="Your name" required>
<cap-widget id="captcha" data-cap-api-endpoint="https://cap.alfieking.dev/57d36430b9cb/api/"></cap-widget>
<input type="hidden" id="snake-score" name="snake-score" value="0">
<button type="submit" id="submit">Submit</button>
</form>
</section>
<section class="max-width" id="snakeLeaderboardSection">
<h2>Leaderboard</h2>
<ul id="snakeLeaderboard">
{% for score in scores %}
<li>
<span>{{ score.position }}</span>
<span>{{ score.name }}</span>
<span>{{ score.score }}</span>
</li>
{% endfor %}
</ul>
</section>
</section>
{% if error %}
<dialog id="errorDialog">
<h2>Error</h2>
<p>{{ error }}</p>
<button onclick="errorDialog.close()">Close</button>
</dialog>
<script>
const errorDialog = document.getElementById('errorDialog');
if (errorDialog) {
errorDialog.showModal();
}
</script>
{% endif %}
{% endblock %}
{% block scripts %}
<script src="/static/js/snake.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@cap.js/widget"></script>
{% endblock %}

17
templates/500.html Normal file
View File

@ -0,0 +1,17 @@
{% extends "base.html" %}
{% block title %}500 - Internal Server Error{% endblock %}
{% block description %}An unexpected error occurred on the server.{% endblock %}
{% block head %}
<link rel="stylesheet" href="/static/css/500.css">
{% endblock %}
{% block content %}
<section class="bluescreen">
<h1>:(</h1>
<p>
Oopsie Woopsie! Uwu We made a fucky wucky!! A wittle fucko boingo! The code monkeys at our headquarters are working VEWY HAWD to fix this!
</p>
</section>
{% endblock %}

View File

@ -3,19 +3,21 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Alfie's basement</title>
<title>{% block title %}Alfie's basement{% endblock %}</title>
<link rel="icon" href="/static/content/icon.webp">
<link rel="stylesheet" href="/static/css/index.css">
<meta name="description" content="Alfie's basement">
<link rel="stylesheet" href="/static/css/base.css">
<meta name="description" content="{% block description %}server backend survivor{% endblock %}">
<meta name="keywords" content="Alfie King, Alfie, King, Alfieking, Alfieking.dev, dev, server">
<meta name="author" content="Alfie King">
<meta name="robots" content="all">
<meta name="theme-color" content="#63de90" data-react-helmet="true">
<meta property="og:site_name" content="Alfieking.dev">
<meta property="og:url" content="https://alfieking.dev">
<meta property="og:title" content="Alfie's basement">
<meta property="og:description" content="server backend survivor">
<meta property="og:title" content="{{ self.title() }}">
<meta property="og:description" content="{{ self.description() }}">
<meta property="og:image" content="static/content/icon.webp">
{% block head %}
{% endblock %}
</head>
<body>
<div id="furry"></div>
@ -31,8 +33,9 @@
<li><a href="https://open.spotify.com/user/xz02oolstlvwxqu1pfcua9exz?si=14396e637f284e03">Spotify</a></li>
<li><a href="https://steamcommunity.com/id/acetheking987/">Steam</a></li>
<li><a href="https://www.youtube.com/@acetheking987">YouTube</a></li>
<li><a href="https://acetheking987.tumblr.com/">Tumblr</a></li>Instagram
<li><a href="https://acetheking987.tumblr.com/">Tumblr</a></li>
<li><a href="https://www.reddit.com/user/acetheking987">Reddit</a></li>
<li><a href="/404">404 >:3</a></li>
</ul>
</section>
</nav>
@ -58,7 +61,7 @@
<section>
<pre class="vsmoltext"> |\ _,,,---,,_<br>ZZZzz /,`.-'`' -. ;-;;,_<br> |,4- ) )-,_. ,\ ( `'-'<br> '---''(_/--' `-'\_)</pre>
</section>
<img src="static/content/haj.gif" alt="haj" class="haj">
<img src="/static/content/haj.gif" alt="haj" class="haj">
</div>
<main id="main">
<header id="home">
@ -70,18 +73,26 @@
</div>
</div>
</header>
<section>
<h1>404</h1>
<p>
It seems like the thing you are looking for is not here :[
</p>
</section>
<nav id="alt-nav">
<ul>
<li><a href="https://git.alfieking.dev/acetheking987">Gitea</a></li>
<li><a href="https://www.last.fm/user/acetheking987">LastFm</a></li>
<li><a href="https://prismic.alfieking.dev">Prismic</a></li>
<li><a href="https://open.spotify.com/user/xz02oolstlvwxqu1pfcua9exz?si=14396e637f284e03">Spotify</a></li>
<li><a href="https://steamcommunity.com/id/acetheking987/">Steam</a></li>
<li><a href="https://www.youtube.com/@acetheking987">YouTube</a></li>
<li><a href="https://acetheking987.tumblr.com/">Tumblr</a></li>
<li><a href="https://www.reddit.com/user/acetheking987">Reddit</a></li>
</ul>
</nav>
{% block content %}{% endblock %}
<section>
<footer>
<p>legal stuff idk :3 | icba to &copy; this :P | made with &hearts; and caffine</p>
</footer>
</section>
</main>
<script src="/static/js/index.js"></script>
{% block scripts %}{% endblock %}
<script src="/static/js/base.js"></script>
</body>
</html>

115
templates/index.html Normal file
View File

@ -0,0 +1,115 @@
{% extends "base.html" %}
{% block title %}Alfie's basement{% endblock %}
{% block description %}server backend survivor{% endblock %}
{%block content %}
<section>
<h1>A lil bit abt me</h1>
<p>
Im not good with writing so dont expect much here. I am a student who is learning c++ and python. I've Done a few projects that i think
are decent enough to show off, so I have put them on this website. I like to mess around with linux and have a few servers that I run. I've
been running a server for a few years now, and I have learned a lot from it. I have also switched to linux on my main computer, which has been
slightly annoying at times (mainly because one of my most played games' anticheat doesn't support on linux atm. Also, the lack of photoshop is
a pain).
<br><br>
I would like to make some more projects in the future, but I am not sure what I want to make yet. I tend to make thing on impulse a lot, and motivation
is "lacking" at times. So the few ideas I do have may never come to fruition. I hope to get better at art so i could hopefully make a game that is somewhat
interesting. But im at a lack of ideas at the moment.
<br><br>
I would also like to have a functional blog on this site, but I bearly talk about much so I dont know what I would write about. I like to ramble on about
random things, but I dont think that would be very interesting to read, and I think that I would forget to update it. I have a tumblr that I have had for a few
years now, but I dont post on it (the social anxiety is too much for me :<). However I hope to get better at that in the future.
</p>
</section>
<section class="blinkies">
<img src="https://adriansblinkiecollection.neocities.org/x45.gif" alt="">
<img src="https://adriansblinkiecollection.neocities.org/t3.gif" alt="">
<img src="https://adriansblinkiecollection.neocities.org/k25.gif" alt="">
<img src="https://s1nez.nekoweb.org/img/52475686_BP77MK3UdnLmIQk.gif" alt="">
<img src="https://s1nez.nekoweb.org/img/hc/hc%20(79).gif" alt="">
<img src="https://dewside.neocities.org/blinkies/bisigns.gif" alt="">
<img src="https://s1nez.nekoweb.org/g/ggg/gg%20(32).gif" alt="">
<img src="https://s1nez.nekoweb.org/img/7dcd20d4.gif" alt="">
</section>
<section class="rowsect">
<a href="" id="spotify-link">
<div id="spotify">
<h1 id="spotify-title"></h1>
<h2 id="spotify-artist"></h2>
</div>
</a>
<div class="stamps">
<img src="https://s1nez.nekoweb.org/img/other/ba4ba47a.png" alt="">
<img src="https://s1nez.nekoweb.org/img/fa02abd7.png" alt="">
<img src="https://s1nez.nekoweb.org/img/hc/hc%20(172).gif" alt="">
<img src="https://gligar.neocities.org/furret2.png" alt="">
<img src="https://gligar.neocities.org/ralsei2.png" alt="">
<img src="https://gligar.neocities.org/tism.png" alt="">
<img src="https://64.media.tumblr.com/11957593416710af9ff049ff6ae7ab63/tumblr_pbb7cd42Ln1xz2nuuo4_100.gif" alt="">
<img src="https://dewside.neocities.org/stamps/dogofwisdom.gif" alt="">
<img src="https://dewside.neocities.org/stamps/kazookid.gif" alt="">
<img src="https://64.media.tumblr.com/3085aeace24ca0c5ddf08aac37cc3ab4/45a30eb92e06a85c-3a/s100x200/b7bfb2e91adbc310f712f4492e668298bd0779de.gif" alt="">
<img src="https://s1nez.nekoweb.org/img/hc/hc%20(27).png" alt="">
<img src="https://s1nez.nekoweb.org/g/ggg/gg%20(13).gif" alt="">
<img src="https://kopawz.neocities.org/stamphoard/stamps2/kriswhere.png" alt="">
<img src="https://adriansblinkiecollection.neocities.org/stamps/g5.gif" alt="">
<img src="https://adriansblinkiecollection.neocities.org/stamps/e40.gif" alt="">
<img src="https://adriansblinkiecollection.neocities.org/stamps/e43.gif" alt="">
</div>
</section>
<section>
<h1>Projects & stuff</h1>
<p>just some projects ive worked on over time</p>
<ul>
<li>
<h2>alfieking.dev</h2>
<p>
This website is a project that I have been working on for a while now. I have made a few versions of it, but I have
never been happy with them. I am quite happy with this version atm since it is more organized and has a design that I
like.
<a href="https://git.alfieking.dev/acetheking987/alfieking.dev">source code</a>
</p>
</li>
<li>
<h2>owo (the terminal command)</h2>
<p>
I made this project as a joke, I can't remember exactly what I baised it off other than the fact that it was somthing
similar to this but in a different language. I originally made it in python, but I have since rewritten it in c++ so
that it would be faster and so that I could learn c++.
<a href="https://git.alfieking.dev/acetheking987/term-owo-cpp">source code</a>
</p>
</li>
<li>
<h2>prismic</h2>
<p>
Prismic is a basic message board that I made, it was mainly made to learn how to use templating and more backend
web development. it uses flask for the web framework and uses a sqlite database to store the messages. I have thought
about remaking it in c++ since I found a c++ web framework that I would like to try out.
<a href="https://prismic.alfieking.dev">Primic</a> | <a href="https://git.alfieking.dev/acetheking987/prismic">source code</a>
</p>
</li>
</ul>
</section>
<section>
<h1>The button collection™</h1>
<div id="button-collection">
</div>
</section>
<section>
<h1>Some News</h1>
<h6>(dont expect this to be updated often tho :P)</h6>
<ul>
<li>
<h2>18-06-2025</h2>
<p>
I plan on updating the site soon, I have a few ideas that I want to implement. I want to make it more
interactive and fun to use. I also want to add a blog section so that I can write about random things that I find interesting. I also
want to add a few more projects that I have been working on. Annoyingly I think it would be a good idea to remake this site with some sort of
framework so i can use templating, however this kinda bothers me since I like the simplicity of this site. And prefer to keep it as a static site
that i can just throw at nginx.
</p>
</li>
</ul>
</section>
{% endblock %}