-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmuc.go
More file actions
127 lines (116 loc) · 2.96 KB
/
muc.go
File metadata and controls
127 lines (116 loc) · 2.96 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
package main
import (
"errors"
"fmt"
"strings"
"github.com/shizeeg/xmpp"
)
// Conference a struct contains info about a single conference
type Conference struct {
JID string
Password string
Parser GluxiParser
Joined bool
Occupants []Occupant
}
// Occupant a struct contains info about a single MUC occupant
type Occupant struct {
Nick string // room nickname. REQUIRED
JID string // optional (if available)
Affil string // owner, admin, member, none
Role string // moderator, participant, visitor, none
}
// NickIndex checks if given string is actual nick
// returns index in Conference.Occupants and true, -1, false otherwise.
func (c *Conference) NickIndex(nick string) (index int, found bool) {
for i, o := range c.Occupants {
if nick == o.Nick {
return i, true
}
}
return -1, false
}
// GetOccupantByNick returns index and actual Occupant if existed in conference
func (c *Conference) GetOccupantByNick(nick string) (i int, occ Occupant) {
for i, o := range c.Occupants {
if nick == o.Nick {
return i, o
}
}
return -1, Occupant{}
}
// ChompNick cuts off <nick> part from "nick: message"
func (c *Conference) ChompNick(msg string) string {
if pos := strings.IndexAny(msg, c.Parser.NickSuffixes); pos > 0 {
nick := msg[:pos]
for _, o := range c.Occupants {
if nick == o.Nick {
return msg[pos+1:]
}
}
}
return msg
}
// OccupantAdd adds occupant from <presence> stanza sent on somebody new joins the conference
func (c *Conference) OccupantAdd(stanza *xmpp.MUCPresence) (added Occupant, err error) {
if len(stanza.X) <= 0 {
return Occupant{}, errors.New("no <x /> child in stanza")
}
x := stanza.X[0]
var nick string
if tmp := strings.SplitN(stanza.From, "/", 2); len(tmp) == 2 {
nick = tmp[1]
}
add := func(o Occupant) {
found := false
for i, p := range c.Occupants {
if o.Nick == p.Nick {
c.Occupants[i] = o
found = true
break
}
}
if !found {
c.Occupants = append(c.Occupants, o)
}
}
for _, item := range x.Items {
added := Occupant{
Affil: item.Affil,
Role: item.Role,
Nick: item.Nick,
JID: item.JID,
}
if len(item.Nick) == 0 {
added.Nick = nick
}
add(added)
}
if stanza.IsCode(xmpp.SELF) {
c.Parser.OwnNick = nick
}
return
}
// OccupantDel removes and returnes an occupant from internal representation
func (c *Conference) OccupantDel(stanza *xmpp.MUCPresence) (deleted Occupant, err error) {
if len(stanza.X) == 0 {
return Occupant{}, errors.New("no <x /> child in stanza")
}
//x := stanza.X[0]
var nick string
if tmp := strings.SplitN(stanza.From, "/", 2); len(tmp) == 2 {
nick = tmp[1]
}
for i, o := range c.Occupants {
if nick == o.Nick {
deleted := c.Occupants[i]
copy(c.Occupants[i:], c.Occupants[i+1:])
c.Occupants = c.Occupants[:len(c.Occupants)-1]
return deleted, nil
}
}
return Occupant{}, fmt.Errorf("nick: %q not in %v", nick, c)
}
//func (c *Conference) NickToJids(nick string, last bool) (jids []string, err error) {
//
//}