Skip to content

Commit

Permalink
Merge pull request #1 from mymatsubara/feat/configs
Browse files Browse the repository at this point in the history
Add configs.json support
  • Loading branch information
mymatsubara authored Apr 20, 2023
2 parents 562911e + d83f9dc commit 3ff6e26
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 35 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/target
/target
configs.json
38 changes: 36 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
[package]
name = "osucraft"
version = "0.1.0"
version = "0.1.1"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
anyhow = "1.0.68"
bevy_ecs = "0.9.1"
colored = "2.0.0"
directories = "5.0.0"
fuzzy-matcher = "0.3.7"
osu-file-parser = "1.1.0"
rand = "0.8.5"
rodio = "0.17.1"
serde = "1.0.160"
serde_json = "1.0.96"
tracing = "0.1.37"
tracing-subscriber = "0.3.16"
valence = { git = "https://github.com/mymatsubara/valence", branch = "osucraft" }
70 changes: 70 additions & 0 deletions src/configs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use anyhow::Result;
use colored::Colorize;
use directories::BaseDirs;
use std::fmt::Display;
use std::str;
use std::{fs, path::PathBuf};

use bevy_ecs::system::Resource;
use serde::{Deserialize, Serialize};
use tracing::warn;

#[derive(Resource, Serialize, Deserialize, Debug)]
pub struct Configs {
songs_directory: String,
}

impl Configs {
pub fn open() -> Self {
Self::read().unwrap_or_else(|_| {
let default_configs = Self::default();

if let Err(error) = default_configs.save() {
warn!("Error while saving configs file: {}", error);
}

default_configs
})
}

pub fn path() -> PathBuf {
PathBuf::from("configs.json")
}

fn read() -> Result<Self> {
let path = Self::path();
let file_data = fs::read(path)?;
let json = str::from_utf8(file_data.as_slice())?;
Ok(serde_json::from_str(json)?)
}

fn save(&self) -> Result<()> {
let json = serde_json::to_string_pretty(self)?;
fs::write(Self::path(), json)?;

Ok(())
}

pub fn songs_directory(&self) -> &str {
&self.songs_directory
}
}

impl Default for Configs {
fn default() -> Self {
let local_dir = BaseDirs::new()
.map(|base_dirs| base_dirs.data_local_dir().to_path_buf())
.unwrap_or_else(|| PathBuf::from("./"));
let songs_directory = local_dir.join("osu!").join("Songs");

Self {
songs_directory: songs_directory.to_str().unwrap().to_owned(),
}
}
}

impl Display for Configs {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}: {}", "Songs directory".cyan(), self.songs_directory)
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub mod beatmap;
pub mod beatmap_selection;
pub mod color;
pub mod commands;
pub mod configs;
pub mod digit;
pub mod hit_object;
pub mod hit_score;
Expand Down
23 changes: 21 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use std::path::PathBuf;

use colored::Colorize;
use osucraft::audio::AudioPlayer;

use osucraft::configs::Configs;
use osucraft::osu::{Osu, OsuInstance};
use osucraft::plugin::OsuPlugin;
use rodio::OutputStream;
Expand Down Expand Up @@ -36,16 +40,31 @@ pub fn main() {
}

fn setup(world: &mut World) {
// Init configs
let configs = Configs::open();
let configs_path = Configs::path();
let header = format!(
"================= CONFIGS ({}) =================",
configs_path.display()
);
println!("{}", header.cyan());
println!("{configs}\n");
let info = format!(
"INFO: To update any config modify the file '{}' and restart the server.\n",
configs_path.display()
);
println!("{}", info.yellow());

let server = world.resource::<Server>();
let mut instance = server.new_instance(DimensionId::default());

// Init osu
world.resource::<Osu>().init(&mut instance);
Osu::init_inventory_selections(world);
Osu::init_inventory_selections(world, PathBuf::from(configs.songs_directory()));

world.spawn((instance, OsuInstance));

println!("Server is running on: \x1b[32mlocalhost:25565\x1b[0m")
println!("Server is running on: {}", "localhost::25565".green())
}

fn init_clients(
Expand Down
4 changes: 2 additions & 2 deletions src/osu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,8 @@ impl Osu {
instance.set_block(block_pos, Block::new(BlockState::BEDROCK));
}

pub fn init_inventory_selections(world: &mut World) {
match SongSelectionInventory::new() {
pub fn init_inventory_selections(world: &mut World, songs_dir: PathBuf) {
match SongSelectionInventory::new(songs_dir) {
Ok(song_selection) => {
world.spawn(song_selection);
}
Expand Down
48 changes: 21 additions & 27 deletions src/song_selection.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use anyhow::{anyhow, Result};
use directories::BaseDirs;
use fuzzy_matcher::{skim::SkimMatcherV2, FuzzyMatcher};
use std::{
cmp::{min, Reverse},
Expand Down Expand Up @@ -36,6 +35,7 @@ const PAGE_SIZE: usize = 36;
pub struct SongSelectionInventory {
cur_page: usize,
songs: Vec<PathBuf>,
songs_dir: PathBuf,
keywords: Option<String>,
}

Expand All @@ -45,17 +45,18 @@ struct Song {
}

impl SongSelectionInventory {
pub fn new() -> Result<(Self, Inventory)> {
pub fn new(songs_dir: PathBuf) -> Result<(Self, Inventory)> {
let inventory = Inventory::new(InventoryKind::Generic9x6);

Ok((
Self {
cur_page: 0,
songs: Self::get_all_songs()?,
keywords: None,
},
inventory,
))
let mut result = Self {
cur_page: 0,
songs_dir,
songs: Default::default(),
keywords: None,
};
result.songs = result.fetch_all_songs()?;

Ok((result, inventory))
}

pub fn go_to_next_page(&mut self) {
Expand All @@ -67,7 +68,7 @@ impl SongSelectionInventory {
}

pub fn set_filter(&mut self, keywords: Option<&str>) -> Result<()> {
self.songs = Self::filter_songs(Self::get_all_songs()?, keywords);
self.songs = Self::filter_songs(self.fetch_all_songs()?, keywords);
self.keywords = keywords.map(|s| s.to_string());
self.cur_page = 0;

Expand Down Expand Up @@ -107,8 +108,15 @@ impl SongSelectionInventory {
(self.songs.len() - 1) / PAGE_SIZE
}

fn get_all_songs() -> Result<Vec<PathBuf>> {
Ok(read_dir(Self::get_songs_dir()?)?
fn fetch_all_songs(&self) -> Result<Vec<PathBuf>> {
if !self.songs_dir.exists() {
return Err(anyhow!(
"Could not find osu! song directory: '{}'.",
self.songs_dir.display()
));
}

Ok(read_dir(self.songs_dir.clone())?
.filter_map(|result| result.ok())
.map(|entry| entry.path())
.filter(|entry| entry.is_dir() && entry.file_name().is_some())
Expand Down Expand Up @@ -140,20 +148,6 @@ impl SongSelectionInventory {
None => songs,
}
}

fn get_songs_dir() -> Result<PathBuf> {
let base_dirs = BaseDirs::new().ok_or(anyhow!("No home directory found in the system"))?;
let beatmaps_dir = base_dirs.data_local_dir().join("osu!").join("Songs");

if beatmaps_dir.exists() {
Ok(beatmaps_dir)
} else {
Err(anyhow!(
"Could not find osu song directory: '{}'",
beatmaps_dir.display()
))
}
}
}

pub fn update_song_selection_inventory(
Expand Down

0 comments on commit 3ff6e26

Please sign in to comment.