use std::any::Any;
use steamkit_protos::steam::{
c_msg_client_lbs_get_lb_entries_response, CMsgClientLbsFindOrCreateLbResponse,
CMsgClientLbsGetLbEntriesResponse, CMsgDpGetNumberOfCurrentPlayersResponse,
};
use crate::base::client_msg::ClientMsgProtobuf;
use crate::base::generated::steam_language::{
ELeaderboardDisplayType, ELeaderboardSortMethod, EResult,
};
use crate::base::packet_base::IPacketMsg;
use crate::error::SteamResult;
use crate::steam::steam_client::callback_mgr::callback_msg::CallbackMsg;
use crate::types::global_id::UGCHandle;
use crate::types::job_id::JobID;
use crate::types::steam_id::SteamID;
#[derive(Clone, Debug)]
pub struct NumberOfPlayersCallback {
job_id: JobID,
result: EResult,
num_players: u32,
}
impl NumberOfPlayersCallback {
pub(crate) fn from_packet(packet_msg: &dyn IPacketMsg) -> SteamResult<Self> {
let msg =
ClientMsgProtobuf::<CMsgDpGetNumberOfCurrentPlayersResponse>::from_packet(packet_msg)?;
Ok(Self {
job_id: packet_msg.target_job_id(),
result: EResult::from_value(msg.body.eresult.unwrap_or_default())
.unwrap_or(EResult::Invalid),
num_players: msg.body.player_count.unwrap_or_default() as u32,
})
}
pub fn result(&self) -> EResult {
self.result
}
pub fn num_players(&self) -> u32 {
self.num_players
}
}
impl CallbackMsg for NumberOfPlayersCallback {
fn job_id(&self) -> JobID {
self.job_id
}
fn set_job_id(&mut self, id: JobID) {
self.job_id = id;
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
#[derive(Clone, Debug)]
pub struct FindOrCreateLeaderboardCallback {
job_id: JobID,
result: EResult,
id: i32,
entry_count: i32,
sort_method: ELeaderboardSortMethod,
display_type: ELeaderboardDisplayType,
}
impl FindOrCreateLeaderboardCallback {
pub(crate) fn from_packet(packet_msg: &dyn IPacketMsg) -> SteamResult<Self> {
let msg =
ClientMsgProtobuf::<CMsgClientLbsFindOrCreateLbResponse>::from_packet(packet_msg)?;
Ok(Self {
job_id: packet_msg.target_job_id(),
result: EResult::from_value(msg.body.eresult.unwrap_or_default())
.unwrap_or(EResult::Invalid),
id: msg.body.leaderboard_id.unwrap_or_default(),
entry_count: msg.body.leaderboard_entry_count.unwrap_or_default(),
sort_method: ELeaderboardSortMethod::from_value(
msg.body.leaderboard_sort_method.unwrap_or_default(),
)
.unwrap_or(ELeaderboardSortMethod::None),
display_type: ELeaderboardDisplayType::from_value(
msg.body.leaderboard_display_type.unwrap_or_default(),
)
.unwrap_or(ELeaderboardDisplayType::None),
})
}
pub fn result(&self) -> EResult {
self.result
}
pub fn id(&self) -> i32 {
self.id
}
pub fn entry_count(&self) -> i32 {
self.entry_count
}
pub fn sort_method(&self) -> ELeaderboardSortMethod {
self.sort_method
}
pub fn display_type(&self) -> ELeaderboardDisplayType {
self.display_type
}
}
impl CallbackMsg for FindOrCreateLeaderboardCallback {
fn job_id(&self) -> JobID {
self.job_id
}
fn set_job_id(&mut self, id: JobID) {
self.job_id = id;
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
#[derive(Clone, Debug)]
pub struct LeaderboardEntriesCallback {
job_id: JobID,
result: EResult,
entry_count: i32,
entries: Vec<LeaderboardEntry>,
}
#[derive(Clone, Debug)]
pub struct LeaderboardEntry {
steam_id: SteamID,
global_rank: i32,
score: i32,
ugc_id: UGCHandle,
details: Vec<i32>,
}
impl LeaderboardEntry {
fn from_entry(entry: &c_msg_client_lbs_get_lb_entries_response::Entry) -> Self {
let details = entry
.details
.as_deref()
.map(|bytes| {
bytes
.chunks_exact(4)
.map(|chunk| i32::from_le_bytes([chunk[0], chunk[1], chunk[2], chunk[3]]))
.collect()
})
.unwrap_or_default();
Self {
steam_id: SteamID::from_id(entry.steam_id_user.unwrap_or_default()),
global_rank: entry.global_rank.unwrap_or_default(),
score: entry.score.unwrap_or_default(),
ugc_id: UGCHandle::from_value(entry.ugc_id.unwrap_or_default()),
details,
}
}
pub fn steam_id(&self) -> SteamID {
self.steam_id
}
pub fn global_rank(&self) -> i32 {
self.global_rank
}
pub fn score(&self) -> i32 {
self.score
}
pub fn ugc_id(&self) -> UGCHandle {
self.ugc_id
}
pub fn details(&self) -> &[i32] {
&self.details
}
}
impl LeaderboardEntriesCallback {
pub(crate) fn from_packet(packet_msg: &dyn IPacketMsg) -> SteamResult<Self> {
let msg = ClientMsgProtobuf::<CMsgClientLbsGetLbEntriesResponse>::from_packet(packet_msg)?;
let entries = msg
.body
.entries
.iter()
.map(LeaderboardEntry::from_entry)
.collect();
Ok(Self {
job_id: packet_msg.target_job_id(),
result: EResult::from_value(msg.body.eresult.unwrap_or_default())
.unwrap_or(EResult::Invalid),
entry_count: msg.body.leaderboard_entry_count.unwrap_or_default(),
entries,
})
}
pub fn result(&self) -> EResult {
self.result
}
pub fn entry_count(&self) -> i32 {
self.entry_count
}
pub fn entries(&self) -> &[LeaderboardEntry] {
&self.entries
}
}
impl CallbackMsg for LeaderboardEntriesCallback {
fn job_id(&self) -> JobID {
self.job_id
}
fn set_job_id(&mut self, id: JobID) {
self.job_id = id;
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}