Skip to content

Commit

Permalink
Merge branch 'EverestAPI:dev' into fav
Browse files Browse the repository at this point in the history
  • Loading branch information
nhruo123 authored Apr 29, 2023
2 parents ac7a773 + d3e14cf commit c6c4a20
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 27 deletions.
3 changes: 3 additions & 0 deletions Celeste.Mod.mm/Content/Dialog/English.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
MENU_MODOPTIONS= Mod Options
MENU_PAUSE_MODOPTIONS= Mod Options

MENU_MODOPTIONS_UPDATE_FAILED= Failed to install Everest Update
MENU_MODOPTIONS_ONE_MOD_FAILEDTOLOAD= 1 mod failed to load
MENU_MODOPTIONS_MULTIPLE_MODS_FAILEDTOLOAD= {0} mods failed to load
MENU_MODOPTIONS_EVEREST_YAML_ERRORS= everest.yaml load errors occurred
Expand Down Expand Up @@ -156,6 +157,7 @@
UPDATER_SRC_STABLE= STABLE
UPDATER_SRC_BETA= BETA
UPDATER_SRC_DEV= DEV
UPDATER_SRC_CORE= CORE

UPDATER_SRC_RELEASE_GITHUB= Tagged releases (GitHub)
UPDATER_SRC_BUILDBOT_AZURE= Automatic builds (Azure)
Expand Down Expand Up @@ -218,6 +220,7 @@
DEPENDENCYDOWNLOADER_DONE= done.
DEPENDENCYDOWNLOADER_DOWNLOAD_DATABASE_FAILED= ERROR: Downloading the database failed. Please check your log.txt for more info.
DEPENDENCYDOWNLOADER_MUST_UPDATE_EVEREST= WARNING: An updated Everest version is required for some mods to load. Install it from the Change Everest Version menu.
DEPENDENCYDOWNLOADER_NEEDS_CORE_EVEREST= WARNING: A (currently WIP) .NET Core build of Everest is required for some mods to load. Install it from the Change Everest Version menu.
DEPENDENCYDOWNLOADER_EVEREST_UPDATE= Everest will be updated to {0} to make some mods work. Press Confirm to continue.
DEPENDENCYDOWNLOADER_MOD_NOT_FOUND= ERROR: {0} could not be found in the database. Please install this mod manually.
DEPENDENCYDOWNLOADER_UPDATE_CELESTE= ERROR: Some of your mods require a more recent version of Celeste to work. Please update your game.
Expand Down
2 changes: 2 additions & 0 deletions Celeste.Mod.mm/Content/Dialog/German.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
MENU_MODOPTIONS= Mod-Optionen
MENU_PAUSE_MODOPTIONS= Mod-Optionen

MENU_MODOPTIONS_UPDATE_FAILED= Beim Aktualisieren von Everest ist ein Fehler aufgetreten
MENU_MODOPTIONS_ONE_MOD_FAILEDTOLOAD= 1 Mod konnte nicht geladen werden
MENU_MODOPTIONS_MULTIPLE_MODS_FAILEDTOLOAD= {0} Mods konnten nicht geladen werden
MENU_MODOPTIONS_EVEREST_YAML_ERRORS= Beim Laden von everest.yaml ist ein Fehler aufgetreten
Expand Down Expand Up @@ -195,6 +196,7 @@
DEPENDENCYDOWNLOADER_DONE= fertig.
DEPENDENCYDOWNLOADER_DOWNLOAD_DATABASE_FAILED= FEHLER: Download der Datenbank fehlgeschlagen. Bitte überprüfe log.txt für mehr Informationen.
DEPENDENCYDOWNLOADER_MUST_UPDATE_EVEREST= WARNUNG: Einige Mods benötigen eine neuere Everest-Version zum Laden. Installiere sie im Menü zum Ändern der Everest-Version.
DEPENDENCYDOWNLOADER_NEEDS_CORE_EVEREST= WARNUNG: Einige Mods benötigen eine (aktuell noch WIP) .NET Core Everest-Version zum Laden. Installiere sie im Menü zum Ändern der Everest-Version.
DEPENDENCYDOWNLOADER_EVEREST_UPDATE= Everest wird auf {0} geupdatet, damit einige Mods geladen werden können. Drücke Bestätigen, um fortzufahren.
DEPENDENCYDOWNLOADER_MOD_NOT_FOUND= FEHLER: {0} konnte nicht in der Datenbank gefunden werden. Bitte installiere diese Mod manuell.
DEPENDENCYDOWNLOADER_UPDATE_CELESTE= FEHLER: Einige Mods benötigen eine neuere Version von Celeste. Bitte update dein Spiel.
Expand Down
8 changes: 4 additions & 4 deletions Celeste.Mod.mm/Content/Lua/boot.lua
Original file line number Diff line number Diff line change
Expand Up @@ -642,16 +642,16 @@ table.insert(package.searchers, loaderVirtualFS)

