Last active
April 23, 2019 18:48
-
-
Save trilleplay/a110aca3c2e90c373221ea4827a689a6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate tungstenite; | |
extern crate url; | |
use url::Url; | |
use tungstenite::{Message, connect}; | |
use serde_json::{Value}; | |
use super::rest; | |
use std::time; | |
use std::thread; | |
use std::sync::RwLock; | |
use std::sync::Arc; | |
use std::sync::Mutex; | |
// Defining Opcodes here as per https://discordapp.com/developers/docs/topics/opcodes-and-status-codes#gateway | |
#[allow(dead_code)] | |
const OPCODE_DISPATCH: i32 = 0; | |
#[allow(dead_code)] | |
const OPCODE_HEARTBEAT: i32 = 1; | |
#[allow(dead_code)] | |
const OPCODE_IDENTIFY: i32 = 2; | |
#[allow(dead_code)] | |
const OPCODE_STATUS_UPDATE: i32 = 3; | |
#[allow(dead_code)] | |
const OPCODE_VOICE_STATE_UPDATE: i32 = 4; | |
#[allow(dead_code)] | |
const OPCODE_RESUME: i32 = 6; | |
#[allow(dead_code)] | |
const OPCODE_RECONNECT: i32 = 7; | |
#[allow(dead_code)] | |
const OPCODE_REQUEST_GUILD_MEMBERS: i32 = 8; | |
#[allow(dead_code)] | |
const OPCODE_INVAILD_SESSION: i32 = 9; | |
const OPCODE_HELLO: i32 = 10; | |
const OPCODE_HEARTBEAT_ACK: i32 = 11; | |
lazy_static! { | |
static ref GLOBAL_SEQ_NUM: RwLock<String> = RwLock::new("null".to_string()); | |
static ref GLOBAL_HEARTBEAT_I: RwLock<Option<u64>> = RwLock::new(Some(0)); | |
} | |
pub fn login(auth_token: String) { | |
let (mut socket, response) = connect(Url::parse(&rest::findgateway().unwrap()).unwrap()) | |
.expect("Connection failed."); | |
let socket = Arc::new(Mutex::new(socket)); | |
println!("Gateway connection established."); | |
let handler = thread::spawn({ | |
let socket = Arc::clone(&socket); | |
move || { | |
loop { | |
println!("event loop"); | |
let msg = socket.lock().unwrap().read_message().expect("Error reading message"); | |
if let Message::Text(text) = msg { | |
println!("Received: {}", text); | |
let v: Value = serde_json::from_str(&text).unwrap(); | |
if v["op"] == OPCODE_HELLO { | |
let mut seq_num_mod = GLOBAL_SEQ_NUM.write().unwrap(); | |
*seq_num_mod = v["s"].to_string(); | |
let mut set_heartbeat_interval = GLOBAL_HEARTBEAT_I.write().unwrap(); | |
*set_heartbeat_interval = v["d"]["heartbeat_interval"].as_u64(); | |
socket.lock().unwrap().write_message(Message::Text(format!(r#"{{"op": 2,"d": {{"token": "{}","properties":{{"$os":"windows","$browser":"oxidecord","$device":"oxidecord"}},"compress":false,"large_threshold":250}}}} "#, auth_token).into())).unwrap(); | |
socket.lock().unwrap().write_message(Message::Text(format!(r#"{{"op": 1,"d": {} }}"#, seq_num_mod)).into()).unwrap(); | |
} | |
if v["op"] == OPCODE_HEARTBEAT_ACK { | |
let mut seq_num_mod = GLOBAL_SEQ_NUM.write().unwrap(); | |
*seq_num_mod = v["s"].to_string(); | |
println!("[OXIDECORD] Heartbeat ACK recieved.") | |
} | |
if v["op"] == OPCODE_DISPATCH { | |
let mut seq_num_mod = GLOBAL_SEQ_NUM.write().unwrap(); | |
*seq_num_mod = v["s"].to_string(); | |
println!("[OXIDECORD] Payload recieved.") | |
} | |
} | |
} | |
} | |
}); | |
thread::spawn({ | |
let socket = Arc::clone(&socket); | |
move|| { | |
let socket = Arc::clone(&socket); | |
let heartbeat_i_var = GLOBAL_HEARTBEAT_I.read().unwrap(); | |
let heartbeat_sleep_millis = time::Duration::from_millis(40000); | |
let now = time::Instant::now(); | |
thread::sleep(heartbeat_sleep_millis); | |
println!("Sending Heartbeat"); | |
let seq_num = GLOBAL_SEQ_NUM.read().unwrap(); | |
socket.lock().unwrap().write_message(Message::Text(format!(r#"{{"op": 1,"d": {} }}"#, *seq_num)).into()).unwrap(); | |
} | |
}); | |
handler.join(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment