record-daemon: refactor, remove api_types entirely
All checks were successful
record-daemon / Build, check and test (push) Successful in 2m5s

This commit is contained in:
2026-03-27 16:36:43 +01:00
parent 785e5073ec
commit 8842cd9e04
3 changed files with 0 additions and 414 deletions

View File

@@ -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<u64>,
/// Account ID.
#[serde(default)]
pub account_id: Option<u64>,
/// PUUID (globally unique identifier).
#[serde(default)]
pub puuid: Option<String>,
/// Display name.
#[serde(default)]
pub display_name: Option<String>,
/// Internal name.
#[serde(default)]
pub internal_name: Option<String>,
/// Name (legacy field).
#[serde(default)]
pub name: Option<String>,
/// Profile icon ID.
#[serde(default)]
pub profile_icon_id: Option<u32>,
/// Summoner level.
#[serde(default)]
pub summoner_level: Option<u32>,
}
// =============================================================================
// 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<String>,
/// Game data (present when in game).
#[serde(default)]
pub game_data: Option<GameData>,
/// Map name.
#[serde(default)]
pub map: Option<String>,
/// Game mode.
#[serde(default)]
pub game_mode: Option<String>,
/// Queue ID.
#[serde(default)]
pub queue_id: Option<u64>,
}
/// 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<u64>,
/// Queue information.
#[serde(default)]
pub queue: Option<QueueData>,
/// Team one players.
#[serde(default)]
pub team_one: Option<Vec<TeamPlayer>>,
/// Team two players.
#[serde(default)]
pub team_two: Option<Vec<TeamPlayer>>,
}
/// Queue data within game data.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct QueueData {
/// Queue ID.
#[serde(default)]
pub id: Option<u64>,
/// Queue name.
#[serde(default)]
pub name: Option<String>,
/// Game mode.
#[serde(default)]
pub game_mode: Option<String>,
/// Map ID.
#[serde(default)]
pub map_id: Option<u64>,
}
/// Player in a team.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TeamPlayer {
/// Player PUUID.
#[serde(default)]
pub puuid: Option<String>,
/// Summoner name.
#[serde(default)]
pub summoner_name: Option<String>,
/// Summoner ID.
#[serde(default)]
pub summoner_id: Option<u64>,
/// Champion ID.
#[serde(default)]
pub champion_id: Option<u64>,
/// Team ID.
#[serde(default)]
pub team_id: Option<u64>,
/// First summoner spell ID.
#[serde(default)]
pub spell1_id: Option<u64>,
/// Second summoner spell ID.
#[serde(default)]
pub spell2_id: Option<u64>,
}
// =============================================================================
// 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<i64>,
/// Timer information.
#[serde(default)]
pub timers: Option<Timers>,
/// My team.
#[serde(default)]
pub my_team: Option<Vec<ChampionSelectPlayer>>,
/// Their team.
#[serde(default)]
pub their_team: Option<Vec<ChampionSelectPlayer>>,
}
/// Timer information in champion select.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Timers {
/// Current phase.
#[serde(default)]
pub phase: Option<String>,
}
/// Player in champion select.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ChampionSelectPlayer {
/// Cell ID.
#[serde(default)]
pub cell_id: Option<i64>,
/// Champion ID.
#[serde(default)]
pub champion_id: Option<u64>,
/// Champion name.
#[serde(default)]
pub champion_name: Option<String>,
/// Team.
#[serde(default)]
pub team: Option<i64>,
/// Skin ID.
#[serde(default)]
pub skin_id: Option<u64>,
}
// =============================================================================
// 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<String>,
/// Display name.
#[serde(default)]
pub display_name: Option<String>,
/// Riot ID.
#[serde(default)]
pub riot_id: Option<String>,
/// Summoner spells.
#[serde(default)]
pub summoner_spells: Option<SummonerSpellsData>,
}
/// 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<SpellData>,
/// Second summoner spell.
#[serde(default)]
pub summoner_spell_two: Option<SpellData>,
/// First spell ID (alternative field).
#[serde(default)]
pub spell1_id: Option<u64>,
/// Second spell ID (alternative field).
#[serde(default)]
pub spell2_id: Option<u64>,
}
/// Individual spell data.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SpellData {
/// Spell ID.
#[serde(default)]
pub spell_id: Option<u64>,
/// Display name.
#[serde(default)]
pub display_name: Option<String>,
}
/// Response from `/liveclientdata/playerlist`
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PlayerListResponse(pub Vec<LiveClientPlayer>);
/// 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<bool>,
/// Summoner name.
#[serde(default)]
pub summoner_name: Option<String>,
/// Riot ID.
#[serde(default)]
pub riot_id: Option<String>,
/// PUUID.
#[serde(default)]
pub puuid: Option<String>,
/// Summoner ID.
#[serde(default)]
pub summoner_id: Option<u64>,
/// Champion name.
#[serde(default)]
pub champion_name: Option<String>,
/// Team.
#[serde(default)]
pub team: Option<u64>,
/// Items.
#[serde(default)]
pub items: Option<Vec<LiveClientItem>>,
}
/// 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<u64>,
/// Display name.
#[serde(default)]
pub display_name: Option<String>,
}
// =============================================================================
// 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()));
}
}

View File

@@ -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<T: DeserializeOwned>(&self, method: &str, endpoint: &str) -> Result<T> {
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<GameflowPhase> {
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<GameflowSessionResponse> {
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<serde_json::Value> {
self.request("GET", endpoints::SESSION).await
}
/// Get current summoner info (typed).
pub async fn get_summoner_typed(&self) -> Result<SummonerResponse> {
self.request_typed("GET", endpoints::SUMMONER).await
}
/// Get current summoner info (raw JSON for backward compatibility).
pub async fn get_summoner(&self) -> Result<serde_json::Value> {
self.request("GET", endpoints::SUMMONER).await
}
/// Get champion select session info (typed).
pub async fn get_champion_select_typed(&self) -> Result<ChampionSelectResponse> {
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<serde_json::Value> {
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<ActivePlayerResponse> {
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<serde_json::Value> {
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<PlayerListResponse> {
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<serde_json::Value> {
self.request("GET", endpoints::LIVE_CLIENT_DATA_PLAYER_LIST)

View File

@@ -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::{