]> git.xonotic.org Git - xonotic/xonotic.git/blobdiff - misc/infrastructure/powerbot/bot.go
Fix macOS SDL2 framework permissions
[xonotic/xonotic.git] / misc / infrastructure / powerbot / bot.go
index 3566eede8d6b0985e519ade70a2d37cf049c6ba7..b373c8262fa0b1d465eb994d9c5437c29ec7490e 100644 (file)
@@ -15,16 +15,21 @@ import (
 
 const (
        syncInterval       = time.Minute
-       syncForceFrequency = 24 * 60
+       syncForceFrequency = int(7 * 24 * time.Hour / syncInterval)
 )
 
+type Room struct {
+       ID   id.RoomID `json:"id"`
+       Name string    `json:"name",omitempty`
+}
+
 type Config struct {
-       Homeserver  string        `json:"homeserver"`
-       UserID      id.UserID     `json:"user_id"`
-       Password    string        `json:"password,omitempty"`
-       DeviceID    id.DeviceID   `json:"device_id,omitempty"`
-       AccessToken string        `json:"access_token,omitempty"`
-       Rooms       [][]id.RoomID `json:"rooms"`
+       Homeserver  string      `json:"homeserver"`
+       UserID      id.UserID   `json:"user_id"`
+       Password    string      `json:"password,omitempty"`
+       DeviceID    id.DeviceID `json:"device_id,omitempty"`
+       AccessToken string      `json:"access_token,omitempty"`
+       Rooms       [][]Room    `json:"rooms"`
 }
 
 func (c *Config) Load() error {
@@ -46,6 +51,9 @@ func (c *Config) Save() error {
 }
 
 func Login(config *Config) (*mautrix.Client, error) {
+       configMu.Lock()
+       defer configMu.Unlock()
+
        // Note: we have to lower case the user ID for Matrix protocol communication.
        uid := id.UserID(strings.ToLower(string(config.UserID)))
        client, err := mautrix.NewClient(config.Homeserver, uid, config.AccessToken)
@@ -80,8 +88,11 @@ func Login(config *Config) (*mautrix.Client, error) {
 }
 
 var (
-       roomUsers       = map[id.RoomID]map[id.UserID]struct{}{}
-       roomUsersMu     sync.RWMutex
+       configMu sync.Mutex
+
+       roomUsersMu sync.RWMutex
+       roomUsers   = map[id.RoomID]map[id.UserID]struct{}{}
+
        fullySynced     bool
        roomPowerLevels = map[id.RoomID]*event.PowerLevelsEventContent{}
 )
@@ -178,7 +189,7 @@ func Run() (err error) {
        }
        for _, group := range config.Rooms {
                for _, room := range group {
-                       roomUsers[room] = map[id.UserID]struct{}{}
+                       roomUsers[room.ID] = map[id.UserID]struct{}{}
                }
        }
        client, err := Login(config)
@@ -186,6 +197,32 @@ func Run() (err error) {
                return fmt.Errorf("failed to login: %v", err)
        }
        syncer := newSyncer()
+       syncer.OnEventType(event.StateTombstone, func(source mautrix.EventSource, evt *event.Event) {
+               if !isRoom(evt.RoomID) {
+                       return
+               }
+               tomb := evt.Content.AsTombstone()
+               if tomb.ReplacementRoom == "" {
+                       log.Printf("Replacement room in tombstone event is not set - not handling: %v", evt)
+                       return
+               }
+               for _, group := range config.Rooms {
+                       for i := range group {
+                               room := &group[i]
+                               if room.ID == evt.RoomID {
+                                       configMu.Lock()
+                                       defer configMu.Unlock()
+                                       room.ID = tomb.ReplacementRoom
+                                       err := config.Save()
+                                       if err != nil {
+                                               log.Printf("failed to save config: %v", err)
+                                       }
+                                       log.Fatalf("room upgrade for %v handled from %v to %v - need restart", room.Name, evt.RoomID, tomb.ReplacementRoom)
+                               }
+                       }
+               }
+               log.Printf("Room not found in config, so not doing room upgrade: %v", evt)
+       })
        syncer.OnEventType(event.EventMessage, func(source mautrix.EventSource, evt *event.Event) {
                if !isRoom(evt.RoomID) {
                        return
@@ -223,7 +260,7 @@ func Run() (err error) {
                if since != "" && !fullySynced {
                        log.Print("Fully synced.")
                        for room, users := range roomUsers {
-                               if len(users) == 0 {
+                               if _, found := users[config.UserID]; !found {
                                        log.Printf("Not actually joined %v yet...", room)
                                        _, err := client.JoinRoom(string(room), "", nil)
                                        if err != nil {
@@ -254,7 +291,7 @@ func Run() (err error) {
                        }
                        for _, group := range config.Rooms {
                                for _, room := range group {
-                                       syncPowerLevels(client, room, group, scoreData, counter%syncForceFrequency == 0)
+                                       syncPowerLevels(client, room.ID, group, scoreData, counter%syncForceFrequency == 0)
                                }
                        }
                        roomUsersMu.RUnlock()