K76L4UCUODWSMCH6TZRX2HKA6INLVLSJ5Y7QIF7KL7YZRCISCHYAC
#[derive(Deserialize, Serialize, Debug, Clone, Default)]
pub(crate) struct Index {
pub(crate) mods: Vec<Mod>,
#[derive(Deserialize, Serialize, Debug, Clone)]
#[serde(rename_all = "PascalCase")]
pub(crate) struct Manifest {
pub name: String,
pub description: String,
pub version: Version,
pub load_priority: u16,
pub convars: Vec<ConvarObj>,
pub scripts: Vec<ScriptObj>,
pub localisation: Vec<String>,
impl Index {
pub fn read() -> Result<Self> {
let p = std::env::current_dir()?.join(FILE_NAME);
if let Ok(raw) = fs::read_to_string(&p) {
ron::from_str(&raw).context("Unable to parse index")
} else {
Ok(Index::default())
impl Manifest {
pub fn new(name: String, description: String) -> Self {
Manifest {
name,
description,
version: Version::new(0, 1, 0),
load_priority: 0,
convars: vec![],
scripts: vec![],
localisation: vec![],
pub fn write(&self) -> Result<()> {
let cfg = ron::ser::PrettyConfig::new().compact_arrays(true);
let p = std::env::current_dir()?.join(FILE_NAME);
let raw = ron::ser::to_string_pretty(self, cfg)?;
fs::write(&p, &raw).context("Failed to write index")?;
pub fn save(&self) -> Result<()> {
let target = std::env::current_dir()?.join("mod.json");
let raw = serde_json::to_string_pretty(self)?;
fs::write(target, &raw).context("Failed to write file")?;
#[derive(Deserialize, Serialize, Debug, Clone, Default)]
#[serde(rename_all = "PascalCase")]
pub(crate) struct ConvarObj {
pub name: String,
pub default_value: String,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "PascalCase")]
pub(crate) struct ScriptObj {
pub path: String,
pub run_on: String,
#[serde(flatten)]
pub client_callback: Option<HashMap<String, String>>,
#[serde(flatten)]
pub server_callback: Option<HashMap<String, String>>,
}
pub fn read() -> Result<Self> {
let p = std::env::current_dir()?.join(FILE_NAME);
let raw = fs::read_to_string(&p)?;
ron::from_str(&raw).context("Unable to parse index")
}
pub fn save(&self) -> Result<()> {
let cfg = ron::ser::PrettyConfig::new().compact_arrays(true);
let p = std::env::current_dir()?.join(FILE_NAME);
let raw = ron::ser::to_string_pretty(self, cfg)?;
fs::write(&p, &raw).context("Failed to write index")?;
Ok(())
}
fn from_str(s: &str) -> Result<Self, Self::Err> {
let re = Regex::new(r"(\d+)\.(\d+)\.(\d+)").unwrap();
if let Some(c) = re.captures(s) {
let major = c.get(1).unwrap().as_str().parse::<u8>().unwrap();
let minor = c.get(2).unwrap().as_str().parse::<u8>().unwrap();
let patch = c.get(3).unwrap().as_str().parse::<u8>().unwrap();
// fn from_str(s: &str) -> Result<Self, Self::Err> {
// let re = Regex::new(r"(\d+)\.(\d+)\.(\d+)").unwrap();
// if let Some(c) = re.captures(s) {
// let major = c.get(1).unwrap().as_str().parse::<u8>().unwrap();
// let minor = c.get(2).unwrap().as_str().parse::<u8>().unwrap();
// let patch = c.get(3).unwrap().as_str().parse::<u8>().unwrap();
impl Display for Version {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}.{}.{}", self.major, self.minor, self.patch)
}
}
// impl Display for Version {
// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// write!(f, "{}.{}.{}", self.major, self.minor, self.patch)
// }
// }
mrvnfile
.mods
.push(Mod::new(author, name, "0.1.0".to_owned()));
mrvnfile.write().unwrap();
pub fn init() {}
fn init_mod(path: &Path, name: &str) {
//create dir
debug!("Creating directory at {}", path.display());
if let Err(e) = fs::create_dir_all(&path) {
error!("Failed to create new mod directory: {}", e);
}
//change to the directory for mrvn.ron stuff
trace!("Change directory to {}", path.display());
if let Err(e) = std::env::set_current_dir(path) {
error!("Couldn't change directory to {}: {}", path.display(), e);
}
//create git repo
debug!("Initializing git repo");
if let Err(e) = Repository::init(&path) {
error!("Failed to initialize git repository: {}", e);
}
//create boilerplate
debug!("Create mod.json");
let mut mo = Manifest::new(name.to_owned(), String::new());
let example = include_str!("example_mod");
let mut map = HashMap::new();
map.insert("After".to_owned(), "MRVN_Example".to_owned());
let scrobj = ScriptObj {
path: "example.nut".to_owned(),
run_on: "( CLIENT || SERVER ) && MP".to_owned(),
server_callback: None,
client_callback: Some(map),
};
mo.scripts.push(scrobj);
let path = path.join("mod").join("scripts").join("vscripts");
fs::create_dir_all(&path).unwrap();
fs::write(path.join("example.nut"), example).unwrap();
mo.save().unwrap();
global function MRVN_Example
void function MRVN_Example () {
print ( "Hello World!" )
}