Skip to content

Commit

Permalink
Cleanup and refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
originalfoo committed Mar 4, 2020
1 parent cf1bd92 commit 5a96923
Show file tree
Hide file tree
Showing 10 changed files with 196 additions and 73 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="Rules for TLM" Description="Code analysis rules for TLM" ToolsVersion="16.0">
<RuleSet Name="Code analysis rules" Description="Code analysis rules" ToolsVersion="16.0">
<Rules AnalyzerId="ReflectionIT.Analyzer.Structs" RuleNamespace="ReflectionIT.Analyzer.Structs">
<Rule Id="RAS0001" Action="Error" />
</Rules>
Expand Down Expand Up @@ -39,4 +39,4 @@
<Rule Id="SA1640" Action="None" />
<Rule Id="SA1652" Action="None" />
</Rules>
</RuleSet>
</RuleSet>
5 changes: 5 additions & 0 deletions DuplicateAssemblyScanner/DuplicateAssemblyScanner.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ VisualStudioVersion = 16.0.29806.167
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DuplicateAssemblyScanner", "DuplicateAssemblyScanner\DuplicateAssemblyScanner.csproj", "{EFBA373B-88B2-427A-8396-6F9D56C89F74}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E06C7F71-21C0-4D8E-920F-F8139B39A120}"
ProjectSection(SolutionItems) = preProject
VersionInfo.cs = VersionInfo.cs
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<AssemblyName>DuplicateAssemblyScanner</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<Deterministic>false</Deterministic>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
Expand All @@ -22,6 +22,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>..\CodeAnalysis.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
Expand All @@ -30,6 +31,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>..\CodeAnalysis.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup>
<SteamPath>~/Library/Application Support/Steam/</SteamPath>
Expand Down Expand Up @@ -72,19 +74,30 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="..\VersionInfo.cs">
<Link>Properties\VersionInfo.cs</Link>
</Compile>
<Compile Include="UserMod.cs" />
<Compile Include="Util\Assemblies.cs" />
<Compile Include="Util\Log.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Util\Settings.cs" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\ReflectionIT.Analyzer.Structs.0.1.0\analyzers\dotnet\cs\ReflectionIT.Analyzer.Structs.dll" />
<Analyzer Include="..\packages\StyleCop.Analyzers.1.1.118\analyzers\dotnet\cs\StyleCop.Analyzers.CodeFixes.dll" />
<Analyzer Include="..\packages\StyleCop.Analyzers.1.1.118\analyzers\dotnet\cs\StyleCop.Analyzers.dll" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>set "DEPLOYDIR=$(LOCALAPPDATA)\Colossal Order\Cities_Skylines\Addons\Mods\$(TargetName)\"

del "%25DEPLOYDIR%25DuplicateAssemblyScanner.dll"
xcopy /y "$(TargetDir)DuplicateAssemblyScanner.dll" "%25DEPLOYDIR%25"
xcopy /y "$(TargetDir)DuplicateAssemblyScanner.dll" "%25DEPLOYDIR%25"

