New opcode: PLAYER_UPDATE_TIMESTAMP

This commit is contained in:
techmetx11 2024-07-21 13:37:34 +01:00
parent 446120f5c9
commit 115c690416
No known key found for this signature in database
GPG Key ID: E60B63635FF4E062
5 changed files with 93 additions and 42 deletions

View File

@ -84,3 +84,14 @@ No additional data required
|has_player| 1 | If the server has a player, this variable will be `0xFF`. or else, it will be `0x00`| |has_player| 1 | If the server has a player, this variable will be `0xFF`. or else, it will be `0x00`|
|player_id | 4 | The server's current player ID. If the server has no player, this will always be `0x00000000`| |player_id | 4 | The server's current player ID. If the server has no player, this will always be `0x00000000`|
### `PLAYER_UPDATE_TIMESTAMP` (0x05)
Get the time of the last player update, The time is represented as seconds since the last update
#### Request
No additional data required
#### Response
| Name | Size (bytes) | Description |
|----------|--------------|-------------|
|timestamp | 8 | Seconds since the last player update |

View File

@ -1,6 +1,6 @@
use futures::SinkExt; use futures::SinkExt;
use rquickjs::{async_with, AsyncContext, AsyncRuntime}; use rquickjs::{async_with, AsyncContext, AsyncRuntime};
use std::{num::NonZeroUsize, sync::Arc, thread::available_parallelism}; use std::{num::NonZeroUsize, sync::Arc, thread::available_parallelism, time::SystemTime};
use tokio::{runtime::Handle, sync::Mutex, task::block_in_place}; use tokio::{runtime::Handle, sync::Mutex, task::block_in_place};
use tub::Pool; use tub::Pool;
@ -12,6 +12,7 @@ pub enum JobOpcode {
DecryptSignature, DecryptSignature,
GetSignatureTimestamp, GetSignatureTimestamp,
PlayerStatus, PlayerStatus,
PlayerUpdateTimestamp,
UnknownOpcode, UnknownOpcode,
} }
@ -23,6 +24,7 @@ impl std::fmt::Display for JobOpcode {
Self::DecryptSignature => write!(f, "DecryptSignature"), Self::DecryptSignature => write!(f, "DecryptSignature"),
Self::GetSignatureTimestamp => write!(f, "GetSignatureTimestamp"), Self::GetSignatureTimestamp => write!(f, "GetSignatureTimestamp"),
Self::PlayerStatus => write!(f, "PlayerStatus"), Self::PlayerStatus => write!(f, "PlayerStatus"),
Self::PlayerUpdateTimestamp => write!(f, "PlayerUpdateTimestamp"),
Self::UnknownOpcode => write!(f, "UnknownOpcode"), Self::UnknownOpcode => write!(f, "UnknownOpcode"),
} }
} }
@ -35,6 +37,7 @@ impl From<u8> for JobOpcode {
0x02 => Self::DecryptSignature, 0x02 => Self::DecryptSignature,
0x03 => Self::GetSignatureTimestamp, 0x03 => Self::GetSignatureTimestamp,
0x04 => Self::PlayerStatus, 0x04 => Self::PlayerStatus,
0x05 => Self::PlayerUpdateTimestamp,
_ => Self::UnknownOpcode, _ => Self::UnknownOpcode,
} }
} }
@ -47,6 +50,7 @@ pub struct PlayerInfo {
pub signature_timestamp: u64, pub signature_timestamp: u64,
pub player_id: u32, pub player_id: u32,
pub has_player: u8, pub has_player: u8,
pub last_update: SystemTime,
} }
pub struct JavascriptInterpreter { pub struct JavascriptInterpreter {
@ -106,6 +110,7 @@ impl GlobalState {
player_id: Default::default(), player_id: Default::default(),
signature_timestamp: Default::default(), signature_timestamp: Default::default(),
has_player: 0x00, has_player: 0x00,
last_update: SystemTime::now(),
}), }),
js_runtime_pool: runtime_pool, js_runtime_pool: runtime_pool,
} }
@ -129,10 +134,7 @@ pub async fn process_fetch_update<W>(
opcode: JobOpcode::ForceUpdate, opcode: JobOpcode::ForceUpdate,
request_id, request_id,
update_status: status, update_status: status,
signature: Default::default(), ..Default::default()
signature_timestamp: Default::default(),
has_player: Default::default(),
player_id: Default::default(),
}) })
.await; .await;
} }
@ -171,11 +173,7 @@ pub async fn process_decrypt_n_signature<W>(
let _ = writer.send(OpcodeResponse { let _ = writer.send(OpcodeResponse {
opcode: JobOpcode::DecryptNSignature, opcode: JobOpcode::DecryptNSignature,
request_id, request_id,
update_status: Ok(Default::default()), ..Default::default()
signature: String::new(),
signature_timestamp: Default::default(),
has_player: Default::default(),
player_id: Default::default(),
}).await; }).await;
return; return;
} }
@ -203,11 +201,7 @@ pub async fn process_decrypt_n_signature<W>(
let _ = writer.send(OpcodeResponse { let _ = writer.send(OpcodeResponse {
opcode: JobOpcode::DecryptNSignature, opcode: JobOpcode::DecryptNSignature,
request_id, request_id,
update_status: Ok(Default::default()), ..Default::default()
signature: String::new(),
signature_timestamp: Default::default(),
has_player: Default::default(),
player_id: Default::default(),
}).await; }).await;
return; return;
} }
@ -218,11 +212,8 @@ pub async fn process_decrypt_n_signature<W>(
let _ = writer.send(OpcodeResponse { let _ = writer.send(OpcodeResponse {
opcode: JobOpcode::DecryptNSignature, opcode: JobOpcode::DecryptNSignature,
request_id, request_id,
update_status: Ok(Default::default()),
signature: decrypted_string, signature: decrypted_string,
signature_timestamp: Default::default(), ..Default::default()
has_player: Default::default(),
player_id: Default::default(),
}).await; }).await;
}) })
.await; .await;
@ -261,11 +252,7 @@ pub async fn process_decrypt_signature<W>(
let _ = writer.send(OpcodeResponse { let _ = writer.send(OpcodeResponse {
opcode: JobOpcode::DecryptSignature, opcode: JobOpcode::DecryptSignature,
request_id, request_id,
update_status: Ok(Default::default()), ..Default::default()
signature: String::new(),
signature_timestamp: Default::default(),
has_player: Default::default(),
player_id: Default::default(),
}).await; }).await;
return; return;
} }
@ -296,11 +283,7 @@ pub async fn process_decrypt_signature<W>(
let _ = writer.send(OpcodeResponse { let _ = writer.send(OpcodeResponse {
opcode: JobOpcode::DecryptSignature, opcode: JobOpcode::DecryptSignature,
request_id, request_id,
update_status: Ok(Default::default()), ..Default::default()
signature: String::new(),
signature_timestamp: Default::default(),
has_player: Default::default(),
player_id: Default::default(),
}).await; }).await;
return; return;
} }
@ -311,11 +294,8 @@ pub async fn process_decrypt_signature<W>(
let _ = writer.send(OpcodeResponse { let _ = writer.send(OpcodeResponse {
opcode: JobOpcode::DecryptSignature, opcode: JobOpcode::DecryptSignature,
request_id, request_id,
update_status: Ok(Default::default()),
signature: decrypted_string, signature: decrypted_string,
signature_timestamp: Default::default(), ..Default::default()
has_player: Default::default(),
player_id: Default::default(),
}).await; }).await;
}) })
.await; .await;
@ -339,11 +319,8 @@ pub async fn process_get_signature_timestamp<W>(
.send(OpcodeResponse { .send(OpcodeResponse {
opcode: JobOpcode::GetSignatureTimestamp, opcode: JobOpcode::GetSignatureTimestamp,
request_id, request_id,
update_status: Ok(Default::default()),
signature: String::new(),
signature_timestamp: timestamp, signature_timestamp: timestamp,
has_player: Default::default(), ..Default::default()
player_id: Default::default(),
}) })
.await; .await;
} }
@ -368,11 +345,38 @@ pub async fn process_player_status<W>(
.send(OpcodeResponse { .send(OpcodeResponse {
opcode: JobOpcode::PlayerStatus, opcode: JobOpcode::PlayerStatus,
request_id, request_id,
update_status: Ok(Default::default()),
signature: String::new(),
signature_timestamp: Default::default(),
has_player, has_player,
player_id, player_id,
..Default::default()
})
.await;
}
pub async fn process_player_update_timestamp<W>(
state: Arc<GlobalState>,
stream: Arc<Mutex<W>>,
request_id: u32,
) where
W: SinkExt<OpcodeResponse> + Unpin + Send,
{
let cloned_writer = stream.clone();
let global_state = state.clone();
let player_info = global_state.player_info.lock().await;
let last_update = player_info.last_update;
let mut writer = cloned_writer.lock().await;
let _ = writer
.send(OpcodeResponse {
opcode: JobOpcode::PlayerUpdateTimestamp,
request_id,
last_player_update: SystemTime::now()
.duration_since(last_update)
.unwrap()
.as_secs(),
..Default::default()
}) })
.await; .await;
} }

