Skip to content

Commit 2125bd6

Browse files
committed
feat[transfer]: add logic for handling transfers and resolving them
1 parent 1738d96 commit 2125bd6

File tree

8 files changed

+175
-60
lines changed

8 files changed

+175
-60
lines changed

controller/src/controller.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl Controller {
6767
let nodes = Nodes::load_all(&drivers);
6868
let groups = Groups::load_all(&nodes);
6969
let servers = Servers::new(handle.clone());
70-
let users = Users::new(/*handle.clone()*/);
70+
let users = Users::new(handle.clone());
7171
let event_bus = EventBus::new(/*handle.clone()*/);
7272
Self {
7373
handle: handle.clone(),

controller/src/controller/event.rs

Lines changed: 13 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
use channel::ChannelMessageSended;
21
use colored::Colorize;
32
use log::debug;
3+
use uuid::Uuid;
44

55
use super::server::{ServerHandle, WeakServerHandle};
6-
use crate::network::server::proto::ChannelMessage;
76

87
use std::{
98
any::{Any, TypeId},
@@ -14,10 +13,12 @@ use std::{
1413
};
1514

1615
pub mod channel;
16+
pub mod transfer;
1717

1818
#[derive(Eq, PartialEq)]
1919
pub enum EventKey {
2020
Channel(String),
21+
Transfer(Uuid),
2122
Custom(TypeId),
2223
}
2324

@@ -54,7 +55,7 @@ impl EventBus {
5455
.push(registered_listener);
5556
}
5657

57-
pub fn register_listener_with_server<E: Event>(
58+
pub fn register_listener_under_server<E: Event>(
5859
&self,
5960
key: EventKey,
6061
server: WeakServerHandle,
@@ -108,12 +109,12 @@ impl EventBus {
108109
}
109110
}
110111

111-
pub fn dispatch<E: Event>(&self, event: &E) -> u32 {
112+
pub fn dispatch<E: Event>(&self, key: &EventKey, event: &E) -> u32 {
112113
debug!("[{}] Dispatching event: {:?}", "EVENTS".blue(), event);
113114

114115
let mut count = 0;
115116
let listeners = self.listeners.lock().unwrap();
116-
if let Some(registered_listeners) = listeners.get(&EventKey::Custom(TypeId::of::<E>())) {
117+
if let Some(registered_listeners) = listeners.get(key) {
117118
for registered_listener in registered_listeners {
118119
if let Some(listener) = registered_listener
119120
.listener
@@ -127,30 +128,8 @@ impl EventBus {
127128
count
128129
}
129130

130-
pub fn dispatch_channel_message(&self, message: ChannelMessage) -> u32 {
131-
debug!(
132-
"[{}] Dispatching channel message: {:?}",
133-
"EVENTS".blue(),
134-
message
135-
);
136-
137-
let mut count = 0;
138-
let listeners = self.listeners.lock().unwrap();
139-
if let Some(registered_listeners) =
140-
listeners.get(&EventKey::Channel(message.channel.clone()))
141-
{
142-
let event = ChannelMessageSended { message };
143-
for registered_listener in registered_listeners {
144-
if let Some(listener) = registered_listener
145-
.listener
146-
.downcast_ref::<EventListener<ChannelMessageSended>>()
147-
{
148-
listener(&event);
149-
count += 1;
150-
}
151-
}
152-
}
153-
count
131+
pub fn dispatch_custom<E: Event>(&self, event: &E) -> u32 {
132+
self.dispatch(&EventKey::Custom(TypeId::of::<E>()), event)
154133
}
155134
}
156135

@@ -161,8 +140,12 @@ impl Hash for EventKey {
161140
state.write_u8(0);
162141
channel.hash(state);
163142
}
164-
EventKey::Custom(type_id) => {
143+
EventKey::Transfer(server) => {
165144
state.write_u8(1);
145+
server.hash(state);
146+
}
147+
EventKey::Custom(type_id) => {
148+
state.write_u8(2);
166149
type_id.hash(state);
167150
}
168151
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
use crate::controller::user::transfer::Transfer;
2+
3+
use super::Event;
4+
5+
#[derive(Debug)]
6+
pub struct UserTransferRequested {
7+
pub transfer: Transfer,
8+
}
9+
10+
impl Event for UserTransferRequested {}

controller/src/controller/group.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,16 @@ impl Group {
234234
true
235235
});
236236
}
237+
238+
pub fn get_free_server(&self) -> Option<ServerHandle> {
239+
let servers = self.servers.lock().expect("Failed to lock servers");
240+
for server in servers.iter() {
241+
if let GroupedServer::Active(server) = server {
242+
return Some(server.clone());
243+
}
244+
}
245+
None
246+
}
237247
}
238248

239249
mod shared {

controller/src/controller/user.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::{
22
collections::HashMap,
3+
ops::Deref,
34
sync::{Arc, Mutex, Weak},
45
};
56

@@ -8,7 +9,10 @@ use log::{debug, info};
89
use transfer::Transfer;
910
use uuid::Uuid;
1011

11-
use super::server::{ServerHandle, WeakServerHandle};
12+
use super::{
13+
server::{ServerHandle, WeakServerHandle},
14+
WeakControllerHandle,
15+
};
1216

1317
pub mod transfer;
1418

@@ -18,16 +22,16 @@ pub type WeakUserHandle = Weak<User>;
1822
type UsersMap = HashMap<Uuid, UserHandle>;
1923

2024
pub struct Users {
21-
//controller: WeakControllerHandle,
25+
controller: WeakControllerHandle,
2226

2327
/* Users that joined some started server */
2428
users: Mutex<UsersMap>,
2529
}
2630

2731
impl Users {
28-
pub fn new(/*controller: WeakControllerHandle*/) -> Self {
32+
pub fn new(controller: WeakControllerHandle) -> Self {
2933
Self {
30-
//controller,
34+
controller,
3135
users: Mutex::new(HashMap::new()),
3236
}
3337
}
@@ -53,7 +57,7 @@ impl Users {
5357
pub fn handle_user_disconnected(&self, server: ServerHandle, uuid: Uuid) {
5458
let mut users = self.users.lock().unwrap();
5559
if let Some(user) = users.get(&uuid).cloned() {
56-
if let CurrentServer::Connected(weak_server) = &user.server {
60+
if let CurrentServer::Connected(weak_server) = user.server.lock().unwrap().deref() {
5761
if let Some(strong_server) = weak_server.upgrade() {
5862
// Verify if the user is connected to the server that is saying he is disconnecting
5963
if Arc::ptr_eq(&strong_server, &server) {
@@ -74,7 +78,7 @@ impl Users {
7478
pub fn cleanup_users(&self, dead_server: &ServerHandle) -> u32 {
7579
let mut amount = 0;
7680
self.users.lock().unwrap().retain(|_, user| {
77-
if let CurrentServer::Connected(weak_server) = &user.server {
81+
if let CurrentServer::Connected(weak_server) = user.server.lock().unwrap().deref() {
7882
if let Some(server) = weak_server.upgrade() {
7983
if Arc::ptr_eq(&server, dead_server) {
8084
info!(
@@ -106,7 +110,7 @@ impl Users {
106110
Arc::new(User {
107111
name,
108112
uuid,
109-
server: CurrentServer::Connected(Arc::downgrade(server)),
113+
server: Mutex::new(CurrentServer::Connected(Arc::downgrade(server))),
110114
})
111115
}
112116
}
@@ -119,5 +123,5 @@ pub enum CurrentServer {
119123
pub struct User {
120124
pub name: String,
121125
pub uuid: Uuid,
122-
pub server: CurrentServer,
126+
pub server: Mutex<CurrentServer>,
123127
}
Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,81 @@
1+
use std::{ops::Deref, sync::Arc};
2+
3+
use log::error;
4+
use log::info;
5+
use log::warn;
6+
17
use crate::controller::{
8+
event::{transfer::UserTransferRequested, EventKey},
29
group::WeakGroupHandle,
310
server::{ServerHandle, WeakServerHandle},
411
};
512

6-
use super::{UserHandle, Users, WeakUserHandle};
13+
use super::{CurrentServer, UserHandle, Users, WeakUserHandle};
714

815
impl Users {
916
pub fn transfer_all_users(&self, _server: &ServerHandle) -> u32 {
1017
// TODO: Move all players from server to another server
1118
0
1219
}
1320

14-
pub fn transfer_user(&self, _user: &UserHandle, _target: &TransferTarget) -> bool {
15-
// TODO: Move all players from server to another server
21+
pub fn resolve_transfer(&self, user: &UserHandle, target: &TransferTarget) -> Option<Transfer> {
22+
if let CurrentServer::Connected(from) = user.server.lock().unwrap().deref() {
23+
match target {
24+
TransferTarget::Server(to) => {
25+
return Some(Transfer::new(
26+
Arc::downgrade(user),
27+
from.clone(),
28+
to.clone(),
29+
));
30+
}
31+
TransferTarget::Group(group) => {
32+
if let Some(group) = group.upgrade() {
33+
if let Some(to) = group.get_free_server() {
34+
return Some(Transfer::new(
35+
Arc::downgrade(user),
36+
from.clone(),
37+
Arc::downgrade(&to),
38+
));
39+
} else {
40+
warn!("Failed to find free server in group {} while resolving transfer of user {}", group.name, user.name);
41+
}
42+
} else {
43+
error!(
44+
"Failed to upgrade group handle while resolving transfer of user {}",
45+
user.name
46+
);
47+
}
48+
}
49+
}
50+
}
51+
52+
None
53+
}
54+
55+
pub fn transfer_user(&self, transfer: Transfer) -> bool {
56+
if let Some((user, from, to)) = transfer.get_strong() {
57+
info!(
58+
"Transfering user {} from {} to server {}",
59+
user.name, from.name, to.name
60+
);
61+
62+
let controller = self
63+
.controller
64+
.upgrade()
65+
.expect("Failed to upgrade controller");
66+
controller.get_event_bus().dispatch(
67+
&EventKey::Transfer(from.uuid),
68+
&UserTransferRequested {
69+
transfer: transfer.clone(),
70+
},
71+
);
72+
73+
*user.server.lock().unwrap() = CurrentServer::Transfering(transfer);
74+
return true;
75+
} else {
76+
error!("Failed to transfer user because some required information is missing");
77+
}
78+
1679
false
1780
}
1881
}
@@ -22,8 +85,22 @@ pub enum TransferTarget {
2285
Group(WeakGroupHandle),
2386
}
2487

88+
#[derive(Clone, Debug)]
2589
pub struct Transfer {
2690
pub user: WeakUserHandle,
2791
pub from: WeakServerHandle,
2892
pub to: WeakServerHandle,
2993
}
94+
95+
impl Transfer {
96+
pub fn new(user: WeakUserHandle, from: WeakServerHandle, to: WeakServerHandle) -> Self {
97+
Self { user, from, to }
98+
}
99+
100+
pub fn get_strong(&self) -> Option<(UserHandle, ServerHandle, ServerHandle)> {
101+
let user = self.user.upgrade()?;
102+
let from = self.from.upgrade()?;
103+
let to = self.to.upgrade()?;
104+
Some((user, from, to))
105+
}
106+
}

0 commit comments

Comments
 (0)