record-daemon: refactor, remove api_types entirely
All checks were successful
record-daemon / Build, check and test (push) Successful in 2m5s
All checks were successful
record-daemon / Build, check and test (push) Successful in 2m5s
This commit is contained in:
@@ -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()));
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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::{
|
||||
|
||||
Reference in New Issue
Block a user