did some grinding off camera

This commit is contained in:
Snorre Ettrup Altschul 2025-02-06 22:56:02 +01:00
parent b036acd3f4
commit 302d405cc3
14 changed files with 169 additions and 91 deletions

View file

@ -1,4 +1,4 @@
@import url(https://fonts.bunny.net/css?family=chivo-mono:500); @import url(https://fonts.bunny.net/css?family=albert-sans:400,800);
@import url(/css/colours.css); @import url(/css/colours.css);
code { code {
@ -8,6 +8,34 @@ code {
border-radius: var(--radius); border-radius: var(--radius);
} }
h1 {
letter-spacing: -4%;
}
h2,
h3 {
letter-spacing: -3%;
margin: calc(2*var(--margin)) 0
}
h1,h2,h3 {
margin-bottom:0px;
}
.header h1 {
margin-bottom: 0.5em;
}
ul,
ol {
padding-left: calc(4*var(--margin));
}
li::marker {
color: var(--link);
}
ul.posts>li { ul.posts>li {
margin-top: var(--margin); margin-top: var(--margin);
} }
@ -23,7 +51,7 @@ pre.codeblock {
html { html {
color: var(--text); color: var(--text);
background-color: var(--background); background-color: var(--background);
font-family: 'Chivo Mono', monospace; font-family: 'Albert Sans', sans-serif;
} }
body { body {
@ -33,9 +61,15 @@ body {
a { a {
color: var(--link); color: var(--link);
transition: 0.1s ease-in-out;
text-decoration: none;
} }
a:visited { a:visited {
color: var(--link);
}
a:hover {
color: var(--link-visited); color: var(--link-visited);
} }
@ -49,7 +83,7 @@ body {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
line-height: 1.5; line-height: 1.3;
} }
#content { #content {

View file

@ -2,6 +2,7 @@
<html> <html>
<head> <head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/css/css.css"> <link rel="stylesheet" href="/css/css.css">
</head> </head>
@ -37,15 +38,13 @@
<marquee>Footer</marquee> <marquee>Footer</marquee>
</div> </div>
<div class="footer" style="grid-area: footer2; text-align: center"> <div class="footer" style="grid-area: footer2; text-align: center">
<!-- <a href="https://nixwebr.ing/next/<name>">&leftarrow; prev</a> <a href="https://nixwebr.ing">nixwebr.ing</a> --> <!-- <a href="https://nixwebr.ing/next/<name>">&leftarrow; prev</a> <a href="https://nixwebr.ing">Nix</a> -->
<!-- <a href="https://nixwebr.ing/prev/<name>">next &rightarrow;</a> --> <!-- <a href="https://nixwebr.ing/prev/<name>">next &rightarrow;</a> -->
webbringGg
</div> </div>
<div class="footer" style="grid-area: footer3; text-align: center;"> <div class="footer" style="grid-area: footer3; text-align: center;">
<!-- <a href="https://512kb.club"><img style="aspect-ratio: 234.383/30" height=30 --> <!-- <a href="https://512kb.club" style="padding:0"><img style="aspect-ratio: 234.383/30" height=24 -->
<!-- alt="a proud member of the green team of 512KB club" --> <!-- alt="a proud member of the green team of 512KB club" -->
<!-- src="https://512kb.club/assets/images/green-team.svg"></a> --> <!-- src="https://512kb.club/assets/images/green-team.svg"></a> -->
aspirant of 512kb.club
</div> </div>
</div> </div>
<div id="background"></div> <div id="background"></div>
@ -61,10 +60,10 @@
let posts = (await response.text()).split("\n"); let posts = (await response.text()).split("\n");
let p = document.querySelector("#content>.content.posts>h2"); let p = document.querySelector("#content>.content.posts>h2");
p.innerText = "Recent posts"; p.innerHTML = "Recent <a href=\"/posts\">posts</a>";
let elem = document.querySelector("#content>.content.posts>ul"); let elem = document.querySelector("#content>.content.posts>ul");
elem.innerHTML = posts.slice(0,3).map(x => `<li><a href="/posts?post=${x}">${x}</a></li>`).join("\n"); elem.innerHTML = posts.slice(0, 3).map(x => `<li><a href="/posts?post=${x}">${x}</a></li>`).join("\n");
elem.style.maxWidth = "40ch"; elem.style.maxWidth = "40ch";
elem.classList.add("posts"); elem.classList.add("posts");
})() })()

View file

@ -23,6 +23,16 @@ const match = (m) => (peek, take) => {
take(m.length); take(m.length);
return true; return true;
} }
const match_identifier = (m) => (peek, take) => {
if (match(m)(peek, take)) {
if (peek(0).match(/[0-9a-z]/)) {
take(-m.length);
return false
}
return true;
}
return false;
}
const take_until = (p) => (peek, take) => { const take_until = (p) => (peek, take) => {
let b = ""; let b = "";
while (!p()) { while (!p()) {
@ -33,7 +43,7 @@ const take_until = (p) => (peek, take) => {
} }
const simpleHighlight = (c) => (keyword) => (peek, take) => { const simpleHighlight = (c) => (keyword) => (peek, take) => {
if (match(keyword)(peek, take)) if (match_identifier(keyword)(peek, take))
return `<span class="${c}">${keyword}</span>`; return `<span class="${c}">${keyword}</span>`;
} }
@ -60,7 +70,7 @@ const multiline_comment = (prefix, suffix) => (peek, take) => {
const string = (c) => (peek, take) => { const string = (c) => (peek, take) => {
if (match(c)(peek, take)) { if (match(c)(peek, take)) {
let b = c; let b = c;
b += take_until(() => match(c)(peek,take))(peek, take); b += take_until(() => match(c)(peek, take))(peek, take);
b += c; b += c;
return `<span class="string">${b}</span>` return `<span class="string">${b}</span>`
} }

View file

@ -62,13 +62,23 @@ const md2tokens = (markdown, newline) => {
case '\\': case '\\':
i++; i++;
if (peek(0) == 't' && peek(1) == 'o' && peek(2) == 'c') { const match_word = (word) => {
advance(); for (let j = 0; j < word.length; j++) {
advance(); if (peek(j) != word[j])
advance(); return false;
}
i += word.length;
return true;
};
if (match_word("toc")) {
tokens.push({ type: "toc" }); tokens.push({ type: "toc" });
break; break;
} }
if (match_word("title")) {
tokens.push({ type: "title" });
break;
}
current_string += markdown[i]; current_string += markdown[i];
break; break;
@ -131,8 +141,7 @@ const md2tokens = (markdown, newline) => {
} }
finish(); finish();
advance(); i += 2;
advance();
let alt_text = capture_until("]"); let alt_text = capture_until("]");
advance(); advance();
if (!match("(")) { if (!match("(")) {
@ -164,10 +173,7 @@ const md2tokens = (markdown, newline) => {
} }
if (peek(0) == "-" && peek(1) == "-" && peek(2) == "-" && peek(3) == "\n") { if (peek(0) == "-" && peek(1) == "-" && peek(2) == "-" && peek(3) == "\n") {
advance(); i += 3;
advance();
advance();
tokens.push({ type: "hline" }); tokens.push({ type: "hline" });
break; break;
} }
@ -191,6 +197,15 @@ const md2tokens = (markdown, newline) => {
break; break;
case '\n': case '\n':
if ((peek(-1) != " " || peek(-2) != " ") && peek(-1) != "\n") {
current_string += " ";
tokens.push({ type: "span", content: current_string });
current_string = "";
newline = true;
break;
}
if (newline_count > 2) if (newline_count > 2)
break; break;
@ -198,6 +213,8 @@ const md2tokens = (markdown, newline) => {
newline_count++; newline_count++;
finish(); finish();
tokens.push({ type: "newline" }) tokens.push({ type: "newline" })
if (newline_count == 1 && peek(-1) == "\n")
tokens.push({ type: "newline" })
break; break;
case '[': case '[':
@ -261,40 +278,20 @@ const highlight_code = (language, code) => {
return highlight(map, code); return highlight(map, code);
} }
const tokens2html = (tokens) => { const tokens2html = (tokens, title) => {
let output = ""; let output = "";
for (let token of tokens) { for (let token of tokens) {
switch (token.type) { switch (token.type) {
case "toc": case "toc":
let htok = tokens.filter(x => x.type == "header"); output += "TABLE LE CONTENTOS"
console.log(htok); break;
const createList = (tokens, depth = 2) => { case "title":
let list = ''; output += `<h1>${title}</h1>`
let listItems = '';
while (tokens.length > 0 && tokens[0].level <= depth) {
const token = tokens.shift();
listItems += `<li><a href="#${token.content}">${token.content}</a></li>`;
if (tokens.length > 0 && tokens[0].level > token.depth) {
listItems += createList(tokens, token.depth + 1);
}
}
if (listItems) {
list = `<ol>${listItems}</ol>`;
}
return list;
};
output += createList(htok);
break; break;
case "span": case "span":
output += `<span>${token.content}</span>`; output += `<span>${token.content}</span>`;
break break;
case "bold": case "bold":
output += `<b>${token.content}</b>` output += `<b>${token.content}</b>`
break; break;
@ -305,7 +302,7 @@ const tokens2html = (tokens) => {
output += `<b><i>${token.content}</i></b>` output += `<b><i>${token.content}</i></b>`
break; break;
case "header": case "header":
output += `<h${token.level}>${token.content}</h${token.level}>` output += `<h${token.level} id="${token.content.replace(/ /g, "-")}">${token.content}</h${token.level}>`
if (token.level == 2) output += "<hr>"; if (token.level == 2) output += "<hr>";
break; break;
case "hline": case "hline":

View file

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View file

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View file

@ -2,32 +2,49 @@
Minecraft Rust Async Networking Proxy CRIU Minecraft Rust Async Networking Proxy CRIU
# Minecraft servers are HUNGRY # Minecraft servers are HUNGRY
They hunger for your ram and your cpu. This makes it either expensive or laggy to try and host multiple servers at once. They hunger for your ram and your cpu. This makes it either expensive or
This was something I encountered when my friend built a homeserver out of spare computer parts that was barely powerful enough to run a minecraft server. laggy to try and host multiple servers at once.
The problem was that soon multiple people wanted a minecraft server hosted by him (which included us wanting to play modded minecraft).
It was a hassle to ssh into the server and start and stop the various servers depending on who wanted to play, This was something I encountered when my friend built a homeserver out of
especially since a lot of people only played very rarily. spare computer parts that was barely powerful enough to run a minecraft
server.
I remembered that I'd seen [a project](https://github.com/gekware/minecraft-server-hibernation) that claimed to be able to hibernate a minecraft server if nobody was playing on it. The problem was that soon multiple people wanted a minecraft server
The only issue was that it worked for a single server, and did so by starting and stopping the server process. hosted by him (which included us wanting to play modded minecraft).
This meant that if we wanted to join a modded server the hundreds of mods could make us wait for several minutes before we could play. It was a hassle to ssh into the server and start and stop the various
servers depending on who wanted to play, especially since a lot of people
only played very rarily.
Another issue was the fact that it could only host a single server. This meant that we would have to run multiple intances of the watcher, I remembered that I'd seen
and that each server would be assigned to an arbitrary port that would be needed when connecting. [a project](https://github.com/gekware/minecraft-server-hibernation)
that claimed to be able to hibernate a minecraft server if nobody was
playing on it. The only issue was that it worked for a single server, and
did so by starting and stopping the server process.
This meant that if we wanted to join a modded server the hundreds of mods
could make us wait for several minutes before we could play.
Another issue was the fact that it could only host a single server. This
meant that we would have to run multiple intances of the watcher, and that
each server would be assigned to an arbitrary port that would be needed
when connecting.
# Building a reverse proxy for minecraft # Building a reverse proxy for minecraft
Since my friends server was accessible through a domain we thought it would be cool if instead of supplying a port Since my friends server was accessible through a domain we thought it
you could connect to a subdomain and be sent to a specific server. would be cool if instead of supplying a port you could connect to a
subdomain and be sent to a specific server.
The simplest way to do this would be to create a dhcp record for each subdomain to point to a server, The simplest way to do this would be to create a dhcp record for each
but that would be slow and tedious to set up for every server. subdomain to point to a server, but that would be slow and tedious to set
up for every server.
We then tried nginx, as it seemingly could magically redirect traffic to an internal port based on the subdomain. We then tried nginx, as it seemingly could magically redirect traffic to
I quickly found out that this did *not* work for minecraft servers (who would have guessed), but after doing some research an internal port based on the subdomain. I quickly found out that this did
I decided on creating my own reverse proxy that spoke the minecraft protocol instead of HTTP. *not* work for minecraft servers (who would have guessed), but after doing
some research I decided on creating my own reverse proxy that spoke the
minecraft protocol instead of HTTP.
# The Minecraft protocol # The Minecraft protocol

View file

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View file

@ -2,6 +2,7 @@
<html> <html>
<head> <head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/css/css.css"> <link rel="stylesheet" href="/css/css.css">
<style> <style>
#content { #content {
@ -11,7 +12,7 @@
"footer2 footer" "footer2 footer"
; ;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
max-width: 120ch; max-width: 75ch;
} }
#content>.content { #content>.content {
@ -19,11 +20,6 @@
text-justify: auto; text-justify: auto;
} }
ul,ol {
margin-top:0;
padding-left: calc(4*var(--margin));
}
pre.quote { pre.quote {
font: inherit; font: inherit;
@ -43,8 +39,9 @@
img { img {
background-color: var(--background-text); background-color: var(--background-text);
border-radius: var(--radius); border-radius: var(--radius);
width: 100%;
} }
img.enlarged { img.enlarged {
@ -75,7 +72,7 @@
<body style="background-color: #222;"> <body style="background-color: #222;">
<div id="content"> <div id="content">
<div class="header" style="grid-area: header; text-align: center"> <div class="header" style="grid-area: header; text-align: center">
<a href="/posts" style="color: inherit; text-decoration: inherit"> <a href="/" style="color: inherit; text-decoration: inherit">
<h1>SpoodyThe<span style="color:var(--background-text)">.</span>One</h1> <h1>SpoodyThe<span style="color:var(--background-text)">.</span>One</h1>
</a> </a>
</div> </div>
@ -102,7 +99,7 @@
generate_background(posts); generate_background(posts);
let elem = document.querySelector("#content>.content"); let elem = document.querySelector("#content>.content");
elem.innerHTML = posts.map(x => `<a href="/posts?post=${x}"><h2>${x}</h2></a>`).join("<br>\n"); elem.innerHTML = `<ul>${posts.map(x => `<li><a href="/posts?post=${x}" style="font-size: 1.2em;">${x}</a></li>`).join("\n")}</ul>`;
elem.style.maxWidth = "80ch"; elem.style.maxWidth = "80ch";
document.querySelector(".header>a").href = "/"; document.querySelector(".header>a").href = "/";
}; };
@ -116,12 +113,17 @@
return; return;
} }
let response = await fetch(`/posts/${post}.md`); let response = await fetch(`/posts/${post}/post.md`);
let content = await response.text(); let content = ""
if (response.status != 200) { if (response.status != 200) {
content = `\nError Exception Null\n#Unknown post '${post}'` response = await fetch(`/posts/${post}.md`);
} if (response.status != 200) {
content = `\nError Exception Null\n# Unknown post '${post}'`
} else
content = await response.text();
} else
content = await response.text();
let lines = content.split("\n"); let lines = content.split("\n");
lines.shift(); lines.shift();
@ -130,7 +132,7 @@
generate_background(terms.split(" ")); generate_background(terms.split(" "));
document.getElementsByClassName("content")[0].innerHTML = tokens2html(md2tokens(content)); document.getElementsByClassName("content")[0].innerHTML = tokens2html(md2tokens(content), post);
await new Promise(res => setTimeout(res, 5000)); await new Promise(res => setTimeout(res, 5000));
if (document.body.scrollHeight > window.innerHeight) { if (document.body.scrollHeight > window.innerHeight) {

View file

@ -1,5 +1,7 @@
0 0
Test Test
\title
---
\toc \toc
# H1 # H1
## H2 ## H2
@ -31,6 +33,7 @@ this is a code block
*/ */
void main(int argc, char** argv) { void main(int argc, char** argv) {
std::string this = "c++ code block"; std::string this = "c++ code block";
int integer = 0;
return 0; return 0;
} }
@ -46,7 +49,7 @@ private:
``` ```
```nix ```nix
{ ... }: { ... } @ inputs :
let let
this = "a nix code block"; this = "a nix code block";
in in

View file

@ -60,9 +60,13 @@ impl Request {
path.push("public"); path.push("public");
path.push( path.push(
PathBuf::from(urlencoding::decode(self.path.as_ref().unwrap()).unwrap().to_string()) PathBuf::from(
.strip_prefix("/") urlencoding::decode(self.path.as_ref().unwrap())
.expect("Failed to strip prefix"), .unwrap()
.to_string(),
)
.strip_prefix("/")
.expect("Failed to strip prefix"),
); );
if path.extension() == None { if path.extension() == None {
@ -119,13 +123,13 @@ fn handle_connection(mut stream: TcpStream) {
let file_name = x.file_name(); let file_name = x.file_name();
let y = file_name.to_str(); let y = file_name.to_str();
if y.is_some() { if y.is_some() {
if y.unwrap().ends_with(".md") { if y.unwrap().ends_with(".html") {
true
} else {
false false
} else {
true
} }
} else { } else {
false true
} }
}) })
.collect::<Vec<DirEntry>>(); .collect::<Vec<DirEntry>>();
@ -133,12 +137,24 @@ fn handle_connection(mut stream: TcpStream) {
let mut a = if let Ok(a) = std::fs::File::open(a.path()) { let mut a = if let Ok(a) = std::fs::File::open(a.path()) {
a a
} else { } else {
return std::cmp::Ordering::Equal; let mut path = a.path().clone();
path.push("post.md");
if let Ok(a) = std::fs::File::open(path) {
a
} else {
return std::cmp::Ordering::Equal;
}
}; };
let mut b = if let Ok(b) = std::fs::File::open(b.path()) { let mut b = if let Ok(b) = std::fs::File::open(b.path()) {
b b
} else { } else {
return std::cmp::Ordering::Equal; let mut path = b.path().clone();
path.push("post.md");
if let Ok(b) = std::fs::File::open(path) {
b
} else {
return std::cmp::Ordering::Equal;
}
}; };
let mut buf: &mut [u8] = &mut [0; 16]; let mut buf: &mut [u8] = &mut [0; 16];
@ -179,9 +195,9 @@ fn handle_connection(mut stream: TcpStream) {
.filter_map(|x| { .filter_map(|x| {
if let Some(n) = x.file_name().to_str() { if let Some(n) = x.file_name().to_str() {
if n.ends_with(".md") { if n.ends_with(".md") {
Some(n.to_owned().replace(".md","")) Some(n.to_owned().replace(".md", ""))
} else { } else {
None Some(n.to_owned())
} }
} else { } else {
None None