Implemented features: - High-performance Rust extension with Redis persistence - Actor/player management with loadout, position, and state tracking - Banking system with deposit, withdraw, and transfer operations - Physical and virtual garage/locker systems for vehicle and equipment storage - Organization management with member tracking and permissions - Client-side UI with React-like state management - Server-side event-driven architecture with CBA Events - Security: Self-transfer prevention at multiple layers - Logging system with per-module log files - ICOM module for inter-server communication Co-Authored-By: Warp <agent@warp.dev>
89 lines
2.3 KiB
Rust
89 lines
2.3 KiB
Rust
use arma_rs::{FromArma, IntoArma};
|
|
use forge_shared::OrgValidationError;
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Org {
|
|
pub id: String,
|
|
pub owner: String,
|
|
pub name: String,
|
|
|
|
#[serde(default)]
|
|
pub funds: f64,
|
|
#[serde(default)]
|
|
pub reputation: i64,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct MemberSummary {
|
|
pub uid: String,
|
|
pub name: String,
|
|
}
|
|
|
|
impl Org {
|
|
pub fn new<S: Into<String>>(id: S, owner: S, name: S) -> Result<Self, OrgValidationError> {
|
|
let org = Self {
|
|
id: id.into(),
|
|
owner: owner.into(),
|
|
name: name.into(),
|
|
funds: 0.0,
|
|
reputation: 0,
|
|
};
|
|
|
|
org.validate()?;
|
|
Ok(org)
|
|
}
|
|
|
|
pub fn validate(&self) -> Result<(), OrgValidationError> {
|
|
if self.id.trim().is_empty() {
|
|
return Err(OrgValidationError::EmptyId);
|
|
}
|
|
|
|
if self.owner.trim().is_empty() {
|
|
return Err(OrgValidationError::EmptyOwner);
|
|
}
|
|
|
|
if self.name.trim().is_empty() {
|
|
return Err(OrgValidationError::EmptyName);
|
|
}
|
|
|
|
if self.funds < 0.0 {
|
|
return Err(OrgValidationError::NegativeFunds);
|
|
}
|
|
|
|
if !self.id.chars().all(|c| c.is_alphanumeric() || c == '_') {
|
|
return Err(OrgValidationError::InvalidId(self.id.clone()));
|
|
}
|
|
|
|
if self.owner != "server"
|
|
&& (!self.owner.chars().all(|c| c.is_numeric()) || self.owner.len() != 17)
|
|
{
|
|
return Err(OrgValidationError::InvalidOwner(self.owner.clone()));
|
|
}
|
|
|
|
if self.name.len() > 100 || self.name.chars().any(|c| c.is_control()) {
|
|
return Err(OrgValidationError::InvalidName(self.name.clone()));
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn id(&self) -> &str {
|
|
&self.id
|
|
}
|
|
}
|
|
|
|
impl FromArma for Org {
|
|
fn from_arma(s: String) -> Result<Self, arma_rs::FromArmaError> {
|
|
serde_json::from_str(&s)
|
|
.map_err(|e| arma_rs::FromArmaError::InvalidPrimitive(format!("Invalid JSON: {}", e)))
|
|
}
|
|
}
|
|
|
|
impl IntoArma for Org {
|
|
fn to_arma(&self) -> arma_rs::Value {
|
|
let json_str = serde_json::to_string(self).unwrap_or_default();
|
|
arma_rs::Value::String(json_str)
|
|
}
|
|
}
|