1 module ircbod.socket; 2 3 import std.socket, std.socketstream, std.conv, std.string; 4 5 class IRCSocket 6 { 7 private: 8 9 char[] host; 10 ushort port; 11 TcpSocket sock; 12 SocketStream stream; 13 14 public: 15 16 this(char[] host, ushort port = 6667) 17 { 18 this.host = host; 19 this.port = port; 20 this.sock = null; 21 } 22 23 bool connected() { 24 return this.sock !is null; 25 } 26 27 bool connect() 28 { 29 this.sock = new TcpSocket(new InternetAddress(this.host, this.port)); 30 this.stream = new SocketStream(this.sock); 31 return true; 32 } 33 34 bool disconnect() 35 { 36 if (connected()) { 37 this.sock.close(); 38 this.sock = null; 39 return true; 40 } 41 return false; 42 } 43 44 void close() 45 { 46 disconnect(); 47 } 48 49 bool reconnect() 50 { 51 disconnect(); 52 return connect(); 53 } 54 55 string read() 56 { 57 return to!string(this.stream.readLine()).chomp(); 58 } 59 60 private void write(string message) 61 { 62 std.stdio.writeln(">> " , message); 63 this.stream.writeString(message ~ "\r\n"); 64 } 65 66 void raw(string[] args) 67 { 68 auto last = args[$ - 1]; 69 if (last) { 70 args[$ - 1] = ":" ~ last; 71 } 72 write(args.join(" ")); 73 } 74 75 private void writeOptional(string command, string[] optional = []) 76 { 77 if(optional.length > 0) { 78 command ~= " " ~ optional.join(" "); 79 } 80 write(command.strip()); 81 } 82 83 void pass(string password) 84 { 85 write("PASS " ~ password); 86 } 87 88 void nick(string nickname) 89 { 90 write("NICK " ~ nickname); 91 } 92 93 void user(string username, uint mode, string unused, string realname) 94 { 95 write("USER " ~ [username, to!string(mode), unused, ":" ~ realname].join(" ")); 96 } 97 98 void oper(string name, string password) 99 { 100 write("OPER " ~ name ~ " " ~ password); 101 } 102 103 void mode(string channel, string[] modes) 104 { 105 write("MODE " ~ channel ~ " " ~ modes.join(" ")); 106 } 107 108 void quit(string message = null) 109 { 110 raw(["QUIT", message]); 111 } 112 113 void join(string channel, string password = "") 114 { 115 writeOptional("JOIN " ~ channel, [password]); 116 } 117 118 void part(string channel, string message = "") 119 { 120 raw(["PART", channel, message]); 121 } 122 123 void topic(string channel, string topic = "") 124 { 125 raw(["TOPIC", channel, topic]); 126 } 127 128 void names(string[] channels) 129 { 130 if(channels.length > 0) 131 write("NAMES " ~ channels.join(",")); 132 else 133 write("NAMES"); 134 } 135 136 void list(string[] channels) 137 { 138 if(channels.length > 0) 139 write("LIST " ~ channels.join(",")); 140 else 141 write("LIST"); 142 } 143 144 void invite(string nickname, string channel) 145 { 146 write("INVITE " ~ nickname ~ " " ~ channel); 147 } 148 149 void kick(string channel, string nickname, string comment = null) 150 { 151 raw(["KICK", channel, nickname, comment]); 152 } 153 154 void privmsg(string target, string message) 155 { 156 write("PRIVMSG " ~ target ~ " :" ~ message); 157 } 158 159 void notice(string target, string message) 160 { 161 write("NOTICE " ~ target ~ " :" ~ message); 162 } 163 164 void motd(string target = null) 165 { 166 writeOptional("MOTD", [target]); 167 } 168 169 void stats(string[] params) 170 { 171 writeOptional("STATS", params); 172 } 173 174 void time(string target = null) 175 { 176 writeOptional("TIME", [target]); 177 } 178 179 void info(string target = null) 180 { 181 writeOptional("INFO", [target]); 182 } 183 184 void squery(string target, string message) 185 { 186 write("SQUERY " ~ target ~ " :" ~ message); 187 } 188 189 void who(string[] params) 190 { 191 writeOptional("WHO", params); 192 } 193 194 void whois(string[] params) 195 { 196 writeOptional("WHOIS", params); 197 } 198 199 void whowas(string[] params) 200 { 201 writeOptional("WHOWAS", params); 202 } 203 204 void kill(string user, string message) 205 { 206 write("KILL " ~ user ~ " :" ~ message); 207 } 208 209 void ping(string server) 210 { 211 write("PING " ~ server); 212 } 213 214 void pong(string server) 215 { 216 write("PONG " ~ server); 217 } 218 219 void away(string message = null) 220 { 221 raw(["AWAY", message]); 222 } 223 224 void users(string target = null) 225 { 226 writeOptional("USERS", [target]); 227 } 228 229 void userhost(string[] users) 230 { 231 write("USERHOST" ~ users.join(" ")); 232 } 233 }