code sharing for steam setup
+ strip server a bit more
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
mod debug;
|
mod debug;
|
||||||
|
mod steam;
|
||||||
mod ui;
|
mod ui;
|
||||||
|
|
||||||
use crate::utils::{auto_rotate, explosions};
|
use crate::utils::{auto_rotate, explosions};
|
||||||
@@ -11,14 +12,12 @@ use bevy::{
|
|||||||
};
|
};
|
||||||
use bevy_common_assets::ron::RonAssetPlugin;
|
use bevy_common_assets::ron::RonAssetPlugin;
|
||||||
use bevy_sprite3d::Sprite3dPlugin;
|
use bevy_sprite3d::Sprite3dPlugin;
|
||||||
use bevy_steamworks::{Client, FriendFlags, SteamworksEvent, SteamworksPlugin};
|
|
||||||
use bevy_trenchbroom::prelude::*;
|
use bevy_trenchbroom::prelude::*;
|
||||||
use bevy_ui_gradients::UiGradientsPlugin;
|
use bevy_ui_gradients::UiGradientsPlugin;
|
||||||
use camera::MainCamera;
|
use camera::MainCamera;
|
||||||
use heads_database::HeadDatabaseAsset;
|
use heads_database::HeadDatabaseAsset;
|
||||||
use loading_assets::AudioAssets;
|
use loading_assets::AudioAssets;
|
||||||
use shared::*;
|
use shared::*;
|
||||||
use std::io::{Read, Write};
|
|
||||||
use utils::{billboards, sprite_3d_animation, squish_animation, trail};
|
use utils::{billboards, sprite_3d_animation, squish_animation, trail};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@@ -52,22 +51,7 @@ fn main() {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
let app_id = 1603000;
|
app.add_plugins(steam::plugin);
|
||||||
// should only be done in production builds
|
|
||||||
#[cfg(not(debug_assertions))]
|
|
||||||
if steamworks::restart_app_if_necessary(app_id.into()) {
|
|
||||||
info!("Restarting app via steam");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
match SteamworksPlugin::init_app(app_id) {
|
|
||||||
Ok(plugin) => {
|
|
||||||
app.add_plugins(plugin);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
warn!("steam init error: {e:?}");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
app.add_plugins(
|
app.add_plugins(
|
||||||
bevy_debug_log::LogViewerPlugin::default()
|
bevy_debug_log::LogViewerPlugin::default()
|
||||||
@@ -143,81 +127,13 @@ fn main() {
|
|||||||
//TODO: let user control this
|
//TODO: let user control this
|
||||||
app.insert_resource(GlobalVolume::new(Volume::Linear(0.4)));
|
app.insert_resource(GlobalVolume::new(Volume::Linear(0.4)));
|
||||||
|
|
||||||
app.add_systems(
|
app.add_systems(Startup, write_trenchbroom_config);
|
||||||
Startup,
|
|
||||||
(
|
|
||||||
write_trenchbroom_config,
|
|
||||||
(steam_system, steam_events)
|
|
||||||
.chain()
|
|
||||||
.run_if(resource_exists::<Client>),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
app.add_systems(OnEnter(GameState::Playing), music);
|
app.add_systems(OnEnter(GameState::Playing), music);
|
||||||
app.add_systems(Update, (set_materials_unlit, set_tonemapping, set_shadows));
|
app.add_systems(Update, (set_materials_unlit, set_tonemapping, set_shadows));
|
||||||
|
|
||||||
app.run();
|
app.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn steam_events(mut events: EventReader<SteamworksEvent>) {
|
|
||||||
for e in events.read() {
|
|
||||||
info!("steam ev: {:?}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn steam_system(steam_client: Res<Client>) {
|
|
||||||
steam_client.matchmaking().request_lobby_list(|list| {
|
|
||||||
let Ok(list) = list else { return };
|
|
||||||
|
|
||||||
info!("lobby list: [{}]", list.len());
|
|
||||||
for (i, l) in list.iter().enumerate() {
|
|
||||||
info!("lobby [{i}]: {:?}", l);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
steam_client
|
|
||||||
.matchmaking()
|
|
||||||
.create_lobby(
|
|
||||||
steamworks::LobbyType::FriendsOnly,
|
|
||||||
4,
|
|
||||||
|result| match result {
|
|
||||||
Ok(lobby_id) => {
|
|
||||||
info!("Created lobby with ID: {:?}", lobby_id);
|
|
||||||
}
|
|
||||||
Err(e) => error!("Failed to create lobby: {}", e),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
for friend in steam_client.friends().get_friends(FriendFlags::IMMEDIATE) {
|
|
||||||
info!(
|
|
||||||
"Steam Friend: {:?} - {}({:?})",
|
|
||||||
friend.id(),
|
|
||||||
friend.name(),
|
|
||||||
friend.state()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
steam_client
|
|
||||||
.remote_storage()
|
|
||||||
.set_cloud_enabled_for_app(true);
|
|
||||||
let f = steam_client.remote_storage().file("hedz_data.dat");
|
|
||||||
if f.exists() {
|
|
||||||
let mut buf = String::new();
|
|
||||||
if let Err(e) = f.read().read_to_string(&mut buf) {
|
|
||||||
error!("File read error: {}", e);
|
|
||||||
} else {
|
|
||||||
info!("File content: {}", buf);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
info!("File does not exist");
|
|
||||||
|
|
||||||
if let Err(e) = f.write().write_all(String::from("hello world").as_bytes()) {
|
|
||||||
error!("steam cloud error: {}", e);
|
|
||||||
} else {
|
|
||||||
info!("steam cloud saved");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn music(assets: Res<AudioAssets>, mut commands: Commands) {
|
fn music(assets: Res<AudioAssets>, mut commands: Commands) {
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Name::new("sfx-music"),
|
Name::new("sfx-music"),
|
||||||
|
|||||||
74
crates/client/src/steam.rs
Normal file
74
crates/client/src/steam.rs
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
use bevy_steamworks::{Client, FriendFlags, SteamworksEvent};
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
|
pub fn plugin(app: &mut App) {
|
||||||
|
app.add_plugins(shared::steam::plugin);
|
||||||
|
|
||||||
|
app.add_systems(
|
||||||
|
Startup,
|
||||||
|
(test_steam_system, log_steam_events)
|
||||||
|
.chain()
|
||||||
|
.run_if(resource_exists::<Client>),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn log_steam_events(mut events: EventReader<SteamworksEvent>) {
|
||||||
|
for e in events.read() {
|
||||||
|
info!("steam ev: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_steam_system(steam_client: Res<Client>) {
|
||||||
|
steam_client.matchmaking().request_lobby_list(|list| {
|
||||||
|
let Ok(list) = list else { return };
|
||||||
|
|
||||||
|
info!("lobby list: [{}]", list.len());
|
||||||
|
for (i, l) in list.iter().enumerate() {
|
||||||
|
info!("lobby [{i}]: {:?}", l);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
steam_client
|
||||||
|
.matchmaking()
|
||||||
|
.create_lobby(
|
||||||
|
steamworks::LobbyType::FriendsOnly,
|
||||||
|
4,
|
||||||
|
|result| match result {
|
||||||
|
Ok(lobby_id) => {
|
||||||
|
info!("Created lobby with ID: {:?}", lobby_id);
|
||||||
|
}
|
||||||
|
Err(e) => error!("Failed to create lobby: {}", e),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
for friend in steam_client.friends().get_friends(FriendFlags::IMMEDIATE) {
|
||||||
|
info!(
|
||||||
|
"Steam Friend: {:?} - {}({:?})",
|
||||||
|
friend.id(),
|
||||||
|
friend.name(),
|
||||||
|
friend.state()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
steam_client
|
||||||
|
.remote_storage()
|
||||||
|
.set_cloud_enabled_for_app(true);
|
||||||
|
let f = steam_client.remote_storage().file("hedz_data.dat");
|
||||||
|
if f.exists() {
|
||||||
|
let mut buf = String::new();
|
||||||
|
if let Err(e) = f.read().read_to_string(&mut buf) {
|
||||||
|
error!("File read error: {}", e);
|
||||||
|
} else {
|
||||||
|
info!("File content: {}", buf);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
info!("File does not exist");
|
||||||
|
|
||||||
|
if let Err(e) = f.write().write_all(String::from("hello world").as_bytes()) {
|
||||||
|
error!("steam cloud error: {}", e);
|
||||||
|
} else {
|
||||||
|
info!("steam cloud saved");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,21 +1,12 @@
|
|||||||
use crate::utils::{auto_rotate, explosions};
|
use crate::utils::{auto_rotate, explosions};
|
||||||
use avian3d::prelude::*;
|
use avian3d::prelude::*;
|
||||||
use bevy::{
|
use bevy::{audio::Volume, core_pipeline::tonemapping::Tonemapping, prelude::*};
|
||||||
audio::{PlaybackMode, Volume},
|
|
||||||
core_pipeline::tonemapping::Tonemapping,
|
|
||||||
prelude::*,
|
|
||||||
render::view::ColorGrading,
|
|
||||||
};
|
|
||||||
use bevy_common_assets::ron::RonAssetPlugin;
|
use bevy_common_assets::ron::RonAssetPlugin;
|
||||||
use bevy_sprite3d::Sprite3dPlugin;
|
use bevy_sprite3d::Sprite3dPlugin;
|
||||||
use bevy_steamworks::{Client, FriendFlags, SteamworksEvent, SteamworksPlugin};
|
|
||||||
use bevy_trenchbroom::prelude::*;
|
use bevy_trenchbroom::prelude::*;
|
||||||
use bevy_ui_gradients::UiGradientsPlugin;
|
use bevy_ui_gradients::UiGradientsPlugin;
|
||||||
use camera::MainCamera;
|
|
||||||
use heads_database::HeadDatabaseAsset;
|
use heads_database::HeadDatabaseAsset;
|
||||||
use loading_assets::AudioAssets;
|
|
||||||
use shared::*;
|
use shared::*;
|
||||||
use std::io::{Read, Write};
|
|
||||||
use utils::{billboards, sprite_3d_animation, squish_animation, trail};
|
use utils::{billboards, sprite_3d_animation, squish_animation, trail};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@@ -49,23 +40,6 @@ fn main() {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
let app_id = 1603000;
|
|
||||||
// should only be done in production builds
|
|
||||||
#[cfg(not(debug_assertions))]
|
|
||||||
if steamworks::restart_app_if_necessary(app_id.into()) {
|
|
||||||
info!("Restarting app via steam");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
match SteamworksPlugin::init_app(app_id) {
|
|
||||||
Ok(plugin) => {
|
|
||||||
app.add_plugins(plugin);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
warn!("steam init error: {e:?}");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
app.add_plugins(
|
app.add_plugins(
|
||||||
bevy_debug_log::LogViewerPlugin::default()
|
bevy_debug_log::LogViewerPlugin::default()
|
||||||
.auto_open_threshold(bevy::log::tracing::level_filters::LevelFilter::OFF),
|
.auto_open_threshold(bevy::log::tracing::level_filters::LevelFilter::OFF),
|
||||||
@@ -138,137 +112,5 @@ fn main() {
|
|||||||
//TODO: let user control this
|
//TODO: let user control this
|
||||||
app.insert_resource(GlobalVolume::new(Volume::Linear(0.4)));
|
app.insert_resource(GlobalVolume::new(Volume::Linear(0.4)));
|
||||||
|
|
||||||
app.add_systems(
|
|
||||||
Startup,
|
|
||||||
(
|
|
||||||
write_trenchbroom_config,
|
|
||||||
(steam_system, steam_events)
|
|
||||||
.chain()
|
|
||||||
.run_if(resource_exists::<Client>),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
app.add_systems(OnEnter(GameState::Playing), music);
|
|
||||||
app.add_systems(Update, (set_materials_unlit, set_tonemapping, set_shadows));
|
|
||||||
|
|
||||||
app.run();
|
app.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn steam_events(mut events: EventReader<SteamworksEvent>) {
|
|
||||||
for e in events.read() {
|
|
||||||
info!("steam ev: {:?}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn steam_system(steam_client: Res<Client>) {
|
|
||||||
steam_client.matchmaking().request_lobby_list(|list| {
|
|
||||||
let Ok(list) = list else { return };
|
|
||||||
|
|
||||||
info!("lobby list: [{}]", list.len());
|
|
||||||
for (i, l) in list.iter().enumerate() {
|
|
||||||
info!("lobby [{i}]: {:?}", l);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
steam_client
|
|
||||||
.matchmaking()
|
|
||||||
.create_lobby(
|
|
||||||
steamworks::LobbyType::FriendsOnly,
|
|
||||||
4,
|
|
||||||
|result| match result {
|
|
||||||
Ok(lobby_id) => {
|
|
||||||
info!("Created lobby with ID: {:?}", lobby_id);
|
|
||||||
}
|
|
||||||
Err(e) => error!("Failed to create lobby: {}", e),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
for friend in steam_client.friends().get_friends(FriendFlags::IMMEDIATE) {
|
|
||||||
info!(
|
|
||||||
"Steam Friend: {:?} - {}({:?})",
|
|
||||||
friend.id(),
|
|
||||||
friend.name(),
|
|
||||||
friend.state()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
steam_client
|
|
||||||
.remote_storage()
|
|
||||||
.set_cloud_enabled_for_app(true);
|
|
||||||
let f = steam_client.remote_storage().file("hedz_data.dat");
|
|
||||||
if f.exists() {
|
|
||||||
let mut buf = String::new();
|
|
||||||
if let Err(e) = f.read().read_to_string(&mut buf) {
|
|
||||||
error!("File read error: {}", e);
|
|
||||||
} else {
|
|
||||||
info!("File content: {}", buf);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
info!("File does not exist");
|
|
||||||
|
|
||||||
if let Err(e) = f.write().write_all(String::from("hello world").as_bytes()) {
|
|
||||||
error!("steam cloud error: {}", e);
|
|
||||||
} else {
|
|
||||||
info!("steam cloud saved");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn music(assets: Res<AudioAssets>, mut commands: Commands) {
|
|
||||||
commands.spawn((
|
|
||||||
Name::new("sfx-music"),
|
|
||||||
AudioPlayer::new(assets.music.clone()),
|
|
||||||
PlaybackSettings {
|
|
||||||
mode: PlaybackMode::Loop,
|
|
||||||
volume: Volume::Linear(0.6),
|
|
||||||
..default()
|
|
||||||
},
|
|
||||||
));
|
|
||||||
|
|
||||||
commands.spawn((
|
|
||||||
Name::new("sfx-ambient"),
|
|
||||||
AudioPlayer::new(assets.ambient.clone()),
|
|
||||||
PlaybackSettings {
|
|
||||||
mode: PlaybackMode::Loop,
|
|
||||||
volume: Volume::Linear(0.8),
|
|
||||||
..default()
|
|
||||||
},
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_trenchbroom_config(server: Res<TrenchBroomServer>, type_registry: Res<AppTypeRegistry>) {
|
|
||||||
if let Err(e) = server
|
|
||||||
.config
|
|
||||||
.write_game_config("trenchbroom/hedz", &type_registry.read())
|
|
||||||
{
|
|
||||||
warn!("Failed to write trenchbroom config: {}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_tonemapping(
|
|
||||||
mut cams: Query<(&mut Tonemapping, &mut ColorGrading), With<MainCamera>>,
|
|
||||||
visuals: Res<DebugVisuals>,
|
|
||||||
) {
|
|
||||||
for (mut tm, mut color) in cams.iter_mut() {
|
|
||||||
*tm = visuals.tonemapping;
|
|
||||||
color.global.exposure = visuals.exposure;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_materials_unlit(
|
|
||||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
|
||||||
visuals: Res<DebugVisuals>,
|
|
||||||
) {
|
|
||||||
if !materials.is_changed() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (_, material) in materials.iter_mut() {
|
|
||||||
material.unlit = visuals.unlit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_shadows(mut lights: Query<&mut DirectionalLight>, visuals: Res<DebugVisuals>) {
|
|
||||||
for mut l in lights.iter_mut() {
|
|
||||||
l.shadows_enabled = visuals.shadows;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ pub mod physics_layers;
|
|||||||
pub mod platforms;
|
pub mod platforms;
|
||||||
pub mod player;
|
pub mod player;
|
||||||
pub mod sounds;
|
pub mod sounds;
|
||||||
|
pub mod steam;
|
||||||
pub mod tb_entities;
|
pub mod tb_entities;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
pub mod water;
|
pub mod water;
|
||||||
|
|||||||
25
crates/shared/src/steam.rs
Normal file
25
crates/shared/src/steam.rs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
use bevy_steamworks::SteamworksPlugin;
|
||||||
|
|
||||||
|
pub fn plugin(app: &mut App) {
|
||||||
|
let app_id = 1603000;
|
||||||
|
|
||||||
|
// should only be done in production builds
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
if steamworks::restart_app_if_necessary(app_id.into()) {
|
||||||
|
info!("Restarting app via steam");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
info!("steam app init: {app_id}");
|
||||||
|
|
||||||
|
match SteamworksPlugin::init_app(app_id) {
|
||||||
|
Ok(plugin) => {
|
||||||
|
info!("steam app init done");
|
||||||
|
app.add_plugins(plugin);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
warn!("steam init error: {e:?}");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
3
justfile
3
justfile
@@ -8,6 +8,9 @@ tb_setup_mac:
|
|||||||
run:
|
run:
|
||||||
RUST_BACKTRACE=1 cargo r --bin hedz_reloaded
|
RUST_BACKTRACE=1 cargo r --bin hedz_reloaded
|
||||||
|
|
||||||
|
server:
|
||||||
|
RUST_BACKTRACE=1 cargo r --bin server
|
||||||
|
|
||||||
dbg:
|
dbg:
|
||||||
RUST_BACKTRACE=1 cargo r --bin hedz_reloaded --features dbg
|
RUST_BACKTRACE=1 cargo r --bin hedz_reloaded --features dbg
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user