/* This file is part of Lupt. Lupt is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Lupt is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Lupt. If not, see */ use super::*; /// Join kaksh impl Handler for ChatPinnd { type Result = Resp; fn handle(&mut self, msg: ms::pind::JoinKaksh, _: &mut Self::Context) -> Self::Result { // check if user exist if let Some(_) = self.vyaktigat_waitlist.iter().position(|vk| vk.kunjika == msg.kunjika) { return Resp::Err("Kunjika already exist".to_owned()); } if let Some(_) = self.kaksh.iter().position(|(_,g)| { match g.loog.iter().position(|a| a.kunjika == msg.kunjika) { Some(_) => true, None => false } }) { return Resp::Err("Kunjika already exist".to_owned()); } // check if kaksh exist and add user match self.kaksh.get_mut(&msg.kaksh_kunjika) { Some(kaksh) =>{ // exist // check if kaksh have no space left if let Some(n) = kaksh.length { if kaksh.loog.len() >= n { return Resp::Err("Kaksh have no space".to_owned()); } } kaksh.loog.iter().for_each(|a: &Loog| { a.addr.do_send(ms::sansad::WsConnected { name: msg.name.to_owned(), kunjika: msg.kunjika.to_owned() }) }); kaksh.loog.push(Loog::new(msg.addr, msg.kunjika,msg.name, None)); }, None => { // don't exist // add kaksh and notify msg.addr.do_send(ms::sansad::WsConnected { name: msg.name.to_owned(), kunjika: msg.kunjika.to_owned() }); self.kaksh.insert(msg.kaksh_kunjika, Kaksh { length: msg.length, last_message_id: 0, loog: vec![Loog::new(msg.addr,msg.kunjika,msg.name, None)] }); } } Resp::Ok } } /// Join random vayakti /// Works as: /// Check if watchlist is empty, if yes add the kunjika andaddr to watchlist /// if watchlist have people get 0th person an connect it impl Handler for ChatPinnd { type Result = Resp; fn handle(&mut self, msg: ms::pind::JoinRandom, _: &mut Self::Context) -> Self::Result { // check if user exist if let Some(_) = self.vyaktigat_waitlist.iter().position(|vk| vk.kunjika == msg.kunjika) { return Resp::Err("Kunjika already exist".to_owned()); } if let Some(_) = self.kaksh.iter().position(|(_,g)| { match g.loog.iter().position(|a| a.kunjika == msg.kunjika) { Some(_) => true, None => false } }) { return Resp::Err("Kunjika already exist".to_owned()); } // Check if watch list is empty if self.vyaktigat_waitlist.len() == 0 { self.vyaktigat_waitlist.push(VyaktiWatchlist { kunjika: msg.kunjika, addr: msg.addr, name: msg.name, tags: msg.tags }); return Resp::None; } // connect person with tag let pos = if msg.tags.len() > 0 { match self.vyaktigat_waitlist.iter().position(|vk| { match vk.tags.iter().position(|t| msg.tags.contains(t)) { Some(_) => true, None => false } }) { Some(i) => i, None => { self.vyaktigat_waitlist.push(VyaktiWatchlist { kunjika: msg.kunjika, addr: msg.addr, name: msg.name, tags: msg.tags }); return Resp::None; } } } else { 0 }; let vayakti_watchlist = self.vyaktigat_waitlist.remove(pos); let group_kunjika = format!("gupt_{}>{}",msg.kunjika.to_owned(), vayakti_watchlist.kunjika); self.kaksh.insert(group_kunjika.to_owned(), Kaksh { length: Some(2), last_message_id: 0, loog: vec![Loog::new(msg.addr.clone(), msg.kunjika.to_owned(), msg.name.to_owned(), Some(msg.tags.clone())), Loog::new(vayakti_watchlist.addr.clone(), vayakti_watchlist.kunjika.to_owned(), vayakti_watchlist.name.to_owned(), Some(vayakti_watchlist.tags.clone()))] }); // notify about connection msg.addr.do_send(ms::sansad::WsConnectedRandom { name: vayakti_watchlist.name, kunjika: vayakti_watchlist.kunjika, kaksh_kunjika: group_kunjika.to_owned() }); vayakti_watchlist.addr.do_send(ms::sansad::WsConnectedRandom { name: msg.name, kunjika: msg.kunjika.to_owned(), kaksh_kunjika: group_kunjika }); Resp::Ok } } /// Next Random next vayakti impl Handler for ChatPinnd { type Result = Resp; fn handle(&mut self, msg: ms::pind::JoinRandomNext, _: &mut Self::Context) -> Self::Result { let kaksh = match self.kaksh.get_mut(&msg.kaksh_kunjika) { Some(v) => v, None => return Resp::Err("Failed to join, check entries!".to_owned()) }; let loog_i = match kaksh.loog.iter().position(|a| a.kunjika == msg.kunjika) { Some(v) => v, None => return Resp::Err("Failed to join, check entries!".to_owned()) }; let addr; let name; let tags; { let loog = match kaksh.loog.get(loog_i) { Some(v) => v, None => return Resp::Err("Failed to join, check entries!".to_owned()) }; if let None = loog.tags { return Resp::Err("You are not a randome vyakti!".to_owned()); } addr = loog.addr.clone(); name = loog.name.to_owned(); tags = match loog.tags.clone() { Some(v) => v, None => return Resp::Err("Failed to join, check entries!".to_owned()) }; } // remove from old kaksh kaksh.loog.remove(loog_i); kaksh.loog.iter().for_each(|a| { a.addr.do_send(ms::sansad::WsDisconnected { kunjika: msg.kunjika.to_owned(), name: name.to_owned() }) }); // Check if watch list is empty if self.vyaktigat_waitlist.len() == 0 { self.vyaktigat_waitlist.push(VyaktiWatchlist { kunjika: msg.kunjika, addr, name, tags }); return Resp::None; } // connect person with tag or to zero let pos = if tags.len() > 0 { match self.vyaktigat_waitlist.iter().position(|vk| { match vk.tags.iter().position(|t| tags.contains(t)) { Some(_) => true, None => false } }) { Some(i) => i, None => { self.vyaktigat_waitlist.push(VyaktiWatchlist { kunjika: msg.kunjika, addr, name, tags }); return Resp::None; } } } else { 0 }; let vayakti_watchlist = self.vyaktigat_waitlist.remove(pos); let group_kunjika = format!("gupt_{}>{}",msg.kunjika.to_owned(), vayakti_watchlist.kunjika); let log_count = kaksh.loog.len(); drop(kaksh); if log_count == 0 { self.kaksh.remove(&msg.kaksh_kunjika); } self.kaksh.insert(group_kunjika.to_owned(), Kaksh { length: Some(2), last_message_id: 0, loog: vec![Loog::new(addr.clone(), msg.kunjika.to_owned(), name.to_owned(), Some(tags.clone())), Loog::new(vayakti_watchlist.addr.clone(), vayakti_watchlist.kunjika.to_owned(), vayakti_watchlist.name.to_owned(), Some(vayakti_watchlist.tags.clone()))] }); // notify about connection addr.do_send(ms::sansad::WsConnectedRandom { name: vayakti_watchlist.name, kunjika: vayakti_watchlist.kunjika, kaksh_kunjika: group_kunjika.to_owned() }); vayakti_watchlist.addr.do_send(ms::sansad::WsConnectedRandom { name, kunjika: msg.kunjika.to_owned(), kaksh_kunjika: group_kunjika }); Resp::Ok } } /// send list of vayakti impl Handler for ChatPinnd { type Result = String; fn handle(&mut self, msg: ms::pind::List, _: &mut Self::Context) -> Self::Result { if let Some(kaksh) = self.kaksh.get(&msg.kaksh_kunjika) { let mut list = Vec::new(); for x in kaksh.loog.iter() { list.push((x.kunjika.to_owned(),x.name.to_owned())); } serde_json::json!(list).to_string() } else { "".to_string() } } } /// Notifiy a vayakti disconnected and trim kaksh impl Handler for ChatPinnd { type Result = (); fn handle(&mut self, msg: ms::pind::LeaveVayakti, _: &mut Self::Context) -> Self::Result { if let Some(kaksh_kunjika) = &msg.kaksh_kunjika { if let Some(kaksh) = self.kaksh.get_mut(kaksh_kunjika) { let name = if let Some(i) = kaksh.loog.iter().position(|x| x.addr == msg.addr) { kaksh.loog.remove(i).name } else { "".to_owned() }; if kaksh.loog.len() == 0 { self.kaksh.remove(kaksh_kunjika); } else { kaksh.loog.iter().for_each(|a| { a.addr.do_send(ms::sansad::WsDisconnected { kunjika: msg.kunjika.to_owned(), name: name.to_owned() }) }); } } } if let Some(i) = self.vyaktigat_waitlist.iter().position(|a| a.kunjika == msg.kunjika) { self.vyaktigat_waitlist.remove(i); } } }