Can send first message to steam
This commit is contained in:
parent
8b1ad9078a
commit
07c6320c71
8
Cargo.lock
generated
8
Cargo.lock
generated
|
@ -471,6 +471,12 @@ version = "0.3.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "home"
|
||||
version = "0.5.9"
|
||||
|
@ -1612,9 +1618,11 @@ dependencies = [
|
|||
"color-eyre",
|
||||
"env_logger",
|
||||
"futures",
|
||||
"hex",
|
||||
"keyvalues-serde",
|
||||
"log",
|
||||
"protobuf",
|
||||
"rand",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"tokio",
|
||||
|
|
|
@ -8,9 +8,11 @@ async-tungstenite = { version = "0.27.0", features = ["tokio-rustls-native-certs
|
|||
color-eyre.workspace = true
|
||||
env_logger.workspace = true
|
||||
futures = "0.3.30"
|
||||
hex = "0.4.3"
|
||||
keyvalues-serde.workspace = true
|
||||
log.workspace = true
|
||||
protobuf.workspace = true
|
||||
rand = "0.8.5"
|
||||
reqwest = { version = "0.12", features = ["rustls-tls-native-roots"], default-features = false}
|
||||
serde = { version = "1.0.209", features = ["derive"] }
|
||||
tokio = { version = "1.39", features = ["rt", "rt-multi-thread", "macros"]}
|
||||
|
|
|
@ -41,6 +41,7 @@ pub async fn bootstrap_find_servers() -> eyre::Result<Vec<String>> {
|
|||
}
|
||||
|
||||
/// A message sent over the socket. Can be either sent or recieved
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CMProtoBufMessage<T: protobuf::Message> {
|
||||
pub action: enums_clientserver::EMsg,
|
||||
pub header: steammessages_base::CMsgProtoBufHeader,
|
||||
|
@ -54,7 +55,7 @@ impl<T: protobuf::Message> CMProtoBufMessage<T> {
|
|||
let length = 4 + 4 + self.header.compute_size() + self.body.compute_size();
|
||||
let mut out = Vec::with_capacity(length.try_into()?);
|
||||
|
||||
out.extend_from_slice(&self.action.value().to_le_bytes());
|
||||
out.extend_from_slice(&(self.action.value() as u32 | 0x80000000).to_le_bytes());
|
||||
out.extend_from_slice(&self.header.cached_size().to_le_bytes());
|
||||
self.header.write_to_vec(&mut out)?;
|
||||
self.body.write_to_vec(&mut out)?;
|
||||
|
@ -74,6 +75,7 @@ impl<T: protobuf::Message> CMProtoBufMessage<T> {
|
|||
}
|
||||
|
||||
/// A message sent over the socket, but the body is still serialized
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CMRawProtoBufMessage {
|
||||
pub action: enums_clientserver::EMsg,
|
||||
pub header: steammessages_base::CMsgProtoBufHeader,
|
||||
|
@ -232,6 +234,33 @@ impl CMSession {
|
|||
CMProtoBufMessage::<Response>::deserialize(response_raw)
|
||||
}
|
||||
|
||||
/// Send a message without a jobid
|
||||
pub async fn send_notification<T: protobuf::Message>(
|
||||
&mut self,
|
||||
action: enums_clientserver::EMsg,
|
||||
body: T,
|
||||
) -> eyre::Result<()> {
|
||||
let header = steammessages_base::CMsgProtoBufHeader {
|
||||
steamid: self.steam_id,
|
||||
realm: Some(self.realm),
|
||||
client_sessionid: Some(self.client_session_id),
|
||||
..Default::default()
|
||||
};
|
||||
let message = CMProtoBufMessage {
|
||||
action,
|
||||
header,
|
||||
body,
|
||||
};
|
||||
|
||||
let serialized = message.serialize()?;
|
||||
|
||||
self.socket
|
||||
.send(tungstenite::protocol::Message::Binary(serialized))
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Whether the current session is authenticated
|
||||
pub fn is_authed(&self) -> bool {
|
||||
self.steam_id.is_some()
|
||||
|
|
|
@ -1,4 +1,14 @@
|
|||
use color_eyre::eyre;
|
||||
use rand::RngCore;
|
||||
use vapore_proto::{
|
||||
enums_clientserver::EMsg,
|
||||
steammessages_auth_steamclient::{
|
||||
CAuthentication_BeginAuthSessionViaQR_Request,
|
||||
CAuthentication_BeginAuthSessionViaQR_Response, CAuthentication_DeviceDetails,
|
||||
EAuthTokenPlatformType,
|
||||
},
|
||||
steammessages_clientserver_login::CMsgClientHello,
|
||||
};
|
||||
|
||||
mod connection;
|
||||
|
||||
|
@ -12,7 +22,66 @@ pub async fn main() -> eyre::Result<()> {
|
|||
let servers = connection::bootstrap_find_servers().await?;
|
||||
log::debug!("Found servers: {:?}", servers);
|
||||
|
||||
let session = connection::CMSession::connect(&servers[0]).await?;
|
||||
let mut session = connection::CMSession::connect(&servers[0]).await?;
|
||||
|
||||
session
|
||||
.send_notification(
|
||||
EMsg::k_EMsgClientHello,
|
||||
CMsgClientHello {
|
||||
protocol_version: Some(0x1002c),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
||||
log::debug!("Sent hello");
|
||||
|
||||
// machine_id is supposed to be a binary key/value with the SHA1 of the machine's
|
||||
// BB3: Machine GUID
|
||||
// FF2: MAC address
|
||||
// 3B3: Disk ID
|
||||
// We should probably make these consistent so Valve doesn't get suspicious,
|
||||
// but for now let's make them random
|
||||
// TODO: Find a more generic way to make this
|
||||
let mut machine_id = Vec::with_capacity(161);
|
||||
machine_id.extend_from_slice(b"\x00MessageObject\x00");
|
||||
for key in [b"BB3", b"FF2", b"3B3"] {
|
||||
let mut data = [0u8; 20];
|
||||
rand::thread_rng().fill_bytes(&mut data);
|
||||
let hex_bytes = hex::encode(data).into_bytes();
|
||||
|
||||
// Type is string
|
||||
machine_id.push(b'\x01');
|
||||
machine_id.extend_from_slice(key);
|
||||
machine_id.push(b'\x00');
|
||||
machine_id.extend_from_slice(&hex_bytes);
|
||||
machine_id.push(b'\x00');
|
||||
}
|
||||
// suitable end bytes
|
||||
machine_id.extend_from_slice(b"\x08\x08");
|
||||
|
||||
let response = session
|
||||
.call_service_method::<_, CAuthentication_BeginAuthSessionViaQR_Response>(
|
||||
"Authentication.BeginAuthSessionViaQR#1".to_string(),
|
||||
CAuthentication_BeginAuthSessionViaQR_Request {
|
||||
device_details: protobuf::MessageField::some(CAuthentication_DeviceDetails {
|
||||
device_friendly_name: Some("vapore".to_string()),
|
||||
platform_type: Some(protobuf::EnumOrUnknown::new(
|
||||
EAuthTokenPlatformType::k_EAuthTokenPlatformType_SteamClient,
|
||||
)),
|
||||
// Windows 10
|
||||
os_type: Some(16),
|
||||
// Unknown
|
||||
gaming_device_type: Some(1),
|
||||
machine_id: Some(machine_id),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
||||
log::debug!("Got response {:#x?}", response);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue