Restructured for better modularity

This commit is contained in:
2026-02-23 17:02:38 +01:00
parent e250895386
commit bdbd37307c
6 changed files with 198 additions and 135 deletions
+23 -121
View File
@@ -5,14 +5,10 @@ mod user;
use std::{collections::HashMap, pin::Pin, sync::Arc}; use std::{collections::HashMap, pin::Pin, sync::Arc};
use session_rs::{server::SessionServer, session::Session}; use session_rs::server::SessionServer;
use sqlx::SqlitePool;
use tokio::sync::Mutex; use tokio::sync::Mutex;
use crate::{ use crate::types::SessionMap;
types::{SessionMap, UUID},
user::User,
};
#[tokio::main(flavor = "current_thread")] #[tokio::main(flavor = "current_thread")]
async fn main() -> session_rs::Result<()> { async fn main() -> session_rs::Result<()> {
@@ -71,7 +67,7 @@ async fn main() -> session_rs::Result<()> {
let sessions = sessions.clone(); let sessions = sessions.clone();
move |_, token| { move |_, token| {
authenticate( methods::auth::authenticate(
sessions.clone(), sessions.clone(),
session.clone(), session.clone(),
uuid.clone(), uuid.clone(),
@@ -158,25 +154,6 @@ async fn main() -> session_rs::Result<()> {
}) })
.await; .await;
session
.on_request::<methods::SetHat, _>({
let uuid = Arc::clone(&uuid);
let pool = Arc::clone(&pool);
move |_, item_id| {
let pool = Arc::clone(&pool);
let item_id = item_id.clone();
cosmetics::equip(
cosmetics::CosmeticKind::Hat,
uuid.clone(),
item_id,
pool,
)
}
})
.await;
session session
.on_request::<methods::Emote, _>({ .on_request::<methods::Emote, _>({
let sessions = Arc::clone(&sessions); let sessions = Arc::clone(&sessions);
@@ -186,18 +163,34 @@ async fn main() -> session_rs::Result<()> {
let sessions = Arc::clone(&sessions); let sessions = Arc::clone(&sessions);
let uuid = Arc::clone(&uuid); let uuid = Arc::clone(&uuid);
send_emote(sessions, uuid, emote) methods::emote::send_emote(sessions, uuid, emote)
} }
}) })
.await; .await;
session session
.on_request::<methods::Player, _>({ .on_request::<methods::GetPlayer, _>({
let sessions = Arc::clone(&sessions); let sessions = Arc::clone(&sessions);
let pool = Arc::clone(&pool); let pool = Arc::clone(&pool);
move |_, uuid: String| { move |_, uuid| {
get_user(sessions.clone(), uuid.clone(), pool.clone()) methods::user::get_user(
sessions.clone(),
uuid.clone(),
pool.clone(),
)
}
})
.await;
session
.on_request::<methods::SendPlayer, _>({
let sessions = Arc::clone(&sessions);
let pool = Arc::clone(&pool);
let uuid = Arc::clone(&uuid);
move |_, targets| {
methods::user::send_user(sessions.clone(), uuid.clone(), targets.clone(), pool.clone())
} }
}) })
.await; .await;
@@ -208,94 +201,3 @@ async fn main() -> session_rs::Result<()> {
}) })
.await .await
} }
async fn get_user(
sessions: SessionMap,
uuid: String,
pool: Arc<SqlitePool>,
) -> Result<Option<User>, String> {
if !sessions.lock().await.contains_key(&uuid) {
return Ok(None);
}
Ok(Some(user::get(&uuid, pool.as_ref()).await?))
}
async fn send_emote(
sessions: SessionMap,
uuid: UUID,
emote: types::EmoteRequest,
) -> Result<String, String> {
let emote_event = types::EventEmote {
from: uuid.lock().await.clone(),
emote: emote.emote,
};
for i in emote.targets {
if let Some(sessions) = sessions.lock().await.get_mut(&i) {
let emote_event = emote_event.clone();
let mut bad_sessions = Vec::new();
for s in sessions.iter() {
if s.notify::<methods::EmoteEvent>(emote_event.clone())
.await
.is_err()
{
bad_sessions.push(s.clone());
}
}
for s in bad_sessions {
sessions.remove(&s);
}
}
}
Ok(format!("Cool"))
}
async fn authenticate(
sessions: SessionMap,
session: Session,
uuid: UUID,
session_token: String,
pool: Arc<SqlitePool>,
) -> Result<User, String> {
if !uuid.lock().await.is_empty() {
return Err(format!("Already authenticated"));
}
let client = reqwest::Client::new();
let response = client
.get("https://api.minecraftservices.com/minecraft/profile")
.bearer_auth(&session_token)
.send()
.await
.map_err(|_| "Failed to validate session".to_string())?;
if !response.status().is_success() {
return Err(format!(
"Authentication failed with code {}",
response.status()
));
}
let auth: types::MinecraftAuthResponse = response
.json()
.await
.map_err(|_| "Unable to parse auth response".to_string())?;
*uuid.lock().await = auth.id.clone();
sessions
.lock()
.await
.entry(auth.id.clone())
.or_default()
.insert(session);
println!("Authenticated as {:?}", auth);
user::get_put(&auth.id, &pool).await
}
+55
View File
@@ -0,0 +1,55 @@
use std::sync::Arc;
use session_rs::session::Session;
use sqlx::SqlitePool;
use crate::{
types::{SessionMap, UUID},
user::User,
};
pub async fn authenticate(
sessions: SessionMap,
session: Session,
uuid: UUID,
session_token: String,
pool: Arc<SqlitePool>,
) -> Result<User, String> {
if !uuid.lock().await.is_empty() {
return Err(format!("Already authenticated"));
}
let client = reqwest::Client::new();
let response = client
.get("https://api.minecraftservices.com/minecraft/profile")
.bearer_auth(&session_token)
.send()
.await
.map_err(|_| "Failed to validate session".to_string())?;
if !response.status().is_success() {
return Err(format!(
"Authentication failed with code {}",
response.status()
));
}
let auth: crate::types::MinecraftAuthResponse = response
.json()
.await
.map_err(|_| "Unable to parse auth response".to_string())?;
*uuid.lock().await = auth.id.clone();
sessions
.lock()
.await
.entry(auth.id.clone())
.or_default()
.insert(session);
println!("Authenticated as {:?}", auth);
crate::user::get_put(&auth.id, &pool).await
}
+34
View File
@@ -0,0 +1,34 @@
use crate::types::{SessionMap, UUID};
pub async fn send_emote(
sessions: SessionMap,
uuid: UUID,
emote: crate::types::EmoteRequest,
) -> Result<(), String> {
let emote_event = crate::types::EventEmote {
from: uuid.lock().await.clone(),
emote: emote.emote,
};
for target in emote.targets {
if let Some(sessions) = sessions.lock().await.get_mut(&target) {
let emote_event = emote_event.clone();
let mut bad_sessions = Vec::new();
for s in sessions.iter() {
if s.notify::<crate::methods::EmoteEvent>(emote_event.clone())
.await
.is_err()
{
bad_sessions.push(s.clone());
}
}
for s in bad_sessions {
sessions.remove(&s);
}
}
}
Ok(())
}
+37 -13
View File
@@ -1,3 +1,7 @@
pub mod auth;
pub mod emote;
pub mod user;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use session_rs::Method; use session_rs::Method;
@@ -6,7 +10,7 @@ use crate::{
user::User, user::User,
}; };
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Auth; pub struct Auth;
impl Method for Auth { impl Method for Auth {
@@ -16,7 +20,7 @@ impl Method for Auth {
type Error = String; type Error = String;
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SetCloak; pub struct SetCloak;
impl Method for SetCloak { impl Method for SetCloak {
@@ -26,7 +30,7 @@ impl Method for SetCloak {
type Error = String; type Error = String;
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SetHat; pub struct SetHat;
impl Method for SetHat { impl Method for SetHat {
@@ -36,7 +40,7 @@ impl Method for SetHat {
type Error = String; type Error = String;
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BuyCloak; pub struct BuyCloak;
impl Method for BuyCloak { impl Method for BuyCloak {
@@ -46,7 +50,7 @@ impl Method for BuyCloak {
type Error = String; type Error = String;
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BuyHat; pub struct BuyHat;
impl Method for BuyHat { impl Method for BuyHat {
@@ -56,32 +60,52 @@ impl Method for BuyHat {
type Error = String; type Error = String;
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Emote; pub struct Emote;
impl Method for Emote { impl Method for Emote {
const NAME: &'static str = "emote"; const NAME: &'static str = "emote";
type Request = EmoteRequest; type Request = EmoteRequest;
type Response = String; type Response = ();
type Error = String; type Error = String;
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EmoteEvent; pub struct EmoteEvent;
impl Method for EmoteEvent { impl Method for EmoteEvent {
const NAME: &'static str = "emote_event"; const NAME: &'static str = "emote_event";
type Request = EventEmote; type Request = EventEmote;
type Response = String; type Response = ();
type Error = String; type Error = ();
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Player; pub struct GetPlayer;
impl Method for Player { impl Method for GetPlayer {
const NAME: &'static str = "player"; const NAME: &'static str = "player";
type Request = String; type Request = String;
type Response = Option<User>; type Response = Option<User>;
type Error = String; type Error = String;
} }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Player;
impl Method for Player {
const NAME: &'static str = "player";
type Request = User;
type Response = ();
type Error = ();
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SendPlayer;
impl Method for SendPlayer {
const NAME: &'static str = "send_player";
type Request = Vec<String>;
type Response = ();
type Error = String;
}
+48
View File
@@ -0,0 +1,48 @@
use std::sync::Arc;
use sqlx::SqlitePool;
use crate::{
methods,
types::{SessionMap, UUID},
user::User,
};
pub async fn get_user(
sessions: SessionMap,
uuid: String,
pool: Arc<SqlitePool>,
) -> Result<Option<User>, String> {
if !sessions.lock().await.contains_key(&uuid) {
return Ok(None);
}
Ok(Some(crate::user::get(&uuid, pool.as_ref()).await?))
}
pub async fn send_user(
sessions: SessionMap,
uuid: UUID,
targets: Vec<String>,
pool: Arc<SqlitePool>,
) -> Result<(), String> {
let user = crate::user::get(&uuid.lock().await, pool.as_ref()).await?;
for target in targets {
if let Some(sessions) = sessions.lock().await.get_mut(&target) {
let mut bad_sessions = Vec::new();
for s in sessions.iter() {
if s.notify::<methods::Player>(user.clone()).await.is_err() {
bad_sessions.push(s.clone());
}
}
for s in bad_sessions {
sessions.remove(&s);
}
}
}
Ok(())
}
+1 -1
View File
@@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sqlx::{Row, SqlitePool}; use sqlx::{Row, SqlitePool};
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct User { pub struct User {
pub cloak: String, pub cloak: String,
pub hat: String, pub hat: String,