Merge branch 'master' into master

This commit is contained in:
Assistant 2020-05-18 18:36:40 -06:00 committed by GitHub
commit a556b56b75
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 1225 additions and 50 deletions

View file

@ -1,6 +1,8 @@
using System;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Windows;
using static ModAssistant.Http;
@ -13,49 +15,124 @@ namespace ModAssistant.API
private static readonly string CustomSongsFolder = Path.Combine("Beat Saber_Data", "CustomLevels");
private const bool BypassDownloadCounter = false;
public static async Task GetFromKey(string Key)
public static async Task<BeatSaverMap> GetFromKey(string Key, bool showNotification = true)
{
BeatSaverApiResponse Map = await GetResponse(BeatSaverURLPrefix + "/api/maps/detail/" + Key);
await InstallMap(Map);
return await GetMap(Key, "key", showNotification);
}
public static async Task GetFromHash(string Hash)
public static async Task<BeatSaverMap> GetFromHash(string Hash, bool showNotification = true)
{
BeatSaverApiResponse Map = await GetResponse(BeatSaverURLPrefix + "/api/maps/by-hash/" + Hash);
await InstallMap(Map);
return await GetMap(Hash, "hash", showNotification);
}
private static async Task<BeatSaverApiResponse> GetResponse(string url)
private static async Task<BeatSaverMap> GetMap(string id, string type, bool showNotification)
{
string urlSegment;
switch (type)
{
case "hash":
urlSegment = "/api/maps/by-hash/";
break;
case "key":
urlSegment = "/api/maps/detail/";
break;
default:
return null;
}
BeatSaverMap map = new BeatSaverMap();
map.Success = false;
try
{
var resp = await HttpClient.GetAsync(url);
var body = await resp.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<BeatSaverApiResponse>(body);
BeatSaverApiResponse beatsaver = await GetResponse(BeatSaverURLPrefix + urlSegment + id);
map.Name = await InstallMap(beatsaver.map, showNotification);
map.Success = true;
}
catch (Exception e)
{
MessageBox.Show($"{Application.Current.FindResource("OneClick:MapDownloadFailed")}\n\n" + e);
ModAssistant.Utils.Log($"Failed downloading BeatSaver map: {id} | Error: {e}", "ERROR");
}
return map;
}
private static async Task<BeatSaverApiResponse> GetResponse(string url, bool showNotification = true)
{
BeatSaverApiResponse response = new BeatSaverApiResponse();
try
{
var resp = await HttpClient.GetAsync(url);
response.statusCode = resp.StatusCode;
response.ratelimit = GetRatelimit(resp.Headers);
if (response.statusCode == HttpStatusCode.OK)
{
if (response.ratelimit.IsSafe)
{
string body = await resp.Content.ReadAsStringAsync();
response.map = JsonSerializer.Deserialize<BeatSaverApiResponseMap>(body);
return response;
}
else
{
return response;
}
}
else
{
return response;
}
}
catch (Exception e)
{
if (showNotification)
{
MessageBox.Show($"{Application.Current.FindResource("OneClick:MapDownloadFailed")}\n\n" + e);
}
return null;
}
}
public static async Task InstallMap(BeatSaverApiResponse Map)
private static BeatSaverRatelimit GetRatelimit(HttpResponseHeaders headers)
{
BeatSaverRatelimit ratelimit = new BeatSaverRatelimit();
var _rateLimitRemaining = headers.GetValues("Rate-Limit-Remaining").GetEnumerator();
var _rateLimitReset = headers.GetValues("Rate-Limit-Reset").GetEnumerator();
var _rateLimitTotal = headers.GetValues("Rate-Limit-Total").GetEnumerator();
_rateLimitRemaining.MoveNext();
_rateLimitReset.MoveNext();
_rateLimitTotal.MoveNext();
ratelimit.Remaining = Int32.Parse(_rateLimitRemaining.Current);
ratelimit.Reset = Int32.Parse(_rateLimitReset.Current);
ratelimit.Total = Int32.Parse(_rateLimitTotal.Current);
ratelimit.ResetTime = UnixTimestampToDateTime((long)ratelimit.Reset);
return ratelimit;
}
public static DateTime UnixTimestampToDateTime(double unixTime)
{
DateTime unixStart = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
long unixTimeStampInTicks = (long)(unixTime * TimeSpan.TicksPerSecond);
return new DateTime(unixStart.Ticks + unixTimeStampInTicks, System.DateTimeKind.Utc);
}
public static async Task<string> InstallMap(BeatSaverApiResponseMap Map, bool showNotification = true)
{
string zip = Path.Combine(Utils.BeatSaberPath, CustomSongsFolder, Map.hash) + ".zip";
string mapName = string.Concat(($"{Map.key} ({Map.metadata.songName} - {Map.metadata.levelAuthorName})")
.Split(ModAssistant.Utils.Constants.IllegalCharacters));
string directory = Path.Combine(Utils.BeatSaberPath, CustomSongsFolder, mapName);
#pragma warning disable CS0162 // Unreachable code detected
if (BypassDownloadCounter)
{
await Utils.DownloadAsset(BeatSaverURLPrefix + Map.directDownload, CustomSongsFolder, Map.hash + ".zip", mapName);
await Utils.DownloadAsset(BeatSaverURLPrefix + Map.directDownload, CustomSongsFolder, Map.hash + ".zip", mapName, showNotification);
}
else
{
await Utils.DownloadAsset(BeatSaverURLPrefix + Map.downloadURL, CustomSongsFolder, Map.hash + ".zip", mapName);
await Utils.DownloadAsset(BeatSaverURLPrefix + Map.downloadURL, CustomSongsFolder, Map.hash + ".zip", mapName, showNotification);
}
#pragma warning restore CS0162 // Unreachable code detected
if (File.Exists(zip))
{
@ -81,14 +158,54 @@ namespace ModAssistant.API
}
else
{
string line1 = (string)Application.Current.FindResource("OneClick:SongDownload:Failed");
string line2 = (string)Application.Current.FindResource("OneClick:SongDownload:NetworkIssues");
string title = (string)Application.Current.FindResource("OneClick:SongDownload:FailedTitle");
MessageBox.Show($"{line1}\n{line2}", title);
if (showNotification)
{
string line1 = (string)Application.Current.FindResource("OneClick:SongDownload:Failed");
string line2 = (string)Application.Current.FindResource("OneClick:SongDownload:NetworkIssues");
string title = (string)Application.Current.FindResource("OneClick:SongDownload:FailedTitle");
MessageBox.Show($"{line1}\n{line2}", title);
}
return null;
}
return mapName;
}
public class BeatSaverMap
{
public BeatSaverApiResponse response { get; set; }
public bool Success { get; set; }
public string Name { get; set; }
}
public class BeatSaverApiResponse
{
public HttpStatusCode statusCode { get; set; }
public BeatSaverRatelimit ratelimit { get; set;}
public BeatSaverApiResponseMap map { get; set; }
}
public class BeatSaverRatelimit
{
public int Remaining { get; set; }
public int Total { get; set; }
public int Reset { get; set; }
public DateTime ResetTime { get; set; }
public bool IsSafe
{
get
{
if (Remaining > 3) return true;
else return false;
}
}
public async Task Wait()
{
await Task.Delay(new TimeSpan(ResetTime.Ticks - DateTime.Now.Ticks));
}
}
public class BeatSaverApiResponseMap
{
public Metadata metadata { get; set; }
public Stats stats { get; set; }

View file

@ -0,0 +1,126 @@
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using static ModAssistant.Http;
using System.Windows;
namespace ModAssistant.API
{
public class Playlists
{
private const string BSaberURLPrefix = "https://bsaber.com/PlaylistAPI/";
private const string PlaylistsFolder = "Playlists";
private static readonly string BeatSaberPath = Utils.BeatSaberPath;
public static async Task DownloadAll(Uri uri)
{
switch (uri.Host)
{
case "playlist":
Uri url = new Uri($"{uri.LocalPath.Trim('/')}");
string filename = await Get(url);
await DownloadFrom(filename);
break;
}
}
public static async Task<string> Get(Uri url)
{
string filename = url.Segments.Last();
string absolutePath = Path.Combine(BeatSaberPath, PlaylistsFolder, filename);
try
{
await Utils.DownloadAsset(url.ToString(), PlaylistsFolder, filename);
return absolutePath;
}
catch
{
return null;
}
}
public static async Task DownloadFrom(string file, bool gui = false, System.Windows.Controls.ProgressBar progress = null)
{
if (Path.Combine(BeatSaberPath, PlaylistsFolder) != Path.GetDirectoryName(file))
{
string destination = Path.Combine(BeatSaberPath, PlaylistsFolder, Path.GetFileName(file));
File.Copy(file, destination, true);
}
int Errors = 0;
int Minimum = 0;
int Value = 0;
if (progress != null)
{
progress.Minimum = 0;
progress.Maximum = 1;
progress.Value = 0;
}
Playlist playlist = JsonSerializer.Deserialize<Playlist>(File.ReadAllText(file));
int Maximum = playlist.songs.Length;
if (progress != null) progress.Maximum = playlist.songs.Length;
foreach (Playlist.Song song in playlist.songs)
{
API.BeatSaver.BeatSaverMap response = new BeatSaver.BeatSaverMap();
if (!string.IsNullOrEmpty(song.hash))
{
response = await BeatSaver.GetFromHash(song.hash, false);
}
else if (!string.IsNullOrEmpty(song.key))
{
response = await BeatSaver.GetFromKey(song.key, false);
}
Value++;
if (progress != null) progress.Value++;
if (gui)
{
if (response.Success)
{
MainWindow.Instance.MainText = $"{string.Format((string)Application.Current.FindResource("Options:InstallingPlaylist"), TextProgress(Minimum, Maximum, Value))}";
}
else
{
MainWindow.Instance.MainText = $"{string.Format((string)Application.Current.FindResource("Options:FailedPlaylistSong"), song.songName)}";
ModAssistant.Utils.Log($"Failed installing BeatSaver map: {song.songName} | {song.key} | {song.hash}");
await Task.Delay(3 * 1000);
Errors++;
}
}
}
if (gui)
{
MainWindow.Instance.MainText = $"{string.Format((string)Application.Current.FindResource("Options:FinishedPlaylist"), Errors, playlist.playlistTitle)}";
}
}
private static string TextProgress(int min, int max, int value)
{
if (max == value)
{
return $" {string.Concat(Enumerable.Repeat("", 10))} [{value}/{max}]";
}
int interval = (int)Math.Floor((double)value / ( ((double)max - (double)min ) / (double)10));
return $" {string.Concat(Enumerable.Repeat("", interval))}{string.Concat(Enumerable.Repeat("", 10 - interval))} [{value}/{max}]";
}
class Playlist
{
public string playlistTitle { get; set; }
public string playlistAuthor { get; set; }
public string image { get; set; }
public Song[] songs { get; set; }
public class Song
{
public string key { get; set; }
public string hash { get; set; }
public string songName { get; set; }
public string uploader { get; set; }
}
}
}
}

View file

@ -11,12 +11,18 @@ namespace ModAssistant.API
{
public static readonly string BeatSaberPath = App.BeatSaberInstallDirectory;
public static async Task DownloadAsset(string link, string folder, bool showNotifcation, string fileName = null)
{
await DownloadAsset(link, folder, fileName, null, showNotifcation);
}
public static async Task DownloadAsset(string link, string folder, string fileName = null, string displayName = null)
{
if (string.IsNullOrEmpty(displayName))
{
displayName = Path.GetFileNameWithoutExtension(fileName);
}
await DownloadAsset(link, folder, fileName, displayName, true);
}
public static async Task DownloadAsset(string link, string folder, string fileName, string displayName, bool showNotification)
{
if (string.IsNullOrEmpty(BeatSaberPath))
{
ModAssistant.Utils.SendNotify((string)Application.Current.FindResource("OneClick:InstallDirNotFound"));
@ -32,9 +38,16 @@ namespace ModAssistant.API
{
fileName = WebUtility.UrlDecode(Path.Combine(BeatSaberPath, folder, fileName));
}
if (string.IsNullOrEmpty(displayName))
{
displayName = Path.GetFileNameWithoutExtension(fileName);
}
await ModAssistant.Utils.Download(link, fileName);
ModAssistant.Utils.SendNotify(string.Format((string)Application.Current.FindResource("OneClick:InstalledAsset"), displayName));
if (showNotification)
{
ModAssistant.Utils.SendNotify(string.Format((string)Application.Current.FindResource("OneClick:InstalledAsset"), displayName));
}
}
catch
{

View file

@ -8,7 +8,7 @@ namespace ModAssistant
{
class OneClickInstaller
{
private static readonly string[] Protocols = new[] { "modelsaber", "beatsaver" };
private static readonly string[] Protocols = new[] { "modelsaber", "beatsaver", "bsplaylist" };
public static async Task InstallAsset(string link)
{
@ -23,6 +23,9 @@ namespace ModAssistant
case "beatsaver":
await BeatSaver(uri);
break;
case "bsplaylist":
await Playlist(uri);
break;
}
}
@ -37,6 +40,11 @@ namespace ModAssistant
await API.ModelSaber.GetModel(uri);
}
private static async Task Playlist(Uri uri)
{
await API.Playlists.DownloadAll(uri);
}
public static void Register(string Protocol, bool Background = false)
{
if (IsRegistered(Protocol) == true)

View file

@ -1,6 +1,7 @@
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
@ -309,7 +310,7 @@ namespace ModAssistant
public static string GetManualDir()
{
var dialog = new Microsoft.Win32.SaveFileDialog()
var dialog = new SaveFileDialog()
{
Title = (string)Application.Current.FindResource("Utils:InstallDir:DialogTitle"),
Filter = "Directory|*.this.directory",
@ -339,6 +340,22 @@ namespace ModAssistant
return null;
}
public static string GetManualFile(string filter = "", string title = "Open File")
{
var dialog = new OpenFileDialog()
{
Title = title,
Filter = filter,
Multiselect = false,
};
if (dialog.ShowDialog() == true)
{
return dialog.FileName;
}
return null;
}
public static bool IsVoid()
{
string directory = App.BeatSaberInstallDirectory;
@ -387,6 +404,13 @@ namespace ModAssistant
MessageBox.Show($"{string.Format((string)Application.Current.FindResource("Utils:CannotOpenFolder"), location)}.");
}
public static void Log(string message, string severity = "LOG")
{
string path = Path.GetDirectoryName(ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).FilePath);
string logFile = $"{path}{Path.DirectorySeparatorChar}log.log";
File.AppendAllText(logFile, $"[{DateTime.UtcNow.ToString("yyyy-mm-dd HH:mm:ss.ffffff")}][{severity.ToUpper()}] {message}\n");
}
public static async Task Download(string link, string output)
{
var resp = await HttpClient.GetAsync(link);

View file

@ -0,0 +1,238 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ModAssistant"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<sys:String x:Key="ResourceDictionaryName">i18n:en-US</sys:String>
<!-- App -->
<sys:String x:Key="App:InstallDirDialog:Title">Der Beat Saber Installationsordner konnte nicht gefunden werden!</sys:String>
<sys:String x:Key="App:InstallDirDialog:OkCancel">Drücke OK um es erneut zu versuchen, oder Abbrechen um das Programm zu beenden.</sys:String>
<sys:String x:Key="App:InvalidArgument">Ungültiges Argument! '{0}' benötigt eine Option.</sys:String>
<sys:String x:Key="App:UnrecognizedArgument">Unbekanntes Argument. Beende Mod Assistant.</sys:String>
<sys:String x:Key="App:UnhandledException">Eine nicht behandelte Ausnahme ist aufgetreten</sys:String>
<sys:String x:Key="App:Exception">Ausnahme</sys:String>
<!-- Main Window -->
<sys:String x:Key="MainWindow:WindowTitle">ModAssistant</sys:String>
<sys:String x:Key="MainWindow:IntroButton">Intro</sys:String>
<sys:String x:Key="MainWindow:ModsButton">Mods</sys:String>
<sys:String x:Key="MainWindow:AboutButton">Über</sys:String>
<sys:String x:Key="MainWindow:OptionsButton">Optionen</sys:String>
<sys:String x:Key="MainWindow:GameVersionLabel">Spiel Version</sys:String>
<sys:String x:Key="MainWindow:VersionLabel">Version</sys:String>
<sys:String x:Key="MainWindow:ModInfoButton">Mod Info</sys:String>
<sys:String x:Key="MainWindow:InstallButtonTop">Installieren/</sys:String>
<sys:String x:Key="MainWindow:InstallButtonBottom">Aktualisieren</sys:String>
<sys:String x:Key="MainWindow:GameVersionLoadFailed">Spielversion konnte nicht geladen werden, der Mods Tab wird nicht verfügbar sein.</sys:String>
<sys:String x:Key="MainWindow:GameUpdateDialog:Title">Neue Spielversion gefunden!</sys:String>
<sys:String x:Key="MainWindow:GameUpdateDialog:Line1">Es scheint ein Spiel Update gegeben zu haben.</sys:String>
<sys:String x:Key="MainWindow:GameUpdateDialog:Line2">Bitte prüfe ob unten links die richtige Version ausgewählt ist!</sys:String>
<sys:String x:Key="MainWindow:NoModSelected">Kein Mod ausgewählt!</sys:String>
<sys:String x:Key="MainWindow:NoModInfoPage">{0} hat keine Informationsseite.</sys:String>
<!-- Intro Page -->
<sys:String x:Key="Intro:Title">Intro</sys:String>
<sys:String x:Key="Intro:PageTitle">Willkommen bei Mod Assistant</sys:String>
<sys:String x:Key="Intro:Terms:Header">Bitte lies diese Seite vollständig und aufmerksam!</sys:String>
<Span x:Key="Intro:Terms:Line1">
Durch Nutzung des Programms wird bestätigt, dass folgende Bedinungen gelesen und akzeptiert wurden:
</Span>
<Span x:Key="Intro:Terms:Line2">
Beat Saber
unterstützt normalerweise <Bold>keine</Bold> Mods. Das heißt:
</Span>
<Span x:Key="Intro:Terms:Term1">
Mods
werden nach jedem Update <Bold>nicht mehr funktionieren</Bold>. Dies ist normal, und
die Schuld liegt <Bold>nicht</Bold> bei Beat Games.
</Span>
<Span x:Key="Intro:Terms:Term2">
Mods
<Bold>werden</Bold> Fehler und Leistungsprobleme verursachen. Die Schuld
liegt <Bold>nicht</Bold> bei Beat Games.
</Span>
<Span x:Key="Intro:Terms:Term3">
Mods werden
<Bold>kostenlos</Bold> von Leuten in deren
<Bold>Freizeit</Bold> erstellt. Bitte sei geduldig und verständnissvoll.
</Span>
<Span x:Key="Intro:ReviewsBeatGamesFault">
Bitte gib <Bold>KEINE</Bold> schlechten Bewertungen weil die Mods nicht funktionieren. Die Schuld
liegt <Bold>nicht</Bold> bei Beat Games.
<LineBreak/> Sie versuchen nicht die Mods zu unterbinden.
</Span>
<Span x:Key="Intro:ReviewsRustySpoon">
Wenn ich weiterhin schlecht Bewertungen
<Italic>wegen</Italic> nicht funktionierenden Mods sehe,
<LineBreak/>
<Bold>Werde ich persönlich die Mods mit einem rostigen Löffel töten</Bold>
</Span>
<Span x:Key="Intro:WikiGuide">
Bitte lies den Einsteiger Leitfaden im
<Hyperlink local:HyperlinkExtensions.IsExternal="True" NavigateUri="https://bsmg.wiki/pc-modding.html">
Wiki
</Hyperlink>.
</Span>
<sys:String x:Key="Intro:AgreeButton">Annehmen</sys:String>
<sys:String x:Key="Intro:DisagreeButton">Ablehnen</sys:String>
<sys:String x:Key="Intro:ClosingApp">Programm wird beendet: Du hast den Bedingunen nicht zugestimmt.</sys:String>
<sys:String x:Key="Intro:VersionDownloadFailed">Versionsliste konnte nicht geladen werden</sys:String>
<sys:String x:Key="Intro:ModsTabDisabled">Mods Tab deaktiviert. Bitte Programm neu starten um es nochmal zu versuchen.</sys:String>
<sys:String x:Key="Intro:ModsTabEnabled">Du kannst jetzt den Mods Tab benutzen!</sys:String>
<!-- Mods Page -->
<sys:String x:Key="Mods:Title">Mods</sys:String>
<sys:String x:Key="Mods:Header:Name">Name</sys:String>
<sys:String x:Key="Mods:Header:Installed">Installiert</sys:String>
<sys:String x:Key="Mods:Header:Latest">Neuste</sys:String>
<sys:String x:Key="Mods:Header:Description">Beschreibung</sys:String>
<sys:String x:Key="Mods:Header:Uninstall">Entfernen</sys:String>
<sys:String x:Key="Mods:UninstallButton">Entfernen</sys:String>
<sys:String x:Key="Mods:LoadFailed">Modliste konnte nicht geladen werden</sys:String>
<sys:String x:Key="Mods:CheckingInstalledMods">Prüfe installierte Mods</sys:String>
<sys:String x:Key="Mods:LoadingMods">Lade Mods</sys:String>
<sys:String x:Key="Mods:FinishedLoadingMods">Laden der Mods abgeschlossen</sys:String>
<sys:String x:Key="Mods:InstallingMod">Installiere {0}</sys:String>
<sys:String x:Key="Mods:InstalledMod">{0} installiert</sys:String>
<sys:String x:Key="Mods:FinishedInstallingMods">Mod Installation abgeschlossen</sys:String>
<sys:String x:Key="Mods:ModDownloadLinkMissing">Downloadlink für {0} konnte nicht gefunden werden</sys:String>
<sys:String x:Key="Mods:UninstallBox:Title">{0} entfernen?</sys:String>
<sys:String x:Key="Mods:UninstallBox:Body1">Bist du dir sicher das du {0} entfernen möchtest?</sys:String>
<sys:String x:Key="Mods:UninstallBox:Body2">Dies kann die anderen Mods unbrauchbar machen</sys:String>
<sys:String x:Key="Mods:FailedExtract">Fehler beim Extrahieren von {0}, neuer Versuch in {1} Sekunden. ({2}/{3})</sys:String>
<sys:String x:Key="Mods:FailedExtractMaxReached">Fehler beim Extrahieren von {0} nach {1} Versuchen, wird übersprungen. Dieser Mod funktioniert möglicherweise nicht richtig, also gehe auf eigenes Risiko vor</sys:String>
<sys:String x:Key="Mods:SearchLabel">Search...</sys:String> <!-- NEEDS TRANSLATING -->
<!-- About Page -->
<sys:String x:Key="About:Title">Über</sys:String>
<sys:String x:Key="About:PageTitle">Über Mod Assistant</sys:String>
<sys:String x:Key="About:List:Header">Ich bin Assistant und ich habe Mod Assistant als Assistent für Mods mit ein paar Prinzipen im Auge gemacht:</sys:String>
<sys:String x:Key="About:List:Item1">Einfachheit</sys:String>
<sys:String x:Key="About:List:Item2">Portabilität</sys:String>
<sys:String x:Key="About:List:Item3">Nur eine Datei</sys:String>
<sys:String x:Key="About:List:Item4">Verantwortungsbewusster Umgang</sys:String>
<Span x:Key="About:SupportAssistant">
Wenn dir das Programm gefällt und du mich unterstützen möchtest, dann besuche meine
<Hyperlink local:HyperlinkExtensions.IsExternal="True" NavigateUri="https://bs.assistant.moe/Donate/">
Spendenseite
</Hyperlink>
oder mein
<Hyperlink local:HyperlinkExtensions.IsExternal="True" NavigateUri="https://www.patreon.com/AssistantMoe">
Patreon
</Hyperlink>
</Span>
<sys:String x:Key="About:SpecialThanks">Besonder Dank ♥</sys:String>
<sys:String x:Key="About:Donate">Spenden</sys:String>
<sys:String x:Key="About:HeadpatsButton">Kopftätscheln</sys:String>
<sys:String x:Key="About:HugsButton">Umarmungen</sys:String>
<!-- Options Page -->
<sys:String x:Key="Options:Title">Optionen</sys:String>
<sys:String x:Key="Options:PageTitle">Einstellungen</sys:String>
<sys:String x:Key="Options:InstallFolder">Installations Ordner</sys:String>
<sys:String x:Key="Options:SelectFolderButton">Ordner wählen</sys:String>
<sys:String x:Key="Options:OpenFolderButton">Order öffnen</sys:String>
<sys:String x:Key="Options:SaveSelectedMods">Ausgewählte Mods speichern</sys:String>
<sys:String x:Key="Options:CheckInstalledMods">Installierte Mods prüfen</sys:String>
<sys:String x:Key="Options:SelectInstalledMods">Installierte Mods auswählen</sys:String>
<sys:String x:Key="Options:ReinstallInstalledMods">Installierte Mods neu installieren</sys:String>
<sys:String x:Key="Options:EnableOneClickInstalls">OneClick™ Installation aktivieren</sys:String>
<sys:String x:Key="Options:BeatSaver">BeatSaver</sys:String>
<sys:String x:Key="Options:ModelSaber">ModelSaber</sys:String>
<sys:String x:Key="Options:GameType">Spiel Typ</sys:String>
<sys:String x:Key="Options:GameType:Steam">Steam</sys:String>
<sys:String x:Key="Options:GameType:Oculus">Oculus</sys:String>
<sys:String x:Key="Options:Tools">Tools</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:InstallPlaylist">Install Playlist</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:InstallingPlaylist">Installing Playlist: {0}</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:FailedPlaylistSong">Failed song: {0}</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:FinishedPlaylist">[{0} fails] Finished Installing Playlist: {1}</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:Diagnostics">Diagnose</sys:String>
<sys:String x:Key="Options:OpenLogsButton">Log öffnen</sys:String>
<sys:String x:Key="Options:OpenAppDataButton">AppData öffnen</sys:String>
<sys:String x:Key="Options:UninstallBSIPAButton">BSIPA entfernen</sys:String>
<sys:String x:Key="Options:RemoveAllModsButton">Mods entfernen</sys:String>
<sys:String x:Key="Options:ApplicationTheme">Design</sys:String>
<sys:String x:Key="Options:ExportTemplateButton">Exportieren</sys:String>
<sys:String x:Key="Options:UploadingLog">Log wird hochgeladen</sys:String>
<sys:String x:Key="Options:LogUrlCopied">Log URL in die Zwischenablage kopiert!</sys:String>
<sys:String x:Key="Options:LogUploadFailed">Log Hochladen fehlgeschlagen!</sys:String>
<sys:String x:Key="Options:LogUploadFailed:Title">Log Hochladen fehlgeschlagen!</sys:String>
<sys:String x:Key="Options:LogUploadFailed:Body">Log Datei konnte nicht zu Teknik hochgeladen werden, bitte nochmal versuchen oder die Datei manuell senden.</sys:String>
<sys:String x:Key="Options:GettingModList">Lade Liste der Mods</sys:String>
<sys:String x:Key="Options:FindingBSIPAVersion">Suche BSIPA Version</sys:String>
<sys:String x:Key="Options:BSIPAUninstalled">BSIPA entfernt</sys:String>
<sys:String x:Key="Options:YeetModsBox:Title">Alle Mods entfernen?</sys:String>
<sys:String x:Key="Options:YeetModsBox:RemoveAllMods">Bist du dir sicher das du ALLE Mods entfernen möchtest?</sys:String>
<sys:String x:Key="Options:YeetModsBox:CannotBeUndone">Dies kann nicht rückgängig gemacht werden.</sys:String>
<sys:String x:Key="Options:AllModsUninstalled">Alle Mods entfernt</sys:String>
<sys:String x:Key="Options:CurrentThemeRemoved">Aktuelles Design wurde entfernt, gehe zurück zum Standart...</sys:String>
<sys:String x:Key="Options:ThemeFolderNotFound">Designs Ordner nicht gefunden! Versuche die Vorlage zu exportieren...</sys:String>
<sys:String x:Key="Options:AppDataNotFound">AppData Ordner nicht gefunden! Versuche dein Spiel zu starten.</sys:String>
<!-- Loading Page -->
<sys:String x:Key="Loading:Loading">Lade Mods</sys:String>
<!-- Invalid Page -->
<sys:String x:Key="Invalid:Title">Ungültig</sys:String>
<sys:String x:Key="Invalid:PageTitle">Ungültige Installation erkannt</sys:String>
<sys:String x:Key="Invalid:PageSubtitle">Die SPielinstallation ist beschädigt oder anderwärtig ungültig</sys:String>
<sys:String x:Key="Invalid:List:Header">Dies kann passieren wenn dein Spiel eine Raubkopie ist oder eine Raubkopie über eine legitime Version kopiert wurde</sys:String>
<Span x:Key="Invalid:List:Line1">
Falls dein Spiel eine Raubkopie ist,
<Bold>bitte kaufe das Spiel
<Hyperlink NavigateUri="https://beatgames.com/" local:HyperlinkExtensions.IsExternal="True">
HIER
</Hyperlink>
</Bold>.
</Span>
<Span x:Key="Invalid:List:Line2">
Wenn dein Spiel
<Bold>keine</Bold> Raubkopie ist, bitte
<Hyperlink NavigateUri="https://bsmg.wiki/support#clean-installation" local:HyperlinkExtensions.IsExternal="True">
mach eine saubere Neuinstallation
</Hyperlink>.
</Span>
<Span x:Key="Invalid:List:Line3">
Falls das nicht hilft, frage im
<Span Foreground="Blue">#support</Span> Kanal in der
<Hyperlink NavigateUri="https://discord.gg/beatsabermods" local:HyperlinkExtensions.IsExternal="True">
BSMG
</Hyperlink>.
</Span>
<sys:String x:Key="Invalid:BoughtGame1">Falls du eine Raubkopie hattest aber das Spiel jetzt gekauft hast</sys:String>
<sys:String x:Key="Invalid:SelectFolderButton">Select Folder</sys:String>
<sys:String x:Key="Invalid:BoughtGame2">Muss Mod Assisstant neu gestartet werden wenn eine legitime Version installiert wurde</sys:String>
<!-- OneClick Class -->
<sys:String x:Key="OneClick:MapDownloadFailed">Map Details konnten nicht geladen werden.</sys:String>
<sys:String x:Key="OneClick:SongDownloadFailed">Titel konnte nicht geladen werden.</sys:String>
<sys:String x:Key="OneClick:SongDownload:Failed">Titel konnte nicht geladen werden.</sys:String>
<sys:String x:Key="OneClick:SongDownload:NetworkIssues">Möglicherweise gibt es Probleme mit BeatSaver oder deiner Internetverbindung.</sys:String>
<sys:String x:Key="OneClick:SongDownload:FailedTitle">Herunterladen der Titel ZIP fehlgeschlagen</sys:String>
<sys:String x:Key="OneClick:InstallDirNotFound">Beat Saber Installations Pfad nicht gefunden.</sys:String>
<sys:String x:Key="OneClick:InstalledAsset">Installiert: {0}</sys:String>
<sys:String x:Key="OneClick:AssetInstallFailed">Installation fehlgeschlagen.</sys:String>
<sys:String x:Key="OneClick:ProtocolHandler:Registered">{0} OneClick™ Installion Handler registriert!</sys:String>
<sys:String x:Key="OneClick:ProtocolHandler:Unregistered">{0} OneClick™ Installion Handler entfernt!</sys:String>
<!-- Themes Class -->
<sys:String x:Key="Themes:ThemeNotFound">Design nicht gefunden, gehe zurück zum Standart Design...</sys:String>
<sys:String x:Key="Themes:ThemeSet">Design gesetzt auf: {0}.</sys:String>
<sys:String x:Key="Themes:ThemeMissing">{0} existiert nicht.</sys:String>
<sys:String x:Key="Themes:SavedTemplateTheme">Designvorlage &quot;{0}&quot; in Design Ordner gespeichert.</sys:String>
<sys:String x:Key="Themes:TemplateThemeExists">Designvorlage existiert bereits!</sys:String>
<sys:String x:Key="Themes:FailedToLoadXaml">Fehler beim Laden der .xaml Datei von Design {0}: {1}</sys:String>
<!-- Updater Class -->
<sys:String x:Key="Updater:CheckFailed">Konnte nicht auf Aktualisierungen prüfen.</sys:String>
<sys:String x:Key="Updater:DownloadFailed">Konnte Aktualisierung nicht herunterladen.</sys:String>
<!-- Utils Class -->
<sys:String x:Key="Utils:NotificationTitle">Mod Assistant</sys:String>
<sys:String x:Key="Utils:NoInstallFolder">Beat Saber Installationsordner konnte nicht erkannt werden. Bitte manuell auswählen.</sys:String>
<sys:String x:Key="Utils:RunAsAdmin">Mod Assistant muss diese Aufgabe mit Administrator Rechten ausführen. Bitte nochmal versuchen.</sys:String>
<sys:String x:Key="Utils:InstallDir:DialogTitle">Wähle den Beat Saber Installationsordner aus</sys:String>
<sys:String x:Key="Utils:CannotOpenFolder">Ordner konnte nicht geöffnet werden: {0}</sys:String>
</ResourceDictionary>

View file

@ -71,6 +71,7 @@
<sys:String x:Key="Mods:UninstallBox:Body2">Mods:UninstallBox:Body2</sys:String>
<sys:String x:Key="Mods:FailedExtract">{0} {1} {2} {3} Mods:FailedExtract</sys:String>
<sys:String x:Key="Mods:FailedExtractMaxReached">{0} {1} Mods:FailedExtractMaxReached</sys:String>
<sys:String x:Key="Mods:SearchLabel">Mods:SearchLabel</sys:String>
<!-- About Page -->
<sys:String x:Key="About:Title">About:Title</sys:String>
@ -102,6 +103,11 @@
<sys:String x:Key="Options:GameType">Options:GameType</sys:String>
<sys:String x:Key="Options:GameType:Steam">Options:GameType:Steam</sys:String>
<sys:String x:Key="Options:GameType:Oculus">Options:GameType:Oculus</sys:String>
<sys:String x:Key="Options:Tools">Options:Tools</sys:String>
<sys:String x:Key="Options:InstallPlaylist">Options:InstallPlaylist</sys:String>
<sys:String x:Key="Options:InstallingPlaylist">{0} Options:InstallingPlaylist</sys:String>
<sys:String x:Key="Options:FailedPlaylistSong">{0} Options:FailedPlaylistSong</sys:String>
<sys:String x:Key="Options:FinishedPlaylist">{0} {1} Options:FinishedPlaylist</sys:String>
<sys:String x:Key="Options:Diagnostics">Options:Diagnostics</sys:String>
<sys:String x:Key="Options:OpenLogsButton">Options:OpenLogsButton</sys:String>
<sys:String x:Key="Options:OpenAppDataButton">Options:OpenAppDataButton</sys:String>

View file

@ -102,6 +102,7 @@
<sys:String x:Key="Mods:UninstallBox:Body2">This could break your other mods</sys:String>
<sys:String x:Key="Mods:FailedExtract">Failed to extract {0}, trying again in {1} seconds. ({2}/{3})</sys:String>
<sys:String x:Key="Mods:FailedExtractMaxReached">Failed to extract {0} after max attempts ({1}), skipping. This mod might not work properly so proceed at your own risk</sys:String>
<sys:String x:Key="Mods:SearchLabel">Search...</sys:String>
<!-- About Page -->
<sys:String x:Key="About:Title">About</sys:String>
@ -142,6 +143,11 @@
<sys:String x:Key="Options:GameType">Game Type</sys:String>
<sys:String x:Key="Options:GameType:Steam">Steam</sys:String>
<sys:String x:Key="Options:GameType:Oculus">Oculus</sys:String>
<sys:String x:Key="Options:Tools">Tools</sys:String>
<sys:String x:Key="Options:InstallPlaylist">Install Playlist</sys:String>
<sys:String x:Key="Options:InstallingPlaylist">Installing Playlist: {0}</sys:String>
<sys:String x:Key="Options:FailedPlaylistSong">Failed song: {0}</sys:String>
<sys:String x:Key="Options:FinishedPlaylist">[{0} fails] Finished Installing Playlist: {1}</sys:String>
<sys:String x:Key="Options:Diagnostics">Diagnostics</sys:String>
<sys:String x:Key="Options:OpenLogsButton">Open Logs</sys:String>
<sys:String x:Key="Options:OpenAppDataButton">Open AppData</sys:String>

View file

@ -0,0 +1,245 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ModAssistant"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<sys:String x:Key="ResourceDictionaryName">i18n:fr-FR</sys:String>
<!-- App -->
<sys:String x:Key="App:InstallDirDialog:Title">Impossible de trouver le dossier d'installation de Beat Saber !</sys:String>
<sys:String x:Key="App:InstallDirDialog:OkCancel">Appuyez sur OK pour réessayer, ou Annuler pour fermer l'application.</sys:String>
<sys:String x:Key="App:InvalidArgument">Argument invalide ! '{0}' nécessite une option.</sys:String>
<sys:String x:Key="App:UnrecognizedArgument">Argument non reconnu. Fermeture de Mod Assistant.</sys:String>
<sys:String x:Key="App:UnhandledException">Une exception non gérée est survenue</sys:String>
<sys:String x:Key="App:Exception">Exception</sys:String>
<!-- Main Window -->
<sys:String x:Key="MainWindow:WindowTitle">ModAssistant</sys:String>
<sys:String x:Key="MainWindow:IntroButton">Intro</sys:String>
<sys:String x:Key="MainWindow:ModsButton">Mods</sys:String>
<sys:String x:Key="MainWindow:AboutButton">À propos</sys:String>
<sys:String x:Key="MainWindow:OptionsButton">Options</sys:String>
<sys:String x:Key="MainWindow:GameVersionLabel">Version du jeu</sys:String>
<sys:String x:Key="MainWindow:VersionLabel">Version</sys:String>
<sys:String x:Key="MainWindow:ModInfoButton">Info sur le mod</sys:String>
<sys:String x:Key="MainWindow:InstallButtonTop">Installer</sys:String>
<sys:String x:Key="MainWindow:InstallButtonBottom">ou Mettre à jour</sys:String>
<sys:String x:Key="MainWindow:GameVersionLoadFailed">Impossible de charger les versions du jeu, l'onglet Mods sera indisponible.</sys:String>
<sys:String x:Key="MainWindow:GameUpdateDialog:Title">Nouvelle version du jeu détectée !</sys:String>
<sys:String x:Key="MainWindow:GameUpdateDialog:Line1">Il semble que le jeu a été mis à jour.</sys:String>
<sys:String x:Key="MainWindow:GameUpdateDialog:Line2">Veuillez vous assurer que la bonne version soit sélectionnée en bas à gauche !</sys:String>
<sys:String x:Key="MainWindow:NoModSelected">Aucun mod sélectionné !</sys:String>
<sys:String x:Key="MainWindow:NoModInfoPage">{0} n'a pas de page informative.</sys:String>
<!-- Intro Page -->
<sys:String x:Key="Intro:Title">Intro</sys:String>
<sys:String x:Key="Intro:PageTitle">Bienvenue sur Mod Assistant</sys:String>
<sys:String x:Key="Intro:Terms:Header">Veuillez lire cette page entièrement et avec attention</sys:String>
<Span x:Key="Intro:Terms:Line1">
En utilisant ce programme, vous attestez que vous avez lu et accepté les modalités suivantes :
</Span>
<Span x:Key="Intro:Terms:Line2">
Beat Saber
<Bold>ne</Bold> supporte
<Bold>pas</Bold> nativement les mods. Cela signifie que :
</Span>
<Span x:Key="Intro:Terms:Term1">
Les mods
<Bold>dysfonctionneront</Bold> à chaque mise à jour. C'est normal, et ce
<Bold>n'</Bold>est
<Bold>pas</Bold> la faute de Beat Games.
</Span>
<Span x:Key="Intro:Terms:Term2">
Les mods
<Bold>causeront</Bold> des bugs et des problèmes de performance. Ce
<Bold>n'</Bold>est
<Bold>pas</Bold> la faute de Beat Games.
</Span>
<Span x:Key="Intro:Terms:Term3">
Les mods sont créés
<Bold>gratuitement</Bold> par des gens sur leur
<Bold>temps libre.</Bold> Veuillez être patient et compréhensif.
</Span>
<Span x:Key="Intro:ReviewsBeatGamesFault">
<Bold>NE</Bold> laissez
<Bold>PAS</Bold> de commentaires négatifs parce que les mods ne fonctionnent plus. Ce
<Bold>n'</Bold>est
<Bold>pas</Bold> la faute de Beat Games.
<LineBreak/> Ils n'essaient pas de faire disparaître les mods.
</Span>
<Span x:Key="Intro:ReviewsRustySpoon">
Si je continue de voir des gens laisser des commentaires négatifs
<Italic>parce que</Italic> les mods ne fonctionnent plus,
<LineBreak/>
<Bold>J'irai personnellement liquider les mods avec une cuillère rouillée</Bold>
</Span>
<Span x:Key="Intro:WikiGuide">
Veuillez lire le Guide du Débutant sur le
<Hyperlink local:HyperlinkExtensions.IsExternal="True" NavigateUri="https://bsmg.wiki/fr/pc-modding.html">
Wiki
</Hyperlink>.
</Span>
<sys:String x:Key="Intro:AgreeButton">J'accepte</sys:String>
<sys:String x:Key="Intro:DisagreeButton">Je refuse</sys:String>
<sys:String x:Key="Intro:ClosingApp">Fermeture de l'application : vous n'avez pas accepté les modalités et conditions.</sys:String>
<sys:String x:Key="Intro:VersionDownloadFailed">Impossible de télécharger la liste des versions</sys:String>
<sys:String x:Key="Intro:ModsTabDisabled">Onglet Mods désactivé. Veuillez relancer pour réessayer.</sys:String>
<sys:String x:Key="Intro:ModsTabEnabled">Vous pouvez désormais utiliser l'onglet Mods !</sys:String>
<!-- Mods Page -->
<sys:String x:Key="Mods:Title">Mods</sys:String>
<sys:String x:Key="Mods:Header:Name">Nom</sys:String>
<sys:String x:Key="Mods:Header:Installed">Installé</sys:String>
<sys:String x:Key="Mods:Header:Latest">Récent</sys:String>
<sys:String x:Key="Mods:Header:Description">Description</sys:String>
<sys:String x:Key="Mods:Header:Uninstall">Désinstaller</sys:String>
<sys:String x:Key="Mods:UninstallButton">Désinstaller</sys:String>
<sys:String x:Key="Mods:LoadFailed">Impossible de charger la liste des mods</sys:String>
<sys:String x:Key="Mods:CheckingInstalledMods">Vérification des mods installés</sys:String>
<sys:String x:Key="Mods:LoadingMods">Chargement des mods</sys:String>
<sys:String x:Key="Mods:FinishedLoadingMods">Fin : mods chargés</sys:String>
<sys:String x:Key="Mods:InstallingMod">Installation de {0}</sys:String>
<sys:String x:Key="Mods:InstalledMod">{0} installé</sys:String>
<sys:String x:Key="Mods:FinishedInstallingMods">Fin : mods installés</sys:String>
<sys:String x:Key="Mods:ModDownloadLinkMissing">Impossible de trouver le lien de téléchargement de {0}</sys:String>
<sys:String x:Key="Mods:UninstallBox:Title">Désinstaller {0} ?</sys:String>
<sys:String x:Key="Mods:UninstallBox:Body1">Êtes-vous sûr de vouloir supprimer {0} ?</sys:String>
<sys:String x:Key="Mods:UninstallBox:Body2">Cela pourrait faire dysfonctionner d'autres mods installés</sys:String>
<sys:String x:Key="Mods:FailedExtract">Échec de l'extraction de {0}, nouvelle tentative dans {1} secondes. ({2}/{3})</sys:String>
<sys:String x:Key="Mods:FailedExtractMaxReached">Échec de l'extraction de {0} après le maximum de tentatives ({1}), abandon. Ce mod pourrait ne pas fonctionner correctement, continuez à vos propres risques</sys:String>
<sys:String x:Key="Mods:SearchLabel">Recherche...</sys:String>
<!-- About Page -->
<sys:String x:Key="About:Title">À propos</sys:String>
<sys:String x:Key="About:PageTitle">À propos de Mod Assistant</sys:String>
<sys:String x:Key="About:List:Header">Je suis Assistant, et je réalise Mod Assistant pour l'assistance aux mods, avec quelques principes en tête :</sys:String>
<sys:String x:Key="About:List:Item1">Simplicité</sys:String>
<sys:String x:Key="About:List:Item2">Portabilité</sys:String>
<sys:String x:Key="About:List:Item3">Exécutable unique</sys:String>
<sys:String x:Key="About:List:Item4">Utilisation responsable</sys:String>
<Span x:Key="About:SupportAssistant">
Si vous aimez ce programme et souhaitez me soutenir, veuillez visiter ma
<Hyperlink local:HyperlinkExtensions.IsExternal="True" NavigateUri="https://bs.assistant.moe/Donate/">
page de don
</Hyperlink>
ou mon
<Hyperlink local:HyperlinkExtensions.IsExternal="True" NavigateUri="https://www.patreon.com/AssistantMoe">
Patreon
</Hyperlink>
</Span>
<sys:String x:Key="About:SpecialThanks">Remerciements particuliers ♥</sys:String>
<sys:String x:Key="About:Donate">Faire un don</sys:String>
<sys:String x:Key="About:HeadpatsButton">Caresses-tête</sys:String>
<sys:String x:Key="About:HugsButton">Câlins</sys:String>
<!-- Options Page -->
<sys:String x:Key="Options:Title">Options</sys:String>
<sys:String x:Key="Options:PageTitle">Paramètres</sys:String>
<sys:String x:Key="Options:InstallFolder">Dossier d'installation</sys:String>
<sys:String x:Key="Options:SelectFolderButton">Sélectionner un dossier</sys:String>
<sys:String x:Key="Options:OpenFolderButton">Ouvrir le dossier</sys:String>
<sys:String x:Key="Options:SaveSelectedMods">Sauvegarder les mods sélectionnés</sys:String>
<sys:String x:Key="Options:CheckInstalledMods">Détecter les mods installés</sys:String>
<sys:String x:Key="Options:SelectInstalledMods">Sélectionner les mods installés</sys:String>
<sys:String x:Key="Options:ReinstallInstalledMods">Réinstaller les mods installés</sys:String>
<sys:String x:Key="Options:EnableOneClickInstalls">Activer les installations OneClick™</sys:String>
<sys:String x:Key="Options:BeatSaver">BeatSaver</sys:String>
<sys:String x:Key="Options:ModelSaber">ModelSaber</sys:String>
<sys:String x:Key="Options:GameType">Type du jeu</sys:String>
<sys:String x:Key="Options:GameType:Steam">Steam</sys:String>
<sys:String x:Key="Options:GameType:Oculus">Oculus</sys:String>
<sys:String x:Key="Options:Tools">Outils</sys:String>
<sys:String x:Key="Options:InstallPlaylist">Installer une playlist</sys:String>
<sys:String x:Key="Options:InstallingPlaylist">Installation de la playlist : {0}</sys:String>
<sys:String x:Key="Options:FailedPlaylistSong">Échec de la musique : {0}</sys:String>
<sys:String x:Key="Options:FinishedPlaylist">[{0} échecs] Installation de la playlist terminée : {1}</sys:String>
<sys:String x:Key="Options:Diagnostics">Diagnostic</sys:String>
<sys:String x:Key="Options:OpenLogsButton">Ouvrir les logs</sys:String>
<sys:String x:Key="Options:OpenAppDataButton">Ouvrir AppData</sys:String>
<sys:String x:Key="Options:UninstallBSIPAButton">Désinstaller BSIPA</sys:String>
<sys:String x:Key="Options:RemoveAllModsButton">Supprimer tous les mods</sys:String>
<sys:String x:Key="Options:ApplicationTheme">Thème de l'application</sys:String>
<sys:String x:Key="Options:ExportTemplateButton">Exporter le modèle</sys:String>
<sys:String x:Key="Options:UploadingLog">Envoi des logs</sys:String>
<sys:String x:Key="Options:LogUrlCopied">URL des logs copiée dans le presse-papier !</sys:String>
<sys:String x:Key="Options:LogUploadFailed">L'envoi des logs a échoué</sys:String>
<sys:String x:Key="Options:LogUploadFailed:Title">L'envoi des logs a échoué !</sys:String>
<sys:String x:Key="Options:LogUploadFailed:Body">Impossible d'envoyer le fichier de logs à Teknik, veuillez réessayer ou envoyer le fichier manuellement.</sys:String>
<sys:String x:Key="Options:GettingModList">Récupération de la liste des mods</sys:String>
<sys:String x:Key="Options:FindingBSIPAVersion">Découverte de la version de BSIPA</sys:String>
<sys:String x:Key="Options:BSIPAUninstalled">BSIPA désinstallé</sys:String>
<sys:String x:Key="Options:YeetModsBox:Title">Désinstaller les mods ?</sys:String>
<sys:String x:Key="Options:YeetModsBox:RemoveAllMods">Êtes-vous sûr de vouloir supprimer TOUS les mods ?</sys:String>
<sys:String x:Key="Options:YeetModsBox:CannotBeUndone">Cela ne peut pas être annulé.</sys:String>
<sys:String x:Key="Options:AllModsUninstalled">Tous les mods ont été désinstallés</sys:String>
<sys:String x:Key="Options:CurrentThemeRemoved">Le thème actuel a été supprimé, passage au thème par défaut...</sys:String>
<sys:String x:Key="Options:ThemeFolderNotFound">Dossier Themes non trouvé ! Essayez d'exporter le modèle...</sys:String>
<sys:String x:Key="Options:AppDataNotFound">Dossier AppData non trouvé ! Essayez de lancer votre jeu.</sys:String>
<!-- Loading Page -->
<sys:String x:Key="Loading:Loading">Chargement des mods</sys:String>
<!-- Invalid Page -->
<sys:String x:Key="Invalid:Title">Invalide</sys:String>
<sys:String x:Key="Invalid:PageTitle">Installation invalide détectée</sys:String>
<sys:String x:Key="Invalid:PageSubtitle">Votre installation du jeu est corrompue sinon invalide</sys:String>
<sys:String x:Key="Invalid:List:Header">Cela peut survenir si votre copie du jeu est piratée, ou si vous copiez une copie piratée sur votre installation légitime</sys:String>
<Span x:Key="Invalid:List:Line1">
Si votre copie du jeu est piratée,
<Bold>veuillez acheter le jeu
<Hyperlink NavigateUri="https://beatgames.com/" local:HyperlinkExtensions.IsExternal="True">
ICI
</Hyperlink>
</Bold>.
</Span>
<Span x:Key="Invalid:List:Line2">
Si votre copie du jeu
<Bold>n'</Bold>est
<Bold>pas</Bold> piratée, veuillez
<Hyperlink NavigateUri="https://bsmg.wiki/fr/support/#installation-propre" local:HyperlinkExtensions.IsExternal="True">
faire une installation propre
</Hyperlink>.
</Span>
<Span x:Key="Invalid:List:Line3">
Si cela n'a pas fonctionné, demandez de l'aide au support dans le canal textuel
<Span Foreground="Blue">#support</Span> dans
<Hyperlink NavigateUri="https://discord.gg/beatsabermods" local:HyperlinkExtensions.IsExternal="True">
BSMG
</Hyperlink>.
</Span>
<sys:String x:Key="Invalid:BoughtGame1">Si vous utilisiez une version piratée mais avez acheté le jeu depuis</sys:String>
<sys:String x:Key="Invalid:SelectFolderButton">Sélectionner un dossier</sys:String>
<sys:String x:Key="Invalid:BoughtGame2">Vous devez relancer Mod Assistant après avoir choisi l'installation légitime</sys:String>
<!-- OneClick Class -->
<sys:String x:Key="OneClick:MapDownloadFailed">Impossible de récupérer les détails de la map.</sys:String>
<sys:String x:Key="OneClick:SongDownloadFailed">Impossible de télécharger la musique.</sys:String>
<sys:String x:Key="OneClick:SongDownload:Failed">Impossible de télécharger la musique.</sys:String>
<sys:String x:Key="OneClick:SongDownload:NetworkIssues">Il pourrait y avoir des problèmes avec BeatSaver ou votre connexion Internet.</sys:String>
<sys:String x:Key="OneClick:SongDownload:FailedTitle">Échec du téléchargement du ZIP de la musique</sys:String>
<sys:String x:Key="OneClick:InstallDirNotFound">Chemin de l'installation de Beat Saber non trouvé.</sys:String>
<sys:String x:Key="OneClick:InstalledAsset">Installé : {0}</sys:String>
<sys:String x:Key="OneClick:AssetInstallFailed">Échec de l'installation.</sys:String>
<sys:String x:Key="OneClick:ProtocolHandler:Registered">{0} : gestionnaires d'installation OneClick™ inscrits !</sys:String>
<sys:String x:Key="OneClick:ProtocolHandler:Unregistered">{0} : gestionnaires d'installation OneClick™ désinscrits !</sys:String>
<!-- Themes Class -->
<sys:String x:Key="Themes:ThemeNotFound">Thème non trouvé, passage au thème par défaut...</sys:String>
<sys:String x:Key="Themes:ThemeSet">Thème défini sur {0}.</sys:String>
<sys:String x:Key="Themes:ThemeMissing">{0} n'existe pas.</sys:String>
<sys:String x:Key="Themes:SavedTemplateTheme">Modèle du thème &quot;{0}&quot; sauvegardé dans le dossier Themes.</sys:String>
<sys:String x:Key="Themes:TemplateThemeExists">Le modèle du thème existe déjà !</sys:String>
<sys:String x:Key="Themes:FailedToLoadXaml">Échec du chargement du fichier .xaml pour le thème {0} : {1}</sys:String>
<!-- Updater Class -->
<sys:String x:Key="Updater:CheckFailed">Impossible de vérifier les mises à jour.</sys:String>
<sys:String x:Key="Updater:DownloadFailed">Impossible de télécharger la mise à jour.</sys:String>
<!-- Utils Class -->
<sys:String x:Key="Utils:NotificationTitle">Mod Assistant</sys:String>
<sys:String x:Key="Utils:NoInstallFolder">Impossible de détecter le dossier d'installation de Beat Saber. Veuillez le sélectionner manuellement.</sys:String>
<sys:String x:Key="Utils:RunAsAdmin">Mod Assistant a besoin de lancer cette tâche en administrateur. Veuillez réessayer.</sys:String>
<sys:String x:Key="Utils:InstallDir:DialogTitle">Sélectionnez le dossier d'installation de Beat Saber</sys:String>
<sys:String x:Key="Utils:CannotOpenFolder">Impossible d'ouvrir le dossier : {0}</sys:String>
</ResourceDictionary>

View file

@ -102,7 +102,7 @@
<sys:String x:Key="Mods:UninstallBox:Body2">Continuando, altre mod potrebbero smettere di funzionare</sys:String>
<sys:String x:Key="Mods:FailedExtract">Impossibile estrarre {0}, prossimo tentativo in {1} secondi. ({2}/{3})</sys:String>
<sys:String x:Key="Mods:FailedExtractMaxReached">Non sono riuscito ad estrarre {0} dopo aver raggiunto il numero massimo di tentativi ({1}), salto questa mod. Questa protrebbe anche non funzionare correttamente, quindi procedi a tuo rischio e pericolo</sys:String>
<sys:String x:Key="Mods:SearchLabel">Cerca...</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Mods:SearchLabel">Cerca...</sys:String>
<!-- About Page -->
<sys:String x:Key="About:Title">Info</sys:String>
@ -143,11 +143,11 @@
<sys:String x:Key="Options:GameType">Tipo di Installazione</sys:String>
<sys:String x:Key="Options:GameType:Steam">Steam</sys:String>
<sys:String x:Key="Options:GameType:Oculus">Oculus</sys:String>
<sys:String x:Key="Options:Tools">Strumenti</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:InstallPlaylist">Installa Playlist</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:InstallingPlaylist">Installazione Playlist: {0}</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:FailedPlaylistSong">Installazione canzone fallita: {0}</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:FinishedPlaylist">[{0} fails] Installazione playlist terminata: {1}</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:Tools">Strumenti</sys:String>
<sys:String x:Key="Options:InstallPlaylist">Installa Playlist</sys:String>
<sys:String x:Key="Options:InstallingPlaylist">Installazione Playlist: {0}</sys:String>
<sys:String x:Key="Options:FailedPlaylistSong">Installazione canzone fallita: {0}</sys:String>
<sys:String x:Key="Options:FinishedPlaylist">[{0} fails] Installazione playlist terminata: {1}</sys:String>
<sys:String x:Key="Options:Diagnostics">Diagnostica</sys:String>
<sys:String x:Key="Options:OpenLogsButton">Apri il Log</sys:String>
<sys:String x:Key="Options:OpenAppDataButton">Apri AppData</sys:String>

View file

@ -0,0 +1,237 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ModAssistant"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<sys:String x:Key="ResourceDictionaryName">i18n:ko-KR</sys:String>
<!-- App -->
<sys:String x:Key="App:InstallDirDialog:Title">비트세이버 설치 폴더를 찾을 수 없습니다!</sys:String>
<sys:String x:Key="App:InstallDirDialog:OkCancel">OK를 눌러 재시도하거나, Cancel을 눌러 프로그램을 종료할 수 있습니다.</sys:String>
<sys:String x:Key="App:InvalidArgument">유효하지 않은 인수입니다! '{0}'은 옵션을 필요로 합니다.</sys:String>
<sys:String x:Key="App:UnrecognizedArgument">인식할 수 없는 인수입니다. 모드 어시스턴트를 종료합니다.</sys:String>
<sys:String x:Key="App:UnhandledException">처리되지 않은 예외가 발생했습니다.</sys:String>
<sys:String x:Key="App:Exception">예외</sys:String>
<!-- Main Window -->
<sys:String x:Key="MainWindow:WindowTitle">모드 어시스턴트</sys:String>
<sys:String x:Key="MainWindow:IntroButton">인트로</sys:String>
<sys:String x:Key="MainWindow:ModsButton">모드</sys:String>
<sys:String x:Key="MainWindow:AboutButton">정보</sys:String>
<sys:String x:Key="MainWindow:OptionsButton">옵션</sys:String>
<sys:String x:Key="MainWindow:GameVersionLabel">게임 버전</sys:String>
<sys:String x:Key="MainWindow:VersionLabel">버전</sys:String>
<sys:String x:Key="MainWindow:ModInfoButton">모드 설명</sys:String>
<sys:String x:Key="MainWindow:InstallButtonTop">설치</sys:String>
<sys:String x:Key="MainWindow:InstallButtonBottom">또는 업데이트</sys:String>
<sys:String x:Key="MainWindow:GameVersionLoadFailed">게임 버전을 로드할 수 없었기 때문에 모드 탭이 비활성화됩니다.</sys:String>
<sys:String x:Key="MainWindow:GameUpdateDialog:Title">새로운 게임 버전이 감지되었습니다!</sys:String>
<sys:String x:Key="MainWindow:GameUpdateDialog:Line1">게임 업데이트가 있었던 것 같습니다.</sys:String>
<sys:String x:Key="MainWindow:GameUpdateDialog:Line2">왼쪽 아래에 선택된 버전이 맞는 버전인지 다시 한번 확인해주세요!</sys:String>
<sys:String x:Key="MainWindow:NoModSelected">아무런 모드도 선택되지 않았습니다!</sys:String>
<sys:String x:Key="MainWindow:NoModInfoPage">{0}는 설명 페이지를 가지고 있지 않습니다.</sys:String>
<!-- Intro Page -->
<sys:String x:Key="Intro:Title">인트로</sys:String>
<sys:String x:Key="Intro:PageTitle">모드 어시스턴트에 어서오세요</sys:String>
<sys:String x:Key="Intro:Terms:Header">이 페이지를 정독해주세요</sys:String>
<Span x:Key="Intro:Terms:Line1">
이 프로그램을 사용하려면 다음 약관을 읽고 동의해야 합니다:
</Span>
<Span x:Key="Intro:Terms:Line2">
비트세이버는 공식적으로 모드를
<Bold>지원하지 않습니다.</Bold>
</Span>
<Span x:Key="Intro:Terms:Term1">
이것은 모드들이 매 업데이트마다
<Bold>망가진다는 것을</Bold> 의미합니다. 이것은 일반적이며, Beat Games'의 탓이
<Bold>아닙니다.</Bold>
</Span>
<Span x:Key="Intro:Terms:Term2">
모드들은 버그와 성능 문제를
<Bold>발생시킵니다.</Bold> 이것은 Beat Games'의 탓이
<Bold>아닙니다.</Bold>
</Span>
<Span x:Key="Intro:Terms:Term3">
모드들은
<Bold>무료로</Bold> 만들어졌으며 모더들의
<Bold>소중한 시간의 결과물입니다.</Bold>기다림을 갖고 이해해주세요.
</Span>
<Span x:Key="Intro:ReviewsBeatGamesFault">
모드가 망가진 것 때문에 게임에 대한 부정적인 의견을<Bold>남기지 마세요.</Bold> 이것은 Beat Games'의 탓이
<Bold>아닙니다.</Bold>
<LineBreak/> Beat Games'는 모드를 죽이려 하지 않습니다.
</Span>
<Span x:Key="Intro:ReviewsRustySpoon">
만일 사람들이 모드가
<Italic>망가진 것을 이유로</Italic> 부정적인 의견을 남기는 것을 계속 보게 된다면,
<LineBreak/>
<Bold>제가 개인적으로 모드를 터트릴지도요..?</Bold>
</Span>
<Span x:Key="Intro:WikiGuide">
<Hyperlink local:HyperlinkExtensions.IsExternal="True" NavigateUri="https://bsmg.wiki/pc-modding.html">
위키
</Hyperlink>에 있는 초보자 가이드를 읽어주세요.
</Span>
<sys:String x:Key="Intro:AgreeButton">동의합니다</sys:String>
<sys:String x:Key="Intro:DisagreeButton">거부합니다</sys:String>
<sys:String x:Key="Intro:ClosingApp">어플리케이션을 종료합니다: 당신은 약관에 동의하지 않았습니다.</sys:String>
<sys:String x:Key="Intro:VersionDownloadFailed">버전 리스트를 다운로드할 수 없었습니다</sys:String>
<sys:String x:Key="Intro:ModsTabDisabled">모드 탭이 비활성화되었습니다. 어시스턴트를 재시작해주세요.</sys:String>
<sys:String x:Key="Intro:ModsTabEnabled">이제 모드 탭을 사용할 수 있습니다!</sys:String>
<!-- Mods Page -->
<sys:String x:Key="Mods:Title">모드</sys:String>
<sys:String x:Key="Mods:Header:Name">이름</sys:String>
<sys:String x:Key="Mods:Header:Installed">설치 버전</sys:String>
<sys:String x:Key="Mods:Header:Latest">최신 버전</sys:String>
<sys:String x:Key="Mods:Header:Description">설명</sys:String>
<sys:String x:Key="Mods:Header:Uninstall">제거</sys:String>
<sys:String x:Key="Mods:UninstallButton">제거</sys:String>
<sys:String x:Key="Mods:LoadFailed">모드 목록을 불러올 수 없었습니다</sys:String>
<sys:String x:Key="Mods:CheckingInstalledMods">설치된 모드들을 확인하고 있습니다</sys:String>
<sys:String x:Key="Mods:LoadingMods">모드들을 불러오고 있습니다</sys:String>
<sys:String x:Key="Mods:FinishedLoadingMods">모드들을 불러왔습니다</sys:String>
<sys:String x:Key="Mods:InstallingMod">Installing {0}</sys:String>
<sys:String x:Key="Mods:InstalledMod">Installed {0}</sys:String>
<sys:String x:Key="Mods:FinishedInstallingMods">모드 설치를 마쳤습니다</sys:String>
<sys:String x:Key="Mods:ModDownloadLinkMissing">{0}를 위한 다운로드 링크를 찾을 수 없었습니다</sys:String>
<sys:String x:Key="Mods:UninstallBox:Title">{0}를 제거하시겠습니까?</sys:String>
<sys:String x:Key="Mods:UninstallBox:Body1">정말로 {0}를 제거하시겠습니까?</sys:String>
<sys:String x:Key="Mods:UninstallBox:Body2">다른 모드를 사용 못하게 만들 수도 있습니다.</sys:String>
<sys:String x:Key="Mods:FailedExtract">{0}를 추출하는데 실패했습니다. {1}초 안에 재시도합니다. ({2}/{3})</sys:String>
<sys:String x:Key="Mods:FailedExtractMaxReached">({1})회동안 {0}를 추출하는데 실패했습니다. 이 모드가 제대로 작동하지 않을지도 모릅니다</sys:String>
<sys:String x:Key="Mods:SearchLabel">Search...</sys:String> <!-- NEEDS TRANSLATING -->
<!-- About Page -->
<sys:String x:Key="About:Title">정보</sys:String>
<sys:String x:Key="About:PageTitle">모드 어시스턴트에 대하여</sys:String>
<sys:String x:Key="About:List:Header">I'm Assistant, and I made Mod Assistant for mod assistance, with a few principles in mind:</sys:String>
<sys:String x:Key="About:List:Item1">Simplicity</sys:String>
<sys:String x:Key="About:List:Item2">Portability</sys:String>
<sys:String x:Key="About:List:Item3">Single Executable</sys:String>
<sys:String x:Key="About:List:Item4">Responsible use</sys:String>
<Span x:Key="About:SupportAssistant">
If you enjoy this program and would like to support me, please visit my
<Hyperlink local:HyperlinkExtensions.IsExternal="True" NavigateUri="https://bs.assistant.moe/Donate/">
donation page
</Hyperlink>
or my
<Hyperlink local:HyperlinkExtensions.IsExternal="True" NavigateUri="https://www.patreon.com/AssistantMoe">
Patreon
</Hyperlink>
</Span>
<sys:String x:Key="About:SpecialThanks">Special Thanks ♥</sys:String>
<sys:String x:Key="About:Donate">Donate</sys:String>
<sys:String x:Key="About:HeadpatsButton">Headpats</sys:String>
<sys:String x:Key="About:HugsButton">Hugs</sys:String>
<!-- Options Page -->
<sys:String x:Key="Options:Title">옵션</sys:String>
<sys:String x:Key="Options:PageTitle">설정</sys:String>
<sys:String x:Key="Options:InstallFolder">설치 폴더</sys:String>
<sys:String x:Key="Options:SelectFolderButton">폴더 선택</sys:String>
<sys:String x:Key="Options:OpenFolderButton">폴더 열기</sys:String>
<sys:String x:Key="Options:SaveSelectedMods">선택된 모드 저장</sys:String>
<sys:String x:Key="Options:CheckInstalledMods">설치된 모드 감지</sys:String>
<sys:String x:Key="Options:SelectInstalledMods">설치된 모드 선택</sys:String>
<sys:String x:Key="Options:ReinstallInstalledMods">설치된 모드 재설치</sys:String>
<sys:String x:Key="Options:EnableOneClickInstalls">OneClick™ 설치 활성화</sys:String>
<sys:String x:Key="Options:BeatSaver">BeatSaver</sys:String>
<sys:String x:Key="Options:ModelSaber">ModelSaber</sys:String>
<sys:String x:Key="Options:GameType">게임 유형</sys:String>
<sys:String x:Key="Options:GameType:Steam">Steam</sys:String>
<sys:String x:Key="Options:GameType:Oculus">Oculus</sys:String>
<sys:String x:Key="Options:Tools">Tools</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:InstallPlaylist">Install Playlist</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:InstallingPlaylist">Installing Playlist: {0}</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:FailedPlaylistSong">Failed song: {0}</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:FinishedPlaylist">[{0} fails] Finished Installing Playlist: {1}</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:Diagnostics">진단</sys:String>
<sys:String x:Key="Options:OpenLogsButton">로그 열기</sys:String>
<sys:String x:Key="Options:OpenAppDataButton">앱데이터 열기</sys:String>
<sys:String x:Key="Options:UninstallBSIPAButton">BSIPA 삭제</sys:String>
<sys:String x:Key="Options:RemoveAllModsButton">모든 모드 삭제</sys:String>
<sys:String x:Key="Options:ApplicationTheme">어플리케이션 테마</sys:String>
<sys:String x:Key="Options:ExportTemplateButton">템플릿 추출</sys:String>
<sys:String x:Key="Options:UploadingLog">로그 제출</sys:String>
<sys:String x:Key="Options:LogUrlCopied">로그 URL이 클립보드에 복사되었습니다!</sys:String>
<sys:String x:Key="Options:LogUploadFailed">로그 제출에 실패하였습니다</sys:String>
<sys:String x:Key="Options:LogUploadFailed:Title">로그 제출에 실패하였습니다!</sys:String>
<sys:String x:Key="Options:LogUploadFailed:Body">Teknik에게 로그 파일을 제출하는데에 실패하였습니다. 재시도하거나 수동으로 파일을 보내주세요.</sys:String>
<sys:String x:Key="Options:GettingModList">모드 목록을 얻는중입니다</sys:String>
<sys:String x:Key="Options:FindingBSIPAVersion">BSIPA 버전을 찾는중입니다</sys:String>
<sys:String x:Key="Options:BSIPAUninstalled">BSIPA가 제거되었습니다</sys:String>
<sys:String x:Key="Options:YeetModsBox:Title">모든 모드를 제거할까요?</sys:String>
<sys:String x:Key="Options:YeetModsBox:RemoveAllMods">정말로 모든 모드를 제거할까요?</sys:String>
<sys:String x:Key="Options:YeetModsBox:CannotBeUndone">이것은 취소할 수 없습니다.</sys:String>
<sys:String x:Key="Options:AllModsUninstalled">모든 모드가 제거되었습니다</sys:String>
<sys:String x:Key="Options:CurrentThemeRemoved">현재 테마를 제거중입니다. 원래 테마로 돌아갑니다...</sys:String>
<sys:String x:Key="Options:ThemeFolderNotFound">테마 폴더를 찾을 수 없습니다! 템플릿으로 내보냅니다...</sys:String>
<sys:String x:Key="Options:AppDataNotFound">AppData 폴더를 찾을 수 없습니다! 게임을 실행해보세요.</sys:String>
<!-- Loading Page -->
<sys:String x:Key="Loading:Loading">모드 로딩중</sys:String>
<!-- Invalid Page -->
<sys:String x:Key="Invalid:Title">잘못된 프로그램</sys:String>
<sys:String x:Key="Invalid:PageTitle">잘못된 프로그램 설치가 감지되었습니다</sys:String>
<sys:String x:Key="Invalid:PageSubtitle">게임이 손상되었거나 다른 이유로 잘못된 것 같습니다</sys:String>
<sys:String x:Key="Invalid:List:Header">이 오류는 게임이 불법적인 경로로 받아졌거나, 불법적인 경로로 받아진 게임을 당신의 정상적인 게임에 덮어씌워졌을 때에 발생합니다</sys:String>
<Span x:Key="Invalid:List:Line1">
만일 당신이 게임을 불법적인 경로로 받았다면,
<Bold>
<Hyperlink NavigateUri="https://beatgames.com/" local:HyperlinkExtensions.IsExternal="True">
여기서
</Hyperlink>
</Bold>게임을 구매해주세요.
</Span>
<Span x:Key="Invalid:List:Line2">
만일 당신의 게임이 불법적인 경로로 받아진게
<Bold>아니라면</Bold>,
<Hyperlink NavigateUri="https://bsmg.wiki/support#clean-installation" local:HyperlinkExtensions.IsExternal="True">
클린재설치
</Hyperlink>를 해주세요.
</Span>
<Span x:Key="Invalid:List:Line3">
만일 그것들이 도움되지 않았다면,
<Hyperlink NavigateUri="https://discord.gg/beatsabermods" local:HyperlinkExtensions.IsExternal="True">
BSMG
</Hyperlink>의
<Span Foreground="Blue">#support</Span> 채널에서 도움을 구하세요.
</Span>
<sys:String x:Key="Invalid:BoughtGame1">만일 불법적인 경로로 받아진 게임을 가지고 있었다가 게임을 구매했다면,</sys:String>
<sys:String x:Key="Invalid:SelectFolderButton">폴더를 선택해주세요</sys:String>
<sys:String x:Key="Invalid:BoughtGame2">정상적인 설치 이후 모드 어시스턴트를 재시작할 필요가 있습니다</sys:String>
<!-- OneClick Class -->
<sys:String x:Key="OneClick:MapDownloadFailed">맵의 세부정보를 얻어올 수 없었습니다.</sys:String>
<sys:String x:Key="OneClick:SongDownloadFailed">곡을 받아올 수 없었습니다.</sys:String>
<sys:String x:Key="OneClick:SongDownload:Failed">곡을 받아올 수 없었습니다.</sys:String>
<sys:String x:Key="OneClick:SongDownload:NetworkIssues">BeatSaver 또는 당신의 인터넷 연결에 문제가 있는 것 같습니다.</sys:String>
<sys:String x:Key="OneClick:SongDownload:FailedTitle">노래 ZIP 파일을 받는 데에 실패했습니다.</sys:String>
<sys:String x:Key="OneClick:InstallDirNotFound">비트세이버 설치 폴더를 찾을 수 없었습니다.</sys:String>
<sys:String x:Key="OneClick:InstalledAsset">설치됨: {0}</sys:String>
<sys:String x:Key="OneClick:AssetInstallFailed">설치에 실패하였습니다.</sys:String>
<sys:String x:Key="OneClick:ProtocolHandler:Registered">{0} OneClick™ 설치 관리자가 등록되었습니다!</sys:String>
<sys:String x:Key="OneClick:ProtocolHandler:Unregistered">{0} OneClick™ 설치 관리자가 등록 취소되었습니다!</sys:String>
<!-- Themes Class -->
<sys:String x:Key="Themes:ThemeNotFound">테마를 찾을 수 없어, 기본 테마로 돌아갑니다...</sys:String>
<sys:String x:Key="Themes:ThemeSet">{0} 테마로 설정합니다.</sys:String>
<sys:String x:Key="Themes:ThemeMissing">{0}는 존재하지 않습니다.</sys:String>
<sys:String x:Key="Themes:SavedTemplateTheme">템플릿 테마 &quot;{0}&quot;가 템플릿 폴더에 저장되었습니다.</sys:String>
<sys:String x:Key="Themes:TemplateThemeExists">템플릿 테마가 이미 존재합니다!</sys:String>
<sys:String x:Key="Themes:FailedToLoadXaml">테마를 위한 .xaml 파일을 불러오지 못했습니다 {0}: {1}</sys:String>
<!-- Updater Class -->
<sys:String x:Key="Updater:CheckFailed">업데이트를 확인할 수 없습니다.</sys:String>
<sys:String x:Key="Updater:DownloadFailed">업데이트를 다운로드할 수 없습니다.</sys:String>
<!-- Utils Class -->
<sys:String x:Key="Utils:NotificationTitle">모드 어시스턴트</sys:String>
<sys:String x:Key="Utils:NoInstallFolder">비트세이버 설치 폴더를 찾을 수 없습니다. 수동으로 선택해주세요.</sys:String>
<sys:String x:Key="Utils:RunAsAdmin">모드 어시스턴트는 이 작업을 관리자 권한으로 실행하는 것을 필요로 합니다. 다시 시도해주세요.</sys:String>
<sys:String x:Key="Utils:InstallDir:DialogTitle">비트세이버 설치 폴더를 선택해주세요</sys:String>
<sys:String x:Key="Utils:CannotOpenFolder">폴더를 열 수 없습니다: {0}</sys:String>
</ResourceDictionary>

View file

@ -36,7 +36,7 @@
<sys:String x:Key="Intro:PageTitle">Welkom bij Mod Assistant</sys:String>
<sys:String x:Key="Intro:Terms:Header">Lees deze pagina alstublieft volledig en aandachtig</sys:String>
<Span x:Key="Intro:Terms:Line1">
Door het gebruiken van dit programma verlkaar ik de volgende voorwaarden te hebben gelezen en hier mee akkoord te gaan:
Door het gebruiken van dit programma verklaar ik de volgende voorwaarden te hebben gelezen en hier mee akkoord te gaan:
</Span>
<Span x:Key="Intro:Terms:Line2">
Beat Saber
@ -67,7 +67,7 @@
<Bold>zal ik persoonlijk met een roestige lepel mods niet meer laten werken</Bold>
</Span>
<Span x:Key="Intro:WikiGuide">
Lees alstublieft de 'Beginners Guide' op de wiki
Lees alstublieft de 'Beginners Guide' op de
<Hyperlink local:HyperlinkExtensions.IsExternal="True" NavigateUri="https://bsmg.wiki/pc-modding.html">
Wiki
</Hyperlink>. (engels)
@ -77,7 +77,7 @@
<sys:String x:Key="Intro:ClosingApp">Sluit applicatie af: U accepteerde de voorwaarden niet.</sys:String>
<sys:String x:Key="Intro:VersionDownloadFailed">Kon de versie lijst niet downloaden</sys:String>
<sys:String x:Key="Intro:ModsTabDisabled">Mods tabblad uitgeschakeld. Herstart het programma om opnieuw te proberen.</sys:String>
<sys:String x:Key="Intro:ModsTabEnabled">U kan nu het mods tabblad gebruiken!</sys:String>
<sys:String x:Key="Intro:ModsTabEnabled">U kunt nu het mods tabblad gebruiken!</sys:String>
<!-- Mods Page -->
<sys:String x:Key="Mods:Title">Mods</sys:String>
@ -100,6 +100,7 @@
<sys:String x:Key="Mods:UninstallBox:Body2">Dit zou uw andere mods niet meer kunnen laten werken</sys:String>
<sys:String x:Key="Mods:FailedExtract">Kon {0} niet extracten, probeer opniew over {1} seconden. ({2}/{3})</sys:String>
<sys:String x:Key="Mods:FailedExtractMaxReached">Kon {0} niet extracten na maximaal aantal pogingen ({1}), Overslaan. Deze mod werkt msischien niet goed dus ga verder op eigen risico</sys:String>
<sys:String x:Key="Mods:SearchLabel">Search...</sys:String> <!-- NEEDS TRANSLATING -->
<!-- About Page -->
<sys:String x:Key="About:Title">Over</sys:String>
@ -140,6 +141,11 @@
<sys:String x:Key="Options:GameType">Game Type</sys:String>
<sys:String x:Key="Options:GameType:Steam">Steam</sys:String>
<sys:String x:Key="Options:GameType:Oculus">Oculus</sys:String>
<sys:String x:Key="Options:Tools">Tools</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:InstallPlaylist">Install Playlist</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:InstallingPlaylist">Installing Playlist: {0}</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:FailedPlaylistSong">Failed song: {0}</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:FinishedPlaylist">[{0} fails] Finished Installing Playlist: {1}</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:Diagnostics">Diagnostiek</sys:String>
<sys:String x:Key="Options:OpenLogsButton">Open Logs</sys:String>
<sys:String x:Key="Options:OpenAppDataButton">Open AppData</sys:String>

View file

@ -94,6 +94,7 @@
<sys:String x:Key="Mods:UninstallBox:Body2">这可能会导致其他Mod不可用。</sys:String>
<sys:String x:Key="Mods:FailedExtract">{0}解压失败,将在{1}秒后重试。({2}/{3}</sys:String>
<sys:String x:Key="Mods:FailedExtractMaxReached">{0}在重试{1}次后仍然无法解压将被跳过。注意这个Mod可能无法使用。</sys:String>
<sys:String x:Key="Mods:SearchLabel">搜索...</sys:String> <!-- NEEDS TRANSLATING -->
<!-- About Page -->
<sys:String x:Key="About:Title">关于</sys:String>
@ -134,6 +135,11 @@
<sys:String x:Key="Options:GameType">游戏类型</sys:String>
<sys:String x:Key="Options:GameType:Steam">Steam</sys:String>
<sys:String x:Key="Options:GameType:Oculus">Oculus</sys:String>
<sys:String x:Key="Options:Tools">工具</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:InstallPlaylist">添加歌单Playlist</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:InstallingPlaylist">正在添加歌单:{0}</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:FailedPlaylistSong">失败歌曲:{0}</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:FinishedPlaylist">[{0}失败]添加{1}完成</sys:String> <!-- NEEDS TRANSLATING -->
<sys:String x:Key="Options:Diagnostics">诊断工具</sys:String>
<sys:String x:Key="Options:OpenLogsButton">打开日志</sys:String>
<sys:String x:Key="Options:OpenAppDataButton">打开游戏存档</sys:String>

View file

@ -38,6 +38,7 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.IO.Compression" />
@ -67,6 +68,7 @@
</ApplicationDefinition>
<Compile Include="Classes\External Interfaces\BeatSaver.cs" />
<Compile Include="Classes\External Interfaces\ModelSaber.cs" />
<Compile Include="Classes\External Interfaces\Playlists.cs" />
<Compile Include="Classes\External Interfaces\Utils.cs" />
<Compile Include="Classes\Http.cs" />
<Compile Include="Classes\HyperlinkExtensions.cs" />
@ -80,6 +82,10 @@
<DependentUpon>Intro.xaml</DependentUpon>
</Compile>
<Compile Include="Classes\Mod.cs" />
<Page Include="Localisation\de.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Localisation\en-DEBUG.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@ -101,6 +107,18 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Localisation\fr.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Localisation\it.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Localisation\ko.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Localisation\nl.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>

View file

@ -12,15 +12,51 @@
mc:Ignorable="d">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock
Name="SearchText"
Padding="5,0,0,0"
Height="0"
Grid.Row="0"
Text="{DynamicResource Mods:SearchLabel}"
Panel.ZIndex="1"
Foreground="{DynamicResource TextColor}"
Background="{DynamicResource BottomStatusBarBackground}" />
<TextBox
Name="SearchBar"
Margin="0,-1,0,0"
Padding="3,1,0,0"
Height="0"
Grid.Row="0"
Panel.ZIndex="2"
Background="#00000000"
Foreground="{DynamicResource TextColor}"
TextChanged="SearchBar_TextChanged"
BorderThickness="0" />
<ListView
Name="ModsListView"
Grid.Column="1"
Grid.Row="1"
SelectionChanged="ModsListView_SelectionChanged"
SelectionMode="Single">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Width="30">
<GridViewColumn.Header>
<Button
Name="SearchButton"
Background="#00000000"
BorderThickness="0"
Click="SearchButton_Click"
Padding="9,-1,9,0"
Margin="-5"
Content="🔍"
FontSize="11" />
</GridViewColumn.Header>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox

View file

@ -12,6 +12,8 @@ using System.Windows.Forms;
using System.Windows.Navigation;
using static ModAssistant.Http;
using ModAssistant.Libs;
using System.Windows.Media.Animation;
using TextBox = System.Windows.Controls.TextBox;
namespace ModAssistant.Pages
{
@ -717,5 +719,59 @@ namespace ModAssistant.Pages
System.Windows.Clipboard.SetText(((TextBlock)sender).Text);
Utils.SendNotify("Copied text to clipboard");
}
private void SearchButton_Click(object sender, RoutedEventArgs e)
{
if (SearchBar.Height == 0)
{
SearchBar.Focus();
Animate(SearchBar, 0, 16, new TimeSpan(0, 0, 0, 0, 300));
Animate(SearchText, 0, 16, new TimeSpan(0, 0, 0, 0, 300));
ModsListView.Items.Filter = new Predicate<object>(SearchFilter);
}
else
{
Animate(SearchBar, 16, 0, new TimeSpan(0, 0, 0, 0, 300));
Animate(SearchText, 16, 0, new TimeSpan(0, 0, 0, 0, 300));
ModsListView.Items.Filter = null;
}
}
private void SearchBar_TextChanged(object sender, TextChangedEventArgs e)
{
ModsListView.Items.Filter = new Predicate<object>(SearchFilter);
if (SearchBar.Text.Length > 0)
{
SearchText.Text = null;
}
else
{
SearchText.Text = (string)FindResource("Mods:SearchLabel");
}
}
private bool SearchFilter(object mod)
{
ModListItem item = mod as ModListItem;
if (item.ModName.ToLower().Contains(SearchBar.Text.ToLower())) return true;
if (item.ModDescription.ToLower().Contains(SearchBar.Text.ToLower())) return true;
if (item.ModName.ToLower().Replace(" ", string.Empty).Contains(SearchBar.Text.ToLower().Replace(" ", string.Empty))) return true;
if (item.ModDescription.ToLower().Replace(" ", string.Empty).Contains(SearchBar.Text.ToLower().Replace(" ", string.Empty))) return true;
return false;
}
private void Animate(TextBlock target, double oldHeight, double newHeight, TimeSpan duration)
{
target.Height = oldHeight;
DoubleAnimation animation = new DoubleAnimation(newHeight, duration);
target.BeginAnimation(TextBlock.HeightProperty, animation);
}
private void Animate(TextBox target, double oldHeight, double newHeight, TimeSpan duration)
{
target.Height = oldHeight;
DoubleAnimation animation = new DoubleAnimation(newHeight, duration);
target.BeginAnimation(TextBox.HeightProperty, animation);
}
}
}

View file

@ -29,6 +29,8 @@
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
@ -72,17 +74,17 @@
<Button
Grid.Row="2"
Grid.Column="2"
Width="93"
Height="30"
Margin="3"
Margin="5"
Padding="5"
Click="SelectDirButton_Click"
Content="{DynamicResource Options:SelectFolderButton}" />
<Button
Grid.Row="2"
Grid.Column="3"
Width="93"
Height="30"
Margin="3"
Margin="5"
Padding="5"
Click="OpenDirButton_Click"
Content="{DynamicResource Options:OpenFolderButton}" />
@ -244,18 +246,18 @@
Name="ApplicationThemeExportTemplate"
Grid.Row="13"
Grid.Column="2"
Width="93"
Height="30"
Margin="3"
Margin="5"
Padding="5"
Click="ApplicationThemeExportTemplate_Click"
Content="{DynamicResource Options:ExportTemplateButton}" />
<Button
Name="ApplicationThemeOpenThemesFolder"
Grid.Row="13"
Grid.Column="3"
Width="93"
Height="30"
Margin="3"
Margin="5"
Padding="5"
Click="ApplicationThemeOpenThemesFolder_Click"
Content="{DynamicResource Options:OpenFolderButton}" />
@ -265,36 +267,58 @@
HorizontalAlignment="Left"
FontSize="24"
FontWeight="Bold"
Text="{DynamicResource Options:Diagnostics}" />
Text="{DynamicResource Options:Tools}" />
<StackPanel
Grid.Row="15"
Grid.ColumnSpan="4"
Margin="0"
HorizontalAlignment="Left"
Orientation="Horizontal">
<Button
Width="80"
Height="30"
Margin="5"
Padding="5"
Click="InstallPlaylistButton_Click"
Content="{DynamicResource Options:InstallPlaylist}" />
</StackPanel>
<TextBlock
Grid.Row="16"
Margin="15,5,5,5"
HorizontalAlignment="Left"
FontSize="24"
FontWeight="Bold"
Text="{DynamicResource Options:Diagnostics}" />
<StackPanel
Grid.Row="17"
Grid.ColumnSpan="4"
Margin="0"
HorizontalAlignment="Left"
Orientation="Horizontal">
<Button
Height="30"
Margin="5"
Padding="5"
Click="OpenLogsDirButton_Click"
Content="{DynamicResource Options:OpenLogsButton}" />
<Button
x:Name="OpenAppData"
Width="100"
Height="30"
Margin="5"
Padding="5"
Click="OpenAppDataButton_Click"
Content="{DynamicResource Options:OpenAppDataButton}" />
<Button
x:Name="YeetBSIPA"
Width="100"
Height="30"
Margin="5"
Padding="5"
Click="YeetBSIPAButton_Click"
Content="{DynamicResource Options:UninstallBSIPAButton}" />
<Button
Width="110"
Height="30"
Margin="5"
Padding="5"
Background="{DynamicResource ButtonDangerBackground}"
Click="YeetModsButton_Click">
<TextBlock Foreground="White" Text="{DynamicResource Options:RemoveAllModsButton}" />

View file

@ -308,5 +308,14 @@ namespace ModAssistant.Pages
MessageBox.Show((string)Application.Current.FindResource("Options:ThemeFolderNotFound"));
}
}
private void InstallPlaylistButton_Click(object sender, RoutedEventArgs e)
{
string playlistFile = Utils.GetManualFile();
if (File.Exists(playlistFile))
{
Task.Run(() => { API.Playlists.DownloadFrom(playlistFile, true).Wait(); });
}
}
}
}

View file

@ -51,5 +51,5 @@ using System.Windows;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.1.6.0")]
[assembly: AssemblyFileVersion("1.1.6.0")]
[assembly: AssemblyVersion("1.1.8.0")]
[assembly: AssemblyFileVersion("1.1.8.0")]