-- Vex forced me to do this.
local function loaderCS(name)
name = name and (name:match("^cs%.(.*)") or name:match("^#(.*)"))
if not name then
local stripped = name and (name:match("^cs%.(.*)") or name:match("^#(.*)"))
if not stripped then
return "\n\tNot a C# reference: " .. name
end

local found = cs
for key in name:gmatch("[^.]+") do
for key in stripped:gmatch("[^.]+") do
found = found[key]
if not found then
return "\n\tC# reference not found: " .. name
return "\n\tC# reference not found: " .. stripped
end
end

Expand Down
94 changes: 81 additions & 13 deletions Celeste.Mod.mm/Mod/Everest/Everest.Updater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static partial class Everest {
public static class Updater {

public enum UpdatePriority {
High, Low, None
None, Low, High
}

public class Entry {
Expand Down Expand Up @@ -159,6 +159,15 @@ public void Clear() {
Index = GetEverestUpdaterDatabaseURL,
ParseData = UpdateListParser("dev")
},
new Source {
Name = "updater_src_core",
Description = "updater_src_buildbot_azure",

UpdatePriority = UpdatePriority.None,

Index = GetEverestUpdaterDatabaseURL,
ParseData = UpdateListParser("core")
},
};

public static Task RequestAll() {
Expand Down Expand Up @@ -200,7 +209,13 @@ private static string GetEverestUpdaterDatabaseURL() {
if (string.IsNullOrEmpty(_everestUpdaterDatabaseURL)) {
using (WebClient wc = new WebClient()) {
Logger.Log(LogLevel.Verbose, "updater", "Fetching everest updater database URL");
_everestUpdaterDatabaseURL = wc.DownloadString("https://everestapi.github.io/everestupdater.txt").Trim();

UriBuilder uri = new UriBuilder(wc.DownloadString("https://everestapi.github.io/everestupdater.txt").Trim());
if ((uri.Query?.Length ?? 0) > 1)
uri.Query = uri.Query.Substring(1) + "&supportsNativeBuilds=true";
else
uri.Query = "supportsNativeBuilds=true";
_everestUpdaterDatabaseURL = uri.ToString();
}
}
return _everestUpdaterDatabaseURL;
Expand Down Expand Up @@ -298,6 +313,24 @@ public static Func<Source, string, List<Entry>> GitHubReleasesParser(int offset,

public static Entry Newest { get; internal set; }
public static bool HasUpdate => Newest != null && Newest.Build > Build;
public static bool UpdateFailed { get; internal set;}

internal static void CheckForUpdateFailure() {
string updateBuildPath = Path.Combine(PathGame, "everest-update", "update-build.txt");
if(!File.Exists(updateBuildPath))
return;

try {
if (Build != int.Parse(File.ReadAllText(updateBuildPath)))
UpdateFailed = true;
} catch(Exception e) {
Logger.Log(LogLevel.Warn, "updater", "Exception when trying to determine update build number");
Logger.LogDetailed(e);
UpdateFailed = true;
} finally {
File.Delete(updateBuildPath);
}
}

public static void Update(OuiLoggedProgress progress, Entry version = null) {
if (!Flags.SupportUpdatingEverest) {
Expand Down Expand Up @@ -355,6 +388,7 @@ private static void _UpdateStart(OuiLoggedProgress progress, Entry version) {
progress.LogLine(Dialog.Clean("EVERESTUPDATER_DOWNLOADFINISHED"));

progress.LogLine(Dialog.Clean("EVERESTUPDATER_EXTRACTING"));
bool isNative = true;
try {
if (extractedPath != PathGame && Directory.Exists(extractedPath))
Directory.Delete(extractedPath, true);
Expand All @@ -374,6 +408,10 @@ private static void _UpdateStart(OuiLoggedProgress progress, Entry version) {
string entryName = entry.FileName;
if (entryName.StartsWith("main/"))
entryName = entryName.Substring(5);

if (entryName == "MiniInstaller.exe")
isNative = false;

string fullPath = Path.Combine(extractedPath, entryName);
string fullDir = Path.GetDirectoryName(fullPath);
if (!Directory.Exists(fullDir))
Expand Down Expand Up @@ -406,24 +444,54 @@ private static void _UpdateStart(OuiLoggedProgress progress, Entry version) {
}
progress.Lines[progress.Lines.Count - 1] = action;

// Start MiniInstaller in a separate process.
try {
// Store the update version for later
File.WriteAllText(Path.Combine(extractedPath, "update-build.txt"), version.Build.ToString());

// Start MiniInstaller in a separate process.
Process installer = new Process();
string installerPath = Path.Combine(extractedPath, "MiniInstaller.exe");
installer.StartInfo.FileName = installerPath;
if (Type.GetType("Mono.Runtime") != null) {
installer.StartInfo.FileName = "mono";
installer.StartInfo.Arguments = $"\"{installerPath}\"";
if (File.Exists("/bin/sh")) {
string pid = Process.GetCurrentProcess().Id.ToString();
installer.StartInfo.FileName = "/bin/sh";
string pathToMono = "mono";
if (File.Exists("/Library/Frameworks/Mono.framework/Versions/Current/Commands/mono")) {
pathToMono = "/Library/Frameworks/Mono.framework/Versions/Current/Commands/mono";

if (!isNative) {
if (Type.GetType("Mono.Runtime") != null) {
// Start MiniInstaller using mono
installer.StartInfo.FileName = "mono";
installer.StartInfo.Arguments = $"\"{installerPath}\"";
if (File.Exists("/bin/sh")) {
string pid = Process.GetCurrentProcess().Id.ToString();
installer.StartInfo.FileName = "/bin/sh";
string pathToMono = "mono";
if (File.Exists("/Library/Frameworks/Mono.framework/Versions/Current/Commands/mono")) {
pathToMono = "/Library/Frameworks/Mono.framework/Versions/Current/Commands/mono";
}
installer.StartInfo.Arguments = $"-c \"kill -0 {pid}; while [ $? = \\\"0\\\" ]; do sleep 1; kill -0 {pid}; done; unset MONO_PATH LD_LIBRARY_PATH LC_ALL MONO_CONFIG; {pathToMono} MiniInstaller.exe\"";
}
installer.StartInfo.Arguments = $"-c \"kill -0 {pid}; while [ $? = \\\"0\\\" ]; do sleep 1; kill -0 {pid}; done; unset MONO_PATH LD_LIBRARY_PATH LC_ALL MONO_CONFIG; {pathToMono} MiniInstaller.exe\"";
}
} else {
// This build ships with native MiniInstaller binaries
installer.StartInfo.FileName = installerPath = Path.Combine(extractedPath,
MonoMod.Utils.PlatformHelper.Is(MonoMod.Utils.Platform.Windows) ?
(MonoMod.Utils.PlatformHelper.Is(MonoMod.Utils.Platform.Bits64) ? "MiniInstaller-win64.exe" : "MiniInstaller-win.exe") :
MonoMod.Utils.PlatformHelper.Is(MonoMod.Utils.Platform.Linux) ? "MiniInstaller-linux" :
MonoMod.Utils.PlatformHelper.Is(MonoMod.Utils.Platform.MacOS) ? "MiniInstaller-osx" :
throw new Exception("Unknown OS platform")
);
installer.StartInfo.UseShellExecute = false;
installer.StartInfo.EnvironmentVariables["EVEREST_UPDATE_CELESTE_PID"] = Process.GetCurrentProcess().Id.ToString();
}

if (!File.Exists(installerPath))
throw new Exception("Couldn't find MiniInstaller executable");

if (isNative && (MonoMod.Utils.PlatformHelper.Is(MonoMod.Utils.Platform.Linux) || MonoMod.Utils.PlatformHelper.Is(MonoMod.Utils.Platform.MacOS))) {
// Make MiniInstaller executable
Process chmodProc = Process.Start(new ProcessStartInfo("chmod", $"u+x \"{installerPath}\""));
chmodProc.WaitForExit();
if (chmodProc.ExitCode != 0)
throw new Exception("Failed to set MiniInstaller executable flag");
}

installer.StartInfo.WorkingDirectory = extractedPath;
if (Environment.OSVersion.Platform == PlatformID.Unix) {
installer.StartInfo.UseShellExecute = false;
Expand Down
3 changes: 3 additions & 0 deletions Celeste.Mod.mm/Mod/Everest/Everest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,9 @@ internal static void Boot() {
// Start requesting the version list ASAP.
Updater.RequestAll();

// Check if an update failed
Updater.CheckForUpdateFailure();

// Request the mod update list as well.
ModUpdaterHelper.RunAsyncCheckForModUpdates(excludeBlacklist: true);

Expand Down
4 changes: 3 additions & 1 deletion Celeste.Mod.mm/Mod/UI/MainMenuModOptionsButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ public MainMenuModOptionsButton(string labelName, string iconName, Oui oui, Vect
// if the update check failed or isn't done yet, assume there are no updates (no message in main menu).
int modUpdatesAvailable = ModUpdaterHelper.IsAsyncUpdateCheckingDone() ? (ModUpdaterHelper.GetAsyncLoadedModUpdates()?.Count ?? 0) : 0;

if (delayedModCount > 1) {
if (Everest.Updater.UpdateFailed) {
subText = Dialog.Clean("MENU_MODOPTIONS_UPDATE_FAILED");
} else if (delayedModCount > 1) {
subText = string.Format(Dialog.Get("MENU_MODOPTIONS_MULTIPLE_MODS_FAILEDTOLOAD"), delayedModCount);
} else if (delayedModCount == 1) {
subText = Dialog.Clean("MENU_MODOPTIONS_ONE_MOD_FAILEDTOLOAD");
Expand Down
38 changes: 30 additions & 8 deletions Celeste.Mod.mm/Mod/UI/OuiDependencyDownloader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ private void downloadAllDependencies() {
// Everest should be updated to satisfy a dependency on Everest
bool shouldUpdateEverestManually = false;

// a mod is .NET Core Everest only
bool requiresNetCoreEverest = false;

// these mods are absent from the database
HashSet<string> modsNotFound = new HashSet<string>();

Expand Down Expand Up @@ -129,6 +132,13 @@ private void downloadAllDependencies() {
shouldUpdateEverestManually = true;
}
}
} else if (dependency.Name == "EverestCore") {
Logger.Log(LogLevel.Verbose, "OuiDependencyDownloader", $"{dependency.Name} requires .NET Core Everest");
shouldUpdateEverestManually = true;
everestVersionToInstall = null;
requiresNetCoreEverest = true;
shouldAutoExit = false;

} else if (tryUnblacklist(dependency, allModsInformation, modFilenamesToUnblacklist)) {
Logger.Log(LogLevel.Verbose, "OuiDependencyDownloader", $"{dependency.Name} is blacklisted, and should be unblacklisted instead");

Expand Down Expand Up @@ -216,7 +226,9 @@ private void downloadAllDependencies() {
}

// display all mods that couldn't be accounted for
if (shouldUpdateEverestManually)
if (requiresNetCoreEverest)
LogLine(Dialog.Clean("DEPENDENCYDOWNLOADER_NEEDS_CORE_EVEREST"));
else if (shouldUpdateEverestManually)
LogLine(Dialog.Clean("DEPENDENCYDOWNLOADER_MUST_UPDATE_EVEREST"));

foreach (string mod in modsNotFound) {
Expand Down Expand Up @@ -358,20 +370,30 @@ private bool isVersionCompatible(Version requiredVersion, string databaseVersion
}

private Everest.Updater.Entry findEverestVersionToInstall(int requestedBuild) {
// Find the entry with the highest build number and the highest priority
Everest.Updater.UpdatePriority updatePrio = Everest.Updater.UpdatePriority.None;
Everest.Updater.Entry updateEntry = null;

foreach (Everest.Updater.Source source in Everest.Updater.Sources) {
if (source?.Entries == null)
if (source?.Entries == null || source?.UpdatePriority is Everest.Updater.UpdatePriority.None)
continue;

foreach (Everest.Updater.Entry entry in source.Entries) {
if (entry.Build >= requestedBuild) {
// we found a suitable build! return it.
return entry;
}
if (entry.Build < requestedBuild)
continue;

if (source.UpdatePriority < updatePrio)
continue;

if (source.UpdatePriority == updatePrio && entry.Build < updateEntry?.Build)
continue;

updatePrio = source.UpdatePriority;
updateEntry = entry;
}
}

// we checked the whole version list and didn't find anything suitable, so...
return null;
return updateEntry;
}

private void downloadDependency(ModUpdateInfo mod, EverestModuleMetadata installedVersion) {
Expand Down
2 changes: 1 addition & 1 deletion Celeste.Mod.mm/Patches/GameLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ private static void checkModSaveDataBackups() {

// skip creating a backup if we are on a develop build
if (previousVersion == new Version(0, 0, 0)) {
Logger.Log(LogLevel.Verbose, "core", "Running in development build, skipping backup");
Logger.Log(LogLevel.Verbose, "core", "Previous Everest version was a development build, skipping backup.");
return;
}

Expand Down

0 comments on commit c6c4a20

Please sign in to comment.