#![allow(dead_code)]
use std::io;
use std::sync::Arc;
use azalea_protocol::connect::Proxy;
use tokio::sync::RwLock;
use tokio::task::JoinHandle;
use uuid::Uuid;
use crate::common::BotInformation;
use crate::core::bot::Bot;
use crate::core::common::{BotCommand, BotPlugins, BotTerminal};
use crate::core::data::{Storage, StorageLock};
use crate::core::events::EventInvoker;
use crate::utils::time::sleep;
pub struct Swarm {
pub bots: Vec<Bot>,
pub terminals: Vec<Arc<BotTerminal>>,
pub handles: Vec<JoinHandle<io::Result<()>>>,
pub shared_storage: StorageLock,
}
pub type SharedSwarm = Arc<RwLock<Swarm>>;
impl Swarm {
pub fn new() -> Self {
Self {
bots: Vec::new(),
terminals: Vec::new(),
handles: Vec::new(),
shared_storage: Arc::new(RwLock::new(Storage::new())),
}
}
pub fn add_object(&mut self, object: SwarmObject) {
let mut bot = Bot::new(&object.username)
.set_connection_timeout(object.connection_timeout)
.set_uuid(object.uuid)
.set_plugins(object.plugins)
.set_information(object.information);
if object.use_shared_storage {
bot = bot.set_shared_storage(self.shared_storage.clone());
}
if let Some(proxy) = object.proxy {
bot = bot.set_proxy(proxy);
}
if let Some(invoker) = object.event_invoker {
bot = bot.set_event_invoker(invoker);
}
let terminal = Arc::clone(&bot.terminal);
self.bots.push(bot);
self.terminals.push(terminal);
}
pub fn get_bot(&self, username: &str) -> Option<&Bot> {
self.bots.iter().find(|b| b.username == username)
}
pub fn get_bot_mut(&mut self, username: &str) -> Option<&mut Bot> {
self.bots.iter_mut().find(|b| b.username == username)
}
pub async fn launch_blocking(&mut self, server_host: &str, server_port: u16, join_delay: u64) {
let bots = std::mem::take(&mut self.bots);
for bot in bots {
self.handles.push(bot.spawn(server_host, server_port));
sleep(join_delay).await;
}
}
pub async fn send(&self, command: BotCommand) {
for terminal in &self.terminals {
terminal.send(command.clone()).await;
}
}
pub async fn send_to(&self, username: &str, command: BotCommand) {
for terminal in &self.terminals {
if terminal.receiver.as_str() == username {
terminal.send(command).await;
break;
}
}
}
pub async fn destroy(&mut self) {
for terminal in &self.terminals {
terminal.send(BotCommand::Disconnect).await;
}
sleep(1000).await;
for handle in &self.handles {
handle.abort();
}
self.bots.clear();
self.terminals.clear();
self.handles.clear();
}
pub fn force_destroy(&mut self) {
for handle in &self.handles {
handle.abort();
}
self.bots.clear();
self.terminals.clear();
self.handles.clear();
}
}
pub struct SwarmObject {
pub username: String,
uuid: Uuid,
plugins: BotPlugins,
event_invoker: Option<EventInvoker>,
connection_timeout: u64,
proxy: Option<Proxy>,
information: BotInformation,
use_shared_storage: bool,
}
impl SwarmObject {
pub fn new(username: String) -> Self {
Self {
username,
uuid: Uuid::nil(),
plugins: BotPlugins::default(),
event_invoker: None,
connection_timeout: 14000,
proxy: None,
information: BotInformation::default(),
use_shared_storage: true,
}
}
pub fn set_uuid(mut self, uuid: Uuid) -> Self {
self.uuid = uuid;
self
}
pub fn set_plugins(mut self, plugins: BotPlugins) -> Self {
self.plugins = plugins;
self
}
pub fn set_event_invoker(mut self, invoker: EventInvoker) -> Self {
self.event_invoker = Some(invoker);
self
}
pub fn set_connection_timeout(mut self, timeout: u64) -> Self {
self.connection_timeout = timeout;
self
}
pub fn set_information(mut self, information: BotInformation) -> Self {
self.information = information;
self
}
pub fn set_proxy(mut self, proxy: Proxy) -> Self {
self.proxy = Some(proxy);
self
}
pub fn set_use_shared_storage(mut self, state: bool) -> Self {
self.use_shared_storage = state;
self
}
}