Add Linux support

This commit is contained in:
Songtronix 2019-06-19 21:25:08 +02:00
parent 5ea624674d
commit 2338084af0
6 changed files with 1407 additions and 67 deletions

1316
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ default-run = "veloren-voxygen"
[features]
gl = ["gfx_device_gl"]
discord = ["discord_game_sdk", "chrono"]
discord = ["discord-rpc-sdk"]
default = ["gl"]
@ -33,8 +33,7 @@ specs = "0.14"
vek = "0.9"
# discord
discord_game_sdk = { version = "0.2.0", optional = true }
chrono = { version = "0.4.6", optional = true }
discord-rpc-sdk = { git = "https://github.com/Songtronix/rust-discord-rpc.git", optional = true }
# Utility
glsl-include = "0.3"

View File

@ -1,17 +1,15 @@
use discord_game_sdk::{Activity, Discord};
use std::ffi::CString;
use discord_rpc_sdk::{DiscordUser, EventHandlers, RichPresence, RPC};
use std::time::SystemTime;
use std::sync::mpsc::Sender;
use std::sync::{mpsc, Mutex, MutexGuard};
use std::thread;
use std::thread::JoinHandle;
use crate::DEFAULT_PUBLIC_SERVER;
use chrono::Utc;
/// Connects to the discord application where Images and more resides
/// can be viewed at https://discordapp.com/developers/applications/583662036194689035/rich-presence/assets
/// but requires an invitation.
const DISCORD_APPLICATION_ID: i64 = 583662036194689035;
const DISCORD_APPLICATION_ID: &str = "583662036194689035";
/// Represents an update of the game which should be reflected in Discord
pub enum DiscordUpdate {
@ -35,58 +33,60 @@ pub fn run() -> Mutex<DiscordState> {
Mutex::new(DiscordState {
tx,
thread: Some(thread::spawn(move || {
let mut discord =
Discord::new(DISCORD_APPLICATION_ID).expect("failed to initiate discord_game_sdk");
let rpc = RPC::init::<Handlers>(DISCORD_APPLICATION_ID, true, None)
.expect("failed to initiate discord_game_sdk");
//Set initial Status
let mut current_activity = Activity::empty();
current_activity.with_details(CString::new("Menu").expect("failed to create CString"));
current_activity.with_state(CString::new("Idling").expect("failed to create CString"));
current_activity.with_small_image_key(
CString::new("veloren_logo_squareicon_2000").expect("failed to create CString"),
);
current_activity.with_small_image_tooltip(
CString::new("Veloren").expect("failed to create CString"),
);
current_activity
.with_large_image_key(CString::new("bg_main").expect("failed to create CString"));
current_activity.with_large_image_tooltip(
CString::new("veloren.net").expect("failed to create CString"),
);
let mut current_presence = RichPresence {
details: Some("In Menu".to_string()),
state: Some("Idling".to_string()),
start_time: Some(SystemTime::now()),
//end_time: Some(SystemTime::now().checked_add(Duration::from_secs(360)).unwrap()),
large_image_key: Some("snow_background".to_string()),
large_image_text: Some("Veloren.net".to_string()),
small_image_key: Some("veloren_logo_1024".to_string()),
small_image_text: Some("*insert joke here*".to_string()),
//party_id: Some("randompartyid".to_owned()),
//party_size: Some(4),
//party_max: Some(13),
//spectate_secret: Some("randomhash".to_string()),
//join_secret: Some("anotherrandomhash".to_string()),
..Default::default()
};
current_activity.with_start_time(Utc::now());
discord.update_activity(&current_activity, |_, _| {});
match rpc.update_presence(current_presence.clone()) {
Ok(_) => {}
Err(e) => log::error!("Failed to update discord presence: {}", e),
}
'outer: loop {
discord.empty_event_receivers();
discord.run_callbacks();
rpc.run_callbacks();
let msg = rx.try_recv();
match msg {
Ok(update) => {
match update {
DiscordUpdate::Details(x) => current_activity
.with_details(CString::new(x).expect("failed to create CString")),
DiscordUpdate::State(x) => current_activity
.with_state(CString::new(x).expect("failed to create CString")),
DiscordUpdate::SmallImg(x) => current_activity.with_small_image_key(
CString::new(x).expect("failed to create CString"),
),
DiscordUpdate::SmallImgDesc(x) => current_activity
.with_small_image_tooltip(
CString::new(x).expect("failed to create CString"),
),
DiscordUpdate::LargeImg(x) => current_activity.with_large_image_key(
CString::new(x).expect("failed to create CString"),
),
DiscordUpdate::LargeImgDesc(x) => current_activity
.with_large_image_tooltip(
CString::new(x).expect("failed to create CString"),
),
DiscordUpdate::Details(x) => current_presence.details = Some(x),
DiscordUpdate::State(x) => current_presence.state = Some(x),
DiscordUpdate::SmallImg(x) => {
current_presence.small_image_key = Some(x)
}
DiscordUpdate::SmallImgDesc(x) => {
current_presence.small_image_text = Some(x)
}
DiscordUpdate::LargeImg(x) => {
current_presence.large_image_key = Some(x)
}
DiscordUpdate::LargeImgDesc(x) => {
current_presence.large_image_text = Some(x)
}
DiscordUpdate::Shutdown => break 'outer,
};
discord.update_activity(&current_activity, |_, _| {});
match rpc.update_presence(current_presence.clone()) {
Ok(_) => {}
Err(e) => log::error!("Failed to update discord presence: {}", e),
}
}
Err(_) => {}
}
@ -95,6 +95,34 @@ pub fn run() -> Mutex<DiscordState> {
})
}
struct Handlers;
impl EventHandlers for Handlers {
fn ready(user: DiscordUser) {
log::debug!("We're ready! {:?}", user);
}
fn errored(errcode: i32, message: &str) {
log::debug!("Error {}: {}", errcode, message);
}
fn disconnected(errcode: i32, message: &str) {
log::debug!("Disconnected {}: {}", errcode, message);
}
fn join_game(secret: &str) {
log::debug!("Joining {}", secret);
}
fn spectate_game(secret: &str) {
log::debug!("Spectating {}", secret);
}
fn join_request(from: DiscordUser) {
log::debug!("Join request from {:?}", from);
}
}
/* Some helpers */
pub fn send_menu(disc: &mut MutexGuard<DiscordState>) {
disc.tx.send(DiscordUpdate::Details("Menu".into()));
@ -104,4 +132,4 @@ pub fn send_menu(disc: &mut MutexGuard<DiscordState>) {
pub fn send_singleplayer(disc: &mut MutexGuard<DiscordState>) {
disc.tx.send(DiscordUpdate::Details("Singleplayer".into()));
disc.tx.send(DiscordUpdate::State("Playing...".into()));
}
}

View File

@ -160,7 +160,7 @@ impl<'a> Widget for EscMenu<'a> {
Err(e) => log::error!("couldn't send Update to discord: {}", e),
}
}
return Some(Event::Logout);
};
// Quit

View File

@ -5,6 +5,12 @@
#[macro_use]
extern crate lazy_static;
#[cfg(feature = "discord")]
pub mod discord;
#[cfg(feature = "discord")]
use std::sync::{mpsc::Sender, Mutex};
#[macro_use]
pub mod ui;
pub mod anim;
@ -21,21 +27,12 @@ pub mod settings;
pub mod singleplayer;
pub mod window;
#[cfg(feature = "discord")]
pub mod discord;
// Reexports
pub use crate::error::Error;
use crate::{audio::AudioFrontend, menu::main::MainMenuState, settings::Settings, window::Window};
use log::{self, debug, error, info, warn};
#[cfg(feature = "discord")]
use std::sync::{
mpsc::Sender,
Mutex,
};
use simplelog::{CombinedLogger, Config, TermLogger, WriteLogger};
use std::{fs::File, mem, panic, str::FromStr};
@ -126,15 +123,15 @@ fn main() {
),
])
.unwrap();
// Initialize discord. (lazy_static intialise lazily...)
// Initialize discord. (lazy_static initalise lazily...)
#[cfg(feature = "discord")]
{
match discord_instance.lock() {
Ok(disc) => {
//great
}
Err(e) => { log::error!("Couldn't init discord: {}", e) }
Err(e) => log::error!("Couldn't init discord: {}", e),
}
}
@ -266,7 +263,7 @@ fn main() {
}
}
}
//Properly shutdown discord thread
#[cfg(feature = "discord")]
{
@ -285,7 +282,7 @@ fn main() {
Err(e) => error!("couldn't gracefully shutdown discord thread: {}", e),
}
}
// Save settings to add new fields or create the file if it is not already there
if let Err(err) = global_state.settings.save_to_file() {
warn!("Failed to save settings: {:?}", err);

View File

@ -57,7 +57,7 @@ impl ClientInit {
Ok(mut client) => {
client.register(player);
let _ = tx.send(Ok(client));
#[cfg(feature = "discord")]
{
match discord_instance.lock() {
@ -74,7 +74,7 @@ impl ClientInit {
}
}
}
return;
}
Err(err) => {