removed all posts
All checks were successful
Restart Website Service / restart_service (push) Successful in 30s
|
@ -63,7 +63,16 @@
|
||||||
if (response.status != 200)
|
if (response.status != 200)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let posts = (await response.text()).split("\n");
|
let posts = (await response.text()).split("\n").filter(x => x != "");
|
||||||
|
|
||||||
|
if (posts.length == 0) {
|
||||||
|
let p = document.querySelector("#content>.content.posts>h2");
|
||||||
|
p.innerHTML = "This is where I would put my posts...<br>IF I HAD ANY!";
|
||||||
|
let elem = document.querySelector("#content>.content.posts>ul");
|
||||||
|
elem.remove();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let p = document.querySelector("#content>.content.posts>h2");
|
let p = document.querySelector("#content>.content.posts>h2");
|
||||||
p.innerHTML = "Recent <a href=\"/posts\">posts</a>";
|
p.innerHTML = "Recent <a href=\"/posts\">posts</a>";
|
||||||
|
|
|
@ -178,6 +178,8 @@ const maps = {
|
||||||
keyword("Ok"),
|
keyword("Ok"),
|
||||||
keyword("Err"),
|
keyword("Err"),
|
||||||
keyword("in"),
|
keyword("in"),
|
||||||
|
keyword("Self"),
|
||||||
|
keyword("mut"),
|
||||||
|
|
||||||
altKeyword("if"),
|
altKeyword("if"),
|
||||||
altKeyword("else"),
|
altKeyword("else"),
|
||||||
|
@ -185,6 +187,9 @@ const maps = {
|
||||||
altKeyword("loop"),
|
altKeyword("loop"),
|
||||||
altKeyword("for"),
|
altKeyword("for"),
|
||||||
altKeyword("while"),
|
altKeyword("while"),
|
||||||
|
altKeyword("return"),
|
||||||
|
altKeyword("async"),
|
||||||
|
altKeyword("await"),
|
||||||
|
|
||||||
altKeyword("mod"),
|
altKeyword("mod"),
|
||||||
altKeyword("use"),
|
altKeyword("use"),
|
||||||
|
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
BIN
public/posts/_Putting hungry minecraft servers to sleep/ping.png
Normal file
After Width: | Height: | Size: 43 KiB |
|
@ -61,17 +61,74 @@ wanted. [One crate](https://www.youtube.com/watch?v=E4WlUXrJgy4) was useful
|
||||||
for seeing how an implementation of parsing packets was done, but ultimately
|
for seeing how an implementation of parsing packets was done, but ultimately
|
||||||
I had to write my own parser.
|
I had to write my own parser.
|
||||||
|
|
||||||
***images of minecraft protocol***
|

|
||||||
|
|
||||||
## Detecting the subdomain
|
## Detecting the subdomain
|
||||||
|
|
||||||
|
The first step in routing the traffic was determining where to send it to.
|
||||||
|
|
||||||
Luckily for me, the Minecraft procotol sends the full address it is trying to
|
Luckily for me, the Minecraft procotol sends the full address it is trying to
|
||||||
connect to during the handshake. This meant that I simply had to parse the
|
connect to during the handshake. This meant that I simply had to parse the
|
||||||
handshake and extract the subdomain from the address, see if it matches any
|
handshake and extract the subdomain from the address, see if it matches any
|
||||||
configured server, and then redirect all traffic to the internal port that
|
configured server, and then redirect all traffic to the internal port that
|
||||||
server runs on.
|
server runs on.
|
||||||
|
|
||||||
***code explanation***
|
`$ vim protocol/handshake.rs`
|
||||||
|
```rust
|
||||||
|
impl Handshake {
|
||||||
|
pub async fn new(buf: &mut BufferedReader) -> Result<Self, Error> {
|
||||||
|
// Packets start with their type id. The handshake is id 0x00
|
||||||
|
if !check_bytes(&[0x00], buf).await? {
|
||||||
|
return Err(Error::Err(
|
||||||
|
"Wrong packet type for handshake. Expected {} got {}".into(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
buf.read(1).await?; // Consume handhake byte
|
||||||
|
|
||||||
|
let protocol_version = VarInt::read_from(buf).await?;
|
||||||
|
let address = read_string(buf).await?;
|
||||||
|
let port = buf.read_u16().await?;
|
||||||
|
let next_state = VarInt::read_from(buf).await?;
|
||||||
|
|
||||||
|
return Ok(
|
||||||
|
Self {
|
||||||
|
protocol_version,
|
||||||
|
address,
|
||||||
|
port,
|
||||||
|
next_state,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The only thing I was interrested in was the `address` part of the packet. This is a full string
|
||||||
|
containing the text the user typed in the `IP Address` field in their client.
|
||||||
|
|
||||||
|
Once I had this it was as simple as splitting by `.` and taking the first result. This "server name" would now be used to look up the corosponding servers information in a table.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
|
||||||
|
let result = Handshake::new(&mut reader).await;
|
||||||
|
if !result.is_ok() {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
let handshake = result.ok().unwrap();
|
||||||
|
let split = handshake.address.split(".").collect::<Vec<&str>>();
|
||||||
|
let server_name = *split.first().unwrap();
|
||||||
|
|
||||||
|
if !SERVERS.lock().unwrap().contains_key(server_name) {
|
||||||
|
println!("Unknown server {}", server_name);
|
||||||
|
write_unknown_server_status(server_name.into(), &mut reader).await?;
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
let mut server_lock = SERVERS.lock().unwrap();
|
||||||
|
let server = server_lock.get_mut(server_name).unwrap();
|
||||||
|
status = server.status;
|
||||||
|
port = server.port;
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
***show images of hibernation and starting***
|
***show images of hibernation and starting***
|
||||||
|
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
@ -127,10 +127,10 @@ fn handle_connection(mut stream: TcpStream) {
|
||||||
let y = file_name.to_str();
|
let y = file_name.to_str();
|
||||||
let ft = x.file_type();
|
let ft = x.file_type();
|
||||||
if y.is_some() {
|
if y.is_some() {
|
||||||
if ft.is_ok() && ft.unwrap().is_dir() {
|
if y.unwrap().starts_with("_") {
|
||||||
true
|
|
||||||
} else if y.unwrap().starts_with("_") {
|
|
||||||
false
|
false
|
||||||
|
} else if ft.is_ok() && ft.unwrap().is_dir() {
|
||||||
|
true
|
||||||
} else if y.unwrap().ends_with(".md") {
|
} else if y.unwrap().ends_with(".md") {
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
|
@ -228,7 +228,7 @@ fn handle_connection(mut stream: TcpStream) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.reduce(|a, b| format!("{}\n{}", b, a))
|
.reduce(|a, b| format!("{}\n{}", b, a))
|
||||||
.unwrap();
|
.unwrap_or("".to_owned());
|
||||||
format!("HTTP/1.1 200 OK\r\nContent-Type: text/text\r\nContent-Length: {}\r\n\r\n{}", data.len(), data)
|
format!("HTTP/1.1 200 OK\r\nContent-Type: text/text\r\nContent-Length: {}\r\n\r\n{}", data.len(), data)
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|