-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathtarget.go
More file actions
185 lines (157 loc) · 4.22 KB
/
target.go
File metadata and controls
185 lines (157 loc) · 4.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
package sdbot
import (
"fmt"
)
// String values of all the auth levels.
const (
Administrator = `~`
Leader = `&`
RoomOwner = `#`
Moderator = `@`
Driver = `%`
TheImmortal = `>`
Battler = `★`
Voiced = `+`
Unvoiced = ` `
Muted = `?`
Locked = `‽`
)
var authLevels = map[string]int{
Locked: 0,
Muted: 1,
Unvoiced: 2,
Voiced: 3,
Battler: 4,
TheImmortal: 5,
Driver: 6,
Moderator: 7,
RoomOwner: 8,
Leader: 9,
Administrator: 10,
}
// User represents a user with their username and the auth levels in rooms
// that the bot knows about.
type User struct {
Name string
Auths map[string]string
}
// Room represents a room with its name and the users currently in it.
type Room struct {
Name string
Users []string // List of unique SANITIZED names of users in the room
}
// NewUser creates a new User, initializing the Auths map.
func NewUser(name string) *User {
return &User{
Name: name,
Auths: make(map[string]string),
}
}
// Reply responds to a user in private message and prepends the user's name to
// the response.
func (u *User) Reply(m *Message, res string) {
s := fmt.Sprintf("(%s) %s", m.User.Name, res)
if len(s) > 300 {
s = s[:300]
}
m.Bot.Connection.QueueMessage(fmt.Sprintf("|/w %s,%s", u.Name, s))
}
// Reply responds to a user in a chat message and prepends the user's name to
// the response. The message is sent to the Room of the method's receiver.
func (r *Room) Reply(m *Message, res string) {
s := fmt.Sprintf("(%s) %s", m.User.Name, res)
if len(s) > 300 {
s = s[:300]
}
m.Bot.Connection.QueueMessage(fmt.Sprintf("%s|%s", r.Name, s))
}
// RawReply responds to a user in private message without prepending their
// username.
func (u *User) RawReply(m *Message, res string) {
if len(res) > 300 {
res = res[:300]
}
m.Bot.Connection.QueueMessage(fmt.Sprintf("|/w %s,%s", u.Name, res))
}
// RawReply responds to a user in a room without prepending their username.
func (r *Room) RawReply(m *Message, res string) {
if len(res) > 300 {
res = res[:300]
}
m.Bot.Connection.QueueMessage(fmt.Sprintf("%s|%s", r.Name, res))
}
// AddAuth adds a room authority level to a user.
func (u *User) AddAuth(room string, auth string) {
u.Auths[Sanitize(room)] = auth
}
// AddUser adds a user to the room.
func (r *Room) AddUser(name string) {
sn := Sanitize(name)
for _, n := range r.Users {
if n == sn {
return
}
}
r.Users = append(r.Users, sn)
}
// RemoveUser removes a user from the room.
func (r *Room) RemoveUser(name string) {
sn := Sanitize(name)
for i, n := range r.Users {
if n == sn {
r.Users = append(r.Users[:i], r.Users[i+1:]...)
return
}
}
}
// FindUserEnsured finds a user if it exists, creates the user if it doesn't.
func FindUserEnsured(name string, b *Bot) *User {
var updateUsers = func() interface{} {
sn := Sanitize(name)
var u *User
if b.UserList[sn] != nil {
u = b.UserList[sn]
u.Name = name
return u
}
user := NewUser(name)
b.UserList[sn] = user
return user
}
return b.Synchronize("room", &updateUsers).(*User)
}
// FindRoomEnsured finds a room if it exists, creates the room if it doesn't.
func FindRoomEnsured(name string, b *Bot) *Room {
sn := SanitizeRoomid(name)
var updateRooms = func() interface{} {
if b.RoomList[sn] != nil {
return b.RoomList[sn]
}
room := &Room{Name: name}
b.RoomList[sn] = room
return room
}
return b.Synchronize("user", &updateRooms).(*Room)
}
// Rename renames a user and updates their record in the UserList.
func Rename(old string, s string, r *Room, b *Bot, auth string) {
var rename = func() interface{} {
b.RoomList[r.Name].RemoveUser(old)
b.RoomList[r.Name].AddUser(s)
u := FindUserEnsured(s, b)
u.AddAuth(r.Name, auth)
u.Name = s
return nil
}
b.Synchronize("user", &rename)
}
// HasAuth checks if a user has AT LEAST a given authorization level in a given room.
func (u *User) HasAuth(roomname string, level string) bool {
return authLevels[u.Auths[roomname]] >= authLevels[level]
}
// Target represents either a Room or a User. The distinction is in where the bot will
// send its message in response.
type Target interface {
Reply(*Message, string)
RawReply(*Message, string)
}