diff --git a/Sunfish/Form1.Designer.cs b/Sunfish/Form1.Designer.cs index c126fab..bc5c41b 100644 --- a/Sunfish/Form1.Designer.cs +++ b/Sunfish/Form1.Designer.cs @@ -143,9 +143,9 @@ this.lbPaths.FormattingEnabled = true; this.lbPaths.IntegralHeight = false; this.lbPaths.ItemHeight = 28; - this.lbPaths.Location = new System.Drawing.Point(0, 58); + this.lbPaths.Location = new System.Drawing.Point(0, 32); this.lbPaths.Name = "lbPaths"; - this.lbPaths.Size = new System.Drawing.Size(253, 233); + this.lbPaths.Size = new System.Drawing.Size(253, 259); this.lbPaths.TabIndex = 7; this.lbPaths.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.lbPaths_DrawItem); this.lbPaths.SelectedIndexChanged += new System.EventHandler(this.lbPaths_SelectedIndexChanged); @@ -232,6 +232,7 @@ this.toolTip1.SetToolTip(this.cbAdmin, "If there is no service located at root sunfish will show a listing page with all " + "availables services and paths."); this.cbAdmin.UseVisualStyleBackColor = true; + this.cbAdmin.Visible = false; this.cbAdmin.CheckedChanged += new System.EventHandler(this.cbAdmin_CheckedChanged); // // tbAdminPWD @@ -243,6 +244,7 @@ this.tbAdminPWD.PasswordChar = '•'; this.tbAdminPWD.Size = new System.Drawing.Size(150, 20); this.tbAdminPWD.TabIndex = 11; + this.tbAdminPWD.Visible = false; this.tbAdminPWD.TextChanged += new System.EventHandler(this.tbAdminPWD_TextChanged); // // Form1 diff --git a/Sunfish/Form1.resx b/Sunfish/Form1.resx index 086e21f..3818855 100644 --- a/Sunfish/Form1.resx +++ b/Sunfish/Form1.resx @@ -128,7 +128,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAq - AQAAAk1TRnQBSQFMAgEBAgEAAZABAAGQAQABEAEAARABAAT/AQUBAAj/AUIBTQF2BwABdgMAASgDAAFA + AQAAAk1TRnQBSQFMAgEBAgEAAZgBAAGYAQABEAEAARABAAT/AQUBAAj/AUIBTQF2BwABdgMAASgDAAFA AwABEAMAAQEBAAEEBgABAhgAAYACAAGAAwACgAEAAYADAAGAAQABgAEAAoACAAPAAQADgAMAAf8CAAH/ AwAC/wEAAf8DAAH/AQAB/wEAAv8CAAP//wD/AAMAAUIBTQE+BwABPgMAASgDAAFAAwABEAMAAQEBAAEB BQABgBcAA/8BAAT/BAAE/wQABP8EAAH8AT8C/wQAAfwBPwL/BAAB/AE/Av8EAAHgAQcB4AEHBAAB4AEH @@ -136,9 +136,6 @@ BAAL - - 17, 17 - 185, 17 diff --git a/Sunfish/Middleware/Templater.cs b/Sunfish/Middleware/Templater.cs index 004d6cd..6a8d5b7 100644 --- a/Sunfish/Middleware/Templater.cs +++ b/Sunfish/Middleware/Templater.cs @@ -88,32 +88,33 @@ return "Sunfish"; if (key == "AppVersion") return Program.VERSION; - foreach (object o in data) - { - if (o == null) - continue; - if (o is Dictionary) + if (data != null) + foreach (object o in data) { - Dictionary d = (Dictionary)o; - object v; - if (d.TryGetValue(key, out v)) - return v; - } - else - { - Type t = o.GetType(); - try + if (o == null) + continue; + if (o is Dictionary) { - PropertyInfo p = t.GetProperty(key); - if (p != null) - { - object v = p.GetValue(o); + Dictionary d = (Dictionary)o; + object v; + if (d.TryGetValue(key, out v)) return v; - } } - catch { }; + else + { + Type t = o.GetType(); + try + { + PropertyInfo p = t.GetProperty(key); + if (p != null) + { + object v = p.GetValue(o); + return v; + } + } + catch { }; + } } - } return null; } diff --git a/Sunfish/Middleware/WebUI.cs b/Sunfish/Middleware/WebUI.cs index 01413c0..db2443f 100644 --- a/Sunfish/Middleware/WebUI.cs +++ b/Sunfish/Middleware/WebUI.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.IO.Compression; using System.Linq; using System.Reflection; using System.Text; @@ -12,35 +13,68 @@ { static WebUI() { + DeletePresealed(); InitResources(); } #region Frontend Resources #if DEBUG - private static bool EXTERNAL_RESOURCES = true; + public static bool EXTERNAL_RESOURCES = true; private static string sfpath; #endif private const string SECBEGIN = ""; public static Dictionary Templs = new Dictionary(); + private static bool ready; + private static Dictionary Res = new Dictionary(); private static void InitResources() { -#if DEBUG - if (EXTERNAL_RESOURCES) + ready = false; + Templs.Clear(); + Res.Clear(); + using (FileStream fs = new FileStream(Assembly.GetExecutingAssembly().Location, FileMode.Open, FileAccess.Read)) { - Templs.Clear(); - sfpath=Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "$sunfish"); - EXTERNAL_RESOURCES = Directory.Exists(sfpath); - if (EXTERNAL_RESOURCES) + LocatePak(fs); + if (fs.Position < fs.Length) { - ProcessTemplate(File.ReadAllText(Path.Combine(sfpath, "$index.html"))); - return; + MemoryStream ms = new MemoryStream(); + ms.TransferFrom(fs, fs.Length - fs.Position - 5); + ms.Position = 0; + using (ZipArchive z = new ZipArchive(ms, ZipArchiveMode.Read, true)) + { + foreach (ZipArchiveEntry e in z.Entries) + { + byte[] ctt = new byte[e.Length]; + using (Stream zf = e.Open()) + zf.Read(ctt, 0, ctt.Length); + if (e.Name[0] == '$') + ProcessTemplate(Encoding.UTF8.GetString(ctt)); + else + Res[e.Name] = ctt; + } + } +#if DEBUG + EXTERNAL_RESOURCES = false; +#endif + ready = true; } } +#if DEBUG + if (!ready) + if (EXTERNAL_RESOURCES) + { + sfpath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "$sunfish"); + EXTERNAL_RESOURCES = Directory.Exists(sfpath); + if (EXTERNAL_RESOURCES) + { + ProcessTemplate(File.ReadAllText(Path.Combine(sfpath, "$templates.html"))); + ready = true; + return; + } + } #endif - } private static void ProcessTemplate(string template) @@ -65,6 +99,25 @@ #endregion + private static bool LocatePak(Stream s) + { + byte[] buf = new byte[5]; + s.Position = s.Length - buf.Length; + if (s.Read(buf, 0, buf.Length) != buf.Length) + throw new Exception("Probleams reading mark"); + if (Encoding.ASCII.GetString(buf) == "SFRes") + { + buf = new byte[4]; + s.Position = s.Length - (5 + buf.Length); + if (s.Read(buf, 0, buf.Length) != buf.Length) + throw new Exception("Probleams reading mark"); + s.Position = BitConverter.ToInt32(buf, 0); + return true; + } + s.Position = s.Length; + return false; + } + public static void WriteResource(string path, HttpCall call) { #if DEBUG @@ -74,7 +127,11 @@ return; } #endif - + byte[] data; + if (Res.TryGetValue(path, out data)) + call.Write(data, 0, data.Length); + else + throw new Exception("Resource not found"); } public static void WriteTemplate(string template, HttpCall call, params object[] para) @@ -86,8 +143,10 @@ Templater t; if (Templs.TryGetValue(template, out t)) call.Write(t.Process(para)); +#if DEBUG else throw new Exception("No template found for: " + template); +#endif } public static string FBytes(double lng) @@ -101,6 +160,62 @@ } return lng.ToString("#0.00") + (taili >= tail.Length ? "^b" : tail[taili]); } + + public static void Seal() + { + string mepath = Assembly.GetExecutingAssembly().Location; + string medir = Path.GetDirectoryName(mepath); + string oldpath = Path.Combine(medir, "Sunfish-preseal.exe"); + string spath = Path.Combine(medir, "$sunfish"); + if (!Directory.Exists(spath)) + throw new Exception("$sunfish directory with resources not found."); + + File.Move(mepath, oldpath); + + // Create resources ZIP + MemoryStream zms = new MemoryStream(); + using (ZipArchive z = new ZipArchive(zms, ZipArchiveMode.Create)) + { + foreach (string fname in Directory.GetFiles(spath)) + { + ZipArchiveEntry zae = z.CreateEntry(fname.Substring(spath.Length + 1)); + using (Stream zs = zae.Open()) + { + byte[] filall = File.ReadAllBytes(fname); + zs.Write(filall, 0, filall.Length); + } + } + } + + // Install package + using (FileStream ofs = new FileStream(oldpath, FileMode.Open, FileAccess.Read)) + { + LocatePak(ofs); + if (ofs.Position != ofs.Length) + ofs.SetLength(ofs.Position); + ofs.Position = 0; + + using (FileStream nfs = new FileStream(mepath, FileMode.Create, FileAccess.Write)) + { + nfs.TransferFrom(ofs, ofs.Length); + byte[] zz = zms.ToArray(); + nfs.Write(zz, 0, zz.Length); + zz = BitConverter.GetBytes((int)ofs.Length); + nfs.Write(zz, 0, zz.Length); + zz = Encoding.ASCII.GetBytes("SFRes"); + nfs.Write(zz, 0, zz.Length); + } + } + } + + public static void DeletePresealed() + { + string pspath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Sunfish-preseal.exe"); + if (File.Exists(pspath)) + File.Delete(pspath); + } + + public static bool Ready => ready; } public class WebUILink diff --git a/Sunfish/Program.cs b/Sunfish/Program.cs index adbede3..afd6e0c 100644 --- a/Sunfish/Program.cs +++ b/Sunfish/Program.cs @@ -6,7 +6,7 @@ { static class Program { - public static string VERSION = "2.0b5"; + public static string VERSION = "2.0"; private static Form1 mainform; /// /// Punto de entrada principal para la aplicación. diff --git a/Sunfish/Services/RootService.cs b/Sunfish/Services/RootService.cs index e5b7643..6fc07dd 100644 --- a/Sunfish/Services/RootService.cs +++ b/Sunfish/Services/RootService.cs @@ -70,7 +70,34 @@ call.Response.ContentType = "application/x-msdownload"; call.Write(File.ReadAllBytes(Assembly.GetExecutingAssembly().Location)); } + else if (path == "info") + { + WebUI.WriteTemplate("sunfish-header", call, null); + call.Write("

Sunfish " + Program.VERSION + " (C) XWolfOverride

"); +#if DEBUG + call.Write("

Debug build

"); + if (WebUI.EXTERNAL_RESOURCES) + call.Write("

Using external resources

"); + else + call.Write("

Using internal resources

"); +#else + call.Write("

Release build

"); +#endif + if (WebUI.Ready) + call.Write("

Resources loaded succesfully

"); + else + call.Write("

No resources

"); + call.Write("

Seal resources

"); + WebUI.WriteTemplate("sunfish-footer", call, null); + + } else if (path == "info/seal") + { + WebUI.Seal(); + call.Response.StatusCode = 307; + call.Response.Headers["Location"] = "/$sunfish/info"; + } else + { // Internal Resources WebUI.WriteResource(path, call);