Skip to content

Commit

Permalink
add: 谱面背景图支持
Browse files Browse the repository at this point in the history
  • Loading branch information
MATRIX-feather committed Feb 25, 2024
1 parent c57ebf8 commit fca33aa
Show file tree
Hide file tree
Showing 4 changed files with 267 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Containers;
using osu.Framework.Logging;
using osu.Framework.Platform;
using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Models;
using Realms;
using File = System.IO.File;
using Path = System.IO.Path;

namespace osu.Game.Rulesets.IGPlayer.Feature.Gosumemory;

public partial class GosuRealmDirectAccessor : CompositeDrawable
{
private readonly RealmAccess realmAccess;
private readonly Realm realm;

public GosuRealmDirectAccessor(RealmAccess realmAccess)
{
this.realmAccess = realmAccess;
this.realm = realm;
}

[Resolved]
private Storage storage { get; set; } = null!;

private string filesRoot()
{
return Path.Combine(storageRoot(), "files");
}

private string storageRoot()
{
return storage.GetFullPath(".");
}

public string? ExportFileSingle(BeatmapSetInfo setInfo, string targetFile, string? desti)
{
try
{
string? path = exportFileSingle(setInfo, targetFile, desti);
return path;
}
catch (Exception e)
{
Logging.LogError(e, "Error occurred while reading file.");
Logger.Log(e.ToString());
return null;
}
}

/// <summary>
///
/// </summary>
/// <param name="setInfo"></param>
/// <param name="targetFile"></param>
/// <param name="desti"></param>
/// <returns>The final location of the exported file.</returns>
private string? exportFileSingle(BeatmapSetInfo setInfo, string targetFile, string? desti)
{
RealmNamedFileUsage? realmNamedFileUsage = setInfo.Files.FirstOrDefault(fileUsage => fileUsage.Filename.Equals(targetFile));

if (realmNamedFileUsage == null)
{
Logger.Log($"File not found for '{targetFile}'");
return null;
}

string sourc = getRealmedFileName(realmNamedFileUsage.File.Hash);
desti ??= Path.Combine(storageRoot(), realmNamedFileUsage.File.Hash.Substring(0, 8));

try
{
string path = Path.Combine(filesRoot(), sourc);

var parent = Directory.GetParent(path);

if (parent == null)
{
Logger.Log($"{path} is filesystem root... It should'n be!");
return null;
}

if (!parent.Exists)
parent.Create();

Logger.Log($"Trying copy {path} to {desti}");

if (File.Exists(desti))
{
File.Delete(desti);
Logger.Log("File already exists! Replacing...");
}

File.Copy(path, desti);
}
catch (Exception e)
{
Logging.LogError(e, "Error occurred coping file to the destination!");
}

return desti;
}

private string getRealmedFileName(string hash)
{
string str = Path.Combine(hash[..1], hash[..2], hash);

Logger.Log("File is located at " + str);
return str;
}

private void buildTree()
{
var allBeatmaps = realm.All<BeatmapSetInfo>();

foreach (BeatmapSetInfo setInfo in allBeatmaps)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Logging;
using osu.Framework.Platform;
using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Rulesets.Mods;

namespace osu.Game.Rulesets.IGPlayer.Feature.Gosumemory.Tracker;

Expand All @@ -13,26 +21,141 @@ public BeatmapTracker(TrackerHub hub)
}

private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
private readonly IBindable<IReadOnlyList<Mod>> mods = new Bindable<IReadOnlyList<Mod>>();

[Resolved]
private IBindable<IReadOnlyList<Mod>> globalMods { get; set; } = null!;

[Resolved]
private BeatmapDifficultyCache beatmapDifficultyCache { get; set; } = null!;

private GosuRealmDirectAccessor? directAccessor;

[BackgroundDependencyLoader]
private void load(Bindable<WorkingBeatmap> globalBeatmap)
{
this.beatmap.BindTo(globalBeatmap);
this.mods.BindTo(globalMods);

directAccessor = new GosuRealmDirectAccessor(realmAccess);
AddInternal(directAccessor);
}

private string staticRoot()
{
return storage.GetFullPath("static", true);
}

protected override void LoadComplete()
{
Logger.Log("DDDLOADCOMPLETE");
base.LoadComplete();

this.beatmap.BindValueChanged(e =>
{
this.onBeatmapChanged(e.NewValue);
}, true);

this.mods.BindValueChanged(e =>
{
this.onModsChanged(e.NewValue);
}, true);
}

private void onModsChanged(IReadOnlyList<Mod> mods)
{
var currentWorking = beatmap.Value;
var difficulty = new BeatmapDifficulty(currentWorking.BeatmapInfo.Difficulty);
double timeRate = 1;

foreach (var mod in mods)
{
switch (mod)
{
case IApplicableToDifficulty applicableToDifficulty:
applicableToDifficulty.ApplyToDifficulty(difficulty);
break;

case IApplicableToRate applicableToRate:
timeRate = applicableToRate.ApplyToRate(0, timeRate);
break;
}
}

Ruleset ruleset = currentWorking.BeatmapInfo.Ruleset.CreateInstance();

var adjusted = ruleset.GetRateAdjustedDisplayDifficulty(difficulty, timeRate);

var dataRoot = Hub.GetDataRoot();

dataRoot.MenuValues.GosuBeatmapInfo.Stats.AR = adjusted.ApproachRate;
dataRoot.MenuValues.GosuBeatmapInfo.Stats.CS = adjusted.CircleSize;
dataRoot.MenuValues.GosuBeatmapInfo.Stats.HP = adjusted.DrainRate;
dataRoot.MenuValues.GosuBeatmapInfo.Stats.OD = adjusted.OverallDifficulty;
}

private IBindable<StarDifficulty?>? starDifficulty;

private CancellationTokenSource cancellationTokenSource;

private void onBeatmapChanged(WorkingBeatmap newBeatmap)
{
Hub.GetDataRoot().UpdateBeatmap(newBeatmap);

Logger.Log($"~BACKGROUND IS {newBeatmap.Metadata.BackgroundFile}");
updateFileSupporters(newBeatmap.BeatmapSetInfo, newBeatmap);

this.onModsChanged(this.mods.Value);

// Beatmap star difficulty
cancellationTokenSource?.Cancel();
cancellationTokenSource = new CancellationTokenSource();

this.starDifficulty?.UnbindAll();
this.starDifficulty = null;
this.starDifficulty = beatmapDifficultyCache.GetBindableDifficulty(newBeatmap.BeatmapInfo, cancellationTokenSource.Token);
this.starDifficulty.BindValueChanged(e =>
{
double newVal = e.NewValue?.Stars ?? -1d;
Hub.GetDataRoot().MenuValues.GosuBeatmapInfo.Stats.SR = (float)newVal;
}, true);
}

[Resolved]
private RealmAccess realmAccess { get; set; } = null!;

[Resolved]
private Storage storage { get; set; } = null!;

// From LegacyExporter in OsuGame
private void updateFileSupporters(BeatmapSetInfo setInfo, WorkingBeatmap beatmap)
{
if (directAccessor == null)
return;

string root = staticRoot();

if (directAccessor == null) return;

string? final = directAccessor.ExportFileSingle(setInfo, beatmap.Metadata.BackgroundFile, $"{root}/cover_{beatmap.GetHashCode()}");

if (final == null) return;

Logger.Log("~~~PUSH TO GOSU!");
var dataRoot = Hub.GetDataRoot();

string boardcast = final.Replace(root, "").Replace("/", "");
Logger.Log("~~~BOARDCAST IS " + boardcast);
dataRoot.MenuValues.GosuBeatmapInfo.Path.BackgroundPath = boardcast;
dataRoot.MenuValues.GosuBeatmapInfo.Path.BgPath = boardcast;

try
{
var server = Hub.GetWsLoader()?.Server;
server?.AddStaticContent(staticRoot(), "/Songs");
}
catch (Exception e)
{
Logging.LogError(e, "Unable to add cache");
}
}
}
5 changes: 5 additions & 0 deletions osu.Game.Rulesets.IGPlayer/Feature/Gosumemory/TrackerHub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ public DataRoot GetDataRoot()
return wsLoader.DataRoot;
}

