mirror of
https://git.ngram.ca/OpenJam/rc-servers
synced 2026-08-23 23:08:52 +00:00
Fix dominating message, fix fake player loading, mess around with reactor crystals
This commit is contained in:
@@ -42,33 +42,41 @@ impl CubeLocationsParser {
|
||||
}
|
||||
}
|
||||
|
||||
fn locations_sorted_by_distance_from_point(cubes: &[super::parser::Cube], point: (u8, u8, u8), locations_of_id: u32) -> Vec<CubeLocationInfo> {
|
||||
let target_x = point.0 as f32;
|
||||
let target_y = point.1 as f32;
|
||||
let target_z = point.2 as f32;
|
||||
let mut relevant_cubes: Vec<(f32, CubeLocationInfo)> = cubes.into_iter()
|
||||
.filter(|x| x.id == locations_of_id)
|
||||
.map(|cube| {
|
||||
let distance = (
|
||||
(cube.x as f32 - target_x).powi(2)
|
||||
+ (cube.y as f32 - target_y).powi(2)
|
||||
+ (cube.z as f32 - target_z).powi(2)
|
||||
).sqrt();
|
||||
(distance, CubeLocationInfo {
|
||||
x: cube.x,
|
||||
y: cube.y,
|
||||
z: cube.z,
|
||||
extras: cube.orientation,
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
relevant_cubes.sort_by_key(|(distance, _)| (distance * 1_000_000.0) as i64);
|
||||
relevant_cubes.into_iter()
|
||||
.map(|(_, cube)| cube)
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn locations_of_by_distance_to_first(&self, r: &mut dyn std::io::Read, locations_of_id: u32, distance_to_id: u32) -> Vec<CubeLocationInfo> {
|
||||
match super::parser::Cube::parse_list(r) {
|
||||
Ok(cubes) => {
|
||||
if let Some(target) = cubes.iter().find(|x| x.id == distance_to_id) {
|
||||
let target_x = target.x as f32;
|
||||
let target_y = target.y as f32;
|
||||
let target_z = target.z as f32;
|
||||
let mut relevant_cubes: Vec<(f32, CubeLocationInfo)> = cubes.into_iter()
|
||||
.filter(|x| x.id == locations_of_id)
|
||||
.map(|cube| {
|
||||
let distance = (
|
||||
(cube.x as f32 - target_x).powi(2)
|
||||
+ (cube.y as f32 - target_y).powi(2)
|
||||
+ (cube.z as f32 - target_z).powi(2)
|
||||
).sqrt();
|
||||
(distance, CubeLocationInfo {
|
||||
x: cube.x,
|
||||
y: cube.y,
|
||||
z: cube.z,
|
||||
extras: cube.orientation,
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
relevant_cubes.sort_by_key(|(distance, _)| (distance * 1_000_000.0) as i64);
|
||||
relevant_cubes.into_iter()
|
||||
.map(|(_, cube)| cube)
|
||||
.collect()
|
||||
Self::locations_sorted_by_distance_from_point(
|
||||
&cubes,
|
||||
(target.x, target.y, target.z),
|
||||
locations_of_id,
|
||||
)
|
||||
} else {
|
||||
log::warn!("No cube with id {} to calculate distance", distance_to_id);
|
||||
cubes.into_iter()
|
||||
@@ -89,4 +97,20 @@ impl CubeLocationsParser {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn locations_of_by_distance_from(&self, r: &mut dyn std::io::Read, locations_of_id: u32, from: (u8, u8, u8)) -> Vec<CubeLocationInfo> {
|
||||
match super::parser::Cube::parse_list(r) {
|
||||
Ok(cubes) => {
|
||||
Self::locations_sorted_by_distance_from_point(
|
||||
&cubes,
|
||||
from,
|
||||
locations_of_id,
|
||||
)
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Failed to parse cube data to find cube locations: {}", e);
|
||||
Vec::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,7 +336,7 @@ fn default_game_modes() -> GameModes {
|
||||
respawn_heal_duration: 10.0,
|
||||
respawn_full_heal_duration: 0.5,
|
||||
kill_limit: 0,
|
||||
game_time_m: 2,
|
||||
game_time_m: 20,
|
||||
},
|
||||
elimination: GameMode {
|
||||
respawn_heal_duration: 10.0,
|
||||
@@ -622,6 +622,7 @@ fn default_multiplayer() -> super::MultiplayerConfig {
|
||||
autostart_after_s: 180,
|
||||
network: super::multiplayer::default_net_conf(),
|
||||
fakes: super::multiplayer::default_fake_users(),
|
||||
filler: super::multiplayer::default_filler_users(),
|
||||
battle_arena: super::multiplayer::default_ba_conf(),
|
||||
pit_config: super::multiplayer::default_pit_conf(),
|
||||
team_death_match: super::multiplayer::default_tdm_conf(),
|
||||
|
||||
@@ -488,6 +488,14 @@ impl <C: Clone + Send> super::ConfigProvider<C> for CubeConfig {
|
||||
}).collect()
|
||||
}
|
||||
|
||||
fn filler_players(&self) -> Vec<super::FakePlayer> {
|
||||
self.battle.multiplayer.filler.iter().map(|player| super::FakePlayer {
|
||||
team: player.team,
|
||||
vehicle: player.vehicle.into_conf(),
|
||||
implementation: player.implementation.clone().to_config(),
|
||||
}).collect()
|
||||
}
|
||||
|
||||
fn energy(&self) -> super::EnergyConfig {
|
||||
super::EnergyConfig {
|
||||
refill_rate: self.battle.energy.refill_rate_per_s,
|
||||
|
||||
@@ -34,6 +34,7 @@ pub trait ConfigProvider<C: Clone> {
|
||||
fn maps(&self) -> std::collections::HashMap<GameMap, MapConfig>;
|
||||
fn url_links(&self) -> LinksConfig;
|
||||
fn fake_players(&self) -> Vec<FakePlayer>;
|
||||
fn filler_players(&self) -> Vec<FakePlayer>;
|
||||
fn energy(&self) -> EnergyConfig;
|
||||
fn ba_settings(&self) -> BattleArenaResolver;
|
||||
fn pit_settings(&self) -> PitSettings;
|
||||
|
||||
@@ -9,6 +9,8 @@ pub struct MultiplayerConfig {
|
||||
pub network: NetworkConf,
|
||||
#[serde(default = "default_fake_users")]
|
||||
pub fakes: Vec<FakePlayerConf>,
|
||||
#[serde(default = "default_filler_users")]
|
||||
pub filler: Vec<FakePlayerConf>,
|
||||
#[serde(default = "default_ba_conf")]
|
||||
pub battle_arena: BattleArenaConfig,
|
||||
#[serde(default = "default_pit_conf")]
|
||||
@@ -166,6 +168,10 @@ pub(super) fn default_fake_users() -> Vec<FakePlayerConf> {
|
||||
]
|
||||
}
|
||||
|
||||
pub(super) fn default_filler_users() -> Vec<FakePlayerConf> {
|
||||
default_fake_users()
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(tag = "impl")]
|
||||
pub enum ClientEmulation {
|
||||
@@ -242,7 +248,7 @@ fn default_ba_base() -> super::garage::PrefabVehicle {
|
||||
}
|
||||
|
||||
fn default_crystal_health() -> u32 {
|
||||
1_000
|
||||
10_000
|
||||
}
|
||||
|
||||
fn default_respawn_time() -> u64 {
|
||||
|
||||
@@ -8,6 +8,7 @@ pub struct AccountProvider {
|
||||
cubes: std::sync::Arc<Vec<u32>>,
|
||||
garage_upgrades: std::sync::Arc<crate::persist::config::GarageUpgrades>,
|
||||
fake_players: std::sync::Arc<Vec<crate::persist::config::FakePlayer>>,
|
||||
filler_players: std::sync::Arc<Vec<crate::persist::config::FakePlayer>>,
|
||||
auto_signups: bool,
|
||||
cdn: std::sync::Arc<String>,
|
||||
auth: std::sync::Arc<String>,
|
||||
@@ -30,6 +31,7 @@ impl AccountProvider {
|
||||
cubes: std::sync::Arc::new(<crate::persist::config::ConfigImpl as ConfigProvider<()>>::ids(conf)),
|
||||
garage_upgrades: std::sync::Arc::new(<crate::persist::config::ConfigImpl as ConfigProvider<()>>::garage_upgrades(conf)),
|
||||
fake_players: std::sync::Arc::new(<crate::persist::config::ConfigImpl as ConfigProvider<()>>::fake_players(conf)),
|
||||
filler_players: std::sync::Arc::new(<crate::persist::config::ConfigImpl as ConfigProvider<()>>::filler_players(conf)),
|
||||
auto_signups: server_settings.auto_signup,
|
||||
cdn: std::sync::Arc::new(server_settings.cdn_url),
|
||||
auth: std::sync::Arc::new(server_settings.auth_url),
|
||||
@@ -113,6 +115,7 @@ impl <C: Clone + Send> super::UserProvider<C> for AccountProvider {
|
||||
cubes: self.cubes.clone(),
|
||||
garage_upgrades: self.garage_upgrades.clone(),
|
||||
fake_players: self.fake_players.clone(),
|
||||
filler_players: self.filler_players.clone(),
|
||||
cdn: self.cdn.clone(),
|
||||
auth: self.auth.clone(),
|
||||
intercom: self.intercom.clone(),
|
||||
@@ -151,6 +154,7 @@ impl <C: Clone + Send> super::UserProvider<C> for AccountProvider {
|
||||
cubes: self.cubes.clone(),
|
||||
garage_upgrades: self.garage_upgrades.clone(),
|
||||
fake_players: self.fake_players.clone(),
|
||||
filler_players: self.filler_players.clone(),
|
||||
cdn: self.cdn.clone(),
|
||||
auth: self.auth.clone(),
|
||||
intercom: self.intercom.clone(),
|
||||
@@ -316,6 +320,7 @@ pub(super) struct UserData {
|
||||
pub(super) cubes: std::sync::Arc<Vec<u32>>,
|
||||
pub(super) garage_upgrades: std::sync::Arc<crate::persist::config::GarageUpgrades>,
|
||||
pub(super) fake_players: std::sync::Arc<Vec<crate::persist::config::FakePlayer>>,
|
||||
pub(super) filler_players: std::sync::Arc<Vec<crate::persist::config::FakePlayer>>,
|
||||
pub(super) cdn: std::sync::Arc<String>,
|
||||
pub(super) auth: std::sync::Arc<String>,
|
||||
pub(super) intercom: std::sync::Arc<String>,
|
||||
|
||||
@@ -58,6 +58,7 @@ impl super::LobbyUser for UserData {
|
||||
cpu_counter: &crate::cubes::CpuListParser,
|
||||
weapon_lister: &crate::cubes::WeaponListParser,
|
||||
chooser: &TeamChooser,
|
||||
missing_players: usize,
|
||||
) -> Result<super::FakePlayers, polariton_server::operations::SimpleOpError> {
|
||||
let now = chrono::Utc::now().timestamp();
|
||||
let guid = crate::persist::user::str_to_i64(&game.guid)
|
||||
@@ -73,7 +74,8 @@ impl super::LobbyUser for UserData {
|
||||
oj_rc_database::schema::multiplayer_game::GameType::Standard
|
||||
};
|
||||
|
||||
let fake_players = self.generate_fake_players_data(guid, &players, factory, cpu_counter, weapon_lister, chooser).await?;
|
||||
let forced_fake_players = self.generate_forced_fake_players_data(guid, &players, factory, cpu_counter, weapon_lister, chooser).await?;
|
||||
let filler_players = self.generate_filler_players_data(guid, &players, factory, cpu_counter, weapon_lister, chooser, missing_players).await?;
|
||||
|
||||
let game_dbo = oj_rc_database::schema::multiplayer_game::ActiveModel {
|
||||
id: oj_rc_database::sea_orm::ActiveValue::NotSet,
|
||||
@@ -95,6 +97,7 @@ impl super::LobbyUser for UserData {
|
||||
})?;
|
||||
|
||||
let players_len = players.len();
|
||||
let forced_fake_players_len = forced_fake_players.len();
|
||||
|
||||
let players: Vec<oj_rc_database::schema::multiplayer_game_player::ActiveModel> = players.into_iter()
|
||||
.enumerate()
|
||||
@@ -113,7 +116,7 @@ impl super::LobbyUser for UserData {
|
||||
variant: oj_rc_database::sea_orm::ActiveValue::Set(oj_rc_database::schema::multiplayer_game_player::ClientType::Client),
|
||||
}
|
||||
})
|
||||
.chain(fake_players.iter()
|
||||
.chain(forced_fake_players.iter()
|
||||
.enumerate()
|
||||
.map(|(i, (fake, variant))| {
|
||||
oj_rc_database::schema::multiplayer_game_player::ActiveModel {
|
||||
@@ -131,6 +134,24 @@ impl super::LobbyUser for UserData {
|
||||
}
|
||||
})
|
||||
)
|
||||
.chain(filler_players.iter()
|
||||
.enumerate()
|
||||
.map(|(i, (fake, variant))| {
|
||||
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), // if ClientAI, they will be assigned to a user during game loading
|
||||
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 + forced_fake_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()),
|
||||
variant: oj_rc_database::sea_orm::ActiveValue::Set(fake_impl_to_db(variant)),
|
||||
}
|
||||
})
|
||||
)
|
||||
.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);
|
||||
@@ -140,6 +161,8 @@ impl super::LobbyUser for UserData {
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok(super::FakePlayers { players: fake_players })
|
||||
Ok(super::FakePlayers {
|
||||
players: forced_fake_players.into_iter().chain(filler_players).collect(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,10 +17,11 @@ impl UserData {
|
||||
cpu_counter: &crate::cubes::CpuListParser,
|
||||
weapon_lister: &crate::cubes::WeaponListParser,
|
||||
chooser: &super::TeamChooser,
|
||||
fake_players: &[crate::persist::config::FakePlayer],
|
||||
) -> Result<Vec<(crate::data::player_data::PlayerData, crate::persist::config::ClientEmulator)>, polariton_server::operations::SimpleOpError> {
|
||||
let mut fakes = Vec::with_capacity(self.fake_players.len());
|
||||
let mut fakes = Vec::with_capacity(fake_players.len());
|
||||
let mut fake_i = real_players.len();
|
||||
for fake in self.fake_players.iter() {
|
||||
for fake in fake_players.iter() {
|
||||
let vehicle = self.resolve_vehicle(&fake.vehicle, factory, weapon_lister, cpu_counter).await?;
|
||||
let out = (
|
||||
crate::data::player_data::PlayerData {
|
||||
@@ -55,6 +56,47 @@ impl UserData {
|
||||
}
|
||||
Ok(fakes)
|
||||
}
|
||||
|
||||
pub(super) async fn generate_forced_fake_players_data(
|
||||
&self,
|
||||
guid: i64,
|
||||
real_players: &[super::PlayerLobbyDescriptor],
|
||||
factory: &dyn oj_rc_factory::VehicleFactoryAdapter,
|
||||
cpu_counter: &crate::cubes::CpuListParser,
|
||||
weapon_lister: &crate::cubes::WeaponListParser,
|
||||
chooser: &super::TeamChooser,
|
||||
) -> Result<Vec<(crate::data::player_data::PlayerData, crate::persist::config::ClientEmulator)>, polariton_server::operations::SimpleOpError> {
|
||||
self.generate_fake_players_data(
|
||||
guid,
|
||||
real_players,
|
||||
factory,
|
||||
cpu_counter,
|
||||
weapon_lister,
|
||||
chooser,
|
||||
&self.fake_players,
|
||||
).await
|
||||
}
|
||||
|
||||
pub(super) async fn generate_filler_players_data(
|
||||
&self,
|
||||
guid: i64,
|
||||
real_players: &[super::PlayerLobbyDescriptor],
|
||||
factory: &dyn oj_rc_factory::VehicleFactoryAdapter,
|
||||
cpu_counter: &crate::cubes::CpuListParser,
|
||||
weapon_lister: &crate::cubes::WeaponListParser,
|
||||
chooser: &super::TeamChooser,
|
||||
count: usize,
|
||||
) -> Result<Vec<(crate::data::player_data::PlayerData, crate::persist::config::ClientEmulator)>, polariton_server::operations::SimpleOpError> {
|
||||
self.generate_fake_players_data(
|
||||
guid,
|
||||
real_players,
|
||||
factory,
|
||||
cpu_counter,
|
||||
weapon_lister,
|
||||
chooser,
|
||||
&self.filler_players[0..count],
|
||||
).await
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
|
||||
@@ -265,7 +265,7 @@ 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 team_chooser(&self, game: &GameDescriptor) -> super::TeamChooser;
|
||||
async fn start_game(&self, game: GameDescriptor, players: Vec<PlayerLobbyDescriptor>, factory: &dyn oj_rc_factory::VehicleFactoryAdapter, cpu_counter: &crate::cubes::CpuListParser, weapon_lister: &crate::cubes::WeaponListParser, team_chooser: &super::TeamChooser) -> Result<FakePlayers, polariton_server::operations::SimpleOpError>;
|
||||
async fn start_game(&self, game: GameDescriptor, players: Vec<PlayerLobbyDescriptor>, factory: &dyn oj_rc_factory::VehicleFactoryAdapter, cpu_counter: &crate::cubes::CpuListParser, weapon_lister: &crate::cubes::WeaponListParser, team_chooser: &super::TeamChooser, missing_players: usize) -> Result<FakePlayers, polariton_server::operations::SimpleOpError>;
|
||||
}
|
||||
|
||||
pub struct FakePlayers {
|
||||
|
||||
Reference in New Issue
Block a user