From a86bbfe0a9c7eb65d4d1f79cea9ae253485e1b75 Mon Sep 17 00:00:00 2001 From: seth Date: Tue, 12 Dec 2023 15:55:04 -0500 Subject: [PATCH] analyze_logs: detect outdated launchers --- src/handlers/event/analyze_logs/issues.rs | 137 ++++++++++++++-------- src/handlers/event/analyze_logs/mod.rs | 6 +- src/handlers/event/mod.rs | 2 +- src/storage/mod.rs | 21 +++- 4 files changed, 115 insertions(+), 51 deletions(-) diff --git a/src/handlers/event/analyze_logs/issues.rs b/src/handlers/event/analyze_logs/issues.rs index 8ea65f1..77acb2b 100644 --- a/src/handlers/event/analyze_logs/issues.rs +++ b/src/handlers/event/analyze_logs/issues.rs @@ -1,23 +1,33 @@ +use crate::Data; + +use color_eyre::eyre::Result; use once_cell::sync::Lazy; use regex::Regex; pub type Issue = Option<(String, String)>; -pub fn find_issues(log: &str) -> Vec<(String, String)> { +pub async fn find_issues(log: &str, data: &Data) -> Result> { let issues = [ - wrong_java, + fabric_internal, flatpak_nvidia, forge_java, intel_hd, - macos_ns, - fabric_internal, - oom, - optinotfine, java_option, lwjgl_2_java_9, + macos_ns, + oom, + optinotfine, pre_1_12_native_transport_java_9, + wrong_java, ]; - issues.iter().filter_map(|issue| issue(log)).collect() + + let mut res: Vec<(String, String)> = issues.iter().filter_map(|issue| issue(log)).collect(); + + if let Some(issues) = outdated_launcher(log, data).await? { + res.push(issues) + } + + Ok(res) } fn fabric_internal(log: &str) -> Issue { @@ -117,6 +127,21 @@ fn java_option(log: &str) -> Issue { None } +fn lwjgl_2_java_9(log: &str) -> Issue { + let issue = ( + "Linux: crash with pre-1.13 and Java 9+".to_string(), + "Using pre-1.13 (which uses LWJGL 2) with Java 9 or later usually causes a crash. \ + Switching to Java 8 or below will fix your issue. + Alternatively, you can use [Temurin](https://adoptium.net/temurin/releases). \ + However, multiplayer will not work in versions from 1.8 to 1.11. + For more information, type `/tag java`." + .to_string(), + ); + + let found = log.contains("check_match: Assertion `version->filename == NULL || ! _dl_name_match_p (version->filename, map)' failed!"); + found.then_some(issue) +} + fn macos_ns(log: &str) -> Issue { let issue = ( "MacOS NSInternalInconsistencyException".to_string(), @@ -151,9 +176,64 @@ fn optinotfine(log: &str) -> Issue { found.then_some(issue) } -// TODO: @TheKodeToad -fn outdated_launcher(_log: &str) -> Issue { - todo!() +async fn outdated_launcher(log: &str, data: &Data) -> Result { + static OUTDATED_LAUNCHER_REGEX: Lazy = + Lazy::new(|| Regex::new("Prism Launcher version: [0-9].[0-9].[0-9]").unwrap()); + + let Some(captures) = OUTDATED_LAUNCHER_REGEX.captures(log) else { + return Ok(None); + }; + + let version_from_log = captures[0].replace("Prism Launcher version: ", ""); + + let storage = &data.storage; + let latest_version = if storage.launcher_version_is_cached().await? { + storage.get_launcher_version().await? + } else { + let version = data + .octocrab + .repos("PrismLauncher", "PrismLauncher") + .releases() + .get_latest() + .await? + .tag_name; + + storage.cache_launcher_version(&version).await?; + version + }; + + if version_from_log < latest_version { + let issue = ( + "Outdated Prism Launcher".to_string(), + format!("Your installed version is {version_from_log}, while the newest version is {latest_version}.\nPlease update, for more info see https://prismlauncher.org/download/") + ); + + Ok(Some(issue)) + } else { + Ok(None) + } +} + +fn pre_1_12_native_transport_java_9(log: &str) -> Issue { + let issue = ( + "Linux: broken multiplayer with 1.8-1.11 and Java 9+".to_string(), + "These versions of Minecraft use an outdated version of Netty which does not properly support Java 9. + +Switching to Java 8 or below will fix this issue. For more information, type `/tag java`. + +If you must use a newer version, do the following: +- Open `options.txt` (in the main window Edit -> Open .minecraft) and change. +- Find `useNativeTransport:true` and change it to `useNativeTransport:false`. +Note: whilst Netty was introduced in 1.7, this option did not exist \ +which is why the issue was not present." + .to_string(), + ); + + let found = log.contains( + "java.lang.RuntimeException: Unable to access address of buffer\n\tat io.netty.channel.epoll" + ); + + found.then_some(issue) } fn wrong_java(log: &str) -> Issue { @@ -179,40 +259,3 @@ fn wrong_java(log: &str) -> Issue { log.contains("Java major version is incompatible. Things might break.") .then_some(issue) } - -fn lwjgl_2_java_9(log: &str) -> Issue { - let issue = ( - "Linux: crash with pre-1.13 and Java 9+".to_string(), - "Using pre-1.13 (which uses LWJGL 2) with Java 9 or later usually causes a crash. \ - Switching to Java 8 or below will fix your issue. - Alternatively, you can use [Temurin](https://adoptium.net/temurin/releases). \ - However, multiplayer will not work in versions from 1.8 to 1.11. - For more information, type `/tag java`." - .to_string(), - ); - - let found = log.contains("check_match: Assertion `version->filename == NULL || ! _dl_name_match_p (version->filename, map)' failed!"); - found.then_some(issue) -} - -fn pre_1_12_native_transport_java_9(log: &str) -> Issue { - let issue = ( - "Linux: broken multiplayer with 1.8-1.11 and Java 9+".to_string(), - "These versions of Minecraft use an outdated version of Netty which does not properly support Java 9. - -Switching to Java 8 or below will fix this issue. For more information, type `/tag java`. - -If you must use a newer version, do the following: -- Open `options.txt` (in the main window Edit -> Open .minecraft) and change. -- Find `useNativeTransport:true` and change it to `useNativeTransport:false`. -Note: whilst Netty was introduced in 1.7, this option did not exist \ -which is why the issue was not present." - .to_string(), - ); - - let found = log.contains( - "java.lang.RuntimeException: Unable to access address of buffer\n\tat io.netty.channel.epoll" - ); - - found.then_some(issue) -} diff --git a/src/handlers/event/analyze_logs/mod.rs b/src/handlers/event/analyze_logs/mod.rs index 74b0c85..0e12127 100644 --- a/src/handlers/event/analyze_logs/mod.rs +++ b/src/handlers/event/analyze_logs/mod.rs @@ -1,4 +1,6 @@ use crate::consts::COLORS; +use crate::Data; + use color_eyre::eyre::Result; use log::*; use poise::serenity_prelude::{Context, Message}; @@ -9,7 +11,7 @@ mod providers; use issues::find_issues; use providers::find_log; -pub async fn handle(ctx: &Context, message: &Message) -> Result<()> { +pub async fn handle(ctx: &Context, message: &Message, data: &Data) -> Result<()> { let channel = message.channel_id; let log = find_log(message).await; @@ -34,7 +36,7 @@ pub async fn handle(ctx: &Context, message: &Message) -> Result<()> { return Ok(()); }; - let issues = find_issues(&log); + let issues = find_issues(&log, data).await?; channel .send_message(ctx, |m| { diff --git a/src/handlers/event/mod.rs b/src/handlers/event/mod.rs index 660b1da..a0db8c2 100644 --- a/src/handlers/event/mod.rs +++ b/src/handlers/event/mod.rs @@ -53,7 +53,7 @@ pub async fn handle( eta::handle(ctx, new_message).await?; expand_link::handle(ctx, new_message).await?; - analyze_logs::handle(ctx, new_message).await?; + analyze_logs::handle(ctx, new_message, data).await?; } Event::MessageDelete { diff --git a/src/storage/mod.rs b/src/storage/mod.rs index 88f9544..3f0d419 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -8,7 +8,8 @@ use redis::{AsyncCommands as _, Client, FromRedisValue, ToRedisArgs}; pub mod message_logger; use message_logger::*; -pub const PK_KEY: &str = "pluralkit-v1"; +const PK_KEY: &str = "pluralkit-v1"; +const LAUNCHER_VERSION_KEY: &str = "launcher-version-v1"; #[derive(Clone, Debug)] pub struct Storage { @@ -134,4 +135,22 @@ impl Storage { Ok(()) } + + pub async fn cache_launcher_version(&self, version: &str) -> Result<()> { + self.set_key(LAUNCHER_VERSION_KEY, version).await?; + + Ok(()) + } + + pub async fn get_launcher_version(&self) -> Result { + let res = self.get_key(LAUNCHER_VERSION_KEY).await?; + + Ok(res) + } + + pub async fn launcher_version_is_cached(&self) -> Result { + let res = self.key_exists(LAUNCHER_VERSION_KEY).await?; + + Ok(res) + } }