mirror of
https://github.com/ModOrganizer2/modorganizer-NCC.git
synced 2026-07-27 14:00:52 -07:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7fbc9f0770 |
@@ -44,8 +44,13 @@ namespace Nexus.Client.CLI
|
||||
|
||||
public bool DataFileExists(string p_strPath)
|
||||
{
|
||||
string unfixedPath = p_strPath;
|
||||
if (unfixedPath.StartsWith("data", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
unfixedPath = unfixedPath.Substring(5);
|
||||
}
|
||||
foreach (string path in SearchPaths) {
|
||||
if (File.Exists(Path.Combine(path, p_strPath)))
|
||||
if (File.Exists(Path.Combine(path, unfixedPath)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3,10 +3,36 @@ using Nexus.Client.Games;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace Nexus.Client.CLI
|
||||
{
|
||||
public class GameModeInterceptorSelector : IInterceptorSelector
|
||||
{
|
||||
public IInterceptor[] SelectInterceptors(Type type, MethodInfo method, IInterceptor[] interceptors)
|
||||
{
|
||||
if (IsGetter(method))
|
||||
{
|
||||
return interceptors;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsGetter(MethodInfo method)
|
||||
{
|
||||
return method.IsSpecialName && method.Name.StartsWith("get_", StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
private bool IsSetter(MethodInfo method)
|
||||
{
|
||||
return method.IsSpecialName && method.Name.StartsWith("set_", StringComparison.Ordinal);
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
class GameModeInterceptor : IInterceptor
|
||||
{
|
||||
@@ -22,6 +48,7 @@ namespace Nexus.Client.CLI
|
||||
public void Intercept(IInvocation invocation)
|
||||
{
|
||||
invocation.Proceed();
|
||||
|
||||
if (invocation.Method.Name == "get_WritablePaths")
|
||||
{
|
||||
IEnumerable<string> temp = (IEnumerable<string>)invocation.ReturnValue;
|
||||
|
||||
@@ -158,19 +158,6 @@ namespace Nexus.Client.CLI
|
||||
|
||||
IGameMode gameMode = gameModeFactory.BuildGameMode(fileUtil, out warning);
|
||||
|
||||
// use a proxy so we can intercept accesses to the IGameMode interface. This allows us to make the additional search paths accessible from
|
||||
// the sandbox and feed in the script extender version even though the nmm lib won't find it.
|
||||
// This is a massive hack and there is an issue: nmm tries to look up the location of the assembly (for whatever reason) and the proxy
|
||||
// generated here is in a dynamic assembly and thus doesn't have a location. We will therefore feed the proxy only to the script executor
|
||||
// and hope for the best
|
||||
ProxyGenerator generator = new ProxyGenerator();
|
||||
GameModeInterceptor interceptor = new GameModeInterceptor(additionalSearchPaths, seVersion != null ? new Version(seVersion) : null);
|
||||
|
||||
IGameMode gameModeProxied = (IGameMode)generator.CreateClassProxyWithTarget(gameMode.GetType(),
|
||||
gameMode,
|
||||
new object[] { environmentInfo, fileUtil },
|
||||
new IInterceptor[] { interceptor });
|
||||
|
||||
IModCacheManager cacheManager = new NexusModCacheManager(environmentInfo.TemporaryPath, gameMode.GameModeEnvironmentInfo.ModDirectory, fileUtil);
|
||||
|
||||
IScriptTypeRegistry scriptTypeRegistry = ScriptTypeRegistry.DiscoverScriptTypes(Path.Combine(Path.GetDirectoryName(exeLocation), "ScriptTypes"), gameMode);
|
||||
@@ -180,6 +167,16 @@ namespace Nexus.Client.CLI
|
||||
return 2;
|
||||
}
|
||||
|
||||
// use a proxy so we can intercept accesses to the IGameMode interface. This allows us to make the additional search paths accessible from
|
||||
// the sandbox and feed in the script extender version even though the nmm lib won't find it.
|
||||
// This has to happen after DiscoverScriptTypes becaus that function tries to localize the assembly which fails for the dynamic assembly
|
||||
// of the proxy. Fortunately DiscoverScriptTypes has no side-effects on the gameMode.
|
||||
// This recreates the gamemode object so it's important no code above modifies gameMode
|
||||
ProxyGenerator generator = new ProxyGenerator();
|
||||
GameModeInterceptor interceptor = new GameModeInterceptor(additionalSearchPaths, seVersion != null ? new Version(seVersion) : null);
|
||||
|
||||
gameMode = (IGameMode)generator.CreateClassProxy(gameMode.GetType(), new object[] { environmentInfo, fileUtil }, new IInterceptor[] { interceptor });
|
||||
|
||||
IModFormatRegistry formatRegistry = ModFormatRegistry.DiscoverFormats(cacheManager, scriptTypeRegistry, Path.Combine(Path.GetDirectoryName(exeLocation), "ModFormats"));
|
||||
if (formatRegistry.Formats.Count == 0)
|
||||
{
|
||||
@@ -220,7 +217,7 @@ namespace Nexus.Client.CLI
|
||||
IGameSpecificValueInstaller gameSpecificValueInstaller = gameMode.GetGameSpecificValueInstaller(mod, installLog, fileManager, new NexusFileUtil(environmentInfo), delegate { return OverwriteResult.No; });
|
||||
IModFileInstaller fileInstaller = new ModFileInstaller(gameMode.GameModeEnvironmentInfo, mod, installLog, pluginManager, dataFileUtility, fileManager, delegate { return OverwriteResult.No; }, false);
|
||||
InstallerGroup installers = new InstallerGroup(dataFileUtility, fileInstaller, iniIniInstaller, gameSpecificValueInstaller, pluginManager);
|
||||
IScriptExecutor executor = mod.InstallScript.Type.CreateExecutor(mod, gameModeProxied, environmentInfo, installers, SynchronizationContext.Current);
|
||||
IScriptExecutor executor = mod.InstallScript.Type.CreateExecutor(mod, gameMode, environmentInfo, installers, SynchronizationContext.Current);
|
||||
// read-only transactions are waaaay faster, especially for solid archives) because the extractor isn't recreated for every extraction (why exactly would it be otherwise?)
|
||||
mod.BeginReadOnlyTransaction(fileUtil);
|
||||
// run the script in a second thread and start the main loop in the main thread to ensure we can handle message boxes and the like
|
||||
|
||||
Reference in New Issue
Block a user