Skip to content

Commit 253164d

Browse files
committed
Started implementing serialization logic
1 parent 73eda2e commit 253164d

File tree

10 files changed

+515
-74
lines changed

10 files changed

+515
-74
lines changed

config/client-example.toml

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,10 @@ nick = "[CHANGEME]"
1111
# The version used in the login packet
1212
version = "GSERV025"
1313

14-
# The platform for the joining client
15-
platform = "win"
16-
17-
# Three identifiers, which are used to identify the user's client, for security
18-
# purposes. The RC client actually uses three such identifiers, and I believe the
19-
# format is usually 3 16-byte values formatted as ASCII hex. The format is basically
20-
# the same as MD5 hashes.
21-
system_ids = ["[CHANGEME]", "[CHANGEME]", "[CHANGEME]"]
14+
# These are IDs used to identify the user's client, for security purposes. The RC client
15+
# actually uses three such identifiers, and I believe the format is usually 3 16-byte
16+
# values formatted as ASCII hex. The format is basically the same as MD5 hashes.
17+
identification = ["win", "[CHANGEME]", "[CHANGEME]", "[CHANGEME]"]
2218

2319
# The account username (e.g. Graal123456)
2420
auth.account_name = "[CHANGEME]"

logging_config.yaml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ appenders:
33
kind: console
44
encoder:
55
pattern: "{h({d(%Y-%m-%d %H:%M:%S)(utc)} - {l}: {m}{n})}"
6+
loggers:
7+
preagonal_client_rs:
8+
level: info
9+
appenders:
10+
- console
11+
additive: false
612
root:
7-
level: debug
13+
level: warn
814
appenders:
915
- console

src/config.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,9 @@ pub struct LoginConfig {
2222
pub nick: Option<String>,
2323
/// The version to use
2424
pub version: String,
25-
/// The account name to use
26-
pub platform: String,
2725
#[serde(default)]
2826
/// The system ids to use
29-
pub system_ids: Vec<String>,
27+
pub identification: Vec<String>,
3028
/// The auth to use
3129
pub auth: LoginAuth,
3230
}

