using System.Collections.ObjectModel; using ArcaneLibs.Extensions; using LibMatrix; using LibMatrix.EventTypes.Spec.State; using LibMatrix.Homeservers; using LibMatrix.Responses; using LibMatrix.RoomTypes; using OsuFederatedBeatmapApi.Events.AccountData; namespace OsuFederatedBeatmapApi.Services; public class FederatedBeatmapApiBotAccountDataService(ILogger logger, AuthenticatedHomeserverGeneric hs, FederatedBeatmapApiBotConfiguration configuration) { private const string BotDataKey = "gay.rory.federated_beatmap_repository_bot_data"; public GenericRoom LogRoom = null!; public GenericRoom ControlRoom = null!; public GenericRoom OwnBeatmapRepositoryRoom = null!; public ObservableCollection ListedRepositories = null!; private BotData botData = null!; public async Task LoadAccountDataAsync() { try { botData = await hs.GetAccountDataAsync(BotDataKey); } catch (Exception e) { if (e is not MatrixException { ErrorCode: "M_NOT_FOUND" }) { logger.LogError("{}", e.ToString()); throw; } botData = new BotData(); } if (string.IsNullOrWhiteSpace(botData.ControlRoom)) { var creationContent = CreateRoomRequest.CreatePrivate(hs, name: "Beatmap Repository - Control room", roomAliasName: $"{hs.UserLocalpart}-control-room"); creationContent.Invite = configuration.Admins; creationContent.CreationContent["type"] = "gay.rory.federated_beatmap_repository.control_room"; botData.ControlRoom = (await hs.CreateRoom(creationContent, true, true, true)).RoomId; } //this doesnt work on conduit yet :c //set access rules to allow joining via control room // creationContent.InitialState.Add(new StateEvent { // Type = "m.room.join_rules", // StateKey = "", // TypedContent = new RoomJoinRulesEventContent { // JoinRule = "knock_restricted", // Allow = new() { // new RoomJoinRulesEventContent.AllowEntry { // Type = "m.room_membership", // RoomId = botData.ControlRoom // } // } // } // }); if (string.IsNullOrWhiteSpace(botData.LogRoom)) { var creationContent = CreateRoomRequest.CreatePrivate(hs, name: "Beatmap Repository - Log room", roomAliasName: $"{hs.UserLocalpart}-log-room"); creationContent.Invite = configuration.Admins; creationContent.CreationContent["type"] = "gay.rory.media_moderator_poc.log_room"; botData.LogRoom = (await hs.CreateRoom(creationContent, true, true, true)).RoomId; } if (string.IsNullOrWhiteSpace(botData.OwnBeatmapRepositoryRoom)) { var creationContent = CreateRoomRequest.CreatePrivate(hs, name: "Beatmap Repository - Own beatmap repository room", roomAliasName: $"{hs.UserLocalpart}-beatmap-repo-room"); creationContent.Invite = configuration.Admins; creationContent.CreationContent["type"] = "gay.rory.media_moderator_poc.beatmap_repository_room"; botData.OwnBeatmapRepositoryRoom = (await hs.CreateRoom(creationContent, true, true, true)).RoomId; } // await hs.SetAccountData(BotDataKey, botData); LogRoom = hs.GetRoom(botData.LogRoom ?? botData.ControlRoom); ControlRoom = hs.GetRoom(botData.ControlRoom); OwnBeatmapRepositoryRoom = hs.GetRoom(botData.OwnBeatmapRepositoryRoom); ListedRepositories = new ObservableCollection(botData.ListedRepositories.Select(hs.GetRoom).ToList()); ListedRepositories.CollectionChanged += async (_, _) => await UpdateAccountData(); if (!ListedRepositories.Any(x => x.RoomId == OwnBeatmapRepositoryRoom.RoomId)) ListedRepositories.Add(OwnBeatmapRepositoryRoom); await UpdateAccountData(); } private async Task UpdateAccountData() { botData.ListedRepositories = ListedRepositories.Select(x => x.RoomId).ToList(); await hs.SetAccountData(BotDataKey, botData); logger.LogInformation("Updated bot account data: {}", botData.ToJson(indent: true, ignoreNull: false)); } }