csgo_gsi_builder/
lib.rs

1//! CSGO Game State Integration builder
2//!
3//! CSGO Game State Integration configuration file builder and installer.
4//!
5//! # Exemples
6//!
7//! You can use one of the ready made components:
8//!
9//! ```no_run
10//! use csgo_gsi_builder::{config::Config, Builder, Components};
11//!
12//! let mut config_builder = Builder::with_config(Config {
13//!     name: String::from("my_gsi_config_file"),
14//!     data: Components::ALL.into(),
15//!     ..Default::default()
16//! });
17//! config_builder
18//!     .build()
19//!     .install("C:\\Counter-Strike Global Offensive\\csgo\\cfg")
20//!     .unwrap();
21//! ```
22//!
23//! Or create your own set of components:
24//!
25//! ```no_run
26//! use csgo_gsi_builder::{
27//!     config::{Config, Data},
28//!     Builder, Components,
29//! };
30//!
31//! let components: &[Components] = &[Components::Provider, Components::PlayerId];
32//! let mut config_builder = Builder::with_config(Config {
33//!     name: String::from("my_gsi_config_file"),
34//!     data: Data::from(components),
35//!     ..Default::default()
36//! });
37//! config_builder
38//!     .build()
39//!     .install("C:\\Counter-Strike Global Offensive\\csgo\\cfg")
40//!     .unwrap();
41//! ```
42//!
43//! # auto-install support
44//!
45//! You can enable the `auto_install` feature to install automatically the
46//! config into CSGO's cfg folder
47//!
48//! ```no_run
49//! use csgo_gsi_builder::{config::Config, Builder, Components};
50//!
51//! let mut config_builder = Builder::with_config(Config {
52//!     name: String::from("my_gsi_config_file"),
53//!     data: Components::ALL.into(),
54//!     ..Default::default()
55//! });
56//! config_builder.build().auto_install().unwrap();
57//! ```
58
59mod components;
60pub use components::Components; // re-export to avoid repetition
61
62pub mod config;
63
64use std::fs;
65use std::path::PathBuf;
66
67use crate::config::Config;
68
69#[derive(Default)]
70pub struct Builder {
71    config: Config,
72    output: String,
73}
74
75impl Builder {
76    /// Creates a config file builder based on a [`Config`].
77    pub fn with_config(config: Config) -> Self {
78        Self {
79            config,
80            ..Default::default()
81        }
82    }
83
84    /// Serializes the [`Config`] to a string ready to be written in a cfg file.
85    pub fn build(&mut self) -> &mut Self {
86        self.output = vdf_serde::to_string(&self.config).unwrap();
87        self
88    }
89
90    /// Gets the serialized [`Config`].
91    ///
92    /// This method must only be called after `build`.
93    pub fn output(&self) -> String {
94        self.output.clone()
95    }
96
97    /// Write the serialized [`Config`] to a cfg file at the path passed in
98    /// argument.
99    pub fn install<P: Into<PathBuf>>(
100        &self,
101        folder_path: P,
102    ) -> Result<(), Box<dyn std::error::Error>> {
103        assert!(
104            !self.output.is_empty(),
105            "config should be build before installing"
106        );
107
108        let mut path: PathBuf = folder_path.into();
109
110        let folder_path = path.as_path();
111        let metadata = fs::metadata(folder_path)?;
112        if !metadata.is_dir() {
113            return Err(format!("{} is not a directory", folder_path.to_string_lossy()).into());
114        }
115
116        path.push(&format!("gamestate_integration_{}.cfg", self.config.name));
117        fs::write(path, self.output.as_bytes())?;
118
119        Ok(())
120    }
121
122    /// Automatically find the CSGO install directory and write the serialized.
123    /// [`Config`] to a cfg file
124    #[cfg(feature = "auto_install")]
125    pub fn auto_install(&self) -> Result<(), Box<dyn std::error::Error>> {
126        let mut steam_dir =
127            steamlocate::SteamDir::locate().ok_or("could not locate steam install directory")?;
128        match steam_dir.app(&730) {
129            None => Err("could not locate CSGO install directory".into()),
130            Some(csgo) => {
131                let mut csgo_path = csgo.path.clone();
132                csgo_path.push("csgo");
133                csgo_path.push("cfg");
134
135                self.install(csgo_path)
136            }
137        }
138    }
139}