Compare commits

...
47 Commits
Author SHA1 Message Date
isanae 707527d264 Merge pull request #7 from isanae/new-versions
Updates for latest NMM compatibility
2020-05-01 01:34:07 -04:00
Silarn 1b96519fb2 Updates for latest NMM compatibility 2020-04-06 09:30:17 -05:00
Chris Bessent d0a4194d55 Merge pull request #6 from ModOrganizer2/2_2_2
Pull in 2.2.2.1 changes
2020-01-13 23:05:09 -07:00
Chris Bessent e954eb9489 Merge pull request #5 from ModOrganizer2/Develop
Stage for release 2.2.2
2020-01-06 05:37:24 -07:00
Silarn 82ff6ae118 Arbitrarily bumping version to cover past changes 2019-08-09 11:37:49 -05:00
Silarn b7268d048f Updating compatibility to 0.70.8 2019-08-09 00:13:42 -05:00
LostDragonist b8cc6b1070 Merge pull request #4 from ModOrganizer2/Develop
Stage for release 2.1.6
2018-12-20 14:04:21 -06:00
Silarn ea91433896 Settings fix for NMM 0.65.10 2018-10-07 22:10:40 -05:00
LostDragonist ed497dd869 Update build for NMM changes 2018-09-26 19:44:53 -05:00
Silarn 989af48f5c Fix variable name so we don't have a null value 2018-09-09 03:13:27 -05:00
Silarn 6e66c2c7e5 Fixes for latest NMM versions 2018-09-09 00:43:09 -05:00
Jeremy Rimpo e6bc8867b2 Merge pull request #3 from Modorganizer2/Develop
Stage for 2.1.3 release
2018-05-08 12:22:53 -05:00
Silarn 3980559fe7 Support for newer NMM versions 2018-05-01 03:50:33 -05:00
Brian Munro 9ffc4d1089 Merge pull request #2 from Modorganizer2/Develop
Merge to Master for Release
2018-04-13 08:44:14 +02:00
Jeremy Rimpo 5dc5c81e36 Merge pull request #1 from Silarn/mainline-dev
C# FOMOD Improvements
2018-03-14 17:18:05 -05:00
Jeremy Rimpo 1616dd5f03 Rework file installer to prevent thread hangs and utilize 7z's threading 2018-03-14 17:16:08 -05:00
Jeremy Rimpo 8b3b82bc6e Preextract the archive so that installation is faster. 2018-03-14 17:16:08 -05:00
Jeremy Rimpo b4fd1b6944 Fix boss/loot dll paths for publishing 2018-03-14 17:16:08 -05:00
Jeremy Rimpo 0d2af775fe Merge pull request #4 from SuperSandro2000/master
Changed lz4 path to var
2018-03-08 16:46:46 -06:00
Sandro Jäckel e53cf69253 Moved all NCC and NMM out of the nmm folder. 2018-03-08 20:04:09 +01:00
Brian Munro c85cfe9a8a Merge pull request #3 from erasmux/master
fix copying of GameModes\data
2017-12-21 08:31:57 +02:00
Eran Mizrahi 107e7455bb fix copying of GameModes\data 2017-12-19 11:24:14 +02:00
Brian Munro 906cf86a41 Merge pull request #2 from Silarn/mainline-dev
Fix dll paths
2017-12-10 19:29:58 +02:00
Jeremy Rimpo 3700460597 Fix dll paths 2017-12-09 23:32:48 -06:00
Brian Munro 88852c1440 Merge pull request #1 from Silarn/mainline-dev
Fixes most problems with the NCC installer (including 32-bit)
2017-12-09 09:37:34 +02:00
Jeremy Rimpo 807eb842dd Add necessary boss and loot DLLs to the publish scripts 2017-12-08 17:08:50 -06:00
Jeremy Rimpo 3857e3b0f1 Defer read only xaction to installer - prevent some FOMODs from hanging 2017-12-08 16:42:11 -06:00
Jeremy Rimpo 8b2837ecea Update Castle build 2017-12-08 16:07:22 -06:00
LePresidente abb1d33042 Updated location of NexusClientCli.exe. 2017-05-04 12:56:10 +02:00
Brian Munro d5773c1850 updated sln file to match lastest NMM project. 2016-11-26 14:48:32 +02:00
Brian Munro 5004b71e96 Updated plublish.bat file to work with latest changes. 2016-11-26 13:35:09 +02:00
Rob Nelson 9ce6d1ab25 Update dependencies 2016-11-15 14:44:53 -08:00
Rob Nelson c8d6ad61a3 Fixed for latest NMM API. 2016-11-15 13:37:01 -08:00
Tannin 097cd233aa updated to work with current nmm code 2016-06-01 19:31:03 +02:00
Tannin 3f4717922e some fixes for new directory structure 2015-11-25 19:36:16 +01:00
Tannin 4557bc64c7 changed directory structure 2015-11-21 11:46:14 +01:00
TanninOne daf39f0347 Update README.txt 2015-10-06 20:07:01 +02:00
convert-repo 2c2a77edf4 update tags 2015-09-07 17:37:11 +00:00
Tannin 5fa02a3045 small stuff in preparation of release 2015-05-31 00:36:16 +02:00
Tannin 53a94be2fd - NCC now built to use "modern" controls 2015-05-24 18:41:21 +02:00
Tannin e61f4aff90 Merge with branch1.2 2015-01-24 19:34:12 +01:00
Tannin 7fbc9f0770 - bugfix: some fomod installers still didn't "see" other installed files
- bugfix: the way the gamemode-proxy was installed caused inconsistent data in some calls (since 1.2.15)
2015-01-11 11:12:15 +01:00
Tannin 3ba23e0a80 Merge with branch1.2 2015-01-03 15:58:52 +01:00
Tannin 66a91265c8 - bugfix: after last commit the NCC installer wasn't able to discover files in the mod being installed 2014-12-14 16:23:40 +01:00
Tannin 89500bc02e - NCC installer can now discover files in other mods (thanks Reunion!) and knows the script extender version 2014-12-13 16:47:11 +01:00
TheBloke e58be3d748 Updated NCC deploy method, in BossDummy.pro -
Replaced publish.bat with a new Powershell script, publish.ps1
 This has the advantage of allowing the setting of "stop on any error"
  (using $ErrorActionPreference = "Stop")
  Therefore, if any file is not created by the (separate) NCC process, the
   MO build will stop and you will know immediately that not all files are OK.
 Updated the rules in publish.ps1 to remove references to the (old) .Net
  BossDummy files, and also NexusClientCLI.exe.manifest which is not created.
 Usage of publish.ps1 -
   publish.ps1 <-debug|-release>
 Passing -debug or -release sets the appropriate output directory