View File

@ -18,6 +18,7 @@ use tokio_util::codec::Framed;
use crate::jobs::{ use crate::jobs::{
process_decrypt_signature, process_get_signature_timestamp, process_player_status, process_decrypt_signature, process_get_signature_timestamp, process_player_status,
process_player_update_timestamp,
}; };
macro_rules! break_fail { macro_rules! break_fail {
@ -152,6 +153,18 @@ async fn process_socket(state: Arc<GlobalState>, socket: UnixStream) {
.await; .await;
}); });
} }
JobOpcode::PlayerUpdateTimestamp => {
let cloned_state = state.clone();
let cloned_sink = arc_sink.clone();
tokio::spawn(async move {
process_player_update_timestamp(
cloned_state,
cloned_sink,
opcode.request_id,
)
.await;
});
}
_ => { _ => {
continue; continue;
} }

View File

@ -27,8 +27,23 @@ pub struct OpcodeResponse {
pub has_player: u8, pub has_player: u8,
pub player_id: u32, pub player_id: u32,
pub last_player_update: u64,
} }
impl Default for OpcodeResponse {
fn default() -> Self {
OpcodeResponse {
opcode: JobOpcode::ForceUpdate,
request_id: 0,
update_status: Ok(()),
signature: String::new(),
signature_timestamp: 0,
has_player: 0,
player_id: 0,
last_player_update: 0,
}
}
}
impl Decoder for OpcodeDecoder { impl Decoder for OpcodeDecoder {
type Item = Opcode; type Item = Opcode;
type Error = std::io::Error; type Error = std::io::Error;
@ -47,7 +62,10 @@ impl Decoder for OpcodeDecoder {
let request_id: u32 = u32::from_be_bytes(src[1..5].try_into().unwrap()); let request_id: u32 = u32::from_be_bytes(src[1..5].try_into().unwrap());
match opcode { match opcode {
JobOpcode::ForceUpdate | JobOpcode::GetSignatureTimestamp | JobOpcode::PlayerStatus => { JobOpcode::ForceUpdate
| JobOpcode::GetSignatureTimestamp
| JobOpcode::PlayerStatus
| JobOpcode::PlayerUpdateTimestamp => {
src.advance(5); src.advance(5);
Ok(Some(Opcode { Ok(Some(Opcode {
opcode, opcode,
@ -123,6 +141,10 @@ impl Encoder<OpcodeResponse> for OpcodeDecoder {
dst.put_u8(item.has_player); dst.put_u8(item.has_player);
dst.put_u32(item.player_id); dst.put_u32(item.player_id);
} }
JobOpcode::PlayerUpdateTimestamp => {
dst.put_u32(8);
dst.put_u64(item.last_player_update);
}
_ => {} _ => {}
} }
Ok(()) Ok(())

View File

@ -1,4 +1,4 @@
use std::sync::Arc; use std::{sync::Arc, time::SystemTime};
use regex::Regex; use regex::Regex;
@ -180,6 +180,7 @@ pub async fn fetch_update(state: Arc<GlobalState>) -> Result<(), FetchUpdateStat
current_player_info.sig_function_name = sig_function_name.to_string(); current_player_info.sig_function_name = sig_function_name.to_string();
current_player_info.signature_timestamp = signature_timestamp; current_player_info.signature_timestamp = signature_timestamp;
current_player_info.has_player = 0xFF; current_player_info.has_player = 0xFF;
current_player_info.last_update = SystemTime::now();
Ok(()) Ok(())
} }