Skip to content

Commit

Permalink
this is so cool
Browse files Browse the repository at this point in the history
  • Loading branch information
dankmeme01 committed Nov 22, 2023
1 parent 1426b3d commit d544f64
Show file tree
Hide file tree
Showing 15 changed files with 331 additions and 166 deletions.
2 changes: 2 additions & 0 deletions server/game/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ serde_json = "1.0.108"
time = { version = "0.3.30", features = ["formatting"] }
tokio = { version = "1.34.0", features = ["full"] }
parking_lot = "0.12.1"
array-init = "2.1.0"
num_enum = "0.7.1"
101 changes: 91 additions & 10 deletions server/game/src/bytebufferext.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use crate::data::types::cocos;
use anyhow::Result;
use anyhow::{anyhow, Result};
use bytebuffer::{ByteBuffer, ByteReader};

type ByteVec = Vec<u8>;

pub trait Encodable {
fn encode(&self, buf: &mut ByteBuffer);
}
Expand Down Expand Up @@ -86,13 +84,16 @@ pub trait ByteBufferExt {
pub trait ByteBufferExtWrite {
fn write_bool(&mut self, val: bool);
// write a byte vector, prefixed with 4 bytes indicating length
fn write_byte_array(&mut self, vec: &ByteVec);
fn write_byte_array(&mut self, vec: &[u8]);

fn write_value<T: Encodable>(&mut self, val: &T);
fn write_optional_value<T: Encodable>(&mut self, val: Option<&T>);

fn write_value_array<T: Encodable, const N: usize>(&mut self, val: &[T; N]);
fn write_value_vec<T: Encodable>(&mut self, val: &[T]);

fn write_enum<E: Into<B>, B: Encodable>(&mut self, val: E);

fn write_color3(&mut self, val: cocos::Color3B);
fn write_color4(&mut self, val: cocos::Color4B);
fn write_point(&mut self, val: cocos::Point);
Expand All @@ -101,13 +102,16 @@ pub trait ByteBufferExtWrite {
pub trait ByteBufferExtRead {
fn read_bool(&mut self) -> Result<bool>;
// read a byte vector, prefixed with 4 bytes indicating length
fn read_byte_array(&mut self) -> Result<ByteVec>;
fn read_byte_array(&mut self) -> Result<Vec<u8>>;

fn read_value<T: Decodable>(&mut self) -> Result<T>;
fn read_optional_value<T: Decodable>(&mut self) -> Result<Option<T>>;

fn read_value_array<T: Decodable, const N: usize>(&mut self) -> Result<[T; N]>;
fn read_value_vec<T: Decodable>(&mut self) -> Result<Vec<T>>;

fn read_enum<E: TryFrom<B>, B: Decodable>(&mut self) -> Result<E>;

fn read_color3(&mut self) -> Result<cocos::Color3B>;
fn read_color4(&mut self) -> Result<cocos::Color4B>;
fn read_point(&mut self) -> Result<cocos::Point>;
Expand All @@ -126,9 +130,9 @@ impl ByteBufferExtWrite for ByteBuffer {
self.write_u8(if val { 1u8 } else { 0u8 });
}

fn write_byte_array(&mut self, vec: &ByteVec) {
self.write_u32(vec.len() as u32);
self.write_bytes(vec);
fn write_byte_array(&mut self, val: &[u8]) {
self.write_u32(val.len() as u32);
self.write_bytes(val);
}

fn write_value<T: Encodable>(&mut self, val: &T) {
Expand All @@ -142,13 +146,21 @@ impl ByteBufferExtWrite for ByteBuffer {
}
}

fn write_value_array<T: Encodable, const N: usize>(&mut self, val: &[T; N]) {
val.iter().for_each(|v| self.write_value(v));
}

fn write_value_vec<T: Encodable>(&mut self, val: &[T]) {
self.write_u32(val.len() as u32);
for elem in val.iter() {
elem.encode(self);
}
}

fn write_enum<E: Into<B>, B: Encodable>(&mut self, val: E) {
self.write_value(&val.into())
}

fn write_color3(&mut self, val: cocos::Color3B) {
self.write_value(&val)
}
Expand All @@ -165,10 +177,10 @@ impl ByteBufferExtWrite for ByteBuffer {
macro_rules! impl_extread {
($decode_fn:ident) => {
fn read_bool(&mut self) -> Result<bool> {
Ok(self.read_u8()? == 1u8)
Ok(self.read_u8()? != 0u8)
}

fn read_byte_array(&mut self) -> Result<ByteVec> {
fn read_byte_array(&mut self) -> Result<Vec<u8>> {
let length = self.read_u32()? as usize;
Ok(self.read_bytes(length)?)
}
Expand All @@ -184,6 +196,10 @@ macro_rules! impl_extread {
})
}

fn read_value_array<T: Decodable, const N: usize>(&mut self) -> Result<[T; N]> {
array_init::try_array_init(|_| self.read_value::<T>())
}

fn read_value_vec<T: Decodable>(&mut self) -> Result<Vec<T>> {
let mut out = Vec::new();
let length = self.read_u32()? as usize;
Expand All @@ -194,6 +210,13 @@ macro_rules! impl_extread {
Ok(out)
}

fn read_enum<E: TryFrom<B>, B: Decodable>(&mut self) -> Result<E> {
let val = self.read_value::<B>()?;
let val: Result<E, _> = val.try_into();

val.map_err(|_| anyhow!("failed to decode enum"))
}

fn read_color3(&mut self) -> Result<cocos::Color3B> {
self.read_value()
}
Expand All @@ -215,3 +238,61 @@ impl ByteBufferExtRead for ByteBuffer {
impl<'a> ByteBufferExtRead for ByteReader<'a> {
impl_extread!(decode_from_reader);
}

/* Implementations for common types */

macro_rules! impl_primitive {
($typ:ty,$read:ident,$write:ident) => {
impl Encodable for $typ {
fn encode(&self, buf: &mut ByteBuffer) {
buf.$write(*self);
}
}

impl Decodable for $typ {
fn decode(buf: &mut ByteBuffer) -> Result<Self>
where
Self: Sized,
{
Ok(buf.$read()?)
}
fn decode_from_reader(buf: &mut ByteReader) -> Result<Self>
where
Self: Sized,
{
Ok(buf.$read()?)
}
}
};
}

impl_primitive!(u8, read_u8, write_u8);
impl_primitive!(u16, read_u16, write_u16);
impl_primitive!(u32, read_u32, write_u32);
impl_primitive!(u64, read_u64, write_u64);
impl_primitive!(i8, read_i8, write_i8);
impl_primitive!(i16, read_i16, write_i16);
impl_primitive!(i32, read_i32, write_i32);
impl_primitive!(i64, read_i64, write_i64);

impl Encodable for Vec<u8> {
fn encode(&self, buf: &mut ByteBuffer) {
buf.write_byte_array(self);
}
}

impl Decodable for Vec<u8> {
fn decode(buf: &mut ByteBuffer) -> Result<Self>
where
Self: Sized,
{
buf.read_byte_array()
}

fn decode_from_reader(buf: &mut ByteReader) -> Result<Self>
where
Self: Sized,
{
buf.read_byte_array()
}
}
12 changes: 0 additions & 12 deletions server/game/src/data/packets/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
pub mod client;
pub mod server;

use std::any::Any;

use crate::bytebufferext::{Decodable, Encodable};

type PacketId = u16;
Expand All @@ -14,7 +12,6 @@ type PacketId = u16;
* packet!(PacketName, id, enc)
*
* followed by packet_encode! and packet_decode! or their _unimpl versions
* the empty_impl! also must be added which is basically Default but less silly i guess?
*/

macro_rules! packet {
Expand All @@ -27,10 +24,6 @@ macro_rules! packet {
fn get_encrypted(&self) -> bool {
$encrypted
}

fn as_any(&self) -> &dyn std::any::Any {
self
}
}

impl crate::data::packets::PacketWithId for $packet_type {
Expand All @@ -51,10 +44,6 @@ macro_rules! packet {
fn get_encrypted(&self) -> bool {
$encrypted
}

fn as_any(&self) -> &dyn std::any::Any {
self
}
}

impl crate::data::packets::PacketWithId for $packet_type {
Expand Down Expand Up @@ -90,7 +79,6 @@ pub(crate) use packet;
pub trait Packet: Encodable + Decodable + Send + Sync {
fn get_packet_id(&self) -> PacketId;
fn get_encrypted(&self) -> bool;
fn as_any(&self) -> &dyn Any;
}

// god i hate this
Expand Down
31 changes: 9 additions & 22 deletions server/game/src/data/types/audio_frame.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,20 @@
use anyhow::bail;

use crate::bytebufferext::{decode_impl, encode_impl, ByteBufferExtRead, ByteBufferExtWrite};

const VOICE_OPUS_FRAMES_IN_AUDIO_FRAME: usize = 20;

type EncodedOpusData = Vec<u8>;
#[derive(Clone, Default)]

#[derive(Clone)]
pub struct EncodedAudioFrame {
pub opus_frames: Vec<EncodedOpusData>,
pub opus_frames: [EncodedOpusData; VOICE_OPUS_FRAMES_IN_AUDIO_FRAME],
}

encode_impl!(EncodedAudioFrame, buf, self, {
buf.write_u16(self.opus_frames.len() as u16);

for frame in self.opus_frames.iter() {
buf.write_byte_array(frame);
}
buf.write_value_array(&self.opus_frames);
});

decode_impl!(EncodedAudioFrame, buf, {
let frames = buf.read_u16()?;
if frames > 64 {
bail!("failed to decode EncodedAudioFrame, way too many frames ({frames})");
}

let mut opus_frames = Vec::with_capacity(frames as usize);

for _ in 0..frames {
let frame = buf.read_byte_array()?;
opus_frames.push(frame);
}

Ok(Self { opus_frames })
Ok(Self {
opus_frames: buf.read_value_array()?,
})
});
21 changes: 12 additions & 9 deletions server/game/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use anyhow::anyhow;
use globed_shared::{GameServerBootData, PROTOCOL_VERSION};
use log::{error, info, LevelFilter};
use logger::Logger;
use server::GameServerConfiguration;
use state::ServerState;

use server::GameServer;
Expand Down Expand Up @@ -83,16 +84,20 @@ async fn main() -> Result<(), Box<dyn Error>> {
.build()
.unwrap();

let state = ServerState::new(client, central_url.clone(), central_pw.clone());
let config = GameServerConfiguration {
http_client: client,
central_url,
central_pw,
};

info!("Retreiving config from the central server..");
let state = ServerState::new();

let state_inner = state.read().await;
info!("Retreiving config from the central server..");

let response = state_inner
let response = config
.http_client
.post(format!("{}{}", state_inner.central_url, "gs/boot"))
.query(&[("pw", state_inner.central_pw.clone())])
.post(format!("{}{}", config.central_url, "gs/boot"))
.query(&[("pw", config.central_pw.clone())])
.send()
.await?
.error_for_status()
Expand All @@ -110,9 +115,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
panic!("aborting due to incompatible protocol versions");
}

drop(state_inner);

let server = Box::leak(Box::new(GameServer::new(host_address, state, boot_data).await));
let server = Box::leak(Box::new(GameServer::new(host_address, state, boot_data, config).await));

server.run().await?;

Expand Down
Loading

0 comments on commit d544f64

Please sign in to comment.