// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; using System.Linq; using Newtonsoft.Json; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Game.Online.Multiplayer.GameTypes; using osu.Game.Online.Multiplayer.RoomStatuses; using osu.Game.Users; namespace osu.Game.Online.Multiplayer { public class Room { [Cached] [JsonProperty("id")] public Bindable RoomID { get; private set; } = new Bindable(); [Cached] [JsonProperty("name")] public Bindable Name { get; private set; } = new Bindable(); [Cached] [JsonProperty("host")] public Bindable Host { get; private set; } = new Bindable(); [Cached] [JsonProperty("playlist")] public BindableList Playlist { get; private set; } = new BindableList(); [Cached] [JsonProperty("channel_id")] public Bindable ChannelId { get; private set; } = new Bindable(); [Cached] [JsonIgnore] public Bindable Duration { get; private set; } = new Bindable(TimeSpan.FromMinutes(30)); [Cached] [JsonIgnore] public Bindable MaxAttempts { get; private set; } = new Bindable(); [Cached] [JsonIgnore] public Bindable Status { get; private set; } = new Bindable(new RoomStatusOpen()); [Cached] [JsonIgnore] public Bindable Availability { get; private set; } = new Bindable(); [Cached] [JsonIgnore] public Bindable Type { get; private set; } = new Bindable(new GameTypeTimeshift()); [Cached] [JsonIgnore] public Bindable MaxParticipants { get; private set; } = new Bindable(); [Cached] [JsonIgnore] public BindableList Participants { get; private set; } = new BindableList(); [Cached] public Bindable ParticipantCount { get; private set; } = new Bindable(); // todo: TEMPORARY [JsonProperty("participant_count")] private int? participantCount { get => ParticipantCount.Value; set => ParticipantCount.Value = value ?? 0; } [JsonProperty("duration")] private int duration { get => (int)Duration.Value.TotalMinutes; set => Duration.Value = TimeSpan.FromMinutes(value); } // Only supports retrieval for now [Cached] [JsonProperty("ends_at")] public Bindable EndDate { get; private set; } = new Bindable(); // Todo: Find a better way to do this (https://github.com/ppy/osu-framework/issues/1930) [JsonProperty("max_attempts", DefaultValueHandling = DefaultValueHandling.Ignore)] private int? maxAttempts { get => MaxAttempts.Value; set => MaxAttempts.Value = value; } /// /// The position of this in the list. This is not read from or written to the API. /// [JsonIgnore] public Bindable Position { get; private set; } = new Bindable(-1); public void CopyFrom(Room other) { RoomID.Value = other.RoomID.Value; Name.Value = other.Name.Value; if (other.Host.Value != null && Host.Value?.Id != other.Host.Value.Id) Host.Value = other.Host.Value; ChannelId.Value = other.ChannelId.Value; Status.Value = other.Status.Value; Availability.Value = other.Availability.Value; Type.Value = other.Type.Value; MaxParticipants.Value = other.MaxParticipants.Value; ParticipantCount.Value = other.ParticipantCount.Value; EndDate.Value = other.EndDate.Value; if (DateTimeOffset.Now >= EndDate.Value) Status.Value = new RoomStatusEnded(); // transfer local beatmaps across to ensure we have Metadata available (CreateRoomRequest does not give us metadata as expected) foreach (var item in other.Playlist) { var localItem = Playlist.FirstOrDefault(i => i.BeatmapID == item.BeatmapID); if (localItem != null) item.Beatmap.Value.Metadata = localItem.Beatmap.Value.Metadata; } if (!Playlist.SequenceEqual(other.Playlist)) { Playlist.Clear(); Playlist.AddRange(other.Playlist); } if (!Participants.SequenceEqual(other.Participants)) { Participants.Clear(); Participants.AddRange(other.Participants); } Position = other.Position; } public bool ShouldSerializeRoomID() => false; public bool ShouldSerializeHost() => false; public bool ShouldSerializeEndDate() => false; } }