package irc func (s *ircd) processIRCMessage(m *ircMessage) { // FIXME put all of these in a map of string->function // and dispatch them that way instead switch m.command { case "CAP": s.processCAPCommand(m) case "NICK": s.processNICKCommand(m) case "USER": s.processUSERCommand(m) default: s.processUnknownCommand(m) } s.log.Infof("client<%s> sent %+v", m.from.Id, m) } func (s *ircd) sayHello(c *ircClient) { //001 welcome //002 host/version decl //003, 004, 005, 251, 252, 253, 254, 255, 256, 266 //375 (begin motd) //372 motd (repeating) //376 end motd // change user mode (from server) :sneak!sneak@butt9q8.a.b.IP MODE sneak :+x /* :irc.butt.es 001 sneak :Welcome to the Buttes IRC Network sneak!sneak@1.2.3.4 :irc.butt.es 002 sneak :Your host is irc.butt.es, running version InspIRCd-3 :irc.butt.es 003 sneak :This server was created 09:33:24 Aug 05 2019 :irc.butt.es 004 sneak irc.butt.es InspIRCd-3 BHIRSWcghiorswxz ACFHIMNOPQRSTXYZbcefijklmnoprstvwz :FHIXYZbefjklovw :irc.butt.es 005 sneak ACCEPT=30 AWAYLEN=200 CALLERID=g CASEMAPPING=ascii CHANLIMIT=#:20 CHANMODES=IXYZbew,k,FHfjl,ACMNOPQRSTcimnprstz CHANNELLEN=64 CHANTYPES=# ELIST=CMNTU ESILENCE=CcdiNnPpTtx EXCEPTS=e EXTBAN=,ACGNOQRSTUacjmprz :are supported by this server :irc.butt.es 005 sneak HOSTLEN=64 INVEX=I KEYLEN=32 KICKLEN=255 LINELEN=512 MAXLIST=IXbew:512 MAXTARGETS=20 MODES=20 NAMESX NETWORK=Buttes NICKLEN=32 OPERLOG OVERRIDE :are supported by this server :irc.butt.es 005 sneak PREFIX=(ov)@+ REMOVE SAFELIST SECURELIST SILENCE=32 STATUSMSG=@+ TOPICLEN=500 USERIP USERLEN=11 VBANLIST WHOX :are supported by this server :irc.butt.es 251 sneak :There are 34 users and 33 invisible on 2 servers :irc.butt.es 252 sneak 2 :operator(s) online :irc.butt.es 253 sneak 1 :unknown connections :irc.butt.es 254 sneak 33 :channels formed :irc.butt.es 255 sneak :I have 60 clients and 1 servers :irc.butt.es 265 sneak :Current local users: 60 Max: 65 :irc.butt.es 266 sneak :Current global users: 67 Max: 72 :irc.butt.es 375 sneak :irc.butt.es message of the day :irc.butt.es 372 sneak :- ____ _ _ _____ _____ _____ ____ :irc.butt.es 372 sneak :- | __ )| | | |_ _|_ _| ____/ ___| :irc.butt.es 372 sneak :- | _ \| | | | | | | | | _| \___ \ :irc.butt.es 376 sneak :End of message of the day. :irc.butt.es 396 sneak butt9q8.a.b.IP :is now your displayed host :sneak!sneak@butt9q8.a.b.IP MODE sneak :+x */ } func (s *ircd) processUnknownCommand(m *ircMessage) { m.from.RespUnknownCommand(m.command) if m.from.session.CheckState("init") { // if they are sending weird commands before NICK/USER, just drop // them // FIXME send an error m.from.Kill() } } func (s *ircd) processNICKCommand(m *ircMessage) { //FIXME check if nick is in use //FIXME check if nick is valid s.log.Infof("%+v", m) s.log.Infof("%+v", m.params) s.log.Infof("%+v", m.from) s.log.Infof("%+v", m.from.session) if len(m.params) == 1 { m.from.session.SetNick(m.params[0]) s.log.Infof("conn<%s> NICK %s", m.from.Id, m.params[0]) } } func (s *ircd) processUSERCommand(m *ircMessage) { // FIXME fail/disconnect if nick not yet set // FIXME fail if run a second time // FIXME tbh the client connection should be an FSM that limits usage of // certain valid commands per-state //params: if !m.from.session.CheckState("init") { // can only do this when going init->normal // FIXME send an error m.from.Kill() } if m.from.session.SetUserInfo(m.params) { //this changes the session state s.log.Infof("%+v", m.from.session) s.sayHello(m.from) } else { // FIXME send an error m.from.Kill() // bye felicia } } func (s *ircd) processCAPCommand(m *ircMessage) { s.log.Debugln("ignoring CAP command, unsupported") // pass }