diff --git a/record-daemon/src/lqp/api_types.rs b/record-daemon/src/lqp/api_types.rs deleted file mode 100644 index b19dcac..0000000 --- a/record-daemon/src/lqp/api_types.rs +++ /dev/null @@ -1,369 +0,0 @@ -//! API response types for League Client API. -//! -//! These structs map directly to the JSON responses from the LQP REST API, -//! allowing automatic deserialization via serde. - -use serde::{Deserialize, Serialize}; - -// ============================================================================= -// Summoner API Responses -// ============================================================================= - -/// Response from `/lol-summoner/v1/current-summoner` -#[derive(Debug, Clone, Default, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct SummonerResponse { - /// Summoner ID. - #[serde(default)] - pub summoner_id: Option, - - /// Account ID. - #[serde(default)] - pub account_id: Option, - - /// PUUID (globally unique identifier). - #[serde(default)] - pub puuid: Option, - - /// Display name. - #[serde(default)] - pub display_name: Option, - - /// Internal name. - #[serde(default)] - pub internal_name: Option, - - /// Name (legacy field). - #[serde(default)] - pub name: Option, - - /// Profile icon ID. - #[serde(default)] - pub profile_icon_id: Option, - - /// Summoner level. - #[serde(default)] - pub summoner_level: Option, -} - -// ============================================================================= -// Gameflow Session API Responses -// ============================================================================= - -/// Response from `/lol-gameflow/v1/session` -#[derive(Debug, Clone, Default, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct GameflowSessionResponse { - /// Current gameflow phase. - #[serde(default)] - pub phase: Option, - - /// Game data (present when in game). - #[serde(default)] - pub game_data: Option, - - /// Map name. - #[serde(default)] - pub map: Option, - - /// Game mode. - #[serde(default)] - pub game_mode: Option, - - /// Queue ID. - #[serde(default)] - pub queue_id: Option, -} - -/// Game data within a gameflow session. -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct GameData { - /// Game ID. - #[serde(default)] - pub game_id: Option, - - /// Queue information. - #[serde(default)] - pub queue: Option, - - /// Team one players. - #[serde(default)] - pub team_one: Option>, - - /// Team two players. - #[serde(default)] - pub team_two: Option>, -} - -/// Queue data within game data. -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct QueueData { - /// Queue ID. - #[serde(default)] - pub id: Option, - - /// Queue name. - #[serde(default)] - pub name: Option, - - /// Game mode. - #[serde(default)] - pub game_mode: Option, - - /// Map ID. - #[serde(default)] - pub map_id: Option, -} - -/// Player in a team. -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct TeamPlayer { - /// Player PUUID. - #[serde(default)] - pub puuid: Option, - - /// Summoner name. - #[serde(default)] - pub summoner_name: Option, - - /// Summoner ID. - #[serde(default)] - pub summoner_id: Option, - - /// Champion ID. - #[serde(default)] - pub champion_id: Option, - - /// Team ID. - #[serde(default)] - pub team_id: Option, - - /// First summoner spell ID. - #[serde(default)] - pub spell1_id: Option, - - /// Second summoner spell ID. - #[serde(default)] - pub spell2_id: Option, -} - -// ============================================================================= -// Champion Select API Responses -// ============================================================================= - -/// Response from `/lol-champ-select/v1/session` -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ChampionSelectResponse { - /// Local player cell ID. - #[serde(default)] - pub local_player_cell_id: Option, - - /// Timer information. - #[serde(default)] - pub timers: Option, - - /// My team. - #[serde(default)] - pub my_team: Option>, - - /// Their team. - #[serde(default)] - pub their_team: Option>, -} - -/// Timer information in champion select. -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct Timers { - /// Current phase. - #[serde(default)] - pub phase: Option, -} - -/// Player in champion select. -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ChampionSelectPlayer { - /// Cell ID. - #[serde(default)] - pub cell_id: Option, - - /// Champion ID. - #[serde(default)] - pub champion_id: Option, - - /// Champion name. - #[serde(default)] - pub champion_name: Option, - - /// Team. - #[serde(default)] - pub team: Option, - - /// Skin ID. - #[serde(default)] - pub skin_id: Option, -} - -// ============================================================================= -// Live Client Data API Responses -// ============================================================================= - -/// Response from `/liveclientdata/activeplayer` -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ActivePlayerResponse { - /// Active player's summoner name. - #[serde(default)] - pub summoner_name: Option, - - /// Display name. - #[serde(default)] - pub display_name: Option, - - /// Riot ID. - #[serde(default)] - pub riot_id: Option, - - /// Summoner spells. - #[serde(default)] - pub summoner_spells: Option, -} - -/// Summoner spells data from live client. -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct SummonerSpellsData { - /// First summoner spell. - #[serde(default)] - pub summoner_spell_one: Option, - - /// Second summoner spell. - #[serde(default)] - pub summoner_spell_two: Option, - - /// First spell ID (alternative field). - #[serde(default)] - pub spell1_id: Option, - - /// Second spell ID (alternative field). - #[serde(default)] - pub spell2_id: Option, -} - -/// Individual spell data. -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct SpellData { - /// Spell ID. - #[serde(default)] - pub spell_id: Option, - - /// Display name. - #[serde(default)] - pub display_name: Option, -} - -/// Response from `/liveclientdata/playerlist` -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct PlayerListResponse(pub Vec); - -/// Player in live client data. -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct LiveClientPlayer { - /// Whether this is the local player. - #[serde(default)] - pub is_local_player: Option, - - /// Summoner name. - #[serde(default)] - pub summoner_name: Option, - - /// Riot ID. - #[serde(default)] - pub riot_id: Option, - - /// PUUID. - #[serde(default)] - pub puuid: Option, - - /// Summoner ID. - #[serde(default)] - pub summoner_id: Option, - - /// Champion name. - #[serde(default)] - pub champion_name: Option, - - /// Team. - #[serde(default)] - pub team: Option, - - /// Items. - #[serde(default)] - pub items: Option>, -} - -/// Item in live client data. -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct LiveClientItem { - /// Item ID. - #[serde(default)] - pub item_id: Option, - - /// Display name. - #[serde(default)] - pub display_name: Option, -} - -// ============================================================================= -// Helper implementations -// ============================================================================= - -impl ChampionSelectResponse { - /// Get the local player's champion selection. - pub fn get_local_player_selection(&self) -> Option<&ChampionSelectPlayer> { - let cell_id = self.local_player_cell_id?; - - // Check my team first - if let Some(ref team) = self.my_team { - for player in team { - if player.cell_id == Some(cell_id) { - return Some(player); - } - } - } - - // Check their team - if let Some(ref team) = self.their_team { - for player in team { - if player.cell_id == Some(cell_id) { - return Some(player); - } - } - } - - None - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_summoner_deserialization() { - let json = r#"{"summonerId": 12345, "puuid": "abc-123", "displayName": "TestPlayer"}"#; - let summoner: SummonerResponse = serde_json::from_str(json).unwrap(); - assert_eq!(summoner.summoner_id, Some(12345)); - assert_eq!(summoner.puuid, Some("abc-123".to_string())); - assert_eq!(summoner.display_name, Some("TestPlayer".to_string())); - } -} diff --git a/record-daemon/src/lqp/client.rs b/record-daemon/src/lqp/client.rs index 5454eb9..e9eba90 100644 --- a/record-daemon/src/lqp/client.rs +++ b/record-daemon/src/lqp/client.rs @@ -5,15 +5,10 @@ use std::sync::Arc; use futures::{SinkExt, StreamExt}; -use serde::de::DeserializeOwned; use tokio::sync::{broadcast, RwLock}; use tokio_tungstenite::{connect_async_tls_with_config, tungstenite::protocol::Message}; use tracing::{debug, error, info, trace, warn}; -use super::api_types::{ - ActivePlayerResponse, ChampionSelectResponse, GameflowSessionResponse, PlayerListResponse, - SummonerResponse, -}; use super::auth::LockfileCredentials; use super::endpoints; use super::events::GameEvent; @@ -348,13 +343,6 @@ impl LqpClient { Ok(json) } - /// Make a typed REST API request to the League Client. - async fn request_typed(&self, method: &str, endpoint: &str) -> Result { - let json = self.request(method, endpoint).await?; - serde_json::from_value(json) - .map_err(|e| LqpError::EventParseError(format!("Deserialization failed: {}", e)).into()) - } - /// Get the current gameflow phase. pub async fn get_gameflow_phase(&self) -> Result { let json = self.request("GET", endpoints::GAMEFLOW_PHASE).await?; @@ -364,31 +352,16 @@ impl LqpClient { Ok(GameflowPhase::from(phase_str)) } - /// Get the current game session info (typed). - pub async fn get_session_typed(&self) -> Result { - self.request_typed("GET", endpoints::SESSION).await - } - /// Get the current game session info (raw JSON for backward compatibility). pub async fn get_session(&self) -> Result { self.request("GET", endpoints::SESSION).await } - /// Get current summoner info (typed). - pub async fn get_summoner_typed(&self) -> Result { - self.request_typed("GET", endpoints::SUMMONER).await - } - /// Get current summoner info (raw JSON for backward compatibility). pub async fn get_summoner(&self) -> Result { self.request("GET", endpoints::SUMMONER).await } - /// Get champion select session info (typed). - pub async fn get_champion_select_typed(&self) -> Result { - self.request_typed("GET", endpoints::CHAMPION_SELECT).await - } - /// Get champion select session info (raw JSON for backward compatibility). pub async fn get_champion_select(&self) -> Result { self.request("GET", endpoints::CHAMPION_SELECT).await @@ -424,24 +397,12 @@ impl LqpClient { self.request("GET", endpoints::LIVE_CLIENT_DATA).await } - /// Get active player data from live client (typed). - pub async fn get_live_client_active_player_typed(&self) -> Result { - self.request_typed("GET", endpoints::LIVE_CLIENT_DATA_ACTIVE_PLAYER) - .await - } - /// Get active player data from live client (raw JSON for backward compatibility). pub async fn get_live_client_active_player(&self) -> Result { self.request("GET", endpoints::LIVE_CLIENT_DATA_ACTIVE_PLAYER) .await } - /// Get player list from live client (typed). - pub async fn get_live_client_player_list_typed(&self) -> Result { - self.request_typed("GET", endpoints::LIVE_CLIENT_DATA_PLAYER_LIST) - .await - } - /// Get player list from live client (raw JSON for backward compatibility). pub async fn get_live_client_player_list(&self) -> Result { self.request("GET", endpoints::LIVE_CLIENT_DATA_PLAYER_LIST) diff --git a/record-daemon/src/lqp/mod.rs b/record-daemon/src/lqp/mod.rs index 247bd46..5097cef 100644 --- a/record-daemon/src/lqp/mod.rs +++ b/record-daemon/src/lqp/mod.rs @@ -3,7 +3,6 @@ //! This module handles communication with the League of Legends client //! via WebSocket and REST API for game event detection and capture. -mod api_types; mod auth; mod client; mod endpoints; @@ -12,11 +11,6 @@ mod state; mod tls; mod websocket; -pub use api_types::{ - ActivePlayerResponse, ChampionSelectPlayer, ChampionSelectResponse, GameData, - GameflowSessionResponse, LiveClientItem, LiveClientPlayer, PlayerListResponse, QueueData, - SummonerResponse, SummonerSpellsData, TeamPlayer, Timers, -}; pub use auth::{LockfileCredentials, LockfileWatcher}; pub use client::LqpClient; pub use endpoints::{