chore(history): squash 2 commit(s) from 2026-09-04
- refactor: удалить launcher и backend — развитие только мода - feat: автор loki5512344 везде, чужие атрибуции убраны, .cbcfg → .lvcfg с легаси-чтением + тесты
This commit is contained in:
parent
53ff8f8f8e
commit
e504859777
1456 changed files with 1752 additions and 12478 deletions
11
.gitignore
vendored
11
.gitignore
vendored
|
|
@ -11,12 +11,6 @@ gradlew.bat
|
||||||
*.iml
|
*.iml
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|
||||||
# Rust
|
|
||||||
*/target/
|
|
||||||
|
|
||||||
# Go
|
|
||||||
*/vendor/
|
|
||||||
|
|
||||||
# OS
|
# OS
|
||||||
.DS_Store
|
.DS_Store
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
|
@ -37,4 +31,7 @@ ref/
|
||||||
*.jar
|
*.jar
|
||||||
*.rar
|
*.rar
|
||||||
*.zip
|
*.zip
|
||||||
backend/server
|
|
||||||
|
# IDE/Build artifacts
|
||||||
|
.factorypath
|
||||||
|
**/bin/
|
||||||
|
|
|
||||||
38
TODO.md
38
TODO.md
|
|
@ -1,36 +1,30 @@
|
||||||
# LoVisual — структура проекта
|
# LoVisual
|
||||||
|
|
||||||
Репозиторий разбит на 3 независимых компонента. **У каждого свой TODO, корневой TODO больше не ведётся.**
|
Проект состоит из одного компонента — мода.
|
||||||
|
|
||||||
| Компонент | Стек | TODO |
|
| Компонент | Стек | TODO |
|
||||||
|-----------|------|------|
|
|-----------|------|------|
|
||||||
| `combatant-client-26.2/` | Java 25, Fabric (MC 26.2) | [`combatant-client-26.2/TODO.md`](combatant-client-26.2/TODO.md) |
|
| `combatant-client-26.2/` | Java 25, Fabric (MC 26.2) | [`combatant-client-26.2/TODO.md`](combatant-client-26.2/TODO.md) |
|
||||||
| `backend/` | Rust 2024 + axum | [`backend/TODO.md`](backend/TODO.md) |
|
|
||||||
| `launcher/` | Rust 2024 + Slint | [`launcher/TODO.md`](launcher/TODO.md) |
|
> Лаунчер (Rust + Slint) и backend (Rust + axum) удалены из проекта — развитие только мода.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Общие правила для Rust-компонентов (backend + launcher)
|
## Правила (для мода, продублированы в его TODO)
|
||||||
- KISS / DRY / SOLID
|
- KISS / DRY / SOLID
|
||||||
- Макс. 200 строк на файл
|
- Макс. 200 строк на файл (фасады-делегаты исключение)
|
||||||
- Макс. 3 файла на папку
|
- Макс. 3 файла на папку
|
||||||
- Обязательно: `cargo fmt` + `cargo clippy --all-targets` + `cargo test`
|
- Никакого статика, никаких this-escape, никаких мёртвых миксинов
|
||||||
- Запрещено `#[allow(dead_code)]`
|
- Без пустышек; каждый этап компилируется (`./gradlew build`)
|
||||||
- Запрещено `unsafe` в собственной логике
|
- Тесты обязательны для новых модулей (JUnit)
|
||||||
- Без пустышек: модуль создаётся только с рабочей реализацией
|
|
||||||
- Каждый этап компилируется
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Статус
|
## Статус
|
||||||
|
- [x] Фаза 1: Ребрендинг `combatant` → `lovisual`
|
||||||
### Backend
|
- [x] Фаза 2: Выкинуть Runtime/JarReplacement + Panic
|
||||||
- [x] Каркас: config, /health, graceful shutdown, CORS
|
- [x] Фаза 3: Разбивка 12 файлов-гигантов
|
||||||
- [ ] Auth (argon2 + JWT), профили, конфиги, IRC — см. `backend/TODO.md`
|
- [x] Фаза 3.5: Удаление читерских модулей (легит-направление)
|
||||||
|
- [x] Фаза 4: Security (BackdoorProtection, StaffTracker)
|
||||||
### Launcher
|
- [x] Фаза 5: Нормализация модулей (ленивый Minecraft, GameClock)
|
||||||
- [x] Каркас: окно логина, фоновая проверка /health
|
- [ ] Фаза 6: Тесты (EventBus, конфиг, утилиты) — см. `combatant-client-26.2/TODO.md`
|
||||||
- [ ] Auth, dashboard, settings, launch — см. `launcher/TODO.md`
|
|
||||||
|
|
||||||
### Мод (combatant-client-26.2)
|
|
||||||
- [ ] Полный rewrite: ребрендинг (1464 `combatant`), разбивка 12 файлов >1500 строк, выкинуть Runtime/JarReplacement, тесты — см. `combatant-client-26.2/TODO.md`
|
|
||||||
|
|
|
||||||
2199
backend/Cargo.lock
generated
2199
backend/Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,44 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "lovisual-backend"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2024"
|
|
||||||
rust-version = "1.85"
|
|
||||||
description = "LoVisual backend: auth, profiles, friends, cloud configs, IRC"
|
|
||||||
license = "GPL-3.0"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
axum = "0.8.9"
|
|
||||||
tokio = { version = "1.53", features = ["full"] }
|
|
||||||
tower-http = { version = "0.7", features = ["cors", "trace", "fs"] }
|
|
||||||
tracing = "0.1"
|
|
||||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
|
||||||
serde = { version = "1", features = ["derive"] }
|
|
||||||
serde_json = "1"
|
|
||||||
sqlx = { version = "0.9", features = ["runtime-tokio", "sqlite", "chrono"] }
|
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
|
||||||
thiserror = "2"
|
|
||||||
anyhow = "1"
|
|
||||||
argon2 = "0.5"
|
|
||||||
jsonwebtoken = "11"
|
|
||||||
uuid = { version = "1", features = ["v4", "serde"] }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
tower = { version = "0.5", features = ["util"] }
|
|
||||||
|
|
||||||
[lints.rust]
|
|
||||||
unsafe_code = "forbid"
|
|
||||||
dead_code = "deny"
|
|
||||||
|
|
||||||
[lints.clippy]
|
|
||||||
correctness = "deny"
|
|
||||||
suspicious = "deny"
|
|
||||||
style = "deny"
|
|
||||||
complexity = "deny"
|
|
||||||
perf = "deny"
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
opt-level = 3
|
|
||||||
lto = "fat"
|
|
||||||
codegen-units = 1
|
|
||||||
panic = "abort"
|
|
||||||
strip = true
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
# LoVisual Backend (Rust + axum)
|
|
||||||
|
|
||||||
## Правила (ОБЯЗАТЕЛЬНЫЕ, нарушение = откат)
|
|
||||||
- **KISS / DRY / SOLID** — простая структура, без оверинжиниринга
|
|
||||||
- **Макс. 200 строк на файл** — превышение = разбить на модули
|
|
||||||
- **Макс. 3 файла на папку** — больше = новая подпапка по смыслу
|
|
||||||
- **Обязательное прохождение:** `cargo fmt` + `cargo clippy --all-targets` (ноль ошибок) + `cargo test`
|
|
||||||
- **Запрещено `#[allow(dead_code)]`** — мёртвый код удаляется, не прячется
|
|
||||||
- **Запрещено `unsafe`** (в собственной логике; lints: `unsafe_code = "forbid"`)
|
|
||||||
- **Без пустышек** — модуль создаётся только с рабочей реализацией
|
|
||||||
- **Каждый этап компилируется** — перед переходом к следующему
|
|
||||||
- **Ошибки JSON-декода не игнорировать** — всегда `.context()`/`?`
|
|
||||||
- **`user_id` из токена, не из тела запроса**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Сделано
|
|
||||||
- [x] Каркас: main.rs + server/{mod,config} + routes/{mod,health}
|
|
||||||
- [x] `GET /health` + graceful shutdown (SIGTERM/SIGINT)
|
|
||||||
- [x] Config из env (LOVISUAL_HOST/PORT/CORS_ORIGINS), валидация на старте
|
|
||||||
- [x] CORS (настраиваемые origins) + tower TraceLayer
|
|
||||||
- [x] Rust 2024 edition, актуальные версии пакетов
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Фаза 1: DB (SQLite, sqlx)
|
|
||||||
- [ ] `src/db/mod.rs` — подключение, миграции
|
|
||||||
- [ ] `src/db/users.rs` — таблица users
|
|
||||||
- [ ] `src/db/configs.rs` — облачные конфиги
|
|
||||||
- [ ] `src/db/profiles.rs` — профили, playtime, friends
|
|
||||||
|
|
||||||
## Фаза 2: Auth
|
|
||||||
- [ ] `src/auth/mod.rs` — argon2 + JWT (jsonwebtoken)
|
|
||||||
- [ ] `src/auth/handlers.rs` — register/login/logout
|
|
||||||
- [ ] `src/auth/middleware.rs` — Bearer token → 401, не panic
|
|
||||||
|
|
||||||
## Фаза 3: Profile API
|
|
||||||
- [ ] `src/profile/mod.rs` — get/update/playtime/search/friends
|
|
||||||
|
|
||||||
## Фаза 4: Configs API
|
|
||||||
- [ ] `src/config_api/mod.rs` — upload/download
|
|
||||||
- [ ] 16-byte share keys (минимум)
|
|
||||||
|
|
||||||
## Фаза 5: IRC
|
|
||||||
- [ ] `src/irc/mod.rs` — WebSocket хаб (axum + tokio-tungstenite)
|
|
||||||
|
|
||||||
## Фаза 6: Middleware
|
|
||||||
- [ ] RateLimit — с cleanup-задачей (без утечки)
|
|
||||||
- [ ] Request logging через tracing
|
|
||||||
|
|
||||||
### Проверка после каждой фазы: `cargo fmt && cargo clippy --all-targets && cargo test`
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
//! LoVisual backend server entry point.
|
|
||||||
|
|
||||||
mod routes;
|
|
||||||
mod server;
|
|
||||||
|
|
||||||
use std::net::SocketAddr;
|
|
||||||
|
|
||||||
use anyhow::Context as _;
|
|
||||||
|
|
||||||
use server::config::Config;
|
|
||||||
use server::serve;
|
|
||||||
|
|
||||||
fn main() -> anyhow::Result<()> {
|
|
||||||
tracing_subscriber::fmt()
|
|
||||||
.with_env_filter(
|
|
||||||
tracing_subscriber::EnvFilter::try_from_default_env()
|
|
||||||
.unwrap_or_else(|_| "lovisual_backend=info,tower_http=info".into()),
|
|
||||||
)
|
|
||||||
.init();
|
|
||||||
|
|
||||||
let config = Config::from_env().context("failed to load config")?;
|
|
||||||
let addr: SocketAddr = config.listen_addr();
|
|
||||||
tracing::info!(%addr, "starting lovisual backend");
|
|
||||||
|
|
||||||
tokio::runtime::Builder::new_multi_thread()
|
|
||||||
.enable_all()
|
|
||||||
.build()
|
|
||||||
.context("failed to build tokio runtime")?
|
|
||||||
.block_on(serve(config))
|
|
||||||
}
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
//! Health/liveness endpoints.
|
|
||||||
|
|
||||||
use axum::Router;
|
|
||||||
use axum::routing::get;
|
|
||||||
use serde::Serialize;
|
|
||||||
|
|
||||||
/// Health response body.
|
|
||||||
#[derive(Debug, Serialize)]
|
|
||||||
pub struct Health {
|
|
||||||
pub status: &'static str,
|
|
||||||
pub version: &'static str,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Build the health router.
|
|
||||||
pub fn router() -> Router {
|
|
||||||
Router::new().route("/health", get(health))
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn health() -> axum::Json<Health> {
|
|
||||||
axum::Json(Health {
|
|
||||||
status: "ok",
|
|
||||||
version: env!("CARGO_PKG_VERSION"),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use axum::body::Body;
|
|
||||||
use axum::http::{Request, StatusCode};
|
|
||||||
use tower::ServiceExt as _;
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn health_returns_ok() {
|
|
||||||
let response = router()
|
|
||||||
.oneshot(
|
|
||||||
Request::builder()
|
|
||||||
.uri("/health")
|
|
||||||
.body(Body::empty())
|
|
||||||
.unwrap(),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
assert_eq!(response.status(), StatusCode::OK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
//! Route definitions.
|
|
||||||
//!
|
|
||||||
//! Top-level router; each domain (auth, profile, configs, irc) will add its
|
|
||||||
//! own sub-router here.
|
|
||||||
|
|
||||||
pub mod health;
|
|
||||||
|
|
||||||
use axum::Router;
|
|
||||||
|
|
||||||
/// Compose the full route tree.
|
|
||||||
pub fn router() -> Router {
|
|
||||||
Router::new().merge(health::router())
|
|
||||||
}
|
|
||||||
|
|
@ -1,120 +0,0 @@
|
||||||
//! Runtime configuration, loaded from environment variables.
|
|
||||||
//!
|
|
||||||
//! Parsed into validated types at the boundary; invalid values fail fast
|
|
||||||
//! at startup instead of blowing up mid-request.
|
|
||||||
|
|
||||||
use std::env;
|
|
||||||
use std::net::{IpAddr, SocketAddr};
|
|
||||||
|
|
||||||
use anyhow::{Context as _, Result, bail};
|
|
||||||
use axum::http::HeaderValue;
|
|
||||||
use tower_http::cors::AllowOrigin;
|
|
||||||
|
|
||||||
/// Application configuration.
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Config {
|
|
||||||
pub host: IpAddr,
|
|
||||||
pub port: u16,
|
|
||||||
pub cors_origins: AllowOrigin,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Config {
|
|
||||||
/// Default host for local development.
|
|
||||||
pub const DEFAULT_HOST: &'static str = "127.0.0.1";
|
|
||||||
/// Default port for local development.
|
|
||||||
pub const DEFAULT_PORT: u16 = 8765;
|
|
||||||
|
|
||||||
/// Load configuration from the environment.
|
|
||||||
pub fn from_env() -> Result<Self> {
|
|
||||||
Self::from_vars(
|
|
||||||
env::var("LOVISUAL_HOST").ok(),
|
|
||||||
env::var("LOVISUAL_PORT").ok(),
|
|
||||||
env::var("LOVISUAL_CORS_ORIGINS").ok(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Build config from raw option values (injectable for tests).
|
|
||||||
fn from_vars(host: Option<String>, port: Option<String>, cors: Option<String>) -> Result<Self> {
|
|
||||||
let host = host
|
|
||||||
.unwrap_or_else(|| Self::DEFAULT_HOST.to_owned())
|
|
||||||
.parse()
|
|
||||||
.context("LOVISUAL_HOST is not a valid IP address")?;
|
|
||||||
let port: u16 = match port {
|
|
||||||
Some(p) => p
|
|
||||||
.parse()
|
|
||||||
.context("LOVISUAL_PORT is not a valid port number")?,
|
|
||||||
None => Self::DEFAULT_PORT,
|
|
||||||
};
|
|
||||||
let origins = parse_origins(&cors)?;
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
host,
|
|
||||||
port,
|
|
||||||
cors_origins: origins,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Resolved listen address.
|
|
||||||
pub fn listen_addr(&self) -> SocketAddr {
|
|
||||||
SocketAddr::new(self.host, self.port)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_origins(raw: &Option<String>) -> Result<AllowOrigin> {
|
|
||||||
let Some(raw) = raw else {
|
|
||||||
// No origins configured: allow same-origin requests only.
|
|
||||||
return Ok(AllowOrigin::any());
|
|
||||||
};
|
|
||||||
|
|
||||||
let origins = raw
|
|
||||||
.split(',')
|
|
||||||
.map(str::trim)
|
|
||||||
.filter(|s| !s.is_empty())
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
if origins.is_empty() {
|
|
||||||
bail!("LOVISUAL_CORS_ORIGINS is set but contains no origins");
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(AllowOrigin::list(
|
|
||||||
origins
|
|
||||||
.into_iter()
|
|
||||||
.map(|o| o.parse::<HeaderValue>().context("invalid CORS origin"))
|
|
||||||
.collect::<Result<Vec<_>, _>>()?,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn empty_origins_allows_any() {
|
|
||||||
assert!(parse_origins(&None).is_ok());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn empty_list_origin_string_fails() {
|
|
||||||
assert!(parse_origins(&Some(String::from(",,"))).is_err());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn invalid_port_fails() {
|
|
||||||
let result = Config::from_vars(None, Some("not-a-port".into()), None);
|
|
||||||
assert!(result.is_err());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn invalid_host_fails() {
|
|
||||||
let result = Config::from_vars(Some("not-an-ip".into()), None, None);
|
|
||||||
assert!(result.is_err());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn defaults_apply_when_empty() {
|
|
||||||
let config = Config::from_vars(None, None, None).unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
config.listen_addr(),
|
|
||||||
SocketAddr::from(([127, 0, 0, 1], 8765))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
//! Server assembly: router, listener, graceful shutdown.
|
|
||||||
|
|
||||||
use anyhow::Context as _;
|
|
||||||
use axum::Router;
|
|
||||||
use tokio::net::TcpListener;
|
|
||||||
use tower_http::cors::CorsLayer;
|
|
||||||
use tower_http::trace::TraceLayer;
|
|
||||||
|
|
||||||
use super::routes;
|
|
||||||
use config::Config;
|
|
||||||
|
|
||||||
pub mod config;
|
|
||||||
|
|
||||||
/// Build the application router for a given config.
|
|
||||||
pub fn app(config: &Config) -> Router {
|
|
||||||
Router::new()
|
|
||||||
.merge(routes::router())
|
|
||||||
.layer(CorsLayer::new().allow_origin(config.cors_origins.clone()))
|
|
||||||
.layer(TraceLayer::new_for_http())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Bind and serve the application until a shutdown signal arrives.
|
|
||||||
pub async fn serve(config: Config) -> anyhow::Result<()> {
|
|
||||||
let listener = TcpListener::bind(config.listen_addr())
|
|
||||||
.await
|
|
||||||
.context("failed to bind listener")?;
|
|
||||||
|
|
||||||
axum::serve(listener, app(&config))
|
|
||||||
.with_graceful_shutdown(shutdown_signal())
|
|
||||||
.await
|
|
||||||
.context("server error")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Resolves on SIGTERM/SIGINT.
|
|
||||||
async fn shutdown_signal() {
|
|
||||||
let ctrl_c = async {
|
|
||||||
tokio::signal::ctrl_c()
|
|
||||||
.await
|
|
||||||
.expect("failed to install ctrl-c handler");
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
let terminate = async {
|
|
||||||
tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate())
|
|
||||||
.expect("failed to install SIGTERM handler")
|
|
||||||
.recv()
|
|
||||||
.await;
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg(not(unix))]
|
|
||||||
let terminate = std::future::pending::<()>();
|
|
||||||
|
|
||||||
tokio::select! {
|
|
||||||
_ = ctrl_c => {},
|
|
||||||
_ = terminate => {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
# LoVisual
|
# LoVisual
|
||||||
|
|
||||||
Minecraft utility client for PvP and automation.
|
Minecraft utility client for PvP and automation.
|
||||||
Fork of [Combatant Client], built on ideas from LiquidBounce, Meteor, and ThunderHack.
|
Developed and maintained by loki5512344.
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||
|
|
@ -21,7 +21,7 @@ Fork of [Combatant Client], built on ideas from LiquidBounce, Meteor, and Thunde
|
||||||
|
|
||||||
LoVisual is an open-source utility and PvP client for Minecraft. It provides configurable combat, movement, visual, automation, HUD, and UI features with a custom ClickGUI, theme system, and addon API.
|
LoVisual is an open-source utility and PvP client for Minecraft. It provides configurable combat, movement, visual, automation, HUD, and UI features with a custom ClickGUI, theme system, and addon API.
|
||||||
|
|
||||||
This repository is a **fork** of [Combatant Client], which drew inspiration from [LiquidBounce], [Meteor Client], and [ThunderHack Recode]. The goal is to continue development, add new features, and maintain compatibility with the latest Minecraft versions.
|
LoVisual is developed and maintained by [loki5512344](https://github.com/loki5512344). The goal is to keep adding new features and maintain compatibility with the latest Minecraft versions.
|
||||||
|
|
||||||
### Quick Start
|
### Quick Start
|
||||||
|
|
||||||
|
|
@ -77,7 +77,7 @@ This repository is a **fork** of [Combatant Client], which drew inspiration from
|
||||||
|
|
||||||
LoVisual — открытый утилитарный и PvP-клиент для Minecraft. Включает настраиваемые боевые, двигательные, визуальные и автоматизированные модули, кастомный ClickGUI, систему тем и API для аддонов.
|
LoVisual — открытый утилитарный и PvP-клиент для Minecraft. Включает настраиваемые боевые, двигательные, визуальные и автоматизированные модули, кастомный ClickGUI, систему тем и API для аддонов.
|
||||||
|
|
||||||
Этот репозиторий является **форком** [Combatant Client], который в свою очередь черпал вдохновение из [LiquidBounce], [Meteor Client] и [ThunderHack Recode]. Цель — продолжать разработку, добавлять новые возможности и поддерживать актуальные версии Minecraft.
|
LoVisual разрабатывается и поддерживается [loki5512344](https://github.com/loki5512344). Цель — добавлять новые возможности и поддерживать актуальные версии Minecraft.
|
||||||
|
|
||||||
### Быстрый старт
|
### Быстрый старт
|
||||||
|
|
||||||
|
|
@ -147,49 +147,6 @@ GNU General Public License v3.0. See [LICENSE](LICENSE).
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
### Фаза 1: Переименование (Rebrand)
|
План разработки и актуальный статус ведутся в [TODO.md](TODO.md).
|
||||||
- [ ] Переименовать package `combatant` → `dev.loki.lovisual`
|
|
||||||
- [ ] Переименовать mod ID `combatant` → `lovisual`
|
|
||||||
- [ ] Сменить название клиента везде (Combatant → LoVisual)
|
|
||||||
- [ ] Обновить `fabric.mod.json`, `mixins.json`
|
|
||||||
- [ ] Обновить все нативные сообщения и debug-строки
|
|
||||||
|
|
||||||
### Фаза 2: Косметические изменения
|
[loki5512344]: https://github.com/loki5512344
|
||||||
- [ ] Заменить `.cbcfg` → `.lvisual`, путь `config/combatant/` → `config/lovisual/`
|
|
||||||
- [ ] Префикс команд оставить `@`
|
|
||||||
- [ ] Новый splash/watermark, иконки, логотип
|
|
||||||
- [ ] Переписать `theme` под LoVisual-стиль
|
|
||||||
|
|
||||||
### Фаза 3: Рефакторинг
|
|
||||||
- [ ] Выкинуть ненужное: дебажные фичи, лишние интеграции (iris/sodium compat оставить)
|
|
||||||
- [ ] Разбить большие файлы (> 1500 строк): Scaffold, KillAura, AutoCrystal, Renderer2D
|
|
||||||
- [ ] Привести структуру к единому стандарту (нейминг, форматирование)
|
|
||||||
|
|
||||||
### Фаза 4: Модули
|
|
||||||
- [ ] Добавить модули из `ref/modules/` (Sprint, Velocity, AntiAFK, AutoRespawn, AutoFish, ...)
|
|
||||||
- [ ] Переписать IRC-модуль (WebSocket)
|
|
||||||
- [ ] Сделать облачные конфиги (CloudAPI)
|
|
||||||
|
|
||||||
### Фаза 5: Backend (Go)
|
|
||||||
- [ ] Написать бэкенд с нуля (Go + chi + SQLite)
|
|
||||||
- [ ] Auth (bcrypt, JWT), профили, друзья
|
|
||||||
- [ ] WebSocket хаб для IRC
|
|
||||||
- [ ] REST API для облачных конфигов
|
|
||||||
|
|
||||||
### Фаза 6: Лаунчер (Rust)
|
|
||||||
- [ ] Написать лаунчер с нуля (Rust + egui)
|
|
||||||
- [ ] Логин/регистрация, дашборд, настройки
|
|
||||||
- [ ] Авто-запуск Minecraft с модом
|
|
||||||
- [ ] Авто-обновление
|
|
||||||
|
|
||||||
### Фаза 7: Polish
|
|
||||||
- [ ] Звуки (49 звуков)
|
|
||||||
- [ ] Анимации (SpringAnimator)
|
|
||||||
- [ ] 6 стилей HUD
|
|
||||||
- [ ] Load-экран
|
|
||||||
- [ ] Главное меню (MainMenu)
|
|
||||||
|
|
||||||
[Combatant Client]: https://github.com/pivosos2007/combatant
|
|
||||||
[LiquidBounce]: https://github.com/CCBlueX/LiquidBounce
|
|
||||||
[Meteor Client]: https://github.com/MeteorDevelopment/meteor-client
|
|
||||||
[ThunderHack Recode]: https://github.com/Pan4ur/ThunderHack-Recode
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
### 1. Ребрендинг не закончен (пункт 2)
|
### 1. Ребрендинг не закончен (пункт 2)
|
||||||
- 288 файлов / **1464 упоминания** `combatant` в main-коде
|
- 288 файлов / **1464 упоминания** `combatant` в main-коде
|
||||||
- Классы: `CombatantRenderSystem`, `CombatantRenderEngineBootstrap`, `CombatantRenderPipelines`, `CombatantVulkanBackend`, `CombatantFrameGraph`, `CombatantTerrainVertex` и др.
|
- Классы: `CombatantRenderSystem`, `CombatantRenderEngineBootstrap`, `CombatantRenderPipelines`, `CombatantVulkanBackend`, `CombatantFrameGraph`, `CombatantTerrainVertex` и др.
|
||||||
- Заголовки файлов: «This file is part of the Combatant Client distribution» / `copyright (c) pivosos2007`
|
- Заголовки файлов: «This file is part of the Combatant Client distribution» / копирайт изначального автора
|
||||||
|
|
||||||
### 2. Файлы-гиганты (пункт 3) — 12 файлов > 1500 строк
|
### 2. Файлы-гиганты (пункт 3) — 12 файлов > 1500 строк
|
||||||
| Файл | Строк |
|
| Файл | Строк |
|
||||||
|
|
|
||||||
|
|
@ -389,7 +389,7 @@ publishing {
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
maven {
|
||||||
name = "GitHubPackages"
|
name = "GitHubPackages"
|
||||||
url = uri("https://maven.pkg.github.com/pivosos2007/lovisual-client")
|
url = uri("https://maven.pkg.github.com/loki5512344/lovisual-client")
|
||||||
credentials {
|
credentials {
|
||||||
username = findProperty("gpr.user") ?: System.getenv("GITHUB_ACTOR") ?: ""
|
username = findProperty("gpr.user") ?: System.getenv("GITHUB_ACTOR") ?: ""
|
||||||
password = findProperty("gpr.key") ?: System.getenv("GITHUB_TOKEN") ?: System.getenv("GH_TOKEN") ?: ""
|
password = findProperty("gpr.key") ?: System.getenv("GITHUB_TOKEN") ?: System.getenv("GH_TOKEN") ?: ""
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ minecraft_version=26.2
|
||||||
loader_version=0.19.3
|
loader_version=0.19.3
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version=0.1.1
|
mod_version=0.1.1
|
||||||
maven_group=pivosos2007
|
maven_group=dev.loki
|
||||||
archives_base_name=lovisual
|
archives_base_name=lovisual
|
||||||
# Dependencies
|
# Dependencies
|
||||||
# check this on https://modmuss50.me/fabric.html
|
# check this on https://modmuss50.me/fabric.html
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
@ -332,7 +332,6 @@ public class LoVisual implements ClientModInitializer {
|
||||||
|
|
||||||
// === ТИКИ ===
|
// === ТИКИ ===
|
||||||
|
|
||||||
|
|
||||||
ClientTickEvents.START_CLIENT_TICK.register(client -> {
|
ClientTickEvents.START_CLIENT_TICK.register(client -> {
|
||||||
if (client.player == null) return;
|
if (client.player == null) return;
|
||||||
if (!Lifecycle.isActive()) return;
|
if (!Lifecycle.isActive()) return;
|
||||||
|
|
@ -377,7 +376,6 @@ public class LoVisual implements ClientModInitializer {
|
||||||
ctx.submitNodeCollector()
|
ctx.submitNodeCollector()
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
// === HUD 2D OVERLAYS ===
|
// === HUD 2D OVERLAYS ===
|
||||||
|
|
||||||
HudElementRegistry.addFirst(
|
HudElementRegistry.addFirst(
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
@ -436,7 +436,6 @@ public enum ConfigSerializer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static JsonLookup findJsonElement(ConfigObject obj, JsonObject root, String valueName) {
|
private static JsonLookup findJsonElement(ConfigObject obj, JsonObject root, String valueName) {
|
||||||
if (root == null || valueName == null) return JsonLookup.missing();
|
if (root == null || valueName == null) return JsonLookup.missing();
|
||||||
JsonElement direct = root.get(valueName);
|
JsonElement direct = root.get(valueName);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package dev.loki.lovisual.config.profile;
|
package dev.loki.lovisual.config.profile;
|
||||||
|
|
||||||
|
|
||||||
import dev.loki.lovisual.features.theme.Theme;
|
import dev.loki.lovisual.features.theme.Theme;
|
||||||
import dev.loki.lovisual.config.ConfigObject;
|
import dev.loki.lovisual.config.ConfigObject;
|
||||||
import dev.loki.lovisual.config.values.ConfigValue;
|
import dev.loki.lovisual.config.values.ConfigValue;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package dev.loki.lovisual.config.profile;
|
package dev.loki.lovisual.config.profile;
|
||||||
|
|
||||||
|
|
||||||
import dev.loki.lovisual.features.theme.Theme;
|
import dev.loki.lovisual.features.theme.Theme;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import dev.loki.lovisual.config.ConfigObject;
|
import dev.loki.lovisual.config.ConfigObject;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
@ -20,15 +20,25 @@ import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
public final class ConfigProfileStorage {
|
public final class ConfigProfileStorage {
|
||||||
public static final String EXTENSION = ".cbcfg";
|
public static final String EXTENSION = ".lvcfg";
|
||||||
private static final Path ROOT = ConfigPaths.profilesRoot();
|
public static final String LEGACY_EXTENSION = ".cbcfg";
|
||||||
|
|
||||||
|
private final Path root;
|
||||||
private final ConfigProfileBinaryCodec codec = new ConfigProfileBinaryCodec();
|
private final ConfigProfileBinaryCodec codec = new ConfigProfileBinaryCodec();
|
||||||
|
|
||||||
|
public ConfigProfileStorage() {
|
||||||
|
this(ConfigPaths.profilesRoot());
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigProfileStorage(Path root) {
|
||||||
|
this.root = root;
|
||||||
|
}
|
||||||
|
|
||||||
public static String sanitizeFileName(String name) {
|
public static String sanitizeFileName(String name) {
|
||||||
if (name == null) return "config";
|
if (name == null) return "config";
|
||||||
String base = name.trim().toLowerCase(Locale.ROOT);
|
String base = name.trim().toLowerCase(Locale.ROOT);
|
||||||
if (base.endsWith(EXTENSION)) base = base.substring(0, base.length() - EXTENSION.length());
|
base = stripExtension(base, EXTENSION);
|
||||||
|
base = stripExtension(base, LEGACY_EXTENSION);
|
||||||
if (base.isEmpty()) return "config";
|
if (base.isEmpty()) return "config";
|
||||||
StringBuilder out = new StringBuilder(base.length());
|
StringBuilder out = new StringBuilder(base.length());
|
||||||
for (int i = 0; i < base.length(); i++) {
|
for (int i = 0; i < base.length(); i++) {
|
||||||
|
|
@ -42,12 +52,17 @@ public final class ConfigProfileStorage {
|
||||||
return out.length() == 0 ? "config" : out.toString();
|
return out.length() == 0 ? "config" : out.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String stripExtension(String value, String extension) {
|
||||||
|
if (value.endsWith(extension)) return value.substring(0, value.length() - extension.length());
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
public Path root() {
|
public Path root() {
|
||||||
return ROOT;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Path directory(ConfigProfileType type) {
|
public Path directory(ConfigProfileType type) {
|
||||||
return ROOT.resolve(type.folderName());
|
return root.resolve(type.folderName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ConfigProfileMeta> list(ConfigProfileType type) {
|
public List<ConfigProfileMeta> list(ConfigProfileType type) {
|
||||||
|
|
@ -56,7 +71,7 @@ public final class ConfigProfileStorage {
|
||||||
Path dir = directory(type);
|
Path dir = directory(type);
|
||||||
if (!Files.isDirectory(dir)) return out;
|
if (!Files.isDirectory(dir)) return out;
|
||||||
try (var stream = Files.list(dir)) {
|
try (var stream = Files.list(dir)) {
|
||||||
stream.filter(path -> Files.isRegularFile(path) && path.getFileName().toString().endsWith(EXTENSION))
|
stream.filter(path -> Files.isRegularFile(path) && hasProfileExtension(path))
|
||||||
.forEach(path -> {
|
.forEach(path -> {
|
||||||
try {
|
try {
|
||||||
ConfigProfileMeta meta = codec.readMeta(Files.readAllBytes(path));
|
ConfigProfileMeta meta = codec.readMeta(Files.readAllBytes(path));
|
||||||
|
|
@ -72,12 +87,16 @@ public final class ConfigProfileStorage {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean hasProfileExtension(Path path) {
|
||||||
|
String name = path.getFileName().toString().toLowerCase(Locale.ROOT);
|
||||||
|
return name.endsWith(EXTENSION) || name.endsWith(LEGACY_EXTENSION);
|
||||||
|
}
|
||||||
|
|
||||||
public ImportResult importProfileFile(Path source, boolean moveSource) throws IOException {
|
public ImportResult importProfileFile(Path source, boolean moveSource) throws IOException {
|
||||||
if (source == null) throw new IllegalArgumentException("profile path is null");
|
if (source == null) throw new IllegalArgumentException("profile path is null");
|
||||||
if (!Files.isRegularFile(source)) throw new IOException("profile is not a regular file: " + source);
|
if (!Files.isRegularFile(source)) throw new IOException("profile is not a regular file: " + source);
|
||||||
String fileName = source.getFileName() == null ? "" : source.getFileName().toString();
|
if (!hasProfileExtension(source)) {
|
||||||
if (!fileName.toLowerCase(Locale.ROOT).endsWith(EXTENSION)) {
|
throw new IOException("not a " + EXTENSION + " or " + LEGACY_EXTENSION + " profile: " + source);
|
||||||
throw new IOException("not a " + EXTENSION + " profile: " + source);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] bytes = Files.readAllBytes(source);
|
byte[] bytes = Files.readAllBytes(source);
|
||||||
|
|
@ -98,7 +117,7 @@ public final class ConfigProfileStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConfigProfileSnapshot read(ConfigProfileType type, String idOrName) throws IOException {
|
public ConfigProfileSnapshot read(ConfigProfileType type, String idOrName) throws IOException {
|
||||||
Path path = file(type, idOrName);
|
Path path = resolveExisting(type, idOrName);
|
||||||
return codec.read(Files.readAllBytes(path));
|
return codec.read(Files.readAllBytes(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,8 +135,9 @@ public final class ConfigProfileStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean delete(ConfigProfileType type, String idOrName) throws IOException {
|
public boolean delete(ConfigProfileType type, String idOrName) throws IOException {
|
||||||
Path path = file(type, idOrName);
|
boolean deleted = Files.deleteIfExists(file(type, idOrName));
|
||||||
return Files.deleteIfExists(path);
|
deleted |= Files.deleteIfExists(legacyFile(type, idOrName));
|
||||||
|
return deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConfigProfileSnapshot rename(ConfigProfileType type, String idOrName, String newName) throws IOException {
|
public ConfigProfileSnapshot rename(ConfigProfileType type, String idOrName, String newName) throws IOException {
|
||||||
|
|
@ -125,7 +145,7 @@ public final class ConfigProfileStorage {
|
||||||
ConfigProfileSnapshot old = read(type, idOrName);
|
ConfigProfileSnapshot old = read(type, idOrName);
|
||||||
ConfigProfileMeta oldMeta = old.meta();
|
ConfigProfileMeta oldMeta = old.meta();
|
||||||
ConfigProfileMeta newMeta = oldMeta.withName(newName.trim(), System.currentTimeMillis());
|
ConfigProfileMeta newMeta = oldMeta.withName(newName.trim(), System.currentTimeMillis());
|
||||||
Path oldPath = file(type, oldMeta.getId());
|
Path oldPath = resolveExisting(type, oldMeta.getId());
|
||||||
Path newPath = file(type, newMeta.getId());
|
Path newPath = file(type, newMeta.getId());
|
||||||
if (!oldMeta.getId().equals(newMeta.getId()) && Files.exists(newPath)) {
|
if (!oldMeta.getId().equals(newMeta.getId()) && Files.exists(newPath)) {
|
||||||
throw new IOException("profile already exists: " + newMeta.name());
|
throw new IOException("profile already exists: " + newMeta.name());
|
||||||
|
|
@ -137,24 +157,42 @@ public final class ConfigProfileStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean exists(ConfigProfileType type, String idOrName) {
|
public boolean exists(ConfigProfileType type, String idOrName) {
|
||||||
return Files.exists(file(type, idOrName));
|
return Files.exists(file(type, idOrName)) || Files.exists(legacyFile(type, idOrName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Canonical storage path — always uses the current {@link #EXTENSION}. */
|
||||||
public Path file(ConfigProfileType type, String idOrName) {
|
public Path file(ConfigProfileType type, String idOrName) {
|
||||||
String id = sanitizeFileName(idOrName);
|
String id = sanitizeFileName(idOrName);
|
||||||
if (!id.endsWith(EXTENSION)) id += EXTENSION;
|
if (id.endsWith(LEGACY_EXTENSION)) {
|
||||||
|
id = stripExtension(id, LEGACY_EXTENSION) + EXTENSION;
|
||||||
|
} else if (!id.endsWith(EXTENSION)) {
|
||||||
|
id += EXTENSION;
|
||||||
|
}
|
||||||
return directory(type).resolve(id);
|
return directory(type).resolve(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Path legacyFile(ConfigProfileType type, String idOrName) {
|
||||||
|
String id = sanitizeFileName(idOrName);
|
||||||
|
if (!id.endsWith(LEGACY_EXTENSION)) id += LEGACY_EXTENSION;
|
||||||
|
return directory(type).resolve(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path resolveExisting(ConfigProfileType type, String idOrName) {
|
||||||
|
Path canonical = file(type, idOrName);
|
||||||
|
if (Files.exists(canonical)) return canonical;
|
||||||
|
Path legacy = legacyFile(type, idOrName);
|
||||||
|
return Files.exists(legacy) ? legacy : canonical;
|
||||||
|
}
|
||||||
|
|
||||||
private void normalizeLooseProfiles() {
|
private void normalizeLooseProfiles() {
|
||||||
if (!Files.isDirectory(ROOT)) return;
|
if (!Files.isDirectory(root)) return;
|
||||||
List<Path> candidates = new ArrayList<>();
|
List<Path> candidates = new ArrayList<>();
|
||||||
try (var stream = Files.walk(ROOT)) {
|
try (var stream = Files.walk(root)) {
|
||||||
stream.filter(Files::isRegularFile)
|
stream.filter(Files::isRegularFile)
|
||||||
.filter(path -> path.getFileName().toString().toLowerCase(Locale.ROOT).endsWith(EXTENSION))
|
.filter(ConfigProfileStorage::hasProfileExtension)
|
||||||
.forEach(candidates::add);
|
.forEach(candidates::add);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
DebugLog.error("Failed to scan loose config profiles %s", e, ROOT.toAbsolutePath());
|
DebugLog.error("Failed to scan loose config profiles %s", e, root.toAbsolutePath());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the LoVisual Client distribution.
|
* This file is part of the LoVisual Client distribution.
|
||||||
* Copyright (c) 2026 pivosos2007.
|
* Copyright (c) 2026 loki5512344.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License v3.0.
|
* Licensed under the GNU General Public License v3.0.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue