Fix filling presence db, fix ban by useragent
This commit is contained in:
@@ -632,8 +632,8 @@ func (j *Jabber) ParseEvent(e any) { //nolint:maintidx,gocognit,gocyclo
|
||||
}
|
||||
} else {
|
||||
log.Infof(
|
||||
"Presence notification, Type: %s, From: %s, To: %s Show: %s, Status: %s, Affiliation: %s, Role: %s, JID: %s",
|
||||
v.Type, v.From, v.To, v.Show, v.Status, v.Affiliation, v.Role, v.JID,
|
||||
"Presence notification, Type: %s, From: %s, To: %s Show: %s, Status: %s, Affiliation: %s, Role: %s, JID: %s, Priority: %s",
|
||||
v.Type, v.From, v.To, v.Show, v.Status, v.Affiliation, v.Role, v.JID, v.Priority,
|
||||
)
|
||||
|
||||
if !strings.Contains(v.From, "/") {
|
||||
@@ -642,6 +642,12 @@ func (j *Jabber) ParseEvent(e any) { //nolint:maintidx,gocognit,gocyclo
|
||||
return
|
||||
}
|
||||
|
||||
if v.JID == "" {
|
||||
log.Info("Useless presence notification without JID field, skipping")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
room := strings.SplitN(v.From, "/", 2)[0]
|
||||
nick := strings.SplitN(v.From, "/", 2)[1]
|
||||
|
||||
@@ -651,68 +657,167 @@ func (j *Jabber) ParseEvent(e any) { //nolint:maintidx,gocognit,gocyclo
|
||||
return
|
||||
}
|
||||
|
||||
// Это наш собственный Presence.
|
||||
if v.Show == "" && v.Status == "" {
|
||||
if nick == j.GetBotNickFromRoomConfig(room) {
|
||||
j.RoomsConnected = append(j.RoomsConnected, room)
|
||||
// На всякий случай дедуплицируем список комнат, к которым мы заджойнились.
|
||||
sort.Strings(j.RoomsConnected)
|
||||
// На всякий случай добавим комнату, из которой пришло уведомление в список тех, в которые вхож бот.
|
||||
if nick == j.GetBotNickFromRoomConfig(room) {
|
||||
j.RoomsConnected = append(j.RoomsConnected, room)
|
||||
// На всякий случай дедуплицируем список комнат, к которым мы заджойнились.
|
||||
sort.Strings(j.RoomsConnected)
|
||||
|
||||
j.RoomsConnected = slices.Compact(j.RoomsConnected)
|
||||
}
|
||||
j.RoomsConnected = slices.Compact(j.RoomsConnected)
|
||||
}
|
||||
|
||||
switch v.Role {
|
||||
// Участник ушёл.
|
||||
case "none":
|
||||
var (
|
||||
newPresences = make([]xmpp.Presence, 0)
|
||||
presenceJSON []byte
|
||||
ok bool
|
||||
presences []xmpp.Presence
|
||||
)
|
||||
|
||||
// Обновлять базу имеет смысл только если есть хоть какая-то запись о комнате в ней.
|
||||
if presenceJSONInterface, present := j.RoomPresences.Get(room); present {
|
||||
presenceJSONStrings := InterfaceToStringSlice(presenceJSONInterface)
|
||||
presenceJSON, ok = presenceJSONInterface.([]byte)
|
||||
|
||||
var newPresenceJSONStrings []string
|
||||
if !ok {
|
||||
log.Errorf("Looks like we have corrupted entry in presence db")
|
||||
|
||||
for _, presenceJSONstring := range presenceJSONStrings {
|
||||
var p xmpp.Presence
|
||||
return
|
||||
}
|
||||
|
||||
_ = json.Unmarshal([]byte(presenceJSONstring), &p)
|
||||
if err := json.Unmarshal(presenceJSON, &presences); err != nil {
|
||||
log.Errorf("Looks like we have corrupted entry in presence db")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
for _, p := range presences { //nolint: gocritic // Развели тут, блять, страну советов, напиши что надо сделать кодом, сука.
|
||||
// Если находим, что у нас уже есть клиент с таким же From, то есть полным nick-ом (для groupchat)
|
||||
// пропускаем его.
|
||||
if p.From == v.From {
|
||||
if j.C.Debug.PresenceDB {
|
||||
log.Debugf("Skipping presence for %s in room %s", v.JID, room)
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
newPresenceJSONStrings = append(newPresenceJSONStrings, presenceJSONstring)
|
||||
if j.C.Debug.PresenceDB {
|
||||
log.Debugf("Appending presence for %s in room %s", v.JID, room)
|
||||
}
|
||||
|
||||
newPresences = append(newPresences, p)
|
||||
}
|
||||
|
||||
j.RoomPresences.Set(room, newPresenceJSONStrings)
|
||||
presenceJSON, _ = json.Marshal(newPresences) //nolint: errchkjson
|
||||
|
||||
if j.C.Debug.PresenceDB {
|
||||
log.Debugf("Updating presence db for room %s", room)
|
||||
}
|
||||
|
||||
j.RoomPresences.Set(room, presenceJSON)
|
||||
|
||||
// Больше нам, похоже с этим уведомлением нечего.
|
||||
return
|
||||
}
|
||||
// Участник пришёл.
|
||||
|
||||
// Участник пришёл или изменил свой статус.
|
||||
default:
|
||||
var (
|
||||
presenceJSONStrings []string
|
||||
newPresenceJSONStrings []string
|
||||
presenceJSONBytes []byte
|
||||
newPresences = make([]xmpp.Presence, 0)
|
||||
presenceJSON []byte
|
||||
ok bool
|
||||
presences []xmpp.Presence
|
||||
skip bool
|
||||
)
|
||||
|
||||
if presenceJSONInterface, present := j.RoomPresences.Get(room); present {
|
||||
presenceJSONStrings = InterfaceToStringSlice(presenceJSONInterface)
|
||||
}
|
||||
presenceJSON, ok = presenceJSONInterface.([]byte)
|
||||
if !ok {
|
||||
log.Errorf("Looks like we have corrupted entry in presence db")
|
||||
|
||||
for _, presenceJSONString := range presenceJSONStrings {
|
||||
var p xmpp.Presence
|
||||
|
||||
_ = json.Unmarshal([]byte(presenceJSONString), &p)
|
||||
|
||||
// Если находим, что у нас уже есть клиент с таким же From, то есть полным nick-ом (для groupchat)
|
||||
// просто замещаем его.
|
||||
if p.From == v.From {
|
||||
continue
|
||||
return
|
||||
}
|
||||
|
||||
newPresenceJSONStrings = append(newPresenceJSONStrings, presenceJSONString)
|
||||
// Если мы нашли запись о комнате, то её надо обновить.
|
||||
if err := json.Unmarshal(presenceJSON, &presences); err != nil {
|
||||
log.Errorf("Looks like we have corrupted entry in presence db")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
for _, p := range presences { //nolint: gocritic // Развели тут, блять, страну советов, напиши что надо сделать кодом, сука.
|
||||
// Если находим, что у нас уже есть клиент с таким же From, то есть полным nick-ом (для groupchat)
|
||||
// запоминаем его и добавим позднее.
|
||||
if p.From == v.From {
|
||||
// Запоминаем участника только если его роль не поменялась на outcast. (То есть если это не
|
||||
// бан.)
|
||||
if v.Role == "outcast" {
|
||||
if j.C.Debug.PresenceDB {
|
||||
log.Debugf("Let's forget about %s because it is outcast/banned", p.JID)
|
||||
}
|
||||
|
||||
skip = true
|
||||
} else if j.C.Debug.PresenceDB {
|
||||
log.Debugf("Skip adding %s to presences for %s, add as last one", p.JID, room)
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if j.C.Debug.PresenceDB {
|
||||
log.Debugf("Appending presence for %s in room %s", v.JID, room)
|
||||
}
|
||||
|
||||
newPresences = append(newPresences, p)
|
||||
}
|
||||
}
|
||||
|
||||
presenceJSONBytes, _ = json.Marshal(v) //nolint:errchkjson
|
||||
newPresenceJSONStrings = append(newPresenceJSONStrings, string(presenceJSONBytes))
|
||||
j.RoomPresences.Set(room, newPresenceJSONStrings)
|
||||
if !skip {
|
||||
if j.C.Debug.PresenceDB {
|
||||
log.Debugf("Appending presence for %s in room %s", v.JID, room)
|
||||
}
|
||||
|
||||
newPresences = append(newPresences, v)
|
||||
} else if j.C.Debug.PresenceDB {
|
||||
log.Debugf("Skip Appending outcast presence for %s in room %s", v.JID, room)
|
||||
}
|
||||
|
||||
presenceJSON, _ = json.Marshal(newPresences) //nolint: errchkjson
|
||||
|
||||
if j.C.Debug.PresenceDB {
|
||||
log.Debugf("Updating presence db for room %s", room)
|
||||
}
|
||||
|
||||
j.RoomPresences.Set(room, presenceJSON)
|
||||
}
|
||||
|
||||
if j.C.Debug.PresenceDB {
|
||||
log.Debugf("List of presence entries in presence db of %s:", room)
|
||||
|
||||
if presenceJSONInterface, present := j.RoomPresences.Get(room); present {
|
||||
var presences []xmpp.Presence
|
||||
|
||||
presenceJSON, ok := presenceJSONInterface.([]byte)
|
||||
|
||||
if !ok {
|
||||
log.Debugf("Looks like we have corrupted entry in presence db")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Если мы нашли запись о комнате, то её надо обновить.
|
||||
if err := json.Unmarshal(presenceJSON, &presences); err != nil {
|
||||
log.Debugf("Looks like we have corrupted entry in presence db")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
for _, p := range presences { //nolint: gocritic // Развели тут, блять, страну советов, напиши что надо сделать кодом, сука.
|
||||
log.Debugf("Found presence for %s from %s", p.JID, room)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Проверяем, а не злодей ли зашёл? Сделать это мы можем, только если мы находимся в комнате.
|
||||
|
||||
Reference in New Issue
Block a user