|
@@ -1,5 +1,6 @@
|
|
|
using FNZCM.Core;
|
|
|
using Microsoft.VisualBasic.FileIO;
|
|
|
+using Newtonsoft.Json;
|
|
|
using System;
|
|
|
using System.Collections.Concurrent;
|
|
|
using System.Collections.Generic;
|
|
@@ -9,7 +10,6 @@ using System.Net;
|
|
|
using System.Text;
|
|
|
using System.Threading;
|
|
|
using System.Threading.Tasks;
|
|
|
-using Newtonsoft.Json;
|
|
|
using SearchOption = Microsoft.VisualBasic.FileIO.SearchOption;
|
|
|
|
|
|
namespace FNZCM.ConHost.Ver2
|
|
@@ -29,6 +29,9 @@ namespace FNZCM.ConHost.Ver2
|
|
|
private static readonly ConcurrentDictionary<string, Library2> Libraries = new();
|
|
|
private static readonly ConcurrentDictionary<string, string> PathMapping = new();
|
|
|
private static readonly ConcurrentDictionary<string, MediaTag2> MediaTags = new();
|
|
|
+ private static readonly ConcurrentDictionary<string, LoadedModule> Modules = new();
|
|
|
+
|
|
|
+ private static LoadedModule _defaultModule;
|
|
|
|
|
|
private static bool _isRunning;
|
|
|
private static bool _isLoading;
|
|
@@ -46,7 +49,7 @@ namespace FNZCM.ConHost.Ver2
|
|
|
_isRunning = true;
|
|
|
tWorker.Start();
|
|
|
|
|
|
- Task.Run(ScanLibrary);
|
|
|
+ Task.Run(ReloadConfig);
|
|
|
|
|
|
Console.WriteLine("Press ENTER to Stop.");
|
|
|
Console.ReadLine();
|
|
@@ -62,18 +65,68 @@ namespace FNZCM.ConHost.Ver2
|
|
|
Console.ReadLine();
|
|
|
}
|
|
|
|
|
|
- private static void ScanLibrary()
|
|
|
+ private static void ReloadConfig()
|
|
|
{
|
|
|
if (_isLoading)
|
|
|
{
|
|
|
- Console.WriteLine("Still scanning, SKIP");
|
|
|
+ Console.WriteLine("Still loading, SKIP");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
_isLoading = true;
|
|
|
+
|
|
|
try
|
|
|
{
|
|
|
ConfigFile.Reload();
|
|
|
+
|
|
|
+ Modules.Clear();
|
|
|
+ _defaultModule = null;
|
|
|
+ if (ConfigFile.Instance.Modules?.Any() == true)
|
|
|
+ {
|
|
|
+ foreach (var modEnt in ConfigFile.Instance.Modules)
|
|
|
+ {
|
|
|
+ Console.WriteLine($"Loading module `{modEnt.Value.DisplayText}'...");
|
|
|
+ var module = new LoadedModule
|
|
|
+ {
|
|
|
+ VirtualPath = modEnt.Key,
|
|
|
+ DisplayText = modEnt.Value.DisplayText,
|
|
|
+ DefaultDocument = modEnt.Value.DefaultDocument,
|
|
|
+ Files = new Dictionary<string, byte[]>()
|
|
|
+ };
|
|
|
+
|
|
|
+ if (Directory.Exists(modEnt.Value.Path))
|
|
|
+ {
|
|
|
+ //load by fs
|
|
|
+ var files = Directory.GetFiles(modEnt.Value.Path, "*", System.IO.SearchOption.AllDirectories);
|
|
|
+ foreach (var item in files)
|
|
|
+ {
|
|
|
+ var k = item.Substring(modEnt.Value.Path.Length + 1).Replace("\\", "/").ToLower();
|
|
|
+ module.Files[k] = File.ReadAllBytes(item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (File.Exists(modEnt.Value.Path))
|
|
|
+ {
|
|
|
+ //load by package
|
|
|
+ using var arc = SharpCompress.Archives.ArchiveFactory.Open(modEnt.Value.Path);
|
|
|
+ foreach (var ent in arc.Entries.Where(p => p.IsDirectory == false))
|
|
|
+ {
|
|
|
+ var buf = new byte[ent.Size];
|
|
|
+ using var s = ent.OpenEntryStream();
|
|
|
+ var r = s.Read(buf, 0, buf.Length);
|
|
|
+ module.Files[ent.Key.ToLower()] = buf;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Console.WriteLine("WARN: resource not found");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (modEnt.Value.IsDefault && _defaultModule == null) _defaultModule = module;
|
|
|
+ Modules[modEnt.Key] = module;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
Console.WriteLine("Scanning libraries...");
|
|
|
MediaTags.Clear();
|
|
|
PathMapping.Clear();
|
|
@@ -233,6 +286,10 @@ namespace FNZCM.ConHost.Ver2
|
|
|
var request = context.Request;
|
|
|
Console.WriteLine($"Request from {request.RemoteEndPoint} {request.HttpMethod} {request.RawUrl}");
|
|
|
|
|
|
+#if DEBUG
|
|
|
+ context.Response.AddHeader("Access-Control-Allow-Origin", "*");
|
|
|
+#endif
|
|
|
+
|
|
|
// GET / show all libraries
|
|
|
|
|
|
// foo=library bar=disc
|
|
@@ -284,14 +341,33 @@ namespace FNZCM.ConHost.Ver2
|
|
|
}
|
|
|
else if (requestPath == "/admin/" && request.QueryString["action"] == "Scan" && request.QueryString["pass"] == ConfigFile.Instance.AdminPassword)
|
|
|
{
|
|
|
- Task.Run(ScanLibrary);
|
|
|
+ Task.Run(ReloadConfig);
|
|
|
context.Response.Redirect("/");
|
|
|
}
|
|
|
else if (requestPath == "/admin/")
|
|
|
{
|
|
|
context.Response.Redirect("/");
|
|
|
}
|
|
|
- else if (requestPath == "/")
|
|
|
+ else if (requestPath.StartsWith("/module/") && pathParts.Count > 1)
|
|
|
+ {
|
|
|
+ var moduleKey = pathParts[1];
|
|
|
+ if (Modules.TryGetValue(moduleKey, out var module))
|
|
|
+ {
|
|
|
+ var entPath = string.Join("/", pathParts.Skip(2));
|
|
|
+ if (module.Files.TryGetValue(entPath, out var bin))
|
|
|
+ {
|
|
|
+ if (entPath.EndsWith(".js")) context.Response.ContentType = "application/javascript";
|
|
|
+ context.Response.OutputStream.Write(bin, 0, bin.Length);
|
|
|
+ }
|
|
|
+ else context.Response.StatusCode = 404;
|
|
|
+ }
|
|
|
+ else context.Response.StatusCode = 404;
|
|
|
+ }
|
|
|
+ else if (requestPath == "/" && _defaultModule != null)
|
|
|
+ {
|
|
|
+ context.Response.Redirect($"/module/{_defaultModule.VirtualPath}/{_defaultModule.DefaultDocument}");
|
|
|
+ }
|
|
|
+ else if (requestPath == "/" || requestPath == "/classic-index")
|
|
|
{
|
|
|
var sb = new StringBuilder();
|
|
|
sb.Append("<!DOCTYPE html><html lang=\"zh-cn\"><meta charset=\"UTF-8\">");
|
|
@@ -301,6 +377,22 @@ namespace FNZCM.ConHost.Ver2
|
|
|
if (_isLoading) sb.Append($"<h4 style=position:fixed;right:0px;top:0px;margin:0>{LoadingText}</h4>");
|
|
|
|
|
|
sb.Append($"<h2>{ConfigFile.Instance.Title}</h2>");
|
|
|
+
|
|
|
+ if (Modules?.Any() == true)
|
|
|
+ {
|
|
|
+ sb.Append($"<h3>Modules</h3>");
|
|
|
+ sb.Append($"<h4>(Total number of modules: {Modules.Count})</h4>");
|
|
|
+
|
|
|
+ sb.Append("<ul>");
|
|
|
+ foreach (var module in Modules)
|
|
|
+ {
|
|
|
+ sb.Append("<li>");
|
|
|
+ sb.Append($"<a href='/module/{module.Key.UrlEscape()}/{module.Value.DefaultDocument}'>{module.Value.DisplayText}</a>");
|
|
|
+ sb.Append("</li>");
|
|
|
+ }
|
|
|
+ sb.Append("</ul>");
|
|
|
+ }
|
|
|
+
|
|
|
sb.Append($"<h3>Libraries</h3>");
|
|
|
sb.Append($"<h4>(Total number of disc: {Libraries.Sum(p => p.Value.Discs.Count)})</h4>");
|
|
|
|