Skip to content

Commit

Permalink
Rework the ClientInfo XML parsing
Browse files Browse the repository at this point in the history
Reduced the XML libraries to one by using the maintained quick_xml crate.

Properly decodes the XML if it defines a custom encoding.
  • Loading branch information
hasenbanck committed Jan 4, 2025
1 parent d73a628 commit 74f1b4e
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 30 deletions.
28 changes: 13 additions & 15 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ chrono = "0.4"
cosmic-text = { version = "0.12", default-features = false }
cpal = "0.15"
derive-new = "0.7"
encoding_rs = "0.8"
etherparse = "0.16"
fast-srgb8 = "1"
flate2 = { version = "1", default-features = false }
Expand All @@ -31,6 +32,7 @@ option-ext = "0.2"
pcap = "2.2"
pollster = "0.4"
proc-macro2 = "1.0"
quick-xml = "0.37"
quote = "1.0"
ragnarok_bytes = { path = "ragnarok_bytes" }
ragnarok_formats = { path = "ragnarok_formats" }
Expand All @@ -42,14 +44,12 @@ rayon = "1.10"
reqwest = "0.12"
ron = "0.8"
serde = "1.0"
serde-xml-rs = "0.6"
spin_sleep = "1.3"
syn = "2.0"
tokio = { version = "1.42", default-features = false }
walkdir = "2.5"
wgpu = "23.0"
winit = "0.30"
xml-rs = "0.8"

[profile.dev.build-override]
opt-level = 3
Expand Down
4 changes: 2 additions & 2 deletions korangar/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ cgmath = { workspace = true, features = ["mint", "serde"] }
chrono = { workspace = true }
cosmic-text = { workspace = true, features = ["std", "fontconfig"] }
derive-new = { workspace = true }
encoding_rs = { workspace = true }
flate2 = { workspace = true, features = ["zlib-rs"] }
hashbrown = { workspace = true }
glidesort = { workspace = true }
Expand All @@ -25,6 +26,7 @@ mlua = { workspace = true, features = ["lua51", "vendored"] }
num = { workspace = true }
option-ext = { workspace = true }
pollster = { workspace = true }
quick-xml = { workspace = true, features = ["serde", "serialize"] }
ragnarok_bytes = { workspace = true, features = ["derive", "cgmath"] }
ragnarok_formats = { workspace = true, features = ["interface"] }
ragnarok_packets = { workspace = true, features = ["derive", "interface", "packet-to-prototype-element"] }
Expand All @@ -33,12 +35,10 @@ random_color = { workspace = true, optional = true }
rayon = { workspace = true }
ron = { workspace = true }
serde = { workspace = true }
serde-xml-rs = { workspace = true }
spin_sleep = { workspace = true }
walkdir = { workspace = true }
wgpu = { workspace = true }
winit = { workspace = true }
xml-rs = { workspace = true }

[features]
debug = ["korangar_debug", "korangar_audio/debug", "ragnarok_packets/debug", "random_color"]
Expand Down
45 changes: 34 additions & 11 deletions korangar/src/loaders/server/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
mod client_info;

use encoding_rs::Encoding;
#[cfg(feature = "debug")]
use korangar_debug::logging::Timer;
use korangar_util::FileLoader;
use quick_xml::de::from_str;
use quick_xml::events::Event;
use quick_xml::Reader;
use serde::{Deserialize, Serialize};
use serde_xml_rs::de::Deserializer;
use xml::reader::{EventReader, ParserConfig};

pub use self::client_info::ClientInfo;
use super::GameFileLoader;
Expand All @@ -17,23 +19,44 @@ pub fn load_client_info(game_file_loader: &GameFileLoader) -> ClientInfo {
#[cfg(feature = "debug")]
let timer = Timer::new("read clientinfo");

let clientinfo = game_file_loader
let client_info = game_file_loader
.get("data\\sclientinfo.xml")
.or_else(|_| game_file_loader.get("data\\clientinfo.xml"))
.expect("failed to find clientinfo");

let source = String::from_utf8(clientinfo).unwrap();
let content = match get_xml_encoding(&client_info) {
Some(encoding) => {
let (cow, ..) = encoding.decode(&client_info);
cow
}
None => String::from_utf8_lossy(client_info.as_slice()),
};

// TODO: Make it work with euc-kr, since it panics
// with error: "Unsupported encoding: euc-kr"
let replaced_source = source.replace("euc-kr", "utf8");

let config = ParserConfig::new().trim_whitespace(true);
let event_reader = EventReader::new_with_config(replaced_source.as_bytes(), config);
let client_info = ClientInfo::deserialize(&mut Deserializer::new(event_reader)).unwrap();
let client_info: ClientInfo = from_str(&content).unwrap();

#[cfg(feature = "debug")]
timer.stop();

client_info
}

fn get_xml_encoding(data: &[u8]) -> Option<&'static Encoding> {
let mut reader = Reader::from_reader(data);

let mut buffer = Vec::new();

loop {
match reader.read_event_into(&mut buffer) {
Ok(Event::Decl(xml_declaration)) => {
if let Some(Ok(encoding)) = xml_declaration.encoding() {
return Encoding::for_label(encoding.as_ref());
}
}
Ok(Event::Eof) | Err(_) => break,
_ => (),
}
buffer.clear();
}

None
}

0 comments on commit 74f1b4e

Please sign in to comment.