Parse vanilla to LogMeta
This commit is contained in:
@@ -11,11 +11,13 @@ license = "MIT"
|
|||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["core", "events"]
|
default = ["core", "events", "mc-vanilla"]
|
||||||
# Core runtime requirements for the currently implemented functionality.
|
# Core runtime requirements for the currently implemented functionality.
|
||||||
core = ["dep:thiserror", "dep:tokio", "dep:tokio-stream", "dep:tokio-util"]
|
core = ["dep:thiserror", "dep:tokio", "dep:tokio-stream", "dep:tokio-util"]
|
||||||
# Placeholder for upcoming event-driven functionality.
|
# Placeholder for upcoming event-driven functionality.
|
||||||
events = []
|
events = []
|
||||||
|
|
||||||
|
mc-vanilla = []
|
||||||
# Add new feature groups here; attach their optional dependencies to the relevant feature list.
|
# Add new feature groups here; attach their optional dependencies to the relevant feature list.
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
pub mod stream;
|
pub mod stream;
|
||||||
pub mod version;
|
pub mod version;
|
||||||
|
|
||||||
pub use stream::{StreamLine, StreamSource};
|
pub use stream::{LogMeta, StreamLine, StreamSource};
|
||||||
pub use version::{MinecraftType, MinecraftVersion, Snapshot, Version};
|
pub use version::{MinecraftType, MinecraftVersion, Snapshot, Version};
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
use std::fmt::{self, Display};
|
use std::fmt::{self, Display};
|
||||||
|
|
||||||
|
#[cfg(feature = "mc-vanilla")]
|
||||||
|
use crate::error::ParserError;
|
||||||
|
|
||||||
/// Identifies which process stream produced a line of output.
|
/// Identifies which process stream produced a line of output.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum StreamSource {
|
pub enum StreamSource {
|
||||||
@@ -22,6 +25,101 @@ pub struct InstanceEvent {}
|
|||||||
#[cfg(feature = "events")]
|
#[cfg(feature = "events")]
|
||||||
pub enum 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 {
|
impl StreamLine {
|
||||||
pub fn new<S: Into<String>>(line: S, source: StreamSource) -> Self {
|
pub fn new<S: Into<String>>(line: S, source: StreamSource) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -43,6 +141,10 @@ impl StreamLine {
|
|||||||
source: StreamSource::Stderr,
|
source: StreamSource::Stderr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn msg(&self) -> String {
|
||||||
|
self.line.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for StreamLine {
|
impl Display for StreamLine {
|
||||||
|
|||||||
@@ -92,3 +92,10 @@ pub enum ServerError {
|
|||||||
#[error("Failed to write to stdin")]
|
#[error("Failed to write to stdin")]
|
||||||
StdinWriteFailed,
|
StdinWriteFailed,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "events")]
|
||||||
|
#[derive(Debug, Clone, Error)]
|
||||||
|
pub enum ParserError {
|
||||||
|
#[error("ParserError")]
|
||||||
|
ParserError,
|
||||||
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ impl InstanceHandle {
|
|||||||
root_dir: root,
|
root_dir: root,
|
||||||
jar_path: path,
|
jar_path: path,
|
||||||
mc_version: parsed_version,
|
mc_version: parsed_version,
|
||||||
mc_type: mc_type,
|
mc_type,
|
||||||
};
|
};
|
||||||
|
|
||||||
let status = InstanceStatus::Stopped;
|
let status = InstanceStatus::Stopped;
|
||||||
@@ -248,32 +248,48 @@ impl InstanceHandle {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "events")]
|
#[cfg(all(feature = "events", any(feature = "mc-vanilla")))]
|
||||||
fn setup_parser(&mut self) -> Result<(), ServerError> {
|
fn setup_parser(&mut self) -> Result<(), ServerError> {
|
||||||
let stdout_stream = self
|
let stdout_stream = self
|
||||||
.subscribe(StreamSource::Stdout)
|
.subscribe(StreamSource::Stdout)
|
||||||
.map_err(|_| ServerError::NoStdoutPipe)?;
|
.map_err(|_| ServerError::NoStdoutPipe)?;
|
||||||
let shutdown = self.shutdown.clone();
|
let shutdown = self.shutdown.clone();
|
||||||
let event_tx = self.events_tx.clone();
|
// TODO: Stream events!!!!
|
||||||
|
let _event_tx = self.events_tx.clone();
|
||||||
|
|
||||||
tokio::spawn(async move {
|
#[cfg(feature = "mc-vanilla")]
|
||||||
let mut rx = stdout_stream;
|
if self.data.mc_type == MinecraftType::Vanilla {
|
||||||
|
use crate::config::LogMeta;
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let mut rx = stdout_stream;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = shutdown.cancelled() => {
|
_ = shutdown.cancelled() => {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
line = rx.next() => {
|
line = rx.next() => {
|
||||||
match line {
|
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(_) => (),
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user