mirror of
https://github.com/LCE-Hub/LCE-Emerald-Launcher.git
synced 2026-09-23 08:32:51 +00:00
feat: playtime counting
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use tauri::{AppHandle, Manager, State};
|
||||
use tauri_plugin_opener::OpenerExt;
|
||||
use crate::commands::runners;
|
||||
@@ -8,6 +9,7 @@ use crate::config;
|
||||
use crate::platform::macos;
|
||||
#[cfg(unix)]
|
||||
use crate::platform::linux;
|
||||
use crate::playtime::{self, PlaytimeResponse};
|
||||
use crate::state::GameState;
|
||||
use crate::types::McServer;
|
||||
use crate::util;
|
||||
@@ -113,6 +115,7 @@ pub async fn launch_game(
|
||||
cmd.arg(a);
|
||||
}
|
||||
cmd.current_dir(&working_dir);
|
||||
let playtime_start = std::time::Instant::now();
|
||||
let child = cmd.spawn().map_err(|e| e.to_string())?;
|
||||
{
|
||||
let mut lock = state.child.lock().await;
|
||||
@@ -138,6 +141,11 @@ pub async fn launch_game(
|
||||
*lock = None;
|
||||
}
|
||||
|
||||
let duration = playtime_start.elapsed();
|
||||
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs();
|
||||
let start = now - duration.as_secs();
|
||||
playtime::record_session(&app, &instance_id, start, now);
|
||||
|
||||
return if status.success() || status.code() == Some(253) || status.code() == Some(96) {
|
||||
Ok(())
|
||||
} else {
|
||||
@@ -222,6 +230,7 @@ pub async fn launch_game(
|
||||
.stdout(std::process::Stdio::null())
|
||||
.stderr(std::process::Stdio::null());
|
||||
|
||||
let playtime_start = std::time::Instant::now();
|
||||
let child = cmd.spawn().map_err(|e| e.to_string())?;
|
||||
{
|
||||
let mut lock = state.child.lock().await;
|
||||
@@ -247,6 +256,11 @@ pub async fn launch_game(
|
||||
*lock = None;
|
||||
}
|
||||
|
||||
let duration = playtime_start.elapsed();
|
||||
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs();
|
||||
let start = now - duration.as_secs();
|
||||
playtime::record_session(&app, &instance_id, start, now);
|
||||
|
||||
return if status.success() || status.code() == Some(253) || status.code() == Some(96) {
|
||||
Ok(())
|
||||
} else {
|
||||
@@ -263,6 +277,7 @@ pub async fn launch_game(
|
||||
#[cfg(unix)]
|
||||
cmd.process_group(0);
|
||||
cmd.current_dir(&working_dir);
|
||||
let playtime_start = std::time::Instant::now();
|
||||
let child = cmd.spawn().map_err(|e| e.to_string())?;
|
||||
{
|
||||
let mut lock = state.child.lock().await;
|
||||
@@ -285,6 +300,10 @@ pub async fn launch_game(
|
||||
let mut lock = state.child.lock().await;
|
||||
*lock = None;
|
||||
}
|
||||
let duration = playtime_start.elapsed();
|
||||
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs();
|
||||
let start = now - duration.as_secs();
|
||||
playtime::record_session(&app, &instance_id, start, now);
|
||||
return if status.success() || status.code() == Some(253) || status.code() == Some(96) {
|
||||
Ok(())
|
||||
} else {
|
||||
@@ -362,6 +381,11 @@ pub fn get_instance_path(app: AppHandle, instance_id: String) -> String {
|
||||
.to_string()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn get_playtime(app: AppHandle, instance_id: String) -> PlaytimeResponse {
|
||||
playtime::get_playtime(&app, &instance_id)
|
||||
}
|
||||
|
||||
pub fn ensure_server_list(instance_dir: &PathBuf, servers: Vec<McServer>) {
|
||||
let servers_db = instance_dir.join("servers.db");
|
||||
let mut all_servers = Vec::new();
|
||||
|
||||
@@ -2,6 +2,7 @@ mod types;
|
||||
mod state;
|
||||
mod config;
|
||||
mod util;
|
||||
mod playtime;
|
||||
mod platform;
|
||||
mod networking;
|
||||
mod workshop_server;
|
||||
@@ -80,6 +81,7 @@ pub fn run() {
|
||||
steam::add_to_steam,
|
||||
proxy_cmd::http_proxy_request,
|
||||
game::get_instance_path,
|
||||
game::get_playtime,
|
||||
commands::console2lce::import_world,
|
||||
stun::stun_discover,
|
||||
direct::start_direct_proxy,
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use tauri::AppHandle;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use crate::util;
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct PlaytimeSession {
|
||||
pub start: u64,
|
||||
pub end: u64,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct PlaytimeData {
|
||||
pub sessions: HashMap<String, Vec<PlaytimeSession>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Clone, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PlaytimeResponse {
|
||||
pub total_seconds: u64,
|
||||
pub week_seconds: u64,
|
||||
pub day_seconds: u64,
|
||||
}
|
||||
|
||||
fn playtime_path(app: &AppHandle) -> PathBuf {
|
||||
util::get_app_dir(app).join("playtime.json")
|
||||
}
|
||||
|
||||
pub fn load(app: &AppHandle) -> PlaytimeData {
|
||||
let path = playtime_path(app);
|
||||
if path.exists() {
|
||||
let content = std::fs::read_to_string(&path).unwrap_or_default();
|
||||
serde_json::from_str(&content).unwrap_or(PlaytimeData { sessions: HashMap::new() })
|
||||
} else {
|
||||
PlaytimeData { sessions: HashMap::new() }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn save(app: &AppHandle, data: &PlaytimeData) {
|
||||
let path = playtime_path(app);
|
||||
if let Some(parent) = path.parent() {
|
||||
let _ = std::fs::create_dir_all(parent);
|
||||
}
|
||||
if let Ok(content) = serde_json::to_string_pretty(data) {
|
||||
let _ = std::fs::write(&path, content);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn record_session(app: &AppHandle, instance_id: &str, start: u64, end: u64) {
|
||||
let mut data = load(app);
|
||||
let sessions = data.sessions.entry(instance_id.to_string()).or_default();
|
||||
sessions.push(PlaytimeSession { start, end });
|
||||
save(app, &data);
|
||||
}
|
||||
|
||||
pub fn get_playtime(app: &AppHandle, instance_id: &str) -> PlaytimeResponse {
|
||||
let data = load(app);
|
||||
let sessions = data.sessions.get(instance_id);
|
||||
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs();
|
||||
let week_ago = now - 7 * 24 * 60 * 60;
|
||||
let day_ago = now - 24 * 60 * 60;
|
||||
let total_seconds: u64 = sessions.map_or(0, |s| s.iter().map(|s| s.end - s.start).sum());
|
||||
let week_seconds: u64 = sessions.map_or(0, |s| s.iter()
|
||||
.filter(|s| s.start >= week_ago)
|
||||
.map(|s| s.end - s.start)
|
||||
.sum());
|
||||
let day_seconds: u64 = sessions.map_or(0, |s| s.iter()
|
||||
.filter(|s| s.start >= day_ago)
|
||||
.map(|s| s.end - s.start)
|
||||
.sum());
|
||||
|
||||
PlaytimeResponse { total_seconds, week_seconds, day_seconds }
|
||||
}
|
||||
Reference in New Issue
Block a user