-
Notifications
You must be signed in to change notification settings - Fork 0
/
ProjectManager.cs
150 lines (124 loc) · 5.78 KB
/
ProjectManager.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
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Threading.Tasks;
using DemonCastle.Files;
using DemonCastle.ProjectFiles;
using DemonCastle.ProjectFiles.Projects;
using DemonCastle.ProjectFiles.Projects.Data;
using DemonCastle.ProjectFiles.Projects.Resources;
using HttpClient = System.Net.Http.HttpClient;
using Version = DemonCastle.ProjectFiles.Version;
namespace DemonCastle;
public class SampleProject {
public string Name { get; }
public string ProjectFile { get; }
public string Url { get; }
public SampleProject(string name, string projectFile, string url) {
Name = name;
ProjectFile = projectFile;
Url = url;
}
public async Task<ProjectWithResources> DownloadProject(string destination) {
var zipFile = await DownloadRepoAsZipFile();
var unZipDir = UnzipFile(zipFile);
File.Delete(zipFile);
// at this point, unZipDir contains a single folder, named like 'PixelPlatformerExample-master'.
// we need to copy the contents of that folder to the destination folder
var subDir = GetFirstSubDirIn(unZipDir);
CopyAllFilesFromTo(subDir, destination);
var projectFilePath = Path.GetFullPath(Path.Combine(destination, ProjectFile));
var resources = new ProjectResources(Path.GetDirectoryName(projectFilePath) ?? throw new DirectoryNotFoundException());
var project = resources.GetProject(projectFilePath);
return new ProjectWithResources(resources, project);
}
private async Task<string> DownloadRepoAsZipFile() {
var zipFile = Path.GetTempFileName();
using var httpClient = new HttpClient();
var responseBytes = await httpClient.GetByteArrayAsync(Url);
await File.WriteAllBytesAsync(zipFile, responseBytes);
return zipFile;
}
private static string UnzipFile(string zipFile) {
var unZipDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
ZipFile.ExtractToDirectory(zipFile, unZipDir);
return unZipDir;
}
private static string GetFirstSubDirIn(string dir) {
var subDirs = Directory.EnumerateDirectories(dir);
return subDirs.First();
}
private static void CopyAllFilesFromTo(string source, string destination) {
var sourceDir = Directory.CreateDirectory(source);
var destDir = Directory.CreateDirectory(destination);
CopyFilesRecursively(sourceDir, destDir);
}
public static void CopyFilesRecursively(DirectoryInfo source, DirectoryInfo target) {
foreach (var dir in source.GetDirectories())
CopyFilesRecursively(dir, target.CreateSubdirectory(dir.Name));
foreach (var file in source.GetFiles())
file.CopyTo(Path.Combine(target.FullName, file.Name));
}
}
public class ProjectManager {
public static List<SampleProject> SampleProjects { get; } = new() {
new SampleProject("Devil Castle Dracula 1", "DevilCastleDracula1.dcp",
"https://github.com/CloneDeath/DevilCastleDracula1/archive/refs/heads/master.zip"),
new SampleProject("Pixel Platformer Example", "PixelPlatformer.dcp",
"https://github.com/CloneDeath/PixelPlatformerExample/archive/refs/heads/master.zip"),
new SampleProject("Two Worlds Theory", "TwoWorldsTheory.dcp",
"https://github.com/CloneDeath/TwoWorldsTheory/archive/refs/heads/master.zip"),
new SampleProject("Harmony of Despair", "HarmonyOfDespair.dcp",
"https://github.com/CloneDeath/HarmonyOfDespair/archive/refs/heads/master.zip")
};
public static bool ProjectsExist => GetProjects().Any();
public static IEnumerable<ProjectWithResources> GetProjects() {
var projectFiles = GetProjectFiles().Where(File.Exists).Distinct();
foreach (var projectFile in projectFiles) {
var resources = new ProjectResources(Path.GetDirectoryName(projectFile) ?? throw new DirectoryNotFoundException());
var project = resources.GetProject(projectFile);
yield return new ProjectWithResources(resources, project);
}
}
protected static IEnumerable<string> GetProjectFiles() {
return LocalProjectList.ProjectFiles;
}
public static void ImportProject(string filePath) {
LocalProjectList.AddProject(filePath);
}
public static void RemoveProject(ProjectInfo project) {
LocalProjectList.RemoveProject(project.FilePath);
}
public static async Task<ProjectWithResources> CreateSample(SampleProject sample, string folderPath) {
if (!Directory.Exists(folderPath)) throw new Exception($"Folder '{folderPath}' does not exist.");
if (Directory.EnumerateFiles(folderPath).Any() || Directory.EnumerateDirectories(folderPath).Any()) {
throw new Exception("Folder must be empty.");
}
await sample.DownloadProject(folderPath);
var projectFilePath = Path.Combine(folderPath, sample.ProjectFile);
LocalProjectList.AddProject(projectFilePath);
var resources = new ProjectResources(Path.GetDirectoryName(projectFilePath) ?? throw new DirectoryNotFoundException());
var project = resources.GetProject(projectFilePath);
return new ProjectWithResources(resources, project);
}
public static ProjectWithResources CreateProject(string folderPath) {
if (!Directory.Exists(folderPath)) throw new Exception($"Folder '{folderPath}' does not exist.");
if (Directory.EnumerateFiles(folderPath).Any() || Directory.EnumerateDirectories(folderPath).Any()) {
throw new Exception("Folder must be empty.");
}
var projectName = Path.GetFileName(folderPath)
?? throw new Exception($"Failed to get Folder Name from '{folderPath}'");
var projectFilePath = Path.Combine(folderPath, $"{projectName}.dcp");
var projectFile = new ProjectFile {
Name = projectName,
Version = Version.Current
};
File.WriteAllText(projectFilePath, Serializer.Serialize(projectFile));
LocalProjectList.AddProject(projectFilePath);
var resources = new ProjectResources(Path.GetDirectoryName(projectFilePath) ?? throw new DirectoryNotFoundException());
var project = resources.GetProject(projectFilePath);
return new ProjectWithResources(resources, project);
}
}