Skip to content

Commit

Permalink
okay
Browse files Browse the repository at this point in the history
  • Loading branch information
dankmeme01 committed Dec 11, 2023
1 parent 2c5b85f commit c7dfac3
Show file tree
Hide file tree
Showing 28 changed files with 267 additions and 268 deletions.
8 changes: 7 additions & 1 deletion server/game/benchmarks/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,13 @@ fn managers(c: &mut Criterion) {
for level_id in 0..100 {
for account_id in 0..10 {
manager.add_to_level(level_id, level_id * 10 + account_id);
manager.set_player_data(level_id * 10 + account_id, &PlayerData {});
manager.set_player_data(
level_id * 10 + account_id,
&PlayerData {
percentage: 0,
attempts: 0,
},
);
}
}

Expand Down
13 changes: 6 additions & 7 deletions server/game/src/data/packets/client/game.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
use crate::data::*;

#[derive(Packet, Decodable)]
#[packet(id = 12000, encrypted = false)]
pub struct RequestPlayerProfilesPacket {
pub requested: i32, // 0 to get all ppl on the level
}

#[derive(Packet, Decodable)]
#[packet(id = 12001, encrypted = false)]
pub struct LevelJoinPacket {
Expand All @@ -16,13 +22,6 @@ pub struct PlayerDataPacket {
pub data: PlayerData,
}

#[derive(Packet, Decodable)]
#[packet(id = 12004, encrypted = false)]
pub struct SyncPlayerMetadataPacket {
pub data: PlayerMetadata,
pub requested: Option<i32>,
}

#[derive(Packet, Decodable)]
#[packet(id = 12010, encrypted = true)]
pub struct VoicePacket {
Expand Down
8 changes: 4 additions & 4 deletions server/game/src/data/packets/server/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ use crate::data::*;
*/

#[derive(Packet, Encodable)]
#[packet(id = 22001, encrypted = false)]
pub struct LevelDataPacket;
#[packet(id = 22000, encrypted = false)]
pub struct PlayerProfilesPacket;

#[derive(Packet, Encodable)]
#[packet(id = 22002, encrypted = false)]
pub struct PlayerMetadataPacket;
#[packet(id = 22001, encrypted = false)]
pub struct LevelDataPacket;

#[derive(Packet, Encodable)]
#[packet(id = 22010, encrypted = true)]
Expand Down
21 changes: 4 additions & 17 deletions server/game/src/data/types/gd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,10 @@ pub enum IconType {
/* PlayerData (data in a level) */

#[derive(Clone, Default, Encodable, KnownSize, Decodable)]
pub struct PlayerData {}
pub struct PlayerData {
pub percentage: u16,
pub attempts: i32,
}

/* AssociatedPlayerData */

Expand All @@ -155,19 +158,3 @@ pub struct AssociatedPlayerData {
pub account_id: i32,
pub data: PlayerData,
}

/* PlayerMetadata (things like your percentage in a level, attempt count) */

#[derive(Copy, Clone, Default, Encodable, KnownSize, Decodable)]
pub struct PlayerMetadata {
percentage: u16,
attempts: i32,
}

/* FullPlayerMetadata */

#[derive(Clone, Default, Encodable, KnownSize)]
pub struct FullPlayerMetadata {
pub account_data: PlayerAccountData,
pub metadata: PlayerMetadata,
}
52 changes: 18 additions & 34 deletions server/game/src/managers/player.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
use nohash_hasher::IntMap;

use crate::data::{
types::{AssociatedPlayerData, PlayerData},
PlayerMetadata,
};

#[derive(Default)]
pub struct PlayerEntry {
pub data: AssociatedPlayerData,
pub meta: PlayerMetadata,
}
use crate::data::types::{AssociatedPlayerData, PlayerData};

#[derive(Default)]
pub struct PlayerManager {
pub players: IntMap<i32, PlayerEntry>, // player id : associated data
pub levels: IntMap<i32, Vec<i32>>, // level id : [player id]
pub players: IntMap<i32, AssociatedPlayerData>, // player id : associated data
pub levels: IntMap<i32, Vec<i32>>, // level id : [player id]
}

impl PlayerManager {
Expand All @@ -23,36 +14,29 @@ impl PlayerManager {
}

pub fn get_player_data(&self, account_id: i32) -> Option<&AssociatedPlayerData> {
self.players.get(&account_id).map(|entry| &entry.data)
}

pub fn get_player_metadata(&self, account_id: i32) -> Option<&PlayerMetadata> {
self.players.get(&account_id).map(|entry| &entry.meta)
self.players.get(&account_id)
}

pub fn create_player(&mut self, account_id: i32) {
let mut entry = PlayerEntry::default();
entry.data.account_id = account_id;

self.players.insert(account_id, entry);
self.players.insert(
account_id,
AssociatedPlayerData {
account_id,
..Default::default()
},
);
}

fn get_or_create_player(&mut self, account_id: i32) -> &mut PlayerEntry {
self.players.entry(account_id).or_insert_with(|| {
let mut entry = PlayerEntry::default();
entry.data.account_id = account_id;
entry
fn get_or_create_player(&mut self, account_id: i32) -> &mut AssociatedPlayerData {
self.players.entry(account_id).or_insert_with(|| AssociatedPlayerData {
account_id,
..Default::default()
})
}

/// set player's data, inserting a new entry if doesn't already exist
pub fn set_player_data(&mut self, account_id: i32, data: &PlayerData) {
self.get_or_create_player(account_id).data.data.clone_from(data);
}

/// set player's metadata, inserting a new entry if it doesn't already exist
pub fn set_player_metadata(&mut self, account_id: i32, data: &PlayerMetadata) {
self.get_or_create_player(account_id).meta.clone_from(data);
self.get_or_create_player(account_id).data.clone_from(data);
}

/// remove the player from the list of players
Expand All @@ -78,7 +62,7 @@ impl PlayerManager {
/// run a function `f` on each player on a level given its ID, with possibility to pass additional data
pub fn for_each_player_on_level<F, A>(&self, level_id: i32, f: F, additional: &mut A) -> usize
where
F: Fn(&PlayerEntry, usize, &mut A) -> bool,
F: Fn(&AssociatedPlayerData, usize, &mut A) -> bool,
{
if let Some(ids) = self.levels.get(&level_id) {
ids.iter()
Expand All @@ -92,7 +76,7 @@ impl PlayerManager {
/// run a function `f` on each player in this `PlayerManager`, with possibility to pass additional data
pub fn for_each_player<F, A>(&self, f: F, additional: &mut A) -> usize
where
F: Fn(&PlayerEntry, usize, &mut A) -> bool,
F: Fn(&AssociatedPlayerData, usize, &mut A) -> bool,
{
self.players
.values()
Expand Down
78 changes: 32 additions & 46 deletions server/game/src/server_thread/handlers/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ impl GameServerThread {
level_id,
|player, count, buf| {
// we do additional length check because player count may have increased since 1st lock
if count < written_players && player.data.account_id != account_id {
buf.write_value(&player.data);
if count < written_players && player.account_id != account_id {
buf.write_value(player);
true
} else {
false
Expand All @@ -100,7 +100,7 @@ impl GameServerThread {
Ok(())
});

gs_handler!(self, handle_sync_player_metadata, SyncPlayerMetadataPacket, packet, {
gs_handler!(self, handle_request_profiles, RequestPlayerProfilesPacket, packet, {
let account_id = gs_needauth!(self);

let level_id = self.level_id.load(Ordering::Relaxed);
Expand All @@ -111,7 +111,6 @@ impl GameServerThread {
let room_id = self.room_id.load(Ordering::Relaxed);

let total_players = self.game_server.state.room_manager.with_any(room_id, |pm| {
pm.set_player_metadata(account_id, &packet.data);
// this unwrap should be safe and > 0 given that self.level_id != 0, but we leave a default just in case
pm.get_player_count_on_level(level_id).unwrap_or(1) - 1
});
Expand All @@ -121,54 +120,41 @@ impl GameServerThread {
return Ok(());
}

let written_players = if packet.requested.is_some() { 1 } else { total_players };
let written_players = if packet.requested != 0 { 1 } else { total_players };

let calc_size = size_of_types!(PacketHeader, u32) + size_of_types!(FullPlayerMetadata) * written_players;
let calc_size = size_of_types!(PacketHeader, u32) + size_of_types!(PlayerAccountData) * written_players;

gs_inline_encode!(self, calc_size, buf, {
buf.write_packet_header::<PlayerMetadataPacket>();
buf.write_packet_header::<PlayerProfilesPacket>();
buf.write_u32(written_players as u32);

let written = self.game_server.state.room_manager.with_any(room_id, |pm| {
// if they requested one specific player, encode just them (if we find them)
if let Some(player_id) = packet.requested {
if let Some(meta) = pm.get_player_metadata(player_id) {
let account_data = self.game_server.get_player_account_data(player_id);
if account_data.is_some() {
let fpm = FullPlayerMetadata {
metadata: *meta,
account_data: account_data.unwrap(),
};

buf.write_value(&fpm);
return 1;
}
}

return 0;
// if they requested one specific player, encode just them (if we find them)
let written = if packet.requested != 0 {
let account_data = self.game_server.get_player_account_data(packet.requested);
if let Some(data) = account_data {
buf.write_value(&data);
1
} else {
0
}

// otherwise, encode everyone on the level
pm.for_each_player_on_level(
level_id,
|player, count, buf| {
let account_data = self.game_server.get_player_account_data(player.data.account_id);
// we do additional length check because player count may have changed since 1st lock
if count < written_players && player.data.account_id != account_id && account_data.is_some() {
let fpm = FullPlayerMetadata {
metadata: player.meta,
account_data: account_data.unwrap(),
};

buf.write_value(&fpm);
true
} else {
false
}
},
&mut buf,
)
});
} else {
self.game_server.state.room_manager.with_any(room_id, |pm| {
// otherwise, encode everyone on the level
pm.for_each_player_on_level(
level_id,
|player, count, buf| {
// we do additional length check because player count may have changed since 1st lock
if count < written_players && player.account_id != account_id {
let account_data = self.game_server.get_player_account_data(player.account_id);
account_data.map(|data| buf.write_value(&data)).is_some()
} else {
false
}
},
&mut buf,
)
})
};

// if the player count has instead decreased, we now lied and the client will fail decoding. re-encode the actual count.
if written != written_players {
Expand Down
2 changes: 1 addition & 1 deletion server/game/src/server_thread/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,10 +431,10 @@ impl GameServerThread {
RequestRoomPlayerListPacket::PACKET_ID => self.handle_request_room_list(&mut data).await,

/* game related */
RequestPlayerProfilesPacket::PACKET_ID => self.handle_request_profiles(&mut data).await,
LevelJoinPacket::PACKET_ID => self.handle_level_join(&mut data).await,
LevelLeavePacket::PACKET_ID => self.handle_level_leave(&mut data).await,
PlayerDataPacket::PACKET_ID => self.handle_player_data(&mut data).await,
SyncPlayerMetadataPacket::PACKET_ID => self.handle_sync_player_metadata(&mut data).await,

VoicePacket::PACKET_ID => self.handle_voice(&mut data).await,
ChatMessagePacket::PACKET_ID => self.handle_chat_message(&mut data).await,
Expand Down
8 changes: 7 additions & 1 deletion server/game/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,13 @@ fn test_player_manager() {
for level_id in 0..100 {
for account_id in 0..100 {
manager.add_to_level(level_id, level_id * 100 + account_id);
manager.set_player_data(level_id * 100 + account_id, &PlayerData {});
manager.set_player_data(
level_id * 100 + account_id,
&PlayerData {
percentage: 0,
attempts: 0,
},
);
}
}

Expand Down
4 changes: 2 additions & 2 deletions server/protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ General

Game related

* 12000 - RequestPlayerProfilesPacket - request account data of another player (or all people on the level)
* 12001 - LevelJoinPacket - join a level
* 12002 - LevelLeavePacket - leave a level
* 12003 - PlayerDataPacket - player data
* 12004^ - SyncPlayerMetadataPacket - request player account data & metadata and sync own
* 12010+ - VoicePacket - voice frame
* 12011?^+ - ChatMessagePacket - chat message

Expand All @@ -67,7 +67,7 @@ General

Game related

* 22000 - PlayerProfilesPacket - list of requested profiles
* 22001 - LevelDataPacket - level data
* 22002 - PlayerMetadataPacket - list of player metadata
* 22010+ - VoiceBroadcastPacket - voice frame from another user
* 22011+ - ChatMessageBroadcastPacket - chat message from another user
Loading

0 comments on commit c7dfac3

Please sign in to comment.