mirror of
https://git.ngram.ca/OpenJam/rc-servers
synced 2026-08-23 23:08:52 +00:00
Minor refactor for fake server players
This commit is contained in:
@@ -28,6 +28,13 @@ impl SpawnPoint {
|
||||
self
|
||||
}
|
||||
|
||||
const fn scale(mut self, scale: f32) -> Self {
|
||||
self.x *= scale;
|
||||
self.y *= scale;
|
||||
self.z *= scale;
|
||||
self
|
||||
}
|
||||
|
||||
fn rotated_from(mut self, x: f32, y: f32, z: f32, rot: num_quaternion::Quaternion<f32>) -> Self {
|
||||
if let Some(unit_rot) = rot.normalize() {
|
||||
let rotated = unit_rot.rotate_vector([self.x, self.y, self.z]);
|
||||
@@ -974,7 +981,7 @@ pub(super) fn default_map() -> std::collections::HashMap<super::combat::GameMap,
|
||||
y: -4.076,
|
||||
z: 435.700,
|
||||
},
|
||||
].into_iter().map(|x| x.offset(283.600 * 0.8, 4.592 * 0.8, -24.100 * 0.8)).collect(),
|
||||
].into_iter().map(|x| x.offset(283.600, 4.592, -24.100).scale(0.8)).collect(),
|
||||
bases: vec![
|
||||
CaptureBase {
|
||||
team: 0,
|
||||
|
||||
@@ -362,7 +362,7 @@ impl UserData {
|
||||
self.perms.administrator | self.perms.developer
|
||||
}
|
||||
|
||||
async fn user_player_data(&self, cpu_counter: &crate::cubes::CpuListParser) -> Result<crate::data::player_data::PlayerData, polariton_server::operations::SimpleOpError> {
|
||||
pub(super) async fn user_player_data(&self, cpu_counter: &crate::cubes::CpuListParser) -> Result<crate::data::player_data::PlayerData, polariton_server::operations::SimpleOpError> {
|
||||
let current_slot = self.db.garage_selected(self.account.id).await.map_err(|e| {
|
||||
log::error!("Failed to retrieve selected vehicle for user_id {} (user_player_data): {}", self.account.id, e);
|
||||
polariton_server::operations::SimpleOpError::with_message(DATABASE_ERR, format!("Could not retrieve selected garage: {}", e))
|
||||
@@ -556,7 +556,7 @@ impl UserData {
|
||||
Ok(players)
|
||||
}
|
||||
|
||||
async fn get_players_in_current_game(&self) -> Result<Vec<(oj_rc_database::schema::multiplayer_game_player::Model, oj_rc_database::schema::user::Model)>, polariton_server::operations::SimpleOpError> {
|
||||
async fn get_players_in_current_game(&self) -> Result<Vec<oj_rc_database::schema::multiplayer_game_player::Model>, polariton_server::operations::SimpleOpError> {
|
||||
let current_game = self.db.game_by_user_id_and_completion(self.account.id, false).await
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to retrieve ongoing game for user {}: {}", self.account.id, e);
|
||||
@@ -567,7 +567,7 @@ impl UserData {
|
||||
})?;
|
||||
if let Some(current_game) = current_game {
|
||||
let guid = current_game.guid;
|
||||
self.db.players_by_game_guid_and_completion_heavy(current_game.guid, false).await
|
||||
self.db.players_by_game_guid_and_completion(current_game.guid, false).await
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to retrieve players for game {} for user {}: {}", guid, self.account.id, e);
|
||||
polariton_server::operations::SimpleOpError::with_message(
|
||||
@@ -580,7 +580,7 @@ impl UserData {
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_teammates_in_current_game(&self) -> Result<Vec<(oj_rc_database::schema::multiplayer_game_player::Model, oj_rc_database::schema::user::Model)>, polariton_server::operations::SimpleOpError> {
|
||||
async fn get_teammates_in_current_game(&self) -> Result<Vec<oj_rc_database::schema::multiplayer_game_player::Model>, polariton_server::operations::SimpleOpError> {
|
||||
let current_game_info = self.db.game_and_player_by_user_id_and_completion(self.account.id, false).await
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to retrieve ongoing game for user {}: {}", self.account.id, e);
|
||||
@@ -591,7 +591,7 @@ impl UserData {
|
||||
})?;
|
||||
if let Some((current_game, current_player)) = current_game_info {
|
||||
let guid = current_game.guid;
|
||||
self.db.players_by_game_guid_and_completion_and_team_heavy(current_game.guid, current_player.team, false).await
|
||||
self.db.players_by_game_guid_and_completion_and_team(current_game.guid, current_player.team, false).await
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to retrieve players for game {} for user {}: {}", guid, self.account.id, e);
|
||||
polariton_server::operations::SimpleOpError::with_message(
|
||||
@@ -1352,7 +1352,7 @@ impl super::ChatUser for UserData {
|
||||
Ok(
|
||||
self.get_teammates_in_current_game().await?
|
||||
.into_iter()
|
||||
.map(|player| player.1.public_id)
|
||||
.map(|player| player.public_id)
|
||||
.collect()
|
||||
)
|
||||
}
|
||||
@@ -1361,197 +1361,8 @@ impl super::ChatUser for UserData {
|
||||
Ok(
|
||||
self.get_players_in_current_game().await?
|
||||
.into_iter()
|
||||
.map(|player| player.1.public_id)
|
||||
.map(|player| player.public_id)
|
||||
.collect()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl super::LobbyUser for UserData {
|
||||
fn user_id(&self) -> i32 {
|
||||
self.account.id
|
||||
}
|
||||
|
||||
async fn player_data(&self, cpu_counter: &crate::cubes::CpuListParser) -> Result<crate::data::player_data::PlayerData, polariton_server::operations::SimpleOpError> {
|
||||
self.user_player_data(cpu_counter).await.map_err(|e| {
|
||||
if let Some(msg) = e.error_msg() {
|
||||
polariton_server::operations::SimpleOpError::with_message(crate::data::error_codes::LobbyReasonCode::from_service_error(e.error_code()) as i16, msg.to_owned())
|
||||
} else {
|
||||
polariton_server::operations::SimpleOpError::with_code(crate::data::error_codes::LobbyReasonCode::from_service_error(e.error_code()) as i16)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
async fn start_game(&self, game: super::GameDescriptor, players: Vec<super::PlayerLobbyDescriptor>) -> Result<(), polariton_server::operations::SimpleOpError> {
|
||||
let now = chrono::Utc::now().timestamp();
|
||||
let guid = crate::persist::user::str_to_i64(&game.guid)
|
||||
.ok_or_else(|| polariton_server::operations::SimpleOpError::with_message(
|
||||
crate::data::error_codes::LobbyReasonCode::UnexpectedError as i16, "Invalid GUID".to_owned()
|
||||
)
|
||||
)?;
|
||||
let variant = if game.is_ranked {
|
||||
oj_rc_database::schema::multiplayer_game::GameType::Ranked
|
||||
} else if game.is_custom {
|
||||
oj_rc_database::schema::multiplayer_game::GameType::Custom
|
||||
} else {
|
||||
oj_rc_database::schema::multiplayer_game::GameType::Standard
|
||||
};
|
||||
|
||||
let game_dbo = oj_rc_database::schema::multiplayer_game::ActiveModel {
|
||||
id: oj_rc_database::sea_orm::ActiveValue::NotSet,
|
||||
creation_time: oj_rc_database::sea_orm::ActiveValue::Set(now),
|
||||
guid: oj_rc_database::sea_orm::ActiveValue::Set(guid),
|
||||
map: oj_rc_database::sea_orm::ActiveValue::Set(game.map),
|
||||
mode: oj_rc_database::sea_orm::ActiveValue::Set(game.mode.to_db()),
|
||||
visibility: oj_rc_database::sea_orm::ActiveValue::Set(game.visibility.to_db()),
|
||||
auto_heal: oj_rc_database::sea_orm::ActiveValue::Set(game.auto_heal),
|
||||
variant: oj_rc_database::sea_orm::ActiveValue::Set(variant),
|
||||
is_complete: oj_rc_database::sea_orm::ActiveValue::Set(false),
|
||||
};
|
||||
let game_dbo = self.db.insert_game(game_dbo).await.map_err(|e| {
|
||||
log::error!("Failed to create game {} through user_id {}: {}", game.guid, self.account.id, e);
|
||||
polariton_server::operations::SimpleOpError::with_message(
|
||||
crate::data::error_codes::LobbyReasonCode::UnexpectedError as i16,
|
||||
format!("Failed to create game {}: {}", game.guid, e),
|
||||
)
|
||||
})?;
|
||||
|
||||
let players: Vec<oj_rc_database::schema::multiplayer_game_player::ActiveModel> = players.into_iter()
|
||||
.enumerate()
|
||||
.map(|(i, player)| {
|
||||
oj_rc_database::schema::multiplayer_game_player::ActiveModel {
|
||||
id: oj_rc_database::sea_orm::ActiveValue::NotSet,
|
||||
user_id: oj_rc_database::sea_orm::ActiveValue::Set(player.user_id),
|
||||
game_id: oj_rc_database::sea_orm::ActiveValue::Set(game_dbo.id),
|
||||
creation_time: oj_rc_database::sea_orm::ActiveValue::Set(now),
|
||||
player_id: oj_rc_database::sea_orm::ActiveValue::Set((i as u8) as _),
|
||||
team: oj_rc_database::sea_orm::ActiveValue::Set(player.team),
|
||||
group: oj_rc_database::sea_orm::ActiveValue::Set(player.group),
|
||||
is_claimed: oj_rc_database::sea_orm::ActiveValue::Set(false),
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
self.db.insert_players(players).await.map_err(|e| {
|
||||
log::error!("Failed to create game players for {} through user_id {}: {}", game.guid, self.account.id, e);
|
||||
polariton_server::operations::SimpleOpError::with_message(
|
||||
crate::data::error_codes::LobbyReasonCode::UnexpectedError as i16,
|
||||
format!("Failed to create game players for {}: {}", game.guid, e),
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl super::MultiplayerUser for UserData {
|
||||
fn user_id(&self) -> i32 {
|
||||
self.account.id
|
||||
}
|
||||
|
||||
fn user_name(&self) -> &'_ str {
|
||||
&self.account.public_id
|
||||
}
|
||||
|
||||
fn display_name(&self) -> &'_ str {
|
||||
&self.account.display_name
|
||||
}
|
||||
|
||||
async fn current_game(&self) -> Result<Option<super::GameDescriptor>, super::MultiplayerError> {
|
||||
Ok(self.db.game_by_user_id_and_completion(self.account.id, false).await
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to retrieve ongoing game for user {}: {}", self.account.id, e);
|
||||
super::MultiplayerError {
|
||||
code: super::MultiplayerErrorCode::CustomString,
|
||||
message: format!("Failed to retrieve ongoing game: {}", e),
|
||||
}
|
||||
})?
|
||||
.map(|game| super::GameDescriptor {
|
||||
guid: crate::persist::user::i64_as_uuid_str(game.guid),
|
||||
map: game.map,
|
||||
mode: crate::data::game_mode::GameMode::from_db(game.mode),
|
||||
visibility: crate::data::game_mode::MapVisibility::from_db(game.visibility),
|
||||
auto_heal: game.auto_heal,
|
||||
is_ranked: matches!(game.variant, oj_rc_database::schema::multiplayer_game::GameType::Ranked),
|
||||
is_custom: matches!(game.variant, oj_rc_database::schema::multiplayer_game::GameType::Custom),
|
||||
is_complete: game.is_complete,
|
||||
}))
|
||||
}
|
||||
|
||||
async fn game_players(&self, guid: &str) -> Result<Vec<super::PlayerDescriptor>, super::MultiplayerError> {
|
||||
if let Some(guid) = crate::persist::user::str_to_i64(guid) {
|
||||
let players = self.db.players_by_game_guid_and_completion_heavy(guid, false).await
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to retrieve players for game {} for user {}: {}", guid, self.account.id, e);
|
||||
super::MultiplayerError {
|
||||
code: super::MultiplayerErrorCode::CustomString,
|
||||
message: format!("Failed to retrieve players for game {}: {}", guid, e),
|
||||
}
|
||||
})?;
|
||||
Ok(players.into_iter()
|
||||
.map(|(player, user)| super::PlayerDescriptor {
|
||||
user_id: player.user_id,
|
||||
player_id: player.player_id as u8,
|
||||
team: player.team,
|
||||
group: player.group,
|
||||
is_rewards_claimed: player.is_claimed,
|
||||
display_name: user.display_name,
|
||||
public_id: user.public_id,
|
||||
})
|
||||
.collect())
|
||||
} else {
|
||||
Err(super::MultiplayerError {
|
||||
code: super::MultiplayerErrorCode::IncorrectGameGuid,
|
||||
message: format!("Failed to parse game GUID {}", guid),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async fn complete_game(&self, guid: &str) -> Result<(), super::MultiplayerError> {
|
||||
if let Some(guid) = crate::persist::user::str_to_i64(guid) {
|
||||
self.db.update_complete_game_by_game_guid(guid).await
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to complete ongoing game with user {}: {}", self.account.id, e);
|
||||
super::MultiplayerError {
|
||||
code: super::MultiplayerErrorCode::CustomString,
|
||||
message: format!("Failed to complete ongoing game: {}", e),
|
||||
}
|
||||
})
|
||||
} else {
|
||||
Err(super::MultiplayerError {
|
||||
code: super::MultiplayerErrorCode::IncorrectGameGuid,
|
||||
message: format!("Failed to parse game GUID {}", guid),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async fn game_info(&self, guid: &str) -> Result<Option<super::GameDescriptor>, super::MultiplayerError> {
|
||||
if let Some(guid) = crate::persist::user::str_to_i64(guid) {
|
||||
let game_opt = self.db.game_by_guid(guid.to_owned()).await
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to retrieve game {} with user {}: {}", guid, self.account.id, e);
|
||||
super::MultiplayerError {
|
||||
code: super::MultiplayerErrorCode::CustomString,
|
||||
message: format!("Failed to retrieve game {}: {}", guid, e),
|
||||
}
|
||||
})?;
|
||||
Ok(game_opt.map(|game| super::GameDescriptor {
|
||||
guid: crate::persist::user::i64_as_uuid_str(game.guid),
|
||||
map: game.map,
|
||||
mode: crate::data::game_mode::GameMode::from_db(game.mode),
|
||||
visibility: crate::data::game_mode::MapVisibility::from_db(game.visibility),
|
||||
auto_heal: game.auto_heal,
|
||||
is_ranked: matches!(game.variant, oj_rc_database::schema::multiplayer_game::GameType::Ranked),
|
||||
is_custom: matches!(game.variant, oj_rc_database::schema::multiplayer_game::GameType::Custom),
|
||||
is_complete: game.is_complete,
|
||||
}))
|
||||
} else {
|
||||
Err(super::MultiplayerError {
|
||||
code: super::MultiplayerErrorCode::IncorrectGameGuid,
|
||||
message: format!("Failed to parse game GUID {}", guid),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
102
rc_core/src/persist/user/lobby.rs
Normal file
102
rc_core/src/persist/user/lobby.rs
Normal file
@@ -0,0 +1,102 @@
|
||||
use super::account_json::UserData;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl super::LobbyUser for UserData {
|
||||
fn user_id(&self) -> i32 {
|
||||
self.account.id
|
||||
}
|
||||
|
||||
async fn player_data(&self, cpu_counter: &crate::cubes::CpuListParser) -> Result<crate::data::player_data::PlayerData, polariton_server::operations::SimpleOpError> {
|
||||
self.user_player_data(cpu_counter).await.map_err(|e| {
|
||||
if let Some(msg) = e.error_msg() {
|
||||
polariton_server::operations::SimpleOpError::with_message(crate::data::error_codes::LobbyReasonCode::from_service_error(e.error_code()) as i16, msg.to_owned())
|
||||
} else {
|
||||
polariton_server::operations::SimpleOpError::with_code(crate::data::error_codes::LobbyReasonCode::from_service_error(e.error_code()) as i16)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
async fn start_game(&self, game: super::GameDescriptor, players: Vec<super::PlayerLobbyDescriptor>) -> Result<super::FakePlayers, polariton_server::operations::SimpleOpError> {
|
||||
let now = chrono::Utc::now().timestamp();
|
||||
let guid = crate::persist::user::str_to_i64(&game.guid)
|
||||
.ok_or_else(|| polariton_server::operations::SimpleOpError::with_message(
|
||||
crate::data::error_codes::LobbyReasonCode::UnexpectedError as i16, "Invalid GUID".to_owned()
|
||||
)
|
||||
)?;
|
||||
let variant = if game.is_ranked {
|
||||
oj_rc_database::schema::multiplayer_game::GameType::Ranked
|
||||
} else if game.is_custom {
|
||||
oj_rc_database::schema::multiplayer_game::GameType::Custom
|
||||
} else {
|
||||
oj_rc_database::schema::multiplayer_game::GameType::Standard
|
||||
};
|
||||
|
||||
let fake_players = self.generate_fake_players_data(guid).await;
|
||||
|
||||
let game_dbo = oj_rc_database::schema::multiplayer_game::ActiveModel {
|
||||
id: oj_rc_database::sea_orm::ActiveValue::NotSet,
|
||||
creation_time: oj_rc_database::sea_orm::ActiveValue::Set(now),
|
||||
guid: oj_rc_database::sea_orm::ActiveValue::Set(guid),
|
||||
map: oj_rc_database::sea_orm::ActiveValue::Set(game.map),
|
||||
mode: oj_rc_database::sea_orm::ActiveValue::Set(game.mode.to_db()),
|
||||
visibility: oj_rc_database::sea_orm::ActiveValue::Set(game.visibility.to_db()),
|
||||
auto_heal: oj_rc_database::sea_orm::ActiveValue::Set(game.auto_heal),
|
||||
variant: oj_rc_database::sea_orm::ActiveValue::Set(variant),
|
||||
is_complete: oj_rc_database::sea_orm::ActiveValue::Set(false),
|
||||
};
|
||||
let game_dbo = self.db.insert_game(game_dbo).await.map_err(|e| {
|
||||
log::error!("Failed to create game {} through user_id {}: {}", game.guid, self.account.id, e);
|
||||
polariton_server::operations::SimpleOpError::with_message(
|
||||
crate::data::error_codes::LobbyReasonCode::UnexpectedError as i16,
|
||||
format!("Failed to create game {}: {}", game.guid, e),
|
||||
)
|
||||
})?;
|
||||
|
||||
let players_len = players.len();
|
||||
|
||||
let players: Vec<oj_rc_database::schema::multiplayer_game_player::ActiveModel> = players.into_iter()
|
||||
.enumerate()
|
||||
.map(|(i, player)| {
|
||||
oj_rc_database::schema::multiplayer_game_player::ActiveModel {
|
||||
id: oj_rc_database::sea_orm::ActiveValue::NotSet,
|
||||
user_id: oj_rc_database::sea_orm::ActiveValue::Set(Some(player.user_id)),
|
||||
game_id: oj_rc_database::sea_orm::ActiveValue::Set(game_dbo.id),
|
||||
creation_time: oj_rc_database::sea_orm::ActiveValue::Set(now),
|
||||
player_id: oj_rc_database::sea_orm::ActiveValue::Set((i as u8) as _),
|
||||
team: oj_rc_database::sea_orm::ActiveValue::Set(player.team),
|
||||
group: oj_rc_database::sea_orm::ActiveValue::Set(player.group),
|
||||
is_claimed: oj_rc_database::sea_orm::ActiveValue::Set(false),
|
||||
public_id: oj_rc_database::sea_orm::ActiveValue::Set(player.public_id),
|
||||
display_name: oj_rc_database::sea_orm::ActiveValue::Set(player.display_name),
|
||||
}
|
||||
})
|
||||
.chain(fake_players.iter()
|
||||
.enumerate()
|
||||
.map(|(i, fake)| {
|
||||
oj_rc_database::schema::multiplayer_game_player::ActiveModel {
|
||||
id: oj_rc_database::sea_orm::ActiveValue::NotSet,
|
||||
user_id: oj_rc_database::sea_orm::ActiveValue::Set(None),
|
||||
game_id: oj_rc_database::sea_orm::ActiveValue::Set(game_dbo.id),
|
||||
creation_time: oj_rc_database::sea_orm::ActiveValue::Set(now),
|
||||
player_id: oj_rc_database::sea_orm::ActiveValue::Set(((i + players_len) as u8) as _),
|
||||
team: oj_rc_database::sea_orm::ActiveValue::Set(fake.team),
|
||||
group: oj_rc_database::sea_orm::ActiveValue::Set(None),
|
||||
is_claimed: oj_rc_database::sea_orm::ActiveValue::Set(true),
|
||||
public_id: oj_rc_database::sea_orm::ActiveValue::Set(fake.name.clone()),
|
||||
display_name: oj_rc_database::sea_orm::ActiveValue::Set(fake.display_name.clone()),
|
||||
}
|
||||
})
|
||||
)
|
||||
.collect();
|
||||
self.db.insert_players(players).await.map_err(|e| {
|
||||
log::error!("Failed to create game players for {} through user_id {}: {}", game.guid, self.account.id, e);
|
||||
polariton_server::operations::SimpleOpError::with_message(
|
||||
crate::data::error_codes::LobbyReasonCode::UnexpectedError as i16,
|
||||
format!("Failed to create game players for {}: {}", game.guid, e),
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok(super::FakePlayers { players: fake_players })
|
||||
}
|
||||
}
|
||||
@@ -11,11 +11,14 @@ mod inventory;
|
||||
pub use inventory::UnlockedParts;
|
||||
|
||||
mod traits;
|
||||
pub use traits::{UserProvider, User, UserToken, UserSlots, UserSlotData, VehicleData, UserInfo, UserLoginInfo, ExtraUserInfo, UserAuthenticator, NewSlotData, UserId, RegistrationInfo, VehicleUploadData, ChatUser, AvatarInfo, GetAvatarInfo, ControlData, ControlType, CustomisationData, GetCustomisationData, SetSanction, SanctionType, LobbyUser, GameDescriptor, PlayerLobbyDescriptor, MultiplayerUser, MultiplayerError, MultiplayerErrorCode, PlayerDescriptor, GameEventSetter, CurrentGameEvent, AuthError, IntercomUser};
|
||||
pub use traits::{UserProvider, User, UserToken, UserSlots, UserSlotData, VehicleData, UserInfo, UserLoginInfo, ExtraUserInfo, UserAuthenticator, NewSlotData, UserId, RegistrationInfo, VehicleUploadData, ChatUser, AvatarInfo, GetAvatarInfo, ControlData, ControlType, CustomisationData, GetCustomisationData, SetSanction, SanctionType, LobbyUser, GameDescriptor, PlayerLobbyDescriptor, MultiplayerUser, MultiplayerError, MultiplayerErrorCode, PlayerDescriptor, GameEventSetter, CurrentGameEvent, AuthError, IntercomUser, FakePlayers};
|
||||
|
||||
mod intercom;
|
||||
pub use intercom::generate_token as generate_intercom_token;
|
||||
|
||||
mod multiplayer;
|
||||
mod lobby;
|
||||
|
||||
pub const TOKEN_SECRET_FILENAME: &str = "token_secret.key";
|
||||
|
||||
pub const USERS_DIR: &str = "accounts";
|
||||
|
||||
140
rc_core/src/persist/user/multiplayer.rs
Normal file
140
rc_core/src/persist/user/multiplayer.rs
Normal file
@@ -0,0 +1,140 @@
|
||||
use super::account_json::UserData;
|
||||
|
||||
impl UserData {
|
||||
pub(super) async fn generate_fake_players_data(&self, _guid: i64) -> Vec<crate::data::player_data::PlayerData> {
|
||||
vec![
|
||||
crate::data::player_data::PlayerData {
|
||||
name: "FakeUser".to_owned(),
|
||||
display_name: "Server".to_owned(),
|
||||
mastery: 1,
|
||||
tier: 1,
|
||||
robot_name: "Very bad but very good".to_owned(),
|
||||
robot_map: crate::persist::VALID_ROBOT.into(),
|
||||
group: None,
|
||||
team: 2,
|
||||
has_premium: true,
|
||||
robot_uuid: "1234_1234".to_owned(),
|
||||
cpu: 42,
|
||||
avatar_id: Some(0),
|
||||
weapon_order: vec![0,0,0],
|
||||
colour_map: crate::persist::VALID_COLOUR.into(),
|
||||
is_ai: false,
|
||||
spawn_effect: "Spawn".into(),
|
||||
death_effect: "Explosion".into(),
|
||||
player_rank: 1,
|
||||
weapon_rank: Default::default(),
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl super::MultiplayerUser for UserData {
|
||||
fn user_id(&self) -> i32 {
|
||||
self.account.id
|
||||
}
|
||||
|
||||
fn user_name(&self) -> &'_ str {
|
||||
&self.account.public_id
|
||||
}
|
||||
|
||||
fn display_name(&self) -> &'_ str {
|
||||
&self.account.display_name
|
||||
}
|
||||
|
||||
async fn current_game(&self) -> Result<Option<super::GameDescriptor>, super::MultiplayerError> {
|
||||
Ok(self.db.game_by_user_id_and_completion(self.account.id, false).await
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to retrieve ongoing game for user {}: {}", self.account.id, e);
|
||||
super::MultiplayerError {
|
||||
code: super::MultiplayerErrorCode::CustomString,
|
||||
message: format!("Failed to retrieve ongoing game: {}", e),
|
||||
}
|
||||
})?
|
||||
.map(|game| super::GameDescriptor {
|
||||
guid: crate::persist::user::i64_as_uuid_str(game.guid),
|
||||
map: game.map,
|
||||
mode: crate::data::game_mode::GameMode::from_db(game.mode),
|
||||
visibility: crate::data::game_mode::MapVisibility::from_db(game.visibility),
|
||||
auto_heal: game.auto_heal,
|
||||
is_ranked: matches!(game.variant, oj_rc_database::schema::multiplayer_game::GameType::Ranked),
|
||||
is_custom: matches!(game.variant, oj_rc_database::schema::multiplayer_game::GameType::Custom),
|
||||
is_complete: game.is_complete,
|
||||
}))
|
||||
}
|
||||
|
||||
async fn game_players(&self, guid: &str) -> Result<Vec<super::PlayerDescriptor>, super::MultiplayerError> {
|
||||
if let Some(guid) = crate::persist::user::str_to_i64(guid) {
|
||||
let players = self.db.players_by_game_guid_and_completion(guid, false).await
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to retrieve players for game {} for user {}: {}", guid, self.account.id, e);
|
||||
super::MultiplayerError {
|
||||
code: super::MultiplayerErrorCode::CustomString,
|
||||
message: format!("Failed to retrieve players for game {}: {}", guid, e),
|
||||
}
|
||||
})?;
|
||||
Ok(players.into_iter()
|
||||
.map(|player| super::PlayerDescriptor {
|
||||
user_id: player.user_id,
|
||||
player_id: player.player_id as u8,
|
||||
team: player.team,
|
||||
group: player.group,
|
||||
is_rewards_claimed: player.is_claimed,
|
||||
display_name: player.display_name,
|
||||
public_id: player.public_id,
|
||||
})
|
||||
.collect())
|
||||
} else {
|
||||
Err(super::MultiplayerError {
|
||||
code: super::MultiplayerErrorCode::IncorrectGameGuid,
|
||||
message: format!("Failed to parse game GUID {}", guid),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async fn complete_game(&self, guid: &str) -> Result<(), super::MultiplayerError> {
|
||||
if let Some(guid) = crate::persist::user::str_to_i64(guid) {
|
||||
self.db.update_complete_game_by_game_guid(guid).await
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to complete ongoing game with user {}: {}", self.account.id, e);
|
||||
super::MultiplayerError {
|
||||
code: super::MultiplayerErrorCode::CustomString,
|
||||
message: format!("Failed to complete ongoing game: {}", e),
|
||||
}
|
||||
})
|
||||
} else {
|
||||
Err(super::MultiplayerError {
|
||||
code: super::MultiplayerErrorCode::IncorrectGameGuid,
|
||||
message: format!("Failed to parse game GUID {}", guid),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async fn game_info(&self, guid: &str) -> Result<Option<super::GameDescriptor>, super::MultiplayerError> {
|
||||
if let Some(guid) = crate::persist::user::str_to_i64(guid) {
|
||||
let game_opt = self.db.game_by_guid(guid.to_owned()).await
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to retrieve game {} with user {}: {}", guid, self.account.id, e);
|
||||
super::MultiplayerError {
|
||||
code: super::MultiplayerErrorCode::CustomString,
|
||||
message: format!("Failed to retrieve game {}: {}", guid, e),
|
||||
}
|
||||
})?;
|
||||
Ok(game_opt.map(|game| super::GameDescriptor {
|
||||
guid: crate::persist::user::i64_as_uuid_str(game.guid),
|
||||
map: game.map,
|
||||
mode: crate::data::game_mode::GameMode::from_db(game.mode),
|
||||
visibility: crate::data::game_mode::MapVisibility::from_db(game.visibility),
|
||||
auto_heal: game.auto_heal,
|
||||
is_ranked: matches!(game.variant, oj_rc_database::schema::multiplayer_game::GameType::Ranked),
|
||||
is_custom: matches!(game.variant, oj_rc_database::schema::multiplayer_game::GameType::Custom),
|
||||
is_complete: game.is_complete,
|
||||
}))
|
||||
} else {
|
||||
Err(super::MultiplayerError {
|
||||
code: super::MultiplayerErrorCode::IncorrectGameGuid,
|
||||
message: format!("Failed to parse game GUID {}", guid),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -249,7 +249,11 @@ impl SanctionType {
|
||||
pub trait LobbyUser {
|
||||
fn user_id(&self) -> i32;
|
||||
async fn player_data(&self, cpu_counter: &crate::cubes::CpuListParser) -> Result<crate::data::player_data::PlayerData, polariton_server::operations::SimpleOpError>;
|
||||
async fn start_game(&self, game: GameDescriptor, players: Vec<PlayerLobbyDescriptor>) -> Result<(), polariton_server::operations::SimpleOpError>;
|
||||
async fn start_game(&self, game: GameDescriptor, players: Vec<PlayerLobbyDescriptor>) -> Result<FakePlayers, polariton_server::operations::SimpleOpError>;
|
||||
}
|
||||
|
||||
pub struct FakePlayers {
|
||||
pub players: Vec<crate::data::player_data::PlayerData>
|
||||
}
|
||||
|
||||
pub struct CurrentGameEvent {
|
||||
@@ -275,12 +279,14 @@ pub struct GameDescriptor {
|
||||
pub struct PlayerLobbyDescriptor {
|
||||
pub user_id: i32,
|
||||
pub team: i32,
|
||||
pub public_id: String,
|
||||
pub display_name: String,
|
||||
pub group: Option<i32>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PlayerDescriptor {
|
||||
pub user_id: i32,
|
||||
pub user_id: Option<i32>,
|
||||
pub player_id: u8,
|
||||
pub team: i32,
|
||||
pub group: Option<i32>,
|
||||
|
||||
Reference in New Issue
Block a user