150 lines
4.3 KiB
Rust
150 lines
4.3 KiB
Rust
use discord_rich_presence::{
|
|
activity::{Activity, Assets, Button},
|
|
DiscordIpc, DiscordIpcClient,
|
|
};
|
|
|
|
use crate::framework::error::{GameError, GameResult};
|
|
use crate::game::{player::Player, shared_game_state::GameDifficulty, stage::StageData};
|
|
|
|
pub enum DiscordRPCState {
|
|
Initializing,
|
|
Idling,
|
|
InGame,
|
|
Jukebox,
|
|
}
|
|
|
|
pub struct DiscordRPC {
|
|
pub enabled: bool,
|
|
pub ready: bool,
|
|
|
|
client: DiscordIpcClient,
|
|
state: DiscordRPCState,
|
|
life: u16,
|
|
max_life: u16,
|
|
stage_name: String,
|
|
difficulty: Option<GameDifficulty>,
|
|
}
|
|
|
|
impl DiscordRPC {
|
|
pub fn new(app_id: &str) -> Self {
|
|
Self {
|
|
enabled: false,
|
|
ready: false,
|
|
|
|
client: DiscordIpcClient::new(app_id).unwrap(),
|
|
state: DiscordRPCState::Idling,
|
|
life: 0,
|
|
max_life: 0,
|
|
stage_name: String::new(),
|
|
difficulty: None,
|
|
}
|
|
}
|
|
|
|
pub fn start(&mut self) -> GameResult {
|
|
log::info!("Starting Discord RPC client...");
|
|
|
|
match self.client.connect() {
|
|
Ok(_) => {
|
|
self.ready = true;
|
|
Ok(())
|
|
}
|
|
Err(e) => Err(GameError::DiscordRPCError(e.to_string())),
|
|
}
|
|
}
|
|
|
|
fn update(&mut self) -> GameResult {
|
|
if !self.enabled {
|
|
return Ok(());
|
|
}
|
|
|
|
let (state, details) = match self.state {
|
|
DiscordRPCState::Initializing => ("Initializing...".to_owned(), "Just started playing".to_owned()),
|
|
DiscordRPCState::Idling => ("In the menus".to_owned(), "Idling".to_owned()),
|
|
DiscordRPCState::InGame => {
|
|
(format!("Currently in: {}", self.stage_name), format!("HP: {} / {}", self.life, self.max_life))
|
|
}
|
|
DiscordRPCState::Jukebox => ("In the menus".to_owned(), "Listening to the soundtrack".to_owned()),
|
|
};
|
|
|
|
log::debug!("Updating Discord RPC state: {} - {}", state, details);
|
|
|
|
let mut activity_assets = Assets::new().large_image("drs");
|
|
|
|
if self.difficulty.is_some() {
|
|
let difficulty = self.difficulty.unwrap();
|
|
|
|
let asset_name = match difficulty {
|
|
GameDifficulty::Easy => "deasy",
|
|
GameDifficulty::Normal => "dnormal",
|
|
GameDifficulty::Hard => "dhard",
|
|
};
|
|
|
|
let asset_label = match difficulty {
|
|
GameDifficulty::Easy => "Easy",
|
|
GameDifficulty::Normal => "Normal",
|
|
GameDifficulty::Hard => "Hard",
|
|
};
|
|
|
|
activity_assets = activity_assets.small_image(asset_name).small_text(asset_label);
|
|
}
|
|
|
|
let activity = Activity::new()
|
|
.state(state.as_str())
|
|
.details(details.as_str())
|
|
.assets(activity_assets)
|
|
.buttons(vec![Button::new("doukutsu-rs on GitHub", "https://github.com/doukutsu-rs/doukutsu-rs")]);
|
|
|
|
match self.client.set_activity(activity) {
|
|
Ok(_) => Ok(()),
|
|
Err(e) => Err(GameError::DiscordRPCError(e.to_string())),
|
|
}
|
|
}
|
|
|
|
pub fn update_stage(&mut self, stage: &StageData) -> GameResult {
|
|
self.stage_name = stage.name.clone();
|
|
self.update()
|
|
}
|
|
|
|
pub fn update_hp(&mut self, player: &Player) -> GameResult {
|
|
self.life = player.life;
|
|
self.max_life = player.max_life;
|
|
self.update()
|
|
}
|
|
|
|
pub fn update_difficulty(&mut self, difficulty: GameDifficulty) -> GameResult {
|
|
self.difficulty = Some(difficulty);
|
|
self.update()
|
|
}
|
|
|
|
pub fn set_initializing(&mut self) -> GameResult {
|
|
self.set_state(DiscordRPCState::Initializing)
|
|
}
|
|
|
|
pub fn set_idling(&mut self) -> GameResult {
|
|
self.difficulty = None;
|
|
self.set_state(DiscordRPCState::Idling)
|
|
}
|
|
|
|
pub fn set_in_game(&mut self) -> GameResult {
|
|
self.set_state(DiscordRPCState::InGame)
|
|
}
|
|
|
|
pub fn set_in_jukebox(&mut self) -> GameResult {
|
|
self.set_state(DiscordRPCState::Jukebox)
|
|
}
|
|
|
|
pub fn set_state(&mut self, state: DiscordRPCState) -> GameResult {
|
|
self.state = state;
|
|
self.update()
|
|
}
|
|
|
|
pub fn clear(&mut self) -> GameResult {
|
|
let _ = self.client.clear_activity();
|
|
Ok(())
|
|
}
|
|
|
|
pub fn dispose(&mut self) {
|
|
let _ = self.client.close();
|
|
}
|
|
}
|