public WebSocketLoader? GetWsLoader()
{
return wsLoader;
}

private readonly List<AbstractTracker> trackers = new List<AbstractTracker>();

[BackgroundDependencyLoader]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,21 @@ private void load()

public void Restart()
{
if (server != null)
if (Server != null)
{
server.Stop();
server.Dispose();
server = null;
}

if (httpServer != null)
{
httpServer.Stop();
httpServer.Dispose();
httpServer = null;
Server.Stop();
Server.Dispose();
Server = null;
}

startServer();
}

public void Boardcast(string text)
{
if (server == null) throw new NullDependencyException("Server not initialized");
if (Server == null) throw new NullDependencyException("Server not initialized");

server.MulticastText(text);
Server.MulticastText(text);
}

private void startServer()
Expand All @@ -61,12 +54,12 @@ private void startServer()
var ip = IPAddress.Loopback;
int port = 24050;

this.server = new GosuServer(ip, port);
this.Server = new GosuServer(ip, port);

server.Start();
Server.Start();

Logger.Log("Done!");
Logger.Log($"WS Server opened at http://{server.Address}:{server.Port}");
Logger.Log($"WS Server opened at http://{Server.Address}:{Server.Port}");
}
catch (Exception e)
{
Expand All @@ -77,16 +70,14 @@ private void startServer()

protected override void Dispose(bool isDisposing)
{
server?.Dispose();
httpServer?.Dispose();
Server?.Dispose();

base.Dispose(isDisposing);
}

private GosuServer? server;
private HttpServer? httpServer;
public GosuServer? Server;

private partial class GosuServer : WsServer
public partial class GosuServer : WsServer
{
public GosuServer(IPAddress address, int port)
: base(address, port)
Expand Down

0 comments on commit fca33aa

Please sign in to comment.