feat(all-in-one): update prettier config, enable format on save

Update the VSCode settings.json to include the Prettier VSCode formatter, and enable formatting on save. A new LICENSE file is added to comply with the MIT license due to the open-source nature of the project. The README.md file has now core features and to-dos that should be taken care of as the project continues to evolve. The index.html file is modified to match changes in src/index.tsx. The postcss configuration files are created, and some files are updated. Finally, new files like build.rs, draworder.json, and commands.rs were created
This commit is contained in:
Walid 2023-05-02 15:51:22 +01:00
parent d26b429ee8
commit 90720c34f9
Signed by: Walidoux
GPG Key ID: CCF21881FE8BEBAF
19 changed files with 335 additions and 57 deletions

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
# MIT License
Copyright (c) 2023 Rypî Dev
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

60
README.md Normal file
View File

@ -0,0 +1,60 @@
# 🧿 Getting started
## 🎯 Todos
- [ ] Two options for downloading Habbo resources:
- [ ] Default data extraction. (Without conversion)
- [ ] Using [Scuti](https://scuti.netlify.app/) dataset for its [renderer.](https://github.com/kozennnn/scuti-renderer)
- [ ] Languages feature. (Default: EN)
- [ ] Download Habbo assets. (>800 MB of disk memory, make sure the IPC handles it correctly)
- [ ] Fix rendering animation issues.
- [ ] Add "abort" button with written data suppression feature.
- [x] Convert front-end with SolidJS
- [x] Fix issue of prettier-plugin-tailwindcss
- [ ] Export helpers/utils methods into Rust.
- [ ] Implementing typesafety with types' collections using Tauri Specta
- [ ] Handling extracted data in:
- [ ] JSON (Default + Adjustements for Scuti)
- [ ] XML (Using quickxml_to_serde)
- [ ] TXT (no idea...)
- [ ] Parsing data using `std::{fs::File, io::Write}`
- [ ] Avoid conflicts in open-source.
- [ ] Undertsand: Memory cache and disk cache.
## Overview
- [How it works](#🏗️-how-it-works)
- [Techs stack](#📦-techs-stack)
- [Interesting topics](#📤-interesting-topics)
- [Credits](#🤝-credits)
## 📦 Techs stack
![Rust lang](https://img.shields.io/badge/Rust-black?style=for-the-badge&logo=rust&logoColor=#E57324)
![Typescript lang](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge&logo=typescript&logoColor=white)
![Vite](https://img.shields.io/badge/Vite-B73BFE?style=for-the-badge&logo=vite&logoColor=FFD62E)
![SolidJS](https://img.shields.io/badge/Solid%20JS-2C4F7C?style=for-the-badge&logo=solid&logoColor=white)
![Tailwind framework](https://img.shields.io/badge/Tailwind_CSS-38B2AC?style=for-the-badge&logo=tailwind-css&logoColor=white)
## 🏗️ How it works
### Gamedata/Generic
It comes first with fetching data using the `@tauri-apps/api/http` module.
Converting uncoming data into minified JSON file formats.
(No need for avro, parquet, protobuf nor CSV for efficient data compression
and encoding schemas for fast data storing/retrieval)
## 📤 Interesting topics
### 🦀 Rust-related
- [Why serde_json crate is the best choice?](https://blog.logrocket.com/json-and-rust-why-serde_json-is-the-top-choice/)
## 🤝 Credits
This wouldn't be possible without the help of [KOZEN](https://github.com/kozennnn)'s contribution.

View File

@ -8,6 +8,6 @@
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
<script src="/src/index.tsx" type="module"></script>
</body>
</html>

7
postcss.config.cjs Normal file
View File

@ -0,0 +1,7 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
...(!process.env.TAURI_DEBUG ? { cssnano: { preset: 'advanced' } } : {})
}
}

View File

@ -1,6 +0,0 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {}
}
}

4
prettier.config.cjs Normal file
View File

@ -0,0 +1,4 @@
module.exports = {
...require("@walidoux/prettier-config"),
plugins: ["prettier-plugin-tailwindcss"],
};

View File

@ -1,3 +0,0 @@
fn main() {
tauri_build::build()
}

View File

@ -0,0 +1 @@
{"std":[["li","lh","ls","lc","ri","bd","sh","lg","ch","cc","cp","wa","ca","rh","rs","rc","hd","fc","ey","hr","hrb","fa","ea","ha","he"],["li","lh","ls","lc","bd","sh","lg","ch","cc","cp","wa","ca","ri","rh","rs","rc","hd","fc","ey","hr","hrb","fa","ea","ha","he"],["li","lh","ls","lc","bd","sh","lg","ch","cc","cp","wa","ca","hd","fc","ey","hr","hrb","fa","ea","ha","he","ri","rh","rs","rc"],["bd","sh","lg","ch","cc","cp","wa","ca","li","lh","ls","lc","hd","fc","ey","hr","hrb","fa","ea","ha","he","ri","rh","rs","rc"],["bd","sh","lg","ch","cc","cp","wa","ca","lh","ls","lc","li","hd","fc","ey","hr","hrb","fa","ea","ha","he","rh","rs","rc","ri"],["rh","rs","rc","ri","bd","sh","lg","ch","cc","cp","wa","ca","li","lh","ls","lc","hd","fc","ey","hr","hrb","fa","ea","ha","he"],["bd","sh","lg","ch","cc","cp","wa","ca","li","lh","ls","lc","hd","fc","ey","hr","hrb","fa","ea","ha","he","rh","rs","rc","ri"],["li","lh","ls","lc","ri","rh","rs","rc","bd","sh","lg","ch","cc","cp","wa","ca","hd","fc","ey","hr","hrb","fa","ea","ha","he"]],"lh-up":{"4":["rh","rs","rc","bd","sh","lg","ch","cc","cp","wa","ri","ca","hd","fc","ey","hr","hrb","fa","ea","ha","he","lh","ls","lc","li"],"5":["rh","rs","rc","ri","bd","sh","lg","ch","cc","cp","wa","ca","hd","fc","ey","hr","hrb","fa","ea","ha","he","li","lh","ls","lc"],"6":["rh","rs","rc","ri","bd","sh","lg","ch","cc","cp","wa","ca","hd","fc","ey","hr","hrb","fa","ea","ha","he","li","lh","ls","lc"]},"rh-up":[["li","lh","ls","lc","ri","bd","sh","lg","ch","cc","cp","wa","ca","hd","fc","ey","hr","hrb","fa","ea","ha","he","rh","rs","rc"],["li","lh","ls","lc","bd","sh","lg","ch","cc","cp","wa","ca","hd","fc","ey","hr","hrb","fa","ea","ha","he","ri","rh","rs","rc"],["li","lh","ls","lc","bd","sh","lg","ch","cc","cp","wa","ca","hd","fc","ey","hr","hrb","fa","ea","ha","he","ri","rh","rs","rc"],["bd","sh","lg","ch","cc","cp","wa","li","lh","ls","lc","ca","hd","fc","ey","hr","hrb","fa","ea","ha","he","ri","rh","rs","rc"]],"sit":{"2":["li","lh","ls","lc","bd","lg","ch","cc","cp","wa","ca","rh","rs","rc","hd","fc","ey","hr","hrb","fa","ea","ha","he","ri","sh"],"3":["bd","lg","ch","cc","cp","wa","ca","li","lh","ls","lc","rh","rs","rc","hd","fc","ey","hr","hrb","fa","ea","ha","he","ri","sh"],"4":["rh","rs","rc","bd","lg","ch","cc","cp","wa","ca","lh","ls","lc","li","hd","fc","ey","hr","hrb","fa","ea","ha","he","ri","sh"]},"sit.lh-up":{"4":["rh","rs","rc","bd","lg","ch","cc","cp","wa","ri","ca","hd","fc","ey","hr","hrb","fa","ea","ha","he","lh","ls","lc","li","sh"]},"sit.rh-up":{"2":["li","lh","ls","lc","bd","lg","ch","cc","cp","wa","ca","hd","fc","ey","hr","hrb","fa","ea","ha","he","ri","rh","rs","rc","sh"],"3":["bd","lg","ch","cc","cp","wa","li","lh","ls","lc","ca","hd","fc","ey","hr","hrb","fa","ea","ha","he","ri","rh","rs","rc","sh"]},"lay":{"2":["lh","ls","lc","li","bd","lg","sh","ch","cc","cp","hd","fc","ey","wa","ri","rh","rs","rc","ca","hr","hrb","fa","ea","ha","he"],"4":["rh","rs","rc","ri","bd","lg","sh","ch","cc","cp","hd","fc","ey","wa","li","lh","ls","lc","ca","hr","hrb","fa","ea","ha","he"]}}

5
src-tauri/src/build.rs Normal file
View File

@ -0,0 +1,5 @@
use tauri_build::build;
fn main() {
build()
}

108
src-tauri/src/commands.rs Normal file
View File

@ -0,0 +1,108 @@
use quickxml_to_serde::{xml_string_to_json, Config, NullValue};
use specta::specta;
use crate::{
structs::{ConvertTypes, GamedataEndpoints},
utils::convert_json,
};
#[specta]
#[tauri::command]
pub fn download_gamedata(data: &str, endpoint: GamedataEndpoints) {
match endpoint.convert {
ConvertTypes::XML => {
let conf = Config::new_with_custom_values(true, "", "txt", NullValue::Null);
let json = xml_string_to_json(data.to_owned(), &conf);
println!("{}", json.expect("Malformed XML").to_string());
}
ConvertTypes::TXT => println!("TXT CONVERTION"),
ConvertTypes::JSON => convert_json(data, endpoint.file_name),
}
}
/* #[specta]
#[tauri::command]
pub fn parse_data(
path: String,
file_name: String,
file_content: String,
) -> Result<(), Box<dyn std::error::Error>> {
let file_dir = PathBuf::from(&path).join(format!("{}.json", file_name));
// By default, output files will be overwritten. I cannot recursively remove the entire output folder
// and create it again because it just won't parse files' contents for some reason
if !exists(&Convertion::gamedata_dir()) {
create_dir_all(&Convertion::gamedata_dir())?;
}
write_file(&file_dir, file_content.as_bytes());
Ok(())
} */
/* pub async fn convert_txt(path: &str, data: &str) -> Result<(), Box<dyn std::error::Error>> {
let mut badges: Vec<Badge> = Vec::new();
let lines: Vec<&str> = data.split('\n').collect();
let badge_pattern = Regex::new(r"^badge_(?:name|desc)_([^=]+)").unwrap();
let description_pattern = Regex::new(r"^badge_desc_(\s*\w+)").unwrap();
let name_pattern = Regex::new(r"^badge_name_(\s*\w+)").unwrap();
for (index, line) in lines.iter().enumerate() {
let parts: Vec<&str> = line.split('=').collect();
if parts.len() < 2 {
continue;
}
let key = parts[0];
let value = parts[1];
if badge_pattern.is_match(key) {
if name_pattern.is_match(key) {
let badge_code = name_pattern.captures(key).unwrap()[1].to_owned();
let existing_badge = badges.iter_mut().find(|badge| badge.code == badge_code);
if let Some(badge) = existing_badge {
badge.name = Some(value.to_owned());
} else {
badges.push(Badge {
code: badge_code,
name: Some(value.to_owned()),
description: None,
});
}
} else if description_pattern.is_match(key) {
let badge_code = description_pattern.captures(key).unwrap()[1].to_owned();
let existing_badge = badges.iter_mut().find(|badge| badge.code == badge_code);
if let Some(badge) = existing_badge {
badge.description = Some(value.to_owned());
} else {
badges.push(Badge {
code: badge_code,
name: None,
description: Some(value.to_owned()),
});
}
}
// Remove the line from the vector
lines[index] = "";
}
}
// Remove empty lines
let lines: Vec<&str> = lines
.iter()
.filter(|line| !line.is_empty())
.cloned()
.collect();
parse_habbo_data(path, "Badges", &badges);
Ok(())
} */

View File

@ -1,8 +1,27 @@
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
pub mod commands;
pub mod structs;
pub mod utils;
use commands::download_gamedata;
use specta::collect_types;
use tauri_specta::ts;
fn main() {
ts::export(collect_types![download_gamedata], "../src/tools/rusty.ts").unwrap();
// This is useful for custom eslint, prettier overrides at the top of the file.
// ts::export_with_cfg_with_header(
// collect_types![download_gamedata].unwrap(),
// Default::default(),
// "../src/tools/rusty.ts",
// "/* eslint-disable */\n".into(),
// )
// .unwrap();
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![download_gamedata])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

39
src-tauri/src/structs.rs Normal file
View File

@ -0,0 +1,39 @@
use serde::{Deserialize, Serialize};
use specta::Type;
/* pub struct Badge {
pub code: String,
pub name: Option<String>,
pub description: Option<String>,
} */
#[derive(Serialize, Deserialize, Type, Debug)]
pub enum ConvertTypes {
TXT,
XML,
JSON,
}
#[derive(Serialize, Deserialize, Type, Debug)]
pub enum Converters {
FigureData,
FigureMap,
EffectMap,
FurniData,
}
#[derive(Serialize, Deserialize, Type, Debug)]
pub struct GamedataEndpoints {
pub src: String,
pub convert: ConvertTypes,
pub file_name: Converters,
}
pub struct FigureData {
pub floor_items: Vec<IFloorItem>,
pub wall_items: Vec<IFurni>,
}
pub struct IFloorItem {}
pub struct IFurni {}

25
src-tauri/src/utils.rs Normal file
View File

@ -0,0 +1,25 @@
use serde_json::Value;
use crate::structs::Converters;
pub fn debug_typeof<T>(_: &T) {
println!("{}", std::any::type_name::<T>())
}
pub fn convert_json(data: &str, file_name: Converters) {
let object: Value = serde_json::from_str(data).unwrap();
println!("{}", object);
match file_name {
/* Converters::FurniData => {
for (key, value) in object["wallitemtypes"]["furnitype"].as_object().unwrap() {
println!("{} {}", key, value);
}
} */
Converters::FigureData => unimplemented!(),
Converters::FigureMap => todo!(),
Converters::EffectMap => todo!(),
Converters::FurniData => todo!(),
}
}

View File

@ -1,11 +1,5 @@
{
"build": {
"beforeDevCommand": "yarn dev",
"beforeBuildCommand": "yarn build",
"devPath": "http://localhost:1420",
"distDir": "../dist",
"withGlobalTauri": false
},
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
"package": {
"productName": "rypi-scrapper",
"version": "0.0.0"
@ -44,7 +38,7 @@
"targets": "all"
},
"security": {
"csp": null
"csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self'"
},
"updater": {
"active": false

View File

@ -1,6 +1,6 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./src/**/*.tsx'],
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx,css,md,mdx,html,json,scss}'],
theme: {
extend: {
colors: {

View File

@ -4,7 +4,6 @@
"useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": false,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
@ -13,8 +12,9 @@
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
"jsx": "preserve",
"types": ["vite/client"],
"jsxImportSource": "solid-js"
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
"include": ["src"]
}

View File

@ -1,9 +0,0 @@
{
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Node",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts"]
}

32
vite.config.tauri.ts Normal file
View File

@ -0,0 +1,32 @@
import { defineConfig, mergeConfig } from 'vite'
import baseViteConfig from './vite.config'
import { tauri } from 'vite-plugin-tauri'
// https://vitejs.dev/config/
export default defineConfig(
mergeConfig(
baseViteConfig,
defineConfig({
plugins: [tauri()],
// prevent vite from obscuring rust errors
clearScreen: false,
// Tauri expects a fixed port, fail if that port is not available
server: {
strictPort: true,
open: false
},
// to make use of `TAURI_PLATFORM`, `TAURI_ARCH`, `TAURI_FAMILY`,
// `TAURI_PLATFORM_VERSION`, `TAURI_PLATFORM_TYPE` and `TAURI_DEBUG`
// env variables
envPrefix: ['VITE_', 'TAURI_'],
build: {
// Tauri supports es2021
target: ['es2022', 'chrome100', 'safari13'],
// don't minify for debug builds
minify: !process.env.TAURI_DEBUG ? 'esbuild' : false,
// produce sourcemaps for debug builds
sourcemap: !!process.env.TAURI_DEBUG,
}
})
)
);

View File

@ -1,26 +1,7 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import solidPlugin from 'vite-plugin-solid'
export default defineConfig(async () => ({
plugins: [react()],
// Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
// prevent vite from obscuring rust errors
clearScreen: false,
// tauri expects a fixed port, fail if that port is not available
server: {
port: 1420,
strictPort: true
},
// to make use of `TAURI_DEBUG` and other env variables
// https://tauri.studio/v1/api/config#buildconfig.beforedevcommand
envPrefix: ['VITE_', 'TAURI_'],
build: {
// Tauri supports es2021
target: process.env.TAURI_PLATFORM == 'windows' ? 'chrome105' : 'safari13',
// don't minify for debug builds
minify: !process.env.TAURI_DEBUG ? 'esbuild' : false,
// produce sourcemaps for debug builds
sourcemap: !!process.env.TAURI_DEBUG
}
}))
// https://vitejs.dev/config/
export default defineConfig({
plugins: [solidPlugin()]
})