Browse Source

Stuff is no longer completely broken. Just mostly.

tags/v0.1.0
Daniel Oaks 8 years ago
parent
commit
04442ddef1
9 changed files with 125 additions and 69 deletions
  1. 1
    0
      CHANGELOG.md
  2. 2
    2
      irc/capability.go
  3. 4
    4
      irc/client.go
  4. 1
    0
      irc/commandhandlers.go
  5. 3
    4
      irc/commands.go
  6. 2
    1
      irc/isupport.go
  7. 79
    33
      irc/modes.go
  8. 1
    0
      irc/numerics.go
  9. 32
    25
      irc/server.go

+ 1
- 0
CHANGELOG.md View File

@@ -25,6 +25,7 @@ Initial release of Oragono!
25 25
 * Default channel modes are now (`+nt`), matching most other IRCds.
26 26
 * CLI argument names made more consistent with typical software.
27 27
 * ONICK: Renamed to SANICK to be more consistent with other IRCds.
28
+* USER: Prepend usernames set by the USER command with `"~"`.
28 29
 
29 30
 ### Removed
30 31
 * Gitconfig config format completely removed and replaced with YAML.

+ 2
- 2
irc/capability.go View File

@@ -105,14 +105,14 @@ func capHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
105 105
 		// make sure all capabilities actually exist
106 106
 		for capability := range capabilities {
107 107
 			if !SupportedCapabilities[capability] {
108
-				client.Send(nil, server.nameString, "CAP", client.nickString, subCommand, capString)
108
+				client.Send(nil, server.nameString, "CAP", client.nickString, "NAK", capString)
109 109
 				return false
110 110
 			}
111 111
 		}
112 112
 		for capability := range capabilities {
113 113
 			client.capabilities[capability] = true
114 114
 		}
115
-		client.Send(nil, server.nameString, "CAP", client.nickString, subCommand, capString)
115
+		client.Send(nil, server.nameString, "CAP", client.nickString, "ACK", capString)
116 116
 
117 117
 	case "END":
118 118
 		if !client.registered {

+ 4
- 4
irc/client.go View File

@@ -56,6 +56,7 @@ func NewClient(server *Server, conn net.Conn) *Client {
56 56
 		flags:        make(map[UserMode]bool),
57 57
 		server:       server,
58 58
 		socket:       &socket,
59
+		nickString:   "*", // * is used until actual nick is given
59 60
 	}
60 61
 	client.Touch()
61 62
 	go client.run()
@@ -68,7 +69,6 @@ func NewClient(server *Server, conn net.Conn) *Client {
68 69
 //
69 70
 
70 71
 func (client *Client) run() {
71
-	var command Command
72 72
 	var err error
73 73
 	var isExiting bool
74 74
 	var line string
@@ -88,14 +88,14 @@ func (client *Client) run() {
88 88
 
89 89
 		msg, err = ircmsg.ParseLine(line)
90 90
 		if err != nil {
91
-			client.Quit("received malformed command")
91
+			client.Quit("received malformed line")
92 92
 			break
93 93
 		}
94 94
 
95 95
 		cmd, exists := Commands[msg.Command]
96 96
 		if !exists {
97
-			//TODO(dan): Reply with 400 or whatever unknown cmd is
98
-			client.Quit("Received unknown command")
97
+			client.Send(nil, client.server.nameString, ERR_UNKNOWNCOMMAND, client.nickString, msg.Command, "Unknown command")
98
+			continue
99 99
 		}
100 100
 
101 101
 		isExiting = cmd.Run(client.server, client, msg)

+ 1
- 0
irc/commandhandlers.go View File

@@ -127,6 +127,7 @@ type ChannelModeCommand struct {
127 127
 	changes ChannelModeChanges
128 128
 }
129 129
 
130
+/*
130 131
 // MODE <channel> ( "+" / "-" )? *( "+" / "-" / <mode character> ) *<modeparams>
131 132
 func ParseChannelModeCommand(channel Name, args []string) (Command, error) {
132 133
 	cmd := &ChannelModeCommand{

+ 3
- 4
irc/commands.go View File

@@ -23,7 +23,7 @@ func (cmd *Command) Run(server *Server, client *Client, msg ircmsg.IrcMessage) b
23 23
 		// command silently ignored
24 24
 		return false
25 25
 	}
26
-	if (!cmd.oper) && (!client.flags[Operator]) {
26
+	if cmd.oper && !client.flags[Operator] {
27 27
 		client.Send(nil, server.nameString, ERR_NOPRIVILEGES, client.nickString, "Permission Denied - You're not an IRC operator")
28 28
 		return false
29 29
 	}
@@ -87,11 +87,10 @@ var Commands = map[string]Command{
87 87
 		handler:   listHandler,
88 88
 		minParams: 0,
89 89
 	},
90
-	/*TODO(dan): ADD THIS BACK.
91 90
 	"MODE": Command{
92 91
 		handler:   modeHandler,
93 92
 		minParams: 1,
94
-	},*/
93
+	},
95 94
 	"MOTD": Command{
96 95
 		handler:   motdHandler,
97 96
 		minParams: 0,
@@ -153,7 +152,7 @@ var Commands = map[string]Command{
153 152
 		usablePreReg: true,
154 153
 		minParams:    0,
155 154
 	},
156
-	/*TODO(dan): ADD THIS BACK IN
155
+	/*TODO(dan): Add this back in
157 156
 	"THEATRE": Command{
158 157
 		handler:   theatreHandler,
159 158
 		minParams: 1,

+ 2
- 1
irc/isupport.go View File

@@ -69,6 +69,7 @@ func (il *ISupportList) RegenerateCachedReply() {
69 69
 
70 70
 func (client *Client) RplISupport() {
71 71
 	for _, tokenline := range client.server.isupport.CachedReply {
72
-		client.Send(nil, client.server.nameString, RPL_ISUPPORT, tokenline...)
72
+		// ugly trickery ahead
73
+		client.Send(nil, client.server.nameString, RPL_ISUPPORT, append([]string{client.nickString}, tokenline...)...)
73 74
 	}
74 75
 }

+ 79
- 33
irc/modes.go View File

@@ -7,6 +7,8 @@ package irc
7 7
 
8 8
 import (
9 9
 	"strings"
10
+
11
+	"github.com/DanielOaks/girc-go/ircmsg"
10 12
 )
11 13
 
12 14
 // user mode flags
@@ -126,60 +128,104 @@ var (
126 128
 // commands
127 129
 //
128 130
 
129
-/*
130
-func (m *ModeCommand) HandleServer(s *Server) {
131
-	client := m.Client()
132
-	target := s.clients.Get(m.nickname)
131
+// MODE <target> [<modestring> [<mode arguments>...]]
132
+func modeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
133
+	name := NewName(msg.Params[0])
134
+	if name.IsChannel() {
135
+		// return cmodeHandler(server, client, msg)
136
+		client.Notice("CMODEs are not yet supported!")
137
+		return false
138
+	} else {
139
+		return umodeHandler(server, client, msg)
140
+	}
141
+}
142
+
143
+// MODE <target> [<modestring> [<mode arguments>...]]
144
+func umodeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
145
+	nickname := NewName(msg.Params[0])
146
+
147
+	target := server.clients.Get(nickname)
133 148
 
134 149
 	if target == nil {
135
-		client.ErrNoSuchNick(m.nickname)
136
-		return
150
+		client.Send(nil, server.nameString, ERR_NOSUCHNICK, client.nickString, msg.Params[0], "No such nick")
151
+		return false
137 152
 	}
138 153
 
154
+	//TODO(dan): restricting to Operator here should be done with SAMODE only
155
+	// point SAMODE at this handler too, if they are operator and SAMODE was called then fine
139 156
 	if client != target && !client.flags[Operator] {
140
-		client.ErrUsersDontMatch()
141
-		return
157
+		if len(msg.Params) > 1 {
158
+			client.Send(nil, server.nameString, ERR_USERSDONTMATCH, client.nickString, "Can't change modes for other users")
159
+		} else {
160
+			client.Send(nil, server.nameString, ERR_USERSDONTMATCH, client.nickString, "Can't view modes for other users")
161
+		}
162
+		return false
142 163
 	}
143 164
 
144
-	changes := make(ModeChanges, 0, len(m.changes))
165
+	// assemble changes
166
+	changes := make(ModeChanges, 0)
167
+
168
+	if len(msg.Params) > 1 {
169
+		modeArg := msg.Params[0]
170
+		op := ModeOp(modeArg[0])
171
+		if (op == Add) || (op == Remove) {
172
+			modeArg = modeArg[1:]
173
+		} else {
174
+			client.Send(nil, server.nameString, ERR_UNKNOWNERROR, client.nickString, "MODE", "Mode string could not be parsed correctly")
175
+			return false
176
+		}
145 177
 
146
-	for _, change := range m.changes {
147
-		switch change.mode {
148
-		case Invisible, ServerNotice, WallOps:
149
-			switch change.op {
150
-			case Add:
151
-				if target.flags[change.mode] {
152
-					continue
153
-				}
154
-				target.flags[change.mode] = true
155
-				changes = append(changes, change)
178
+		for _, mode := range modeArg {
179
+			if mode == '-' || mode == '+' {
180
+				op = ModeOp(mode)
181
+				continue
182
+			}
183
+			changes = append(changes, &ModeChange{
184
+				mode: UserMode(mode),
185
+				op:   op,
186
+			})
187
+		}
156 188
 
157
-			case Remove:
158
-				if !target.flags[change.mode] {
159
-					continue
189
+		for _, change := range changes {
190
+			switch change.mode {
191
+			case Invisible, ServerNotice, WallOps:
192
+				switch change.op {
193
+				case Add:
194
+					if target.flags[change.mode] {
195
+						continue
196
+					}
197
+					target.flags[change.mode] = true
198
+					changes = append(changes, change)
199
+
200
+				case Remove:
201
+					if !target.flags[change.mode] {
202
+						continue
203
+					}
204
+					delete(target.flags, change.mode)
205
+					changes = append(changes, change)
160 206
 				}
161
-				delete(target.flags, change.mode)
162
-				changes = append(changes, change)
163
-			}
164 207
 
165
-		case Operator, LocalOperator:
166
-			if change.op == Remove {
167
-				if !target.flags[change.mode] {
168
-					continue
208
+			case Operator, LocalOperator:
209
+				if change.op == Remove {
210
+					if !target.flags[change.mode] {
211
+						continue
212
+					}
213
+					delete(target.flags, change.mode)
214
+					changes = append(changes, change)
169 215
 				}
170
-				delete(target.flags, change.mode)
171
-				changes = append(changes, change)
172 216
 			}
173 217
 		}
174 218
 	}
175 219
 
176 220
 	if len(changes) > 0 {
177
-		client.Reply(RplModeChanges(client, target, changes))
221
+		client.Send(nil, client.nickMaskString, "MODE", target.nickString, changes.String())
178 222
 	} else if client == target {
179
-		client.RplUModeIs(client)
223
+		client.Send(nil, target.nickMaskString, RPL_UMODEIS, target.nickString, target.ModeString())
180 224
 	}
225
+	return false
181 226
 }
182 227
 
228
+/*
183 229
 func (msg *ChannelModeCommand) HandleServer(server *Server) {
184 230
 	client := msg.Client()
185 231
 	channel := server.channels.Get(msg.channel)

+ 1
- 0
irc/numerics.go View File

@@ -90,6 +90,7 @@ const (
90 90
 	RPL_USERS             = "393"
91 91
 	RPL_ENDOFUSERS        = "394"
92 92
 	RPL_NOUSERS           = "395"
93
+	ERR_UNKNOWNERROR      = "400"
93 94
 	ERR_NOSUCHNICK        = "401"
94 95
 	ERR_NOSUCHSERVER      = "402"
95 96
 	ERR_NOSUCHCHANNEL     = "403"

+ 32
- 25
irc/server.go View File

@@ -287,11 +287,11 @@ func (s *Server) tryRegister(c *Client) {
287 287
 	// send welcome text
288 288
 	//NOTE(dan): we specifically use the NICK here instead of the nickmask
289 289
 	// see http://modern.ircdocs.horse/#rplwelcome-001 for details on why we avoid using the nickmask
290
-	c.Send(nil, s.nameString, RPL_WELCOME, fmt.Sprintf("Welcome to the Internet Relay Network %s", c.nickString))
291
-	c.Send(nil, s.nameString, RPL_YOURHOST, fmt.Sprintf("Your host is %s, running version %s", s.nameString, SEM_VER))
292
-	c.Send(nil, s.nameString, RPL_CREATED, fmt.Sprintf("This server was created %s", s.ctime.Format(time.RFC1123)))
290
+	c.Send(nil, s.nameString, RPL_WELCOME, c.nickString, fmt.Sprintf("Welcome to the Internet Relay Network %s", c.nickString))
291
+	c.Send(nil, s.nameString, RPL_YOURHOST, c.nickString, fmt.Sprintf("Your host is %s, running version %s", s.nameString, SEM_VER))
292
+	c.Send(nil, s.nameString, RPL_CREATED, c.nickString, fmt.Sprintf("This server was created %s", s.ctime.Format(time.RFC1123)))
293 293
 	//TODO(dan): Look at adding last optional [<channel modes with a parameter>] parameter
294
-	c.Send(nil, s.nameString, RPL_MYINFO, s.nameString, SEM_VER, supportedUserModesString, supportedChannelModesString)
294
+	c.Send(nil, s.nameString, RPL_MYINFO, c.nickString, s.nameString, SEM_VER, supportedUserModesString, supportedChannelModesString)
295 295
 	c.RplISupport()
296 296
 	s.MOTD(c)
297 297
 }
@@ -332,6 +332,12 @@ func passHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
332 332
 		return false
333 333
 	}
334 334
 
335
+	// if no password exists, skip checking
336
+	if len(server.password) == 0 {
337
+		client.authorized = true
338
+		return false
339
+	}
340
+
335 341
 	// check the provided password
336 342
 	password := []byte(msg.Params[0])
337 343
 	if ComparePassword(server.password, password) != nil {
@@ -383,8 +389,8 @@ func userHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
383 389
 	// we do it this way to ONLY replace what hasn't already been set
384 390
 	server.clients.Remove(client)
385 391
 
386
-	if client.username != "" {
387
-		client.username = Name(msg.Params[0])
392
+	if !client.HasUsername() {
393
+		client.username = Name("~" + msg.Params[0])
388 394
 		client.updateNickMask()
389 395
 	}
390 396
 	if client.realname != "" {
@@ -446,6 +452,7 @@ func joinHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
446 452
 	for i, nameString := range channels {
447 453
 		name = Name(nameString)
448 454
 		if !name.IsChannel() {
455
+			fmt.Println("ISN'T CHANNEL NAME:", nameString)
449 456
 			client.Send(nil, server.nameString, ERR_NOSUCHCHANNEL, client.nickString, nameString, "No such channel")
450 457
 			continue
451 458
 		}
@@ -551,10 +558,10 @@ func (client *Client) WhoisChannelsNames(target *Client) []string {
551 558
 // WHOIS [ <target> ] <mask> *( "," <mask> )
552 559
 func whoisHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
553 560
 	var masksString string
554
-	var target string
561
+	//var target string
555 562
 
556 563
 	if len(msg.Params) > 1 {
557
-		target = msg.Params[0]
564
+		//target = msg.Params[0]
558 565
 		masksString = msg.Params[1]
559 566
 	} else {
560 567
 		masksString = msg.Params[0]
@@ -639,10 +646,10 @@ func whoHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
639 646
 
640 647
 	//TODO(dan): is this used and would I put this param in the Modern doc?
641 648
 	// if not, can we remove it?
642
-	var operatorOnly bool
643
-	if len(msg.Params) > 1 && msg.Params[1] == "o" {
644
-		operatorOnly = true
645
-	}
649
+	//var operatorOnly bool
650
+	//if len(msg.Params) > 1 && msg.Params[1] == "o" {
651
+	//	operatorOnly = true
652
+	//}
646 653
 
647 654
 	if mask == "" {
648 655
 		for _, channel := range server.channels {
@@ -679,7 +686,7 @@ func operHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
679 686
 	}
680 687
 
681 688
 	client.flags[Operator] = true
682
-	client.Send(nil, server.nameString, RPL_YOUREOPER, client.nickString, "You are not an IRC operator")
689
+	client.Send(nil, server.nameString, RPL_YOUREOPER, client.nickString, "You are now an IRC operator")
683 690
 	//TODO(dan): Should this be sent automagically as part of setting the flag/mode?
684 691
 	modech := ModeChanges{&ModeChange{
685 692
 		mode: Operator,
@@ -740,10 +747,10 @@ func isonHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
740 747
 // MOTD [<target>]
741 748
 func motdHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
742 749
 	//TODO(dan): hook this up when we have multiple servers I guess???
743
-	var target string
744
-	if len(msg.Params) > 0 {
745
-		target = msg.Params[0]
746
-	}
750
+	//var target string
751
+	//if len(msg.Params) > 0 {
752
+	//	target = msg.Params[0]
753
+	//}
747 754
 
748 755
 	server.MOTD(client)
749 756
 	return false
@@ -902,10 +909,10 @@ func namesHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
902 909
 	if len(msg.Params) > 0 {
903 910
 		channels = strings.Split(msg.Params[0], ",")
904 911
 	}
905
-	var target string
906
-	if len(msg.Params) > 1 {
907
-		target = msg.Params[1]
908
-	}
912
+	//var target string
913
+	//if len(msg.Params) > 1 {
914
+	//	target = msg.Params[1]
915
+	//}
909 916
 
910 917
 	if len(channels) == 0 {
911 918
 		for _, channel := range server.channels {
@@ -1002,10 +1009,10 @@ func whowasHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
1002 1009
 	if len(msg.Params) > 1 {
1003 1010
 		count, _ = strconv.ParseInt(msg.Params[1], 10, 64)
1004 1011
 	}
1005
-	var target string
1006
-	if len(msg.Params) > 2 {
1007
-		target = msg.Params[2]
1008
-	}
1012
+	//var target string
1013
+	//if len(msg.Params) > 2 {
1014
+	//	target = msg.Params[2]
1015
+	//}
1009 1016
 	for _, nickname := range nicknames {
1010 1017
 		results := server.whoWas.Find(Name(nickname), count)
1011 1018
 		if len(results) == 0 {

Loading…
Cancel
Save