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);
code {
@ -8,6 +8,34 @@ code {
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 {
margin-top: var(--margin);
}
@ -23,7 +51,7 @@ pre.codeblock {
html {
color: var(--text);
background-color: var(--background);
font-family: 'Chivo Mono', monospace;
font-family: 'Albert Sans', sans-serif;
}
body {
@ -33,9 +61,15 @@ body {
a {
color: var(--link);
transition: 0.1s ease-in-out;
text-decoration: none;
}
a:visited {
color: var(--link);
}
a:hover {
color: var(--link-visited);
}
@ -49,7 +83,7 @@ body {
align-items: center;
justify-content: center;
line-height: 1.5;
line-height: 1.3;
}
#content {

View file

@ -2,6 +2,7 @@
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/css/css.css">
</head>
@ -37,15 +38,13 @@
<marquee>Footer</marquee>
</div>
<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> -->
webbringGg
</div>
<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" -->
<!-- src="https://512kb.club/assets/images/green-team.svg"></a> -->
aspirant of 512kb.club
</div>
</div>
<div id="background"></div>
@ -61,10 +60,10 @@
let posts = (await response.text()).split("\n");
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");
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.classList.add("posts");
})()

View file

@ -23,6 +23,16 @@ const match = (m) => (peek, take) => {
take(m.length);
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) => {
let b = "";
while (!p()) {
@ -33,7 +43,7 @@ const take_until = (p) => (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>`;
}
@ -60,7 +70,7 @@ const multiline_comment = (prefix, suffix) => (peek, take) => {
const string = (c) => (peek, take) => {
if (match(c)(peek, take)) {
let b = c;
b += take_until(() => match(c)(peek,take))(peek, take);
b += take_until(() => match(c)(peek, take))(peek, take);
b += c;
return `<span class="string">${b}</span>`
}

View file

@ -62,13 +62,23 @@ const md2tokens = (markdown, newline) => {
case '\\':
i++;
if (peek(0) == 't' && peek(1) == 'o' && peek(2) == 'c') {
advance();
advance();
advance();
const match_word = (word) => {
for (let j = 0; j < word.length; j++) {
if (peek(j) != word[j])
return false;
}
i += word.length;
return true;
};
if (match_word("toc")) {
tokens.push({ type: "toc" });
break;
}
if (match_word("title")) {
tokens.push({ type: "title" });
break;
}
current_string += markdown[i];
break;
@ -131,8 +141,7 @@ const md2tokens = (markdown, newline) => {
}
finish();
advance();
advance();
i += 2;
let alt_text = capture_until("]");
advance();
if (!match("(")) {
@ -164,10 +173,7 @@ const md2tokens = (markdown, newline) => {
}
if (peek(0) == "-" && peek(1) == "-" && peek(2) == "-" && peek(3) == "\n") {
advance();
advance();
advance();
i += 3;
tokens.push({ type: "hline" });
break;
}
@ -191,6 +197,15 @@ const md2tokens = (markdown, newline) => {
break;
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)
break;
@ -198,6 +213,8 @@ const md2tokens = (markdown, newline) => {
newline_count++;
finish();
tokens.push({ type: "newline" })
if (newline_count == 1 && peek(-1) == "\n")
tokens.push({ type: "newline" })
break;
case '[':
@ -261,40 +278,20 @@ const highlight_code = (language, code) => {
return highlight(map, code);
}
const tokens2html = (tokens) => {
const tokens2html = (tokens, title) => {
let output = "";
for (let token of tokens) {
switch (token.type) {
case "toc":
let htok = tokens.filter(x => x.type == "header");
console.log(htok);
const createList = (tokens, depth = 2) => {
let list = '';
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);
output += "TABLE LE CONTENTOS"
break;
case "title":
output += `<h1>${title}</h1>`
break;
case "span":
output += `<span>${token.content}</span>`;
break
break;
case "bold":
output += `<b>${token.content}</b>`
break;
@ -305,7 +302,7 @@ const tokens2html = (tokens) => {
output += `<b><i>${token.content}</i></b>`
break;
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>";
break;
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 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.
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.
The problem was that soon multiple people wanted a minecraft server hosted by him (which included us wanting to play modded minecraft).
They hunger for your ram and your cpu. This makes it either expensive or
laggy to try and host multiple servers at once.
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.
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.
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 only issue was that it worked for a single server, and did so by starting and stopping the server process.
The problem was that soon multiple people wanted a minecraft server
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,
and that each server would be assigned to an arbitrary port that would be needed when connecting.
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 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
Since my friends server was accessible through a domain we thought it would be cool if instead of supplying a port
you could connect to a subdomain and be sent to a specific server.
Since my friends server was accessible through a domain we thought it
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,
but that would be slow and tedious to set up for every server.
The simplest way to do this would be to create a dhcp record for each
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.
I quickly found out that this did *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.
We then tried nginx, as it seemingly could magically redirect traffic to
an internal port based on the subdomain. I quickly found out that this did
*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

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>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/css/css.css">
<style>
#content {
@ -11,7 +12,7 @@
"footer2 footer"
;
grid-template-columns: 1fr 1fr;
max-width: 120ch;
max-width: 75ch;
}
#content>.content {
@ -19,11 +20,6 @@
text-justify: auto;
}
ul,ol {
margin-top:0;
padding-left: calc(4*var(--margin));
}
pre.quote {
font: inherit;
@ -43,8 +39,9 @@
img {
background-color: var(--background-text);
border-radius: var(--radius);
width: 100%;
}
img.enlarged {
@ -75,7 +72,7 @@
<body style="background-color: #222;">
<div id="content">
<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>
</a>
</div>
@ -102,7 +99,7 @@
generate_background(posts);
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";
document.querySelector(".header>a").href = "/";
};
@ -116,12 +113,17 @@
return;
}
let response = await fetch(`/posts/${post}.md`);
let content = await response.text();
let response = await fetch(`/posts/${post}/post.md`);
let content = ""
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");
lines.shift();
@ -130,7 +132,7 @@
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));
if (document.body.scrollHeight > window.innerHeight) {

View file

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

View file

@ -60,9 +60,13 @@ impl Request {
path.push("public");
path.push(
PathBuf::from(urlencoding::decode(self.path.as_ref().unwrap()).unwrap().to_string())
.strip_prefix("/")
.expect("Failed to strip prefix"),
PathBuf::from(
urlencoding::decode(self.path.as_ref().unwrap())
.unwrap()
.to_string(),
)
.strip_prefix("/")
.expect("Failed to strip prefix"),
);
if path.extension() == None {
@ -119,13 +123,13 @@ fn handle_connection(mut stream: TcpStream) {
let file_name = x.file_name();
let y = file_name.to_str();
if y.is_some() {
if y.unwrap().ends_with(".md") {
true
} else {
if y.unwrap().ends_with(".html") {
false
} else {
true
}
} else {
false
true
}
})
.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()) {
a
} 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()) {
b
} 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];
@ -179,9 +195,9 @@ fn handle_connection(mut stream: TcpStream) {
.filter_map(|x| {
if let Some(n) = x.file_name().to_str() {
if n.ends_with(".md") {
Some(n.to_owned().replace(".md",""))
Some(n.to_owned().replace(".md", ""))
} else {
None
Some(n.to_owned())
}
} else {
None