mirror of
https://github.com/shiroyashik/sculptor.git
synced 2025-12-06 13:01:12 +03:00
(*≧ω≦*) Preparing for 0.3.0 release!
~ README revised ~ updated Docker files + all const are placed in a separate file + auto creation for avatars folder + automatic retrieval of the latest Figura version for version request in api
This commit is contained in:
parent
d45a495cbf
commit
dabe176e0e
13 changed files with 355 additions and 224 deletions
|
|
@ -1,13 +1,29 @@
|
|||
use axum::{extract::State, Json};
|
||||
use serde_json::{json, Value};
|
||||
use tracing::error;
|
||||
|
||||
use crate::{utils::get_motd, AppState};
|
||||
use crate::{
|
||||
utils::{get_figura_versions, get_motd, FiguraVersions}, AppState, FIGURA_DEFAULT_VERSION
|
||||
};
|
||||
|
||||
pub async fn version() -> Json<Value> {
|
||||
Json(json!({
|
||||
"release": "0.1.4",
|
||||
"prerelease": "0.1.4"
|
||||
}))
|
||||
pub async fn version(State(state): State<AppState>) -> Json<FiguraVersions> {
|
||||
let res = state.figura_versions.read().await.clone();
|
||||
if let Some(res) = res {
|
||||
Json(res)
|
||||
} else {
|
||||
let actual = get_figura_versions().await;
|
||||
if let Ok(res) = actual {
|
||||
let mut stored = state.figura_versions.write().await;
|
||||
*stored = Some(res);
|
||||
return Json(stored.clone().unwrap())
|
||||
} else {
|
||||
error!("get_figura_versions: {:?}", actual.unwrap_err());
|
||||
}
|
||||
Json(FiguraVersions {
|
||||
release: FIGURA_DEFAULT_VERSION.to_string(),
|
||||
prerelease: FIGURA_DEFAULT_VERSION.to_string()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn motd(State(state): State<AppState>) -> String {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@ use tokio::{
|
|||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
api::errors::internal_and_log, auth::Token, utils::{calculate_file_sha256, format_uuid}, ApiError, ApiResult, AppState
|
||||
api::errors::internal_and_log,
|
||||
auth::Token, utils::{calculate_file_sha256, format_uuid},
|
||||
ApiError, ApiResult, AppState
|
||||
};
|
||||
use super::types::S2CMessage;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::{sync::Arc, time::Duration};
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use axum::{
|
||||
|
|
@ -8,12 +8,10 @@ use dashmap::DashMap;
|
|||
use tracing::{debug, error, trace};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{ApiError, ApiResult, AppState};
|
||||
use crate::{ApiError, ApiResult, AppState, TIMEOUT, USER_AGENT};
|
||||
|
||||
use super::types::*;
|
||||
|
||||
const TIMEOUT: Duration = Duration::from_secs(5);
|
||||
|
||||
// It's an extractor that pulls a token from the Header.
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct Token(pub String);
|
||||
|
|
@ -63,7 +61,7 @@ async fn fetch_json(
|
|||
server_id: &str,
|
||||
username: &str,
|
||||
) -> anyhow::Result<anyhow::Result<(Uuid, AuthProvider)>> {
|
||||
let client = reqwest::Client::builder().timeout(TIMEOUT).build().unwrap();
|
||||
let client = reqwest::Client::builder().timeout(TIMEOUT).user_agent(USER_AGENT).build().unwrap();
|
||||
let url = auth_provider.url.clone();
|
||||
|
||||
let res = client
|
||||
|
|
|
|||
12
src/consts.rs
Normal file
12
src/consts.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
pub const LOGGER_ENV: &'static str = "RUST_LOG";
|
||||
pub const CONFIG_ENV: &'static str = "RUST_CONFIG";
|
||||
pub const LOGS_ENV: &'static str = "LOGS_FOLDER";
|
||||
|
||||
pub const SCULPTOR_VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
||||
pub const REPOSITORY: &'static str = "shiroyashik/sculptor";
|
||||
|
||||
pub const USER_AGENT: &'static str = "reqwest";
|
||||
pub const TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
|
||||
|
||||
pub const FIGURA_RELEASES_URL: &'static str = "https://api.github.com/repos/figuramc/figura/releases";
|
||||
pub const FIGURA_DEFAULT_VERSION: &'static str = "0.1.4";
|
||||
27
src/main.rs
27
src/main.rs
|
|
@ -5,12 +5,16 @@ use axum::{
|
|||
use dashmap::DashMap;
|
||||
use tracing_panic::panic_hook;
|
||||
use tracing_subscriber::{fmt::{self, time::ChronoLocal}, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};
|
||||
use std::sync::Arc;
|
||||
use tokio::{sync::{broadcast, mpsc, RwLock}, time::Instant};
|
||||
use std::{path::PathBuf, sync::Arc};
|
||||
use tokio::{fs, sync::{broadcast, mpsc, RwLock}, time::Instant};
|
||||
use tower_http::trace::TraceLayer;
|
||||
use tracing::info;
|
||||
use uuid::Uuid;
|
||||
|
||||
// Consts
|
||||
mod consts;
|
||||
pub use consts::*;
|
||||
|
||||
// Errors
|
||||
pub use api::errors::{ApiResult, ApiError};
|
||||
|
||||
|
|
@ -31,7 +35,7 @@ use state::Config;
|
|||
|
||||
// Utils
|
||||
mod utils;
|
||||
use utils::{check_updates, get_log_file, update_advanced_users, update_bans_from_minecraft};
|
||||
use utils::{check_updates, get_log_file, update_advanced_users, update_bans_from_minecraft, FiguraVersions};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AppState {
|
||||
|
|
@ -45,14 +49,10 @@ pub struct AppState {
|
|||
broadcasts: Arc<DashMap<Uuid, broadcast::Sender<Vec<u8>>>>,
|
||||
/// Current configuration
|
||||
config: Arc<RwLock<state::Config>>,
|
||||
/// Figura Versions
|
||||
figura_versions: Arc<RwLock<Option<FiguraVersions>>>,
|
||||
}
|
||||
|
||||
const LOGGER_ENV: &'static str = "RUST_LOG";
|
||||
const CONFIG_ENV: &'static str = "RUST_CONFIG";
|
||||
const LOGS_ENV: &'static str = "LOGS_FOLDER";
|
||||
const SCULPTOR_VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
||||
const REPOSITORY: &'static str = "shiroyashik/sculptor";
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
let _ = dotenvy::dotenv();
|
||||
|
|
@ -92,6 +92,14 @@ async fn main() -> Result<()> {
|
|||
// }));
|
||||
|
||||
info!("The Sculptor v{}{}", SCULPTOR_VERSION, check_updates(REPOSITORY, &SCULPTOR_VERSION).await?);
|
||||
|
||||
{
|
||||
let path = PathBuf::from("avatars");
|
||||
if !path.exists() {
|
||||
fs::create_dir(path).await.expect("Can't create avatars folder!");
|
||||
info!("Created avatars directory");
|
||||
}
|
||||
}
|
||||
|
||||
// Config
|
||||
let config = Arc::new(RwLock::new(Config::parse(config_file.clone().into())));
|
||||
|
|
@ -103,6 +111,7 @@ async fn main() -> Result<()> {
|
|||
user_manager: Arc::new(UManager::new()),
|
||||
session: Arc::new(DashMap::new()),
|
||||
broadcasts: Arc::new(DashMap::new()),
|
||||
figura_versions: Arc::new(RwLock::new(None)),
|
||||
config,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
use anyhow::anyhow;
|
||||
use reqwest::Client;
|
||||
use semver::Version;
|
||||
use serde::Deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tracing::error;
|
||||
|
||||
use crate::{FIGURA_RELEASES_URL, TIMEOUT, USER_AGENT};
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct Tag {
|
||||
name: String
|
||||
|
|
@ -11,8 +13,8 @@ struct Tag {
|
|||
|
||||
async fn get_latest_version(repo: &str, current_version: Version) -> anyhow::Result<Option<String>> {
|
||||
let url = format!("https://api.github.com/repos/{repo}/tags");
|
||||
let client = Client::new();
|
||||
let response = client.get(&url).header("User-Agent", "reqwest").send().await?;
|
||||
let client = Client::builder().timeout(TIMEOUT).user_agent(USER_AGENT).build().unwrap();
|
||||
let response = client.get(&url).send().await?;
|
||||
|
||||
if response.status().is_success() {
|
||||
let tags: Vec<Tag> = response.json().await?;
|
||||
|
|
@ -55,3 +57,50 @@ pub async fn check_updates(repo: &str, current_version: &str) -> anyhow::Result<
|
|||
}
|
||||
}
|
||||
|
||||
// Figura
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct Release {
|
||||
tag_name: String,
|
||||
prerelease: bool
|
||||
}
|
||||
|
||||
pub async fn get_figura_versions() -> anyhow::Result<FiguraVersions> {
|
||||
let client = Client::builder().timeout(TIMEOUT).user_agent(USER_AGENT).build().unwrap();
|
||||
let response = client.get(FIGURA_RELEASES_URL).send().await?;
|
||||
|
||||
let mut release_ver = Version::new(0, 0, 0);
|
||||
let mut prerelease_ver = Version::new(0, 0, 0);
|
||||
|
||||
if response.status().is_success() {
|
||||
let multiple_releases: Vec<Release> = response.json().await?;
|
||||
for release in multiple_releases {
|
||||
let tag_ver = if let Ok(res) = Version::parse(&release.tag_name) { res } else {
|
||||
error!("Incorrect tag name! {release:?}");
|
||||
continue;
|
||||
};
|
||||
if release.prerelease {
|
||||
if tag_ver > prerelease_ver {
|
||||
prerelease_ver = tag_ver
|
||||
}
|
||||
} else {
|
||||
if tag_ver > release_ver {
|
||||
release_ver = tag_ver
|
||||
}
|
||||
}
|
||||
}
|
||||
if release_ver > prerelease_ver {
|
||||
prerelease_ver = release_ver.clone();
|
||||
}
|
||||
// Stop
|
||||
Ok(FiguraVersions { release: release_ver.to_string(), prerelease: prerelease_ver.to_string() })
|
||||
} else {
|
||||
Err(anyhow!("Response status code: {}", response.status().as_u16()))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug, Clone)]
|
||||
pub struct FiguraVersions {
|
||||
pub release: String,
|
||||
pub prerelease: String
|
||||
}
|
||||
|
|
@ -4,4 +4,4 @@ mod motd;
|
|||
|
||||
pub use utils::*;
|
||||
pub use motd::*;
|
||||
pub use check_updates::check_updates;
|
||||
pub use check_updates::*;
|
||||
Loading…
Add table
Add a link
Reference in a new issue