mirror of
https://github.com/osukey/osukey.git
synced 2025-08-04 15:16:38 +09:00
Merge remote-tracking branch 'origin/master' into user-registration
This commit is contained in:
@ -9,7 +9,6 @@ using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Users;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
|
||||
@ -20,7 +19,6 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
private const float height = 50;
|
||||
|
||||
private readonly UpdateableAvatar avatar;
|
||||
private readonly ClickableArea clickableArea;
|
||||
private readonly FillFlowContainer fields;
|
||||
|
||||
private BeatmapSetInfo beatmapSet;
|
||||
@ -73,7 +71,7 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
clickableArea = new ClickableArea
|
||||
new Container
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
CornerRadius = 3,
|
||||
@ -100,14 +98,8 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(UserProfileOverlay profile)
|
||||
private void load()
|
||||
{
|
||||
clickableArea.Action = () =>
|
||||
{
|
||||
if (avatar.User != null) profile?.ShowUser(avatar.User);
|
||||
};
|
||||
|
||||
updateDisplay();
|
||||
}
|
||||
|
||||
|
@ -10,11 +10,11 @@ using osu.Framework.Input.Events;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Leaderboards;
|
||||
using osu.Game.Overlays.Profile.Sections.Ranks;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Overlays.BeatmapSet.Scores
|
||||
|
@ -12,12 +12,12 @@ using osu.Framework.Input.Events;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Leaderboards;
|
||||
using osu.Game.Overlays.Profile.Sections.Ranks;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Overlays.BeatmapSet.Scores
|
||||
|
@ -1,72 +1,38 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.Chat;
|
||||
using osu.Game.Users;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.Chat
|
||||
{
|
||||
public class ChatLine : Container
|
||||
public class ChatLine : CompositeDrawable
|
||||
{
|
||||
private static readonly Color4[] username_colours =
|
||||
{
|
||||
OsuColour.FromHex("588c7e"),
|
||||
OsuColour.FromHex("b2a367"),
|
||||
OsuColour.FromHex("c98f65"),
|
||||
OsuColour.FromHex("bc5151"),
|
||||
OsuColour.FromHex("5c8bd6"),
|
||||
OsuColour.FromHex("7f6ab7"),
|
||||
OsuColour.FromHex("a368ad"),
|
||||
OsuColour.FromHex("aa6880"),
|
||||
public const float LEFT_PADDING = default_message_padding + default_horizontal_padding * 2;
|
||||
|
||||
OsuColour.FromHex("6fad9b"),
|
||||
OsuColour.FromHex("f2e394"),
|
||||
OsuColour.FromHex("f2ae72"),
|
||||
OsuColour.FromHex("f98f8a"),
|
||||
OsuColour.FromHex("7daef4"),
|
||||
OsuColour.FromHex("a691f2"),
|
||||
OsuColour.FromHex("c894d3"),
|
||||
OsuColour.FromHex("d895b0"),
|
||||
private const float default_message_padding = 200;
|
||||
|
||||
OsuColour.FromHex("53c4a1"),
|
||||
OsuColour.FromHex("eace5c"),
|
||||
OsuColour.FromHex("ea8c47"),
|
||||
OsuColour.FromHex("fc4f4f"),
|
||||
OsuColour.FromHex("3d94ea"),
|
||||
OsuColour.FromHex("7760ea"),
|
||||
OsuColour.FromHex("af52c6"),
|
||||
OsuColour.FromHex("e25696"),
|
||||
protected virtual float MessagePadding => default_message_padding;
|
||||
|
||||
OsuColour.FromHex("677c66"),
|
||||
OsuColour.FromHex("9b8732"),
|
||||
OsuColour.FromHex("8c5129"),
|
||||
OsuColour.FromHex("8c3030"),
|
||||
OsuColour.FromHex("1f5d91"),
|
||||
OsuColour.FromHex("4335a5"),
|
||||
OsuColour.FromHex("812a96"),
|
||||
OsuColour.FromHex("992861"),
|
||||
};
|
||||
private const float default_horizontal_padding = 15;
|
||||
|
||||
public const float LEFT_PADDING = message_padding + padding * 2;
|
||||
protected virtual float HorizontalPadding => default_horizontal_padding;
|
||||
|
||||
private const float padding = 15;
|
||||
private const float message_padding = 200;
|
||||
private const float action_padding = 3;
|
||||
private const float text_size = 20;
|
||||
protected virtual float TextSize => 20;
|
||||
|
||||
private Color4 customUsernameColour;
|
||||
|
||||
@ -75,14 +41,13 @@ namespace osu.Game.Overlays.Chat
|
||||
public ChatLine(Message message)
|
||||
{
|
||||
Message = message;
|
||||
|
||||
Padding = new MarginPadding { Left = HorizontalPadding, Right = HorizontalPadding };
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
|
||||
Padding = new MarginPadding { Left = padding, Right = padding };
|
||||
}
|
||||
|
||||
private ChannelManager chatManager;
|
||||
[Resolved(CanBeNull = true)]
|
||||
private ChannelManager chatManager { get; set; }
|
||||
|
||||
private Message message;
|
||||
private OsuSpriteText username;
|
||||
@ -106,10 +71,9 @@ namespace osu.Game.Overlays.Chat
|
||||
}
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(OsuColour colours, ChannelManager chatManager)
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
this.chatManager = chatManager;
|
||||
customUsernameColour = colours.ChatBlue;
|
||||
}
|
||||
|
||||
@ -125,7 +89,7 @@ namespace osu.Game.Overlays.Chat
|
||||
{
|
||||
Font = @"Exo2.0-BoldItalic",
|
||||
Colour = hasBackground ? customUsernameColour : username_colours[message.Sender.Id % username_colours.Length],
|
||||
TextSize = text_size,
|
||||
TextSize = TextSize,
|
||||
};
|
||||
|
||||
if (hasBackground)
|
||||
@ -163,11 +127,11 @@ namespace osu.Game.Overlays.Chat
|
||||
};
|
||||
}
|
||||
|
||||
Children = new Drawable[]
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
Size = new Vector2(message_padding, text_size),
|
||||
Size = new Vector2(MessagePadding, TextSize),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
timestamp = new OsuSpriteText
|
||||
@ -176,7 +140,7 @@ namespace osu.Game.Overlays.Chat
|
||||
Origin = Anchor.CentreLeft,
|
||||
Font = @"Exo2.0-SemiBold",
|
||||
FixedWidth = true,
|
||||
TextSize = text_size * 0.75f,
|
||||
TextSize = TextSize * 0.75f,
|
||||
},
|
||||
new MessageSender(message.Sender)
|
||||
{
|
||||
@ -191,7 +155,7 @@ namespace osu.Game.Overlays.Chat
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding { Left = message_padding + padding },
|
||||
Padding = new MarginPadding { Left = MessagePadding + HorizontalPadding },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
contentFlow = new LinkFlowContainer(t =>
|
||||
@ -204,7 +168,7 @@ namespace osu.Game.Overlays.Chat
|
||||
t.Colour = OsuColour.FromHex(message.Sender.Colour);
|
||||
}
|
||||
|
||||
t.TextSize = text_size;
|
||||
t.TextSize = TextSize;
|
||||
})
|
||||
{
|
||||
AutoSizeAxes = Axes.Y,
|
||||
@ -257,5 +221,44 @@ namespace osu.Game.Overlays.Chat
|
||||
new OsuMenuItem("Start Chat", MenuItemType.Standard, startChatAction),
|
||||
};
|
||||
}
|
||||
|
||||
private static readonly Color4[] username_colours =
|
||||
{
|
||||
OsuColour.FromHex("588c7e"),
|
||||
OsuColour.FromHex("b2a367"),
|
||||
OsuColour.FromHex("c98f65"),
|
||||
OsuColour.FromHex("bc5151"),
|
||||
OsuColour.FromHex("5c8bd6"),
|
||||
OsuColour.FromHex("7f6ab7"),
|
||||
OsuColour.FromHex("a368ad"),
|
||||
OsuColour.FromHex("aa6880"),
|
||||
|
||||
OsuColour.FromHex("6fad9b"),
|
||||
OsuColour.FromHex("f2e394"),
|
||||
OsuColour.FromHex("f2ae72"),
|
||||
OsuColour.FromHex("f98f8a"),
|
||||
OsuColour.FromHex("7daef4"),
|
||||
OsuColour.FromHex("a691f2"),
|
||||
OsuColour.FromHex("c894d3"),
|
||||
OsuColour.FromHex("d895b0"),
|
||||
|
||||
OsuColour.FromHex("53c4a1"),
|
||||
OsuColour.FromHex("eace5c"),
|
||||
OsuColour.FromHex("ea8c47"),
|
||||
OsuColour.FromHex("fc4f4f"),
|
||||
OsuColour.FromHex("3d94ea"),
|
||||
OsuColour.FromHex("7760ea"),
|
||||
OsuColour.FromHex("af52c6"),
|
||||
OsuColour.FromHex("e25696"),
|
||||
|
||||
OsuColour.FromHex("677c66"),
|
||||
OsuColour.FromHex("9b8732"),
|
||||
OsuColour.FromHex("8c5129"),
|
||||
OsuColour.FromHex("8c3030"),
|
||||
OsuColour.FromHex("1f5d91"),
|
||||
OsuColour.FromHex("4335a5"),
|
||||
OsuColour.FromHex("812a96"),
|
||||
OsuColour.FromHex("992861"),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ namespace osu.Game.Overlays.Chat
|
||||
public class DrawableChannel : Container
|
||||
{
|
||||
public readonly Channel Channel;
|
||||
private readonly ChatLineContainer flow;
|
||||
protected readonly ChatLineContainer ChatLineFlow;
|
||||
private readonly ScrollContainer scroll;
|
||||
|
||||
public DrawableChannel(Channel channel)
|
||||
@ -38,7 +38,7 @@ namespace osu.Game.Overlays.Chat
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Child = flow = new ChatLineContainer
|
||||
Child = ChatLineFlow = new ChatLineContainer
|
||||
{
|
||||
Padding = new MarginPadding { Left = 20, Right = 20 },
|
||||
RelativeSizeAxes = Axes.X,
|
||||
@ -72,17 +72,19 @@ namespace osu.Game.Overlays.Chat
|
||||
Channel.PendingMessageResolved -= pendingMessageResolved;
|
||||
}
|
||||
|
||||
protected virtual ChatLine CreateChatLine(Message m) => new ChatLine(m);
|
||||
|
||||
private void newMessagesArrived(IEnumerable<Message> newMessages)
|
||||
{
|
||||
// Add up to last Channel.MAX_HISTORY messages
|
||||
var displayMessages = newMessages.Skip(Math.Max(0, newMessages.Count() - Channel.MaxHistory));
|
||||
|
||||
flow.AddRange(displayMessages.Select(m => new ChatLine(m)));
|
||||
ChatLineFlow.AddRange(displayMessages.Select(CreateChatLine));
|
||||
|
||||
if (scroll.IsScrolledToEnd(10) || !flow.Children.Any() || newMessages.Any(m => m is LocalMessage))
|
||||
if (scroll.IsScrolledToEnd(10) || !ChatLineFlow.Children.Any() || newMessages.Any(m => m is LocalMessage))
|
||||
scrollToEnd();
|
||||
|
||||
var staleMessages = flow.Children.Where(c => c.LifetimeEnd == double.MaxValue).ToArray();
|
||||
var staleMessages = ChatLineFlow.Children.Where(c => c.LifetimeEnd == double.MaxValue).ToArray();
|
||||
int count = staleMessages.Length - Channel.MaxHistory;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
@ -96,25 +98,25 @@ namespace osu.Game.Overlays.Chat
|
||||
|
||||
private void pendingMessageResolved(Message existing, Message updated)
|
||||
{
|
||||
var found = flow.Children.LastOrDefault(c => c.Message == existing);
|
||||
var found = ChatLineFlow.Children.LastOrDefault(c => c.Message == existing);
|
||||
if (found != null)
|
||||
{
|
||||
Trace.Assert(updated.Id.HasValue, "An updated message was returned with no ID.");
|
||||
|
||||
flow.Remove(found);
|
||||
ChatLineFlow.Remove(found);
|
||||
found.Message = updated;
|
||||
flow.Add(found);
|
||||
ChatLineFlow.Add(found);
|
||||
}
|
||||
}
|
||||
|
||||
private void messageRemoved(Message removed)
|
||||
{
|
||||
flow.Children.FirstOrDefault(c => c.Message == removed)?.FadeColour(Color4.Red, 400).FadeOut(600).Expire();
|
||||
ChatLineFlow.Children.FirstOrDefault(c => c.Message == removed)?.FadeColour(Color4.Red, 400).FadeOut(600).Expire();
|
||||
}
|
||||
|
||||
private void scrollToEnd() => ScheduleAfterChildren(() => scroll.ScrollToEnd());
|
||||
|
||||
private class ChatLineContainer : FillFlowContainer<ChatLine>
|
||||
protected class ChatLineContainer : FillFlowContainer<ChatLine>
|
||||
{
|
||||
protected override int Compare(Drawable x, Drawable y)
|
||||
{
|
||||
|
@ -20,7 +20,7 @@ using osu.Game.Graphics.Containers;
|
||||
|
||||
namespace osu.Game.Overlays.Chat.Selection
|
||||
{
|
||||
public class ChannelSelectionOverlay : OsuFocusedOverlayContainer
|
||||
public class ChannelSelectionOverlay : WaveOverlayContainer
|
||||
{
|
||||
public static readonly float WIDTH_PADDING = 170;
|
||||
|
||||
@ -39,6 +39,11 @@ namespace osu.Game.Overlays.Chat.Selection
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
|
||||
Waves.FirstWaveColour = OsuColour.FromHex("353535");
|
||||
Waves.SecondWaveColour = OsuColour.FromHex("434343");
|
||||
Waves.ThirdWaveColour = OsuColour.FromHex("515151");
|
||||
Waves.FourthWaveColour = OsuColour.FromHex("595959");
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
@ -19,6 +20,7 @@ using osu.Game.Online.Chat;
|
||||
using osu.Game.Overlays.Chat;
|
||||
using osu.Game.Overlays.Chat.Selection;
|
||||
using osu.Game.Overlays.Chat.Tabs;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Overlays
|
||||
{
|
||||
@ -222,7 +224,7 @@ namespace osu.Game.Overlays
|
||||
else
|
||||
{
|
||||
currentChannelContainer.Clear(false);
|
||||
Scheduler.Add(() => currentChannelContainer.Add(loaded));
|
||||
currentChannelContainer.Add(loaded);
|
||||
}
|
||||
}
|
||||
|
||||
@ -262,6 +264,39 @@ namespace osu.Game.Overlays
|
||||
return base.OnDragEnd(e);
|
||||
}
|
||||
|
||||
private void selectTab(int index)
|
||||
{
|
||||
var channel = channelTabControl.Items.Skip(index).FirstOrDefault();
|
||||
if (channel != null && channel.Name != "+")
|
||||
channelTabControl.Current.Value = channel;
|
||||
}
|
||||
|
||||
protected override bool OnKeyDown(KeyDownEvent e)
|
||||
{
|
||||
if (e.AltPressed)
|
||||
{
|
||||
switch (e.Key)
|
||||
{
|
||||
case Key.Number1:
|
||||
case Key.Number2:
|
||||
case Key.Number3:
|
||||
case Key.Number4:
|
||||
case Key.Number5:
|
||||
case Key.Number6:
|
||||
case Key.Number7:
|
||||
case Key.Number8:
|
||||
case Key.Number9:
|
||||
selectTab((int)e.Key - (int)Key.Number1);
|
||||
return true;
|
||||
case Key.Number0:
|
||||
selectTab(9);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return base.OnKeyDown(e);
|
||||
}
|
||||
|
||||
public override bool AcceptsFocus => true;
|
||||
|
||||
protected override void OnFocus(FocusEvent e)
|
||||
|
@ -82,6 +82,7 @@ namespace osu.Game.Overlays.Profile
|
||||
Origin = Anchor.BottomLeft,
|
||||
Masking = true,
|
||||
CornerRadius = 5,
|
||||
OpenOnClick = { Value = false },
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Type = EdgeEffectType.Shadow,
|
||||
@ -114,7 +115,7 @@ namespace osu.Game.Overlays.Profile
|
||||
Y = -48,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
usernameText = new OsuSpriteText
|
||||
{
|
||||
Text = user.Username,
|
||||
Font = @"Exo2.0-RegularItalic",
|
||||
@ -316,6 +317,8 @@ namespace osu.Game.Overlays.Profile
|
||||
levelBadge.Texture = textures.Get(@"Profile/levelbadge");
|
||||
}
|
||||
|
||||
private readonly OsuSpriteText usernameText;
|
||||
|
||||
private User user;
|
||||
|
||||
public User User
|
||||
@ -343,6 +346,8 @@ namespace osu.Game.Overlays.Profile
|
||||
if (user.IsSupporter)
|
||||
SupporterTag.Show();
|
||||
|
||||
usernameText.Text = user.Username;
|
||||
|
||||
if (!string.IsNullOrEmpty(user.Colour))
|
||||
{
|
||||
colourBar.Colour = OsuColour.FromHex(user.Colour);
|
||||
|
@ -6,8 +6,8 @@ using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.Leaderboards;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Scoring;
|
||||
|
||||
|
@ -10,7 +10,7 @@ using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Chat;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osu.Game.Online.Leaderboards;
|
||||
|
||||
namespace osu.Game.Overlays.Profile.Sections.Recent
|
||||
{
|
||||
|
@ -31,6 +31,7 @@ namespace osu.Game.Overlays.Toolbar
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
CornerRadius = 4,
|
||||
OpenOnClick = { Value = false },
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Type = EdgeEffectType.Shadow,
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
@ -18,7 +19,20 @@ namespace osu.Game.Overlays.Volume
|
||||
{
|
||||
public class MuteButton : Container, IHasCurrentValue<bool>
|
||||
{
|
||||
public Bindable<bool> Current { get; } = new Bindable<bool>();
|
||||
private readonly Bindable<bool> current = new Bindable<bool>();
|
||||
|
||||
public Bindable<bool> Current
|
||||
{
|
||||
get => current;
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
throw new ArgumentNullException(nameof(value));
|
||||
|
||||
current.UnbindBindings();
|
||||
current.BindTo(value);
|
||||
}
|
||||
}
|
||||
|
||||
private Color4 hoveredColour, unhoveredColour;
|
||||
private const float width = 100;
|
||||
|
Reference in New Issue
Block a user