mirror of
https://github.com/ppy/osu.git
synced 2024-11-06 06:17:23 +08:00
Merge pull request #210 from peppy/online-improvements
Add login support, better API state change handling.
This commit is contained in:
commit
20947623d5
@ -1 +1 @@
|
||||
Subproject commit ab7b953ec9393d8df5aeb23d23e8b1f8154601c1
|
||||
Subproject commit 6edd5eacdd25cc8c4f4dbca3414678c0b7dc5deb
|
@ -14,9 +14,9 @@ using osu.Game;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Online.Chat;
|
||||
using osu.Game.Online.Chat.Display;
|
||||
using OpenTK;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Online.Chat.Drawables;
|
||||
|
||||
namespace osu.Desktop.VisualTests.Tests
|
||||
{
|
||||
@ -45,7 +45,7 @@ namespace osu.Desktop.VisualTests.Tests
|
||||
{
|
||||
base.Reset();
|
||||
|
||||
if (api.State != APIAccess.APIState.Online)
|
||||
if (api.State != APIState.Online)
|
||||
api.OnStateChange += delegate { initializeChannels(); };
|
||||
else
|
||||
initializeChannels();
|
||||
@ -65,7 +65,7 @@ namespace osu.Desktop.VisualTests.Tests
|
||||
{
|
||||
careChannels = new List<Channel>();
|
||||
|
||||
if (api.State != APIAccess.APIState.Online)
|
||||
if (api.State != APIState.Online)
|
||||
return;
|
||||
|
||||
Add(flow = new FlowContainer
|
||||
|
@ -12,6 +12,7 @@ using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Backgrounds;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
@ -128,45 +129,5 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public class Triangles : Container
|
||||
{
|
||||
private Texture triangle;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
{
|
||||
triangle = textures.Get(@"Play/osu/triangle@2x");
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
Add(new Sprite
|
||||
{
|
||||
Texture = triangle,
|
||||
Origin = Anchor.TopCentre,
|
||||
RelativePositionAxes = Axes.Both,
|
||||
Position = new Vector2(RNG.NextSingle(), RNG.NextSingle()),
|
||||
Scale = new Vector2(RNG.NextSingle() * 0.4f + 0.2f),
|
||||
Alpha = RNG.NextSingle() * 0.3f
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
foreach (Drawable d in Children)
|
||||
{
|
||||
d.Position -= new Vector2(0, (float)(d.Scale.X * (Time.Elapsed / 880)));
|
||||
if (d.DrawPosition.Y + d.DrawSize.Y * d.Scale.Y < 0)
|
||||
d.MoveToY(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ namespace osu.Game.Configuration
|
||||
Set(OsuConfig.AudioDevice, string.Empty);
|
||||
//Set(OsuConfig.ReleaseStream, ReleaseStream.Lazer, true);
|
||||
Set(OsuConfig.UpdateFailCount, 0);
|
||||
//Set(OsuConfig.SavePassword, Password != null);
|
||||
Set(OsuConfig.SavePassword, false);
|
||||
Set(OsuConfig.SaveUsername, true);
|
||||
//Set(OsuConfig.TreeSortMode, TreeGroupMode.Show_All);
|
||||
//Set(OsuConfig.TreeSortMode2, TreeSortMode.Title);
|
||||
|
85
osu.Game/Graphics/Backgrounds/Triangles.cs
Normal file
85
osu.Game/Graphics/Backgrounds/Triangles.cs
Normal file
@ -0,0 +1,85 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.MathUtils;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Graphics.Backgrounds
|
||||
{
|
||||
public class Triangles : Container
|
||||
{
|
||||
private Texture triangle;
|
||||
|
||||
public Triangles()
|
||||
{
|
||||
Alpha = 0.3f;
|
||||
}
|
||||
|
||||
private float triangleScale = 1;
|
||||
|
||||
public float TriangleScale
|
||||
{
|
||||
get { return triangleScale; }
|
||||
set
|
||||
{
|
||||
triangleScale = value;
|
||||
|
||||
Children.ForEach(t => t.ScaleTo(triangleScale));
|
||||
}
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
{
|
||||
triangle = textures.Get(@"Play/osu/triangle@2x");
|
||||
}
|
||||
|
||||
private int aimTriangleCount => (int)((DrawWidth * DrawHeight) / 800 / triangleScale);
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
foreach (Drawable d in Children)
|
||||
{
|
||||
d.Position -= new Vector2(0, (float)(d.Scale.X * (50 / DrawHeight) * (Time.Elapsed / 880)) / triangleScale);
|
||||
if (d.DrawPosition.Y + d.DrawSize.Y * d.Scale.Y < 0)
|
||||
d.Expire();
|
||||
}
|
||||
|
||||
bool useRandomX = Children.Count() < aimTriangleCount / 2;
|
||||
while (Children.Count() < aimTriangleCount)
|
||||
addTriangle(useRandomX);
|
||||
|
||||
}
|
||||
|
||||
protected virtual Sprite CreateTriangle()
|
||||
{
|
||||
var scale = triangleScale * RNG.NextSingle() * 0.4f + 0.2f;
|
||||
|
||||
return new Sprite
|
||||
{
|
||||
Texture = triangle,
|
||||
Origin = Anchor.TopCentre,
|
||||
RelativePositionAxes = Axes.Both,
|
||||
Scale = new Vector2(scale),
|
||||
Alpha = RNG.NextSingle(),
|
||||
Depth = scale,
|
||||
};
|
||||
}
|
||||
|
||||
private void addTriangle(bool randomX)
|
||||
{
|
||||
var sprite = CreateTriangle();
|
||||
sprite.Position = new Vector2(RNG.NextSingle(), randomX ? RNG.NextSingle() : 1);
|
||||
Add(sprite);
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ using osu.Framework.Input;
|
||||
using OpenTK;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics.Transformations;
|
||||
|
||||
namespace osu.Game.Graphics.Containers
|
||||
{
|
||||
@ -35,11 +36,16 @@ namespace osu.Game.Graphics.Containers
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
bool firstUpdate = true;
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
content.Position = (ToLocalSpace(input.CurrentState.Mouse.NativeState.Position) - DrawSize / 2) * ParallaxAmount;
|
||||
|
||||
content.MoveTo((ToLocalSpace(input.CurrentState.Mouse.NativeState.Position) - DrawSize / 2) * ParallaxAmount, firstUpdate ? 0 : 1000, EasingTypes.OutQuint);
|
||||
content.Scale = new Vector2(1 + ParallaxAmount);
|
||||
|
||||
firstUpdate = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ namespace osu.Game.Graphics.Cursor
|
||||
float distance = diff.Length;
|
||||
Vector2 direction = diff / distance;
|
||||
|
||||
float interval = size.X / 2;
|
||||
float interval = (size.X / 2) * 0.9f;
|
||||
|
||||
for (float d = interval; d < distance; d += interval)
|
||||
{
|
||||
|
@ -3,9 +3,12 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Online.API.Requests;
|
||||
@ -17,8 +20,8 @@ namespace osu.Game.Online.API
|
||||
private OAuth authentication;
|
||||
|
||||
public string Endpoint = @"https://new.ppy.sh";
|
||||
const string ClientId = @"daNBnfdv7SppRVc61z0XuOI13y6Hroiz";
|
||||
const string ClientSecret = @"d6fgZuZeQ0eSXkEj5igdqQX6ztdtS6Ow";
|
||||
const string ClientId = @"5";
|
||||
const string ClientSecret = @"FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk";
|
||||
|
||||
ConcurrentQueue<APIRequest> queue = new ConcurrentQueue<APIRequest>();
|
||||
|
||||
@ -26,15 +29,11 @@ namespace osu.Game.Online.API
|
||||
|
||||
public string Username;
|
||||
|
||||
private SecurePassword password;
|
||||
//private SecurePassword password;
|
||||
|
||||
public string Password
|
||||
{
|
||||
set
|
||||
{
|
||||
password = string.IsNullOrEmpty(value) ? null : new SecurePassword(value);
|
||||
}
|
||||
}
|
||||
public string Password;
|
||||
|
||||
public Bindable<User> LocalUser = new Bindable<User>();
|
||||
|
||||
public string Token
|
||||
{
|
||||
@ -50,7 +49,7 @@ namespace osu.Game.Online.API
|
||||
}
|
||||
}
|
||||
|
||||
protected bool HasLogin => Token != null || (!string.IsNullOrEmpty(Username) && password != null);
|
||||
protected bool HasLogin => Token != null || (!string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Password));
|
||||
|
||||
private Thread thread;
|
||||
|
||||
@ -65,6 +64,25 @@ namespace osu.Game.Online.API
|
||||
thread.Start();
|
||||
}
|
||||
|
||||
private List<IOnlineComponent> components = new List<IOnlineComponent>();
|
||||
|
||||
public void Register(IOnlineComponent component)
|
||||
{
|
||||
Scheduler.Add(delegate
|
||||
{
|
||||
components.Add(component);
|
||||
component.APIStateChanged(this, state);
|
||||
});
|
||||
}
|
||||
|
||||
public void Unregister(IOnlineComponent component)
|
||||
{
|
||||
Scheduler.Add(delegate
|
||||
{
|
||||
components.Remove(component);
|
||||
});
|
||||
}
|
||||
|
||||
public string AccessToken => authentication.RequestAccessToken();
|
||||
|
||||
/// <summary>
|
||||
@ -102,7 +120,7 @@ namespace osu.Game.Online.API
|
||||
if (State < APIState.Connecting)
|
||||
State = APIState.Connecting;
|
||||
|
||||
if (!authentication.HasValidAccessToken && !authentication.AuthenticateWithLogin(Username, password.Get(Representation.Raw)))
|
||||
if (!authentication.HasValidAccessToken && !authentication.AuthenticateWithLogin(Username, Password))
|
||||
{
|
||||
//todo: this fails even on network-related issues. we should probably handle those differently.
|
||||
//NotificationManager.ShowMessage("Login failed!");
|
||||
@ -111,6 +129,17 @@ namespace osu.Game.Online.API
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
var userReq = new GetUserRequest();
|
||||
userReq.Success += (u) => {
|
||||
LocalUser.Value = u;
|
||||
};
|
||||
if (!handleRequest(userReq))
|
||||
{
|
||||
State = APIState.Failing;
|
||||
continue;
|
||||
}
|
||||
|
||||
//we're connected!
|
||||
State = APIState.Online;
|
||||
failureCount = 0;
|
||||
@ -142,7 +171,17 @@ namespace osu.Game.Online.API
|
||||
private void ClearCredentials()
|
||||
{
|
||||
Username = null;
|
||||
password = null;
|
||||
Password = null;
|
||||
}
|
||||
|
||||
public void Login(string username, string password)
|
||||
{
|
||||
Debug.Assert(State == APIState.Offline);
|
||||
|
||||
Username = username;
|
||||
Password = password;
|
||||
|
||||
State = APIState.Connecting;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -154,6 +193,7 @@ namespace osu.Game.Online.API
|
||||
{
|
||||
try
|
||||
{
|
||||
Logger.Log($@"Performing request {req}", LoggingTarget.Network);
|
||||
req.Perform(this);
|
||||
|
||||
State = APIState.Online;
|
||||
@ -221,6 +261,7 @@ namespace osu.Game.Online.API
|
||||
log.Add($@"We just went {newState}!");
|
||||
Scheduler.Add(delegate
|
||||
{
|
||||
components.ForEach(c => c.APIStateChanged(this, newState));
|
||||
OnStateChange?.Invoke(oldState, newState);
|
||||
});
|
||||
}
|
||||
@ -237,29 +278,6 @@ namespace osu.Game.Online.API
|
||||
|
||||
public delegate void StateChangeDelegate(APIState oldState, APIState newState);
|
||||
|
||||
public enum APIState
|
||||
{
|
||||
/// <summary>
|
||||
/// We cannot login (not enough credentials).
|
||||
/// </summary>
|
||||
Offline,
|
||||
|
||||
/// <summary>
|
||||
/// We are having connectivity issues.
|
||||
/// </summary>
|
||||
Failing,
|
||||
|
||||
/// <summary>
|
||||
/// We are in the process of (re-)connecting.
|
||||
/// </summary>
|
||||
Connecting,
|
||||
|
||||
/// <summary>
|
||||
/// We are online.
|
||||
/// </summary>
|
||||
Online
|
||||
}
|
||||
|
||||
private void flushQueue(bool failOldRequests = true)
|
||||
{
|
||||
var oldQueue = queue;
|
||||
@ -277,6 +295,7 @@ namespace osu.Game.Online.API
|
||||
|
||||
public void Logout()
|
||||
{
|
||||
ClearCredentials();
|
||||
authentication.Clear();
|
||||
State = APIState.Offline;
|
||||
}
|
||||
@ -286,4 +305,27 @@ namespace osu.Game.Online.API
|
||||
Scheduler.Update();
|
||||
}
|
||||
}
|
||||
|
||||
public enum APIState
|
||||
{
|
||||
/// <summary>
|
||||
/// We cannot login (not enough credentials).
|
||||
/// </summary>
|
||||
Offline,
|
||||
|
||||
/// <summary>
|
||||
/// We are having connectivity issues.
|
||||
/// </summary>
|
||||
Failing,
|
||||
|
||||
/// <summary>
|
||||
/// We are in the process of (re-)connecting.
|
||||
/// </summary>
|
||||
Connecting,
|
||||
|
||||
/// <summary>
|
||||
/// We are online.
|
||||
/// </summary>
|
||||
Online
|
||||
}
|
||||
}
|
||||
|
16
osu.Game/Online/API/IOnlineComponent.cs
Normal file
16
osu.Game/Online/API/IOnlineComponent.cs
Normal file
@ -0,0 +1,16 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace osu.Game.Online.API
|
||||
{
|
||||
public interface IOnlineComponent
|
||||
{
|
||||
void APIStateChanged(APIAccess api, APIState state);
|
||||
}
|
||||
}
|
@ -30,7 +30,7 @@ namespace osu.Game.Online.API
|
||||
{
|
||||
var req = new AccessTokenRequestPassword(username, password)
|
||||
{
|
||||
Url = $@"{endpoint}/oauth/access_token",
|
||||
Url = $@"{endpoint}/oauth/token",
|
||||
Method = HttpMethod.POST,
|
||||
ClientId = clientId,
|
||||
ClientSecret = clientSecret
|
||||
@ -55,7 +55,7 @@ namespace osu.Game.Online.API
|
||||
{
|
||||
var req = new AccessTokenRequestRefresh(refresh)
|
||||
{
|
||||
Url = $@"{endpoint}/oauth/access_token",
|
||||
Url = $@"{endpoint}/oauth/token",
|
||||
Method = HttpMethod.POST,
|
||||
ClientId = clientId,
|
||||
ClientSecret = clientSecret
|
||||
|
18
osu.Game/Online/API/Requests/GetUserRequest.cs
Normal file
18
osu.Game/Online/API/Requests/GetUserRequest.cs
Normal file
@ -0,0 +1,18 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class GetUserRequest : APIRequest<User>
|
||||
{
|
||||
private int? userId;
|
||||
|
||||
public GetUserRequest(int? userId = null)
|
||||
{
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
protected override string Target => userId.HasValue ? $@"users/{userId}" : @"me";
|
||||
}
|
||||
}
|
@ -4,15 +4,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Transformations;
|
||||
using OpenTK;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
|
||||
namespace osu.Game.Online.Chat.Display
|
||||
namespace osu.Game.Online.Chat.Drawables
|
||||
{
|
||||
public class ChannelDisplay : Container
|
||||
{
|
@ -8,7 +8,7 @@ using osu.Framework.Graphics.Sprites;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Online.Chat.Display
|
||||
namespace osu.Game.Online.Chat.Drawables
|
||||
{
|
||||
public class ChatLine : Container
|
||||
{
|
@ -10,6 +10,9 @@ namespace osu.Game.Online
|
||||
[JsonProperty(@"username")]
|
||||
public string Name;
|
||||
|
||||
[JsonProperty(@"id")]
|
||||
public int Id;
|
||||
|
||||
[JsonProperty(@"colour")]
|
||||
public string Colour;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ using osu.Game.Database;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics.Transformations;
|
||||
using osu.Game.Modes;
|
||||
using osu.Game.Overlays.Toolbar;
|
||||
using osu.Game.Screens;
|
||||
using osu.Game.Screens.Menu;
|
||||
using osu.Game.Screens.Play;
|
||||
@ -31,7 +32,7 @@ namespace osu.Game
|
||||
{
|
||||
public Toolbar Toolbar;
|
||||
|
||||
private ChatConsole chat;
|
||||
private ChatOverlay chat;
|
||||
|
||||
private MusicController musicController;
|
||||
|
||||
@ -116,7 +117,7 @@ namespace osu.Game
|
||||
});
|
||||
|
||||
//overlay elements
|
||||
(chat = new ChatConsole(API) { Depth = 0 }).Preload(this, overlayContent.Add);
|
||||
(chat = new ChatOverlay { Depth = 0 }).Preload(this, overlayContent.Add);
|
||||
(Options = new OptionsOverlay { Depth = -1 }).Preload(this, overlayContent.Add);
|
||||
(musicController = new MusicController() { Depth = -3 }).Preload(this, overlayContent.Add);
|
||||
(Toolbar = new Toolbar
|
||||
|
@ -16,12 +16,14 @@ using osu.Game.Database;
|
||||
using osu.Game.Graphics.Cursor;
|
||||
using osu.Game.Graphics.Processing;
|
||||
using osu.Game.IPC;
|
||||
using osu.Game.Online;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Online.API.Requests;
|
||||
|
||||
namespace osu.Game
|
||||
{
|
||||
public class OsuGameBase : BaseGame
|
||||
public class OsuGameBase : BaseGame, IOnlineComponent
|
||||
{
|
||||
internal OsuConfigManager Config;
|
||||
|
||||
@ -43,7 +45,7 @@ namespace osu.Game
|
||||
Dependencies.Cache(this);
|
||||
Dependencies.Cache(Config);
|
||||
Dependencies.Cache(new BeatmapDatabase(Host.Storage, Host));
|
||||
|
||||
|
||||
//this completely overrides the framework default. will need to change once we make a proper FontStore.
|
||||
Dependencies.Cache(Fonts = new FontStore { ScaleAdjust = 0.01f }, true);
|
||||
|
||||
@ -73,6 +75,19 @@ namespace osu.Game
|
||||
Password = Config.Get<string>(OsuConfig.Password),
|
||||
Token = Config.Get<string>(OsuConfig.Token)
|
||||
});
|
||||
|
||||
API.Register(this);
|
||||
}
|
||||
|
||||
public void APIStateChanged(APIAccess api, APIState state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case APIState.Online:
|
||||
Config.Set(OsuConfig.Username, Config.Get<bool>(OsuConfig.SaveUsername) ? API.Username : string.Empty);
|
||||
Config.Set(OsuConfig.Password, Config.Get<bool>(OsuConfig.SavePassword) ? API.Password : string.Empty);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
|
@ -1,12 +1,12 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
@ -16,11 +16,11 @@ using osu.Framework.Threading;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Online.Chat;
|
||||
using osu.Game.Online.Chat.Display;
|
||||
using osu.Game.Online.Chat.Drawables;
|
||||
|
||||
namespace osu.Game.Overlays
|
||||
{
|
||||
public class ChatConsole : OverlayContainer
|
||||
public class ChatOverlay : OverlayContainer, IOnlineComponent
|
||||
{
|
||||
private ChannelDisplay channelDisplay;
|
||||
|
||||
@ -32,10 +32,8 @@ namespace osu.Game.Overlays
|
||||
|
||||
private APIAccess api;
|
||||
|
||||
public ChatConsole(APIAccess api)
|
||||
public ChatOverlay()
|
||||
{
|
||||
this.api = api;
|
||||
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Size = new Vector2(1, 300);
|
||||
Anchor = Anchor.BottomLeft;
|
||||
@ -57,50 +55,16 @@ namespace osu.Game.Overlays
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
private void load(APIAccess api)
|
||||
{
|
||||
initializeChannels();
|
||||
this.api = api;
|
||||
api.Register(this);
|
||||
}
|
||||
|
||||
private long? lastMessageId;
|
||||
|
||||
private List<Channel> careChannels;
|
||||
|
||||
private void initializeChannels()
|
||||
{
|
||||
careChannels = new List<Channel>();
|
||||
|
||||
//if (api.State != APIAccess.APIState.Online)
|
||||
// return;
|
||||
|
||||
SpriteText loading;
|
||||
Add(loading = new SpriteText
|
||||
{
|
||||
Text = @"Loading available channels...",
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
TextSize = 40,
|
||||
});
|
||||
|
||||
messageRequest?.Cancel();
|
||||
|
||||
ListChannelsRequest req = new ListChannelsRequest();
|
||||
req.Success += delegate (List<Channel> channels)
|
||||
{
|
||||
Scheduler.Add(delegate
|
||||
{
|
||||
loading.FadeOut(100);
|
||||
addChannel(channels.Find(c => c.Name == @"#osu"));
|
||||
});
|
||||
|
||||
//addChannel(channels.Find(c => c.Name == @"#lobby"));
|
||||
//addChannel(channels.Find(c => c.Name == @"#english"));
|
||||
|
||||
messageRequest = Scheduler.AddDelayed(() => FetchNewMessages(api), 1000, true);
|
||||
};
|
||||
api.Queue(req);
|
||||
}
|
||||
|
||||
private void addChannel(Channel channel)
|
||||
{
|
||||
Add(channelDisplay = new ChannelDisplay(channel));
|
||||
@ -145,8 +109,58 @@ namespace osu.Game.Overlays
|
||||
|
||||
protected override void PopOut()
|
||||
{
|
||||
MoveToY(DrawSize.Y, transition_length, EasingTypes.InQuint);
|
||||
FadeOut(transition_length, EasingTypes.InQuint);
|
||||
MoveToY(DrawSize.Y, transition_length, EasingTypes.InSine);
|
||||
FadeOut(transition_length, EasingTypes.InSine);
|
||||
}
|
||||
|
||||
public void APIStateChanged(APIAccess api, APIState state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case APIState.Online:
|
||||
initializeChannels();
|
||||
break;
|
||||
default:
|
||||
messageRequest?.Cancel();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeChannels()
|
||||
{
|
||||
Clear();
|
||||
|
||||
careChannels = new List<Channel>();
|
||||
|
||||
//if (api.State != APIAccess.APIState.Online)
|
||||
// return;
|
||||
|
||||
SpriteText loading;
|
||||
Add(loading = new SpriteText
|
||||
{
|
||||
Text = @"Loading available channels...",
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
TextSize = 40,
|
||||
});
|
||||
|
||||
messageRequest?.Cancel();
|
||||
|
||||
ListChannelsRequest req = new ListChannelsRequest();
|
||||
req.Success += delegate (List<Channel> channels)
|
||||
{
|
||||
Scheduler.Add(delegate
|
||||
{
|
||||
loading.FadeOut(100);
|
||||
addChannel(channels.Find(c => c.Name == @"#osu"));
|
||||
});
|
||||
|
||||
//addChannel(channels.Find(c => c.Name == @"#lobby"));
|
||||
//addChannel(channels.Find(c => c.Name == @"#english"));
|
||||
|
||||
messageRequest = Scheduler.AddDelayed(() => FetchNewMessages(api), 1000, true);
|
||||
};
|
||||
api.Queue(req);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using OpenTK;
|
||||
using System;
|
||||
using OpenTK;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
@ -10,38 +11,72 @@ using osu.Game.Online.API;
|
||||
|
||||
namespace osu.Game.Overlays.Options.General
|
||||
{
|
||||
public class LoginOptions : OptionsSubsection
|
||||
public class LoginOptions : OptionsSubsection, IOnlineComponent
|
||||
{
|
||||
private Container loginForm;
|
||||
protected override string Header => "Sign In";
|
||||
|
||||
public LoginOptions()
|
||||
{
|
||||
Children = new[]
|
||||
{
|
||||
loginForm = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Children = new[] { new LoadingAnimation() }
|
||||
}
|
||||
};
|
||||
}
|
||||
private Action performLogout;
|
||||
protected override string Header => "Sign In";
|
||||
|
||||
[BackgroundDependencyLoader(permitNulls: true)]
|
||||
private void load(APIAccess api)
|
||||
{
|
||||
api?.Register(this);
|
||||
}
|
||||
|
||||
public void APIStateChanged(APIAccess api, APIState state)
|
||||
{
|
||||
if (api == null)
|
||||
return;
|
||||
loginForm.Children = new Drawable[]
|
||||
switch (state)
|
||||
{
|
||||
new LoginForm(api)
|
||||
};
|
||||
case APIState.Offline:
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new LoginForm()
|
||||
};
|
||||
break;
|
||||
case APIState.Failing:
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new SpriteText
|
||||
{
|
||||
Text = "Connection failing :(",
|
||||
},
|
||||
};
|
||||
break;
|
||||
case APIState.Connecting:
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new SpriteText
|
||||
{
|
||||
Text = "Connecting...",
|
||||
},
|
||||
};
|
||||
break;
|
||||
case APIState.Online:
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new SpriteText
|
||||
{
|
||||
Text = $"Connected as {api.Username}!",
|
||||
},
|
||||
new OsuButton
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Text = "Sign out",
|
||||
Action = api.Logout
|
||||
}
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
class LoginForm : FlowContainer
|
||||
{
|
||||
public LoginForm(APIAccess api)
|
||||
private TextBox username;
|
||||
private TextBox password;
|
||||
private APIAccess api;
|
||||
|
||||
public LoginForm()
|
||||
{
|
||||
Direction = FlowDirection.VerticalOnly;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
@ -51,16 +86,29 @@ namespace osu.Game.Overlays.Options.General
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new SpriteText { Text = "Username" },
|
||||
new TextBox { Height = 20, RelativeSizeAxes = Axes.X, Text = api?.Username ?? string.Empty },
|
||||
username = new TextBox { Height = 20, RelativeSizeAxes = Axes.X, Text = api?.Username ?? string.Empty },
|
||||
new SpriteText { Text = "Password" },
|
||||
new TextBox { Height = 20, RelativeSizeAxes = Axes.X },
|
||||
password = new PasswordTextBox { Height = 20, RelativeSizeAxes = Axes.X },
|
||||
new OsuButton
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Text = "Log in",
|
||||
Action = performLogin
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void performLogin()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(username.Text) && !string.IsNullOrEmpty(password.Text))
|
||||
api.Login(username.Text, password.Text);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader(permitNulls: true)]
|
||||
private void load(APIAccess api)
|
||||
{
|
||||
this.api = api;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,22 +2,21 @@
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Transformations;
|
||||
using osu.Framework.Input;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Game.Modes;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Framework.Input;
|
||||
using osu.Game.Online.API;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays
|
||||
namespace osu.Game.Overlays.Toolbar
|
||||
{
|
||||
public class Toolbar : OverlayContainer
|
||||
{
|
||||
@ -29,7 +28,6 @@ namespace osu.Game.Overlays
|
||||
public Action OnMusicController;
|
||||
|
||||
private ToolbarModeSelector modeSelector;
|
||||
private ToolbarButton userButton;
|
||||
private Box solidBackground;
|
||||
private Box gradientBackground;
|
||||
|
||||
@ -127,10 +125,7 @@ namespace osu.Game.Overlays
|
||||
{
|
||||
Icon = FontAwesome.fa_search
|
||||
},
|
||||
userButton = new ToolbarButton
|
||||
{
|
||||
Icon = FontAwesome.fa_user,
|
||||
},
|
||||
new ToolbarUserButton(),
|
||||
new ToolbarButton
|
||||
{
|
||||
Icon = FontAwesome.fa_bars
|
||||
@ -143,12 +138,6 @@ namespace osu.Game.Overlays
|
||||
Size = new Vector2(1, height);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuConfigManager config)
|
||||
{
|
||||
userButton.Text = config.Get<string>(OsuConfig.Username);
|
||||
}
|
||||
|
||||
public void SetGameMode(PlayMode mode) => modeSelector.SetGameMode(mode);
|
||||
}
|
||||
}
|
@ -4,20 +4,19 @@
|
||||
using System;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Transformations;
|
||||
using osu.Framework.Input;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Backgrounds;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
|
||||
namespace osu.Game.Overlays
|
||||
namespace osu.Game.Overlays.Toolbar
|
||||
{
|
||||
public class ToolbarButton : Container
|
||||
{
|
||||
public const float WIDTH = 60;
|
||||
|
||||
public FontAwesome Icon
|
||||
{
|
||||
get { return DrawableIcon.Icon; }
|
||||
@ -58,6 +57,7 @@ namespace osu.Game.Overlays
|
||||
private FlowContainer tooltipContainer;
|
||||
private SpriteText tooltip1;
|
||||
private SpriteText tooltip2;
|
||||
protected FlowContainer Flow;
|
||||
|
||||
public ToolbarButton()
|
||||
{
|
||||
@ -66,16 +66,17 @@ namespace osu.Game.Overlays
|
||||
HoverBackground = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = new Color4(80, 80, 80, 180),
|
||||
BlendingMode = BlendingMode.Additive,
|
||||
Colour = new Color4(60, 60, 60, 255),
|
||||
Alpha = 0,
|
||||
},
|
||||
new FlowContainer
|
||||
Flow = new FlowContainer
|
||||
{
|
||||
Direction = FlowDirection.HorizontalOnly,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Padding = new MarginPadding { Left = 5, Right = 5 },
|
||||
Padding = new MarginPadding { Left = 15, Right = 15 },
|
||||
Spacing = new Vector2(5),
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
AutoSizeAxes = Axes.X,
|
||||
Children = new Drawable[]
|
||||
@ -87,7 +88,6 @@ namespace osu.Game.Overlays
|
||||
},
|
||||
DrawableText = new SpriteText
|
||||
{
|
||||
Margin = new MarginPadding { Left = 5 },
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
},
|
||||
@ -118,7 +118,6 @@ namespace osu.Game.Overlays
|
||||
};
|
||||
|
||||
RelativeSizeAxes = Axes.Y;
|
||||
Size = new Vector2(WIDTH, 1);
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
@ -126,7 +125,7 @@ namespace osu.Game.Overlays
|
||||
base.Update();
|
||||
|
||||
//todo: find a way to avoid using this (autosize needs to be able to ignore certain drawables.. in this case the tooltip)
|
||||
Size = new Vector2(WIDTH + (DrawableText.IsVisible ? DrawableText.DrawSize.X : 0), 1);
|
||||
Size = new Vector2(Flow.DrawSize.X, 1);
|
||||
}
|
||||
|
||||
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) => true;
|
||||
@ -134,21 +133,44 @@ namespace osu.Game.Overlays
|
||||
protected override bool OnClick(InputState state)
|
||||
{
|
||||
Action?.Invoke();
|
||||
HoverBackground.FlashColour(Color4.White, 400);
|
||||
HoverBackground.FlashColour(new Color4(255, 255, 255, 180), 800, EasingTypes.OutQuint);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override bool OnHover(InputState state)
|
||||
{
|
||||
HoverBackground.FadeTo(0.4f, 200);
|
||||
HoverBackground.FadeIn(200);
|
||||
tooltipContainer.FadeIn(100);
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(InputState state)
|
||||
{
|
||||
HoverBackground.FadeTo(0, 200);
|
||||
HoverBackground.FadeOut(200);
|
||||
tooltipContainer.FadeOut(100);
|
||||
}
|
||||
}
|
||||
|
||||
public class OpaqueBackground : Container
|
||||
{
|
||||
public OpaqueBackground()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
Masking = true;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = new Color4(30, 30, 30, 255)
|
||||
},
|
||||
new Triangles
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0.05f,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -2,14 +2,12 @@
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Modes;
|
||||
using osu.Game.Screens.Play;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays
|
||||
namespace osu.Game.Overlays.Toolbar
|
||||
{
|
||||
public class ToolbarModeButton : ToolbarButton
|
||||
{
|
||||
@ -30,7 +28,23 @@ namespace osu.Game.Overlays
|
||||
{
|
||||
set
|
||||
{
|
||||
//Background.Colour = value ? new Color4(100, 100, 100, 255) : new Color4(20, 20, 20, 255);
|
||||
if (value)
|
||||
{
|
||||
DrawableIcon.Colour = Color4.White;
|
||||
DrawableIcon.Masking = true;
|
||||
DrawableIcon.EdgeEffect = new EdgeEffect
|
||||
{
|
||||
Type = EdgeEffectType.Glow,
|
||||
Colour = new Color4(255, 194, 224, 100),
|
||||
Radius = 15,
|
||||
Roundness = 15,
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawableIcon.Masking = false;
|
||||
DrawableIcon.Colour = new Color4(255, 194, 224, 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,26 +3,25 @@
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using osu.Framework.Caching;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Transformations;
|
||||
using osu.Game.Graphics.Backgrounds;
|
||||
using osu.Game.Modes;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Caching;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Modes;
|
||||
using osu.Game.Screens.Play;
|
||||
|
||||
namespace osu.Game.Overlays
|
||||
namespace osu.Game.Overlays.Toolbar
|
||||
{
|
||||
class ToolbarModeSelector : Container
|
||||
{
|
||||
const float padding = 10;
|
||||
|
||||
private FlowContainer modeButtons;
|
||||
private Box modeButtonLine;
|
||||
private Drawable modeButtonLine;
|
||||
private ToolbarModeButton activeButton;
|
||||
|
||||
public Action<PlayMode> OnPlayModeChange;
|
||||
@ -33,11 +32,7 @@ namespace osu.Game.Overlays
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = new Color4(20, 20, 20, 255)
|
||||
},
|
||||
new OpaqueBackground(),
|
||||
modeButtons = new FlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
@ -45,14 +40,29 @@ namespace osu.Game.Overlays
|
||||
Direction = FlowDirection.HorizontalOnly,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Padding = new MarginPadding { Left = 10, Right = 10 },
|
||||
},
|
||||
modeButtonLine = new Box
|
||||
modeButtonLine = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Size = new Vector2(0.3f, 3),
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.TopCentre,
|
||||
Colour = Color4.White
|
||||
Origin = Anchor.TopLeft,
|
||||
Masking = true,
|
||||
EdgeEffect = new EdgeEffect
|
||||
{
|
||||
Type = EdgeEffectType.Glow,
|
||||
Colour = new Color4(255, 194, 224, 100),
|
||||
Radius = 15,
|
||||
Roundness = 15,
|
||||
},
|
||||
Children = new []
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -72,9 +82,13 @@ namespace osu.Game.Overlays
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// We need to set the size within LoadComplete, because
|
||||
Size = new Vector2(amountButtons * ToolbarButton.WIDTH + padding * 2, 1);
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
Size = new Vector2(modeButtons.DrawSize.X, 1);
|
||||
}
|
||||
|
||||
public void SetGameMode(PlayMode mode)
|
||||
@ -97,7 +111,7 @@ namespace osu.Game.Overlays
|
||||
base.UpdateLayout();
|
||||
|
||||
if (!activeMode.EnsureValid())
|
||||
activeMode.Refresh(() => modeButtonLine.MoveToX(activeButton.DrawPosition.X + activeButton.DrawSize.X / 2 + padding, 200, EasingTypes.OutQuint));
|
||||
activeMode.Refresh(() => modeButtonLine.MoveToX(activeButton.DrawPosition.X, 200, EasingTypes.OutQuint));
|
||||
}
|
||||
}
|
||||
}
|
140
osu.Game/Overlays/Toolbar/ToolbarUserButton.cs
Normal file
140
osu.Game/Overlays/Toolbar/ToolbarUserButton.cs
Normal file
@ -0,0 +1,140 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Online.API;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.Toolbar
|
||||
{
|
||||
class ToolbarUserButton : ToolbarButton, IOnlineComponent
|
||||
{
|
||||
private Avatar avatar;
|
||||
|
||||
public ToolbarUserButton()
|
||||
{
|
||||
DrawableText.Font = @"Exo2.0-MediumItalic";
|
||||
|
||||
Add(new OpaqueBackground { Depth = 1 });
|
||||
|
||||
Flow.Add(avatar = new Avatar());
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(APIAccess api, OsuConfigManager config)
|
||||
{
|
||||
api.Register(this);
|
||||
}
|
||||
|
||||
public void APIStateChanged(APIAccess api, APIState state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
default:
|
||||
Text = @"Guest";
|
||||
avatar.UserId = 1;
|
||||
break;
|
||||
case APIState.Online:
|
||||
Text = api.Username;
|
||||
avatar.UserId = api.LocalUser.Value.Id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public class Avatar : Container
|
||||
{
|
||||
public Drawable Sprite;
|
||||
|
||||
private int userId;
|
||||
private OsuGame game;
|
||||
private Texture guestTexture;
|
||||
|
||||
public Avatar()
|
||||
{
|
||||
Size = new Vector2(32);
|
||||
Anchor = Anchor.CentreLeft;
|
||||
Origin = Anchor.CentreLeft;
|
||||
|
||||
CornerRadius = Size.X / 8;
|
||||
|
||||
EdgeEffect = new EdgeEffect
|
||||
{
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Radius = 4,
|
||||
Colour = new Color4(0, 0, 0, 0.1f),
|
||||
};
|
||||
|
||||
Masking = true;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGame game, TextureStore textures)
|
||||
{
|
||||
this.game = game;
|
||||
|
||||
guestTexture = textures.Get(@"Online/avatar-guest@2x");
|
||||
}
|
||||
|
||||
public int UserId
|
||||
{
|
||||
get { return userId; }
|
||||
set
|
||||
{
|
||||
if (userId == value)
|
||||
return;
|
||||
|
||||
userId = value;
|
||||
|
||||
Sprite newSprite;
|
||||
if (userId > 1)
|
||||
newSprite = new OnlineSprite($@"https://a.ppy.sh/{userId}");
|
||||
else
|
||||
newSprite = new Sprite { Texture = guestTexture };
|
||||
|
||||
newSprite.FillMode = FillMode.Fit;
|
||||
|
||||
newSprite.Preload(game, s =>
|
||||
{
|
||||
Sprite?.FadeOut();
|
||||
Sprite?.Expire();
|
||||
Sprite = s;
|
||||
|
||||
Add(s);
|
||||
|
||||
s.FadeInFromZero(200);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class OnlineSprite : Sprite
|
||||
{
|
||||
private readonly string url;
|
||||
private readonly int userId;
|
||||
|
||||
public OnlineSprite(string url)
|
||||
{
|
||||
Debug.Assert(url != null);
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
{
|
||||
Texture = textures.Get(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@ using osu.Framework.Audio.Track;
|
||||
using osu.Framework.GameModes;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Transformations;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Screens.Backgrounds;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
@ -34,13 +35,21 @@ namespace osu.Game.Screens.Menu
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
logo = new OsuLogo()
|
||||
new ParallaxContainer
|
||||
{
|
||||
Alpha = 0,
|
||||
BlendingMode = BlendingMode.Additive,
|
||||
Interactive = false,
|
||||
Colour = Color4.DarkGray,
|
||||
Ripple = false
|
||||
ParallaxAmount = 0.01f,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
logo = new OsuLogo
|
||||
{
|
||||
Alpha = 0,
|
||||
Triangles = false,
|
||||
BlendingMode = BlendingMode.Additive,
|
||||
Interactive = false,
|
||||
Colour = Color4.DarkGray,
|
||||
Ripple = false
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -2,14 +2,19 @@
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Graphics.Transformations;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Game.Graphics.Backgrounds;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Menu
|
||||
{
|
||||
@ -21,16 +26,27 @@ namespace osu.Game.Screens.Menu
|
||||
private Sprite logo;
|
||||
private CircularContainer logoContainer;
|
||||
private Container logoBounceContainer;
|
||||
private Container logoHoverContainer;
|
||||
private MenuVisualisation vis;
|
||||
|
||||
private Container colourAndTriangles;
|
||||
|
||||
public Action Action;
|
||||
|
||||
public float SizeForFlow => logo == null ? 0 : logo.DrawSize.X * logo.Scale.X * logoBounceContainer.Scale.X * 0.8f;
|
||||
public float SizeForFlow => logo == null ? 0 : logo.DrawSize.X * logo.Scale.X * logoBounceContainer.Scale.X * logoHoverContainer.Scale.X * 0.78f;
|
||||
|
||||
private Sprite ripple;
|
||||
|
||||
private Container rippleContainer;
|
||||
|
||||
public bool Triangles
|
||||
{
|
||||
set
|
||||
{
|
||||
colourAndTriangles.Alpha = value ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Contains(Vector2 screenSpacePos)
|
||||
{
|
||||
return logoContainer.Contains(screenSpacePos);
|
||||
@ -61,41 +77,77 @@ namespace osu.Game.Screens.Menu
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
logoContainer = new CircularContainer
|
||||
logoHoverContainer = new Container
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
Children = new[]
|
||||
{
|
||||
logo = new Sprite
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
},
|
||||
},
|
||||
},
|
||||
rippleContainer = new Container
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
ripple = new Sprite()
|
||||
new BufferedContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
logoContainer = new CircularContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Scale = new Vector2(0.8f),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
colourAndTriangles = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = new Color4(233, 103, 161, 255),
|
||||
},
|
||||
new OsuLogoTriangles
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
},
|
||||
},
|
||||
logo = new Sprite
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Scale = new Vector2(0.5f),
|
||||
},
|
||||
}
|
||||
},
|
||||
rippleContainer = new Container
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
ripple = new Sprite()
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
BlendingMode = BlendingMode.Additive,
|
||||
Scale = new Vector2(0.5f),
|
||||
Alpha = 0.15f
|
||||
}
|
||||
}
|
||||
},
|
||||
vis = new MenuVisualisation
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = logo.Size,
|
||||
BlendingMode = BlendingMode.Additive,
|
||||
Alpha = 0.05f
|
||||
Alpha = 0.2f,
|
||||
}
|
||||
}
|
||||
},
|
||||
vis = new MenuVisualisation
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = logo.Size,
|
||||
BlendingMode = BlendingMode.Additive,
|
||||
Alpha = 0.2f,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -105,15 +157,15 @@ namespace osu.Game.Screens.Menu
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
{
|
||||
logo.Texture = textures.Get(@"Menu/logo");
|
||||
ripple.Texture = textures.Get(@"Menu/logo");
|
||||
logo.Texture = textures.Get(@"Menu/logo@2x");
|
||||
ripple.Texture = textures.Get(@"Menu/logo@2x");
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
ripple.ScaleTo(1.1f, 500);
|
||||
ripple.ScaleTo(ripple.Scale * 1.1f, 500);
|
||||
ripple.FadeOut(500);
|
||||
ripple.Loop(300);
|
||||
}
|
||||
@ -122,14 +174,14 @@ namespace osu.Game.Screens.Menu
|
||||
{
|
||||
if (!Interactive) return false;
|
||||
|
||||
logoBounceContainer.ScaleTo(1.1f, 1000, EasingTypes.Out);
|
||||
logoBounceContainer.ScaleTo(0.9f, 1000, EasingTypes.Out);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
|
||||
{
|
||||
|
||||
logoBounceContainer.ScaleTo(1.2f, 500, EasingTypes.OutElastic);
|
||||
logoBounceContainer.ScaleTo(1f, 500, EasingTypes.OutElastic);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -144,13 +196,39 @@ namespace osu.Game.Screens.Menu
|
||||
protected override bool OnHover(InputState state)
|
||||
{
|
||||
if (!Interactive) return false;
|
||||
logoBounceContainer.ScaleTo(1.2f, 500, EasingTypes.OutElastic);
|
||||
logoHoverContainer.ScaleTo(1.2f, 500, EasingTypes.OutElastic);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(InputState state)
|
||||
{
|
||||
logoBounceContainer.ScaleTo(1, 500, EasingTypes.OutElastic);
|
||||
logoHoverContainer.ScaleTo(1, 500, EasingTypes.OutElastic);
|
||||
}
|
||||
|
||||
class OsuLogoTriangles : Triangles
|
||||
{
|
||||
public OsuLogoTriangles()
|
||||
{
|
||||
TriangleScale = 4;
|
||||
Alpha = 1;
|
||||
}
|
||||
|
||||
protected override Sprite CreateTriangle()
|
||||
{
|
||||
var triangle = base.CreateTriangle();
|
||||
triangle.Alpha = 1;
|
||||
triangle.Colour = getTriangleShade();
|
||||
return triangle;
|
||||
}
|
||||
|
||||
private Color4 getTriangleShade()
|
||||
{
|
||||
float val = RNG.NextSingle();
|
||||
return Interpolation.ValueAt(val,
|
||||
new Color4(222, 91, 149, 255),
|
||||
new Color4(255, 125, 183, 255),
|
||||
0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -64,11 +64,14 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Beatmaps\Drawables\BeatmapBackgroundSprite.cs" />
|
||||
<Compile Include="Graphics\Backgrounds\Triangles.cs" />
|
||||
<Compile Include="Graphics\Cursor\CursorTrail.cs" />
|
||||
<Compile Include="Graphics\UserInterface\BackButton.cs" />
|
||||
<Compile Include="Modes\Objects\HitObjectParser.cs" />
|
||||
<Compile Include="Modes\Score.cs" />
|
||||
<Compile Include="Modes\ScoreProcesssor.cs" />
|
||||
<Compile Include="Online\API\IOnlineComponent.cs" />
|
||||
<Compile Include="Online\API\Requests\GetUserRequest.cs" />
|
||||
<Compile Include="Overlays\DragBar.cs" />
|
||||
<Compile Include="Overlays\MusicController.cs" />
|
||||
<Compile Include="Beatmaps\Beatmap.cs" />
|
||||
@ -89,6 +92,7 @@
|
||||
<Compile Include="Beatmaps\Timing\SampleChange.cs" />
|
||||
<Compile Include="Beatmaps\Timing\TimingChange.cs" />
|
||||
<Compile Include="Configuration\OsuConfigManager.cs" />
|
||||
<Compile Include="Overlays\Toolbar\ToolbarUserButton.cs" />
|
||||
<Compile Include="Screens\BackgroundMode.cs" />
|
||||
<Compile Include="Screens\Backgrounds\BackgroundModeBeatmap.cs" />
|
||||
<Compile Include="Screens\Backgrounds\BackgroundModeCustom.cs" />
|
||||
@ -150,18 +154,18 @@
|
||||
<Compile Include="Online\API\SecurePassword.cs" />
|
||||
<Compile Include="Online\API\Requests\ListChannels.cs" />
|
||||
<Compile Include="Online\Chat\Channel.cs" />
|
||||
<Compile Include="Online\Chat\Display\ChannelDisplay.cs" />
|
||||
<Compile Include="Online\Chat\Display\ChatLine.cs" />
|
||||
<Compile Include="Online\Chat\Drawables\ChannelDisplay.cs" />
|
||||
<Compile Include="Online\Chat\Drawables\ChatLine.cs" />
|
||||
<Compile Include="Online\Chat\Message.cs" />
|
||||
<Compile Include="Online\User.cs" />
|
||||
<Compile Include="OsuGame.cs" />
|
||||
<Compile Include="OsuGameBase.cs" />
|
||||
<Compile Include="Overlays\ChatConsole.cs" />
|
||||
<Compile Include="Overlays\ChatOverlay.cs" />
|
||||
<Compile Include="Overlays\OptionsOverlay.cs" />
|
||||
<Compile Include="Overlays\Toolbar.cs" />
|
||||
<Compile Include="Overlays\ToolbarButton.cs" />
|
||||
<Compile Include="Overlays\ToolbarModeButton.cs" />
|
||||
<Compile Include="Overlays\ToolbarModeSelector.cs" />
|
||||
<Compile Include="Overlays\Toolbar\Toolbar.cs" />
|
||||
<Compile Include="Overlays\Toolbar\ToolbarButton.cs" />
|
||||
<Compile Include="Overlays\Toolbar\ToolbarModeButton.cs" />
|
||||
<Compile Include="Overlays\Toolbar\ToolbarModeSelector.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Screens\Select\BeatmapInfoWedge.cs" />
|
||||
<Compile Include="Users\User.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user