aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src-tauri/bindings/ParsedLogResults.ts4
-rw-r--r--src-tauri/bindings/ParsedModFromLog.ts3
-rw-r--r--src-tauri/src/main.rs3
-rw-r--r--src-tauri/src/repair_and_verify/log_handling.rs117
-rw-r--r--src-tauri/src/repair_and_verify/mod.rs2
-rw-r--r--src-vue/src/views/DeveloperView.vue66
6 files changed, 194 insertions, 1 deletions
diff --git a/src-tauri/bindings/ParsedLogResults.ts b/src-tauri/bindings/ParsedLogResults.ts
new file mode 100644
index 00000000..6ae3c0ad
--- /dev/null
+++ b/src-tauri/bindings/ParsedLogResults.ts
@@ -0,0 +1,4 @@
+// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
+import type { ParsedModFromLog } from "./ParsedModFromLog";
+
+export interface ParsedLogResults { northstar_launcher_version: string, installed_mods: Array<ParsedModFromLog>, has_northstar_crashed: boolean, } \ No newline at end of file
diff --git a/src-tauri/bindings/ParsedModFromLog.ts b/src-tauri/bindings/ParsedModFromLog.ts
new file mode 100644
index 00000000..f71ed83d
--- /dev/null
+++ b/src-tauri/bindings/ParsedModFromLog.ts
@@ -0,0 +1,3 @@
+// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
+
+export interface ParsedModFromLog { mod_name: string, enabled: boolean, } \ No newline at end of file
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index ba9264ee..ce7708b1 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -37,6 +37,8 @@ use tauri::Manager;
use tauri_plugin_store::PluginBuilder;
use tokio::time::sleep;
+use crate::repair_and_verify::log_handling::parse_given_log_text;
+
#[derive(Default)]
struct Counter(Arc<Mutex<i32>>);
@@ -110,6 +112,7 @@ fn main() {
delete_northstar_mod,
get_server_player_count,
delete_thunderstore_mod,
+ parse_given_log_text,
])
.run(tauri::generate_context!())
.expect("error while running tauri application");
diff --git a/src-tauri/src/repair_and_verify/log_handling.rs b/src-tauri/src/repair_and_verify/log_handling.rs
new file mode 100644
index 00000000..2cbc4ae6
--- /dev/null
+++ b/src-tauri/src/repair_and_verify/log_handling.rs
@@ -0,0 +1,117 @@
+use regex::Regex;
+use serde::{Deserialize, Serialize};
+use ts_rs::TS;
+
+#[derive(Serialize, Deserialize, Debug, Clone, TS)]
+#[ts(export)]
+pub struct ParsedModFromLog {
+ mod_name: String,
+ enabled: bool,
+}
+
+#[derive(Serialize, Deserialize, Debug, Clone, TS)]
+#[ts(export)]
+pub struct ParsedLogResults {
+ northstar_launcher_version: String,
+ installed_mods: Vec<ParsedModFromLog>,
+ has_northstar_crashed: bool,
+}
+
+/// Parse logs for installed mods
+fn parse_given_log_text_for_installed_mods(
+ log_text: String,
+) -> Result<Vec<ParsedModFromLog>, String> {
+ // Regex to capture mod loading and whether enabled/disabled
+ let regex = Regex::new(r"(?m)Loaded mod (.*) successfully\n.*\[NORTHSTAR\] \[info\] Mod (.*) is (enabled|disabled)\n").unwrap();
+
+ // Run regex, result will be an iterator over tuples containing the start and end indices for each match in the string
+ let result = regex.captures_iter(&log_text);
+
+ let mut mods = Vec::new();
+ for mat in result {
+ // Get the captured string, which is the first and only capturing group in the regex
+ let mod_name = match mat.get(1) {
+ Some(mod_name) => mod_name.as_str().to_string(),
+ None => {
+ println!("Failed parsing {:?}", mat); // log on failure
+ continue;
+ }
+ };
+ let mod_name_copy = match mat.get(2) {
+ Some(mod_name) => mod_name.as_str().to_string(),
+ None => {
+ println!("Failed parsing {:?}", mat); // log on failure
+ continue;
+ }
+ };
+ let enabled_disabled = match mat.get(3) {
+ Some(mod_name) => mod_name.as_str().to_string(),
+ None => {
+ println!("Failed parsing {:?}", mat); // log on failure
+ continue;
+ }
+ };
+ println!("{}, {}, {}", mod_name, mod_name_copy, enabled_disabled);
+ if mod_name != mod_name_copy {
+ return Err("Mod names don't match up".to_string());
+ }
+
+ // TODO improve checking
+ let mod_enabled;
+ if enabled_disabled == "enabled" {
+ mod_enabled = true;
+ } else {
+ mod_enabled = false;
+ }
+
+ let parsed_mod_from_log = ParsedModFromLog {
+ mod_name,
+ enabled: mod_enabled,
+ };
+
+ // Add mod to list
+ mods.push(parsed_mod_from_log);
+ }
+
+ // Return the captured mod names
+ return Ok(mods);
+}
+
+/// Parse logs for Northstar launcher version
+fn parse_for_northstar_launcher_version(log_text: String) -> Result<String, String> {
+ let regex = Regex::new(r"(?m)NorthstarLauncher version: (.*)\n").unwrap();
+
+ // result will be an iterator over tuples containing the start and end indices for each match in the string
+ let mut result = regex.captures_iter(&log_text);
+
+ // Return found Northstar launcher version number
+ match result.next() {
+ None => Err("Couldn't parse Northstar launcher version".to_string()),
+ Some(mat) => match mat.get(1) {
+ None => Err("Couldn't parse Northstar launcher version".to_string()),
+ Some(mod_name) => Ok(mod_name.as_str().to_string()),
+ },
+ }
+}
+
+fn parse_log_for_crash(log_text: String) -> bool {
+ let pattern = Regex::new(r"(?m)Northstar has crashed!").unwrap();
+ pattern.is_match(&log_text)
+}
+
+/// Parse logs for installed mods
+#[tauri::command]
+pub async fn parse_given_log_text(log_text: String) -> Result<ParsedLogResults, String> {
+ let installed_mods = parse_given_log_text_for_installed_mods(log_text.clone())?;
+ let northstar_launcher_version = parse_for_northstar_launcher_version(log_text.clone())?;
+ let has_northstar_crashed = parse_log_for_crash(log_text);
+
+ let parsed_log_results = ParsedLogResults {
+ northstar_launcher_version,
+ installed_mods,
+ has_northstar_crashed,
+ };
+
+ // Return the parsed results
+ return Ok(parsed_log_results);
+}
diff --git a/src-tauri/src/repair_and_verify/mod.rs b/src-tauri/src/repair_and_verify/mod.rs
index 5d58dfaf..ed00ba16 100644
--- a/src-tauri/src/repair_and_verify/mod.rs
+++ b/src-tauri/src/repair_and_verify/mod.rs
@@ -1,3 +1,5 @@
+pub mod log_handling;
+
use crate::{
mod_management::{rebuild_enabled_mods_json, set_mod_enabled_status},
northstar::CORE_MODS,
diff --git a/src-vue/src/views/DeveloperView.vue b/src-vue/src/views/DeveloperView.vue
index 6770caaa..23410c23 100644
--- a/src-vue/src/views/DeveloperView.vue
+++ b/src-vue/src/views/DeveloperView.vue
@@ -51,6 +51,43 @@
<el-button type="primary" @click="clearFlightCorePersistentStore">
Delete FlightCore persistent store
</el-button>
+
+ <h3>Tech support</h3>
+
+ <el-button type="primary" @click="parseGivenLogTextForMods">
+ Parse logs
+ </el-button>
+ <el-input
+ v-model="log_content"
+ type="textarea"
+ :rows="5"
+ placeholder="Paste log content here"
+
+ />
+ <div>
+ <el-table :data="logResults">
+ <el-table-column prop="northstar_launcher_version"
+ label="Northstar Launcher Version"></el-table-column>
+ <el-table-column prop="installed_mods" label="Installed and enabled/disabled Mods">
+ <template v-slot="{ row }">
+ <ul>
+ <li v-for="mod in row.installed_mods">
+ <el-icon class="no-inherit">
+ <Select v-if="mod.enabled" />
+ <Close v-else />
+ </el-icon>
+ {{ mod.mod_name }}
+ </li>
+ </ul>
+ </template>
+ </el-table-column>
+ <el-table-column prop="has_northstar_crashed" label="Northstar Crashed">
+ <template v-slot="{ row }">
+ {{ row.has_northstar_crashed }}
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
</el-scrollbar>
</div>
</template>
@@ -61,6 +98,8 @@ import { invoke } from "@tauri-apps/api";
import { ElNotification } from "element-plus";
import { GameInstall } from "../utils/GameInstall";
import { Store } from 'tauri-plugin-store-api';
+import { ParsedLogResults } from "../../../src-tauri/bindings/ParsedLogResults";
+import { ParsedModFromLog } from "../../../src-tauri/bindings/ParsedModFromLog";
const persistentStore = new Store('flight-core-settings.json');
export default defineComponent({
@@ -68,6 +107,8 @@ export default defineComponent({
data() {
return {
mod_to_install_field_string : "",
+ log_content : "",
+ logResults: [] as ParsedLogResults[]
}
},
methods: {
@@ -207,7 +248,30 @@ export default defineComponent({
await persistentStore.clear();
// ...and save
await persistentStore.save();
- }
+ },
+ async parseGivenLogTextForMods() {
+ let current_log_content = this.log_content;
+ await invoke<[ParsedLogResults]>("parse_given_log_text", { logText: current_log_content })
+ .then((message) => {
+ console.log(message); // TODO present better here
+ this.logResults.push(message);
+ // Show user notification if task completed.
+ ElNotification({
+ title: `Done`,
+ message: `${message}`,
+ type: 'success',
+ position: 'bottom-right'
+ });
+ })
+ .catch((error) => {
+ ElNotification({
+ title: 'Error',
+ message: error,
+ type: 'error',
+ position: 'bottom-right'
+ });
+ });
+ },
}
});
</script>