use std::fmt;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use crate::types::steam_id::BitVector64;
const STEAM_EPOCH_UNIX_SECONDS: u64 = 1_104_537_600;
#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct GlobalID {
gid_bits: BitVector64,
}
impl GlobalID {
pub fn new() -> GlobalID {
GlobalID::from_value(u64::MAX)
}
pub fn from_value(gid: u64) -> GlobalID {
GlobalID {
gid_bits: BitVector64::new(gid),
}
}
pub fn value(&self) -> u64 {
self.gid_bits.data()
}
pub fn set_value(&mut self, value: u64) {
self.gid_bits.set_data(value);
}
pub fn sequential_count(&self) -> u32 {
self.gid_bits.get(0, 0xF_FFFF) as u32
}
pub fn set_sequential_count(&mut self, value: u32) {
self.gid_bits.set(0, 0xF_FFFF, value as u64);
}
pub fn start_time(&self) -> SystemTime {
let start_time = self.gid_bits.get(20, 0x3_FFFF_FFFF) as u64;
UNIX_EPOCH + Duration::from_secs(STEAM_EPOCH_UNIX_SECONDS + start_time)
}
pub fn set_start_time(&mut self, value: SystemTime) {
let unix_seconds = match value.duration_since(UNIX_EPOCH) {
Ok(delta) => delta.as_secs() as i64,
Err(err) => -(err.duration().as_secs() as i64),
};
let seconds_since_steam_epoch = unix_seconds - STEAM_EPOCH_UNIX_SECONDS as i64;
self.gid_bits
.set(20, 0x3_FFFF_FFFF, seconds_since_steam_epoch as u64);
}
pub fn process_id(&self) -> u32 {
self.gid_bits.get(50, 0xF) as u32
}
pub fn set_process_id(&mut self, value: u32) {
self.gid_bits.set(50, 0xF, value as u64);
}
pub fn box_id(&self) -> u32 {
self.gid_bits.get(54, 0x3_FF) as u32
}
pub fn set_box_id(&mut self, value: u32) {
self.gid_bits.set(54, 0x3_FF, value as u64);
}
}
impl fmt::Display for GlobalID {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.value())
}
}
impl fmt::Debug for GlobalID {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}
impl From<GlobalID> for u64 {
fn from(gid: GlobalID) -> u64 {
gid.value()
}
}
impl From<u64> for GlobalID {
fn from(gid: u64) -> GlobalID {
GlobalID::from_value(gid)
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct UGCHandle {
global_id: GlobalID,
}
impl UGCHandle {
pub fn new() -> UGCHandle {
UGCHandle {
global_id: GlobalID::new(),
}
}
pub fn from_value(ugc_id: u64) -> UGCHandle {
UGCHandle {
global_id: GlobalID::from_value(ugc_id),
}
}
pub fn value(&self) -> u64 {
self.global_id.value()
}
pub fn global_id(&self) -> GlobalID {
self.global_id
}
}
impl fmt::Display for UGCHandle {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.value())
}
}
impl fmt::Debug for UGCHandle {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}
impl From<UGCHandle> for u64 {
fn from(handle: UGCHandle) -> u64 {
handle.value()
}
}
impl From<u64> for UGCHandle {
fn from(ugc_id: u64) -> UGCHandle {
UGCHandle::from_value(ugc_id)
}
}