1
0
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:
NG (Graham)
2026-01-15 18:49:29 -05:00
parent 16f0761380
commit a48f9dcfe9
13 changed files with 222 additions and 52 deletions

View File

@@ -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()
}
}
}
}

View File

@@ -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(),

View File

@@ -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,

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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>,

View File

@@ -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(),
})
}
}

View File

@@ -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]

View File

@@ -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 {