summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authornea <nea@nea.moe>2023-01-29 20:38:21 +0100
committernea <nea@nea.moe>2023-01-29 20:38:21 +0100
commitb9e1d23e2000cca681370cb9d215efa8c74ef52b (patch)
tree3fc15554b060ef51d26e0e50ed4f2076e416f93d /src
downloadmgasi-b9e1d23e2000cca681370cb9d215efa8c74ef52b.tar.gz
mgasi-b9e1d23e2000cca681370cb9d215efa8c74ef52b.tar.bz2
mgasi-b9e1d23e2000cca681370cb9d215efa8c74ef52b.zip
initial
Diffstat (limited to 'src')
-rw-r--r--src/main.rs98
1 files changed, 98 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..8f925e3
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,98 @@
+use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener, TcpStream};
+
+use anyhow::Result;
+use craftio_rs::{CraftIo, CraftSyncReader, CraftSyncWriter, CraftTcpConnection};
+use mcproto_rs::protocol::State;
+use mcproto_rs::status::{StatusFaviconSpec, StatusPlayersSpec, StatusSpec, StatusVersionSpec};
+use mcproto_rs::types::{Chat, TextComponent};
+use mcproto_rs::types::Chat::Text;
+use mcproto_rs::v1_19::{HandshakeNextState, Packet759, RawPacket759, StatusPingSpec, StatusPongSpec, StatusResponseSpec};
+use mcproto_rs::v1_19::Packet759Kind::{Handshake, PlayServerPlayerAbilities};
+use tokio;
+
+pub struct MinecraftClient {
+ connection: CraftTcpConnection,
+}
+
+impl MinecraftClient {
+ pub fn new(connection: CraftTcpConnection) -> Self {
+ Self { connection }
+ }
+
+ pub fn from_stream(stream: TcpStream) -> anyhow::Result<Self> {
+ Ok(Self {
+ connection: CraftTcpConnection::from_std(stream, mcproto_rs::protocol::PacketDirection::ServerBound)?,
+ })
+ }
+ pub async fn read_next_packet(&mut self) -> Result<Option<Packet759>> {
+ if let Some(raw) = self.connection.read_packet::<RawPacket759>()? {
+ println!("Client -> Server: {:?}", raw);
+ Ok(Some(raw))
+ } else {
+ Ok(None)
+ }
+ }
+ pub async fn send_packet(&mut self, packet: Packet759) -> Result<()> {
+ self.connection.write_packet(packet)?;
+ Ok(())
+ }
+}
+
+macro_rules! assert_packet {
+ ($packet_type:ident, $obj:expr) => {if let Packet759::$packet_type(packet_data) = $obj { packet_data } else {panic!("Expected packet of type {}", stringify!($packet_type))}};
+}
+
+#[tokio::main]
+async fn main() -> Result<()> {
+ println!("Starting server");
+ let bind = TcpListener::bind(SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 25565))?;
+ loop {
+ if let Ok((socket, address)) = bind.accept() {
+ println!("Connection accepted from {}", address);
+ let mut client = MinecraftClient::from_stream(socket)?;
+ if let Err(x) = handle_conn(client).await {
+ println!("Error: {:?}", x);
+ }
+ }
+ }
+}
+
+async fn handle_conn(mut client: MinecraftClient) -> Result<()> {
+ let hs = assert_packet!(Handshake, client.read_next_packet().await?.ok_or(anyhow::anyhow!("Missing packet"))?);
+ println!("Hs: {:?}", hs);
+ if hs.next_state == HandshakeNextState::Login {
+ client.connection.set_state(State::Login);
+ let loginstart = assert_packet!(LoginStart, client.read_next_packet().await?.ok_or(anyhow::anyhow!("Missing packet"))?);
+ println!("Login: {:?}", loginstart)
+ } else {
+ client.connection.set_state(State::Status);
+ loop {
+ println!("Polling status packet");
+ match client.read_next_packet().await?.ok_or(anyhow::anyhow!("Missing packet"))? {
+ Packet759::StatusRequest(_) => {
+ client.send_packet(Packet759::StatusResponse(StatusResponseSpec {
+ response: StatusSpec {
+ version: Some(StatusVersionSpec { name: "1.19 mgasi".to_string(), protocol: 759 }),
+ players: StatusPlayersSpec {
+ max: 100,
+ online: 0,
+ sample: vec![],
+ },
+ description: Chat::from_text("hehehe"),
+ favicon: None,
+ },
+ })).await?;
+ }
+ Packet759::StatusPing(StatusPingSpec { payload }) => {
+ client.send_packet(Packet759::StatusPong(StatusPongSpec {
+ payload,
+ })).await?;
+ return Ok(())
+ }
+ _ => anyhow::bail!("")
+ }
+ }
+ }
+ Ok(())
+}
+