Parse vanilla to LogMeta
This commit is contained in:
@@ -11,11 +11,13 @@ license = "MIT"
|
||||
publish = false
|
||||
|
||||
[features]
|
||||
default = ["core", "events"]
|
||||
default = ["core", "events", "mc-vanilla"]
|
||||
# Core runtime requirements for the currently implemented functionality.
|
||||
core = ["dep:thiserror", "dep:tokio", "dep:tokio-stream", "dep:tokio-util"]
|
||||
# Placeholder for upcoming event-driven functionality.
|
||||
events = []
|
||||
|
||||
mc-vanilla = []
|
||||
# Add new feature groups here; attach their optional dependencies to the relevant feature list.
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
pub mod stream;
|
||||
pub mod version;
|
||||
|
||||
pub use stream::{StreamLine, StreamSource};
|
||||
pub use stream::{LogMeta, StreamLine, StreamSource};
|
||||
pub use version::{MinecraftType, MinecraftVersion, Snapshot, Version};
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
use std::fmt::{self, Display};
|
||||
|
||||
#[cfg(feature = "mc-vanilla")]
|
||||
use crate::error::ParserError;
|
||||
|
||||
/// Identifies which process stream produced a line of output.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum StreamSource {
|
||||
@@ -22,6 +25,101 @@ pub struct InstanceEvent {}
|
||||
#[cfg(feature = "events")]
|
||||
pub enum Events {}
|
||||
|
||||
#[cfg(feature = "mc-vanilla")]
|
||||
pub struct LogMeta {
|
||||
time: String,
|
||||
thread: String,
|
||||
level: LogLevel,
|
||||
msg: String,
|
||||
}
|
||||
|
||||
#[cfg(feature = "mc-vanilla")]
|
||||
pub enum LogLevel {
|
||||
Info,
|
||||
Warn,
|
||||
Error,
|
||||
Other,
|
||||
}
|
||||
|
||||
#[cfg(feature = "mc-vanilla")]
|
||||
impl LogMeta {
|
||||
pub fn new<S: Into<String>>(line: S) -> Result<Option<Self>, ParserError> {
|
||||
let line: String = line.into();
|
||||
let line = line.trim();
|
||||
|
||||
if !line.starts_with('[') {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let time_end = match line.find(']') {
|
||||
Some(i) => i,
|
||||
None => return Ok(None),
|
||||
};
|
||||
let time = line[1..time_end].to_string();
|
||||
|
||||
let meta_start = match line[time_end + 1..].find('[') {
|
||||
Some(j) => time_end + 1 + j,
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
let msg_sep = match line[meta_start..].find("]: ") {
|
||||
Some(k) => meta_start + k,
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
let meta = &line[(meta_start + 1)..msg_sep]; // inside the brackets
|
||||
let msg = line[(msg_sep + 3)..].to_string(); // after "]: "
|
||||
|
||||
let mut thread_level = meta.splitn(2, '/');
|
||||
let thread = thread_level
|
||||
.next()
|
||||
.ok_or(ParserError::ParserError)?
|
||||
.to_string();
|
||||
let level_str = thread_level
|
||||
.next()
|
||||
.ok_or(ParserError::ParserError)?
|
||||
.trim_end_matches(']'); // just in case
|
||||
|
||||
let level = match level_str {
|
||||
"INFO" => LogLevel::Info,
|
||||
"WARN" => LogLevel::Warn,
|
||||
"ERROR" => LogLevel::Error,
|
||||
_ => LogLevel::Other,
|
||||
};
|
||||
|
||||
Ok(Some(LogMeta {
|
||||
time,
|
||||
thread,
|
||||
level,
|
||||
msg,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "mc-vanilla")]
|
||||
impl Display for LogMeta {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let line = format!(
|
||||
"Time: {}\nThread: {}\nLevel: {}\nMessage: {}",
|
||||
self.time, self.thread, self.level, self.msg
|
||||
);
|
||||
|
||||
write!(f, "{}", line)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "mc-vanilla")]
|
||||
impl Display for LogLevel {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
LogLevel::Info => write!(f, "INFO"),
|
||||
LogLevel::Warn => write!(f, "WARN"),
|
||||
LogLevel::Error => write!(f, "ERROR"),
|
||||
LogLevel::Other => write!(f, "OTHER"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StreamLine {
|
||||
pub fn new<S: Into<String>>(line: S, source: StreamSource) -> Self {
|
||||
Self {
|
||||
@@ -43,6 +141,10 @@ impl StreamLine {
|
||||
source: StreamSource::Stderr,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn msg(&self) -> String {
|
||||
self.line.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for StreamLine {
|
||||
|
||||
@@ -92,3 +92,10 @@ pub enum ServerError {
|
||||
#[error("Failed to write to stdin")]
|
||||
StdinWriteFailed,
|
||||
}
|
||||
|
||||
#[cfg(feature = "events")]
|
||||
#[derive(Debug, Clone, Error)]
|
||||
pub enum ParserError {
|
||||
#[error("ParserError")]
|
||||
ParserError,
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ impl InstanceHandle {
|
||||
root_dir: root,
|
||||
jar_path: path,
|
||||
mc_version: parsed_version,
|
||||
mc_type: mc_type,
|
||||
mc_type,
|
||||
};
|
||||
|
||||
let status = InstanceStatus::Stopped;
|
||||
@@ -248,14 +248,18 @@ impl InstanceHandle {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "events")]
|
||||
#[cfg(all(feature = "events", any(feature = "mc-vanilla")))]
|
||||
fn setup_parser(&mut self) -> Result<(), ServerError> {
|
||||
let stdout_stream = self
|
||||
.subscribe(StreamSource::Stdout)
|
||||
.map_err(|_| ServerError::NoStdoutPipe)?;
|
||||
let shutdown = self.shutdown.clone();
|
||||
let event_tx = self.events_tx.clone();
|
||||
// TODO: Stream events!!!!
|
||||
let _event_tx = self.events_tx.clone();
|
||||
|
||||
#[cfg(feature = "mc-vanilla")]
|
||||
if self.data.mc_type == MinecraftType::Vanilla {
|
||||
use crate::config::LogMeta;
|
||||
tokio::spawn(async move {
|
||||
let mut rx = stdout_stream;
|
||||
|
||||
@@ -266,7 +270,18 @@ impl InstanceHandle {
|
||||
}
|
||||
line = rx.next() => {
|
||||
match line {
|
||||
Some(Ok(_)) => {
|
||||
Some(Ok(val)) => {
|
||||
let msg = val.msg();
|
||||
let meta = LogMeta::new(msg);
|
||||
match meta {
|
||||
Ok(val) => {
|
||||
if val.is_some() {
|
||||
println!("{}", val.unwrap());
|
||||
}
|
||||
}
|
||||
Err(_) => (),
|
||||
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
@@ -274,6 +289,7 @@ impl InstanceHandle {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user