irc_server.rs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. use std::{
  2. net::{TcpStream},
  3. };
  4. use rand::{RngCore, rngs::OsRng};
  5. use futures::{
  6. io::{WriteHalf}, AsyncWriteExt,
  7. };
  8. use log::{debug, info};
  9. use smol::Async;
  10. use drk::{
  11. net,
  12. Error, Result,
  13. };
  14. use crate::privmsg::PrivMsg;
  15. /*
  16. NICK fifififif
  17. USER username 0 * :Real
  18. :behemoth 001 fifififif :Hi, welcome to IRC
  19. :behemoth 002 fifififif :Your host is behemoth, running version miniircd-2.1
  20. :behemoth 003 fifififif :This server was created sometime
  21. :behemoth 004 fifififif behemoth miniircd-2.1 o o
  22. :behemoth 251 fifififif :There are 1 users and 0 services on 1 server
  23. :behemoth 422 fifififif :MOTD File is missing
  24. JOIN #dev
  25. :fifififif!username@127.0.0.1 JOIN #dev
  26. :behemoth 331 fifififif #dev :No topic is set
  27. :behemoth 353 fifififif = #dev :fifififif
  28. :behemoth 366 fifififif #dev :End of NAMES list
  29. PRIVMSG #dev hihi
  30. */
  31. pub struct IrcServerConnection {
  32. write_stream: WriteHalf<Async<TcpStream>>,
  33. is_nick_init: bool,
  34. is_user_init: bool,
  35. is_registered: bool,
  36. nickname: String,
  37. channels: Vec<String>,
  38. }
  39. impl IrcServerConnection {
  40. pub fn new(write_stream: WriteHalf<Async<TcpStream>>) -> Self {
  41. Self {
  42. write_stream,
  43. is_nick_init: false,
  44. is_user_init: false,
  45. is_registered: false,
  46. nickname: "".to_string(),
  47. channels: vec![],
  48. }
  49. }
  50. pub async fn update(&mut self, line: String, p2p: net::P2pPtr) -> Result<()> {
  51. let mut tokens = line.split_ascii_whitespace();
  52. // Commands can begin with :garbage but we will reject clients doing that for now
  53. // to keep the protocol simple and focused.
  54. let command = tokens.next().ok_or(Error::MalformedPacket)?;
  55. debug!("Received command: {}", command);
  56. match command {
  57. "NICK" => {
  58. let nickname = tokens.next().ok_or(Error::MalformedPacket)?;
  59. self.is_nick_init = true;
  60. self.nickname = nickname.to_string();
  61. }
  62. "USER" => {
  63. // We can stuff any extra things like public keys in here
  64. // Ignore it for now
  65. self.is_user_init = true;
  66. }
  67. "JOIN" => {
  68. // Ignore since channels are all autojoin
  69. //let channel = tokens.next().ok_or(Error::MalformedPacket)?;
  70. //self.channels.push(channel.to_string());
  71. //let join_reply = format!(":{}!darkfi@127.0.0.1 JOIN {}\n", self.nickname,
  72. // channel); self.reply(&join_reply).await?;
  73. //self.write_stream.write_all(b":f00!f00@127.0.0.1 PRIVMSG #dev :y0\n").await?;
  74. }
  75. "PING" => {
  76. self.reply("PONG").await?;
  77. }
  78. "PRIVMSG" => {
  79. let channel = tokens.next().ok_or(Error::MalformedPacket)?;
  80. let substr_idx = line.find(':').ok_or(Error::MalformedPacket)?;
  81. if substr_idx >= line.len() {
  82. return Err(Error::MalformedPacket)
  83. }
  84. let message = &line[substr_idx + 1..];
  85. info!("Message {}: {}", channel, message);
  86. let protocol_msg = PrivMsg {
  87. id: OsRng.next_u32(),
  88. nickname: self.nickname.clone(),
  89. channel: channel.to_string(),
  90. message: message.to_string(),
  91. };
  92. p2p.broadcast(protocol_msg).await?;
  93. }
  94. _ => {}
  95. }
  96. if !self.is_registered && self.is_nick_init && self.is_user_init {
  97. debug!("Initializing peer connection");
  98. let register_reply = format!(":darkfi 001 {} :Let there be dark\n", self.nickname);
  99. self.reply(&register_reply).await?;
  100. self.is_registered = true;
  101. // Auto-joins
  102. for channel in ["#dev", "#markets", "#welcome"] {
  103. let join_reply = format!(":{}!darkfi@127.0.0.1 JOIN {}\n", self.nickname, channel);
  104. self.reply(&join_reply).await?;
  105. }
  106. }
  107. Ok(())
  108. }
  109. pub async fn reply(&mut self, message: &str) -> Result<()> {
  110. self.write_stream.write_all(message.as_bytes()).await?;
  111. debug!("Sent {}", message);
  112. Ok(())
  113. }
  114. }