Skip to content

Commit

Permalink
wtf that was so hard xdd
Browse files Browse the repository at this point in the history
  • Loading branch information
Rexicon226 committed Mar 11, 2023
1 parent f01ccf5 commit f43c70b
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 49 deletions.
5 changes: 5 additions & 0 deletions app/src/api/models/modinfo/browse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ export interface BrowseModInfo {
versions: ModVersion[];
}


export interface ModWithDistance {
mod: BrowseModInfo;
dist: undefined;
}
export const finishBrowseModInfo = (
raw: Partial<BrowseModInfo>
): BrowseModInfo => {
Expand Down
6 changes: 6 additions & 0 deletions app/src/invoke.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ export interface ModsArgs {
count: number;
}

export interface QueryData {
query: string;
modName: string;
}

export interface InvokeFunction {
download_bepinex: [DownloadArgs, string];
uninstall_bepinex: [undefined, string];
Expand All @@ -36,6 +41,7 @@ export interface InvokeFunction {
get_mod: [ModArgs, FullModInfo];
get_mod_download: [ModArgs, string];
get_mods: [ModsArgs, BrowseResult];
get_distance: [QueryData, undefined];

install_mod: [ModArgs, undefined];
}
Expand Down
60 changes: 14 additions & 46 deletions app/src/routes/mods/Browse.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import "./Browse.scss";
import {useEffect, useState} from "preact/compat";
import {Mod} from "../../components/Mod";
import {Pagination} from "../../components/Pagination";
import {BrowseModInfo} from "../../api/models/modinfo/browse";
import {BrowseModInfo, ModWithDistance} from "../../api/models/modinfo/browse";
import {invoke_proxy} from "../../invoke";
import {SearchBar} from "../../components/SearchBar";

Expand Down Expand Up @@ -33,72 +33,40 @@ export const Browse = () => {
})();
}, [page, initialLoad, perPage]);

function levenshteinDistance(a: string | any[], b: string | any[]) {
const m = a.length;
const n = b.length;
const matrix = [];

if (m === 0) return n;
if (n === 0) return m;

for (let i = 0; i <= m; i++) {
matrix[i] = [i];
}
for (let j = 0; j <= n; j++) {
matrix[0][j] = j;
}

for (let i = 1; i <= m; i++) {
for (let j = 1; j <= n; j++) {
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
matrix[i][j] = Math.min(
matrix[i - 1][j] + 1,
matrix[i][j - 1] + 1,
matrix[i - 1][j - 1] + cost
);
}
}
return matrix[m][n];
}


function searchMods(mods: BrowseModInfo[], query: string): BrowseModInfo[] {
setLoading(true);
async function searchMods(mods: BrowseModInfo[], query: string): Promise<BrowseModInfo[]> {
console.log();
const test_data = await invoke_proxy("get_distance", {query, modName: mods[0].name});
console.log(test_data);
const exactMatches: BrowseModInfo[] = [];
const closeMatches: BrowseModInfo[] = [];
const closeMatches: ModWithDistance[] = [];

const regex = new RegExp(`^${query}`, 'i');

mods.forEach((mod) => {
for (const mod of mods) {
if (mod.name.toLowerCase() === query.toLowerCase() || regex.test(mod.name)) {
exactMatches.push(mod);
} else {
closeMatches.push(mod);
const dist = await invoke_proxy("get_distance", {query, modName: mod.name});
closeMatches.push({mod, dist});
}
});
}

closeMatches.sort((a, b) => {
const distanceA = levenshteinDistance(a.name.toLowerCase(), query.toLowerCase());
const distanceB = levenshteinDistance(b.name.toLowerCase(), query.toLowerCase());
return distanceA - distanceB;
});
closeMatches.sort((a, b) => a.dist! - b.dist!);

setLoading(false);
return exactMatches.concat(closeMatches);
return exactMatches.concat(closeMatches.map((m) => m.mod));
}

const handleSearch = (query: string) => {
const handleSearch = async (query: string) => {
console.log('Searching for:', query);

const matches = searchMods(
const matches = await searchMods(
results,
query
);

console.log(matches);

setResults(matches);

};

return (
Expand Down
22 changes: 22 additions & 0 deletions common/src/mods/schema/browse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,25 @@ impl BrowseResult {
return out;
}
}

#[derive(Debug, Deserialize)]
pub struct BrowseModInfo {
pub name: String,
id: i32,
game: String,
game_id: i32,
short_description: String,
downloads: i32,
followers: i32,
author: String,
default_version_id: i32,
shared_authors: Vec<Value>,
background: String,
bg_offset_y: String,
license: String,
website: String,
donations: String,
source_code: String,
url: String,
versions: Vec<ModVersion>,
}
2 changes: 1 addition & 1 deletion gui/src/installer/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/// The code to download the SpaceWarp release.
pub mod bepinex;
pub mod bepinex_loader;
pub mod bepinex_loader;
46 changes: 44 additions & 2 deletions gui/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
use installer::bepinex::BepInExInstallManager;
use tauri::Window;
use std::{path::PathBuf, process::Command};
use wormhole_common::{finder::find_install_dir, instances::InstanceInfo, mods::{spacedock::SpaceDockAPI, schema::browse::{ModInfo, BrowseResult}}, installer::mods::ModInstaller};
use wormhole_common::{finder::find_install_dir, instances::InstanceInfo, mods::{spacedock::SpaceDockAPI, schema::browse::{ModInfo, BrowseResult}}};
use wormhole_common::installer::mods::ModInstaller;
use wormhole_common::mods::schema::browse::BrowseModInfo;

pub mod installer;
pub mod progress;
Expand Down Expand Up @@ -92,6 +94,45 @@ async fn install_mod(mod_id: i32) {
installer.install_from_spacedock(mod_id).await;
}

async fn levenshtein_distance(a: &str, b: &str) -> usize {
let m = a.chars().count();
let n = b.chars().count();
let mut matrix = vec![vec![0; n + 1]; m + 1];

if m == 0 {
return n;
}
if n == 0 {
return m;
}

for i in 0..=m {
matrix[i][0] = i;
}
for j in 0..=n {
matrix[0][j] = j;
}

for i in 1..=m {
for j in 1..=n {
let cost = if a.chars().nth(i - 1) == b.chars().nth(j - 1) {
0
} else {
1
};
matrix[i][j] = (matrix[i - 1][j] + 1)
.min(matrix[i][j - 1] + 1)
.min(matrix[i - 1][j - 1] + cost);
}
}
matrix[m][n]
}

#[tauri::command]
async fn get_distance(mod_name:&str, query: &str) -> Result<usize, String> {
Ok(levenshtein_distance(query, mod_name).await)
}

pub fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![
Expand All @@ -104,7 +145,8 @@ pub fn main() {
get_instances,
get_mod,
get_mods,
install_mod
install_mod,
get_distance
])
.run(tauri::generate_context!())
.expect("Error while starting Wormhole!");
Expand Down

0 comments on commit f43c70b

Please sign in to comment.