forked from tModLoader/tModLoader
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Program.cs
164 lines (136 loc) · 5.17 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Terraria.ModLoader.Properties;
namespace Terraria.ModLoader.Setup
{
static class Program
{
public static readonly string appDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
public static readonly string libDir = Path.Combine(appDir, "..", "lib");
public static readonly string toolsDir = Path.Combine(appDir, "..", "tools");
public static readonly string logsDir = Path.Combine("setup", "logs");
public static readonly string referencesDir = "references";
public static string SteamDir => Settings.Default.SteamDir;
public static string TerrariaPath => Path.Combine(SteamDir, "Terraria.exe");
public static string TerrariaServerPath => Path.Combine(SteamDir, "TerrariaServer.exe");
public static string tMLSteamDir { get; private set; }
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args) {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
AppDomain.CurrentDomain.AssemblyResolve += (sender, resArgs) => {
var assemblyName = new AssemblyName(resArgs.Name);
var name = assemblyName.Name;
if (name == "Mono.Cecil" && assemblyName.Version < new Version(0, 10)) //multiple cecil versions need to be loaded separately
name += "_0.9.6.0";
return ResolveAssemblyFrom(libDir, name) ?? ResolveAssemblyFrom(referencesDir, name);
};
/*if (args.Length == 1 && args[0] == "--steamdir") {
Console.WriteLine(SteamDir);
return;
}*/
tMLSteamDir = Path.Combine(Path.GetDirectoryName(SteamDir), "tModLoader");
if (!Directory.Exists(tMLSteamDir))
tMLSteamDir = SteamDir;
UpdateSteamDirTargetsFile();
Application.Run(new MainForm());
}
private static Assembly ResolveAssemblyFrom(string libDir, string name)
{
var path = Path.Combine(libDir, name);
path = new[] {".exe", ".dll"}.Select(ext => path+ext).SingleOrDefault(File.Exists);
return path != null ? Assembly.LoadFrom(path) : null;
}
public static int RunCmd(string dir, string cmd, string args,
Action<string> output = null,
Action<string> error = null,
string input = null,
CancellationToken cancel = default(CancellationToken)) {
using (var process = new Process()) {
process.StartInfo = new ProcessStartInfo {
FileName = cmd,
Arguments = args,
WorkingDirectory = dir,
UseShellExecute = false,
RedirectStandardInput = input != null,
CreateNoWindow = true
};
if (output != null) {
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.StandardOutputEncoding = Encoding.UTF8;
}
if (error != null) {
process.StartInfo.RedirectStandardError = true;
process.StartInfo.StandardErrorEncoding = Encoding.UTF8;
}
if (!process.Start())
throw new Exception($"Failed to start process: \"{cmd} {args}\"");
if (input != null) {
var w = new StreamWriter(process.StandardInput.BaseStream, new UTF8Encoding(false));
w.Write(input);
w.Close();
}
while (!process.HasExited) {
if (cancel.IsCancellationRequested) {
process.Kill();
throw new OperationCanceledException(cancel);
}
process.WaitForExit(100);
output?.Invoke(process.StandardOutput.ReadToEnd());
error?.Invoke(process.StandardError.ReadToEnd());
}
return process.ExitCode;
}
}
public static bool SelectTerrariaDialog() {
while (true) {
var dialog = new OpenFileDialog {
InitialDirectory = Path.GetFullPath(Directory.Exists(SteamDir) ? SteamDir : "."),
Filter = "Terraria|Terraria.exe",
Title = "Select Terraria.exe"
};
if (dialog.ShowDialog() != DialogResult.OK)
return false;
string err = null;
if (Path.GetFileName(dialog.FileName) != "Terraria.exe")
err = "File must be named Terraria.exe";
else if (!File.Exists(Path.Combine(Path.GetDirectoryName(dialog.FileName), "TerrariaServer.exe")))
err = "TerrariaServer.exe does not exist in the same directory";
if (err != null) {
if (MessageBox.Show(err, "Invalid Selection", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error) == DialogResult.Cancel)
return false;
}
else {
Settings.Default.SteamDir = Path.GetDirectoryName(dialog.FileName);
Settings.Default.Save();
UpdateSteamDirTargetsFile();
return true;
}
}
}
private static readonly string targetsFilePath = Path.Combine("src", "TerrariaSteamPath.targets");
private static void UpdateSteamDirTargetsFile() {
SetupOperation.CreateParentDirectory(targetsFilePath);
string targetsText =
$@"<?xml version=""1.0"" encoding=""utf-8""?>
<Project ToolsVersion=""14.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
<PropertyGroup>
<TerrariaSteamPath>{SteamDir}</TerrariaSteamPath>
<tModLoaderSteamPath>{tMLSteamDir}</tModLoaderSteamPath>
</PropertyGroup>
</Project>";
if (File.Exists(targetsFilePath) && targetsText == File.ReadAllText(targetsFilePath))
return;
File.WriteAllText(targetsFilePath, targetsText);
}
}
}