mirror of
https://github.com/acemod/arma3-wiki.git
synced 2025-12-23 14:10:16 +00:00
316 lines
11 KiB
Rust
316 lines
11 KiB
Rust
use std::{collections::HashMap, path::Path};
|
|
|
|
use arma3_wiki::model::{EventHandler, EventHandlerNamespace, ParsedEventHandler};
|
|
use arma3_wiki_github::report::Report;
|
|
use reqwest::Client;
|
|
|
|
use crate::WafSkip;
|
|
|
|
#[allow(clippy::too_many_lines, clippy::cognitive_complexity)]
|
|
pub async fn event_handlers(
|
|
client: &Client,
|
|
report: &mut Report,
|
|
dry_run: bool,
|
|
) -> HashMap<EventHandlerNamespace, Vec<EventHandler>> {
|
|
const URL: &str = "https://community.bistudio.com/wiki?title=Arma_3:_Event_Handlers&action=raw";
|
|
let tmp = std::env::temp_dir()
|
|
.join("arma3-wiki-fetch")
|
|
.join("eventhandler_main.html");
|
|
|
|
let body: String = if tmp.exists() {
|
|
std::fs::read_to_string(&tmp).unwrap()
|
|
} else {
|
|
let request = client.bi_get(URL).send().await.unwrap();
|
|
assert!(
|
|
request.status().is_success(),
|
|
"Failed to fetch event handlers list"
|
|
);
|
|
let content = request.text().await.unwrap();
|
|
std::fs::write(&tmp, &content).unwrap();
|
|
content
|
|
};
|
|
|
|
println!("Body length: {}", body.len());
|
|
|
|
let mut event_handlers: HashMap<EventHandlerNamespace, Vec<EventHandler>> = HashMap::new();
|
|
|
|
let mut section = None;
|
|
let mut recording = false;
|
|
let mut buffer = String::new();
|
|
|
|
let lines = body.lines();
|
|
|
|
let headings = vec![
|
|
(EventHandlerNamespace::Standard, "=== Standard ==="),
|
|
(
|
|
EventHandlerNamespace::Multiplayer,
|
|
"== Multiplayer Event Handlers ==",
|
|
),
|
|
(
|
|
EventHandlerNamespace::Mission,
|
|
"== Mission Event Handlers ==",
|
|
),
|
|
(
|
|
EventHandlerNamespace::UserAction,
|
|
"{{ArgTitle|2|UserAction Event Handlers|{{GVI|arma3|2.06}}}}",
|
|
),
|
|
(
|
|
EventHandlerNamespace::Projectile,
|
|
"{{ArgTitle|2|Projectile Event Handlers|{{GVI|arma3|2.10}}}}",
|
|
),
|
|
(
|
|
EventHandlerNamespace::Group,
|
|
"{{ArgTitle|2|Group Event Handlers|{{GVI|arma3|2.10}}}}",
|
|
),
|
|
(
|
|
EventHandlerNamespace::UserInterface,
|
|
"== UI Event Handlers (Displays and Controls) ==",
|
|
),
|
|
(EventHandlerNamespace::Music, "== Music Event Handlers =="),
|
|
(EventHandlerNamespace::Eden, "== Eden Editor =="),
|
|
];
|
|
|
|
'line: for line in lines {
|
|
match section {
|
|
None => {
|
|
if line == "=== Standard ===" {
|
|
section = Some(EventHandlerNamespace::Standard);
|
|
}
|
|
}
|
|
Some(ns) => {
|
|
for (ns, heading) in &headings {
|
|
if &line == heading {
|
|
section = Some(*ns);
|
|
recording = false;
|
|
if !buffer.is_empty() && !buffer.contains("{{ConfigPage|abc}}") {
|
|
match ParsedEventHandler::from_wiki(&buffer) {
|
|
Ok(event_handler) => {
|
|
event_handlers
|
|
.entry(*ns)
|
|
.or_default()
|
|
.push(EventHandler::Parsed(event_handler));
|
|
}
|
|
Err((name, e)) => {
|
|
eprintln!("Failed to parse event handler: {e}");
|
|
event_handlers
|
|
.entry(*ns)
|
|
.or_default()
|
|
.push(EventHandler::Failed(name, e));
|
|
}
|
|
}
|
|
}
|
|
buffer.clear();
|
|
continue 'line;
|
|
}
|
|
}
|
|
|
|
if line.starts_with("===")
|
|
|| line.starts_with("{{ArgTitle|4|")
|
|
|| line.starts_with("{{ConfigPage|end}}")
|
|
{
|
|
if recording {
|
|
match ParsedEventHandler::from_wiki(&buffer) {
|
|
Ok(event_handler) => {
|
|
event_handlers
|
|
.entry(ns)
|
|
.or_default()
|
|
.push(EventHandler::Parsed(event_handler));
|
|
}
|
|
Err((name, e)) => {
|
|
eprintln!("Failed to parse event handler: {e}");
|
|
event_handlers
|
|
.entry(ns)
|
|
.or_default()
|
|
.push(EventHandler::Failed(name, e));
|
|
}
|
|
}
|
|
}
|
|
buffer.clear();
|
|
recording = line.starts_with("====") || line.starts_with("{{ArgTitle|4|");
|
|
}
|
|
|
|
if recording {
|
|
buffer.push_str(line);
|
|
buffer.push('\n');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
event_handlers.insert(
|
|
EventHandlerNamespace::Eden,
|
|
subsection(
|
|
client,
|
|
"https://community.bistudio.com/wiki/Arma_3:_Eden_Editor_Event_Handlers?action=raw",
|
|
"eden",
|
|
None,
|
|
Some("== Object Event Handlers ==".to_owned()),
|
|
)
|
|
.await,
|
|
);
|
|
event_handlers.insert(
|
|
EventHandlerNamespace::Standard,
|
|
subsection(
|
|
client,
|
|
"https://community.bistudio.com/wiki/Arma_3:_Eden_Editor_Event_Handlers?action=raw",
|
|
"eden",
|
|
Some("== Object Event Handlers ==".to_owned()),
|
|
None,
|
|
)
|
|
.await,
|
|
);
|
|
event_handlers.insert(
|
|
EventHandlerNamespace::UserInterface,
|
|
subsection(
|
|
client,
|
|
"https://community.bistudio.com/wiki/User_Interface_Event_Handlers?action=raw",
|
|
"ui",
|
|
None,
|
|
None,
|
|
)
|
|
.await
|
|
.into_iter()
|
|
.map(|eh| match eh {
|
|
EventHandler::Parsed(mut eh) => {
|
|
eh.set_id(eh.id().trim_start_matches("on").to_string());
|
|
EventHandler::Parsed(eh)
|
|
}
|
|
EventHandler::Failed(name, e) => EventHandler::Failed(name, e),
|
|
})
|
|
.collect(),
|
|
);
|
|
event_handlers.insert(
|
|
EventHandlerNamespace::Mission,
|
|
subsection(
|
|
client,
|
|
"https://community.bistudio.com/wiki/Arma_3:_Mission_Event_Handlers?action=raw",
|
|
"mission",
|
|
None,
|
|
None,
|
|
)
|
|
.await,
|
|
);
|
|
|
|
for (ns, handlers) in &event_handlers {
|
|
for handler in handlers {
|
|
match &handler {
|
|
EventHandler::Failed(_, _) => {
|
|
report.add_failed_event_handler(*ns, handler.clone());
|
|
}
|
|
EventHandler::Parsed(handler) => {
|
|
let mut dist_path = Path::new("./dist/events")
|
|
.join(urlencoding::encode(&ns.to_string()).to_string())
|
|
.join(handler.id());
|
|
dist_path.set_extension("yml");
|
|
let mut write = true;
|
|
if dist_path.exists() {
|
|
// Check if the file has changed
|
|
let old = std::fs::read_to_string(&dist_path).unwrap();
|
|
if old == serde_yaml::to_string(&handler).unwrap() {
|
|
write = false;
|
|
report.add_outdated_event_handler(*ns, handler.clone());
|
|
}
|
|
}
|
|
if write {
|
|
report.add_passed_event_handler(*ns, handler.clone());
|
|
}
|
|
if !dry_run && write {
|
|
if !dist_path.parent().expect("parent").exists() {
|
|
std::fs::create_dir_all(dist_path.parent().expect("parent")).unwrap();
|
|
}
|
|
let mut file = tokio::fs::File::create(dist_path).await.unwrap();
|
|
tokio::io::AsyncWriteExt::write_all(
|
|
&mut file,
|
|
serde_yaml::to_string(&handler).unwrap().as_bytes(),
|
|
)
|
|
.await
|
|
.unwrap();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
event_handlers
|
|
}
|
|
|
|
async fn subsection(
|
|
client: &Client,
|
|
url: &str,
|
|
tag: &str,
|
|
get_from: Option<String>,
|
|
get_to: Option<String>,
|
|
) -> Vec<EventHandler> {
|
|
let tmp = std::env::temp_dir()
|
|
.join("arma3-wiki-fetch")
|
|
.join(format!("eventhandler_{tag}.html"));
|
|
|
|
let mut body: String = if tmp.exists() {
|
|
std::fs::read_to_string(&tmp).unwrap()
|
|
} else {
|
|
let request = client.bi_get(url).send().await.unwrap();
|
|
assert!(
|
|
request.status().is_success(),
|
|
"Failed to fetch event handlers list"
|
|
);
|
|
let content = request.text().await.unwrap();
|
|
std::fs::write(&tmp, &content).unwrap();
|
|
content
|
|
};
|
|
|
|
if let Some(from) = get_from {
|
|
if let Some((_, rest)) = body.split_once(&from) {
|
|
body = rest.to_owned();
|
|
}
|
|
}
|
|
if let Some(to) = get_to {
|
|
if let Some((rest, _)) = body.split_once(&to) {
|
|
body = rest.to_owned();
|
|
}
|
|
}
|
|
|
|
let mut event_handlers = Vec::new();
|
|
|
|
let mut recording = false;
|
|
let mut buffer = String::new();
|
|
|
|
for line in body.lines() {
|
|
if line.starts_with("===")
|
|
|| line.starts_with("{{ArgTitle|4|")
|
|
|| line.starts_with("{{ConfigPage|end}}")
|
|
{
|
|
if recording {
|
|
match ParsedEventHandler::from_wiki(&buffer) {
|
|
Ok(event_handler) => {
|
|
event_handlers.push(EventHandler::Parsed(event_handler));
|
|
}
|
|
Err((name, e)) => {
|
|
eprintln!("Failed to parse event handler: {e}");
|
|
event_handlers.push(EventHandler::Failed(name, e));
|
|
}
|
|
}
|
|
buffer.clear();
|
|
}
|
|
recording = line.starts_with("====") || line.starts_with("{{ArgTitle|4|");
|
|
}
|
|
if recording {
|
|
buffer.push_str(line);
|
|
buffer.push('\n');
|
|
}
|
|
}
|
|
|
|
if !buffer.is_empty() {
|
|
match ParsedEventHandler::from_wiki(&buffer) {
|
|
Ok(event_handler) => {
|
|
event_handlers.push(EventHandler::Parsed(event_handler));
|
|
}
|
|
Err((name, e)) => {
|
|
eprintln!("Failed to parse event handler: {e}");
|
|
event_handlers.push(EventHandler::Failed(name, e));
|
|
}
|
|
}
|
|
}
|
|
|
|
event_handlers
|
|
}
|