set DEPLOYDIR=</PostBuildEvent>
</PropertyGroup>
</Project>
</Project>
Original file line number Diff line number Diff line change
@@ -1,36 +1,6 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Reflection;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("DuplicateAssemblyScanner")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DuplicateAssemblyScanner")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("efba373b-88b2-427a-8396-6f9d56c89f74")]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// 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.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
27 changes: 23 additions & 4 deletions DuplicateAssemblyScanner/DuplicateAssemblyScanner/UserMod.cs
Original file line number Diff line number Diff line change
@@ -1,32 +1,51 @@
namespace DuplicateAssemblyScanner {
using ColossalFramework.UI;
using DuplicateAssemblyScanner.Util;
using ICities;
using JetBrains.Annotations;
using UnityEngine.SceneManagement;

/// <summary>
/// The main mod class which the game instantiates when the mod is enabled.
/// </summary>
public class UserMod : IUserMod {

/// <summary>
/// Gets mod name shown in content manager and options screens.
/// Version defined in Solution Items > VersionInfo.cs file.
/// </summary>
[UsedImplicitly]
public string Name => "DAS";
public string Name => $"DAS v{typeof(UserMod).Assembly.GetName().Version.ToString(3)}";

/// <summary>
/// Gets mod description shown in content manager.
/// </summary>
[UsedImplicitly]
public string Description => "Scans for duplicate assemblies in the app domain, which can cause bugs.";

/// <summary>
/// Called when mod is enabled.
/// </summary>
[UsedImplicitly]
public void OnEnabled() {
Log.Info("Enabled");
}

/// <summary>
/// Called when settings UI is required.
/// </summary>
///
/// <param name="helper">Helper for creating UI.</param>
[UsedImplicitly]
public void OnSettingsUI(UIHelperBase helper) {
Log.Info("SettingsUI");
Settings.CreateUI(helper);
}

/// <summary>
/// Called when mod is disabled.
/// </summary>
[UsedImplicitly]
public void OnDisabled() {
Log.Info("Disabled");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ namespace DuplicateAssemblyScanner.Util {
using System.Reflection;
using static ColossalFramework.Plugins.PluginManager;

/// <summary>
/// Scans for duplicate assemblies and, where found, attempts to work out which mods they are from.
/// </summary>
public class Assemblies {

/// <summary>
Expand Down Expand Up @@ -47,7 +50,7 @@ public static Dictionary<string, List<string>> Scan(out bool duplicatesFound) {
} else {

results.Add(name, new List<string>() {
{ ver }
{ ver },
});

}
Expand Down
94 changes: 83 additions & 11 deletions DuplicateAssemblyScanner/DuplicateAssemblyScanner/Util/Log.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,73 @@
namespace DuplicateAssemblyScanner.Util {
using System.Diagnostics;
using System.IO;
using System.Reflection;
using UnityEngine;

/// <summary>
/// A simple logging class.
///
/// When mod activates, it creates a log file in same location as `output_log.txt`.
/// Mac users: It will be in the Cities app contents.
/// </summary>
public class Log {
public static readonly string LogFileName = "DuplicateAssemblyScanner.log";

private enum LogLevel {
Debug,
Info,
Error
}
/// <summary>
/// File name for log file.
/// </summary>
public static readonly string LogFileName = $"{typeof(Log).Assembly.GetName().Name}.log";

/// <summary>
/// Full path and file name of log file.
/// </summary>
private static readonly string LogFilePath = Path.Combine(Application.dataPath, LogFileName);

/// <summary>
/// Set to <c>true</c> to include timestamp in log entries.
/// </summary>
private static readonly bool TimeStamp = false;

/// <summary>
/// Stopwatch used if <see cref="TimeStamp"/> is <c>true</c>.
/// </summary>
private static readonly Stopwatch Timer;

/// <summary>
/// Initializes static members of the <see cref="Log"/> class.
/// Resets log file on startup.
/// </summary>
static Log() {
try {
if (File.Exists(LogFilePath)) {
File.Delete(LogFilePath);
}
} catch { }

if (TimeStamp) {
Timer = Stopwatch.StartNew();
}

AssemblyName details = typeof(Log).Assembly.GetName();
Info($"{details.Name} v{details.Version.ToString()}", true);
} catch {
// ignore
}
}

/// <summary>
/// Log levels. Also output in log file.
/// </summary>
private enum LogLevel {
Debug,
Info,
Error,
}

/// <summary>
/// Logs debug trace, only in <c>DEBUG</c> builds.
/// </summary>
///
/// <param name="message">Log entry text.</param>
/// <param name="copyToGameLog">If <c>true</c> will copy to the main game log file.</param>
[Conditional("DEBUG")]
public static void Debug(string message, bool copyToGameLog = false) {
LogToFile(message, LogLevel.Debug);
Expand All @@ -30,31 +76,57 @@ public static void Debug(string message, bool copyToGameLog = false) {
}
}

/// <summary>
/// Logs info message.
/// </summary>
///
/// <param name="message">Log entry text.</param>
/// <param name="copyToGameLog">If <c>true</c> will copy to the main game log file.</param>
public static void Info(string message, bool copyToGameLog = false) {
LogToFile(message, LogLevel.Info);
if (copyToGameLog) {
UnityEngine.Debug.Log(message);
}
}

/// <summary>
/// Logs error message and also outputs a stack trace.
/// </summary>
///
/// <param name="message">Log entry text.</param>
/// <param name="copyToGameLog">If <c>true</c> will copy to the main game log file.</param>
public static void Error(string message, bool copyToGameLog = true) {
LogToFile(message, LogLevel.Error);
if (copyToGameLog) {
UnityEngine.Debug.LogError(message);
}
}

private static void LogToFile(string log, LogLevel level) {
/// <summary>
/// Write a message to log file.
/// </summary>
///
/// <param name="message">Log entry text.</param>
/// <param name="level">Logging level. If set to <see cref="LogLevel.Error"/> a stack trace will be appended.</param>
private static void LogToFile(string message, LogLevel level) {
try {
using (StreamWriter w = File.AppendText(LogFilePath)) {
w.Write("{0, -9}", $"[{level.ToString()}] ");
w.WriteLine(log);
w.Write("{0, -8}", $"[{level.ToString()}] ");

if (TimeStamp) {
w.Write("{0, 15}", Timer.ElapsedTicks + " | ");
}

w.WriteLine(message);

if (level == LogLevel.Error) {
w.WriteLine(new StackTrace().ToString());
w.WriteLine();
}
}
} catch { }
} catch {
// ignore
}
}
}
}
Loading

0 comments on commit 5a96923

Please sign in to comment.