Merge branch 'feature/lua-support' into develop
This commit is contained in:
commit
fe960a2018
|
|
@ -17,7 +17,7 @@ use uuid::Uuid;
|
|||
* address: the ip address of the connected user.
|
||||
* public_key: the public key used when sending messages to the user.
|
||||
*/
|
||||
#[derive(Deserialize, Serialize, Debug, Clone)]
|
||||
#[derive(Deserialize, Serialize, Debug, Clone, Default)]
|
||||
pub struct ClientDetails {
|
||||
pub uuid: Uuid,
|
||||
pub username: String,
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ tokio = { version = "1.9.0", features = ["full"] }
|
|||
futures = "0.3.16"
|
||||
async-trait = "0.1.52"
|
||||
actix = "0.13"
|
||||
mlua = { version = "0.7.3", features=["lua54", "async", "serde", "macros"] }
|
||||
rhai = {version = "1.7.0"}
|
||||
mlua = { version = "0.8.1", features=["lua54", "async", "serde", "macros", "vendored"] }
|
||||
libloading = "0.7"
|
||||
toml = "0.4.2"
|
||||
aquamarine = "0.1.11"
|
||||
|
|
|
|||
|
|
@ -1,73 +1,18 @@
|
|||
use actix::{Actor, Addr, AsyncContext, Context, Handler, Recipient};
|
||||
use foundation::ClientDetails;
|
||||
use foundation::messages::client::ClientStreamIn;
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use actix::{
|
||||
Actor,
|
||||
Addr,
|
||||
ArbiterHandle,
|
||||
AsyncContext,
|
||||
Context,
|
||||
Handler,
|
||||
Message,
|
||||
MessageResponse,
|
||||
Recipient,
|
||||
Running,
|
||||
WeakAddr,
|
||||
};
|
||||
use foundation::{
|
||||
messages::client::{ClientStreamIn, ClientStreamOut},
|
||||
ClientDetails,
|
||||
};
|
||||
use serde_json::{from_str, to_string};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
client_management::client::ClientObservableMessage::{
|
||||
SendGlobalMessageRequest,
|
||||
SendMessageRequest,
|
||||
UpdateRequest,
|
||||
},
|
||||
network::{
|
||||
Connection,
|
||||
ConnectionMessage,
|
||||
ConnectionMessage::SendData,
|
||||
ConnectionOuput,
|
||||
},
|
||||
prelude::{
|
||||
messages::ObservableMessage,
|
||||
messages::ObservableMessage::{Subscribe, Unsubscribe},
|
||||
},
|
||||
};
|
||||
|
||||
/// Message sent ot the clients delegate
|
||||
#[derive(Message)]
|
||||
#[rtype(result = "()")]
|
||||
pub enum ClientMessage {
|
||||
SendUpdate(Vec<ClientDetails>),
|
||||
SendMessage { from: Uuid, content: String },
|
||||
SendGlobalMessage { from: Uuid, content: String },
|
||||
}
|
||||
|
||||
#[derive(Message)]
|
||||
#[rtype(result = "ClientDetailsResponse")]
|
||||
pub struct ClientDataMessage;
|
||||
|
||||
#[derive(MessageResponse)]
|
||||
pub struct ClientDetailsResponse(pub ClientDetails);
|
||||
use crate::client_management::client::messages::{ClientDataMessage, ClientDataResponse, ClientMessage, ClientObservableMessage};
|
||||
use crate::client_management::client::messages::ClientObservableMessage::{SendGlobalMessageRequest, SendMessageRequest, UpdateRequest};
|
||||
use crate::network::{Connection, ConnectionOuput};
|
||||
use crate::prelude::messages::ObservableMessage;
|
||||
|
||||
/// messages the client will send to itself
|
||||
enum SelfMessage {
|
||||
ReceivedMessage(ClientStreamIn),
|
||||
}
|
||||
|
||||
/// message that is sent to all observers of the current client.
|
||||
#[derive(Message, Clone)]
|
||||
#[rtype(result = "()")]
|
||||
pub enum ClientObservableMessage {
|
||||
SendMessageRequest(WeakAddr<Client>, Uuid, String),
|
||||
SendGlobalMessageRequest(WeakAddr<Client>, String),
|
||||
UpdateRequest(WeakAddr<Client>),
|
||||
}
|
||||
|
||||
/// # Client
|
||||
/// This represents a connected client.
|
||||
/// it will handle received message from a connection.
|
||||
|
|
@ -97,12 +42,13 @@ impl Client {
|
|||
addr: SocketAddr,
|
||||
data: String,
|
||||
) {
|
||||
use ClientStreamIn::{
|
||||
use foundation::messages::client::ClientStreamIn::{
|
||||
Disconnect,
|
||||
SendGlobalMessage,
|
||||
SendMessage,
|
||||
Update,
|
||||
};
|
||||
use serde_json::from_str;
|
||||
let msg = from_str::<ClientStreamIn>(data.as_str())
|
||||
.expect("[Client] failed to decode incoming message");
|
||||
match msg {
|
||||
|
|
@ -161,8 +107,12 @@ impl Actor for Client {
|
|||
|
||||
// tells the client that it has been connected.
|
||||
fn started(&mut self, ctx: &mut Self::Context) {
|
||||
use ClientStreamOut::Connected;
|
||||
use ConnectionMessage::SendData;
|
||||
use foundation::messages::client::ClientStreamOut::Connected;
|
||||
use serde_json::to_string;
|
||||
use foundation::messages::client::ClientStreamOut;
|
||||
use crate::network::ConnectionMessage::SendData;
|
||||
use crate::network::ConnectionOuput;
|
||||
use crate::prelude::messages::ObservableMessage::Subscribe;
|
||||
println!("[Client] started");
|
||||
self.connection
|
||||
.do_send::<ObservableMessage<ConnectionOuput>>(Subscribe(ctx.address().recipient()));
|
||||
|
|
@ -172,8 +122,12 @@ impl Actor for Client {
|
|||
}
|
||||
|
||||
fn stopped(&mut self, ctx: &mut Self::Context) {
|
||||
use ClientStreamOut::Disconnected;
|
||||
use ConnectionMessage::SendData;
|
||||
use foundation::messages::client::ClientStreamOut::Disconnected;
|
||||
use serde_json::to_string;
|
||||
use foundation::messages::client::ClientStreamOut;
|
||||
use crate::network::ConnectionMessage::SendData;
|
||||
use crate::network::ConnectionOuput;
|
||||
use crate::prelude::messages::ObservableMessage::Unsubscribe;
|
||||
self.connection
|
||||
.do_send::<ObservableMessage<ConnectionOuput>>(Unsubscribe(ctx.address().recipient()));
|
||||
self.connection.do_send(SendData(
|
||||
|
|
@ -183,13 +137,16 @@ impl Actor for Client {
|
|||
}
|
||||
|
||||
impl Handler<ClientDataMessage> for Client {
|
||||
type Result = ClientDetailsResponse;
|
||||
type Result = ClientDataResponse;
|
||||
fn handle(
|
||||
&mut self,
|
||||
msg: ClientDataMessage,
|
||||
ctx: &mut Self::Context,
|
||||
) -> Self::Result {
|
||||
ClientDetailsResponse(self.details.clone())
|
||||
match msg {
|
||||
ClientDataMessage::Details => ClientDataResponse::Details(self.details.clone()),
|
||||
_ => todo!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -201,8 +158,11 @@ impl Handler<ClientMessage> for Client {
|
|||
msg: ClientMessage,
|
||||
_ctx: &mut Self::Context,
|
||||
) -> Self::Result {
|
||||
use ClientMessage::{SendGlobalMessage, SendMessage, SendUpdate};
|
||||
use ClientStreamOut::{ConnectedClients, GlobalMessage, UserMessage};
|
||||
use crate::client_management::client::messages::ClientMessage::{SendGlobalMessage, SendMessage, SendUpdate};
|
||||
use foundation::messages::client::ClientStreamOut::{ConnectedClients, GlobalMessage, UserMessage};
|
||||
use serde_json::to_string;
|
||||
use foundation::messages::client::ClientStreamOut;
|
||||
use crate::network::ConnectionMessage::SendData;
|
||||
|
||||
match msg {
|
||||
SendUpdate(clients) => self.connection.do_send(SendData(
|
||||
|
|
@ -236,7 +196,7 @@ impl Handler<ConnectionOuput> for Client {
|
|||
msg: ConnectionOuput,
|
||||
ctx: &mut Self::Context,
|
||||
) -> Self::Result {
|
||||
use ConnectionOuput::RecvData;
|
||||
use crate::network::ConnectionOuput::RecvData;
|
||||
match msg {
|
||||
RecvData(sender, addr, data) => {
|
||||
self.handle_request(ctx, sender, addr, data)
|
||||
|
|
@ -255,7 +215,7 @@ impl Handler<ObservableMessage<ClientObservableMessage>> for Client {
|
|||
msg: ObservableMessage<ClientObservableMessage>,
|
||||
ctx: &mut Self::Context,
|
||||
) -> Self::Result {
|
||||
use ObservableMessage::{Subscribe, Unsubscribe};
|
||||
use crate::prelude::messages::ObservableMessage::{Subscribe, Unsubscribe};
|
||||
match msg {
|
||||
Subscribe(r) => {
|
||||
println!("[Client] adding subscriber");
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
use actix::{WeakAddr, Message, MessageResponse};
|
||||
use uuid::Uuid;
|
||||
use foundation::ClientDetails;
|
||||
use crate::client_management::client::client::Client;
|
||||
|
||||
/// Message sent ot the clients delegate
|
||||
#[derive(Message)]
|
||||
#[rtype(result = "()")]
|
||||
pub enum ClientMessage {
|
||||
SendUpdate(Vec<ClientDetails>),
|
||||
SendMessage { from: Uuid, content: String },
|
||||
SendGlobalMessage { from: Uuid, content: String },
|
||||
}
|
||||
|
||||
#[derive(Message)]
|
||||
#[rtype(result = "ClientDataResponse")]
|
||||
pub enum ClientDataMessage {
|
||||
Details,
|
||||
Uuid,
|
||||
Username,
|
||||
Address,
|
||||
}
|
||||
|
||||
#[derive(MessageResponse)]
|
||||
pub enum ClientDataResponse {
|
||||
Details(ClientDetails),
|
||||
Uuid(Uuid),
|
||||
Username(String),
|
||||
Address(String),
|
||||
}
|
||||
|
||||
/// message that is sent to all observers of the current client.
|
||||
#[derive(Message, Clone)]
|
||||
#[rtype(result = "()")]
|
||||
pub enum ClientObservableMessage {
|
||||
SendMessageRequest(WeakAddr<Client>, Uuid, String),
|
||||
SendGlobalMessageRequest(WeakAddr<Client>, String),
|
||||
UpdateRequest(WeakAddr<Client>),
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
mod messages;
|
||||
mod client;
|
||||
|
||||
pub use messages::*;
|
||||
pub use client::{Client};
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use actix::{
|
||||
fut::{wrap_future, wrap_stream},
|
||||
Actor,
|
||||
ActorFutureExt,
|
||||
ActorStreamExt,
|
||||
|
|
@ -9,6 +8,7 @@ use actix::{
|
|||
ArbiterHandle,
|
||||
AsyncContext,
|
||||
Context,
|
||||
fut::{wrap_future, wrap_stream},
|
||||
Handler,
|
||||
MailboxError,
|
||||
Message,
|
||||
|
|
@ -20,39 +20,23 @@ use actix::{
|
|||
WeakRecipient,
|
||||
};
|
||||
use foundation::{
|
||||
messages::client::{ClientStreamIn, ClientStreamIn::SendGlobalMessage},
|
||||
ClientDetails,
|
||||
messages::client::{ClientStreamIn, ClientStreamIn::SendGlobalMessage},
|
||||
};
|
||||
use futures::{SinkExt, TryStreamExt};
|
||||
use tokio_stream::StreamExt;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
client_management::{
|
||||
client::{
|
||||
ClientDataMessage,
|
||||
ClientMessage,
|
||||
ClientMessage::SendMessage,
|
||||
ClientObservableMessage,
|
||||
},
|
||||
Client,
|
||||
},
|
||||
network::NetworkOutput,
|
||||
prelude::messages::ObservableMessage,
|
||||
};
|
||||
|
||||
#[derive(Message)]
|
||||
#[rtype(result = "()")]
|
||||
pub(crate) enum ClientManagerMessage {
|
||||
AddClient(Uuid, Addr<Client>),
|
||||
RemoveClient(Uuid),
|
||||
}
|
||||
|
||||
#[derive(Message)]
|
||||
#[rtype(result = "()")]
|
||||
pub enum ClientManagerOutput {
|
||||
UpdateRequest(Addr<ClientManager>),
|
||||
}
|
||||
use crate::client_management::client::{Client, ClientDataResponse};
|
||||
use crate::client_management::client::{ClientDataMessage, ClientMessage, ClientObservableMessage};
|
||||
use crate::client_management::client::ClientDataResponse::Details;
|
||||
use crate::client_management::client::ClientMessage::SendMessage;
|
||||
use crate::client_management::messages::{ClientManagerDataMessage, ClientManagerDataResponse, ClientManagerMessage, ClientManagerOutput};
|
||||
use crate::client_management::messages::ClientManagerDataResponse::{ClientCount, Clients};
|
||||
|
||||
pub struct ClientManager {
|
||||
clients: HashMap<Uuid, Addr<Client>>,
|
||||
|
|
@ -60,22 +44,31 @@ pub struct ClientManager {
|
|||
}
|
||||
|
||||
impl ClientManager {
|
||||
pub(crate) fn new(
|
||||
delegate: WeakRecipient<ClientManagerOutput>,
|
||||
) -> Addr<Self> {
|
||||
ClientManager {
|
||||
delegate,
|
||||
clients: HashMap::new(),
|
||||
}
|
||||
.start()
|
||||
}
|
||||
|
||||
pub(crate) fn send_update(
|
||||
&mut self,
|
||||
ctx: &mut Context<Self>,
|
||||
addr: WeakAddr<Client>,
|
||||
) {
|
||||
println!("[ClientManager] sending update to client");
|
||||
use ClientMessage::SendUpdate;
|
||||
use crate::client_management::client::ClientMessage::SendUpdate;
|
||||
let self_addr = ctx.address();
|
||||
if let Some(to_send) = addr.upgrade() {
|
||||
let client_addr: Vec<Addr<Client>> =
|
||||
self.clients.iter().map(|(_, v)| v).cloned().collect();
|
||||
|
||||
let collection = tokio_stream::iter(client_addr)
|
||||
.then(|addr| addr.send(ClientDataMessage))
|
||||
.map(|val| val.unwrap().0)
|
||||
// .filter(|val| )
|
||||
.then(|addr| addr.send(ClientDataMessage::Details))
|
||||
.map(|val| if let Details(details) = val.unwrap() { details } else { ClientDetails::default() })
|
||||
.collect();
|
||||
|
||||
let fut = wrap_future(async move {
|
||||
|
|
@ -99,18 +92,30 @@ impl ClientManager {
|
|||
self.clients.iter().map(|(_, v)| v).cloned().collect();
|
||||
|
||||
let collection = tokio_stream::iter(client_addr)
|
||||
.then(|addr| addr.send(ClientDataMessage))
|
||||
.map(|val| val.unwrap().0)
|
||||
.then(|addr| addr.send(ClientDataMessage::Details))
|
||||
.map(|val| val.unwrap())
|
||||
.map(|val: ClientDataResponse| if let Details(details) = val {
|
||||
details
|
||||
} else {
|
||||
ClientDetails::default()
|
||||
})
|
||||
.collect();
|
||||
|
||||
let fut = wrap_future(async move {
|
||||
if let Some(sender) = sender.upgrade() {
|
||||
let from: Uuid =
|
||||
sender.send(ClientDataMessage).await.unwrap().0.uuid;
|
||||
let details: ClientDataResponse =
|
||||
sender.send(ClientDataMessage::Details).await.unwrap();
|
||||
|
||||
let from = if let Details(details) = details {
|
||||
details.uuid
|
||||
} else {
|
||||
ClientDetails::default().uuid
|
||||
};
|
||||
|
||||
let client_details: Vec<ClientDetails> = collection.await;
|
||||
let pos = client_details.iter().position(|i| i.uuid == from);
|
||||
if let Some(pos) = pos {
|
||||
sender.send(SendMessage { content, from }).await;
|
||||
sender.send(SendMessage { content, from }).await.expect("TODO: panic message");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -124,14 +129,22 @@ impl ClientManager {
|
|||
sender: WeakAddr<Client>,
|
||||
content: String,
|
||||
) {
|
||||
use ClientMessage::SendGlobalMessage;
|
||||
use crate::client_management::client::ClientMessage::SendGlobalMessage;
|
||||
let client_addr: Vec<Addr<Client>> =
|
||||
self.clients.iter().map(|(_, v)| v).cloned().collect();
|
||||
|
||||
if let Some(sender) = sender.upgrade() {
|
||||
let fut = wrap_future(async move {
|
||||
let from: Uuid =
|
||||
sender.send(ClientDataMessage).await.unwrap().0.uuid;
|
||||
|
||||
let details: ClientDataResponse =
|
||||
sender.send(ClientDataMessage::Details).await.unwrap();
|
||||
|
||||
let from = if let Details(details) = details {
|
||||
details.uuid
|
||||
} else {
|
||||
ClientDetails::default().uuid
|
||||
};
|
||||
|
||||
let collection = tokio_stream::iter(client_addr)
|
||||
.then(move |addr| {
|
||||
addr.send(SendGlobalMessage {
|
||||
|
|
@ -145,18 +158,6 @@ impl ClientManager {
|
|||
ctx.spawn(fut);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ClientManager {
|
||||
pub(crate) fn new(
|
||||
delegate: WeakRecipient<ClientManagerOutput>,
|
||||
) -> Addr<Self> {
|
||||
ClientManager {
|
||||
delegate,
|
||||
clients: HashMap::new(),
|
||||
}
|
||||
.start()
|
||||
}
|
||||
|
||||
fn add_client(
|
||||
&mut self,
|
||||
|
|
@ -214,7 +215,7 @@ impl Handler<ClientObservableMessage> for ClientManager {
|
|||
msg: ClientObservableMessage,
|
||||
ctx: &mut Self::Context,
|
||||
) -> Self::Result {
|
||||
use ClientObservableMessage::{
|
||||
use crate::client_management::client::ClientObservableMessage::{
|
||||
SendGlobalMessageRequest,
|
||||
SendMessageRequest,
|
||||
UpdateRequest,
|
||||
|
|
@ -231,3 +232,20 @@ impl Handler<ClientObservableMessage> for ClientManager {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Handler<ClientManagerDataMessage> for ClientManager {
|
||||
type Result = ClientManagerDataResponse;
|
||||
|
||||
fn handle(&mut self, msg: ClientManagerDataMessage, ctx: &mut Self::Context) -> Self::Result {
|
||||
match msg {
|
||||
ClientManagerDataMessage::ClientCount => {
|
||||
ClientCount(self.clients.values().count())
|
||||
}
|
||||
ClientManagerDataMessage::Clients => Clients(
|
||||
self.clients.values()
|
||||
.map(|a| a.downgrade())
|
||||
.collect()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
use actix::{Addr, Message, MessageResponse, WeakAddr};
|
||||
use uuid::Uuid;
|
||||
use crate::client_management::ClientManager;
|
||||
use crate::client_management::client::Client;
|
||||
|
||||
#[derive(Message)]
|
||||
#[rtype(result = "()")]
|
||||
pub(crate) enum ClientManagerMessage {
|
||||
AddClient(Uuid, Addr<Client>),
|
||||
RemoveClient(Uuid),
|
||||
}
|
||||
|
||||
#[derive(Message)]
|
||||
#[rtype(result = "()")]
|
||||
pub(crate) enum ClientManagerOutput {
|
||||
UpdateRequest(Addr<ClientManager>),
|
||||
}
|
||||
|
||||
#[derive(Message)]
|
||||
#[rtype(result = "ClientManagerDataResponse")]
|
||||
pub enum ClientManagerDataMessage {
|
||||
ClientCount,
|
||||
Clients
|
||||
}
|
||||
|
||||
#[derive(MessageResponse)]
|
||||
pub enum ClientManagerDataResponse {
|
||||
ClientCount(usize),
|
||||
Clients(Vec<WeakAddr<Client>>)
|
||||
}
|
||||
|
|
@ -1,9 +1,12 @@
|
|||
mod client;
|
||||
pub mod client;
|
||||
mod client_manager;
|
||||
mod messages;
|
||||
|
||||
pub(crate) use client::Client;
|
||||
pub(crate) use client_manager::{
|
||||
ClientManager,
|
||||
|
||||
pub(crate) use client_manager::ClientManager;
|
||||
pub(crate) use messages::{
|
||||
ClientManagerMessage,
|
||||
ClientManagerOutput,
|
||||
ClientManagerDataMessage,
|
||||
ClientManagerDataResponse,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
use actix::{Actor, Addr};
|
||||
use mlua::Lua;
|
||||
use rhai::{Engine, RegisterNativeFunction, Scope};
|
||||
use crate::client_management::ClientManager;
|
||||
use crate::lua::lua_manager::LuaManager;
|
||||
use crate::network::NetworkManager;
|
||||
use crate::Server;
|
||||
|
||||
pub struct Builder {
|
||||
pub(crate) engine: Lua,
|
||||
pub(super) server: Addr<Server>,
|
||||
pub(super) network_manager: Addr<NetworkManager>,
|
||||
pub(super) client_manager: Addr<ClientManager>,
|
||||
}
|
||||
|
||||
impl Builder {
|
||||
pub(super) fn new(
|
||||
server: Addr<Server>,
|
||||
network_manager: Addr<NetworkManager>,
|
||||
client_manager: Addr<ClientManager>,
|
||||
) -> Self {
|
||||
Builder {
|
||||
engine: Lua::new(),
|
||||
server,
|
||||
network_manager,
|
||||
client_manager,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn build(self) -> Addr<LuaManager> {
|
||||
Addr::from(self)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
use std::sync::Arc;
|
||||
use mlua::prelude::LuaUserData;
|
||||
use mlua::{UserDataFields, UserDataMethods};
|
||||
use crate::client::Client;
|
||||
use crate::messages::ClientMessage;
|
||||
|
||||
pub struct ClientLua<Out: 'static>(pub Arc<Client<Out>>)
|
||||
where
|
||||
Out: From<ClientMessage> + Send;
|
||||
|
||||
impl<Out> ClientLua<Out>
|
||||
where
|
||||
Out: From<ClientMessage> + Send
|
||||
{
|
||||
pub fn new(client: Arc<Client<Out>>) -> Self {
|
||||
ClientLua(client)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Out: 'static> LuaUserData for ClientLua<Out>
|
||||
where
|
||||
Out: From<ClientMessage> + Send
|
||||
{
|
||||
fn add_fields<'lua, F: UserDataFields<'lua, Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("uuid", |_lua, this| {
|
||||
Ok(this.0.details.uuid.to_string())
|
||||
});
|
||||
|
||||
fields.add_field_method_get("username", |_lua, this| {
|
||||
Ok(this.0.details.username.to_string())
|
||||
});
|
||||
|
||||
fields.add_field_method_get("address", |_lua, this| {
|
||||
Ok(this.0.details.address.to_string())
|
||||
});
|
||||
}
|
||||
|
||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(_methods: &mut M) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use mlua::{Function, MetaMethod, Nil, ToLua, UserDataFields, UserDataMethods};
|
||||
use mlua::prelude::LuaUserData;
|
||||
use uuid::Uuid;
|
||||
use crate::client_manager::{ClientManager, ClientMgrMessage};
|
||||
use crate::lua::ClientLua;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ClientManagerLua<'lua, Out: 'static>(pub Arc<ClientManager<Out>>, pub Vec<Function<'lua>>)
|
||||
where
|
||||
Out: From<ClientMgrMessage> + Send;
|
||||
|
||||
impl<Out: 'static> ClientManagerLua<'_, Out>
|
||||
where
|
||||
Out: From<ClientMgrMessage> + Send
|
||||
{
|
||||
pub fn new(manager: Arc<ClientManager<Out>>) -> Self {
|
||||
ClientManagerLua(manager, Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl<Out: 'static> LuaUserData for ClientManagerLua<'_, Out>
|
||||
where
|
||||
Out: From<ClientMgrMessage> + Clone + Send
|
||||
{
|
||||
fn add_fields<'lua, F: UserDataFields<'lua, Self>>(fields: &mut F) {
|
||||
|
||||
}
|
||||
|
||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
methods.add_async_method("getCount", |_lua,this,()| {
|
||||
let this = this.0.clone();
|
||||
async move {
|
||||
Ok(this.clients.lock().await.len())
|
||||
}
|
||||
});
|
||||
|
||||
methods.add_async_method("getClientList", |_lua,this,()| {
|
||||
let this = this.0.clone();
|
||||
async move {
|
||||
let clients = this.clients.lock().await;
|
||||
let clients: Vec<ClientLua<ClientMgrMessage>> = clients.iter()
|
||||
.map(|(_id,c)| ClientLua::new(c.clone()))
|
||||
.collect();
|
||||
Ok(clients)
|
||||
}
|
||||
});
|
||||
|
||||
methods.add_async_meta_method(MetaMethod::Index, |lua, this, (index): (String)| {
|
||||
let manager = this.0.clone();
|
||||
async move {
|
||||
if let Ok(id) = Uuid::from_str(&index) {
|
||||
let map = manager.clients.lock().await;
|
||||
if let Some(found) = map.get(&id) {
|
||||
return Ok(ClientLua::new(found.clone()).to_lua(lua)?);
|
||||
}
|
||||
}
|
||||
return Ok(Nil);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
//! # lua_manager.rs
|
||||
//!
|
||||
//! Holds the LuaManger struct and implements it's methods
|
||||
|
||||
use actix::{Actor, Addr, ArbiterHandle, AsyncContext, Context, Running};
|
||||
use actix::fut::wrap_future;
|
||||
use mlua::{Lua, Thread, ThreadStatus};
|
||||
use rhai::{Engine, Func, Scope};
|
||||
use crate::client_management::ClientManager;
|
||||
use crate::lua::builder::Builder;
|
||||
use crate::network::NetworkManager;
|
||||
use crate::scripting::scriptable_server::ScriptableServer;
|
||||
use crate::Server;
|
||||
|
||||
/// # LuaManager
|
||||
/// Holds common server objects
|
||||
/// todo: change to weak references
|
||||
pub struct LuaManager {
|
||||
pub(super) server: Addr<Server>,
|
||||
pub(super) network_manager: Addr<NetworkManager>,
|
||||
pub(super) client_manager: Addr<ClientManager>,
|
||||
}
|
||||
|
||||
impl LuaManager {
|
||||
pub fn create(
|
||||
server: Addr<Server>,
|
||||
network_manager: Addr<NetworkManager>,
|
||||
client_manager: Addr<ClientManager>
|
||||
) -> Builder {
|
||||
Builder::new(
|
||||
server,
|
||||
network_manager,
|
||||
client_manager
|
||||
)
|
||||
}
|
||||
|
||||
fn create_lua(&self) -> Lua {
|
||||
let engine = Lua::new();
|
||||
let server = ScriptableServer::from(self.server.clone());
|
||||
|
||||
let api = engine.create_table().unwrap();
|
||||
api.set::<&str, ScriptableServer>("server", server).unwrap();
|
||||
|
||||
engine.globals().set("chat", api).unwrap();
|
||||
engine
|
||||
}
|
||||
}
|
||||
|
||||
impl Actor for LuaManager {
|
||||
type Context = Context<Self>;
|
||||
|
||||
fn started(&mut self, ctx: &mut Self::Context) {
|
||||
let engine = self.create_lua();
|
||||
|
||||
ctx.spawn(wrap_future(async move {
|
||||
let coroutine: Thread = engine.load(r#"
|
||||
coroutine.create(function ()
|
||||
print("hello lua")
|
||||
print(chat.server:name())
|
||||
end)
|
||||
"#).eval().unwrap();
|
||||
let coroutine = coroutine.into_async::<(),()>(());
|
||||
coroutine.await.expect("TODO: panic message");
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
// by implementing it for the addr type,
|
||||
// we enforce the actor model on the consumer of the api.
|
||||
impl From<Builder> for Addr<LuaManager> {
|
||||
fn from(b: Builder) -> Addr<LuaManager> {
|
||||
LuaManager {
|
||||
server: b.server,
|
||||
network_manager: b.network_manager,
|
||||
client_manager: b.client_manager
|
||||
}.start()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,4 @@
|
|||
mod client_lua;
|
||||
mod client_manager_lua;
|
||||
mod server_lua;
|
||||
mod lua_manager;
|
||||
mod builder;
|
||||
|
||||
pub use client_lua::ClientLua;
|
||||
pub use client_manager_lua::ClientManagerLua;
|
||||
pub use server_lua::ServerLua;
|
||||
pub use lua_manager::LuaManager;
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
use std::sync::Arc;
|
||||
use mlua::prelude::LuaUserData;
|
||||
use mlua::{UserDataFields, UserDataMethods};
|
||||
use crate::lua::ClientManagerLua;
|
||||
use crate::Server;
|
||||
|
||||
/// # ServerLua
|
||||
/// A wrapper struct for making the Server lua scriptable.
|
||||
///
|
||||
/// # Attributes
|
||||
/// - 1: A reference to the server.
|
||||
#[derive(Clone)]
|
||||
pub struct ServerLua(Arc<Server>);
|
||||
|
||||
impl ServerLua {
|
||||
pub fn new(server: Arc<Server>) -> Self {
|
||||
ServerLua(server)
|
||||
}
|
||||
}
|
||||
|
||||
impl LuaUserData for ServerLua {
|
||||
fn add_fields<'lua, F: UserDataFields<'lua, Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("ClientManager", |lua,this| {
|
||||
println!("Getting count");
|
||||
Ok(ClientManagerLua(this.0.client_manager.clone(), vec![]))
|
||||
});
|
||||
fields.add_field_method_get("NetworkManager", |lua,this| {
|
||||
Ok("unimplemented")
|
||||
});
|
||||
fields.add_field_method_get("address", |lua,this| {
|
||||
Ok("unimplemented")
|
||||
});
|
||||
}
|
||||
|
||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(_methods: &mut M) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,9 @@ pub(crate) mod server;
|
|||
pub(crate) mod client_management;
|
||||
pub(crate) mod network;
|
||||
pub(crate) mod prelude;
|
||||
pub(crate) mod rhai;
|
||||
pub(crate) mod lua;
|
||||
pub(crate) mod scripting;
|
||||
|
||||
use std::env::args;
|
||||
use server::Server;
|
||||
|
|
|
|||
|
|
@ -38,5 +38,7 @@ use listener::{ListenerMessage, ListenerOutput, NetworkListener};
|
|||
pub(crate) use network_manager::{
|
||||
NetworkManager,
|
||||
NetworkOutput,
|
||||
NetworkMessage
|
||||
NetworkMessage,
|
||||
NetworkDataMessage,
|
||||
NetworkDataOutput
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use actix::Addr;
|
||||
use foundation::ClientDetails;
|
||||
use crate::network::Connection;
|
||||
use actix::Message;
|
||||
use actix::{Message, MessageResponse};
|
||||
|
||||
#[derive(Message, Debug, Ord, PartialOrd, Eq, PartialEq)]
|
||||
#[rtype(result = "()")]
|
||||
|
|
@ -15,4 +15,15 @@ pub enum NetworkMessage {
|
|||
pub enum NetworkOutput {
|
||||
NewClient(Addr<Connection>, ClientDetails),
|
||||
InfoRequested(Addr<Connection>),
|
||||
}
|
||||
|
||||
#[derive(Message, Debug, Ord, PartialOrd, Eq, PartialEq)]
|
||||
#[rtype(result = "()")]
|
||||
pub enum NetworkDataMessage {
|
||||
IsListening
|
||||
}
|
||||
|
||||
#[derive(MessageResponse)]
|
||||
pub enum NetworkDataOutput {
|
||||
IsListening(bool),
|
||||
}
|
||||
|
|
@ -10,4 +10,4 @@ mod config;
|
|||
use config::*;
|
||||
pub(crate) use network_manager::{NetworkManager};
|
||||
pub(crate) use builder::*;
|
||||
pub(crate) use messages::{NetworkMessage,NetworkOutput};
|
||||
pub(crate) use messages::{NetworkMessage, NetworkOutput, NetworkDataMessage, NetworkDataOutput};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use actix::{Actor, Addr, AsyncContext, Context, Handler, WeakRecipient};
|
||||
use foundation::ClientDetails;
|
||||
use crate::network::{Connection, ConnectionInitiator, InitiatorOutput};
|
||||
use crate::network::{Connection, ConnectionInitiator, InitiatorOutput, NetworkDataMessage, NetworkDataOutput};
|
||||
use crate::network::listener::{ListenerMessage, ListenerOutput};
|
||||
use crate::network::listener::NetworkListener;
|
||||
use crate::network::network_manager::Builder;
|
||||
|
|
@ -135,6 +135,16 @@ impl Handler<NetworkMessage> for NetworkManager {
|
|||
}
|
||||
}
|
||||
|
||||
impl Handler<NetworkDataMessage> for NetworkManager {
|
||||
type Result = ();
|
||||
|
||||
fn handle(&mut self, msg: NetworkDataMessage, ctx: &mut Self::Context) -> Self::Result {
|
||||
match msg {
|
||||
NetworkDataMessage::IsListening => NetworkDataOutput::IsListening(if self.)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Handler<ListenerOutput> for NetworkManager {
|
||||
type Result = ();
|
||||
fn handle(
|
||||
|
|
|
|||
|
|
@ -7,12 +7,13 @@ pub mod actors {
|
|||
//! exports all actors used in the program.
|
||||
pub use crate::server::Server;
|
||||
pub(crate) use crate::network::{Connection, ConnectionInitiator, NetworkManager};
|
||||
pub(crate) use crate::client_management::{Client,ClientManager};
|
||||
pub(crate) use crate::client_management::ClientManager;
|
||||
pub(crate) use crate::client_management::client::Client;
|
||||
}
|
||||
pub mod messages {
|
||||
//! exports all messages used in the program.
|
||||
pub(crate) use super::observer::ObservableMessage;
|
||||
pub(crate) use crate::network::{NetworkMessage,NetworkOutput,ConnectionMessage,ConnectionOuput};
|
||||
pub(crate) use crate::client_management::{ClientManagerOutput,ClientManagerMessage};
|
||||
pub(crate) use crate::network::{ConnectionMessage, ConnectionOuput, NetworkMessage, NetworkOutput};
|
||||
pub(crate) use crate::client_management::{ClientManagerMessage, ClientManagerOutput};
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
use actix::{Actor, Addr};
|
||||
use mlua::Lua;
|
||||
use rhai::{Engine, RegisterNativeFunction, Scope};
|
||||
use crate::client_management::ClientManager;
|
||||
use crate::rhai::rhai_manager::RhaiManager;
|
||||
use crate::network::NetworkManager;
|
||||
use crate::Server;
|
||||
|
||||
pub struct Builder {
|
||||
engine: Engine,
|
||||
server: Addr<Server>,
|
||||
network_manager: Addr<NetworkManager>,
|
||||
client_manager: Addr<ClientManager>,
|
||||
scope: Scope<'static>,
|
||||
}
|
||||
|
||||
impl Builder {
|
||||
pub(super) fn new(
|
||||
server: Addr<Server>,
|
||||
network_manager: Addr<NetworkManager>,
|
||||
client_manager: Addr<ClientManager>,
|
||||
) -> Self {
|
||||
Builder {
|
||||
engine: Engine::new(),
|
||||
server,
|
||||
network_manager,
|
||||
client_manager,
|
||||
scope: Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scope_object<T: 'static>(mut self, name: &str, obj: T) -> Self
|
||||
where
|
||||
T: Clone {
|
||||
self.engine.register_type::<T>();
|
||||
self.scope.set_value(name, obj);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn scope_fn<F, A>(mut self, name: &str, func: F ) -> Self
|
||||
where
|
||||
F: RegisterNativeFunction<A, ()>
|
||||
{
|
||||
self.engine.register_fn(name, func);
|
||||
self
|
||||
}
|
||||
|
||||
|
||||
pub(crate) fn build(self) -> Addr<RhaiManager> {
|
||||
RhaiManager {
|
||||
engine: self.engine,
|
||||
scope: self.scope,
|
||||
server: self.server,
|
||||
network_manager: self.network_manager,
|
||||
client_manager: self.client_manager
|
||||
}.start()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
mod rhai_manager;
|
||||
mod builder;
|
||||
|
||||
pub use rhai_manager::RhaiManager;
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
use actix::{Actor, Addr, ArbiterHandle, AsyncContext, Context, Running};
|
||||
use actix::fut::wrap_future;
|
||||
use rhai::{Engine, Func, Scope};
|
||||
use crate::client_management::ClientManager;
|
||||
use crate::rhai::builder::Builder;
|
||||
use crate::network::NetworkManager;
|
||||
use crate::Server;
|
||||
|
||||
pub struct RhaiManager {
|
||||
pub(super) engine: Engine,
|
||||
pub(super) scope: Scope<'static>,
|
||||
pub(super) server: Addr<Server>,
|
||||
pub(super) network_manager: Addr<NetworkManager>,
|
||||
pub(super) client_manager: Addr<ClientManager>,
|
||||
}
|
||||
|
||||
impl RhaiManager {
|
||||
pub fn create(
|
||||
server: Addr<Server>,
|
||||
network_manager: Addr<NetworkManager>,
|
||||
client_manager: Addr<ClientManager>
|
||||
) -> Builder {
|
||||
Builder::new(server.clone(), network_manager.clone(), client_manager.clone())
|
||||
.scope_object("server", server)
|
||||
}
|
||||
}
|
||||
|
||||
impl Actor for RhaiManager {
|
||||
type Context = Context<Self>;
|
||||
|
||||
fn started(&mut self, ctx: &mut Self::Context) {
|
||||
self.engine.run(r#"
|
||||
print("hello rhai")
|
||||
"#).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
pub(crate) mod scriptable_server;
|
||||
pub(crate) mod scriptable_network_manager;
|
||||
pub(crate) mod scriptable_client_manager;
|
||||
pub(crate) mod scriptable_client;
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
use actix::Addr;
|
||||
use mlua::{Error, UserData, UserDataFields, UserDataMethods};
|
||||
use crate::client_management::client::Client;
|
||||
use crate::client_management::client::{ClientDataMessage, ClientDataResponse};
|
||||
use crate::client_management::client::ClientDataResponse::{Username, Uuid};
|
||||
use crate::server::ServerDataResponse::Name;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct ScriptableClient {
|
||||
addr: Addr<Client>
|
||||
}
|
||||
|
||||
impl UserData for ScriptableClient {
|
||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
methods.add_async_method("username", |_lua, obj, ()| async move {
|
||||
let name: Option<ClientDataResponse> = obj.addr.send(ClientDataMessage::Username).await.ok();
|
||||
if let Some(Username(name)) = name {
|
||||
Ok(name)
|
||||
} else {
|
||||
Err(Error::RuntimeError("Name returned null or other value".to_string()))
|
||||
}
|
||||
});
|
||||
|
||||
methods.add_async_method("uuid", |_lua, obj, ()| async move {
|
||||
let uuid: Option<ClientDataResponse> = obj.addr.send(ClientDataMessage::Uuid).await.ok();
|
||||
if let Some(Uuid(uuid)) = uuid {
|
||||
Ok(uuid.to_string())
|
||||
} else {
|
||||
Err(Error::RuntimeError("Uuid returned null or other value".to_string()))
|
||||
}
|
||||
});
|
||||
|
||||
methods.add_async_method("address", |_lua, obj, ()| async move {
|
||||
let address: Option<ClientDataResponse> = obj.addr.send(ClientDataMessage::Address).await.ok();
|
||||
if let Some(Username(address)) = address {
|
||||
Ok(address)
|
||||
} else {
|
||||
Err(Error::RuntimeError("address returned null or other value".to_string()))
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Addr<Client>> for ScriptableClient {
|
||||
fn from(addr: Addr<Client>) -> Self {
|
||||
Self {
|
||||
addr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
use actix::{ActorStreamExt, Addr};
|
||||
use mlua::{Error, UserData, UserDataFields, UserDataMethods};
|
||||
use crate::client_management::{ClientManager, ClientManagerDataMessage};
|
||||
use crate::client_management::ClientManagerDataResponse::Clients;
|
||||
use crate::scripting::scriptable_client::ScriptableClient;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct ScriptableClientManager {
|
||||
addr: Addr<ClientManager>
|
||||
}
|
||||
|
||||
impl UserData for ScriptableClientManager {
|
||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
methods.add_async_method("clients", |lua, obj, ()| async move {
|
||||
let res = obj.addr.send(ClientManagerDataMessage::Clients).await;
|
||||
if let Ok(Clients(clients)) = res {
|
||||
|
||||
let clients: Vec<ScriptableClient> = clients.into_iter()
|
||||
.map(|a| a.upgrade())
|
||||
.filter(|o| o.is_some())
|
||||
.map(|o| o.unwrap())
|
||||
.map(|a| ScriptableClient::from(a))
|
||||
.collect();
|
||||
|
||||
Ok(clients)
|
||||
} else {
|
||||
Err(Error::RuntimeError("clients returned null or other value".to_string()))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Addr<ClientManager>> for ScriptableClientManager {
|
||||
fn from(addr: Addr<ClientManager>) -> Self {
|
||||
Self {
|
||||
addr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
use actix::Addr;
|
||||
use mlua::{Error, UserData, UserDataMethods};
|
||||
use crate::network::{NetworkDataMessage, NetworkManager};
|
||||
use crate::network::NetworkDataOutput::IsListening;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct ScriptableNetworkManager {
|
||||
addr: Addr<NetworkManager>
|
||||
}
|
||||
|
||||
impl UserData for ScriptableNetworkManager {
|
||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
methods.add_async_method("Listening", |_lua, obj, ()| async move {
|
||||
let is_listening = obj.addr.send(NetworkDataMessage::IsListening).await.ok();
|
||||
if let Some(IsListening(is_listening)) = is_listening {
|
||||
Ok(is_listening)
|
||||
} else {
|
||||
Err(Error::RuntimeError("Uuid returned null or other value".to_string()))
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Addr<NetworkManager>> for ScriptableNetworkManager {
|
||||
fn from(addr: Addr<NetworkManager>) -> Self {
|
||||
Self {
|
||||
addr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
use actix::Addr;
|
||||
use mlua::{Error, UserData, UserDataFields, UserDataMethods};
|
||||
use crate::scripting::scriptable_client_manager::ScriptableClientManager;
|
||||
use crate::scripting::scriptable_network_manager::ScriptableNetworkManager;
|
||||
|
||||
use crate::server::*;
|
||||
use crate::server::ServerDataResponse::{ClientManager, Name, NetworkManager, Owner, Port};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct ScriptableServer {
|
||||
pub(super) addr: Addr<Server>
|
||||
}
|
||||
|
||||
impl UserData for ScriptableServer {
|
||||
|
||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
methods.add_async_method("name", |_lua, obj, ()| async move {
|
||||
let name: Option<ServerDataResponse> = obj.addr.send(ServerDataMessage::Name).await.ok();
|
||||
if let Some(Name(name)) = name {
|
||||
Ok(name)
|
||||
} else {
|
||||
Err(Error::RuntimeError("Name returned null or other value".to_string()))
|
||||
}
|
||||
});
|
||||
|
||||
methods.add_async_method("port", |_lua, obj, ()| async move {
|
||||
let port: Option<ServerDataResponse> = obj.addr.send(ServerDataMessage::Port).await.ok();
|
||||
if let Some(Port(name)) = port {
|
||||
Ok(name)
|
||||
} else {
|
||||
Err(Error::RuntimeError("Name returned null or other value".to_string()))
|
||||
}
|
||||
});
|
||||
|
||||
methods.add_async_method("owner", |_lua, obj, ()| async move {
|
||||
let owner: Option<ServerDataResponse> = obj.addr.send(ServerDataMessage::Owner).await.ok();
|
||||
if let Some(Owner(name)) = owner {
|
||||
Ok(name)
|
||||
} else {
|
||||
Err(Error::RuntimeError("Name returned null or other value".to_string()))
|
||||
}
|
||||
});
|
||||
|
||||
methods.add_async_method("client_manager", |_lua, obj, ()| async move {
|
||||
let name: Option<ServerDataResponse> = obj.addr.send(ServerDataMessage::ClientManager).await.ok();
|
||||
if let Some(ClientManager(Some(cm))) = name {
|
||||
Ok(ScriptableClientManager::from(cm))
|
||||
} else {
|
||||
Err(Error::RuntimeError("Name returned null or other value".to_string()))
|
||||
}
|
||||
});
|
||||
|
||||
methods.add_async_method("network_manager", |_lua, obj, ()| async move {
|
||||
let name: Option<ServerDataResponse> = obj.addr.send(ServerDataMessage::NetworkManager).await.ok();
|
||||
if let Some(NetworkManager(Some(nm))) = name {
|
||||
Ok(ScriptableNetworkManager::from(nm))
|
||||
} else {
|
||||
Err(Error::RuntimeError("Name returned null or other value".to_string()))
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Addr<Server>> for ScriptableServer {
|
||||
fn from(addr: Addr<Server>) -> Self {
|
||||
Self {
|
||||
addr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ pub struct ServerBuilder {
|
|||
pub(super) owner: Option<String>,
|
||||
}
|
||||
|
||||
impl ServerBuilder {
|
||||
impl<'rhai> ServerBuilder {
|
||||
pub(super) fn new() -> Self {
|
||||
Self {
|
||||
name: None,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
use actix::{Addr, Message, MessageResponse};
|
||||
use crate::client_management::ClientManager;
|
||||
use crate::network::NetworkManager;
|
||||
|
||||
|
||||
#[derive(Message, Clone)]
|
||||
#[rtype(result = "ServerDataResponse")]
|
||||
pub enum ServerDataMessage {
|
||||
Name,
|
||||
Port,
|
||||
Owner,
|
||||
ClientManager,
|
||||
NetworkManager,
|
||||
}
|
||||
|
||||
#[derive(MessageResponse, Clone)]
|
||||
pub enum ServerDataResponse {
|
||||
Name(String),
|
||||
Port(u16),
|
||||
Owner(String),
|
||||
ClientManager(Option<Addr<ClientManager>>),
|
||||
NetworkManager(Option<Addr<NetworkManager>>),
|
||||
}
|
||||
|
|
@ -6,7 +6,9 @@
|
|||
mod server;
|
||||
mod config;
|
||||
mod builder;
|
||||
mod messages;
|
||||
|
||||
use config::ServerConfig;
|
||||
pub use server::Server;
|
||||
pub(crate) use builder::ServerBuilder;
|
||||
pub use builder::ServerBuilder;
|
||||
pub use messages::*;
|
||||
|
|
@ -1,13 +1,21 @@
|
|||
//! This crate holds the implementations and functions for the server
|
||||
//! including server boot procedures
|
||||
|
||||
use actix::{Actor, ActorFutureExt, Addr, AsyncContext, Context, ContextFutureSpawner, Handler};
|
||||
use actix::dev::MessageResponse;
|
||||
use actix::fut::wrap_future;
|
||||
use mlua::Lua;
|
||||
use foundation::ClientDetails;
|
||||
use foundation::messages::network::NetworkSockOut::GotInfo;
|
||||
use crate::client_management::{Client, ClientManager, ClientManagerOutput};
|
||||
use crate::client_management::{ClientManager, ClientManagerOutput};
|
||||
use crate::client_management::client::Client;
|
||||
use crate::client_management::ClientManagerMessage::AddClient;
|
||||
use crate::lua::LuaManager;
|
||||
use crate::rhai::RhaiManager;
|
||||
use crate::network::{Connection, NetworkManager, NetworkMessage, NetworkOutput};
|
||||
use crate::network::ConnectionMessage::{CloseConnection, SendData};
|
||||
use crate::network::NetworkOutput::{InfoRequested, NewClient};
|
||||
use crate::server::{builder, ServerBuilder};
|
||||
use crate::server::{builder, ServerBuilder, ServerDataMessage, ServerDataResponse};
|
||||
use crate::server::config::ServerConfig;
|
||||
|
||||
/// This struct is the main actor of the server.
|
||||
|
|
@ -16,18 +24,11 @@ pub struct Server {
|
|||
config: ServerConfig,
|
||||
network_manager: Option<Addr<NetworkManager>>,
|
||||
client_management: Option<Addr<ClientManager>>,
|
||||
rhai_manager: Option<Addr<RhaiManager>>,
|
||||
lua_manager: Option<Addr<LuaManager>>
|
||||
}
|
||||
|
||||
impl Server {
|
||||
pub(crate) fn new() -> Addr<Self> {
|
||||
Server {
|
||||
config: Default::default(),
|
||||
network_manager: None,
|
||||
client_management: None,
|
||||
}
|
||||
.start()
|
||||
}
|
||||
|
||||
pub fn create() -> builder::ServerBuilder {
|
||||
ServerBuilder::new()
|
||||
}
|
||||
|
|
@ -75,11 +76,20 @@ impl Actor for Server {
|
|||
let nm = NetworkManager::create(addr.clone().recipient())
|
||||
.port(self.config.port)
|
||||
.build();
|
||||
self.network_manager.replace(nm);
|
||||
self.network_manager.replace(nm.clone());
|
||||
|
||||
self.client_management.replace(ClientManager::new(
|
||||
let cm = ClientManager::new(
|
||||
addr.clone().recipient(),
|
||||
));
|
||||
);
|
||||
self.client_management.replace(cm.clone());
|
||||
|
||||
let rm = RhaiManager::create(ctx.address(), nm.clone(), cm.clone())
|
||||
.build();
|
||||
self.rhai_manager.replace(rm);
|
||||
|
||||
let lm = LuaManager::create(ctx.address(), nm, cm)
|
||||
.build();
|
||||
self.lua_manager.replace(lm);
|
||||
|
||||
if let Some(net_mgr) = self.network_manager.as_ref() {
|
||||
net_mgr.do_send(NetworkMessage::StartListening);
|
||||
|
|
@ -87,6 +97,21 @@ impl Actor for Server {
|
|||
}
|
||||
}
|
||||
|
||||
impl Handler<ServerDataMessage> for Server {
|
||||
type Result = ServerDataResponse;
|
||||
|
||||
fn handle(&mut self, msg: ServerDataMessage, ctx: &mut Self::Context) -> Self::Result {
|
||||
println!("data message");
|
||||
match msg {
|
||||
ServerDataMessage::Name => ServerDataResponse::Name(self.config.name.clone()),
|
||||
ServerDataMessage::Port => ServerDataResponse::Port(self.config.port.clone()),
|
||||
ServerDataMessage::Owner => ServerDataResponse::Owner(self.config.owner.clone()),
|
||||
ServerDataMessage::ClientManager => ServerDataResponse::ClientManager(self.client_management.clone()),
|
||||
ServerDataMessage::NetworkManager => ServerDataResponse::NetworkManager(self.network_manager.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Handler<NetworkOutput> for Server {
|
||||
type Result = ();
|
||||
fn handle(
|
||||
|
|
@ -118,7 +143,7 @@ impl Handler<ClientManagerOutput> for Server {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<builder::ServerBuilder> for Server {
|
||||
impl From<ServerBuilder> for Server {
|
||||
fn from(builder: ServerBuilder) -> Self {
|
||||
Server {
|
||||
config: ServerConfig {
|
||||
|
|
@ -127,7 +152,9 @@ impl From<builder::ServerBuilder> for Server {
|
|||
owner: builder.owner.unwrap_or_else(|| "Default owner".to_string()),
|
||||
},
|
||||
network_manager: None,
|
||||
client_management: None
|
||||
client_management: None,
|
||||
rhai_manager: None,
|
||||
lua_manager: None
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue