Browse Source

move modes code to its own file; fix SQL (un)marshalling

tags/v0.1.0
Jeremy Latt 10 years ago
parent
commit
d85e6681d9
7 changed files with 173 additions and 136 deletions
  1. 2
    2
      irc/channel.go
  2. 2
    2
      irc/client_lookup_set.go
  3. 0
    40
      irc/constants.go
  4. 162
    0
      irc/modes.go
  5. 2
    1
      irc/reply.go
  6. 5
    70
      irc/server.go
  7. 0
    21
      irc/types.go

+ 2
- 2
irc/channel.go View File

@@ -444,8 +444,8 @@ func (channel *Channel) Persist() (err error) {
444 444
               (name, flags, key, topic, user_limit, ban_list, except_list,
445 445
                invite_list)
446 446
               VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
447
-			channel.name, channel.flags.String(), channel.key, channel.topic,
448
-			channel.userLimit, channel.lists[BanMask].String(),
447
+			channel.name.String(), channel.flags.String(), channel.key.String(),
448
+			channel.topic.String(), channel.userLimit, channel.lists[BanMask].String(),
449 449
 			channel.lists[ExceptMask].String(), channel.lists[InviteMask].String())
450 450
 	} else {
451 451
 		_, err = channel.server.db.Exec(`

+ 2
- 2
irc/client_lookup_set.go View File

@@ -153,7 +153,7 @@ func NewClientDB() *ClientDB {
153 153
 
154 154
 func (db *ClientDB) Add(client *Client) {
155 155
 	_, err := db.db.Exec(`INSERT INTO client (nickname, userhost) VALUES (?, ?)`,
156
-		client.Nick(), client.UserHost())
156
+		client.Nick().String(), client.UserHost().String())
157 157
 	if err != nil {
158 158
 		Log.error.Println("ClientDB.Add:", err)
159 159
 	}
@@ -161,7 +161,7 @@ func (db *ClientDB) Add(client *Client) {
161 161
 
162 162
 func (db *ClientDB) Remove(client *Client) {
163 163
 	_, err := db.db.Exec(`DELETE FROM client WHERE nickname = ?`,
164
-		client.Nick())
164
+		client.Nick().String())
165 165
 	if err != nil {
166 166
 		Log.error.Println("ClientDB.Remove:", err)
167 167
 	}

+ 0
- 40
irc/constants.go View File

@@ -1,14 +1,5 @@
1 1
 package irc
2 2
 
3
-import (
4
-	"errors"
5
-)
6
-
7
-var (
8
-	// errors
9
-	ErrAlreadyDestroyed = errors.New("already destroyed")
10
-)
11
-
12 3
 const (
13 4
 	SEM_VER       = "ergonomadic-1.3.1"
14 5
 	CRLF          = "\r\n"
@@ -184,35 +175,4 @@ const (
184 175
 	ERR_NOOPERHOST        NumericCode = 491
185 176
 	ERR_UMODEUNKNOWNFLAG  NumericCode = 501
186 177
 	ERR_USERSDONTMATCH    NumericCode = 502
187
-
188
-	Add    ModeOp = '+'
189
-	List   ModeOp = '='
190
-	Remove ModeOp = '-'
191
-
192
-	Away          UserMode = 'a'
193
-	Invisible     UserMode = 'i'
194
-	LocalOperator UserMode = 'O'
195
-	Operator      UserMode = 'o'
196
-	Restricted    UserMode = 'r'
197
-	ServerNotice  UserMode = 's' // deprecated
198
-	WallOps       UserMode = 'w'
199
-
200
-	Anonymous       ChannelMode = 'a' // flag
201
-	BanMask         ChannelMode = 'b' // arg
202
-	ChannelCreator  ChannelMode = 'O' // flag
203
-	ChannelOperator ChannelMode = 'o' // arg
204
-	ExceptMask      ChannelMode = 'e' // arg
205
-	InviteMask      ChannelMode = 'I' // arg
206
-	InviteOnly      ChannelMode = 'i' // flag
207
-	Key             ChannelMode = 'k' // flag arg
208
-	Moderated       ChannelMode = 'm' // flag
209
-	NoOutside       ChannelMode = 'n' // flag
210
-	OpOnlyTopic     ChannelMode = 't' // flag
211
-	Persistent      ChannelMode = 'P' // flag
212
-	Private         ChannelMode = 'p' // flag
213
-	Quiet           ChannelMode = 'q' // flag
214
-	ReOp            ChannelMode = 'r' // flag
215
-	Secret          ChannelMode = 's' // flag, deprecated
216
-	UserLimit       ChannelMode = 'l' // flag arg
217
-	Voice           ChannelMode = 'v' // arg
218 178
 )

+ 162
- 0
irc/modes.go View File

@@ -0,0 +1,162 @@
1
+package irc
2
+
3
+import (
4
+	"strings"
5
+)
6
+
7
+// user mode flags
8
+type UserMode rune
9
+
10
+func (mode UserMode) String() string {
11
+	return string(mode)
12
+}
13
+
14
+type UserModes []UserMode
15
+
16
+func (modes UserModes) String() string {
17
+	strs := make([]string, len(modes))
18
+	for index, mode := range modes {
19
+		strs[index] = mode.String()
20
+	}
21
+	return strings.Join(strs, "")
22
+}
23
+
24
+// channel mode flags
25
+type ChannelMode rune
26
+
27
+func (mode ChannelMode) String() string {
28
+	return string(mode)
29
+}
30
+
31
+type ChannelModes []ChannelMode
32
+
33
+func (modes ChannelModes) String() string {
34
+	strs := make([]string, len(modes))
35
+	for index, mode := range modes {
36
+		strs[index] = mode.String()
37
+	}
38
+	return strings.Join(strs, "")
39
+}
40
+
41
+type ModeOp rune
42
+
43
+func (op ModeOp) String() string {
44
+	return string(op)
45
+}
46
+
47
+const (
48
+	Add    ModeOp = '+'
49
+	List   ModeOp = '='
50
+	Remove ModeOp = '-'
51
+)
52
+
53
+const (
54
+	Away          UserMode = 'a'
55
+	Invisible     UserMode = 'i'
56
+	LocalOperator UserMode = 'O'
57
+	Operator      UserMode = 'o'
58
+	Restricted    UserMode = 'r'
59
+	ServerNotice  UserMode = 's' // deprecated
60
+	WallOps       UserMode = 'w'
61
+)
62
+
63
+var (
64
+	SupportedUserModes = UserModes{
65
+		Away, Invisible, Operator,
66
+	}
67
+)
68
+
69
+const (
70
+	Anonymous       ChannelMode = 'a' // flag
71
+	BanMask         ChannelMode = 'b' // arg
72
+	ChannelCreator  ChannelMode = 'O' // flag
73
+	ChannelOperator ChannelMode = 'o' // arg
74
+	ExceptMask      ChannelMode = 'e' // arg
75
+	InviteMask      ChannelMode = 'I' // arg
76
+	InviteOnly      ChannelMode = 'i' // flag
77
+	Key             ChannelMode = 'k' // flag arg
78
+	Moderated       ChannelMode = 'm' // flag
79
+	NoOutside       ChannelMode = 'n' // flag
80
+	OpOnlyTopic     ChannelMode = 't' // flag
81
+	Persistent      ChannelMode = 'P' // flag
82
+	Private         ChannelMode = 'p' // flag
83
+	Quiet           ChannelMode = 'q' // flag
84
+	ReOp            ChannelMode = 'r' // flag
85
+	Secret          ChannelMode = 's' // flag, deprecated
86
+	UserLimit       ChannelMode = 'l' // flag arg
87
+	Voice           ChannelMode = 'v' // arg
88
+)
89
+
90
+var (
91
+	SupportedChannelModes = ChannelModes{
92
+		BanMask, ExceptMask, InviteMask, InviteOnly, Key, NoOutside,
93
+		OpOnlyTopic, Persistent, Private, UserLimit,
94
+	}
95
+)
96
+
97
+//
98
+// commands
99
+//
100
+
101
+func (m *ModeCommand) HandleServer(s *Server) {
102
+	client := m.Client()
103
+	target := s.clients.Get(m.nickname)
104
+
105
+	if target == nil {
106
+		client.ErrNoSuchNick(m.nickname)
107
+		return
108
+	}
109
+
110
+	if client != target && !client.flags[Operator] {
111
+		client.ErrUsersDontMatch()
112
+		return
113
+	}
114
+
115
+	changes := make(ModeChanges, 0, len(m.changes))
116
+
117
+	for _, change := range m.changes {
118
+		switch change.mode {
119
+		case Invisible, ServerNotice, WallOps:
120
+			switch change.op {
121
+			case Add:
122
+				if target.flags[change.mode] {
123
+					continue
124
+				}
125
+				target.flags[change.mode] = true
126
+				changes = append(changes, change)
127
+
128
+			case Remove:
129
+				if !target.flags[change.mode] {
130
+					continue
131
+				}
132
+				delete(target.flags, change.mode)
133
+				changes = append(changes, change)
134
+			}
135
+
136
+		case Operator, LocalOperator:
137
+			if change.op == Remove {
138
+				if !target.flags[change.mode] {
139
+					continue
140
+				}
141
+				delete(target.flags, change.mode)
142
+				changes = append(changes, change)
143
+			}
144
+		}
145
+	}
146
+
147
+	// Who should get these replies?
148
+	if len(changes) > 0 {
149
+		client.Reply(RplMode(client, target, changes))
150
+	}
151
+}
152
+
153
+func (msg *ChannelModeCommand) HandleServer(server *Server) {
154
+	client := msg.Client()
155
+	channel := server.channels.Get(msg.channel)
156
+	if channel == nil {
157
+		client.ErrNoSuchChannel(msg.channel)
158
+		return
159
+	}
160
+
161
+	channel.Mode(client, msg.changes)
162
+}

+ 2
- 1
irc/reply.go View File

@@ -181,7 +181,8 @@ func (target *Client) RplCreated() {
181 181
 
182 182
 func (target *Client) RplMyInfo() {
183 183
 	target.NumericReply(RPL_MYINFO,
184
-		"%s %s aiOorsw abeIikmntpqrsl", target.server.name, SEM_VER)
184
+		"%s %s %s %s",
185
+		target.server.name, SEM_VER, SupportedUserModes, SupportedChannelModes)
185 186
 }
186 187
 
187 188
 func (target *Client) RplUModeIs(client *Client) {

+ 5
- 70
irc/server.go View File

@@ -94,9 +94,7 @@ func (server *Server) loadChannels() {
94 94
 		log.Fatal("error loading channels: ", err)
95 95
 	}
96 96
 	for rows.Next() {
97
-		var name Name
98
-		var flags string
99
-		var key, topic Text
97
+		var name, flags, key, topic string
100 98
 		var userLimit uint64
101 99
 		var banList, exceptList, inviteList string
102 100
 		err = rows.Scan(&name, &flags, &key, &topic, &userLimit, &banList,
@@ -106,12 +104,12 @@ func (server *Server) loadChannels() {
106 104
 			continue
107 105
 		}
108 106
 
109
-		channel := NewChannel(server, name)
107
+		channel := NewChannel(server, NewName(name))
110 108
 		for _, flag := range flags {
111 109
 			channel.flags[ChannelMode(flag)] = true
112 110
 		}
113
-		channel.key = key
114
-		channel.topic = topic
111
+		channel.key = NewText(key)
112
+		channel.topic = NewText(topic)
115 113
 		channel.userLimit = userLimit
116 114
 		loadChannelList(channel, banList, BanMask)
117 115
 		loadChannelList(channel, exceptList, ExceptMask)
@@ -339,7 +337,7 @@ func (msg *RFC2812UserCommand) HandleRegServer(server *Server) {
339 337
 	}
340 338
 	flags := msg.Flags()
341 339
 	if len(flags) > 0 {
342
-		for _, mode := range msg.Flags() {
340
+		for _, mode := range flags {
343 341
 			client.flags[mode] = true
344 342
 		}
345 343
 		client.RplUModeIs(client)
@@ -491,58 +489,6 @@ func (msg *PrivMsgCommand) HandleServer(server *Server) {
491 489
 	}
492 490
 }
493 491
 
494
-func (m *ModeCommand) HandleServer(s *Server) {
495
-	client := m.Client()
496
-	target := s.clients.Get(m.nickname)
497
-
498
-	if target == nil {
499
-		client.ErrNoSuchNick(m.nickname)
500
-		return
501
-	}
502
-
503
-	if client != target && !client.flags[Operator] {
504
-		client.ErrUsersDontMatch()
505
-		return
506
-	}
507
-
508
-	changes := make(ModeChanges, 0, len(m.changes))
509
-
510
-	for _, change := range m.changes {
511
-		switch change.mode {
512
-		case Invisible, ServerNotice, WallOps:
513
-			switch change.op {
514
-			case Add:
515
-				if target.flags[change.mode] {
516
-					continue
517
-				}
518
-				target.flags[change.mode] = true
519
-				changes = append(changes, change)
520
-
521
-			case Remove:
522
-				if !target.flags[change.mode] {
523
-					continue
524
-				}
525
-				delete(target.flags, change.mode)
526
-				changes = append(changes, change)
527
-			}
528
-
529
-		case Operator, LocalOperator:
530
-			if change.op == Remove {
531
-				if !target.flags[change.mode] {
532
-					continue
533
-				}
534
-				delete(target.flags, change.mode)
535
-				changes = append(changes, change)
536
-			}
537
-		}
538
-	}
539
-
540
-	// Who should get these replies?
541
-	if len(changes) > 0 {
542
-		client.Reply(RplMode(client, target, changes))
543
-	}
544
-}
545
-
546 492
 func (client *Client) WhoisChannelsNames() []string {
547 493
 	chstrs := make([]string, len(client.channels))
548 494
 	index := 0
@@ -579,17 +525,6 @@ func (m *WhoisCommand) HandleServer(server *Server) {
579 525
 	}
580 526
 }
581 527
 
582
-func (msg *ChannelModeCommand) HandleServer(server *Server) {
583
-	client := msg.Client()
584
-	channel := server.channels.Get(msg.channel)
585
-	if channel == nil {
586
-		client.ErrNoSuchChannel(msg.channel)
587
-		return
588
-	}
589
-
590
-	channel.Mode(client, msg.changes)
591
-}
592
-
593 528
 func whoChannel(client *Client, channel *Channel, friends ClientSet) {
594 529
 	for member := range channel.members {
595 530
 		if !client.flags[Invisible] || friends[client] {

+ 0
- 21
irc/types.go View File

@@ -9,27 +9,6 @@ import (
9 9
 // simple types
10 10
 //
11 11
 
12
-// add, remove, list modes
13
-type ModeOp rune
14
-
15
-func (op ModeOp) String() string {
16
-	return string(op)
17
-}
18
-
19
-// user mode flags
20
-type UserMode rune
21
-
22
-func (mode UserMode) String() string {
23
-	return string(mode)
24
-}
25
-
26
-// channel mode flags
27
-type ChannelMode rune
28
-
29
-func (mode ChannelMode) String() string {
30
-	return string(mode)
31
-}
32
-
33 12
 type ChannelNameMap map[Name]*Channel
34 13
 
35 14
 func (channels ChannelNameMap) Get(name Name) *Channel {

Loading…
Cancel
Save