Skip to content

Commit

Permalink
.excluded approach
Browse files Browse the repository at this point in the history
  • Loading branch information
kianzarrin committed Nov 24, 2022
1 parent 51b9277 commit 8181d93
Show file tree
Hide file tree
Showing 9 changed files with 371 additions and 307 deletions.
5 changes: 3 additions & 2 deletions LoadOrder.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30204.135
# Visual Studio Version 17
VisualStudioVersion = 17.3.32929.385
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LoadOrderTool", "LoadOrder\LoadOrderTool.csproj", "{B89FEAE6-A22E-4576-9683-D2B5A1732544}"
EndProject
Expand All @@ -21,6 +21,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
TODO = TODO
patchloader.txt = patchloader.txt
Version.props = Version.props
EndProjectSection
EndProject
Expand Down
8 changes: 4 additions & 4 deletions LoadOrder/CO/IO/DataLocation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -296,11 +296,11 @@ public static class Util {
int i = mod.IncludedPath.IndexOf(WSDirName);
if (i > 0) {
string WSDirPath = mod.IncludedPath.Substring(0, i + WSDirName.Length);
string m =
$"tool uses '{WorkshopContentPath}'\n" +
$"game uses '{WSDirPath}'";
Log.Debug(m);
if (WorkshopContentPath != WSDirPath) {
string m =
$"tool uses '{WorkshopContentPath}'\n" +
$"game uses '{WSDirPath}'";
Log.Debug(m);
new Exception($"Path mismatch! enabling/disabling may not work.\n" + m).Log();
return;
}
Expand Down
109 changes: 38 additions & 71 deletions LoadOrder/CO/Plugins/PluginManger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,33 @@ public class PluginInfo : IWSItem {

private TypeDefinition m_UserModImplementation;

private string m_Path;

private bool m_IsBuiltin;

private bool m_Unloaded;

private string m_Path;

/// <summary> dir name without prefix. </summary>
private string m_CachedName;

public string dllName => userModImplementation?.Module.Assembly.Name.Name;
/// <summary> real mod path (with prefix if any) </summary>
public string ModPath => m_Path;
/// <summary>the name of the directory that contains the mod</summary>
public string dirName => new DirectoryInfo(ModPath).Name;

public string IncludedPath {
get {
if (dirName.StartsWith("_"))
return Path.Combine(parentDirPath, dirName.Substring(1));
else
return ModPath;
}
}

private string dllPath_;

public string dllName => userModImplementation?.Module.Assembly.Name.Name;
public string dllPath {
get {
if(dllPath_ == null)
Expand All @@ -73,22 +88,6 @@ public class PluginInfo : IWSItem {
public bool IsLocal => !IsWorkshop;
public bool IsWorkshop => PublishedFileId.IsValid;

public string ModPath => m_Path;

public string IncludedPath {
get {
if (dirName.StartsWith("_"))
return Path.Combine(parentDirPath, dirName.Substring(1));
else
return ModPath;
}
}

/// <summary>
/// the name of the directory that contains the mod
/// </summary>
public string dirName => new DirectoryInfo(ModPath).Name;

/// <summary>
/// full path to the parent of the mod's directory.
/// </summary>
Expand All @@ -111,11 +110,13 @@ public class PluginInfo : IWSItem {
modName = SteamCache?.Name;

if (modName.IsNullorEmpty()) {
displayText_ = DispalyPath;
} else {
string version = UserModAssemblyVersion == null ? "" : "V" + UserModAssemblyVersion;
displayText_ = $"{modName} ({DispalyPath} {version})";
modName = DispalyPath;
}

string version = UserModAssemblyVersion == null ? "" : "V" + UserModAssemblyVersion;
string dllDetail = $"{DispalyPath} {version}";
displayText_ = $"{modName} ({dllDetail})";

}
return displayText_;
}
Expand Down Expand Up @@ -180,7 +181,6 @@ public class PluginInfo : IWSItem {
public bool IsHarmonyMod() =>
name == "2040656402" || dllName == "CitiesHarmony";


/// <summary>
/// precondition: all dependent assemblies are loaded.
/// </summary>
Expand All @@ -200,21 +200,25 @@ public class PluginInfo : IWSItem {
}

public bool IsIncluded {
get => !dirName.StartsWith("_");
get =>
!dirName.StartsWith("_") &&
!File.Exists(Path.Combine(ModPath, ContentUtil.EXCLUDED_FILE_NAME));
set {
isIncludedPending_ = value;
if (value == IsIncluded)
return;
Log.Debug($"set_IsIncluded current value = {IsIncluded} | target value = {value}");
string parentPath = Directory.GetParent(m_Path).FullName;
string targetDirname =
value
? dirName.Substring(1) // drop _ prefix
: "_" + dirName; // add _ prefix
string targetPath = Path.Combine(parentPath, targetDirname);
ContentUtil.EnsureModAt(m_Path);
bool success = MoveToPath(targetPath);
if (!success) {
bool success;
if (value) {
success = ContentUtil.Include(m_Path);
} else {
success = ContentUtil.Exclude(m_Path);
}
if (success) {
// fix mod path if necessary.
string includedPath = ContentUtil.ToIncludedPath(m_Path);
dllPath_ = dllPath_.Replace(m_Path, includedPath);
m_Path = includedPath;
} else {
// move failed. reverse value:
isIncludedPending_ = IsIncluded;
var modGrid = LoadOrderWindow.Instance?.dataGridMods;
Expand All @@ -224,43 +228,6 @@ public class PluginInfo : IWSItem {
}
}

/// <returns>true on success</returns>
public bool MoveToPath(string targetPath) {
try {
string newPath = ContentUtil.EnsureModAt(m_Path);
if (newPath == null)
throw new Exception($"cannot move because could not ensure item.");
Log.Debug($"moving mod from {newPath} to {targetPath}");

if (newPath == targetPath)
return true; // no need to move if ensuring moved the directory for us.
if (Directory.Exists(targetPath))
throw new Exception($"cannot move because targetPath already exists ({targetPath})"); // unreachable code.
if (!Directory.Exists(newPath))
throw new Exception($"cannot move because source path does not exists ({newPath})"); // unreachable code.

Directory.Move(newPath, targetPath);

if(Directory.Exists(targetPath)) {
Log.Debug($"move successful!");
} else {
Log.Debug($"FAILED!");
throw new Exception($"failed to move directory from {m_Path} to {targetPath}");
}

dllPath_ = dllPath_.Replace(m_Path, targetPath); // update dllPAth
m_Path = targetPath; // must be done last because we need m_Path to know what old path was.
} catch (Exception ex) {
//string assemblyName = userModImplementation.GetType().Assembly.GetName().Name;
if ( dllName == "LoadOrderMod")
Log.Error("Cannot move Load Order because LoadOrderTool is in use");
else
Log.Exception(ex, "dllName:" + dllName);
return false;
}
return true;
}

private PublishedFileId m_PublishedFileId = PublishedFileId.invalid;

private PluginInfo() {
Expand Down
113 changes: 60 additions & 53 deletions LoadOrder/Util/ContentUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace LoadOrderTool.Util {
public static class ContentUtil {
public const string WS_URL_PREFIX = @"https://steamcommunity.com/sharedfiles/filedetails/?id=";
public const string DLC_URL_PREFIX = @"https://store.steampowered.com/app/";

public const string EXCLUDED_FILE_NAME = ".excluded";
public static string GetItemURL(PublishedFileId id) {
if (id == PublishedFileId.invalid || id.AsUInt64 == 0)
return null;
Expand Down Expand Up @@ -163,7 +163,7 @@ public static class ContentUtil {

private static bool TryGetID(string dirName, out ulong id) {
if (dirName.StartsWith("_"))
dirName = dirName.Remove(0, 1);
dirName = dirName.Substring(1);
return ulong.TryParse(dirName, out id);
}

Expand All @@ -173,72 +173,79 @@ public static class ContentUtil {
return ret;
}

public static void Touch(string path) {
if (!File.Exists(path)) {
File.CreateText(path).Dispose();
}
}

public static void TryDelete(string path) {
if (File.Exists(path)) {
File.Delete(path);
}
}

public static bool Exclude(string path) {
try {
string excludedPath = ToExcludedPath(path);
string includedPath = ToIncludedPath(path);
if (Directory.Exists(excludedPath)) {
if (Directory.Exists(includedPath)) {
Directory.Delete(excludedPath, true);
} else {
Directory.Move(excludedPath, includedPath);
}
} else if(!Directory.Exists(includedPath)) {
Log.Error(message: $"'{path}' does not exist.");
return false;
}
Touch(Path.Combine(includedPath, EXCLUDED_FILE_NAME));
return true;
} catch(Exception ex) { ex.Log(); }
return false;
}

public static bool Include(string path) {
try {
string excludedPath = ToExcludedPath(path);
string includedPath = ToIncludedPath(path);
if (Directory.Exists(excludedPath)) {
if (Directory.Exists(includedPath)) {
Directory.Delete(excludedPath, true);
} else {
Directory.Move(excludedPath, includedPath);
}
} else if (!Directory.Exists(includedPath)) {
Log.Error(message: $"'{path}' does not exist.");
return false;
}
TryDelete(Path.Combine(includedPath, EXCLUDED_FILE_NAME));
return true;
} catch (Exception ex) { ex.Log(); }
return false;
}

static object ensureLock_ = new object();
public static void EnsureSubscribedItems() {
Log.Called();
lock (ensureLock_) {
List<string> includedPaths = new List<string>();
List<string> excludedPaths = new List<string>();
foreach (var path in Directory.GetDirectories(DataLocation.WorkshopContentPath)) {
var dirName = Path.GetFileName(path);
if (!TryGetID(dirName, out ulong id)) continue;
if (dirName.StartsWith("_"))
excludedPaths.Add(path);
else
includedPaths.Add(path);
}

foreach (var excludedPath in excludedPaths) {
var excludedID = Path2ID(excludedPath);
foreach (var includedPath in includedPaths) {
var includedID = Path2ID(includedPath);
if (excludedID == includedID) {
Log.Info($"moving '{includedPath}' to '{excludedPath}'");
Directory.Delete(excludedPath, recursive: true);
Directory.Move(includedPath, excludedPath);
break;
}
if (dirName.StartsWith("_")) {
Exclude(path);
}
}
}
}

public static string EnsureModAt(string dir) {
try {
if (!Directory.Exists(dir))
return null;

var included = ToIncludedPath(dir);
var excluded = ToExcludedPath(dir);
if (Directory.Exists(included) && Directory.Exists(excluded)) {
Directory.Delete(excluded, recursive: true);
Directory.Move(included, excluded);
return excluded;
}
return dir;
} catch (Exception ex) { ex.Log(); }
return null;
}

public static void EnsureLocalItemsAt(string parentDir) {
Log.Called(parentDir);
lock (ensureLock_) {
List<string> includedPaths = new List<string>();
List<string> excludedPaths = new List<string>();
foreach (var path in Directory.GetDirectories(parentDir)) {
var dirName = Path.GetFileName(path);
if (dirName.StartsWith("_"))
excludedPaths.Add(path);
else
includedPaths.Add(path);
}

foreach (var excludedPath in excludedPaths) {
var excludedDir = Path.GetFileName(excludedPath);
var includedDir = excludedDir.Substring(1);
foreach (var includedPath in includedPaths) {
if (Path.GetFileName(includedPath) == includedDir) {
Directory.Delete(excludedPath, recursive: true);
break;
}
if (dirName.StartsWith("_")) {
Exclude(path);
}
}
}
Expand Down
Loading

0 comments on commit 8181d93

Please sign in to comment.