src/main.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,12 +186,11 @@ async fn main() {
186186
let protocol = GProtocolV5::new(reader, writer);
187187
let encryption_key: u8 = rand::random::<u8>() & 0x7f;
188188
let login_packet = RcLogin::new(
189-
encryption_key as u32,
189+
encryption_key,
190190
login.version,
191191
login.auth.account_name,
192192
login.auth.password,
193-
login.platform,
194-
login.system_ids,
193+
login.identification,
195194
);
196195

197196
// Wrap the protocol in an Arc<Mutex<_>> so it can be shared safely.

src/net/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,6 @@ pub mod packet;
55

66
/// This module contains the protocol definitions and implementations.
77
pub mod protocol;
8+
9+
/// This module contains the serialization / deserialization logic
10+
pub mod serialization;
Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,30 @@
11
#![deny(missing_docs)]
22

3-
use crate::net::packet::{GPacket, PacketId};
3+
use serde::Serialize;
4+
5+
use crate::net::{
6+
packet::{GPacket, PacketId},
7+
serialization::serialize::serialize_to_vector,
8+
};
49

510
use super::FromClientPacketId;
611

712
/// RcChat packet.
8-
#[derive(Debug)]
13+
#[derive(Debug, Serialize)]
914
pub struct RcChat {
1015
/// Message
1116
pub message: String,
1217
}
1318

1419
impl RcChat {
1520
/// Create a new RcChat packet.
16-
pub fn new(message: String) -> Self {
17-
Self { message }
18-
}
19-
20-
fn serialize(&self) -> Vec<u8> {
21-
// Simply turn the message into a byte vector.
22-
self.message.as_bytes().to_vec()
21+
pub fn new<S>(message: S) -> Self
22+
where
23+
S: Into<String>,
24+
{
25+
Self {
26+
message: message.into(),
27+
}
2328
}
2429
}
2530

@@ -29,6 +34,6 @@ impl GPacket for RcChat {
2934
}
3035

3136
fn data(&self) -> Vec<u8> {
32-
self.serialize()
37+
serialize_to_vector(self).expect("Failed to serialize RcChat packet")
3338
}
3439
}
Lines changed: 25 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,48 @@
11
#![deny(missing_docs)]
22

3-
use crate::{
4-
io::{GraalIoError, io_vec::IntoSyncGraalWriterRef},
5-
net::packet::{GPacket, PacketId},
3+
use serde::Serialize;
4+
5+
use crate::net::{
6+
packet::{GPacket, PacketId},
7+
serialization::{GString, serialize::serialize_to_vector},
68
};
79

810
use super::FromClientPacketId;
911

1012
/// RcLogin packet.
11-
#[derive(Debug)]
13+
#[derive(Debug, Serialize)]
1214
pub struct RcLogin {
1315
/// Encryption key.
14-
pub encryption_key: u32,
16+
pub encryption_key: u8,
1517
/// Version.
1618
pub version: String,
1719
/// Account.
18-
pub account: String,
20+
pub account: GString,
1921
/// Password.
20-
pub password: String,
21-
/// Platform.
22-
pub platform: String,
22+
pub password: GString,
2323
/// PC IDs
24-
pub pc_ids: Vec<String>,
24+
pub identification: Vec<String>,
2525
}
2626

2727
impl RcLogin {
2828
/// Create a new RcLogin packet.
29-
pub fn new(
30-
encryption_key: u32,
31-
version: String,
32-
account: String,
33-
password: String,
34-
platform: String,
35-
pc_ids: Vec<String>,
36-
) -> Self {
29+
pub fn new<S>(
30+
encryption_key: u8,
31+
version: S,
32+
account: S,
33+
password: S,
34+
identification: Vec<String>,
35+
) -> Self
36+
where
37+
S: Into<String>,
38+
{
3739
Self {
3840
encryption_key,
39-
version,
40-
account,
41-
password,
42-
platform,
43-
pc_ids,
44-
}
45-
}
46-
47-
fn serialize(&self) -> Result<Vec<u8>, GraalIoError> {
48-
let mut vec = Vec::new();
49-
{
50-
let mut writer = vec.into_sync_graal_writer();
51-
52-
writer.write_gu8(self.encryption_key.into())?;
53-
writer.write_bytes(self.version.as_bytes())?;
54-
writer.write_gstring(&self.account)?;
55-
writer.write_gstring(&self.password)?;
56-
writer.write_bytes(self.platform.as_bytes())?;
57-
writer.write_bytes(b",\"")?;
58-
for (i, pc_id) in self.pc_ids.iter().enumerate() {
59-
if i > 0 {
60-
writer.write_bytes(b"\",\"")?;
61-
}
62-
writer.write_bytes(pc_id.as_bytes())?;
63-
}
64-
writer.write_bytes(b"\"")?;
65-
writer.flush()?;
41+
version: version.into(),
42+
account: GString(account.into()),
43+
password: GString(password.into()),
44+
identification,
6645
}
67-
68-
Ok(vec)
6946
}
7047
}
7148

@@ -75,7 +52,6 @@ impl GPacket for RcLogin {
7552
}
7653

7754
fn data(&self) -> Vec<u8> {
78-
self.serialize()
79-
.expect("Failed to serialize RcLogin packet")
55+
serialize_to_vector(&self).expect("Failed to serialize RcLogin packet")
8056
}
8157
}

src/net/serialization/error.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use std::fmt::Display;
2+
3+
use serde::de;
4+
use thiserror::Error;
5+
6+
use crate::io::GraalIoError;
7+
8+
/// An error type for Graal IO operations.
9+
#[derive(Debug, Error)]
10+
pub enum GraalSerializationError {
11+
/// An IO error occurred.
12+
#[error("IO error: {0}")]
13+
Io(#[from] GraalIoError),
14+
15+
/// An error occurred while encoding or decoding a Graal value.
16+
#[error("Other: {0}")]
17+
Other(String),
18+
}
19+
20+
impl serde::ser::Error for GraalSerializationError {
21+
fn custom<T: Display>(msg: T) -> Self {
22+
GraalSerializationError::Other(msg.to_string())
23+
}
24+
}
25+
26+
impl de::Error for GraalSerializationError {
27+
fn custom<T: Display>(msg: T) -> Self {
28+
GraalSerializationError::Other(msg.to_string())
29+
}
30+
}

src/net/serialization/mod.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#![deny(missing_docs)]
2+
3+
use serde::{Deserialize, Serialize};
4+
5+
/// This module defines the error types for serialization.
6+
pub mod error;
7+
/// This module handles the serialization of packets.
8+
pub mod serialize;
9+
10+
/// A GString is a string that is serialized as a length-preceded string.
11+
#[derive(Debug, Serialize, Deserialize)]
12+
pub struct GString(pub String);
13+
14+
/// Allow conversion from GString to String.
15+
impl From<GString> for String {
16+
fn from(g: GString) -> Self {
17+
g.0
18+
}
19+
}
20+
21+
/// Allow conversion from String to GString.
22+
impl From<String> for GString {
23+
fn from(s: String) -> Self {
24+
GString(s)
25+
}
26+
}
27+
28+
/// Allow conversion from &str to GString.
29+
impl From<&str> for GString {
30+
fn from(s: &str) -> Self {
31+
GString(s.to_string())
32+
}
33+
}

0 commit comments

Comments
 (0)