merge develop into master #20

Merged
michael-bailey merged 181 commits from develop into master 2023-12-01 21:48:28 +00:00
13 changed files with 125 additions and 72 deletions
Showing only changes of commit 0624b568f9 - Show all commits

View File

@ -1,31 +1,65 @@
use crate::event::event_result::EventResultBuilder;
use crate::event::EventResult;
use crate::event::EventResultType;
use std::collections::HashMap;
use uuid::Uuid;
use futures::channel::oneshot::{channel, Receiver, Sender};
//todo: move this out of foundation
pub enum EventType<'a> {
NewConnection,
ClientAdded,
Custom(&'a str),
}
pub struct Event<T> {
/// # Eventw
/// Object that holds details about an event being passed through the application.
///
/// ## Properties
/// - r#type: The event type
/// - args: A hashmap of arguments to be carried by the event
/// - sender: The sender to send the result for the event.
/// - receiver: The reciever of the event result from the event.
pub struct Event<T>
where
T: Sync + Send,
{
pub r#type: T,
args: HashMap<String, String>,
sender: Sender<EventResult>,
receiver: Option<Receiver<EventResult>>,
}
impl<T> Event<T>
where
T: Sync + Send,
{
/// Fetches an argument from the arguments of the event.
pub fn get_arg(&self, key: String) -> Option<String> {
self.args.get(&key).cloned()
}
/// Creates an event result using the sender of the event.
/// This consumes the event.
pub fn respond(self, result_type: EventResultType) -> EventResultBuilder {
EventResult::create(result_type, self.sender)
}
/// Used to await the result of the event if required.
pub fn get_reciever(&mut self) -> Receiver<EventResult> {
self.receiver.take().unwrap()
}
}
pub struct EventBuilder<T> {
#[allow(dead_code)]
r#type: T,
#[allow(dead_code)]
args: HashMap<String, String>,
#[allow(dead_code)]
sender: Sender<EventResult>,
#[allow(dead_code)]
receiver: Option<Receiver<EventResult>>,
}
impl<T> EventBuilder<T> {
#[allow(dead_code)]
pub(super) fn new(r#type: T) -> EventBuilder<T> {
let (sender, receiver) = channel();
EventBuilder {
@ -41,7 +75,11 @@ impl<T> EventBuilder<T> {
self
}
pub(crate) fn build(self) -> Event<T> {
#[allow(dead_code)]
pub(crate) fn build(self) -> Event<T>
where
T: Sync + Send,
{
Event {
r#type: self.r#type,
args: self.args,

View File

@ -3,6 +3,7 @@ use std::collections::HashMap;
pub enum EventResultType {
Success,
NoResponse,
InvalidArgs,
InvalidCode,
Other(String),
@ -14,21 +15,25 @@ pub struct EventResult {
}
impl EventResult {
pub fn create(result_type: EventResultType) -> EventResultBuilder {
EventResultBuilder::new(result_type)
pub fn create(result_type: EventResultType, sender: Sender<EventResult>) -> EventResultBuilder {
EventResultBuilder::new(result_type, sender)
}
}
/// # EventResultBuilder
/// Builds the result of an event
pub struct EventResultBuilder {
code: EventResultType,
args: HashMap<String, String>,
sender: Sender<EventResult>,
}
impl EventResultBuilder {
pub(self) fn new(result_type: EventResultType) -> Self {
pub(self) fn new(result_type: EventResultType, sender: Sender<EventResult>) -> Self {
Self {
code: result_type,
args: HashMap::default(),
sender,
}
}
@ -37,15 +42,9 @@ impl EventResultBuilder {
self
}
pub fn build(self) -> EventResult {
EventResult {
code: self.code,
args: self.args,
}
}
pub fn send(self, sender: Sender<EventResult>) {
sender
pub fn send(self) {
self
.sender
.send(EventResult {
code: self.code,
args: self.args,

View File

@ -1,7 +1,8 @@
#[allow(clippy::module_inception)]
mod event;
mod event_result;
mod responder;
pub use self::responder::IResponder;
pub use event::{Event, EventBuilder, EventType};
pub use event::{Event, EventBuilder};
pub use event_result::{EventResult, EventResultType};

View File

@ -1,7 +1,9 @@
use crate::event::Event;
use std::sync::Weak;
pub trait IResponder<T> {
pub trait IResponder<T>
where
T: Sync + Send {
fn post_event(&self, event: Event<T>) {
if let Some(next) = self.get_next() {
if let Some(next) = next.upgrade() {

View File

@ -26,6 +26,7 @@ openssl = "0.10.33"
tokio = { version = "1.9.0", features = ["full"] }
futures = "0.3.16"
async-trait = "0.1.52"
actix = "0.12"
mlua = { version = "0.7.3", features=["lua54", "async", "serde", "macros"] }
libloading = "0.7"

10
server/src/event_type.rs Normal file
View File

@ -0,0 +1,10 @@
use crate::client::Client;
use std::sync::Arc;
use uuid::Uuid;
pub enum EventType<'a> {
NewConnection,
// Todo: - change client to use traits
ClientAdded(Uuid),
Custom(&'a str),
}

View File

@ -1,10 +1,11 @@
// mod chat_manager;
mod client;
mod client_manager;
mod event;
mod event_type;
mod lua;
mod messages;
mod network_manager;
pub mod plugin;
// pub mod plugin;
mod server;
pub use server::Server;

View File

@ -1,10 +1,11 @@
// pub mod chat_manager;
pub mod client;
pub mod client_manager;
mod event_type;
mod lua;
pub mod messages;
pub mod network_manager;
mod plugin;
// mod plugin;
pub mod server;
use std::io;
@ -15,22 +16,6 @@ use server::Server;
#[tokio::main]
async fn main() -> io::Result<()> {
let _args = App::new("--rust chat server--")
.version("0.1.5")
.author("Mitchel Hardie <mitch161>, Michael Bailey <michael-bailey>")
.about(
"this is a chat server developed in rust, depending on the version one of two implementations will be used",
)
.arg(
Arg::with_name("config")
.short("p")
.long("port")
.value_name("PORT")
.help("sets the port the server runs on.")
.takes_value(true),
)
.get_matches();
let server = Server::new().await.unwrap();
server.start().await;

View File

@ -27,7 +27,7 @@ pub trait IPlugin<T>: Send + Sync + Debug {
fn details(&self) -> PluginDetails;
fn on_event(&self, event: Event<T>);
fn set_interface(&self, interface: WeakPluginInterface);
fn set_interface(&self, interface: WeakPluginInterface<T>);
fn init(&self);
async fn run(&self);

View File

@ -2,8 +2,9 @@ use crate::plugin::plugin_interface::IPluginInterface;
use crate::plugin::PluginInterface;
use foundation::event::Event;
use crate::event_type::EventType;
use foundation::event::EventResult;
use foundation::event::EventType;
use foundation::event::IResponder;
use serde::{Deserialize, Serialize};
use std::sync::Weak;
@ -39,7 +40,10 @@ pub(crate) enum PluginExecutionState {
/// Used to provide an api for the plugin to use.
/// Also acts as gatekeeper to server data with permissions.
#[derive(Debug)]
pub(crate) struct PluginEntry {
pub(crate) struct PluginEntry<T>
where
T: Sync + Send,
{
server_permission: PluginPermission,
network_permission: PluginPermission,
client_manager_permission: PluginPermission,
@ -47,11 +51,14 @@ pub(crate) struct PluginEntry {
state: Arc<Mutex<PluginExecutionState>>,
plugin: Plugin,
plugin: Plugin<EventType<'static>>,
}
impl PluginEntry {
pub fn new(plugin: Plugin) -> Arc<PluginEntry> {
impl<T> PluginEntry<T>
where
T: Sync + Send,
{
pub fn new(plugin: Plugin<EventType>) -> Arc<PluginEntry<T>> {
let entry = Arc::new(PluginEntry {
server_permission: PluginPermission::None,
network_permission: PluginPermission::None,
@ -63,7 +70,7 @@ impl PluginEntry {
plugin: plugin.clone(),
});
let entry_ref = entry.clone() as PluginInterface;
let entry_ref = entry.clone() as PluginInterface<T>;
plugin.set_interface(Arc::downgrade(&entry_ref));
entry
@ -134,31 +141,31 @@ impl PluginEntry {
}
}
impl IPluginInterface for PluginEntry {
fn send_event(&self, _event: Event) -> Receiver<EventResult> {
impl<T> IPluginInterface<T> for PluginEntry {
fn send_event(&self, _event: Event<EventType>) -> Receiver<EventResult> {
todo!()
}
}
impl IResponder for PluginEntry {
fn on_event(&self, event: Event) {
impl IResponder<EventType<'_>> for PluginEntry {
fn on_event(&self, event: Event<EventType>) {
use EventType::{ClientAdded, Custom, NewConnection};
use PluginPermission::{None, Read, ReadWrite, Write};
match (
&event.Type,
&event.r#type,
&self.network_permission,
&self.client_manager_permission,
&self.client_permission,
&self.server_permission,
) {
(NewConnection, Read | ReadWrite, _, _, _) => self.plugin.on_event(event),
(ClientAdded, _, Read | ReadWrite, _, _) => self.plugin.on_event(event),
(ClientAdded(id), _, Read | ReadWrite, _, _) => self.plugin.on_event(event),
(Custom("ping"), _, _, _, _) => println!("[PluginEntry:on_event] Ping!"),
_ => println!("[PluginEntry:on_event] not handled"),
};
}
fn get_next(&self) -> Option<Weak<dyn IResponder>> {
fn get_next(&self) -> Option<Weak<dyn IResponder<EventType>>> {
todo!()
}
}

View File

@ -7,9 +7,19 @@ use std::sync::Weak;
use futures::channel::oneshot::Receiver;
pub type WeakPluginInterface = Weak<dyn IPluginInterface>;
pub(crate) type PluginInterface = Arc<dyn IPluginInterface>;
pub type WeakPluginInterface<T>
where
T: Sync + Send,
= Weak<dyn IPluginInterface<T>>;
pub trait IPluginInterface: IResponder + Send + Sync + Debug {
fn send_event(&self, event: Event) -> Receiver<EventResult>;
pub(crate) type PluginInterface<T>
where
T: Sync + Send,
= Arc<dyn IPluginInterface<T>>;
pub trait IPluginInterface<T>: IResponder<T> + Send + Sync + Debug
where
T: Sync + Send,
{
fn send_event(&self, event: Event<T>) -> Receiver<EventResult>;
}

View File

@ -84,7 +84,7 @@ where
.map(|item| item.0)
.map(|item| unsafe {
let lib = Library::new(item.path()).unwrap();
let plugin_fn = lib.get::<GetPluginFn>("get_plugin".as_ref()).unwrap();
let plugin_fn = lib.get::<GetPluginFn<()>>("get_plugin".as_ref()).unwrap();
PluginEntry::new(plugin_fn())
})
.collect();

View File

@ -8,8 +8,7 @@ use tokio::sync::{
Mutex,
};
use crate::plugin::{PluginManager, PluginManagerMessage};
use crate::plugin_manager::PluginManagerMessage;
// use crate::plugin::{PluginManager, PluginManagerMessage};
use crate::{
client_manager::{ClientManager, ClientMgrMessage},
network_manager::{NetworkManager, NetworkManagerMessage},
@ -64,11 +63,11 @@ impl From<ClientMgrMessage> for ServerMessage {
}
}
impl From<PluginManagerMessage> for ServerMessage {
fn from(_: PluginManagerMessage) -> Self {
todo!()
}
}
// impl From<PluginManagerMessage> for ServerMessage {
// fn from(_: PluginManagerMessage) -> Self {
// todo!()
// }
// }
/// # Server
/// authors: @michael-bailey, @Mitch161
@ -84,7 +83,7 @@ impl From<PluginManagerMessage> for ServerMessage {
pub struct Server {
pub client_manager: Arc<ClientManager<ServerMessage>>,
network_manager: Arc<NetworkManager<ServerMessage>>,
plugin_manager: Arc<PluginManager<ServerMessage>>,
// plugin_manager: Arc<PluginManager<ServerMessage>>,
receiver: Mutex<Receiver<ServerMessage>>,
}
@ -96,7 +95,7 @@ impl Server {
let server = Arc::new(Server {
client_manager: ClientManager::new(sender.clone()),
network_manager: NetworkManager::new("0.0.0.0:5600", sender.clone()).await?,
plugin_manager: PluginManager::new(sender),
// plugin_manager: PluginManager::new(sender),
receiver: Mutex::new(receiver),
});
@ -111,7 +110,7 @@ impl Server {
// start client manager and network manager
self.network_manager.clone().start();
self.client_manager.clone().start();
let _ = self.plugin_manager.clone().load().await;
// let _ = self.plugin_manager.clone().load().await;
// clone block items
let server = self.clone();