mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 12:17:26 +08:00
Merge branch 'master' into fix-database-migration-failure
This commit is contained in:
commit
b59c45ca57
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,6 +1,3 @@
|
||||
[submodule "osu-framework"]
|
||||
path = osu-framework
|
||||
url = https://github.com/ppy/osu-framework
|
||||
[submodule "osu-resources"]
|
||||
path = osu-resources
|
||||
url = https://github.com/ppy/osu-resources
|
@ -1,6 +1,6 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="VisualTests (netcoreapp2.0)" type="DotNetProject" factoryName=".NET Project">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/netcoreapp2.0/osu.Game.Tests.dll" />
|
||||
<configuration default="false" name="VisualTests (netcoreapp2.1)" type="DotNetProject" factoryName=".NET Project">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/netcoreapp2.1/osu.Game.Tests.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tests" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
@ -12,7 +12,7 @@
|
||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.0" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
|
||||
<method />
|
||||
</configuration>
|
||||
</component>
|
@ -1,6 +1,6 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="osu! (netcoreapp2.0)" type="DotNetProject" factoryName=".NET Project">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp2.0/osu!.dll" />
|
||||
<configuration default="false" name="osu! (netcoreapp2.1)" type="DotNetProject" factoryName=".NET Project">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp2.1/osu!.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
@ -12,7 +12,7 @@
|
||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.0" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
|
||||
<method />
|
||||
</configuration>
|
||||
</component>
|
16
.vscode/launch.json
vendored
16
.vscode/launch.json
vendored
@ -58,12 +58,12 @@
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "VisualTests (Debug, netcoreapp2.0)",
|
||||
"name": "VisualTests (Debug, netcoreapp2.1)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.0/osu.Game.Tests.dll"
|
||||
"${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.1/osu.Game.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build tests (Debug, dotnet)",
|
||||
@ -71,12 +71,12 @@
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "VisualTests (Release, netcoreapp2.0)",
|
||||
"name": "VisualTests (Release, netcoreapp2.1)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.0/osu.Game.Tests.dll"
|
||||
"${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.1/osu.Game.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build tests (Release, dotnet)",
|
||||
@ -84,12 +84,12 @@
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "osu! (Debug, netcoreapp2.0)",
|
||||
"name": "osu! (Debug, netcoreapp2.1)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.0/osu!.dll",
|
||||
"${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1/osu!.dll",
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build osu! (Debug, dotnet)",
|
||||
@ -97,12 +97,12 @@
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "osu! (Release, netcoreapp2.0)",
|
||||
"name": "osu! (Release, netcoreapp2.1)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.0/osu!.dll",
|
||||
"${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.1/osu!.dll",
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build osu! (Release, dotnet)",
|
||||
|
10
.vscode/tasks.json
vendored
10
.vscode/tasks.json
vendored
@ -38,7 +38,7 @@
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Desktop",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
"/verbosity:m"
|
||||
@ -54,7 +54,7 @@
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Desktop",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:Configuration=Release",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
@ -71,7 +71,7 @@
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Game.Tests",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
"/verbosity:m"
|
||||
@ -87,7 +87,7 @@
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Game.Tests",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:Configuration=Release",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
@ -106,7 +106,7 @@
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Restore (netcoreapp2.0)",
|
||||
"label": "Restore (netcoreapp2.1)",
|
||||
"type": "shell",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
|
@ -2,11 +2,6 @@ clone_depth: 1
|
||||
version: '{branch}-{build}'
|
||||
image: Visual Studio 2017
|
||||
configuration: Debug
|
||||
cache:
|
||||
- C:\ProgramData\chocolatey\bin -> appveyor.yml
|
||||
- C:\ProgramData\chocolatey\lib -> appveyor.yml
|
||||
- inspectcode -> appveyor.yml
|
||||
- packages -> **\packages.config
|
||||
install:
|
||||
- cmd: git submodule update --init --recursive --depth=5
|
||||
- cmd: choco install resharper-clt -y
|
||||
|
@ -1,29 +1,24 @@
|
||||
branches:
|
||||
only:
|
||||
- release
|
||||
skip_tags: true
|
||||
skip_branch_with_pr: true
|
||||
clone_depth: 1
|
||||
version: '{branch}-{build}'
|
||||
version: '{build}'
|
||||
skip_non_tags: true
|
||||
image: Visual Studio 2017
|
||||
configuration: Debug
|
||||
cache:
|
||||
- packages -> **\packages.config
|
||||
install:
|
||||
- cmd: git submodule update --init --recursive --depth=5
|
||||
- git clone https://github.com/ppy/osu-deploy
|
||||
before_build:
|
||||
- ps: if($env:appveyor_repo_tag -eq 'True') { Update-AppveyorBuild -Version $env:appveyor_repo_tag_name }
|
||||
- cmd: git submodule update --init --recursive --depth=5
|
||||
- cmd: nuget restore -verbosity quiet
|
||||
build:
|
||||
project: osu.Desktop.Deploy/osu.Desktop.Deploy.csproj
|
||||
verbosity: minimal
|
||||
after_build:
|
||||
build_script:
|
||||
- ps: iex ((New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/appveyor/secure-file/master/install.ps1'))
|
||||
- appveyor DownloadFile https://puu.sh/A6g5K/4d08705438.enc # signing certificate
|
||||
- cmd: appveyor-tools\secure-file -decrypt 4d08705438.enc -secret %decode_secret% -out %HOMEPATH%\deanherbert.pfx
|
||||
- appveyor DownloadFile https://puu.sh/A6g75/fdc6f19b04.enc # deploy configuration
|
||||
- cmd: appveyor-tools\secure-file -decrypt fdc6f19b04.enc -secret %decode_secret% -out osu.Desktop.Deploy\bin\Debug\net471\osu.Desktop.Deploy.exe.config
|
||||
- cd osu.Desktop.Deploy\bin\Debug\net471\
|
||||
- osu.Desktop.Deploy.exe %code_signing_password%
|
||||
- cd osu-deploy
|
||||
- nuget restore -verbosity quiet
|
||||
- msbuild osu.Desktop.Deploy.csproj
|
||||
- cmd: ..\appveyor-tools\secure-file -decrypt ..\fdc6f19b04.enc -secret %decode_secret% -out bin\Debug\net471\osu.Desktop.Deploy.exe.config
|
||||
- cd bin\Debug\net471\
|
||||
- osu.Desktop.Deploy.exe %code_signing_password% %APPVEYOR_REPO_TAG_NAME%
|
||||
environment:
|
||||
TargetFramework: net471
|
||||
decode_secret:
|
||||
@ -32,3 +27,6 @@ environment:
|
||||
secure: 34tLNqvjmmZEi97MLKfrnQ==
|
||||
artifacts:
|
||||
- path: 'Releases\*'
|
||||
deploy:
|
||||
- provider: Environment
|
||||
name: github
|
@ -1 +0,0 @@
|
||||
Subproject commit 804a4b81b89cb4569af5221e6fa2296d559c28fb
|
@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
-->
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<add key="StagingFolder" value="Staging" />
|
||||
<add key="ReleasesFolder" value="Releases" />
|
||||
<add key="GitHubAccessToken" value="" />
|
||||
<add key="GitHubUsername" value="ppy" />
|
||||
<add key="GitHubRepoName" value="osu" />
|
||||
<add key="ProjectName" value="osu.Desktop" />
|
||||
<add key="NuSpecName" value="osu.Desktop\osu.nuspec" />
|
||||
<add key="SolutionName" value="osu" />
|
||||
<add key="TargetName" value="osu.Desktop" />
|
||||
<add key="PackageName" value="osulazer" />
|
||||
<add key="IconName" value="lazer.ico" />
|
||||
<add key="CodeSigningCertificate" value="" />
|
||||
</appSettings>
|
||||
</configuration>
|
@ -1,16 +0,0 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace osu.Desktop.Deploy
|
||||
{
|
||||
public class GitHubObject
|
||||
{
|
||||
[JsonProperty(@"id")]
|
||||
public int Id;
|
||||
|
||||
[JsonProperty(@"name")]
|
||||
public string Name;
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace osu.Desktop.Deploy
|
||||
{
|
||||
public class GitHubRelease
|
||||
{
|
||||
[JsonProperty(@"id")]
|
||||
public int Id;
|
||||
|
||||
[JsonProperty(@"tag_name")]
|
||||
public string TagName => $"v{Name}";
|
||||
|
||||
[JsonProperty(@"name")]
|
||||
public string Name;
|
||||
|
||||
[JsonProperty(@"draft")]
|
||||
public bool Draft;
|
||||
|
||||
[JsonProperty(@"prerelease")]
|
||||
public bool PreRelease;
|
||||
|
||||
[JsonProperty(@"upload_url")]
|
||||
public string UploadUrl;
|
||||
}
|
||||
}
|
@ -1,471 +0,0 @@
|
||||
// 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.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Management.Automation;
|
||||
using Newtonsoft.Json;
|
||||
using osu.Framework.IO.Network;
|
||||
using FileWebRequest = osu.Framework.IO.Network.FileWebRequest;
|
||||
using WebRequest = osu.Framework.IO.Network.WebRequest;
|
||||
|
||||
namespace osu.Desktop.Deploy
|
||||
{
|
||||
internal static class Program
|
||||
{
|
||||
private static string packages => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages");
|
||||
private static string nugetPath => Path.Combine(packages, @"nuget.commandline\4.5.1\tools\NuGet.exe");
|
||||
private static string squirrelPath => Path.Combine(packages, @"squirrel.windows\1.8.0\tools\Squirrel.exe");
|
||||
private const string msbuild_path = @"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe";
|
||||
|
||||
public static string StagingFolder = ConfigurationManager.AppSettings["StagingFolder"];
|
||||
public static string ReleasesFolder = ConfigurationManager.AppSettings["ReleasesFolder"];
|
||||
public static string GitHubAccessToken = ConfigurationManager.AppSettings["GitHubAccessToken"];
|
||||
public static string GitHubUsername = ConfigurationManager.AppSettings["GitHubUsername"];
|
||||
public static string GitHubRepoName = ConfigurationManager.AppSettings["GitHubRepoName"];
|
||||
public static string SolutionName = ConfigurationManager.AppSettings["SolutionName"];
|
||||
public static string ProjectName = ConfigurationManager.AppSettings["ProjectName"];
|
||||
public static string NuSpecName = ConfigurationManager.AppSettings["NuSpecName"];
|
||||
public static string TargetNames = ConfigurationManager.AppSettings["TargetName"];
|
||||
public static string PackageName = ConfigurationManager.AppSettings["PackageName"];
|
||||
public static string IconName = ConfigurationManager.AppSettings["IconName"];
|
||||
public static string CodeSigningCertificate = ConfigurationManager.AppSettings["CodeSigningCertificate"];
|
||||
|
||||
public static string GitHubApiEndpoint => $"https://api.github.com/repos/{GitHubUsername}/{GitHubRepoName}/releases";
|
||||
public static string GitHubReleasePage => $"https://github.com/{GitHubUsername}/{GitHubRepoName}/releases";
|
||||
|
||||
/// <summary>
|
||||
/// How many previous build deltas we want to keep when publishing.
|
||||
/// </summary>
|
||||
private const int keep_delta_count = 4;
|
||||
|
||||
private static string codeSigningCmd => string.IsNullOrEmpty(codeSigningPassword) ? "" : $"-n \"/a /f {codeSigningCertPath} /p {codeSigningPassword} /t http://timestamp.comodoca.com/authenticode\"";
|
||||
|
||||
private static string homeDir => Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
||||
private static string codeSigningCertPath => Path.Combine(homeDir, CodeSigningCertificate);
|
||||
private static string solutionPath => Environment.CurrentDirectory;
|
||||
private static string stagingPath => Path.Combine(solutionPath, StagingFolder);
|
||||
private static string iconPath => Path.Combine(solutionPath, ProjectName, IconName);
|
||||
|
||||
private static string nupkgFilename(string ver) => $"{PackageName}.{ver}.nupkg";
|
||||
private static string nupkgDistroFilename(string ver) => $"{PackageName}-{ver}-full.nupkg";
|
||||
|
||||
private static readonly Stopwatch sw = new Stopwatch();
|
||||
|
||||
private static string codeSigningPassword;
|
||||
|
||||
private static bool interactive;
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
interactive = args.Length == 0;
|
||||
|
||||
displayHeader();
|
||||
|
||||
findSolutionPath();
|
||||
|
||||
if (!Directory.Exists(ReleasesFolder))
|
||||
{
|
||||
write("WARNING: No release directory found. Make sure you want this!", ConsoleColor.Yellow);
|
||||
Directory.CreateDirectory(ReleasesFolder);
|
||||
}
|
||||
|
||||
checkGitHubReleases();
|
||||
|
||||
refreshDirectory(StagingFolder);
|
||||
|
||||
//increment build number until we have a unique one.
|
||||
string verBase = DateTime.Now.ToString("yyyy.Mdd.");
|
||||
int increment = 0;
|
||||
while (Directory.GetFiles(ReleasesFolder, $"*{verBase}{increment}*").Any())
|
||||
increment++;
|
||||
|
||||
string version = $"{verBase}{increment}";
|
||||
|
||||
Console.ForegroundColor = ConsoleColor.White;
|
||||
Console.Write($"Ready to deploy {version}!");
|
||||
pauseIfInteractive();
|
||||
|
||||
sw.Start();
|
||||
|
||||
if (!string.IsNullOrEmpty(CodeSigningCertificate))
|
||||
{
|
||||
Console.Write("Enter code signing password: ");
|
||||
codeSigningPassword = args.Length > 0 ? args[0] : readLineMasked();
|
||||
}
|
||||
|
||||
write("Updating AssemblyInfo...");
|
||||
updateCsprojVersion(version);
|
||||
updateAppveyorVersion(version);
|
||||
|
||||
write("Running build process...");
|
||||
foreach (string targetName in TargetNames.Split(','))
|
||||
runCommand(msbuild_path, $"/v:quiet /m /t:{targetName.Replace('.', '_')} /p:OutputPath={stagingPath};Targets=\"Clean;Build\";Configuration=Release {SolutionName}.sln");
|
||||
|
||||
write("Creating NuGet deployment package...");
|
||||
runCommand(nugetPath, $"pack {NuSpecName} -Version {version} -Properties Configuration=Deploy -OutputDirectory {stagingPath} -BasePath {stagingPath}");
|
||||
|
||||
//prune once before checking for files so we can avoid erroring on files which aren't even needed for this build.
|
||||
pruneReleases();
|
||||
|
||||
checkReleaseFiles();
|
||||
|
||||
write("Running squirrel build...");
|
||||
runCommand(squirrelPath, $"--releasify {stagingPath}\\{nupkgFilename(version)} --framework-version=net471 --setupIcon {iconPath} --icon {iconPath} {codeSigningCmd} --no-msi");
|
||||
|
||||
//prune again to clean up before upload.
|
||||
pruneReleases();
|
||||
|
||||
//rename setup to install.
|
||||
File.Copy(Path.Combine(ReleasesFolder, "Setup.exe"), Path.Combine(ReleasesFolder, "install.exe"), true);
|
||||
File.Delete(Path.Combine(ReleasesFolder, "Setup.exe"));
|
||||
|
||||
uploadBuild(version);
|
||||
|
||||
//reset assemblyinfo.
|
||||
updateCsprojVersion("0.0.0");
|
||||
|
||||
write("Done!", ConsoleColor.White);
|
||||
pauseIfInteractive();
|
||||
}
|
||||
|
||||
private static void displayHeader()
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(" Please note that OSU! and PPY are registered trademarks and as such covered by trademark law.");
|
||||
Console.WriteLine(" Do not distribute builds of this project publicly that make use of these.");
|
||||
Console.ResetColor();
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensure we have all the files in the release directory which are expected to be there.
|
||||
/// This should have been accounted for in earlier steps, and just serves as a verification step.
|
||||
/// </summary>
|
||||
private static void checkReleaseFiles()
|
||||
{
|
||||
if (!canGitHub) return;
|
||||
|
||||
var releaseLines = getReleaseLines();
|
||||
|
||||
//ensure we have all files necessary
|
||||
foreach (var l in releaseLines)
|
||||
if (!File.Exists(Path.Combine(ReleasesFolder, l.Filename)))
|
||||
error($"Local file missing {l.Filename}");
|
||||
}
|
||||
|
||||
private static IEnumerable<ReleaseLine> getReleaseLines() => File.ReadAllLines(Path.Combine(ReleasesFolder, "RELEASES")).Select(l => new ReleaseLine(l));
|
||||
|
||||
private static void pruneReleases()
|
||||
{
|
||||
if (!canGitHub) return;
|
||||
|
||||
write("Pruning RELEASES...");
|
||||
|
||||
var releaseLines = getReleaseLines().ToList();
|
||||
|
||||
var fulls = releaseLines.Where(l => l.Filename.Contains("-full")).Reverse().Skip(1);
|
||||
|
||||
//remove any FULL releases (except most recent)
|
||||
foreach (var l in fulls)
|
||||
{
|
||||
write($"- Removing old release {l.Filename}", ConsoleColor.Yellow);
|
||||
File.Delete(Path.Combine(ReleasesFolder, l.Filename));
|
||||
releaseLines.Remove(l);
|
||||
}
|
||||
|
||||
//remove excess deltas
|
||||
var deltas = releaseLines.Where(l => l.Filename.Contains("-delta")).ToArray();
|
||||
if (deltas.Length > keep_delta_count)
|
||||
{
|
||||
foreach (var l in deltas.Take(deltas.Length - keep_delta_count))
|
||||
{
|
||||
write($"- Removing old delta {l.Filename}", ConsoleColor.Yellow);
|
||||
File.Delete(Path.Combine(ReleasesFolder, l.Filename));
|
||||
releaseLines.Remove(l);
|
||||
}
|
||||
}
|
||||
|
||||
var lines = new List<string>();
|
||||
releaseLines.ForEach(l => lines.Add(l.ToString()));
|
||||
File.WriteAllLines(Path.Combine(ReleasesFolder, "RELEASES"), lines);
|
||||
}
|
||||
|
||||
private static void uploadBuild(string version)
|
||||
{
|
||||
if (!canGitHub || string.IsNullOrEmpty(CodeSigningCertificate))
|
||||
return;
|
||||
|
||||
write("Publishing to GitHub...");
|
||||
|
||||
write($"- Creating release {version}...", ConsoleColor.Yellow);
|
||||
var req = new JsonWebRequest<GitHubRelease>($"{GitHubApiEndpoint}")
|
||||
{
|
||||
Method = HttpMethod.POST,
|
||||
};
|
||||
req.AddRaw(JsonConvert.SerializeObject(new GitHubRelease
|
||||
{
|
||||
Name = version,
|
||||
Draft = true,
|
||||
PreRelease = true
|
||||
}));
|
||||
req.AuthenticatedBlockingPerform();
|
||||
|
||||
var assetUploadUrl = req.ResponseObject.UploadUrl.Replace("{?name,label}", "?name={0}");
|
||||
foreach (var a in Directory.GetFiles(ReleasesFolder).Reverse()) //reverse to upload RELEASES first.
|
||||
{
|
||||
write($"- Adding asset {a}...", ConsoleColor.Yellow);
|
||||
var upload = new WebRequest(assetUploadUrl, Path.GetFileName(a))
|
||||
{
|
||||
Method = HttpMethod.POST,
|
||||
Timeout = 240000,
|
||||
ContentType = "application/octet-stream",
|
||||
};
|
||||
|
||||
upload.AddRaw(File.ReadAllBytes(a));
|
||||
upload.AuthenticatedBlockingPerform();
|
||||
}
|
||||
|
||||
openGitHubReleasePage();
|
||||
}
|
||||
|
||||
private static void openGitHubReleasePage() => Process.Start(GitHubReleasePage);
|
||||
|
||||
private static bool canGitHub => !string.IsNullOrEmpty(GitHubAccessToken);
|
||||
|
||||
private static void checkGitHubReleases()
|
||||
{
|
||||
if (!canGitHub) return;
|
||||
|
||||
write("Checking GitHub releases...");
|
||||
var req = new JsonWebRequest<List<GitHubRelease>>($"{GitHubApiEndpoint}");
|
||||
req.AuthenticatedBlockingPerform();
|
||||
|
||||
var lastRelease = req.ResponseObject.FirstOrDefault();
|
||||
|
||||
if (lastRelease == null)
|
||||
return;
|
||||
|
||||
if (lastRelease.Draft)
|
||||
{
|
||||
openGitHubReleasePage();
|
||||
error("There's a pending draft release! You probably don't want to push a build with this present.");
|
||||
}
|
||||
|
||||
//there's a previous release for this project.
|
||||
var assetReq = new JsonWebRequest<List<GitHubObject>>($"{GitHubApiEndpoint}/{lastRelease.Id}/assets");
|
||||
assetReq.AuthenticatedBlockingPerform();
|
||||
var assets = assetReq.ResponseObject;
|
||||
|
||||
//make sure our RELEASES file is the same as the last build on the server.
|
||||
var releaseAsset = assets.FirstOrDefault(a => a.Name == "RELEASES");
|
||||
|
||||
//if we don't have a RELEASES asset then the previous release likely wasn't a Squirrel one.
|
||||
if (releaseAsset == null) return;
|
||||
|
||||
write($"Last GitHub release was {lastRelease.Name}.");
|
||||
|
||||
bool requireDownload = false;
|
||||
|
||||
if (!File.Exists(Path.Combine(ReleasesFolder, nupkgDistroFilename(lastRelease.Name))))
|
||||
{
|
||||
write("Last version's package not found locally.", ConsoleColor.Red);
|
||||
requireDownload = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var lastReleases = new RawFileWebRequest($"{GitHubApiEndpoint}/assets/{releaseAsset.Id}");
|
||||
lastReleases.AuthenticatedBlockingPerform();
|
||||
if (File.ReadAllText(Path.Combine(ReleasesFolder, "RELEASES")) != lastReleases.ResponseString)
|
||||
{
|
||||
write("Server's RELEASES differed from ours.", ConsoleColor.Red);
|
||||
requireDownload = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!requireDownload) return;
|
||||
|
||||
write("Refreshing local releases directory...");
|
||||
refreshDirectory(ReleasesFolder);
|
||||
|
||||
foreach (var a in assets)
|
||||
{
|
||||
if (a.Name.EndsWith(".exe")) continue;
|
||||
|
||||
write($"- Downloading {a.Name}...", ConsoleColor.Yellow);
|
||||
new FileWebRequest(Path.Combine(ReleasesFolder, a.Name), $"{GitHubApiEndpoint}/assets/{a.Id}").AuthenticatedBlockingPerform();
|
||||
}
|
||||
}
|
||||
|
||||
private static void refreshDirectory(string directory)
|
||||
{
|
||||
if (Directory.Exists(directory))
|
||||
Directory.Delete(directory, true);
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
|
||||
private static void updateCsprojVersion(string version)
|
||||
{
|
||||
var toUpdate = new[] { "<Version>", "<FileVersion>" };
|
||||
string file = Path.Combine(ProjectName, $"{ProjectName}.csproj");
|
||||
|
||||
var l1 = File.ReadAllLines(file);
|
||||
List<string> l2 = new List<string>();
|
||||
foreach (var l in l1)
|
||||
{
|
||||
string line = l;
|
||||
|
||||
foreach (var tag in toUpdate)
|
||||
{
|
||||
int startIndex = l.IndexOf(tag, StringComparison.InvariantCulture);
|
||||
if (startIndex == -1)
|
||||
continue;
|
||||
startIndex += tag.Length;
|
||||
|
||||
int endIndex = l.IndexOf("<", startIndex, StringComparison.InvariantCulture);
|
||||
line = $"{l.Substring(0, startIndex)}{version}{l.Substring(endIndex)}";
|
||||
}
|
||||
|
||||
l2.Add(line);
|
||||
}
|
||||
|
||||
File.WriteAllLines(file, l2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find the base path of the active solution (git checkout location)
|
||||
/// </summary>
|
||||
private static void findSolutionPath()
|
||||
{
|
||||
string path = Path.GetDirectoryName(Environment.CommandLine.Replace("\"", "").Trim());
|
||||
|
||||
if (string.IsNullOrEmpty(path))
|
||||
path = Environment.CurrentDirectory;
|
||||
|
||||
while (!File.Exists(Path.Combine(path, $"{SolutionName}.sln")))
|
||||
path = path.Remove(path.LastIndexOf(Path.DirectorySeparatorChar));
|
||||
path += Path.DirectorySeparatorChar;
|
||||
|
||||
Environment.CurrentDirectory = path;
|
||||
}
|
||||
|
||||
private static bool runCommand(string command, string args)
|
||||
{
|
||||
var psi = new ProcessStartInfo(command, args)
|
||||
{
|
||||
WorkingDirectory = solutionPath,
|
||||
CreateNoWindow = true,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false,
|
||||
WindowStyle = ProcessWindowStyle.Hidden
|
||||
};
|
||||
|
||||
Process p = Process.Start(psi);
|
||||
if (p == null) return false;
|
||||
|
||||
string output = p.StandardOutput.ReadToEnd();
|
||||
output += p.StandardError.ReadToEnd();
|
||||
|
||||
if (p.ExitCode == 0) return true;
|
||||
|
||||
write(output);
|
||||
error($"Command {command} {args} failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
private static string readLineMasked()
|
||||
{
|
||||
var fg = Console.ForegroundColor;
|
||||
Console.ForegroundColor = Console.BackgroundColor;
|
||||
var ret = Console.ReadLine();
|
||||
Console.ForegroundColor = fg;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static void error(string message)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine($"FATAL ERROR: {message}");
|
||||
|
||||
pauseIfInteractive();
|
||||
Environment.Exit(-1);
|
||||
}
|
||||
|
||||
private static void pauseIfInteractive()
|
||||
{
|
||||
if (interactive)
|
||||
Console.ReadLine();
|
||||
else
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
private static bool updateAppveyorVersion(string version)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (PowerShell ps = PowerShell.Create())
|
||||
{
|
||||
ps.AddScript($"Update-AppveyorBuild -Version \"{version}\"");
|
||||
ps.Invoke();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// we don't have appveyor and don't care
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void write(string message, ConsoleColor col = ConsoleColor.Gray)
|
||||
{
|
||||
if (sw.ElapsedMilliseconds > 0)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
Console.Write(sw.ElapsedMilliseconds.ToString().PadRight(8));
|
||||
}
|
||||
Console.ForegroundColor = col;
|
||||
Console.WriteLine(message);
|
||||
}
|
||||
|
||||
public static void AuthenticatedBlockingPerform(this WebRequest r)
|
||||
{
|
||||
r.AddHeader("Authorization", $"token {GitHubAccessToken}");
|
||||
r.Perform();
|
||||
}
|
||||
}
|
||||
|
||||
internal class RawFileWebRequest : WebRequest
|
||||
{
|
||||
public RawFileWebRequest(string url) : base(url)
|
||||
{
|
||||
}
|
||||
|
||||
protected override string Accept => "application/octet-stream";
|
||||
}
|
||||
|
||||
internal class ReleaseLine
|
||||
{
|
||||
public string Hash;
|
||||
public string Filename;
|
||||
public int Filesize;
|
||||
|
||||
public ReleaseLine(string line)
|
||||
{
|
||||
var split = line.Split(' ');
|
||||
Hash = split[0];
|
||||
Filename = split[1];
|
||||
Filesize = int.Parse(split[2]);
|
||||
}
|
||||
|
||||
public override string ToString() => $"{Hash} {Filename} {Filesize}";
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\osu.Game.props" />
|
||||
<PropertyGroup Label="Project">
|
||||
<TargetFrameworks>net471</TargetFrameworks>
|
||||
<OutputType>Exe</OutputType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Package References">
|
||||
<PackageReference Include="NuGet.CommandLine" Version="4.5.1" />
|
||||
<PackageReference Include="NUnit" Version="3.10.1" />
|
||||
<PackageReference Include="squirrel.windows" Version="1.8.0" Condition="'$(TargetFramework)' == 'net471'" />
|
||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.4.0" />
|
||||
<PackageReference Include="System.Management.Automation.dll" Version="10.0.10586" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -3,7 +3,6 @@
|
||||
|
||||
using System.Diagnostics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Development;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
@ -14,6 +13,7 @@ using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
using osu.Game.Utils;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\osu.Game.props" />
|
||||
<PropertyGroup Label="Project">
|
||||
<TargetFrameworks>net471;netcoreapp2.0</TargetFrameworks>
|
||||
<TargetFrameworks>net471;netcoreapp2.1</TargetFrameworks>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
@ -20,9 +20,6 @@
|
||||
<StartupObject>osu.Desktop.Program</StartupObject>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="Project References">
|
||||
<!-- This can be removed after .NET Core SDK version 2.1.300; see https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dotnet -->
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.3" />
|
||||
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj" />
|
||||
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
|
||||
@ -38,8 +35,4 @@
|
||||
<ItemGroup Label="Resources">
|
||||
<EmbeddedResource Include="lazer.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<!-- This can be removed after .NET Core SDK version 2.1.300; see https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dotnet -->
|
||||
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -22,7 +22,7 @@
|
||||
},
|
||||
"type": "mono",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/bin/Debug/net471/osu.Game.Rulesets.Catch.Tests.exe",
|
||||
"program": "${workspaceRoot}/bin/Release/net471/osu.Game.Rulesets.Catch.Tests.exe",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build (Release, msbuild)",
|
||||
"runtimeExecutable": null,
|
||||
@ -30,12 +30,12 @@
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "VisualTests (Debug, netcoreapp2.0)",
|
||||
"name": "VisualTests (Debug, netcoreapp2.1)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Catch.Tests.dll"
|
||||
"${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Catch.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build (Debug, dotnet)",
|
||||
@ -43,12 +43,12 @@
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "VisualTests (Release, netcoreapp2.0)",
|
||||
"name": "VisualTests (Release, netcoreapp2.1)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Catch.Tests.dll"
|
||||
"${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Catch.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build (Release, dotnet)",
|
||||
|
@ -40,7 +40,7 @@
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Game.Rulesets.Catch.Tests.csproj",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
"/verbosity:m"
|
||||
@ -56,7 +56,7 @@
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Game.Rulesets.Catch.Tests.csproj",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:Configuration=Release",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
@ -75,7 +75,7 @@
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Restore (netcoreapp2.0)",
|
||||
"label": "Restore (netcoreapp2.1)",
|
||||
"type": "shell",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
|
@ -2,7 +2,7 @@
|
||||
<Import Project="..\osu.TestProject.props" />
|
||||
<PropertyGroup Label="Project">
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFrameworks>netcoreapp2.0;net471</TargetFrameworks>
|
||||
<TargetFrameworks>netcoreapp2.1;net471</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
|
||||
|
@ -22,7 +22,7 @@
|
||||
},
|
||||
"type": "mono",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/bin/Debug/net471/osu.Game.Rulesets.Mania.Tests.exe",
|
||||
"program": "${workspaceRoot}/bin/Release/net471/osu.Game.Rulesets.Mania.Tests.exe",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build (Release, msbuild)",
|
||||
"runtimeExecutable": null,
|
||||
@ -30,12 +30,12 @@
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "VisualTests (Debug, netcoreapp2.0)",
|
||||
"name": "VisualTests (Debug, netcoreapp2.1)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Mania.Tests.dll"
|
||||
"${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Mania.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build (Debug, dotnet)",
|
||||
@ -43,12 +43,12 @@
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "VisualTests (Release, netcoreapp2.0)",
|
||||
"name": "VisualTests (Release, netcoreapp2.1)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Mania.Tests.dll"
|
||||
"${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Mania.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build (Release, dotnet)",
|
||||
|
@ -40,7 +40,7 @@
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Game.Rulesets.Mania.Tests.csproj",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
"/verbosity:m"
|
||||
@ -56,7 +56,7 @@
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Game.Rulesets.Mania.Tests.csproj",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:Configuration=Release",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
@ -75,7 +75,7 @@
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Restore (netcoreapp2.0)",
|
||||
"label": "Restore (netcoreapp2.1)",
|
||||
"type": "shell",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
|
@ -2,7 +2,7 @@
|
||||
<Import Project="..\osu.TestProject.props" />
|
||||
<PropertyGroup Label="Project">
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFrameworks>netcoreapp2.0;net471</TargetFrameworks>
|
||||
<TargetFrameworks>netcoreapp2.1;net471</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj" />
|
||||
|
10
osu.Game.Rulesets.Osu.Tests/.vscode/launch.json
vendored
10
osu.Game.Rulesets.Osu.Tests/.vscode/launch.json
vendored
@ -22,7 +22,7 @@
|
||||
},
|
||||
"type": "mono",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/bin/Debug/net471/osu.Game.Rulesets.Osu.Tests.exe",
|
||||
"program": "${workspaceRoot}/bin/Release/net471/osu.Game.Rulesets.Osu.Tests.exe",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build (Release, msbuild)",
|
||||
"runtimeExecutable": null,
|
||||
@ -30,12 +30,12 @@
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "VisualTests (Debug, netcoreapp2.0)",
|
||||
"name": "VisualTests (Debug, netcoreapp2.1)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Osu.Tests.dll"
|
||||
"${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Osu.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build (Debug, dotnet)",
|
||||
@ -43,12 +43,12 @@
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "VisualTests (Release, netcoreapp2.0)",
|
||||
"name": "VisualTests (Release, netcoreapp2.1)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Osu.Tests.dll"
|
||||
"${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Osu.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build (Release, dotnet)",
|
||||
|
@ -40,7 +40,7 @@
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Game.Rulesets.Osu.Tests.csproj",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
"/verbosity:m"
|
||||
@ -56,7 +56,7 @@
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Game.Rulesets.Osu.Tests.csproj",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:Configuration=Release",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
@ -75,7 +75,7 @@
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Restore (netcoreapp2.0)",
|
||||
"label": "Restore (netcoreapp2.1)",
|
||||
"type": "shell",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
|
@ -2,7 +2,7 @@
|
||||
<Import Project="..\osu.TestProject.props" />
|
||||
<PropertyGroup Label="Project">
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFrameworks>netcoreapp2.0;net471</TargetFrameworks>
|
||||
<TargetFrameworks>netcoreapp2.1;net471</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
||||
|
@ -7,33 +7,34 @@ using System.Linq;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Mods
|
||||
{
|
||||
public class OsuModHidden : ModHidden, IApplicableToDrawableHitObjects
|
||||
public class OsuModHidden : ModHidden
|
||||
{
|
||||
public override string Description => @"Play with no approach circles and fading circles/sliders.";
|
||||
public override double ScoreMultiplier => 1.06;
|
||||
|
||||
private const double fade_in_duration_multiplier = 0.4;
|
||||
private const double fade_out_duration_multiplier = 0.3;
|
||||
|
||||
public void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
||||
public override void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
||||
{
|
||||
void adjustFadeIn(OsuHitObject h) => h.TimeFadein = h.TimePreempt * fade_in_duration_multiplier;
|
||||
|
||||
foreach (var d in drawables.OfType<DrawableOsuHitObject>())
|
||||
{
|
||||
d.ApplyCustomUpdateState += ApplyHiddenState;
|
||||
|
||||
d.HitObject.TimeFadein = d.HitObject.TimePreempt * fade_in_duration_multiplier;
|
||||
adjustFadeIn(d.HitObject);
|
||||
foreach (var h in d.HitObject.NestedHitObjects.OfType<OsuHitObject>())
|
||||
h.TimeFadein = h.TimePreempt * fade_in_duration_multiplier;
|
||||
}
|
||||
adjustFadeIn(h);
|
||||
}
|
||||
|
||||
protected void ApplyHiddenState(DrawableHitObject drawable, ArmedState state)
|
||||
base.ApplyToDrawableHitObjects(drawables);
|
||||
}
|
||||
|
||||
protected override void ApplyHiddenState(DrawableHitObject drawable, ArmedState state)
|
||||
{
|
||||
if (!(drawable is DrawableOsuHitObject d))
|
||||
return;
|
||||
|
@ -22,7 +22,7 @@
|
||||
},
|
||||
"type": "mono",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/bin/Debug/net471/osu.Game.Rulesets.Taiko.Tests.exe",
|
||||
"program": "${workspaceRoot}/bin/Release/net471/osu.Game.Rulesets.Taiko.Tests.exe",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build (Release, msbuild)",
|
||||
"runtimeExecutable": null,
|
||||
@ -30,12 +30,12 @@
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "VisualTests (Debug, netcoreapp2.0)",
|
||||
"name": "VisualTests (Debug, netcoreapp2.1)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Taiko.Tests.dll"
|
||||
"${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Taiko.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build (Debug, dotnet)",
|
||||
@ -43,12 +43,12 @@
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "VisualTests (Release, netcoreapp2.0)",
|
||||
"name": "VisualTests (Release, netcoreapp2.1)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Taiko.Tests.dll"
|
||||
"${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Taiko.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build (Release, dotnet)",
|
||||
|
@ -40,7 +40,7 @@
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Game.Rulesets.Taiko.Tests.csproj",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
"/verbosity:m"
|
||||
@ -56,7 +56,7 @@
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Game.Rulesets.Taiko.Tests.csproj",
|
||||
"/p:TargetFramework=netcoreapp2.0",
|
||||
"/p:TargetFramework=netcoreapp2.1",
|
||||
"/p:Configuration=Release",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
@ -75,7 +75,7 @@
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Restore (netcoreapp2.0)",
|
||||
"label": "Restore (netcoreapp2.1)",
|
||||
"type": "shell",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
|
@ -2,7 +2,7 @@
|
||||
<Import Project="..\osu.TestProject.props" />
|
||||
<PropertyGroup Label="Project">
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFrameworks>netcoreapp2.0;net471</TargetFrameworks>
|
||||
<TargetFrameworks>netcoreapp2.1;net471</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" />
|
||||
|
@ -264,7 +264,8 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
|
||||
private string createTemporaryBeatmap()
|
||||
{
|
||||
var temp = new FileInfo(osz_path).CopyTo(Path.GetTempFileName(), true).FullName;
|
||||
var temp = Path.GetTempFileName() + ".osz";
|
||||
File.Copy(osz_path, temp, true);
|
||||
Assert.IsTrue(File.Exists(temp));
|
||||
return temp;
|
||||
}
|
||||
@ -344,12 +345,12 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
|
||||
private void waitForOrAssert(Func<bool> result, string failureMessage, int timeout = 60000)
|
||||
{
|
||||
Action waitAction = () =>
|
||||
Task task = Task.Run(() =>
|
||||
{
|
||||
while (!result()) Thread.Sleep(200);
|
||||
};
|
||||
});
|
||||
|
||||
Assert.IsTrue(waitAction.BeginInvoke(null, null).AsyncWaitHandle.WaitOne(timeout), failureMessage);
|
||||
Assert.IsTrue(task.Wait(timeout), failureMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,11 +65,7 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
carousel.SelectionChanged = s => currentSelection = s;
|
||||
|
||||
AddStep("Load Beatmaps", () => { carousel.BeatmapSets = beatmapSets; });
|
||||
|
||||
bool changed = false;
|
||||
carousel.BeatmapSetsChanged = () => changed = true;
|
||||
AddUntilStep(() => changed, "Wait for load");
|
||||
loadBeatmaps(beatmapSets);
|
||||
|
||||
testTraversal();
|
||||
testFiltering();
|
||||
@ -84,6 +80,17 @@ namespace osu.Game.Tests.Visual
|
||||
testCarouselRootIsRandom();
|
||||
}
|
||||
|
||||
private void loadBeatmaps(List<BeatmapSetInfo> beatmapSets)
|
||||
{
|
||||
bool changed = false;
|
||||
AddStep($"Load {beatmapSets.Count} Beatmaps", () =>
|
||||
{
|
||||
carousel.BeatmapSetsChanged = () => changed = true;
|
||||
carousel.BeatmapSets = beatmapSets;
|
||||
});
|
||||
AddUntilStep(() => changed, "Wait for load");
|
||||
}
|
||||
|
||||
private void ensureRandomFetchSuccess() =>
|
||||
AddAssert("ensure prev random fetch worked", () => selectedSets.Peek() == carousel.SelectedBeatmapSet);
|
||||
|
||||
@ -423,7 +430,7 @@ namespace osu.Game.Tests.Visual
|
||||
for (int i = 1; i <= 50; i++)
|
||||
beatmapSets.Add(createTestBeatmapSet(i));
|
||||
|
||||
AddStep("Load 50 Beatmaps", () => { carousel.BeatmapSets = beatmapSets; });
|
||||
loadBeatmaps(beatmapSets);
|
||||
advanceSelection(direction: 1, diff: false);
|
||||
checkNonmatchingFilter();
|
||||
checkNonmatchingFilter();
|
||||
|
@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual
|
||||
AddStep("show", () =>
|
||||
{
|
||||
infoWedge.State = Visibility.Visible;
|
||||
infoWedge.UpdateBeatmap(beatmap);
|
||||
infoWedge.Beatmap = beatmap;
|
||||
});
|
||||
|
||||
// select part is redundant, but wait for load isn't
|
||||
@ -133,7 +133,7 @@ namespace osu.Game.Tests.Visual
|
||||
AddStep($"select {b.Metadata.Title} beatmap", () =>
|
||||
{
|
||||
infoBefore = infoWedge.Info;
|
||||
infoWedge.UpdateBeatmap(beatmap.Value = new TestWorkingBeatmap(b));
|
||||
infoWedge.Beatmap = beatmap.Value = new TestWorkingBeatmap(b);
|
||||
});
|
||||
|
||||
AddUntilStep(() => infoWedge.Info != infoBefore, "wait for async load");
|
||||
@ -144,7 +144,7 @@ namespace osu.Game.Tests.Visual
|
||||
AddStep("select null beatmap", () =>
|
||||
{
|
||||
beatmap.Value = beatmap.Default;
|
||||
infoWedge.UpdateBeatmap(beatmap);
|
||||
infoWedge.Beatmap = beatmap;
|
||||
});
|
||||
}
|
||||
|
||||
|
115
osu.Game.Tests/Visual/TestCaseLoaderAnimation.cs
Normal file
115
osu.Game.Tests/Visual/TestCaseLoaderAnimation.cs
Normal file
@ -0,0 +1,115 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Screens;
|
||||
using osu.Game.Screens.Menu;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseLoaderAnimation : OsuTestCase
|
||||
{
|
||||
private TestLoader loader;
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
// required to preload the logo in a headless run (so it doesn't delay the loading itself).
|
||||
Add(new OsuLogo());
|
||||
|
||||
bool logoVisible = false;
|
||||
AddStep("almost instant display", () => Child = loader = new TestLoader(250));
|
||||
AddUntilStep(() =>
|
||||
{
|
||||
logoVisible = loader.Logo?.Alpha > 0;
|
||||
return loader.Logo != null && loader.ScreenLoaded;
|
||||
}, "loaded");
|
||||
AddAssert("logo not visible", () => !logoVisible);
|
||||
|
||||
AddStep("short load", () => Child = loader = new TestLoader(800));
|
||||
AddUntilStep(() =>
|
||||
{
|
||||
logoVisible = loader.Logo?.Alpha > 0;
|
||||
return loader.Logo != null && loader.ScreenLoaded;
|
||||
}, "loaded");
|
||||
AddAssert("logo visible", () => logoVisible);
|
||||
AddUntilStep(() => loader.Logo?.Alpha == 0, "logo gone");
|
||||
|
||||
AddStep("longer load", () => Child = loader = new TestLoader(1400));
|
||||
AddUntilStep(() =>
|
||||
{
|
||||
logoVisible = loader.Logo?.Alpha > 0;
|
||||
return loader.Logo != null && loader.ScreenLoaded;
|
||||
}, "loaded");
|
||||
AddAssert("logo visible", () => logoVisible);
|
||||
AddUntilStep(() => loader.Logo?.Alpha == 0, "logo gone");
|
||||
}
|
||||
|
||||
private class TestLoader : Loader
|
||||
{
|
||||
private readonly double delay;
|
||||
|
||||
public OsuLogo Logo;
|
||||
private TestScreen screen;
|
||||
|
||||
public bool ScreenLoaded => screen.IsCurrentScreen;
|
||||
|
||||
public TestLoader(double delay)
|
||||
{
|
||||
this.delay = delay;
|
||||
}
|
||||
|
||||
protected override void LogoArriving(OsuLogo logo, bool resuming)
|
||||
{
|
||||
Logo = logo;
|
||||
base.LogoArriving(logo, resuming);
|
||||
}
|
||||
|
||||
protected override OsuScreen CreateLoadableScreen() => screen = new TestScreen();
|
||||
protected override ShaderPrecompiler CreateShaderPrecompiler() => new TestShaderPrecompiler(delay);
|
||||
|
||||
private class TestShaderPrecompiler : ShaderPrecompiler
|
||||
{
|
||||
private readonly double delay;
|
||||
private double startTime;
|
||||
|
||||
public TestShaderPrecompiler(double delay)
|
||||
{
|
||||
this.delay = delay;
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
startTime = Time.Current;
|
||||
}
|
||||
|
||||
protected override bool AllLoaded => Time.Current > startTime + delay;
|
||||
}
|
||||
|
||||
private class TestScreen : OsuScreen
|
||||
{
|
||||
public TestScreen()
|
||||
{
|
||||
Child = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.DarkSlateGray,
|
||||
Alpha = 0,
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LogoArriving(OsuLogo logo, bool resuming)
|
||||
{
|
||||
base.LogoArriving(logo, resuming);
|
||||
Child.FadeInFromZero(200);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
<Import Project="..\osu.TestProject.props" />
|
||||
<PropertyGroup Label="Project">
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFrameworks>netcoreapp2.0;net471</TargetFrameworks>
|
||||
<TargetFrameworks>netcoreapp2.1;net471</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
||||
|
@ -170,7 +170,7 @@ namespace osu.Game.Beatmaps
|
||||
{
|
||||
if (error is OperationCanceledException) return;
|
||||
|
||||
downloadNotification.State = ProgressNotificationState.Completed;
|
||||
downloadNotification.State = ProgressNotificationState.Cancelled;
|
||||
Logger.Error(error, "Beatmap download failed!");
|
||||
currentDownloads.Remove(request);
|
||||
};
|
||||
|
@ -82,6 +82,8 @@ namespace osu.Game.Configuration
|
||||
|
||||
Set(OsuSetting.SpeedChangeVisualisation, SpeedChangeVisualisationMethod.Sequential);
|
||||
|
||||
Set(OsuSetting.IncreaseFirstObjectVisibility, true);
|
||||
|
||||
// Update
|
||||
Set(OsuSetting.ReleaseStream, ReleaseStream.Lazer);
|
||||
|
||||
@ -144,6 +146,7 @@ namespace osu.Game.Configuration
|
||||
ScreenshotCaptureMenuCursor,
|
||||
SongSelectRightMouseScroll,
|
||||
BeatmapSkins,
|
||||
BeatmapHitsounds
|
||||
BeatmapHitsounds,
|
||||
IncreaseFirstObjectVisibility
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using osu.Framework.IO.File;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.IO;
|
||||
@ -364,7 +365,7 @@ namespace osu.Game.Database
|
||||
using (Stream s = reader.GetStream(file))
|
||||
fileInfos.Add(new TFileModel
|
||||
{
|
||||
Filename = file,
|
||||
Filename = FileSafety.PathSanitise(file),
|
||||
FileInfo = files.Add(s)
|
||||
});
|
||||
|
||||
|
@ -8,6 +8,7 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Input;
|
||||
using OpenTK;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Game.Overlays;
|
||||
|
||||
namespace osu.Game.Graphics.Containers
|
||||
{
|
||||
@ -16,13 +17,13 @@ namespace osu.Game.Graphics.Containers
|
||||
private SampleChannel samplePopIn;
|
||||
private SampleChannel samplePopOut;
|
||||
|
||||
private readonly BindableBool allowOpeningOverlays = new BindableBool(true);
|
||||
protected readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>(OverlayActivation.All);
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(OsuGame osuGame, AudioManager audio)
|
||||
{
|
||||
if (osuGame != null)
|
||||
allowOpeningOverlays.BindTo(osuGame.AllowOpeningOverlays);
|
||||
OverlayActivationMode.BindTo(osuGame.OverlayActivationMode);
|
||||
|
||||
samplePopIn = audio.Sample.Get(@"UI/overlay-pop-in");
|
||||
samplePopOut = audio.Sample.Get(@"UI/overlay-pop-out");
|
||||
@ -51,21 +52,19 @@ namespace osu.Game.Graphics.Containers
|
||||
}
|
||||
|
||||
private void onStateChanged(Visibility visibility)
|
||||
{
|
||||
if (allowOpeningOverlays)
|
||||
{
|
||||
switch (visibility)
|
||||
{
|
||||
case Visibility.Visible:
|
||||
if (OverlayActivationMode != OverlayActivation.Disabled)
|
||||
samplePopIn?.Play();
|
||||
else
|
||||
State = Visibility.Hidden;
|
||||
break;
|
||||
case Visibility.Hidden:
|
||||
samplePopOut?.Play();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
State = Visibility.Hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using osu.Framework.IO.File;
|
||||
|
||||
namespace osu.Game.IO.Archives
|
||||
{
|
||||
@ -15,19 +14,20 @@ namespace osu.Game.IO.Archives
|
||||
{
|
||||
private readonly string path;
|
||||
|
||||
public LegacyFilesystemReader(string path) : base(Path.GetFileName(path))
|
||||
public LegacyFilesystemReader(string path)
|
||||
: base(Path.GetFileName(path))
|
||||
{
|
||||
this.path = path;
|
||||
// re-get full path to standardise with Directory.GetFiles return values below.
|
||||
this.path = Path.GetFullPath(path);
|
||||
}
|
||||
|
||||
public override Stream GetStream(string name) => File.OpenRead(Path.Combine(path, name));
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
|
||||
public override IEnumerable<string> Filenames => Directory.GetFiles(path, "*", SearchOption.AllDirectories).Select(f => FileSafety.GetRelativePath(f, path)).ToArray();
|
||||
public override IEnumerable<string> Filenames => Directory.GetFiles(path, "*", SearchOption.AllDirectories).Select(f => f.Replace(path, string.Empty).Trim(Path.DirectorySeparatorChar)).ToArray();
|
||||
|
||||
public override Stream GetUnderlyingStream() => null;
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ namespace osu.Game.Online.API
|
||||
throw new TimeoutException(@"API request timeout hit");
|
||||
|
||||
WebRequest = CreateWebRequest();
|
||||
WebRequest.Failed += Fail;
|
||||
WebRequest.AllowRetryOnTimeout = false;
|
||||
WebRequest.AddHeader("Authorization", $"Bearer {api.AccessToken}");
|
||||
|
||||
|
@ -77,8 +77,7 @@ namespace osu.Game
|
||||
|
||||
public float ToolbarOffset => Toolbar.Position.Y + Toolbar.DrawHeight;
|
||||
|
||||
public readonly BindableBool HideOverlaysOnEnter = new BindableBool();
|
||||
public readonly BindableBool AllowOpeningOverlays = new BindableBool(true);
|
||||
public readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>();
|
||||
|
||||
private OsuScreen screenStack;
|
||||
|
||||
@ -94,6 +93,8 @@ namespace osu.Game
|
||||
|
||||
private SettingsOverlay settings;
|
||||
|
||||
private readonly List<OverlayContainer> overlays = new List<OverlayContainer>();
|
||||
|
||||
// todo: move this to SongSelect once Screen has the ability to unsuspend.
|
||||
public readonly Bindable<IEnumerable<Mod>> SelectedMods = new Bindable<IEnumerable<Mod>>(new List<Mod>());
|
||||
|
||||
@ -106,6 +107,17 @@ namespace osu.Game
|
||||
|
||||
public void ToggleDirect() => direct.ToggleVisibility();
|
||||
|
||||
/// <summary>
|
||||
/// Close all game-wide overlays.
|
||||
/// </summary>
|
||||
/// <param name="toolbar">Whether the toolbar should also be hidden.</param>
|
||||
public void CloseAllOverlays(bool toolbar = true)
|
||||
{
|
||||
foreach (var o in overlays)
|
||||
o.State = Visibility.Hidden;
|
||||
if (toolbar) Toolbar.State = Visibility.Hidden;
|
||||
}
|
||||
|
||||
private DependencyContainer dependencies;
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) =>
|
||||
@ -251,7 +263,7 @@ namespace osu.Game
|
||||
Depth = -5,
|
||||
OnHome = delegate
|
||||
{
|
||||
hideAllOverlays();
|
||||
CloseAllOverlays(false);
|
||||
intro?.ChildScreen?.MakeCurrent();
|
||||
},
|
||||
}, overlayContent.Add);
|
||||
@ -308,6 +320,8 @@ namespace osu.Game
|
||||
|
||||
// ensure only one of these overlays are open at once.
|
||||
var singleDisplayOverlays = new OverlayContainer[] { chat, social, direct };
|
||||
overlays.AddRange(singleDisplayOverlays);
|
||||
|
||||
foreach (var overlay in singleDisplayOverlays)
|
||||
{
|
||||
overlay.StateChanged += state =>
|
||||
@ -323,6 +337,8 @@ namespace osu.Game
|
||||
}
|
||||
|
||||
var singleDisplaySideOverlays = new OverlayContainer[] { settings, notifications };
|
||||
overlays.AddRange(singleDisplaySideOverlays);
|
||||
|
||||
foreach (var overlay in singleDisplaySideOverlays)
|
||||
{
|
||||
overlay.StateChanged += state =>
|
||||
@ -339,6 +355,8 @@ namespace osu.Game
|
||||
|
||||
// eventually informational overlays should be displayed in a stack, but for now let's only allow one to stay open at a time.
|
||||
var informationalOverlays = new OverlayContainer[] { beatmapSetOverlay, userProfile };
|
||||
overlays.AddRange(informationalOverlays);
|
||||
|
||||
foreach (var overlay in informationalOverlays)
|
||||
{
|
||||
overlay.StateChanged += state =>
|
||||
@ -353,6 +371,11 @@ namespace osu.Game
|
||||
};
|
||||
}
|
||||
|
||||
OverlayActivationMode.ValueChanged += v =>
|
||||
{
|
||||
if (v != OverlayActivation.All) CloseAllOverlays();
|
||||
};
|
||||
|
||||
void updateScreenOffset()
|
||||
{
|
||||
float offset = 0;
|
||||
@ -367,21 +390,6 @@ namespace osu.Game
|
||||
|
||||
settings.StateChanged += _ => updateScreenOffset();
|
||||
notifications.StateChanged += _ => updateScreenOffset();
|
||||
|
||||
notifications.Enabled.BindTo(AllowOpeningOverlays);
|
||||
|
||||
HideOverlaysOnEnter.ValueChanged += hide =>
|
||||
{
|
||||
//central game screen change logic.
|
||||
if (hide)
|
||||
{
|
||||
hideAllOverlays();
|
||||
musicController.State = Visibility.Hidden;
|
||||
Toolbar.State = Visibility.Hidden;
|
||||
}
|
||||
else
|
||||
Toolbar.State = Visibility.Visible;
|
||||
};
|
||||
}
|
||||
|
||||
private void forwardLoggedErrorsToNotifications()
|
||||
@ -498,16 +506,6 @@ namespace osu.Game
|
||||
private OsuScreen currentScreen;
|
||||
private FrameworkConfigManager frameworkConfig;
|
||||
|
||||
private void hideAllOverlays()
|
||||
{
|
||||
settings.State = Visibility.Hidden;
|
||||
chat.State = Visibility.Hidden;
|
||||
direct.State = Visibility.Hidden;
|
||||
social.State = Visibility.Hidden;
|
||||
userProfile.State = Visibility.Hidden;
|
||||
notifications.State = Visibility.Hidden;
|
||||
}
|
||||
|
||||
protected override bool OnExiting()
|
||||
{
|
||||
if (screenStack.ChildScreen == null) return false;
|
||||
|
@ -10,7 +10,6 @@ using System.Reflection;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Development;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.IO.Stores;
|
||||
@ -31,6 +30,7 @@ using osu.Game.IO;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Skinning;
|
||||
using DebugUtils = osu.Game.Utils.DebugUtils;
|
||||
|
||||
namespace osu.Game
|
||||
{
|
||||
@ -59,8 +59,6 @@ namespace osu.Game
|
||||
|
||||
protected MenuCursorContainer MenuCursorContainer;
|
||||
|
||||
protected override string MainResourceFile => @"osu.Game.Resources.dll";
|
||||
|
||||
private Container content;
|
||||
|
||||
protected override Container<Drawable> Content => content;
|
||||
@ -100,6 +98,8 @@ namespace osu.Game
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Resources.AddStore(new DllResourceStore(@"osu.Game.Resources.dll"));
|
||||
|
||||
dependencies.Cache(contextFactory = new DatabaseContextFactory(Host));
|
||||
|
||||
dependencies.Cache(new LargeTextureStore(new RawTextureLoaderStore(new NamespacedResourceStore<byte[]>(Resources, @"Textures"))));
|
||||
|
@ -21,7 +21,7 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
private const float metadata_width = 225;
|
||||
private const float spacing = 20;
|
||||
|
||||
private readonly MetadataSection description, source, tags;
|
||||
private readonly MetadataSection source, tags;
|
||||
private readonly Box successRateBackground;
|
||||
private readonly SuccessRate successRate;
|
||||
|
||||
@ -83,7 +83,7 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
Child = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Child = description = new MetadataSection("Description"),
|
||||
Child = new MetadataSection("Description"),
|
||||
},
|
||||
},
|
||||
new Container
|
||||
@ -135,8 +135,6 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
successRateBackground.Colour = colours.GrayE;
|
||||
source.TextColour = description.TextColour = colours.Gray5;
|
||||
tags.TextColour = colours.BlueDark;
|
||||
|
||||
updateDisplay();
|
||||
}
|
||||
@ -195,7 +193,7 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
header.Colour = colours.Gray5;
|
||||
header.Colour = textFlow.Colour = colours.Gray5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ namespace osu.Game.Overlays.KeyBinding
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override bool OnWheel(InputState state)
|
||||
protected override bool OnScroll(InputState state)
|
||||
{
|
||||
if (HasFocus)
|
||||
{
|
||||
@ -192,7 +192,7 @@ namespace osu.Game.Overlays.KeyBinding
|
||||
}
|
||||
}
|
||||
|
||||
return base.OnWheel(state);
|
||||
return base.OnScroll(state);
|
||||
}
|
||||
|
||||
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
||||
|
@ -22,11 +22,6 @@ namespace osu.Game.Overlays
|
||||
|
||||
public const float TRANSITION_LENGTH = 600;
|
||||
|
||||
/// <summary>
|
||||
/// Whether posted notifications should be processed.
|
||||
/// </summary>
|
||||
public readonly BindableBool Enabled = new BindableBool(true);
|
||||
|
||||
private FlowContainer<NotificationSection> sections;
|
||||
|
||||
/// <summary>
|
||||
@ -34,27 +29,6 @@ namespace osu.Game.Overlays
|
||||
/// </summary>
|
||||
public Func<float> GetToolbarHeight;
|
||||
|
||||
public NotificationOverlay()
|
||||
{
|
||||
ScheduledDelegate notificationsEnabler = null;
|
||||
Enabled.ValueChanged += v =>
|
||||
{
|
||||
if (!IsLoaded)
|
||||
{
|
||||
processingPosts = v;
|
||||
return;
|
||||
}
|
||||
|
||||
notificationsEnabler?.Cancel();
|
||||
|
||||
if (v)
|
||||
// we want a slight delay before toggling notifications on to avoid the user becoming overwhelmed.
|
||||
notificationsEnabler = Scheduler.AddDelayed(() => processingPosts = true, 1000);
|
||||
else
|
||||
processingPosts = false;
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
@ -103,6 +77,29 @@ namespace osu.Game.Overlays
|
||||
};
|
||||
}
|
||||
|
||||
private ScheduledDelegate notificationsEnabler;
|
||||
private void updateProcessingMode()
|
||||
{
|
||||
bool enabled = OverlayActivationMode == OverlayActivation.All || State == Visibility.Visible;
|
||||
|
||||
notificationsEnabler?.Cancel();
|
||||
|
||||
if (enabled)
|
||||
// we want a slight delay before toggling notifications on to avoid the user becoming overwhelmed.
|
||||
notificationsEnabler = Scheduler.AddDelayed(() => processingPosts = true, State == Visibility.Visible ? 0 : 1000);
|
||||
else
|
||||
processingPosts = false;
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
StateChanged += _ => updateProcessingMode();
|
||||
OverlayActivationMode.ValueChanged += _ => updateProcessingMode();
|
||||
OverlayActivationMode.TriggerChange();
|
||||
}
|
||||
|
||||
private int totalCount => sections.Select(c => c.DisplayedCount).Sum();
|
||||
private int unreadCount => sections.Select(c => c.UnreadCount).Sum();
|
||||
|
||||
|
12
osu.Game/Overlays/OverlayActivation.cs
Normal file
12
osu.Game/Overlays/OverlayActivation.cs
Normal file
@ -0,0 +1,12 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Overlays
|
||||
{
|
||||
public enum OverlayActivation
|
||||
{
|
||||
Disabled,
|
||||
UserTriggered,
|
||||
All
|
||||
}
|
||||
}
|
26
osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs
Normal file
26
osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Configuration;
|
||||
|
||||
namespace osu.Game.Overlays.Settings.Sections.Gameplay
|
||||
{
|
||||
public class ModsSettings : SettingsSubsection
|
||||
{
|
||||
protected override string Header => "Mods";
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuConfigManager config)
|
||||
{
|
||||
Children = new[]
|
||||
{
|
||||
new SettingsCheckbox
|
||||
{
|
||||
LabelText = "Increase visibility of first object with \"Hidden\" mod",
|
||||
Bindable = config.GetBindable<bool>(OsuSetting.IncreaseFirstObjectVisibility)
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -21,7 +21,8 @@ namespace osu.Game.Overlays.Settings.Sections
|
||||
{
|
||||
new GeneralSettings(),
|
||||
new SongSelectSettings(),
|
||||
new ScrollingSettings()
|
||||
new ScrollingSettings(),
|
||||
new ModsSettings(),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Development;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
@ -12,6 +11,7 @@ using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Rulesets;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using DebugUtils = osu.Game.Utils.DebugUtils;
|
||||
|
||||
namespace osu.Game.Overlays.Settings
|
||||
{
|
||||
|
@ -10,6 +10,8 @@ using osu.Framework.Input;
|
||||
using osu.Game.Graphics;
|
||||
using OpenTK;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
|
||||
namespace osu.Game.Overlays.Toolbar
|
||||
{
|
||||
@ -29,6 +31,8 @@ namespace osu.Game.Overlays.Toolbar
|
||||
private const float alpha_hovering = 0.8f;
|
||||
private const float alpha_normal = 0.6f;
|
||||
|
||||
private readonly Bindable<OverlayActivation> overlayActivationMode = new Bindable<OverlayActivation>(OverlayActivation.All);
|
||||
|
||||
public Toolbar()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
@ -76,6 +80,19 @@ namespace osu.Game.Overlays.Toolbar
|
||||
Size = new Vector2(1, HEIGHT);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(OsuGame osuGame)
|
||||
{
|
||||
if (osuGame != null)
|
||||
overlayActivationMode.BindTo(osuGame.OverlayActivationMode);
|
||||
|
||||
StateChanged += visibility =>
|
||||
{
|
||||
if (overlayActivationMode == OverlayActivation.Disabled)
|
||||
State = Visibility.Hidden;
|
||||
};
|
||||
}
|
||||
|
||||
public class ToolbarBackground : Container
|
||||
{
|
||||
private readonly Box solidBackground;
|
||||
|
15
osu.Game/Rulesets/Mods/IReadFromConfig.cs
Normal file
15
osu.Game/Rulesets/Mods/IReadFromConfig.cs
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Configuration;
|
||||
|
||||
namespace osu.Game.Rulesets.Mods
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface for mods that require reading access to the osu! configuration.
|
||||
/// </summary>
|
||||
public interface IReadFromConfig
|
||||
{
|
||||
void ReadFromConfig(OsuConfigManager config);
|
||||
}
|
||||
}
|
@ -1,16 +1,37 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace osu.Game.Rulesets.Mods
|
||||
{
|
||||
public abstract class ModHidden : Mod
|
||||
public abstract class ModHidden : Mod, IReadFromConfig, IApplicableToDrawableHitObjects
|
||||
{
|
||||
public override string Name => "Hidden";
|
||||
public override string ShortenedName => "HD";
|
||||
public override FontAwesome Icon => FontAwesome.fa_osu_mod_hidden;
|
||||
public override ModType Type => ModType.DifficultyIncrease;
|
||||
public override bool Ranked => true;
|
||||
|
||||
protected Bindable<bool> IncreaseFirstObjectVisibility = new Bindable<bool>();
|
||||
|
||||
public void ReadFromConfig(OsuConfigManager config)
|
||||
{
|
||||
IncreaseFirstObjectVisibility = config.GetBindable<bool>(OsuSetting.IncreaseFirstObjectVisibility);
|
||||
}
|
||||
|
||||
public virtual void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
||||
{
|
||||
// todo: fix ordering of objects so we don't have to do this (#2740).
|
||||
foreach (var d in drawables.Reverse().Skip(IncreaseFirstObjectVisibility ? 1 : 0))
|
||||
d.ApplyCustomUpdateState += ApplyHiddenState;
|
||||
}
|
||||
|
||||
protected virtual void ApplyHiddenState(DrawableHitObject hitObject, ArmedState state) { }
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Database;
|
||||
|
||||
namespace osu.Game.Rulesets
|
||||
@ -114,8 +115,9 @@ namespace osu.Game.Rulesets
|
||||
var assembly = Assembly.LoadFrom(file);
|
||||
loaded_assemblies[assembly] = assembly.GetTypes().First(t => t.IsPublic && t.IsSubclassOf(typeof(Ruleset)));
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error(e, "Failed to load ruleset");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ namespace osu.Game.Rulesets.UI
|
||||
public abstract IEnumerable<HitObject> Objects { get; }
|
||||
|
||||
private readonly Lazy<Playfield> playfield;
|
||||
|
||||
/// <summary>
|
||||
/// The playfield.
|
||||
/// </summary>
|
||||
@ -130,7 +131,6 @@ namespace osu.Game.Rulesets.UI
|
||||
HasReplayLoaded.Value = ReplayInputManager.ReplayInputHandler != null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates the cursor. May be null if the <see cref="RulesetContainer"/> doesn't provide a custom cursor.
|
||||
/// </summary>
|
||||
@ -194,6 +194,7 @@ namespace osu.Game.Rulesets.UI
|
||||
|
||||
protected override Container<Drawable> Content => content;
|
||||
private Container content;
|
||||
private IEnumerable<Mod> mods;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to assume the beatmap passed into this <see cref="RulesetContainer{TObject}"/> is for the current ruleset.
|
||||
@ -216,13 +217,10 @@ namespace osu.Game.Rulesets.UI
|
||||
|
||||
KeyBindingInputManager = CreateInputManager();
|
||||
KeyBindingInputManager.RelativeSizeAxes = Axes.Both;
|
||||
|
||||
// Add mods, should always be the last thing applied to give full control to mods
|
||||
applyMods(Mods);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
private void load(OsuConfigManager config)
|
||||
{
|
||||
KeyBindingInputManager.Add(content = new Container
|
||||
{
|
||||
@ -235,6 +233,9 @@ namespace osu.Game.Rulesets.UI
|
||||
if (Cursor != null)
|
||||
KeyBindingInputManager.Add(Cursor);
|
||||
|
||||
// Apply mods
|
||||
applyMods(Mods, config);
|
||||
|
||||
loadObjects();
|
||||
}
|
||||
|
||||
@ -242,13 +243,16 @@ namespace osu.Game.Rulesets.UI
|
||||
/// Applies the active mods to this RulesetContainer.
|
||||
/// </summary>
|
||||
/// <param name="mods"></param>
|
||||
private void applyMods(IEnumerable<Mod> mods)
|
||||
private void applyMods(IEnumerable<Mod> mods, OsuConfigManager config)
|
||||
{
|
||||
if (mods == null)
|
||||
return;
|
||||
|
||||
foreach (var mod in mods.OfType<IApplicableToRulesetContainer<TObject>>())
|
||||
mod.ApplyToRulesetContainer(this);
|
||||
|
||||
foreach (var mod in mods.OfType<IReadFromConfig>())
|
||||
mod.ReadFromConfig(config);
|
||||
}
|
||||
|
||||
public override void SetReplay(Replay replay)
|
||||
|
@ -121,8 +121,6 @@ namespace osu.Game.Rulesets.UI
|
||||
/// </summary>
|
||||
private bool validState;
|
||||
|
||||
protected override bool RequiresChildrenUpdate => base.RequiresChildrenUpdate && validState;
|
||||
|
||||
private bool isAttached => replayInputHandler != null && !UseParentState;
|
||||
|
||||
private const int max_catch_up_updates_per_frame = 50;
|
||||
|
@ -182,9 +182,9 @@ namespace osu.Game.Screens.Edit
|
||||
LoadComponentAsync(currentScreen, screenContainer.Add);
|
||||
}
|
||||
|
||||
protected override bool OnWheel(InputState state)
|
||||
protected override bool OnScroll(InputState state)
|
||||
{
|
||||
if (state.Mouse.WheelDelta > 0)
|
||||
if (state.Mouse.ScrollDelta.X + state.Mouse.ScrollDelta.Y > 0)
|
||||
clock.SeekBackward(true);
|
||||
else
|
||||
clock.SeekForward(true);
|
||||
|
@ -123,15 +123,15 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
|
||||
/// </summary>
|
||||
private float? localZoomTarget;
|
||||
|
||||
protected override bool OnWheel(InputState state)
|
||||
protected override bool OnScroll(InputState state)
|
||||
{
|
||||
if (!state.Keyboard.ControlPressed)
|
||||
return base.OnWheel(state);
|
||||
return base.OnScroll(state);
|
||||
|
||||
relativeContentZoomTarget = Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X;
|
||||
localZoomTarget = ToLocalSpace(state.Mouse.NativeState.Position).X;
|
||||
|
||||
Zoom += state.Mouse.WheelDelta;
|
||||
Zoom += state.Mouse.ScrollDelta.Y;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
// 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
@ -30,43 +29,48 @@ namespace osu.Game.Screens
|
||||
{
|
||||
base.LogoArriving(logo, resuming);
|
||||
|
||||
logo.BeatMatching = false;
|
||||
logo.Triangles = false;
|
||||
logo.Origin = Anchor.BottomRight;
|
||||
logo.Anchor = Anchor.BottomRight;
|
||||
logo.Position = new Vector2(-40);
|
||||
logo.Scale = new Vector2(0.2f);
|
||||
|
||||
logo.FadeInFromZero(5000, Easing.OutQuint);
|
||||
}
|
||||
|
||||
private OsuScreen loadScreen;
|
||||
private ShaderPrecompiler precompiler;
|
||||
|
||||
protected override void OnEntering(Screen last)
|
||||
{
|
||||
base.OnEntering(last);
|
||||
|
||||
LoadComponentAsync(precompiler = new ShaderPrecompiler(loadIfReady), Add);
|
||||
LoadComponentAsync(loadScreen = showDisclaimer ? (OsuScreen)new Disclaimer() : new Intro(), s => loadIfReady());
|
||||
}
|
||||
|
||||
private void loadIfReady()
|
||||
{
|
||||
if (ChildScreen == loadScreen) return;
|
||||
|
||||
if (loadScreen.LoadState != LoadState.Ready)
|
||||
return;
|
||||
|
||||
if (!precompiler.FinishedCompiling)
|
||||
return;
|
||||
|
||||
Push(loadScreen);
|
||||
logo.Delay(500).FadeInFromZero(1000, Easing.OutQuint);
|
||||
}
|
||||
|
||||
protected override void LogoSuspending(OsuLogo logo)
|
||||
{
|
||||
base.LogoSuspending(logo);
|
||||
logo.FadeOut(100);
|
||||
logo.FadeOut(logo.Alpha * 400);
|
||||
}
|
||||
|
||||
private OsuScreen loadableScreen;
|
||||
private ShaderPrecompiler precompiler;
|
||||
|
||||
protected virtual OsuScreen CreateLoadableScreen() => showDisclaimer ? (OsuScreen)new Disclaimer() : new Intro();
|
||||
|
||||
protected virtual ShaderPrecompiler CreateShaderPrecompiler() => new ShaderPrecompiler();
|
||||
|
||||
protected override void OnEntering(Screen last)
|
||||
{
|
||||
base.OnEntering(last);
|
||||
|
||||
LoadComponentAsync(precompiler = CreateShaderPrecompiler(), Add);
|
||||
LoadComponentAsync(loadableScreen = CreateLoadableScreen());
|
||||
|
||||
checkIfLoaded();
|
||||
}
|
||||
|
||||
private void checkIfLoaded()
|
||||
{
|
||||
if (loadableScreen.LoadState != LoadState.Ready || !precompiler.FinishedCompiling)
|
||||
{
|
||||
Schedule(checkIfLoaded);
|
||||
return;
|
||||
}
|
||||
|
||||
Push(loadableScreen);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
@ -80,16 +84,10 @@ namespace osu.Game.Screens
|
||||
/// </summary>
|
||||
public class ShaderPrecompiler : Drawable
|
||||
{
|
||||
private readonly Action onLoaded;
|
||||
private readonly List<Shader> loadTargets = new List<Shader>();
|
||||
|
||||
public bool FinishedCompiling { get; private set; }
|
||||
|
||||
public ShaderPrecompiler(Action onLoaded)
|
||||
{
|
||||
this.onLoaded = onLoaded;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(ShaderManager manager)
|
||||
{
|
||||
@ -103,16 +101,17 @@ namespace osu.Game.Screens
|
||||
loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_3, FragmentShaderDescriptor.TEXTURE));
|
||||
}
|
||||
|
||||
protected virtual bool AllLoaded => loadTargets.All(s => s.Loaded);
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
// if our target is null we are done.
|
||||
if (loadTargets.All(s => s.Loaded))
|
||||
if (AllLoaded)
|
||||
{
|
||||
FinishedCompiling = true;
|
||||
Expire();
|
||||
onLoaded?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ using osu.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
@ -17,6 +16,7 @@ using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Input.Bindings;
|
||||
using osu.Game.Overlays;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Input;
|
||||
@ -27,9 +27,6 @@ namespace osu.Game.Screens.Menu
|
||||
{
|
||||
public event Action<MenuState> StateChanged;
|
||||
|
||||
private readonly BindableBool hideOverlaysOnEnter = new BindableBool();
|
||||
private readonly BindableBool allowOpeningOverlays = new BindableBool();
|
||||
|
||||
public Action OnEdit;
|
||||
public Action OnExit;
|
||||
public Action OnDirect;
|
||||
@ -133,15 +130,12 @@ namespace osu.Game.Screens.Menu
|
||||
buttonFlow.AddRange(buttonsTopLevel);
|
||||
}
|
||||
|
||||
private OsuGame game;
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(AudioManager audio, OsuGame game)
|
||||
{
|
||||
if (game != null)
|
||||
{
|
||||
hideOverlaysOnEnter.BindTo(game.HideOverlaysOnEnter);
|
||||
allowOpeningOverlays.BindTo(game.AllowOpeningOverlays);
|
||||
}
|
||||
|
||||
this.game = game;
|
||||
sampleBack = audio.Sample.Get(@"Menu/button-back-select");
|
||||
}
|
||||
|
||||
@ -331,8 +325,8 @@ namespace osu.Game.Screens.Menu
|
||||
{
|
||||
logoTracking = false;
|
||||
|
||||
hideOverlaysOnEnter.Value = true;
|
||||
allowOpeningOverlays.Value = false;
|
||||
if (game != null)
|
||||
game.OverlayActivationMode.Value = state == MenuState.Exit ? OverlayActivation.Disabled : OverlayActivation.UserTriggered;
|
||||
|
||||
logo.ClearTransforms(targetMember: nameof(Position));
|
||||
logo.RelativePositionAxes = Axes.Both;
|
||||
@ -366,8 +360,11 @@ namespace osu.Game.Screens.Menu
|
||||
if (impact)
|
||||
logo.Impact();
|
||||
|
||||
hideOverlaysOnEnter.Value = false;
|
||||
allowOpeningOverlays.Value = true;
|
||||
if (game != null)
|
||||
{
|
||||
game.OverlayActivationMode.Value = OverlayActivation.All;
|
||||
game.Toolbar.State = Visibility.Visible;
|
||||
}
|
||||
}, 200);
|
||||
break;
|
||||
default:
|
||||
|
@ -9,6 +9,7 @@ using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Game.Overlays;
|
||||
|
||||
namespace osu.Game.Screens.Menu
|
||||
{
|
||||
@ -19,7 +20,7 @@ namespace osu.Game.Screens.Menu
|
||||
private Color4 iconColour;
|
||||
|
||||
protected override bool HideOverlaysOnEnter => true;
|
||||
protected override bool AllowOpeningOverlays => false;
|
||||
protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.Disabled;
|
||||
|
||||
public override bool CursorVisible => false;
|
||||
|
||||
|
@ -15,6 +15,7 @@ using osu.Game.IO.Archives;
|
||||
using osu.Game.Screens.Backgrounds;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Game.Overlays;
|
||||
|
||||
namespace osu.Game.Screens.Menu
|
||||
{
|
||||
@ -32,7 +33,7 @@ namespace osu.Game.Screens.Menu
|
||||
private SampleChannel seeya;
|
||||
|
||||
protected override bool HideOverlaysOnEnter => true;
|
||||
protected override bool AllowOpeningOverlays => false;
|
||||
protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.Disabled;
|
||||
|
||||
public override bool CursorVisible => false;
|
||||
|
||||
@ -79,10 +80,17 @@ namespace osu.Game.Screens.Menu
|
||||
seeya = audio.Sample.Get(@"seeya");
|
||||
}
|
||||
|
||||
protected override void OnEntering(Screen last)
|
||||
{
|
||||
base.OnEntering(last);
|
||||
private const double delay_step_one = 2300;
|
||||
private const double delay_step_two = 600;
|
||||
|
||||
public const int EXIT_DELAY = 3000;
|
||||
|
||||
protected override void LogoArriving(OsuLogo logo, bool resuming)
|
||||
{
|
||||
base.LogoArriving(logo, resuming);
|
||||
|
||||
if (!resuming)
|
||||
{
|
||||
Game.Beatmap.Value = beatmap;
|
||||
|
||||
if (menuVoice)
|
||||
@ -104,15 +112,6 @@ namespace osu.Game.Screens.Menu
|
||||
}, delay_step_two);
|
||||
}
|
||||
|
||||
private const double delay_step_one = 2300;
|
||||
private const double delay_step_two = 600;
|
||||
|
||||
public const int EXIT_DELAY = 3000;
|
||||
|
||||
protected override void LogoArriving(OsuLogo logo, bool resuming)
|
||||
{
|
||||
base.LogoArriving(logo, resuming);
|
||||
|
||||
logo.RelativePositionAxes = Axes.Both;
|
||||
logo.Colour = Color4.White;
|
||||
logo.Ripple = false;
|
||||
|
@ -25,7 +25,6 @@ namespace osu.Game.Screens.Menu
|
||||
private readonly ButtonSystem buttons;
|
||||
|
||||
protected override bool HideOverlaysOnEnter => buttons.State == MenuState.Initial;
|
||||
protected override bool AllowOpeningOverlays => buttons.State != MenuState.Initial;
|
||||
|
||||
protected override bool AllowBackButton => buttons.State != MenuState.Initial;
|
||||
|
||||
|
@ -24,8 +24,8 @@ namespace osu.Game.Screens.Menu
|
||||
|
||||
private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
||||
|
||||
private readonly Box leftBox;
|
||||
private readonly Box rightBox;
|
||||
private Box leftBox;
|
||||
private Box rightBox;
|
||||
|
||||
private const float amplitude_dead_zone = 0.25f;
|
||||
private const float alpha_multiplier = (1 - amplitude_dead_zone) / 0.55f;
|
||||
@ -42,27 +42,6 @@ namespace osu.Game.Screens.Menu
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
Children = new Drawable[]
|
||||
{
|
||||
leftBox = new Box
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = box_width,
|
||||
Alpha = 0,
|
||||
Blending = BlendingMode.Additive,
|
||||
},
|
||||
rightBox = new Box
|
||||
{
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = box_width,
|
||||
Alpha = 0,
|
||||
Blending = BlendingMode.Additive,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
@ -72,10 +51,34 @@ namespace osu.Game.Screens.Menu
|
||||
|
||||
// linear colour looks better in this case, so let's use it for now.
|
||||
Color4 gradientDark = colours.Blue.Opacity(0).ToLinear();
|
||||
Color4 gradientLight = colours.Blue.Opacity(0.3f).ToLinear();
|
||||
Color4 gradientLight = colours.Blue.Opacity(0.6f).ToLinear();
|
||||
|
||||
leftBox.Colour = ColourInfo.GradientHorizontal(gradientLight, gradientDark);
|
||||
rightBox.Colour = ColourInfo.GradientHorizontal(gradientDark, gradientLight);
|
||||
Children = new Drawable[]
|
||||
{
|
||||
leftBox = new Box
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = box_width * 2,
|
||||
// align off-screen to make sure our edges don't become visible during parallax.
|
||||
X = -box_width,
|
||||
Alpha = 0,
|
||||
Blending = BlendingMode.Additive,
|
||||
Colour = ColourInfo.GradientHorizontal(gradientLight, gradientDark)
|
||||
},
|
||||
rightBox = new Box
|
||||
{
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = box_width * 2,
|
||||
X = box_width,
|
||||
Alpha = 0,
|
||||
Blending = BlendingMode.Additive,
|
||||
Colour = ColourInfo.GradientHorizontal(gradientDark, gradientLight)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||
|
@ -64,6 +64,8 @@ namespace osu.Game.Screens.Menu
|
||||
set { colourAndTriangles.FadeTo(value ? 1 : 0, transition_length, Easing.OutQuint); }
|
||||
}
|
||||
|
||||
public bool BeatMatching = true;
|
||||
|
||||
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => logoContainer.ReceiveMouseInputAt(screenSpacePos);
|
||||
|
||||
public bool Ripple
|
||||
@ -264,6 +266,8 @@ namespace osu.Game.Screens.Menu
|
||||
{
|
||||
base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes);
|
||||
|
||||
if (!BeatMatching) return;
|
||||
|
||||
lastBeatIndex = beatIndex;
|
||||
|
||||
var beatLength = timingPoint.BeatLength;
|
||||
|
@ -18,6 +18,8 @@ using osu.Game.Rulesets;
|
||||
using osu.Game.Screens.Menu;
|
||||
using OpenTK;
|
||||
using OpenTK.Input;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
|
||||
namespace osu.Game.Screens
|
||||
{
|
||||
@ -40,19 +42,19 @@ namespace osu.Game.Screens
|
||||
/// </summary>
|
||||
protected virtual BackgroundScreen CreateBackground() => null;
|
||||
|
||||
private readonly BindableBool hideOverlaysOnEnter = new BindableBool();
|
||||
private Action updateOverlayStates;
|
||||
|
||||
/// <summary>
|
||||
/// Whether overlays should be hidden when this screen is entered or resumed.
|
||||
/// Whether all overlays should be hidden when this screen is entered or resumed.
|
||||
/// </summary>
|
||||
protected virtual bool HideOverlaysOnEnter => false;
|
||||
|
||||
private readonly BindableBool allowOpeningOverlays = new BindableBool();
|
||||
protected readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>();
|
||||
|
||||
/// <summary>
|
||||
/// Whether overlays should be able to be opened while this screen is active.
|
||||
/// Whether overlays should be able to be opened once this screen is entered or resumed.
|
||||
/// </summary>
|
||||
protected virtual bool AllowOpeningOverlays => true;
|
||||
protected virtual OverlayActivation InitialOverlayActivationMode => OverlayActivation.All;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this <see cref="OsuScreen"/> allows the cursor to be displayed.
|
||||
@ -103,8 +105,15 @@ namespace osu.Game.Screens
|
||||
if (osuGame != null)
|
||||
{
|
||||
Ruleset.BindTo(osuGame.Ruleset);
|
||||
hideOverlaysOnEnter.BindTo(osuGame.HideOverlaysOnEnter);
|
||||
allowOpeningOverlays.BindTo(osuGame.AllowOpeningOverlays);
|
||||
OverlayActivationMode.BindTo(osuGame.OverlayActivationMode);
|
||||
|
||||
updateOverlayStates = () =>
|
||||
{
|
||||
if (HideOverlaysOnEnter)
|
||||
osuGame.CloseAllOverlays();
|
||||
else
|
||||
osuGame.Toolbar.State = Visibility.Visible;
|
||||
};
|
||||
}
|
||||
|
||||
sampleExit = audio.Sample.Get(@"UI/screen-back");
|
||||
@ -225,6 +234,7 @@ namespace osu.Game.Screens
|
||||
logo.Anchor = Anchor.TopLeft;
|
||||
logo.Origin = Anchor.Centre;
|
||||
logo.RelativePositionAxes = Axes.None;
|
||||
logo.BeatMatching = true;
|
||||
logo.Triangles = true;
|
||||
logo.Ripple = true;
|
||||
}
|
||||
@ -239,8 +249,9 @@ namespace osu.Game.Screens
|
||||
if (backgroundParallaxContainer != null)
|
||||
backgroundParallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * BackgroundParallaxAmount;
|
||||
|
||||
hideOverlaysOnEnter.Value = HideOverlaysOnEnter;
|
||||
allowOpeningOverlays.Value = AllowOpeningOverlays;
|
||||
OverlayActivationMode.Value = InitialOverlayActivationMode;
|
||||
|
||||
updateOverlayStates?.Invoke();
|
||||
}
|
||||
|
||||
private void onExitingLogo()
|
||||
|
@ -21,6 +21,7 @@ using osu.Game.Configuration;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Cursor;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
@ -37,6 +38,8 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
protected override bool HideOverlaysOnEnter => true;
|
||||
|
||||
protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.UserTriggered;
|
||||
|
||||
public Action RestartRequested;
|
||||
|
||||
public bool HasFailed { get; private set; }
|
||||
@ -364,7 +367,7 @@ namespace osu.Game.Screens.Play
|
||||
Background?.FadeTo(1f, fade_out_duration);
|
||||
}
|
||||
|
||||
protected override bool OnWheel(InputState state) => mouseWheelDisabled.Value && !pauseContainer.IsPaused;
|
||||
protected override bool OnScroll(InputState state) => mouseWheelDisabled.Value && !pauseContainer.IsPaused;
|
||||
|
||||
private void initializeStoryboard(bool asyncLoad)
|
||||
{
|
||||
|
@ -50,11 +50,11 @@ namespace osu.Game.Screens.Play.PlayerSettings
|
||||
content.ResizeHeightTo(0, transition_duration, Easing.OutQuint);
|
||||
}
|
||||
|
||||
button.FadeColour(expanded ? buttonActiveColour : Color4.White, 200, Easing.OutQuint);
|
||||
updateExpanded();
|
||||
}
|
||||
}
|
||||
|
||||
private Color4 buttonActiveColour;
|
||||
private Color4 expandedColour;
|
||||
|
||||
protected PlayerSettingsGroup()
|
||||
{
|
||||
@ -130,9 +130,13 @@ namespace osu.Game.Screens.Play.PlayerSettings
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
button.Colour = buttonActiveColour = colours.Yellow;
|
||||
expandedColour = colours.Yellow;
|
||||
|
||||
updateExpanded();
|
||||
}
|
||||
|
||||
private void updateExpanded() => button.FadeColour(expanded ? expandedColour : Color4.White, 200, Easing.InOutQuint);
|
||||
|
||||
protected override Container<Drawable> Content => content;
|
||||
|
||||
protected override bool OnHover(InputState state) => true;
|
||||
|
@ -6,7 +6,6 @@ using OpenTK.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using System.Linq;
|
||||
@ -120,14 +119,8 @@ namespace osu.Game.Screens.Select
|
||||
Margin = new MarginPadding { Top = spacing * 2 },
|
||||
Children = new[]
|
||||
{
|
||||
description = new MetadataSection("Description")
|
||||
{
|
||||
TextColour = Color4.White.Opacity(0.75f),
|
||||
},
|
||||
source = new MetadataSection("Source")
|
||||
{
|
||||
TextColour = Color4.White.Opacity(0.75f),
|
||||
},
|
||||
description = new MetadataSection("Description"),
|
||||
source = new MetadataSection("Source"),
|
||||
tags = new MetadataSection("Tags"),
|
||||
},
|
||||
},
|
||||
@ -164,10 +157,9 @@ namespace osu.Game.Screens.Select
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours, APIAccess api)
|
||||
private void load(APIAccess api)
|
||||
{
|
||||
this.api = api;
|
||||
tags.TextColour = colours.Yellow;
|
||||
}
|
||||
|
||||
protected override void UpdateAfterChildren()
|
||||
@ -364,7 +356,7 @@ namespace osu.Game.Screens.Select
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Colour = textFlow.Colour,
|
||||
Colour = Color4.White.Opacity(0.75f),
|
||||
Text = text
|
||||
}, loaded =>
|
||||
{
|
||||
@ -375,12 +367,6 @@ namespace osu.Game.Screens.Select
|
||||
this.FadeIn(transition_duration);
|
||||
});
|
||||
}
|
||||
|
||||
public Color4 TextColour
|
||||
{
|
||||
get { return textFlow.Colour; }
|
||||
set { textFlow.Colour = value; }
|
||||
}
|
||||
}
|
||||
|
||||
private class DimmedLoadingAnimation : VisibilityContainer
|
||||
|
@ -57,7 +57,7 @@ namespace osu.Game.Screens.Select
|
||||
{
|
||||
if (osuGame != null)
|
||||
ruleset.BindTo(osuGame.Ruleset);
|
||||
ruleset.ValueChanged += updateRuleset;
|
||||
ruleset.ValueChanged += _ => updateDisplay();
|
||||
}
|
||||
|
||||
protected override bool BlockPassThroughMouse => false;
|
||||
@ -78,66 +78,76 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
private WorkingBeatmap beatmap;
|
||||
|
||||
public void UpdateBeatmap(WorkingBeatmap beatmap)
|
||||
public WorkingBeatmap Beatmap
|
||||
{
|
||||
this.beatmap = beatmap;
|
||||
loadBeatmap();
|
||||
get => beatmap;
|
||||
set
|
||||
{
|
||||
if (beatmap == value) return;
|
||||
|
||||
beatmap = value;
|
||||
updateDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateRuleset(RulesetInfo ruleset) => loadBeatmap();
|
||||
private BufferedWedgeInfo loadingInfo;
|
||||
|
||||
private void loadBeatmap()
|
||||
private void updateDisplay()
|
||||
{
|
||||
void updateState()
|
||||
void removeOldInfo()
|
||||
{
|
||||
State = beatmap == null ? Visibility.Hidden : Visibility.Visible;
|
||||
|
||||
Info?.FadeOut(250);
|
||||
Info?.Expire();
|
||||
Info = null;
|
||||
}
|
||||
|
||||
if (beatmap == null)
|
||||
{
|
||||
updateState();
|
||||
removeOldInfo();
|
||||
return;
|
||||
}
|
||||
|
||||
LoadComponentAsync(new BufferedWedgeInfo(beatmap, ruleset.Value)
|
||||
LoadComponentAsync(loadingInfo = new BufferedWedgeInfo(beatmap, ruleset.Value)
|
||||
{
|
||||
Shear = -Shear,
|
||||
Depth = Info?.Depth + 1 ?? 0,
|
||||
}, newInfo =>
|
||||
Depth = Info?.Depth + 1 ?? 0
|
||||
}, loaded =>
|
||||
{
|
||||
updateState();
|
||||
Add(Info = newInfo);
|
||||
// ensure we are the most recent loaded wedge.
|
||||
if (loaded != loadingInfo) return;
|
||||
|
||||
removeOldInfo();
|
||||
Add(Info = loaded);
|
||||
});
|
||||
}
|
||||
|
||||
public class BufferedWedgeInfo : BufferedContainer
|
||||
{
|
||||
private readonly WorkingBeatmap working;
|
||||
public OsuSpriteText VersionLabel { get; private set; }
|
||||
public OsuSpriteText TitleLabel { get; private set; }
|
||||
public OsuSpriteText ArtistLabel { get; private set; }
|
||||
public FillFlowContainer MapperContainer { get; private set; }
|
||||
public FillFlowContainer InfoLabelContainer { get; private set; }
|
||||
|
||||
private UnicodeBindableString titleBinding;
|
||||
private UnicodeBindableString artistBinding;
|
||||
|
||||
private readonly WorkingBeatmap beatmap;
|
||||
private readonly RulesetInfo ruleset;
|
||||
|
||||
public BufferedWedgeInfo(WorkingBeatmap working, RulesetInfo userRuleset)
|
||||
public BufferedWedgeInfo(WorkingBeatmap beatmap, RulesetInfo userRuleset)
|
||||
{
|
||||
this.working = working;
|
||||
|
||||
ruleset = userRuleset ?? working.BeatmapInfo.Ruleset;
|
||||
this.beatmap = beatmap;
|
||||
ruleset = userRuleset ?? beatmap.BeatmapInfo.Ruleset;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(LocalisationEngine localisation)
|
||||
{
|
||||
var beatmapInfo = working.BeatmapInfo;
|
||||
var metadata = beatmapInfo.Metadata ?? working.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata();
|
||||
var beatmapInfo = beatmap.BeatmapInfo;
|
||||
var metadata = beatmapInfo.Metadata ?? beatmap.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata();
|
||||
|
||||
PixelSnapping = true;
|
||||
CacheDrawnFrameBuffer = true;
|
||||
@ -165,7 +175,7 @@ namespace osu.Game.Screens.Select
|
||||
Children = new[]
|
||||
{
|
||||
// Zoomed-in and cropped beatmap background
|
||||
new BeatmapBackgroundSprite(working)
|
||||
new BeatmapBackgroundSprite(beatmap)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
@ -248,27 +258,27 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
private InfoLabel[] getInfoLabels()
|
||||
{
|
||||
var beatmap = working.Beatmap;
|
||||
var b = beatmap.Beatmap;
|
||||
|
||||
List<InfoLabel> labels = new List<InfoLabel>();
|
||||
|
||||
if (beatmap?.HitObjects?.Any() == true)
|
||||
if (b?.HitObjects?.Any() == true)
|
||||
{
|
||||
HitObject lastObject = beatmap.HitObjects.LastOrDefault();
|
||||
HitObject lastObject = b.HitObjects.LastOrDefault();
|
||||
double endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0;
|
||||
|
||||
labels.Add(new InfoLabel(new BeatmapStatistic
|
||||
{
|
||||
Name = "Length",
|
||||
Icon = FontAwesome.fa_clock_o,
|
||||
Content = TimeSpan.FromMilliseconds(endTime - beatmap.HitObjects.First().StartTime).ToString(@"m\:ss"),
|
||||
Content = TimeSpan.FromMilliseconds(endTime - b.HitObjects.First().StartTime).ToString(@"m\:ss"),
|
||||
}));
|
||||
|
||||
labels.Add(new InfoLabel(new BeatmapStatistic
|
||||
{
|
||||
Name = "BPM",
|
||||
Icon = FontAwesome.fa_circle,
|
||||
Content = getBPMRange(beatmap),
|
||||
Content = getBPMRange(b),
|
||||
}));
|
||||
|
||||
IBeatmap playableBeatmap;
|
||||
@ -276,12 +286,12 @@ namespace osu.Game.Screens.Select
|
||||
try
|
||||
{
|
||||
// Try to get the beatmap with the user's ruleset
|
||||
playableBeatmap = working.GetPlayableBeatmap(ruleset);
|
||||
playableBeatmap = beatmap.GetPlayableBeatmap(ruleset);
|
||||
}
|
||||
catch (BeatmapInvalidForRulesetException)
|
||||
{
|
||||
// Can't be converted to the user's ruleset, so use the beatmap's own ruleset
|
||||
playableBeatmap = working.GetPlayableBeatmap(working.BeatmapInfo.Ruleset);
|
||||
playableBeatmap = beatmap.GetPlayableBeatmap(beatmap.BeatmapInfo.Ruleset);
|
||||
}
|
||||
|
||||
labels.AddRange(playableBeatmap.GetStatistics().Select(s => new InfoLabel(s)));
|
||||
|
@ -8,6 +8,7 @@ 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.Shapes;
|
||||
using osu.Framework.Input;
|
||||
using osu.Game.Graphics;
|
||||
@ -142,6 +143,8 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
{
|
||||
flagBadgeContainer = new Container
|
||||
{
|
||||
Origin = Anchor.BottomLeft,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Size = new Vector2(87f, 20f),
|
||||
Masking = true,
|
||||
Children = new Drawable[]
|
||||
@ -155,14 +158,16 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Origin = Anchor.BottomLeft,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(10f, 0f),
|
||||
Margin = new MarginPadding { Left = edge_margin, },
|
||||
Margin = new MarginPadding { Left = edge_margin },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
maxCombo = new ScoreComponentLabel(FontAwesome.fa_link, Score.MaxCombo.ToString()),
|
||||
accuracy = new ScoreComponentLabel(FontAwesome.fa_crosshairs, string.Format(Score.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", Score.Accuracy)),
|
||||
maxCombo = new ScoreComponentLabel(FontAwesome.fa_link, Score.MaxCombo.ToString(), "Max Combo"),
|
||||
accuracy = new ScoreComponentLabel(FontAwesome.fa_crosshairs, string.Format(Score.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", Score.Accuracy), "Accuracy"),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -305,37 +310,61 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
}
|
||||
}
|
||||
|
||||
private class ScoreComponentLabel : Container
|
||||
private class ScoreComponentLabel : Container, IHasTooltip
|
||||
{
|
||||
public ScoreComponentLabel(FontAwesome icon, string value)
|
||||
{
|
||||
Anchor = Anchor.CentreLeft;
|
||||
Origin = Anchor.CentreLeft;
|
||||
Size = new Vector2(60f, 20f);
|
||||
Padding = new MarginPadding { Top = 10f, };
|
||||
private const float icon_size = 20;
|
||||
|
||||
private readonly string name;
|
||||
private readonly FillFlowContainer content;
|
||||
|
||||
public override bool Contains(Vector2 screenSpacePos) => content.Contains(screenSpacePos);
|
||||
|
||||
public string TooltipText => name;
|
||||
|
||||
public ScoreComponentLabel(FontAwesome icon, string value, string name)
|
||||
{
|
||||
this.name = name;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
Width = 60;
|
||||
|
||||
Child = content = new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new[]
|
||||
{
|
||||
new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Icon = FontAwesome.fa_square,
|
||||
Colour = OsuColour.FromHex(@"3087ac"),
|
||||
Size = new Vector2(icon_size),
|
||||
Rotation = 45,
|
||||
Size = new Vector2(20),
|
||||
Colour = OsuColour.FromHex(@"3087ac"),
|
||||
Icon = FontAwesome.fa_square,
|
||||
Shadow = true,
|
||||
},
|
||||
new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Icon = icon,
|
||||
Size = new Vector2(icon_size - 6),
|
||||
Colour = OsuColour.FromHex(@"a4edff"),
|
||||
Size = new Vector2(14),
|
||||
Icon = icon,
|
||||
},
|
||||
},
|
||||
},
|
||||
new GlowingSpriteText(value, @"Exo2.0-Bold", 17, Color4.White, OsuColour.FromHex(@"83ccfa"))
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Margin = new MarginPadding { Left = 15, },
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -430,7 +430,7 @@ namespace osu.Game.Screens.Select
|
||||
backgroundModeBeatmap.FadeTo(1, 250);
|
||||
}
|
||||
|
||||
beatmapInfoWedge.UpdateBeatmap(beatmap);
|
||||
beatmapInfoWedge.Beatmap = beatmap;
|
||||
}
|
||||
|
||||
private void ensurePlayingSelected(bool preview = false)
|
||||
|
@ -59,9 +59,9 @@ namespace osu.Game.Tests.Visual
|
||||
Clock.ProcessFrame();
|
||||
}
|
||||
|
||||
protected override bool OnWheel(InputState state)
|
||||
protected override bool OnScroll(InputState state)
|
||||
{
|
||||
if (state.Mouse.WheelDelta > 0)
|
||||
if (state.Mouse.ScrollDelta.Y > 0)
|
||||
Clock.SeekBackward(true);
|
||||
else
|
||||
Clock.SeekForward(true);
|
||||
|
@ -1,8 +1,6 @@
|
||||
// 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.IO;
|
||||
using System.Reflection;
|
||||
using osu.Framework.Testing;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
@ -13,8 +11,6 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
public class OsuTestCaseTestRunner : OsuGameBase, ITestCaseTestRunner
|
||||
{
|
||||
protected override string MainResourceFile => File.Exists(base.MainResourceFile) ? base.MainResourceFile : Assembly.GetExecutingAssembly().Location;
|
||||
|
||||
private TestCaseTestRunner.TestRunner runner;
|
||||
|
||||
protected override void LoadAsyncComplete()
|
||||
|
21
osu.Game/Utils/DebugUtils.cs
Normal file
21
osu.Game/Utils/DebugUtils.cs
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Utils
|
||||
{
|
||||
public static class DebugUtils
|
||||
{
|
||||
public static bool IsDebug
|
||||
{
|
||||
get
|
||||
{
|
||||
// ReSharper disable once RedundantAssignment
|
||||
bool isDebug = false;
|
||||
// Debug.Assert conditions are only evaluated in debug mode
|
||||
System.Diagnostics.Debug.Assert(isDebug = true);
|
||||
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
|
||||
return isDebug;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -11,7 +11,6 @@
|
||||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj" />
|
||||
<ProjectReference Include="..\osu-resources\osu.Game.Resources\osu.Game.Resources.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Package References">
|
||||
@ -19,6 +18,7 @@
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.0.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.0.3" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2018.606.0" />
|
||||
<PackageReference Include="SharpCompress" Version="0.18.1" />
|
||||
<PackageReference Include="NUnit" Version="3.10.1" />
|
||||
<PackageReference Include="System.ComponentModel.Annotations" Version="4.4.0" />
|
||||
|
@ -7,7 +7,6 @@
|
||||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj" />
|
||||
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
|
||||
<ProjectReference Include="..\osu-resources\osu.Game.Resources\osu.Game.Resources.csproj" />
|
||||
</ItemGroup>
|
||||
|
10
osu.sln
10
osu.sln
@ -5,8 +5,6 @@ VisualStudioVersion = 15.0.27004.2006
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game", "osu.Game\osu.Game.csproj", "{2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Framework", "osu-framework\osu.Framework\osu.Framework.csproj", "{C76BF5B3-985E-4D39-95FE-97C9C879B83A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Resources", "osu-resources\osu.Game.Resources\osu.Game.Resources.csproj", "{D9A367C9-4C1A-489F-9B05-A0CEA2B53B58}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Rulesets.Osu", "osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj", "{C92A607B-1FDD-4954-9F92-03FF547D9080}"
|
||||
@ -17,8 +15,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Rulesets.Taiko", "
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Rulesets.Mania", "osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj", "{48F4582B-7687-4621-9CBE-5C24197CB536}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Desktop.Deploy", "osu.Desktop.Deploy\osu.Desktop.Deploy.csproj", "{BAEA2F74-0315-4667-84E0-ACAC0B4BF785}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Tests", "osu.Game.Tests\osu.Game.Tests.csproj", "{54377672-20B1-40AF-8087-5CF73BF3953A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Desktop", "osu.Desktop\osu.Desktop.csproj", "{419659FD-72EA-4678-9EB8-B22A746CED70}"
|
||||
@ -41,10 +37,6 @@ Global
|
||||
{2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C76BF5B3-985E-4D39-95FE-97C9C879B83A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C76BF5B3-985E-4D39-95FE-97C9C879B83A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C76BF5B3-985E-4D39-95FE-97C9C879B83A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C76BF5B3-985E-4D39-95FE-97C9C879B83A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D9A367C9-4C1A-489F-9B05-A0CEA2B53B58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D9A367C9-4C1A-489F-9B05-A0CEA2B53B58}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D9A367C9-4C1A-489F-9B05-A0CEA2B53B58}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@ -65,8 +57,6 @@ Global
|
||||
{48F4582B-7687-4621-9CBE-5C24197CB536}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{48F4582B-7687-4621-9CBE-5C24197CB536}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{48F4582B-7687-4621-9CBE-5C24197CB536}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BAEA2F74-0315-4667-84E0-ACAC0B4BF785}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BAEA2F74-0315-4667-84E0-ACAC0B4BF785}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{54377672-20B1-40AF-8087-5CF73BF3953A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{54377672-20B1-40AF-8087-5CF73BF3953A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{54377672-20B1-40AF-8087-5CF73BF3953A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
Loading…
Reference in New Issue
Block a user