Skip to content

Commit

Permalink
clean up cli, add nbt decoding
Browse files Browse the repository at this point in the history
  • Loading branch information
nothendev committed Oct 1, 2023
1 parent 86cae2d commit a318e37
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 19 deletions.
34 changes: 30 additions & 4 deletions cli/src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
//! Spanned-clap, lol

use itertools::Itertools;
use std::{marker::PhantomData, path::PathBuf, str::FromStr};
use std::{borrow::Cow, marker::PhantomData, path::PathBuf, str::FromStr};

use aott::prelude::*;
use oxcr_protocol::{
aott::{
self, pfn_type,
text::{ascii::ident, digits, inline_whitespace, int, whitespace},
text::{ascii::ident, digits, inline_whitespace},
},
bytes::{BufMut, Bytes, BytesMut},
bytes::Bytes,
nbt::NbtTagType,
tracing::{level_filters::LevelFilter, Level},
};

Expand All @@ -33,6 +34,7 @@ pub enum CliCommand {
Help,
VarInt(ByteInput),
Decompress(ByteInput),
Nbt(NbtTagType, ByteInput),
}

#[derive(Debug, Clone)]
Expand All @@ -48,6 +50,7 @@ pub enum Flag {
Decode(ByteInput),
VarInt(ByteInput),
Decompress(ByteInput),
Nbt(NbtTagType, ByteInput),
}

#[derive(Debug)]
Expand Down Expand Up @@ -147,6 +150,28 @@ fn flags(input: &str) -> Vec<Flag> {
Flag::VarInt(byte_input(input)?)
}
FlagName::Short("h") | FlagName::Long("help") => Flag::Help,
FlagName::Short("n") | FlagName::Long("nbt") => {
one_of(" =")(input)?;
let before_nbt_tag = input.offset;

let nbt_tag = match ident(input)? {
"compound" => NbtTagType::Compound,
tag => {
return Err(ParseError::Expected {
expected: Expectation::AnyOfStr(vec!["compound"]),
found: tag.chars().next().expect("no tag at all"),
at: input.span_since(before_nbt_tag).into(),
help: Some(Cow::Borrowed("an NBT tag type is: Compound")),
})
}
};

just(",")(input)?;

inline_whitespace().check_with(input)?;

Flag::Nbt(nbt_tag, byte_input(input)?)
}
FlagName::Short(flag) | FlagName::Long(flag) => Err(ParseError::UnknownFlag {
flag: flag.to_owned(),
at: input.span_since(before).into(),
Expand All @@ -168,6 +193,7 @@ fn flags_handle<'a>(
Flag::Decode(input) => cli.command = CliCommand::Decode(input),
Flag::VarInt(input) => cli.command = CliCommand::VarInt(input),
Flag::Decompress(input) => cli.command = CliCommand::Decompress(input),
Flag::Nbt(tag, input) => cli.command = CliCommand::Nbt(tag, input),
}
}
try { flags(input)?.into_iter().for_each(|flag| handle(cli, flag)) }
Expand All @@ -177,7 +203,7 @@ fn flags_handle<'a>(
pub fn yay(input: &str) -> Cli {
try {
let mut cli = Cli {
level: LevelFilter::OFF,
level: LevelFilter::INFO,
command: CliCommand::Help,
};

Expand Down
2 changes: 2 additions & 0 deletions cli/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ pub enum ParseError {
pub enum Expectation {
#[error("{}", any_of(.0))]
AnyOf(Vec<char>),
#[error("{}", any_of(.0))]
AnyOfStr(Vec<&'static str>),
#[error("end of input")]
EndOfInput,
#[error("a digit with radix {_0}")]
Expand Down
42 changes: 28 additions & 14 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
#![allow(dead_code)]
#![feature(iterator_try_collect, try_blocks)]

use oxcr_protocol::{
aott::{self, prelude::Parser},
bytes::Bytes,
error::Error,
logging::CraftLayer,
miette::{self, bail, IntoDiagnostic, Report},
miette::{bail, IntoDiagnostic, Report},
model::{
packets::{play::LoginPlay, Packet, PacketContext, SerializedPacket},
packets::{play::LoginPlay, Packet, SerializedPacket},
VarInt,
},
ser::{BytesSource, Deserialize, Serialize, WithSource},
nbt::Nbt,
ser::{BytesSource, Deserialize, WithSource},
tracing::debug,
};
use tracing_subscriber::{
prelude::__tracing_subscriber_SubscriberExt, util::SubscriberInitExt, EnvFilter,
};

use crate::cli::{ByteInput, Cli, CliCommand};
use crate::cli::{ByteInput, CliCommand};

mod cli;
mod error;
Expand All @@ -39,7 +41,7 @@ fn run(_path: String, args: &str) -> Result<(), Report> {
.with(CraftLayer)
.set_default();

debug!("{:?}", cli);
debug!(%cli.level, ?cli.command);

match cli.command {
CliCommand::Help => help(),
Expand All @@ -62,7 +64,15 @@ fn run(_path: String, args: &str) -> Result<(), Report> {
.map_err(reconcile(bytes))?
);
}
CliCommand::Decompress(inp) => todo!(),
CliCommand::Nbt(tag, inp) => {
let bytes = read_byte_input(inp)?;
let nbt = Nbt::single
.parse_with_context(&bytes, tag)
.map_err(reconcile(bytes))?;

println!("{nbt:#?}");
}
CliCommand::Decompress(_inp) => todo!(),
};

Ok(())
Expand Down Expand Up @@ -111,16 +121,20 @@ fn main() -> Result<(), Report> {
fn help() {
println!(
r#"
This is the OxCraft CLI. Here you can serialize and deserialize packets (currently only LoginPlay).
This is the OxCraft CLI. Here you can serialize and deserialize packets (currently only LoginPlay) and NBT.
Example usage:
cargo run -p oxcr_cli -- -Dd 0xbd7d9a9f7e
This will turn on debug logging and deserialize LoginPlay from the data 0xbd7d etc.
Example usage:
cargo run -p oxcr_cli -- -Dd 0xbd7d9a9f7e
This will deserialize turn on debug logging and deserialize LoginPlay from the data 0xbd7d etc.
Clarifications:
<DATA> is either inline binary (0b...), octal (0o...), hexadecimal (0x...), or decimal data (0d...); or it could be a path like ./mydata.bin
Flags:
-l --level <LEVEL> what log level
-D --debug same as --level debug
-d --deserialize --decode <BINARY/OCTAL/HEX/DECIMAL (0d) DATA> deserializes a packet from <DATA>, then debug-logs it.
Flags:
-l --level <LEVEL> what log level (error, warn, info, debug, trace)
-D --debug same as --level debug
-d --deserialize --decode <DATA> deserializes a packet from <DATA>, then debug-logs it.
-n --nbt <TAG_TYPE>, <DATA> deserializes a <TAG_TYPE> from <DATA>. <TAG_TYPE> is (right now only) compound
"#
);
}
1 change: 0 additions & 1 deletion protocol/src/nbt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,6 @@ impl NbtTag {

#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[doc(hidden)]
pub enum NbtTagType {
End = 0,
Byte,
Expand Down

0 comments on commit a318e37

Please sign in to comment.