package main import ( "context" "fmt" "log" "slices" "sort" "strings" "github.com/hashicorp/go-version" "github.com/matrix-org/gomatrixserverlib/fclient" "maunium.net/go/mautrix" "maunium.net/go/mautrix/id" "codeberg.org/june64/mrvc/config" "codeberg.org/june64/mrvc/roominfotree" ) func compareVersionStrings(a, b string) int { // Try to parse a and b as versions. // Use only the first part of the version string as sometimes there are suffixes after a space, like " ()", which then can't be parsed. aStart := strings.Split(a, " ")[0] bStart := strings.Split(b, " ")[0] aVersion, aErr := version.NewVersion(aStart) bVersion, bErr := version.NewVersion(bStart) // An input, which can't be parsed as a version, should be interpreted as being smaller than an input, which can be parsed as a version. switch { case aErr != nil && bErr == nil: return -1 case aErr == nil && bErr != nil: return 1 case aErr != nil && bErr != nil: return strings.Compare(a, b) } if cmpResult := aVersion.Compare(bVersion); cmpResult != 0 { return cmpResult } else { // When the versions are equal, look at the potential suffixes in the version string. aEnd := strings.TrimPrefix(a, aStart) bEnd := strings.TrimPrefix(b, bStart) return strings.Compare(aEnd, bEnd) } } func main() { config := config.Get() userId := id.UserID(config.UserID) _, homeserver, err := userId.ParseAndValidate() if err != nil { log.Fatal(err) } clientWellKnown, err := mautrix.DiscoverClientAPI(context.Background(), homeserver) if err != nil { log.Fatal(err) } homeserverURL := clientWellKnown.Homeserver.BaseURL client, err := mautrix.NewClient( homeserverURL, userId, config.Token, ) if err != nil { log.Fatal(err) } federationClient := fclient.NewClient( fclient.WithWellKnownSRVLookups(true), fclient.WithTimeout(config.HomeserverVersionInfoTimeout), ) roomIDSet := make(map[id.RoomID]bool) aliasSetByRoomID := make(map[id.RoomID](map[string]bool)) for _, room := range config.Rooms { // Check, if given room is an alias and try to resolve it into a room id. if strings.HasPrefix(room, "#") { resolvedAlias, err := client.ResolveAlias(context.Background(), id.RoomAlias(room)) if err != nil { log.Fatal(err) } roomIDSet[resolvedAlias.RoomID] = true aliasSet, ok := aliasSetByRoomID[resolvedAlias.RoomID] if !ok { aliasSet = make(map[string]bool) aliasSetByRoomID[resolvedAlias.RoomID] = aliasSet } aliasSet[room] = true } else { roomIDSet[id.RoomID(room)] = true } } roomIDs := make([]id.RoomID, 0, len(roomIDSet)) for roomID := range roomIDSet { roomIDs = append(roomIDs, roomID) } roomInfoTree := roominfotree.Get(roomIDs, client, federationClient) for roomID, roomInfo := range roomInfoTree { fmt.Println("Room:") fmt.Printf(" %s -> %d\n", roomID, roomInfo.MemberCount) aliasSet, ok := aliasSetByRoomID[roomID] if ok { fmt.Println("Given Aliases:") for alias := range aliasSet { fmt.Printf(" %s\n", alias) } } fmt.Println("Version Support:") maxRoomVersionKeys := make([]string, 0, len(roomInfo.MaxRoomVersions)) for key := range roomInfo.MaxRoomVersions { maxRoomVersionKeys = append(maxRoomVersionKeys, key) } slices.SortFunc(maxRoomVersionKeys, compareVersionStrings) for _, maxRoomVersionKey := range maxRoomVersionKeys { maxRoomVersionInfo := roomInfo.MaxRoomVersions[maxRoomVersionKey] fmt.Printf(" %s -> %d\n", maxRoomVersionKey, maxRoomVersionInfo.MemberCount) serverKeys := make([]string, 0, len(maxRoomVersionInfo.Servers)) for key := range maxRoomVersionInfo.Servers { serverKeys = append(serverKeys, key) } sort.Strings(serverKeys) for _, serverKey := range serverKeys { serverInfo := maxRoomVersionInfo.Servers[serverKey] fmt.Printf(" %s -> %d\n", serverKey, serverInfo.MemberCount) versionKeys := make([]string, 0, len(serverInfo.Versions)) for key := range serverInfo.Versions { versionKeys = append(versionKeys, key) } slices.SortFunc(versionKeys, compareVersionStrings) for _, versionKey := range versionKeys { versionInfo := serverInfo.Versions[versionKey] fmt.Printf(" %s -> %d\n", versionKey, versionInfo.MemberCount) if config.PrintHomeserverMemberCount { homeserverKeys := make([]string, 0, len(versionInfo.Homeservers)) for key := range versionInfo.Homeservers { homeserverKeys = append(homeserverKeys, key) } sort.Strings(homeserverKeys) for _, homeserverKey := range homeserverKeys { homeserverInfo := versionInfo.Homeservers[homeserverKey] fmt.Printf(" %s -> %d\n", homeserverKey, homeserverInfo.MemberCount) } } } } } fmt.Println() } }