steamkit/types/
game_id.rs1use std::fmt;
4
5use crate::types::steam_id::BitVector64;
6
7#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
9pub enum GameType {
10 #[default]
12 App = 0,
13 GameMod = 1,
15 Shortcut = 2,
17 P2P = 3,
19}
20
21impl GameType {
22 pub const fn value(self) -> u32 {
24 self as u32
25 }
26
27 pub const fn from_raw(raw: u32) -> GameType {
29 match raw {
30 1 => GameType::GameMod,
31 2 => GameType::Shortcut,
32 3 => GameType::P2P,
33 _ => GameType::App,
34 }
35 }
36}
37
38#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
40pub struct GameID {
41 gameid: BitVector64,
42}
43
44impl GameID {
45 pub fn new() -> GameID {
47 GameID::from_value(0)
48 }
49
50 pub fn from_value(id: u64) -> GameID {
52 GameID {
53 gameid: BitVector64::new(id),
54 }
55 }
56
57 pub fn from_app_id(n_app_id: i32) -> GameID {
59 GameID::from_value(n_app_id as u64)
60 }
61
62 pub fn from_mod(n_app_id: u32, mod_path: &str) -> GameID {
64 let mut game_id = GameID::from_value(0);
65 game_id.set_app_id(n_app_id);
66 game_id.set_app_type(GameType::GameMod);
67 game_id.set_mod_id(crc32_of(mod_path.as_bytes()));
68 game_id
69 }
70
71 pub fn from_shortcut(exe_path: &str, app_name: &str) -> GameID {
73 let mut combined = String::with_capacity(exe_path.len() + app_name.len());
74 combined.push_str(exe_path);
75 combined.push_str(app_name);
76
77 let mut game_id = GameID::from_value(0);
78 game_id.set_app_id(0);
79 game_id.set_app_type(GameType::Shortcut);
80 game_id.set_mod_id(crc32_of(combined.as_bytes()));
81 game_id
82 }
83
84 pub fn set(&mut self, game_id: u64) {
86 self.gameid.set_data(game_id);
87 }
88
89 pub fn to_u64(&self) -> u64 {
91 self.gameid.data()
92 }
93
94 pub fn app_id(&self) -> u32 {
96 self.gameid.get(0, 0xFF_FFFF) as u32
97 }
98
99 pub fn set_app_id(&mut self, value: u32) {
101 self.gameid.set(0, 0xFF_FFFF, value as u64);
102 }
103
104 pub fn app_type(&self) -> GameType {
106 GameType::from_raw(self.gameid.get(24, 0xFF) as u32)
107 }
108
109 pub fn set_app_type(&mut self, value: GameType) {
111 self.gameid.set(24, 0xFF, value.value() as u64);
112 }
113
114 pub fn mod_id(&self) -> u32 {
116 self.gameid.get(32, 0xFFFF_FFFF) as u32
117 }
118
119 pub fn set_mod_id(&mut self, value: u32) {
121 self.gameid.set(32, 0xFFFF_FFFF, value as u64);
122 self.gameid.set(63, 0xFF, 1);
123 }
124
125 pub fn is_mod(&self) -> bool {
127 self.app_type() == GameType::GameMod
128 }
129
130 pub fn is_shortcut(&self) -> bool {
132 self.app_type() == GameType::Shortcut
133 }
134
135 pub fn is_p2p_file(&self) -> bool {
137 self.app_type() == GameType::P2P
138 }
139
140 pub fn is_steam_app(&self) -> bool {
142 self.app_type() == GameType::App
143 }
144}
145
146impl fmt::Display for GameID {
147 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
148 write!(f, "{}", self.to_u64())
149 }
150}
151
152impl fmt::Debug for GameID {
153 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
154 fmt::Display::fmt(self, f)
155 }
156}
157
158impl From<GameID> for u64 {
159 fn from(gid: GameID) -> u64 {
160 gid.to_u64()
161 }
162}
163
164impl From<u64> for GameID {
165 fn from(id: u64) -> GameID {
166 GameID::from_value(id)
167 }
168}
169
170impl From<GameID> for String {
171 fn from(gid: GameID) -> String {
172 gid.to_u64().to_string()
173 }
174}
175
176fn crc32_of(data: &[u8]) -> u32 {
178 crc32fast::hash(data)
179}