Skip to content

Commit

Permalink
🎉WebSocket refactored!
Browse files Browse the repository at this point in the history
  • Loading branch information
shiroyashik committed Oct 28, 2024
1 parent 7a4f3dc commit 4c0871e
Show file tree
Hide file tree
Showing 30 changed files with 650 additions and 587 deletions.
323 changes: 146 additions & 177 deletions Cargo.lock

Large diffs are not rendered by default.

52 changes: 26 additions & 26 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,40 +7,40 @@ publish = false

[dependencies]
# Logging
tracing-subscriber = { version = "0.3.18", features = ["env-filter", "chrono"] }
tracing-appender = "0.2.3"
tracing-panic = "0.1.2"
tracing = "0.1.40"
tracing-subscriber = { version = "0.3", features = ["env-filter", "chrono"] }
tracing-appender = "0.2"
tracing-panic = "0.1"
tracing = "0.1"

# Errors handelers
anyhow = "1.0.83"
thiserror = "1.0.64"
chrono = { version = "0.4.38", features = ["now", "serde"] }
serde = { version = "1.0.201", features = ["derive"] }
serde_json = "1.0.117"
toml = "0.8.19"
anyhow = "1.0"
thiserror = "1.0"
chrono = { version = "0.4", features = ["now", "serde"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
toml = "0.8"

# Other
dashmap = { version = "6.0.1", features = ["serde"] }
hex = "0.4.3"
uuid = { version = "1.8.0", features = ["serde"] }
base64 = "0.22.1"
reqwest = { version = "0.12.7", features = ["blocking", "json"] }
dotenvy = "0.15.7"
semver = "1.0.23"
walkdir = "2.5.0"
dashmap = { version = "6.0", features = ["serde"] }
hex = "0.4"
uuid = { version = "1.11", features = ["serde"] }
base64 = "0.22"
reqwest = { version = "0.12", features = ["blocking", "json"] }
dotenvy = "0.15"
semver = "1.0"
walkdir = "2.5"

# Crypto
ring = "0.17.8"
rand = "0.8.5"
ring = "0.17"
rand = "0.8"

# Web framework
axum = { version = "0.7.7", features = ["ws", "macros", "http2"] }
tower-http = { version = "0.6.1", features = ["trace"] }
tokio = { version = "1.37.0", features = ["full"] }
indexmap = { version = "2.5.0", features = ["serde"] }
zip = "2.2.0"
lazy_static = "1.5.0"
axum = { version = "0.7", features = ["ws", "macros", "http2"] }
tower-http = { version = "0.6", features = ["trace"] }
tokio = { version = "1.37", features = ["full"] }
indexmap = { version = "2.6", features = ["serde"] }
zip = "2.2"
lazy_static = "1.5"

[dev-dependencies]
cross = "0.2.5"
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Chef
# FROM clux/muslrust:stable AS chef
FROM rust:1.81.0-alpine3.20 AS chef
FROM rust:1.82.0-alpine3.20 AS chef
USER root
RUN apk add --no-cache musl-dev libressl-dev
RUN cargo install cargo-chef
Expand Down
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# The Sculptor

[![Push Dev](https://github.com/shiroyashik/sculptor/actions/workflows/dev-release.yml/badge.svg?branch=dev)](https://github.com/shiroyashik/sculptor/actions/workflows/dev-release.yml)
![maintenance-status](https://img.shields.io/badge/maintenance-actively--developed-brightgreen.svg)

Unofficial backend for the Minecraft mod [Figura](https://github.com/FiguraMC/Figura).

Expand All @@ -19,11 +20,11 @@ I'm keeping the public server running at the moment!

You can use it if running your own Sculptor instance is difficult for you.

To connect, simply change **IP Server** in Figura settings to the address below:
To connect, simply change **Figura Cloud IP** in Figura settings to the address below:

> figura.shsr.ru
Authentication is enabled on the server via: Mojang and [Ely.By](https://ely.by/)
Authentication is enabled on the server via: Mojang(Microsoft) and [Ely.By](https://ely.by/)

For reasons beyond my control, the server is not available in some countries.

Expand Down Expand Up @@ -73,10 +74,15 @@ cargo run --release
```

## Contributing
![Ask me anything!](https://img.shields.io/badge/Ask%20me-anything-1abc9c.svg)
on
[![Telegram](https://badgen.net/static/icon/telegram?icon=telegram&color=cyan&label)](https://t.me/shiroyashik)
or
![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)

If you have ideas for new features, have found a bug, or want to suggest improvements,
please create an [issue](https://github.com/shiroyashik/sculptor/issues)
or contact me directly via Discord/Telegram (@shiroyashik).
or contact me directly via Discord/Telegram (**@shiroyashik**).

If you are a Rust developer, you can modify the code yourself and request a Pull Request:

Expand Down
18 changes: 12 additions & 6 deletions README.ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@

# The Sculptor
[![Push Dev](https://github.com/shiroyashik/sculptor/actions/workflows/dev-release.yml/badge.svg?branch=dev)](https://github.com/shiroyashik/sculptor/actions/workflows/dev-release.yml)
![maintenance-status](https://img.shields.io/badge/maintenance-actively--developed-brightgreen.svg)

Неофициальный бэкенд для Minecraft мода [Figura](https://github.com/FiguraMC/Figura).

Это полноценная замена официальной версии. Реализован весь функционал который вы можете использовать во время игры.

А также отличительной особенностью является возможность игры с сторонними провайдерерами аутентификации (таких как [Ely.By](https://ely.by/))
А также отличительной особенностью является возможность игры с сторонними провайдерерами аутентификации (такими как [Ely.By](https://ely.by/))

## Публичный сервер

Expand All @@ -18,13 +19,13 @@

Вы можете использовать его если запуск собственного сервера затруднителен для вас.

Для подключения достаточно сменить **Сервер IP** в настройках Figura на адрес ниже:
Для подключения достаточно сменить **IP сервера Figura** в настройках Figura на адрес ниже:

> figura.shsr.ru
На сервере включена аутентификация через: Mojang и [Ely.By](https://ely.by/)
На сервере включена аутентификация через: Mojang(Microsoft) и [Ely.By](https://ely.by/)

По неконтролируемым мною причинам, сервер не доступен в некоторых странах
По неконтролируемым мною причинам, сервер не доступен в некоторых странах.

## Запуск

Expand Down Expand Up @@ -71,15 +72,20 @@ cargo run --release
```

## Вклад в развитие
![Спроси меня о чём угодно!](https://img.shields.io/badge/Ask%20me-anything-1abc9c.svg)
в
[![Telegram](https://badgen.net/static/icon/telegram?icon=telegram&color=cyan&label)](https://t.me/shiroyashik)
или
![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)

Если у вас есть идем, нашли баг или хотите предложить улучшения
создавайте [issue](https://github.com/shiroyashik/sculptor/issues)
или свяжитесь со мной напрямую через Discord/Telegram (@shiroyashik).
или свяжитесь со мной напрямую через Discord/Telegram (**@shiroyashik**).

Если вы Rust разработчик, буду рад вашим Pull Request'ам:

1. Форкните репу
2. Создайте новую репу для вашего гения
2. Создайте новую ветку
3. Создайте PR!

Буду рад любой вашей помощи! ❤
Expand Down
20 changes: 9 additions & 11 deletions src/api/figura/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ async fn versions() -> ApiResult<Json<Value>> {

let mut directories = Vec::new();

let mut entries = fs::read_dir(dir_path).await.map_err(|err| internal_and_log(err))?;
let mut entries = fs::read_dir(dir_path).await.map_err(internal_and_log)?;

while let Some(entry) = entries.next_entry().await.map_err(|err| internal_and_log(err))? {
if entry.metadata().await.map_err(|err| internal_and_log(err))?.is_dir() {
while let Some(entry) = entries.next_entry().await.map_err(internal_and_log)? {
if entry.metadata().await.map_err(internal_and_log)?.is_dir() {
if let Some(name) = entry.file_name().to_str() {
let name = name.to_string();
if !name.starts_with('.') {
Expand All @@ -38,7 +38,7 @@ async fn versions() -> ApiResult<Json<Value>> {
}

async fn hashes(Path(version): Path<String>) -> ApiResult<Json<IndexMap<String, Value>>> {
let map = index_assets(&version).await.map_err(|err| internal_and_log(err))?;
let map = index_assets(&version).await.map_err(internal_and_log)?;
Ok(Json(map))
}

Expand All @@ -49,7 +49,7 @@ async fn download(Path((version, path)): Path<(String, String)>) -> ApiResult<Ve
return Err(ApiError::NotFound)
};
let mut buffer = Vec::new();
file.read_to_end(&mut buffer).await.map_err(|err| internal_and_log(err))?;
file.read_to_end(&mut buffer).await.map_err(internal_and_log)?;
Ok(buffer)
}

Expand All @@ -65,13 +65,11 @@ async fn index_assets(version: &str) -> anyhow::Result<IndexMap<String, Value>>
Err(_) => continue
};

let path: String;

if cfg!(windows) {
path = entry.path().strip_prefix(version_path.clone())?.to_string_lossy().to_string().replace("\\", "/");
let path: String = if cfg!(windows) {
entry.path().strip_prefix(version_path.clone())?.to_string_lossy().to_string().replace("\\", "/")
} else {
path = entry.path().strip_prefix(version_path.clone())?.to_string_lossy().to_string();
}
entry.path().strip_prefix(version_path.clone())?.to_string_lossy().to_string()
};

map.insert(path, Value::from(hex::encode(digest(&SHA256, &data).as_ref())));
}
Expand Down
2 changes: 1 addition & 1 deletion src/api/figura/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ pub mod profile;
pub mod info;
pub mod assets;

pub use websocket::handler as ws;
pub use websocket::{initial as ws, SessionMessage};
20 changes: 10 additions & 10 deletions src/api/figura/profile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{
auth::Token, utils::{calculate_file_sha256, format_uuid},
ApiError, ApiResult, AppState, AVATARS_VAR
};
use super::types::S2CMessage;
use super::websocket::S2CMessage;

pub async fn user_info(
Path(uuid): Path<Uuid>,
Expand Down Expand Up @@ -85,7 +85,7 @@ pub async fn download_avatar(Path(uuid): Path<Uuid>) -> ApiResult<Vec<u8>> {
return Err(ApiError::NotFound)
};
let mut buffer = Vec::new();
file.read_to_end(&mut buffer).await.map_err(|err| internal_and_log(err))?;
file.read_to_end(&mut buffer).await.map_err(internal_and_log)?;
Ok(buffer)
}

Expand All @@ -103,15 +103,15 @@ pub async fn upload_avatar(
user_info.username
);
let avatar_file = format!("{}/{}.moon", *AVATARS_VAR, user_info.uuid);
let mut file = BufWriter::new(fs::File::create(&avatar_file).await.map_err(|err| internal_and_log(err))?);
io::copy(&mut request_data.as_ref(), &mut file).await.map_err(|err| internal_and_log(err))?;
let mut file = BufWriter::new(fs::File::create(&avatar_file).await.map_err(internal_and_log)?);
io::copy(&mut request_data.as_ref(), &mut file).await.map_err(internal_and_log)?;
}
Ok("ok".to_string())
}

pub async fn equip_avatar(Token(token): Token, State(state): State<AppState>) -> ApiResult<&'static str> {
debug!("[API] S2C : Equip");
let uuid = state.user_manager.get(&token).ok_or_else(|| ApiError::Unauthorized)?.uuid;
let uuid = state.user_manager.get(&token).ok_or(ApiError::Unauthorized)?.uuid;
send_event(&state, &uuid).await;
Ok("ok")
}
Expand All @@ -124,24 +124,24 @@ pub async fn delete_avatar(Token(token): Token, State(state): State<AppState>) -
user_info.username
);
let avatar_file = format!("{}/{}.moon", *AVATARS_VAR, user_info.uuid);
fs::remove_file(avatar_file).await.map_err(|err| internal_and_log(err))?;
fs::remove_file(avatar_file).await.map_err(internal_and_log)?;
send_event(&state, &user_info.uuid).await;
}
Ok("ok".to_string())
}

pub async fn send_event(state: &AppState, uuid: &Uuid) {
// To user subscribers
if let Some(broadcast) = state.broadcasts.get(&uuid) {
if broadcast.send(S2CMessage::Event(*uuid).to_vec()).is_err() {
if let Some(broadcast) = state.subscribes.get(uuid) {
if broadcast.send(S2CMessage::Event(*uuid).into()).is_err() {
debug!("[WebSocket] Failed to send Event! There is no one to send. UUID: {uuid}")
};
} else {
debug!("[WebSocket] Failed to send Event! Can't find UUID: {uuid}")
};
// To user
if let Some(session) = state.session.get(&uuid) {
if session.send(S2CMessage::Event(*uuid).to_vec()).await.is_err() {
if let Some(session) = state.session.get(uuid) {
if session.send(super::SessionMessage::Ping(S2CMessage::Event(*uuid).into())).await.is_err() {
debug!("[WebSocket] Failed to send Event! WS doesn't connected? UUID: {uuid}")
};
} else {
Expand Down
9 changes: 1 addition & 8 deletions src/api/figura/types/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1 @@
mod c2s;
mod errors;
mod s2c;
pub mod auth;

pub use c2s::C2SMessage;
pub use errors::MessageLoadError;
pub use s2c::S2CMessage;
pub mod auth;
Loading

0 comments on commit 4c0871e

Please sign in to comment.