first commit
7
.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/dist/
|
||||
/target/
|
||||
/Cargo.lock
|
||||
.vscode/extensions.json
|
||||
.vscode/settings.json
|
||||
public/tauri.svg
|
||||
public/yew.png
|
||||
3
.taurignore
Normal file
@@ -0,0 +1,3 @@
|
||||
/src
|
||||
/public
|
||||
/Cargo.toml
|
||||
19
Cargo.toml
Normal file
@@ -0,0 +1,19 @@
|
||||
[package]
|
||||
name = "kaihai-ui"
|
||||
version = "0.0.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[dependencies]
|
||||
yew = { version = "0.21", features = ["csr"] }
|
||||
yew-router = "0.18"
|
||||
wasm-bindgen = "0.2"
|
||||
wasm-bindgen-futures = "0.4"
|
||||
web-sys = "0.3"
|
||||
js-sys = "0.3"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde-wasm-bindgen = "0.6"
|
||||
console_error_panic_hook = "0.1.7"
|
||||
|
||||
[workspace]
|
||||
members = ["src-tauri"]
|
||||
7
README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Tauri + Yew
|
||||
|
||||
This template should help get you started developing with Tauri and Yew.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
[VS Code](https://code.visualstudio.com/) + [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) + [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer).
|
||||
10
Trunk.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[build]
|
||||
target = "./index.html"
|
||||
|
||||
[watch]
|
||||
ignore = ["./src-tauri"]
|
||||
|
||||
[serve]
|
||||
address = "127.0.0.1"
|
||||
port = 1420
|
||||
open = false
|
||||
11
index.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Tauri + Yew App</title>
|
||||
<link data-trunk rel="css" href="styles.css" />
|
||||
<link data-trunk rel="copy-dir" href="public" />
|
||||
</head>
|
||||
<body></body>
|
||||
d
|
||||
</html>
|
||||
7
src-tauri/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
|
||||
# Generated by Tauri
|
||||
# will have schema files for capabilities auto-completion
|
||||
/gen/schemas
|
||||
20
src-tauri/Cargo.toml
Normal file
@@ -0,0 +1,20 @@
|
||||
[package]
|
||||
name = "kaihai"
|
||||
version = "0.0.0"
|
||||
description = "A Tauri App"
|
||||
authors = ["you"]
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "1", features = [] }
|
||||
|
||||
[dependencies]
|
||||
tauri = { version = "1", features = ["shell-open"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
|
||||
[features]
|
||||
# This feature is used for production builds or when a dev server is not specified, DO NOT REMOVE!!
|
||||
custom-protocol = ["tauri/custom-protocol"]
|
||||
3
src-tauri/build.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
tauri_build::build()
|
||||
}
|
||||
BIN
src-tauri/icons/128x128.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
src-tauri/icons/128x128@2x.png
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
src-tauri/icons/32x32.png
Normal file
|
After Width: | Height: | Size: 974 B |
BIN
src-tauri/icons/Square107x107Logo.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
src-tauri/icons/Square142x142Logo.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
src-tauri/icons/Square150x150Logo.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
src-tauri/icons/Square284x284Logo.png
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
BIN
src-tauri/icons/Square30x30Logo.png
Normal file
|
After Width: | Height: | Size: 903 B |
BIN
src-tauri/icons/Square310x310Logo.png
Normal file
|
After Width: | Height: | Size: 8.4 KiB |
BIN
src-tauri/icons/Square44x44Logo.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
src-tauri/icons/Square71x71Logo.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
src-tauri/icons/Square89x89Logo.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
src-tauri/icons/StoreLogo.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
src-tauri/icons/icon.icns
Normal file
BIN
src-tauri/icons/icon.ico
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
src-tauri/icons/icon.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
15
src-tauri/src/main.rs
Normal file
@@ -0,0 +1,15 @@
|
||||
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
|
||||
#[tauri::command]
|
||||
fn greet(name: &str) -> String {
|
||||
format!("Hello, {}! You've been greeted from Rust!", name)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
tauri::Builder::default()
|
||||
.invoke_handler(tauri::generate_handler![greet])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
44
src-tauri/tauri.conf.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"build": {
|
||||
"beforeDevCommand": "trunk serve",
|
||||
"beforeBuildCommand": "trunk build",
|
||||
"devPath": "http://localhost:1420",
|
||||
"distDir": "../dist",
|
||||
"withGlobalTauri": true
|
||||
},
|
||||
"package": {
|
||||
"productName": "kaihai",
|
||||
"version": "0.0.0"
|
||||
},
|
||||
"tauri": {
|
||||
"allowlist": {
|
||||
"all": false,
|
||||
"shell": {
|
||||
"all": false,
|
||||
"open": true
|
||||
}
|
||||
},
|
||||
"windows": [
|
||||
{
|
||||
"title": "kaihai",
|
||||
"width": 800,
|
||||
"height": 600
|
||||
}
|
||||
],
|
||||
"security": {
|
||||
"csp": null
|
||||
},
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"identifier": "com.tauri.dev",
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/128x128.png",
|
||||
"icons/128x128@2x.png",
|
||||
"icons/icon.icns",
|
||||
"icons/icon.ico"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
45
src/app.rs
Normal file
@@ -0,0 +1,45 @@
|
||||
use wasm_bindgen::prelude::*;
|
||||
use yew::prelude::*;
|
||||
use yew_router::prelude::*;
|
||||
|
||||
use crate::views::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_namespace = ["window", "__TAURI__", "tauri"])]
|
||||
async fn invoke(cmd: &str, args: JsValue) -> JsValue;
|
||||
}
|
||||
|
||||
#[derive(Clone, Routable, PartialEq)]
|
||||
pub enum Route {
|
||||
#[at("/")]
|
||||
Home,
|
||||
#[at("/extract")]
|
||||
Extract,
|
||||
#[at("/settings")]
|
||||
Settings,
|
||||
#[not_found]
|
||||
#[at("/404")]
|
||||
NotFound,
|
||||
}
|
||||
|
||||
|
||||
#[function_component(App)]
|
||||
pub fn app() -> Html {
|
||||
html! {
|
||||
<BrowserRouter>
|
||||
<nav::Nav/>
|
||||
<Switch<Route> render={switch} />
|
||||
</BrowserRouter>
|
||||
}
|
||||
}
|
||||
|
||||
fn switch(routes: Route) -> Html {
|
||||
match routes {
|
||||
Route::Home => html! { <Home/> },
|
||||
Route::Extract => html! { <Extract/> },
|
||||
Route::Settings => html! { <Settings/> },
|
||||
Route::NotFound => html! { <h1>{"404 Page Not Found"}</h1> },
|
||||
}
|
||||
}
|
||||
|
||||
38
src/config_settings.rs
Normal file
@@ -0,0 +1,38 @@
|
||||
use std::fs;
|
||||
use rocket::config;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, FromForm)]
|
||||
pub struct Config {
|
||||
pub cslol_dir: String,
|
||||
pub wad_dir: String,
|
||||
pub extract_dir: String,
|
||||
}
|
||||
|
||||
pub fn init_config() {
|
||||
if fs::metadata("config.toml").is_err() {
|
||||
let config = Config {
|
||||
cslol_dir: "".to_string(),
|
||||
wad_dir: "C:\\Riot Games\\League of Legends\\Game\\DATA\\FINAL\\Champions".to_string(),
|
||||
extract_dir: "".to_string(),
|
||||
};
|
||||
write_config(&config);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_config() -> Config {
|
||||
let config = fs::read_to_string("config.toml")
|
||||
.expect("Failed to read config.toml file");
|
||||
|
||||
toml::from_str(&config)
|
||||
.expect("Failed to parse config.toml file")
|
||||
}
|
||||
|
||||
pub fn write_config(config: &Config) {
|
||||
let config_content = toml::to_string(config)
|
||||
.expect("Failed to serialize config");
|
||||
|
||||
fs::write("config.toml", config_content)
|
||||
.expect("Failed to write to config.toml file");
|
||||
}
|
||||
|
||||
56
src/extractor.rs
Normal file
@@ -0,0 +1,56 @@
|
||||
use std::process::Command;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use walkdir::WalkDir;
|
||||
use std::ffi::OsString;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::config_settings;
|
||||
|
||||
pub fn extract_wad() {
|
||||
let config = config_settings::load_config();
|
||||
let wad_files: Vec<OsString> = WalkDir::new(config.wad_dir)
|
||||
.into_iter()
|
||||
.filter_map(|entry| entry.ok())
|
||||
.filter(|entry| {
|
||||
let path = entry.path();
|
||||
let file_name = path.file_name().and_then(|name| name.to_str()).unwrap_or("");
|
||||
let extension = path.extension().and_then(|ext| ext.to_str()).unwrap_or("");
|
||||
extension == "client" &&
|
||||
file_name.ends_with(".wad.client") &&
|
||||
file_name.split('.').count() == 3
|
||||
})
|
||||
.map(|entry| entry.path().to_owned().into_os_string())
|
||||
.collect();
|
||||
|
||||
if wad_files.is_empty() {
|
||||
eprintln!("No valid .wad.client files found in the directory");
|
||||
return;
|
||||
}
|
||||
|
||||
let current_dir = env::current_dir().expect("Failed to get current directory");
|
||||
let extraction_path = current_dir.join("wads");
|
||||
let bat_path = PathBuf::from(config.cslol_dir).join("cslol-tools\\wad-extract.exe");
|
||||
|
||||
if !extraction_path.exists() {
|
||||
fs::create_dir_all(&extraction_path).expect("Failed to create extraction folder");
|
||||
}
|
||||
|
||||
for (i, wad_file) in wad_files.iter().enumerate() {
|
||||
let status = Command::new(&bat_path)
|
||||
.arg(&wad_file)
|
||||
.arg(&extraction_path)
|
||||
.status()
|
||||
.expect("Failed to execute command");
|
||||
|
||||
if status.success() {
|
||||
println!("Successfully executed wad-extract.bat for {:?}", wad_file);
|
||||
} else {
|
||||
eprintln!("wad-extract.bat returned a non-zero status for {:?}", wad_file);
|
||||
}
|
||||
|
||||
if i >= 3 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
10
src/main.rs
Normal file
@@ -0,0 +1,10 @@
|
||||
mod app;
|
||||
mod views;
|
||||
|
||||
use app::App;
|
||||
|
||||
|
||||
fn main() {
|
||||
console_error_panic_hook::set_once();
|
||||
yew::Renderer::<App>::new().render();
|
||||
}
|
||||
18
src/views/extract.rs
Normal file
@@ -0,0 +1,18 @@
|
||||
use yew::prelude::*;
|
||||
|
||||
#[function_component(Extract)]
|
||||
pub fn extract() -> Html {
|
||||
html! {
|
||||
<div class="content">
|
||||
<h2>{"Extract"}</h2>
|
||||
<p>{"Exctract shit"}</p>
|
||||
|
||||
<form action="/extract-wads" method="post">
|
||||
<div class="option">
|
||||
<button type="submit">{"Extract WADs"}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
}
|
||||
}
|
||||
11
src/views/home.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
use yew::prelude::*;
|
||||
|
||||
#[function_component(Home)]
|
||||
pub fn home() -> Html {
|
||||
html! {
|
||||
<div class="content">
|
||||
<h2>{"Home Page"}</h2>
|
||||
<p>{"Welcome to the Home page!"}</p>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
8
src/views/mod.rs
Normal file
@@ -0,0 +1,8 @@
|
||||
pub mod extract;
|
||||
pub mod home;
|
||||
pub mod nav;
|
||||
pub mod settings;
|
||||
|
||||
pub use extract::*;
|
||||
pub use home::*;
|
||||
pub use settings::*;
|
||||
14
src/views/nav.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
use yew::prelude::*;
|
||||
use yew_router::prelude::*;
|
||||
use crate::app::Route;
|
||||
|
||||
#[function_component(Nav)]
|
||||
pub fn nav() -> Html {
|
||||
html! {
|
||||
<div class="nav">
|
||||
<Link<Route> to={Route::Home}>{"Home"}</Link<Route>>
|
||||
<Link<Route> to={Route::Extract}>{"Extract"}</Link<Route>>
|
||||
<Link<Route> to={Route::Settings}>{"Settings"}</Link<Route>>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
34
src/views/settings.rs
Normal file
@@ -0,0 +1,34 @@
|
||||
use yew::prelude::*;
|
||||
|
||||
|
||||
#[function_component(Settings)]
|
||||
pub fn settings() -> Html {
|
||||
html! {
|
||||
<div class="content">
|
||||
<h2>{"Settings"}</h2>
|
||||
<form action="/write-settings" method="post">
|
||||
<div class="option">
|
||||
<label for="cslol_dir">{"Location of CSLoL"}</label>
|
||||
<br/>
|
||||
<input type="text" name="cslol_dir" id="cslol_dir" value="{{ config.cslol_dir }}"/>
|
||||
</div>
|
||||
|
||||
<div class="option">
|
||||
<label for="wad_dir">{"Custom location of Champion Wads"}</label>
|
||||
<br/>
|
||||
<input type="text" name="wad_dir" id="wad_dir" value="{{ config.wad_dir }}"/>
|
||||
</div>
|
||||
|
||||
<div class="option">
|
||||
<label for="extract_dir">{"Custom location to Extract to"}</label>
|
||||
<br/>
|
||||
<input type="text" name="extract_dir" id="extract_dir" value="{{ config.extract_dir }}"/>
|
||||
</div>
|
||||
|
||||
<div class="option">
|
||||
<button type="submit">{"Save Settings"}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
86
styles.css
Normal file
@@ -0,0 +1,86 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
color: white;
|
||||
background-color: #181a1b;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
/* Style the side navigation */
|
||||
.nav {
|
||||
height: 100%;
|
||||
width: 200px;
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: #111;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
|
||||
/* Side navigation links */
|
||||
.nav a {
|
||||
color: white;
|
||||
padding: 16px;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Change color on hover */
|
||||
.nav a:hover {
|
||||
background-color: #363b3d;
|
||||
}
|
||||
|
||||
/* Style the content */
|
||||
.content {
|
||||
margin-left: 200px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.option {
|
||||
margin-bottom: 10px;
|
||||
/* Adds space below each option group */
|
||||
padding: 10px 0px;
|
||||
/* Adds padding inside each option group */
|
||||
border-radius: 5px;
|
||||
/* Rounds the corners of the option group */
|
||||
}
|
||||
|
||||
.option label {
|
||||
margin: 5px 0px;
|
||||
}
|
||||
|
||||
.option input {
|
||||
outline: none;
|
||||
border: 2px solid #111;
|
||||
background-color: #111;
|
||||
color: white;
|
||||
width: 50%;
|
||||
padding: 10px 20px;
|
||||
margin: 10px 0px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.option input:focus {
|
||||
background-color: #363b3d;
|
||||
border: 2px solid #111;
|
||||
}
|
||||
|
||||
.option button {
|
||||
background-color: #111;
|
||||
border: 2px solid #111;
|
||||
color: white;
|
||||
padding: 16px 32px;
|
||||
margin: 10px 0px;
|
||||
border-radius: 6px;
|
||||
|
||||
}
|
||||
|
||||
.option button:hover {
|
||||
background-color: #363b3d;
|
||||
border: 2px solid #111;
|
||||
}
|
||||