From 2614c7ce77de32977cb0fc1d88c19050427f67c4 Mon Sep 17 00:00:00 2001 From: Garen Tyler Date: Tue, 14 Mar 2023 17:41:24 -0600 Subject: [PATCH] Update documentation --- .gitignore | 2 +- LICENSE | 2 +- README.md | 18 ++++++++++++------ composition.toml | 3 +-- server-icon.png | Bin 11088 -> 0 bytes 5 files changed, 15 insertions(+), 10 deletions(-) delete mode 100644 server-icon.png diff --git a/.gitignore b/.gitignore index 573fc9e..15af779 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ target /output.log /world -/.cargo +/server-icon.png diff --git a/LICENSE b/LICENSE index 2c8b763..0a479b7 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020-2022 Garen Tyler +Copyright (c) 2020-2023 Garen Tyler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 1c92894..9c19d9c 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,19 @@ # Composition +Composition is a new Minecraft server written from the ground-up in Rust. -Composition is targeting 1.8.9, protocol version 47. -The main goal is to get a working server, then optimize for speed. +Composition is targeting Minecraft version 1.19.3, protocol version 761. +The main goal is to get a working server, then optimize for speed (multi-threading/kubernetes/etc). -## Development Resources +## Project Structure +Composition is broken up into multiple crates to speed up build times and improve modularity. +- `src/main.rs` is a wrapper around `composition-core` that sets up logging among other things. + This is the main binary that is exported with `cargo build`. +- `composition-core` implements the main server logic, such as handling clients and loading world chunks. +- `composition-protocol` handles the types and packets needed for network communication. + The library was designed to be able to used by anyone looking to implement a Minecraft server. -- [Normal Login Sequence](https://wiki.vg/Protocol_FAQ#What.27s_the_normal_login_sequence_for_a_client.3F) +## Useful Resources - [Protocol Specification](https://wiki.vg/Protocol) +- [Normal Login Sequence](https://wiki.vg/Protocol_FAQ#What.27s_the_normal_login_sequence_for_a_client.3F) - [Server Ping](https://wiki.vg/Server_List_Ping) - [Map Format](https://wiki.vg/Map_Format) -- [Rust TcpStream Docs](https://doc.rust-lang.org/std/net/struct.TcpStream.html) -- [Rust Channel Docs](https://doc.rust-lang.org/std/sync/mpsc/index.html) diff --git a/composition.toml b/composition.toml index 102e5ff..fb3713f 100644 --- a/composition.toml +++ b/composition.toml @@ -1,7 +1,6 @@ log_level = "debug" max_players = 20 motd = "Hello world!" -ping_game_version = "1.18.1" +ping_game_version = "1.19.3" port = 25565 server_icon = "server-icon.png" - diff --git a/server-icon.png b/server-icon.png deleted file mode 100644 index 4ef7bdb6a4e2643c908c1f757414981753d890e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11088 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 W@q7V{-&J-10000