2014-07-07 20:43:41 +01:00
Tannin 8bf91045b5 - NCC will now report an error if a script tries to extract a non-existent file instead of creating an empty output file
- ncc installer plugin now uses a more reliable method to force the installer window to the foreground
- missing version on TESV.exe will no longer be reported as an error
- bugfix: loot client didn't read list of active mods
- bugfix: invalid free call in error reporting function
2014-05-15 19:11:19 +02:00
41 changed files with 9531 additions and 1321 deletions
+5
View File
@@ -0,0 +1,5 @@
/nmm
/NexusClientCLI/obj
/.vs
/.idea
/*.log
+845
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
+14
View File
@@ -0,0 +1,14 @@
Copyright 2004-2014 Castle Project - http://www.castleproject.org/
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+95
View File
@@ -0,0 +1,95 @@
/* This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
using System;
using System.IO;
using System.Linq;
using System.Text;
using Nexus.Client.ModManagement.Scripting;
using System.Collections.Generic;
namespace Nexus.Client.CLI
{
/// <summary>
/// Provides access to some files in previously installed mods' installation path.
/// </summary>
class DummyDataFileUtil : IDataFileUtil
{
private string m_gamePath;
private DataFileUtil m_dataFileUtil;
protected List<string> SearchPaths { get; set; }
// To be used internally by DummyDataFileUtilFactory
// Use DummyDataFileUtilFactory.CreateDummyDataFileUtil() to instantiate
internal DummyDataFileUtil(string installationPath, string gamePath, List<string> installationPaths)
{
m_gamePath = gamePath;
m_dataFileUtil = new DataFileUtil(installationPath);
SearchPaths = installationPaths;
}
public void AssertFilePathIsSafe(string p_strPath)
{
m_dataFileUtil.AssertFilePathIsSafe(p_strPath);
}
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, unfixedPath)))
{
return true;
}
}
return false;
}
public string[] GetExistingDataFileList(string p_strPath, string p_strPattern, bool p_booAllFolders)
{
// Not implemented
// Will implement if needed
return new string[] {};
}
public byte[] GetExistingDataFile(string p_strPath)
{
AssertFilePathIsSafe(p_strPath);
if (p_strPath.StartsWith("data", StringComparison.OrdinalIgnoreCase))
{
foreach (string path in SearchPaths)
{
string dataPath = Path.Combine(path, p_strPath.Substring(5));
Console.WriteLine("test: " + dataPath + " - " + File.Exists(dataPath));
if (File.Exists(dataPath))
{
return File.ReadAllBytes(dataPath);
}
}
}
else
{
string dataPath = Path.Combine(m_gamePath, p_strPath);
if (File.Exists(dataPath))
{
return File.ReadAllBytes(dataPath);
}
}
throw new FileNotFoundException();
}
}
}
@@ -0,0 +1,75 @@
/* This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace Nexus.Client.CLI
{
class DummyDataFileUtilFactory
{
private string m_installationPath;
private string m_gamePath;
private List<string> m_searchPaths = new List<string>();
/// <summary>
/// Creates an instance of DummyDataFileUtilFactory.
/// </summary>
/// <param name="installationPath">The path where the current mod is being installed</param>
/// <param name="modlistFile">The path to the modlist.txt file</param>
/// <param name="modsPath">The path to the mods directory where previously installed mods are located</param>
public DummyDataFileUtilFactory(string installationPath, string modlistFile, string modsPath, string gamePath, List<string> additionalSearchPaths)
{
m_installationPath = installationPath;
m_gamePath = gamePath;
m_searchPaths = additionalSearchPaths;
m_searchPaths.Add(Path.Combine(m_installationPath, "data"));
StreamReader reader = new StreamReader(modlistFile);
string line;
while ((line = reader.ReadLine()) != null)
{
// A mod name per line
// Handle only activated mods (ignore inactive and unmanaged)
if (line[0] == '+')
{
string modName = line.Substring(1);
string modPath = Path.Combine(modsPath, modName);
// Ignore mod when it is being reinstalled
// That folder has no relevant data files anyway
// This happens when an activated mod is being reinstalled
if (modPath.Equals(m_installationPath, StringComparison.InvariantCultureIgnoreCase))
{
Logger.Debug("Ignoring mod {0} that appears to be the one that is being installed", modName);
}
else
{
m_searchPaths.Add(modPath);
}
}
}
}
/// <summary>
/// Create a new instance DummyDataFileUtil that will use the dummy data folder created by this factory.
/// </summary>
/// <returns>New instance of DummyDataFileUtil</returns>
public DummyDataFileUtil CreateDummyDataFileUtil()
{
return new DummyDataFileUtil(m_installationPath, m_gamePath, m_searchPaths);
}
}
}
@@ -21,15 +21,15 @@ using Nexus.Client.ModManagement.InstallationLog;
namespace Nexus.Client.ModManagement.InstallationLog
{
class DummyInstallLog : IInstallLog
{
private Dictionary<string, Pair<IMod, string> > m_InstalledFiles = null;
public partial class DummyInstallLog : IInstallLog
{
private Dictionary<string, Pair<IMod, string>> m_InstalledFiles = null;
private Set<string> m_UsedKeys = null;
public DummyInstallLog()
{
m_InstalledFiles = new Dictionary<string, Pair<IMod, string>>();
m_UsedKeys = new Set<string>();
}
@@ -100,44 +100,44 @@ namespace Nexus.Client.ModManagement.InstallationLog
}
public void AddIniEdit(IMod p_modInstallingMod, string p_strSettingsFileName, string p_strSection, string p_strKey, string p_strValue)
{
// nop
}
{
// nop
}
public void ReplaceIniEdit(IMod p_modInstallingMod, string p_strSettingsFileName, string p_strSection, string p_strKey, string p_strValue)
{
// nop
}
public void ReplaceIniEdit(IMod p_modInstallingMod, string p_strSettingsFileName, string p_strSection, string p_strKey, string p_strValue)
{
// nop
}
public void RemoveIniEdit(IMod p_modInstallingMod, string p_strSettingsFileName, string p_strSection, string p_strKey)
{
// nop
}
public void RemoveIniEdit(IMod p_modInstallingMod, string p_strSettingsFileName, string p_strSection, string p_strKey)
{
// nop
}
public IMod GetCurrentIniEditOwner(string p_strSettingsFileName, string p_strSection, string p_strKey)
{
return null;
}
public IMod GetCurrentIniEditOwner(string p_strSettingsFileName, string p_strSection, string p_strKey)
{
return null;
}
public string GetCurrentIniEditOwnerKey(string p_strSettingsFileName, string p_strSection, string p_strKey)
{
return null;
}
public string GetCurrentIniEditOwnerKey(string p_strSettingsFileName, string p_strSection, string p_strKey)
{
return null;
}
public string GetPreviousIniValue(string p_strSettingsFileName, string p_strSection, string p_strKey)
{
return null;
}
public string GetPreviousIniValue(string p_strSettingsFileName, string p_strSection, string p_strKey)
{
return null;
}
public void LogOriginalIniValue(string p_strSettingsFileName, string p_strSection, string p_strKey, string p_strValue)
{
// nop
}
public void LogOriginalIniValue(string p_strSettingsFileName, string p_strSection, string p_strKey, string p_strValue)
{
// nop
}
public IList<IniEdit> GetInstalledIniEdits(IMod p_modInstaller)
{
return null;
}
public IList<IniEdit> GetInstalledIniEdits(IMod p_modInstaller)
{
return null;
}
public IList<IMod> GetIniEditInstallers(string p_strSettingsFileName, string p_strSection, string p_strKey)
{
@@ -156,18 +156,18 @@ namespace Nexus.Client.ModManagement.InstallationLog
}
public void AddDataFile(IMod p_modInstallingMod, string p_strDataFilePath)
{
{
string key = GenerateKey();
m_InstalledFiles[p_strDataFilePath.ToLower()] = new Pair<IMod, string>(p_modInstallingMod, key);
}
}
public void RemoveDataFile(IMod p_modInstallingMod, string p_strDataFilePath)
{
public void RemoveDataFile(IMod p_modInstallingMod, string p_strDataFilePath)
{
m_InstalledFiles.Remove(p_strDataFilePath.ToLower());
}
}
public IMod GetCurrentFileOwner(string p_strPath)
{
public IMod GetCurrentFileOwner(string p_strPath)
{
string strPathLower = p_strPath.ToLower();
if (m_InstalledFiles.ContainsKey(strPathLower))
{
@@ -177,15 +177,15 @@ namespace Nexus.Client.ModManagement.InstallationLog
{
return null;
}
}
}
public IMod GetPreviousFileOwner(string p_strPath)
{
return null;
}
public IMod GetPreviousFileOwner(string p_strPath)
{
return null;
}
public string GetCurrentFileOwnerKey(string p_strPath)
{
public string GetCurrentFileOwnerKey(string p_strPath)
{
string strPathLower = p_strPath.ToLower();
if (m_InstalledFiles.ContainsKey(strPathLower))
{
@@ -197,18 +197,18 @@ namespace Nexus.Client.ModManagement.InstallationLog
}
}
public string GetPreviousFileOwnerKey(string p_strPath)
{
return null;
}
public string GetPreviousFileOwnerKey(string p_strPath)
{
return null;
}
public void LogOriginalDataFile(string p_strDataFilePath)
{
// nop
}
public void LogOriginalDataFile(string p_strDataFilePath)
{
// nop
}
public IList<string> GetInstalledModFiles(IMod p_modInstaller)
{
public IList<string> GetInstalledModFiles(IMod p_modInstaller)
{
Set<string> result = new Set<string>();
foreach (KeyValuePair<string, Pair<IMod, string>> file in m_InstalledFiles)
{
@@ -217,8 +217,8 @@ namespace Nexus.Client.ModManagement.InstallationLog
result.Add(file.Key);
}
}
return result;
}
return result;
}
public IList<IMod> GetFileInstallers(string p_strPath)
{
@@ -232,24 +232,26 @@ namespace Nexus.Client.ModManagement.InstallationLog
}
public void AddActiveMod(IMod p_modMod)
{
// nop
}
{
// nop
}
public void ReplaceActiveMod(IMod p_modOldMod, IMod p_modNewMod)
{
// nop
}
public void ReplaceActiveMod(IMod p_modOldMod, IMod p_modNewMod)
{
// nop
}
public string GetModKey(IMod p_modMod)
{
return null;
}
public string GetModKey(IMod p_modMod)
{
return null;
}
/* protected IMod GetMod(string p_strKey)
{
return null;
}*/
/*
protected IMod GetMod(string p_strKey)
{
return null;
}
*/
public IEnumerable<KeyValuePair<IMod, IMod>> GetMismatchedVersionMods()
{
@@ -265,5 +267,20 @@ namespace Nexus.Client.ModManagement.InstallationLog
{
// nop
}
public byte[] GetXmlModList()
{
return null;
}
public byte[] GetXmlIniList()
{
return null;
}
public IInstallLog ReInitialize(string p_strLogPath)
{
return this; // ???
}
}
}
+23
View File
@@ -0,0 +1,23 @@
using Nexus.Client.ModManagement;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Nexus.Client.CLI
{
class DummyModLinkInstaller : IModLinkInstaller
{
public string AddFileLink(Mods.IMod p_modMod, string p_strBaseFilePath, string p_strSourceFile, bool p_booIsSwitching)
{
return AddFileLink(p_modMod, p_strBaseFilePath, p_strSourceFile, p_booIsSwitching, false);
}
public string AddFileLink(Mods.IMod p_modMod, string p_strBaseFilePath, string p_strSourceFile, bool p_booIsSwitching, bool p_booHandlePlugin)
{
// nop, linking is done by MO
return string.Empty;
}
}
}
@@ -19,6 +19,8 @@ using Nexus.Client.Plugins;
using Nexus.Client.Util.Collections;
using Nexus.Client.Games;
using Nexus.Client.Mods;
using Nexus.Client.UI;
using Nexus.Client.BackgroundTasks;
namespace Nexus.Client.PluginManagement
@@ -31,8 +33,8 @@ namespace Nexus.Client.PluginManagement
public DummyPluginManager(string pluginsFile, IGameMode gameMode, IMod mod)
{
StreamReader reader = new StreamReader(pluginsFile);
string installationPath = Path.Combine(gameMode.GameModeEnvironmentInfo.InstallationPath, gameMode.GetModFormatAdjustedPath(mod.Format, null));
string installationPath = Path.Combine(gameMode.GameModeEnvironmentInfo.InstallationPath, gameMode.GetModFormatAdjustedPath(mod.Format, null, false));
string line;
while ((line = reader.ReadLine()) != null)
@@ -57,12 +59,12 @@ namespace Nexus.Client.PluginManagement
#region Properties
public ReadOnlyObservableList<Plugin> ManagedPlugins
{
get
{
{
get
{
return m_ROOLPlugins;
}
}
}
}
public ReadOnlyObservableList<Plugin> ActivePlugins
{
@@ -90,6 +92,16 @@ namespace Nexus.Client.PluginManagement
// nop
}
public IBackgroundTask AutoPluginSorting(ConfirmActionMethod p_camConfirm)
{
return null;
}
public IBackgroundTask ManageMultiplePluginsTask(List<Plugin> p_lstPlugins, bool p_booEnable, ConfirmActionMethod p_camConfirm)
{
return null;
}
public bool IsPluginRegistered(string p_strPath)
{
return false;
@@ -173,16 +185,33 @@ namespace Nexus.Client.PluginManagement
{
return false;
}
public bool CanActivatePlugins()
{
return true;
return true;
}
public int MaxAllowedActivePluginsCount
{
get
{
return 255;
}
}
public List<Plugin> GetOrphanedPlugins(string p_strMasterName)
{
return null;
}
public string GetPluginDescription(string p_strPlugin)
{
return null;
}
public IBackgroundTask ApplyLoadOrder(Dictionary<Plugin, string> p_kvpRegisteredPlugins, bool p_booSortingOnly)
{
return null;
}
public int MaxAllowedActivePluginsCount {
get {
return 255;
}
}
}
}
+302
View File
@@ -0,0 +1,302 @@
using Nexus.Client.ModManagement;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Nexus.Client.BackgroundTasks;
using Nexus.Client.UI;
namespace Nexus.Client.CLI
{
class DummyVirtualModActivator : IVirtualModActivator
{
public event EventHandler ModActivationChanged;
protected IEnvironmentInfo EnvironmentInfo { get; private set; }
public bool MultiHDMode
{
get { return false; }
}
public bool Initialized
{
get { return true; }
}
public bool DisableLinkCreation
{
get { return false; }
}
public bool DisableIniLogging
{
get { return true; }
}
public string VirtualPath
{
get
{
//string[] components = EnvironmentInfo.Settings.InstallationPaths[GameMode.ModeId].Split(Path.DirectorySeparatorChar);
//return components[components.Length - 1];
return "";
}
}
public string HDLinkFolder
{
get { throw new NotImplementedException(); }
}
public Util.Collections.ThreadSafeObservableList<IVirtualModLink> VirtualLinks
{
get { throw new NotImplementedException(); }
}
public Util.Collections.ThreadSafeObservableList<IVirtualModInfo> VirtualMods
{
get { throw new NotImplementedException(); }
}
public IEnumerable<string> ActiveModList
{
get { throw new NotImplementedException(); }
}
public int ModCount
{
get { throw new NotImplementedException(); }
}
public Games.IGameMode GameMode { get; private set; }
public DummyVirtualModActivator(Games.IGameMode gameMode, IEnvironmentInfo environment)
{
GameMode = gameMode;
EnvironmentInfo = environment;
}
public void Initialize()
{
throw new NotImplementedException();
}
public void Setup()
{
throw new NotImplementedException();
}
public void Reset()
{
throw new NotImplementedException();
}
public void SaveList()
{
throw new NotImplementedException();
}
public void SetCurrentList(IList<IVirtualModLink> p_ilvVirtualLinks)
{
throw new NotImplementedException();
}
public List<IVirtualModLink> LoadList(string p_strXMLFilePath)
{
throw new NotImplementedException();
}
public List<IVirtualModLink> LoadImportedList(string p_strXML)
{
throw new NotImplementedException();
}
public bool LoadListOnDemand(string p_strProfilePath, out List<IVirtualModLink> p_lstVirtualLinks, out List<IVirtualModInfo> p_lstVirtualMods)
{
throw new NotImplementedException();
}
public void SaveModList(string p_strPath)
{
throw new NotImplementedException();
}
public string CheckVirtualLink(string p_strFilePath)
{
throw new NotImplementedException();
}
public int CheckFileLink(string p_strFilePath, out Mods.IMod p_modMod, out List<IVirtualModLink> lstFileLinks)
{
throw new NotImplementedException();
}
public bool PurgeLinks()
{
throw new NotImplementedException();
}
public void AddInactiveLink(Mods.IMod p_modMod, string p_strBaseFilePath, int p_intPriority)
{
throw new NotImplementedException();
}
public string AddFileLink(Mods.IMod p_modMod, string p_strBaseFilePath, bool p_booIsSwitching, bool p_booIsRestoring, int p_intPriority)
{
throw new NotImplementedException();
}
public string AddFileLink(Mods.IMod p_modMod, string p_strBaseFilePath, string p_strSourceFile, bool p_booIsSwitching, bool p_booIsRestoring, bool p_booHandlePlugin, int p_intPriority)
{
throw new NotImplementedException();
}
public void RemoveFileLink(string p_strFilePath, Mods.IMod p_modMod)
{
throw new NotImplementedException();
}
public void RemoveFileLink(IVirtualModLink p_ivlVirtualLink, Mods.IMod p_modMod)
{
throw new NotImplementedException();
}
public void UpdateLinkPriority(IVirtualModLink p_ivlFileLink)
{
throw new NotImplementedException();
}
public void UpdateLinkListPriority(List<IVirtualModLink> lstFileLinks)
{
throw new NotImplementedException();
}
public void DisableMod(Mods.IMod p_modMod)
{
throw new NotImplementedException();
}
public void DisableModFiles(Mods.IMod p_modMod)
{
throw new NotImplementedException();
}
public void FinalizeModDeactivation(Mods.IMod p_modMod)
{
throw new NotImplementedException();
}
public void EnableMod(Mods.IMod p_modMod)
{
throw new NotImplementedException();
}
public void FinalizeModActivation(Mods.IMod p_modMod)
{
throw new NotImplementedException();
}
public void LogIniEdits(Mods.IMod p_modMod, string p_strSettingsFileName, string p_strSection, string p_strKey, string p_strValue)
{
throw new NotImplementedException();
}
public void RestoreIniEdits()
{
throw new NotImplementedException();
}
public void PurgeIniEdits()
{
throw new NotImplementedException();
}
public void ImportIniEdits(string p_strIniXML)
{
throw new NotImplementedException();
}
public void SetNewFolders(string p_strVirtual, string p_strLink, bool? p_booMultiHD)
{
throw new NotImplementedException();
}
public void CheckLinkListIntegrity(IList<IVirtualModLink> p_ivlVirtualLinks, out Dictionary<string, string> p_dicUninstalled, out Dictionary<string, string> p_dicMissing, IList<string> p_lstForced)
{
throw new NotImplementedException();
}
public IModLinkInstaller GetModLinkInstaller()
{
return new DummyModLinkInstaller();
}
public void PurgeMods(List<Mods.IMod> p_lstMods, string p_strPath)
{
throw new NotImplementedException();
}
public bool CheckHasActiveLinks(Mods.IMod p_modMod)
{
throw new NotImplementedException();
}
public string GetCurrentFileOwner(string p_strPath)
{
throw new NotImplementedException();
}
public BackgroundTasks.IBackgroundTask ActivatingMod(Mods.IMod p_modMod, bool p_booDisabling, UI.ConfirmActionMethod p_camConfirm)
{
throw new NotImplementedException();
}
public void SaveModList(string p_strPath, List<IVirtualModInfo> p_lstVirtualModInfo, List<IVirtualModLink> p_lstVirtualModList)
{
throw new NotImplementedException();
}
public string RequiresFixing()
{
throw new NotImplementedException();
}
public string RequiresFixing(string p_strFilePath)
{
throw new NotImplementedException();
}
bool IVirtualModActivator.SaveList()
{
throw new NotImplementedException();
}
public bool SaveList(bool p_booModActivationChange)
{
throw new NotImplementedException();
}
public List<IVirtualModLink> LoadImportedList(string p_strXML, string p_strSavePath)
{
throw new NotImplementedException();
}
public void UpdateDownloadId(string p_strCurrentProfilePath, Dictionary<string, string> p_dctNewDownloadID)
{
throw new NotImplementedException();
}
public void CheckLinkListIntegrity(IList<IVirtualModLink> p_ivlVirtualLinks, out List<IVirtualModInfo> p_lstMissingModInfo, IList<string> p_lstForced)
{
throw new NotImplementedException();
}
public IBackgroundTask FixConfigFiles(List<string> p_lstFiles, IModProfile p_mprProfile, ConfirmActionMethod p_camConfirm)
{
throw new NotImplementedException();
}
}
}
+133
View File
@@ -0,0 +1,133 @@
/* This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
namespace Nexus.Client
{
using System;
using System.IO;
using System.Windows.Forms;
using Microsoft.Win32;
using Nexus.Client.Settings;
using Nexus.Client.Util;
/// <summary>
/// Provides information about the current programme environment.
/// </summary>
public class EnvironmentInfo : IEnvironmentInfo
{
#region Properties
private string m_strApplicationPersonalDataFolderPath = null;
private string m_strPersonalDataFolderPath = null;
private string m_strTempPath = null;
/// <summary>
/// Gets the path to the user's personal data folder.
/// </summary>
/// <value>The path to the user's personal data folder.</value>
public string PersonalDataFolderPath { get; } = null;
/// <summary>
/// Gets the path to the mod manager's folder in the user's personal data folder.
/// </summary>
/// <value>The path to the mod manager's folder in the user's personal data folder.</value>
public string ApplicationPersonalDataFolderPath { get; } = null;
/// <summary>
/// Gets whether the programme is running under the Mono framework.
/// </summary>
/// <value>Whether the programme is running under the Mono framework.</value>
public bool IsMonoMode
{
get
{
return Type.GetType("Mono.Runtime") != null;
}
}
/// <summary>
/// Gets the temporary path used by the application.
/// </summary>
/// <value>The temporary path used by the application.</value>
public string TemporaryPath { get; } = null;
/// <summary>
/// Gets the path to the directory where programme data is stored.
/// </summary>
/// <value>The path to the directory where programme data is stored.</value>
public string ProgrammeInfoDirectory
{
get
{
return Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "data");
}
}
/// <summary>
/// Gets whether the current process is 64bit.
/// </summary>
/// <value>Whether the current process is 64bit.</value>
public bool Is64BitProcess
{
get
{
return (IntPtr.Size == 8);
}
}
/// <summary>
/// Gets the application and user settings.
/// </summary>
/// <value>The application and user settings.</value>
public ISettings Settings { get; private set; }
/// <summary>
/// Gets the version of the running application.
/// </summary>
/// <value>The version of the running application.</value>
public Version ApplicationVersion
{
get
{
return new Version(CommonData.VersionString);
}
}
#endregion
#region Constructors
/// <summary>
/// A simple constructor that initializes the object with the given dependencies.
/// </summary>
/// <param name="p_setSettings">The application and user settings.</param>
public EnvironmentInfo(ISettings p_setSettings)
{
Settings = p_setSettings;
PersonalDataFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
if (String.IsNullOrEmpty(PersonalDataFolderPath))
PersonalDataFolderPath = Registry.GetValue(@"HKEY_CURRENT_USER\software\microsoft\windows\currentversion\explorer\user shell folders", "Personal", null).ToString();
if (String.IsNullOrEmpty(Settings.TempPathFolder))
{
TemporaryPath = Path.Combine(Path.GetTempPath(), Application.ProductName);
if (!Directory.Exists(TemporaryPath))
Directory.CreateDirectory(TemporaryPath);
}
else
TemporaryPath = Settings.TempPathFolder;
ApplicationPersonalDataFolderPath = Path.Combine(PersonalDataFolderPath, CommonData.ModManagerName);
}
#endregion
}
}
+64
View File
@@ -0,0 +1,64 @@
using Castle.DynamicProxy;
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
{
private List<string> m_AdditionalWritablePaths;
private Version m_ExtenderVersion;
public GameModeInterceptor(List<string> additionalWritablePaths, Version extenderVersion)
{
m_AdditionalWritablePaths = additionalWritablePaths;
m_ExtenderVersion = extenderVersion;
}
public void Intercept(IInvocation invocation)
{
invocation.Proceed();
if (invocation.Method.Name == "get_WritablePaths")
{
IEnumerable<string> temp = (IEnumerable<string>)invocation.ReturnValue;
invocation.ReturnValue = temp.Concat(m_AdditionalWritablePaths);
}
else if (invocation.Method.Name == "get_ScriptExtenderVersion")
{
if (invocation.ReturnValue == null)
invocation.ReturnValue = m_ExtenderVersion;
}
}
}
}
+135
View File
@@ -0,0 +1,135 @@
/* This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Reflection;
namespace Nexus.Client.CLI
{
class Logger
{
public enum Level
{
None = 0,
Error = 1,
Warning = 2,
Info = 3,
Debug = 4,
Fine = 5,
// Place finer levels here if needed
All = 9
}
private const string s_logfileName = "NexusClientCLI.log";
private static string s_logfilePath = null;
private static Level s_maxVerbosity = Level.None;
public static void SetVerbosity(Level verbostity)
{
s_maxVerbosity = verbostity;
}
public static void SetLogDestination(string path)
{
s_logfilePath = Path.Combine(path, s_logfileName);
}
public static void Error(String msg)
{
if (IsLevelLoggable(Level.Error))
WriteMessage(Level.Error, msg);
}
public static void Error(String fmt, Object arg)
{
if (IsLevelLoggable(Level.Error))
WriteMessage(Level.Error, String.Format(fmt, arg));
}
public static void Warning(String msg)
{
if (IsLevelLoggable(Level.Warning))
WriteMessage(Level.Warning, msg);
}
public static void Warning(String fmt, Object arg)
{
if (IsLevelLoggable(Level.Warning))
WriteMessage(Level.Warning, String.Format(fmt, arg));
}
public static void Info(String msg)
{
if (IsLevelLoggable(Level.Info))
WriteMessage(Level.Info, msg);
}
public static void Info(String fmt, Object arg)
{
if (IsLevelLoggable(Level.Info))
WriteMessage(Level.Info, String.Format(fmt, arg));
}
public static void Debug(String msg)
{
if (IsLevelLoggable(Level.Debug))
WriteMessage(Level.Debug, msg);
}
public static void Debug(String fmt, Object arg)
{
if (IsLevelLoggable(Level.Debug))
WriteMessage(Level.Debug, String.Format(fmt, arg));
}
public static void Fine(String msg)
{
if (IsLevelLoggable(Level.Fine))
WriteMessage(Level.Fine, msg);
}
public static void Fine(String fmt, Object arg)
{
if (IsLevelLoggable(Level.Fine))
WriteMessage(Level.Fine, String.Format(fmt, arg));
}
public static bool IsLevelLoggable(Level level)
{
return level <= s_maxVerbosity;
}
private static void WriteMessage(Level level, string msg)
{
try
{
string output = string.Format("[{0}] {1}{2}", level, msg, Environment.NewLine);
if (s_logfilePath != null) {
File.AppendAllText(s_logfilePath, output);
}
else
{
Console.WriteLine(output);
}
}
catch (Exception)
{
// Ignore exception
}
}
}
}
@@ -1,4 +1,4 @@
using Nexus.Client.Mods;
/*using Nexus.Client.Mods;
//using Nexus.Client.Mods.Formats.FOMod;
//using Nexus.Client.Mods.Formats.OMod;
using Nexus.Client.Util;
@@ -78,19 +78,6 @@ namespace Extensions
}
}
/// <summary>
/// write the specified file to a stream
/// </summary>
/// <param name="p_strFile">The file to retrieve.</param>
/// <param name="p_outStream">The stream to write to.</param>
/// <exception cref="System.IO.FileNotFoundException">Thrown if the specified file
/// is not in the mod.</exception>
/* public static void ExtractFileTo(this OMod mod, string p_strFile, Stream p_outStream)
{
byte[] data = mod.GetFile(p_strFile);
p_outStream.Write(data, 0, data.Length);
} */
/// <summary>
/// write the specified file to a stream
/// </summary>
@@ -122,4 +109,4 @@ namespace Extensions
}
}
*/
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Nexus.Client.ModManagement.Scripting;
using Nexus.Client.ModManagement.InstallationLog;
using Nexus.Client.Mods;
@@ -8,7 +9,9 @@ using Nexus.Client.PluginManagement;
using Nexus.Client.Util;
using Nexus.Client.Games;
using ChinhDo.Transactions;
using Extensions;
using SevenZip;
//using Extensions;
using System.Text.RegularExpressions;
namespace Nexus.Client.ModManagement
{
@@ -67,6 +70,18 @@ namespace Nexus.Client.ModManagement
/// <value>true or false.</value>
protected bool IsPlugin { get; private set; }
protected string ExtractPath { get; private set; }
protected string Prefix { get; private set; }
protected Dictionary<string, ArchiveFileInfo> TargetFiles { get; private set; }
protected List<string> IgnoreFolders = new List<string> { "__MACOSX" };
protected IList<string> StopFolders { get; private set; }
private Dictionary<string, string> m_dicMovedArchiveFiles = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
private List<string> m_strFiles = null;
private Dictionary<string, ArchiveFileInfo> m_dicFileInfo = null;
#endregion
#region Constructors
@@ -82,7 +97,7 @@ namespace Nexus.Client.ModManagement
/// <param name="p_tfmFileManager">The transactional file manager to use to interact with the file system.</param>
/// <param name="p_dlgOverwriteConfirmationDelegate">The method to call in order to confirm an overwrite.</param>
/// <param name="p_UsesPlugins">Whether the file is a mod or a plugin.</param>
public ModFileInstaller(IGameModeEnvironmentInfo p_gmiGameModeInfo, IMod p_modMod, IInstallLog p_ilgInstallLog, IPluginManager p_pmgPluginManager, IDataFileUtil p_dfuDataFileUtility, TxFileManager p_tfmFileManager, ConfirmItemOverwriteDelegate p_dlgOverwriteConfirmationDelegate, bool p_UsesPlugins)
public ModFileInstaller(IGameModeEnvironmentInfo p_gmiGameModeInfo, IMod p_modMod, IInstallLog p_ilgInstallLog, IPluginManager p_pmgPluginManager, IDataFileUtil p_dfuDataFileUtility, TxFileManager p_tfmFileManager, ConfirmItemOverwriteDelegate p_dlgOverwriteConfirmationDelegate, bool p_UsesPlugins, string p_extractPath, IEnumerable<string> p_stopFolders)
{
GameModeInfo = p_gmiGameModeInfo;
Mod = p_modMod;
@@ -90,8 +105,18 @@ namespace Nexus.Client.ModManagement
PluginManager = p_pmgPluginManager;
DataFileUtility = p_dfuDataFileUtility;
TransactionalFileManager = p_tfmFileManager;
TargetFiles = new Dictionary<string, ArchiveFileInfo>();
m_dlgOverwriteConfirmationDelegate = p_dlgOverwriteConfirmationDelegate ?? ((s, b, m) => OverwriteResult.No);
IsPlugin = p_UsesPlugins;
ExtractPath = p_extractPath;
StopFolders = new List<string>(p_stopFolders);
if (!StopFolders.Contains("fomod", StringComparer.OrdinalIgnoreCase))
StopFolders.Add("fomod");
Archive archive = new Archive(Mod.ModArchivePath);
Prefix = FindPathPrefix(archive);
m_dicFileInfo = new Dictionary<string, ArchiveFileInfo>(StringComparer.OrdinalIgnoreCase);
m_strFiles = new List<string>();
LoadFileIndices();
}
#endregion
@@ -192,78 +217,167 @@ namespace Nexus.Client.ModManagement
/// <param name="p_strInstallPath">The path on the file system where the file is to be installed.</param>
/// <returns><c>true</c> if the file was written; <c>false</c> if the user chose
/// not to overwrite an existing file.</returns>
public bool InstallFileFromMod(string p_strModFilePath, string p_strInstallPath, bool p_booSecondaryInstallPath)
public bool InstallFileFromMod(string p_strModFilePath, string p_strInstallPath)
{
string destinationPath = installPath(p_strInstallPath, p_booSecondaryInstallPath);
if (!Directory.Exists(Path.GetDirectoryName(destinationPath)))
TransactionalFileManager.CreateDirectory(Path.GetDirectoryName(destinationPath));
else
try
{
if (!TestDoOverwrite(p_strInstallPath))
return false;
string filePath = GetRealPath(p_strModFilePath);
string extractPath = Path.Combine(ExtractPath, filePath);
Directory.CreateDirectory(Path.GetDirectoryName(extractPath));
string strPath = filePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
if (File.Exists(destinationPath))
{
FileInfo Info = new FileInfo(destinationPath);
if (Info.IsReadOnly == true)
File.SetAttributes(destinationPath, File.GetAttributes(destinationPath) & ~FileAttributes.ReadOnly);
string strInstallDirectory = Path.GetDirectoryName(p_strInstallPath);
string strBackupDirectory = Path.Combine(GameModeInfo.OverwriteDirectory, strInstallDirectory);
string strOldModKey = InstallLog.GetCurrentFileOwnerKey(p_strInstallPath);
if (strOldModKey == null)
{
InstallLog.LogOriginalDataFile(p_strInstallPath);
strOldModKey = InstallLog.OriginalValuesKey;
}
string strInstallingModKey = InstallLog.GetModKey(Mod);
//if this mod has installed this file already we just replace it and don't
// need to back it up.
if (!strOldModKey.Equals(strInstallingModKey))
{
//back up the current version of the file if the current mod
// didn't install it
if (!Directory.Exists(strBackupDirectory))
TransactionalFileManager.CreateDirectory(strBackupDirectory);
//we get the file name this way in order to preserve the file name's case
string strFile = Path.GetFileName(Directory.GetFiles(Path.GetDirectoryName(destinationPath), Path.GetFileName(destinationPath))[0]);
strFile = strOldModKey + "_" + strFile;
string strBackupFilePath = Path.Combine(strBackupDirectory, strFile);
Info = new FileInfo(strBackupFilePath);
if ((Info.IsReadOnly == true) && (File.Exists(strBackupFilePath)))
File.SetAttributes(strBackupFilePath, File.GetAttributes(strBackupFilePath) & ~FileAttributes.ReadOnly);
TransactionalFileManager.Copy(destinationPath, strBackupFilePath, true);
}
TransactionalFileManager.Delete(destinationPath);
}
ArchiveFileInfo afiFile = m_dicFileInfo[strPath];
TargetFiles[p_strInstallPath] = afiFile;
return true;
}
using (FileStream stream = File.Create(destinationPath))
catch (Exception)
{
Mod.ExtractFileTo(p_strModFilePath, stream);
return false;
}
// Checks whether the file is a gamebryo plugin
if (IsPlugin)
if (PluginManager.IsActivatiblePluginFile(destinationPath))
PluginManager.AddPlugin(destinationPath);
InstallLog.AddDataFile(Mod, p_strInstallPath);
return IsPlugin;
}
private string installPath(string installPath, bool useSecondaryInstallPath)
protected string GetRealPath(string p_strPath)
{
string strPath = p_strPath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
strPath = strPath.Trim(Path.DirectorySeparatorChar);
string strAdjustedPath = null;
if (m_dicMovedArchiveFiles.TryGetValue(strPath, out strAdjustedPath))
return strAdjustedPath;
if (String.IsNullOrEmpty(Prefix))
return p_strPath;
if (strPath.ToLowerInvariant().IndexOf(Prefix.ToLowerInvariant()) == 0)
return p_strPath;
else
return Path.Combine(Prefix, p_strPath);
}
/// <summary>
/// This finds where in the archive the FOMod file structure begins.
/// </summary>
/// <remarks>
/// This methods finds the path prefix to the folder containing the core files and folders of the FOMod. If
/// there are any files that are above the core folder, than they are given new file names inside the
/// core folder.
/// </remarks>
protected string FindPathPrefix(Archive m_arcFile)
{
string strPrefixPath = null;
Stack<string> stkPaths = new Stack<string>();
stkPaths.Push("/");
while (stkPaths.Count > 0)
{
string strSourcePath = stkPaths.Pop();
string[] directories = m_arcFile.GetDirectories(strSourcePath);
bool booFoundPrefix = false;
foreach (string strDirectory in directories)
{
bool booSkipFolder = false;
foreach (string Folder in IgnoreFolders)
if (strDirectory.IndexOf(Folder, StringComparison.InvariantCultureIgnoreCase) >= 0)
{
booSkipFolder = true;
break;
}
if (booSkipFolder)
continue;
stkPaths.Push(strDirectory);
if (StopFolders.Contains(Path.GetFileName(strDirectory).ToLowerInvariant()))
{
booFoundPrefix = true;
break;
}
}
if (booFoundPrefix)
{
strPrefixPath = strSourcePath;
break;
}
}
strPrefixPath = (strPrefixPath == null) ? "" : strPrefixPath.Trim(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
if (!String.IsNullOrEmpty(strPrefixPath))
strPrefixPath = InitializeMovedArchive(strPrefixPath, m_arcFile);
return strPrefixPath;
}
private string InitializeMovedArchive(string p_strPathPrefix, Archive m_arcFile)
{
p_strPathPrefix = p_strPathPrefix.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
p_strPathPrefix = p_strPathPrefix.Trim(Path.DirectorySeparatorChar);
p_strPathPrefix += Path.DirectorySeparatorChar;
m_dicMovedArchiveFiles.Clear();
string[] strFiles = m_arcFile.GetFiles("/", true);
Int32 intTrimLength = p_strPathPrefix.Length;
for (Int32 i = strFiles.Length - 1; i >= 0; i--)
{
strFiles[i] = strFiles[i].Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
string strFile = strFiles[i];
string strNewFileName = null;
if (!strFile.StartsWith(p_strPathPrefix, StringComparison.OrdinalIgnoreCase))
{
strNewFileName = strFile;
string strDirectory = Path.GetDirectoryName(strNewFileName);
string strFileName = Path.GetFileNameWithoutExtension(strFile);
string strExtension = Path.GetExtension(strFile);
for (Int32 j = 1; m_dicMovedArchiveFiles.ContainsKey(strNewFileName); j++)
strNewFileName = Path.Combine(strDirectory, strFileName + " " + j + strExtension);
}
else
strNewFileName = strFile.Remove(0, intTrimLength);
m_dicMovedArchiveFiles[strNewFileName] = strFile;
}
return p_strPathPrefix;
}
/// <summary>
/// Caches information about the files in the archive.
/// </summary>
protected void LoadFileIndices()
{
SevenZipExtractor extractor = new SevenZipExtractor(Mod.ModArchivePath);
m_dicFileInfo.Clear();
m_strFiles.Clear();
foreach (ArchiveFileInfo afiFile in extractor.ArchiveFileData)
if (!afiFile.IsDirectory)
{
m_dicFileInfo[afiFile.FileName.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar)] = afiFile;
m_strFiles.Add(afiFile.FileName.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar));
}
extractor.Dispose();
}
private string installPath(string installPath)
{
DataFileUtility.AssertFilePathIsSafe(installPath);
string result = null;
return Path.Combine(GameModeInfo.InstallationPath, installPath);
}
if (useSecondaryInstallPath && !(String.IsNullOrEmpty(GameModeInfo.SecondaryInstallationPath)))
result = Path.Combine(GameModeInfo.SecondaryInstallationPath, installPath);
else
result = Path.Combine(GameModeInfo.InstallationPath, installPath);
private static readonly Regex m_rgxCleanPath = new Regex("[" + Path.DirectorySeparatorChar + Path.AltDirectorySeparatorChar + "]{1,}");
return result;
private void CreateDirectoryRecursion(string[] paths, int roffset)
{
string path = string.Join("" + Path.DirectorySeparatorChar, paths.Take(paths.Length - roffset).ToArray());
if (!Directory.Exists(path)) {
CreateDirectoryRecursion(paths, roffset + 1);
Directory.CreateDirectory(path);
}
}
private void CreateDirectory(string path)
{
string normalizedPath = m_rgxCleanPath.Replace(Path.GetFullPath(path), Path.DirectorySeparatorChar.ToString());
string[] paths = normalizedPath.Split(Path.DirectorySeparatorChar);
CreateDirectoryRecursion(paths, 0);
}
/// <summary>
@@ -279,19 +393,24 @@ namespace Nexus.Client.ModManagement
/// not to overwrite an existing file.</returns>
/// <exception cref="IllegalFilePathException">Thrown if <paramref name="p_strPath"/> is
/// not safe.</exception>
public virtual bool GenerateDataFile(string p_strPath, byte[] p_bteData, bool p_booSecondaryInstallPath)
public virtual bool GenerateDataFile(string p_strPath, byte[] p_bteData)
{
DataFileUtility.AssertFilePathIsSafe(p_strPath);
string strInstallFilePath = null;
if (p_booSecondaryInstallPath && !(String.IsNullOrEmpty(GameModeInfo.SecondaryInstallationPath)))
strInstallFilePath = Path.Combine(GameModeInfo.SecondaryInstallationPath, p_strPath);
else
strInstallFilePath = Path.Combine(GameModeInfo.InstallationPath, p_strPath);
string[] components = p_strPath.Split(Path.DirectorySeparatorChar);
p_strPath = string.Join("" + Path.DirectorySeparatorChar, components.Skip(1).Take(components.Length - 1).ToArray());
string strInstallFilePath = installPath(p_strPath);
//string strInstallFilePath = null;
//strInstallFilePath = Path.Combine(GameModeInfo.InstallationPath, p_strPath);
string installDirPath = Path.GetDirectoryName(strInstallFilePath);
FileInfo Info = new FileInfo(strInstallFilePath);
if (!Directory.Exists(Path.GetDirectoryName(strInstallFilePath)))
TransactionalFileManager.CreateDirectory(Path.GetDirectoryName(strInstallFilePath));
if (!Directory.Exists(installDirPath)) {
CreateDirectory(installDirPath);
}
else
{
if (!TestDoOverwrite(p_strPath))
@@ -317,10 +436,10 @@ namespace Nexus.Client.ModManagement
//back up the current version of the file if the current mod
// didn't install it
if (!Directory.Exists(strBackupDirectory))
TransactionalFileManager.CreateDirectory(strBackupDirectory);
CreateDirectory(strBackupDirectory);
//we get the file name this way in order to preserve the file name's case
string strFile = Path.GetFileName(Directory.GetFiles(Path.GetDirectoryName(strInstallFilePath), Path.GetFileName(strInstallFilePath))[0]);
string strFile = Path.GetFileName(Directory.GetFiles(installDirPath, Path.GetFileName(strInstallFilePath))[0]);
strFile = strOldModKey + "_" + strFile;
string strBackupFilePath = Path.Combine(strBackupDirectory, strFile);
@@ -349,9 +468,10 @@ namespace Nexus.Client.ModManagement
/// </remarks>
/// <param name="p_strPath">The path to the file that is to be uninstalled.</param>
/// <param name="p_booSecondaryInstallPath">Whether to use the secondary install path.</param>
public void UninstallDataFile(string p_strPath, bool p_booSecondaryInstallPath)
public bool UninstallDataFile(string p_strPath)
{
// NOP - Not supported in CLI version
// NOP - Not supported in CLI version
return false;
}
/// <summary>
@@ -382,6 +502,22 @@ namespace Nexus.Client.ModManagement
/// </summary>
public virtual void FinalizeInstall()
{
SevenZipExtractor extractor = new SevenZipExtractor(Mod.ModArchivePath);
List<int> indexes = new List<int>();
foreach (var entry in TargetFiles) {
indexes.Add(entry.Value.Index);
}
indexes.Sort();
extractor.ExtractFiles(ExtractPath, indexes.ToArray());
extractor.Dispose();
foreach (var entry in TargetFiles)
{
if (File.Exists(Path.Combine(ExtractPath, entry.Value.FileName)))
{
byte[] bteModFile = File.ReadAllBytes(Path.Combine(ExtractPath, entry.Value.FileName));
GenerateDataFile(entry.Key, bteModFile);
}
}
}
public List<string> InstallErrors {
@@ -389,5 +525,10 @@ namespace Nexus.Client.ModManagement
return new List<string>();
}
}
public bool PluginCheck(string p_strPath, bool p_booRemove)
{
throw new NotImplementedException();
}
}
}
+241
View File
@@ -0,0 +1,241 @@
using Nexus.Client.Util;
using System;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Collections.Generic;
using SevenZip;
namespace Nexus.Client.Mods
{
/// <summary>
/// The mod cache manager.
/// </summary>
/// <remarks>
/// A mod cache manager provides information od methods to use the mod cache.
/// </remarks>
public class NexusModCacheManager : IModCacheManager
{
#region IModCacheManager Members
/// <summary>
/// Gets the path of the directory where the current Game Mode's mods' cache files are stored.
/// </summary>
/// <value>The path of the directory where the current Game Mode's mods' cache files are stored.</value>
public string ModCacheDirectory { get; private set; }
/// <summary>
/// Gets the path of the directory where the current Game Mode's mod files are stored.
/// </summary>
/// <value>The path of the directory where the current Game Mode's mod files are stored.</value>
protected string ModDirectory { get; private set; }
/// <summary>
/// Gets or sets the file utility class.
/// </summary>
/// <value>The file utility class.</value>
public FileUtil FileUtility { get; private set; }
/// <summary>
/// Gets the application's envrionment info.
/// </summary>
/// <value>The application's envrionment info.</value>
public IEnvironmentInfo EnvironmentInfo { get; private set; }
protected bool m_booCacheOverhaulSetup = false;
#endregion
#region Constructors
/// <summary>
/// A simple constructor that initializes the object with the given dependencies.
/// </summary>
/// <param name="p_strModCacheDirectory">The path of the directory where the current Game Mode's mods' cache files are stored.</param>
/// <param name="p_strModDirectory">The path of the directory where the current Game Mode's mod files are stored.</param>
/// <param name="p_futFileUtility">The file utility class.</param>
public NexusModCacheManager(string p_strModCacheDirectory, string p_strModDirectory, FileUtil p_futFileUtility, IEnvironmentInfo p_eifEnvironmentInfo)
{
ModCacheDirectory = p_strModCacheDirectory;
ModDirectory = p_strModDirectory;
FileUtility = p_futFileUtility;
EnvironmentInfo = p_eifEnvironmentInfo;
CheckModCache();
}
#endregion
/// <summary>
/// This removes any old cache files.
/// </summary>
private void CheckModCache()
{
string[] strCaches = Directory.GetFiles(ModCacheDirectory);
foreach (string strCache in strCaches)
{
string strModPath = Path.Combine(ModDirectory, Path.GetFileNameWithoutExtension(strCache));
if (!File.Exists(strModPath) || (File.GetLastWriteTimeUtc(strCache) < File.GetLastWriteTimeUtc(strModPath)))
FileUtil.ForceDelete(strCache);
}
}
/// <summary>
/// Gets the path to the specified mod's cache file.
/// </summary>
/// <param name="p_modMod">The mod for which to get the cache filename.</param>
/// <returns>The path to the specified mod's cache file.</returns>
private string GetCacheFilePath(IMod p_modMod)
{
return Path.Combine(ModCacheDirectory, Path.GetFileName(p_modMod.ModArchivePath) + ".zip");
}
/// <summary>
/// Gets the path to the specified mod's cache file.
/// </summary>
/// <param name="p_strPath">The path for which to get the cache file.</param>
/// <returns>The path to the specified mod's cache file.</returns>
public string GetCacheFilePath(string p_strPath)
{
return Path.Combine(ModCacheDirectory, Path.GetFileNameWithoutExtension(p_strPath));
}
/// <summary>
/// Gets the cache file for the specified path.
/// </summary>
/// <param name="p_strPath">The path for which to get the cache file.</param>
/// <returns>The cache file for the specified path, or <c>null</c>
/// if there is no cache file.</returns>
public Archive GetCacheFile(string p_strPath)
{
string strCachePath = Path.Combine(ModCacheDirectory, Path.GetFileName(p_strPath) + ".zip");
if (File.Exists(strCachePath))
{
try
{
return new Archive(strCachePath);
}
catch (SevenZipArchiveException)
{
//the cachef ile is corrupt - so delete it
FileUtil.ForceDelete(strCachePath);
}
catch (UnauthorizedAccessException)
{
//we can't access the file - who know why
//destroy it so we can try again
FileUtil.ForceDelete(strCachePath);
}
}
return null;
}
/// <summary>
/// Gets the cache file for the specified mod.
/// </summary>
/// <param name="p_modMod">The mod for which to get the cache file.</param>
/// <returns>The cache file for the specified mod, or <c>null</c>
/// if there is no cache file.</returns>
public Archive GetCacheFile(IMod p_modMod)
{
string strCachePath = GetCacheFilePath(p_modMod);
if (File.Exists(strCachePath))
{
try
{
return new Archive(strCachePath);
}
catch (SevenZipArchiveException)
{
//the cachef ile is corrupt - so delete it
FileUtil.ForceDelete(strCachePath);
}
catch (UnauthorizedAccessException)
{
//we can't access the file - who know why
//destroy it so we can try again
FileUtil.ForceDelete(strCachePath);
}
}
return null;
}
/// <summary>
/// Creates a cache file for the given mod, containing the specified files.
/// </summary>
/// <param name="p_modMod">The mod for which to create the cache file.</param>
/// <param name="p_strFilesToCacheFolder">The folder containing the files to put into the cache.</param>
/// <returns>The cache file for the specified mod, or <c>null</c>
/// if there were no files to cache.</returns>
public void CreateCacheFile(IMod p_modMod, string p_strFilesToCacheFolder)
{
if (!String.IsNullOrEmpty(p_strFilesToCacheFolder))
{
var strFilesToCompress = Directory.EnumerateFiles(p_strFilesToCacheFolder, "*.*", SearchOption.AllDirectories);
if (strFilesToCompress.Count() > 0)
{
string strCachePath = Path.Combine(ModCacheDirectory, Path.GetFileNameWithoutExtension(p_modMod.Filename));
string strArcCacheFile = Path.Combine(ModCacheDirectory, Path.GetFileName(p_modMod.Filename) + ".zip");
try
{
if (!Directory.Exists(strCachePath))
{
if (File.Exists(strArcCacheFile))
{
ExportCacheArchive(strArcCacheFile, strCachePath, EnvironmentInfo.Settings.CacheOverhaulSetup);
}
else
{
Directory.CreateDirectory(strCachePath);
copyDirectory(p_strFilesToCacheFolder, strCachePath);
}
}
}
catch (FileNotFoundException ex)
{
}
}
}
}
/// <summary>
/// Migrates the cache zip file for the given mod to the cache folder.
/// </summary>
/// <param name="p_modMod">The mod for which to create the cache file.</param>
public void MigrateCacheFile(IMod p_modMod)
{
return;
}
private void ExportCacheArchive(string p_strCacheSource, string p_strDestinationFolder, bool p_booCacheOverhaulSetup)
{
try
{
ZipFile.ExtractToDirectory(p_strCacheSource, p_strDestinationFolder);
}
catch { }
if (p_booCacheOverhaulSetup)
FileUtil.ForceDelete(p_strCacheSource);
}
public static void copyDirectory(string strSource, string strDestination)
{
String[] Files;
if (strDestination[strDestination.Length - 1] != Path.DirectorySeparatorChar)
strDestination += Path.DirectorySeparatorChar;
if (!Directory.Exists(strDestination)) Directory.CreateDirectory(strDestination);
Files = Directory.GetFileSystemEntries(strSource);
foreach (string Element in Files)
{
// Sub directories
if (Directory.Exists(Element))
copyDirectory(Element, strDestination + Path.GetFileName(Element));
// Files in directory
else
File.Copy(Element, strDestination + Path.GetFileName(Element), true);
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More