static void Main() { Trace.Listeners.Add(new ConsoleTraceListener()); Paths = new SpringPaths(null); Scanner = new SpringScanner(Paths); Scanner.LocalResourceAdded += (s, e) => Trace.TraceInformation("New resource found: {0}", e.Item.InternalName); Scanner.LocalResourceRemoved += (s, e) => Trace.TraceInformation("Resource removed: {0}", e.Item.InternalName); SpringScanner.MapRegistered += (s, e) => Trace.TraceInformation("Map registered: {0}", e.MapName); SpringScanner.ModRegistered += (s, e) => Trace.TraceInformation("Mod registered: {0}", e.Data.Name); Scanner.Start(); Downloader = new PlasmaDownloader.PlasmaDownloader(new Config(), Scanner, Paths); Downloader.DownloadAdded += (s, e) => Trace.TraceInformation("Download started: {0}", e.Data.Name); Downloader.GetAndSwitchEngine(GlobalConst.DefaultEngineOverride); //for ZKL equivalent, see PlasmaShared/GlobalConst.cs Downloader.PackagesChanged += Downloader_PackagesChanged; while (true) { Thread.Sleep(10000); } /*Application.EnableVisualStyles(); * Application.SetCompatibleTextRenderingDefault(false); * Application.Run(new Form1());*/ }
public MainForm(SpringPaths paths = null, SpringScanner scanner = null, PlasmaDownloader.PlasmaDownloader downloader = null) { InitializeComponent(); if (paths != null) { springPaths = paths; } else { springPaths = new SpringPaths(null, writableFolderOverride: null); } if (scanner != null) { springScanner = scanner; } else { springScanner = new SpringScanner(springPaths); springScanner.Start(); } if (downloader != null) { springDownloader = downloader; } else { springDownloader = new PlasmaDownloader.PlasmaDownloader(new PlasmaConfig(), springScanner, springPaths); } var timer = new Timer(); timer.Tick += (sender, args) => { tbDownloads.Clear(); foreach (var d in springDownloader.Downloads.Where(x => x.IsComplete == null)) { tbDownloads.AppendText(string.Format("{1:F0}% {0} ETA: {2} {3}\n", d.Name, d.TotalProgress, d.TimeRemaining, d.IsComplete)); } }; timer.Interval = 1000; timer.Enabled = true; tbEngine.Text = springPaths.SpringVersion; }
//[STAThread] private static void Main(params string[] args) { var startupPath = Path.GetDirectoryName(Path.GetFullPath(Application.ExecutablePath)); var springPaths = new SpringPaths(startupPath); Spring runningSpring = null; TcpTransport connection = null; // speed up spring start springPaths.SpringVersionChanged += (sender, engine) => { Utils.StartAsync( () => { UnitSync unitSync = null; try { unitSync = new UnitSync(springPaths, engine); // initialize unitsync to avoid slowdowns when starting if (unitSync.UnitsyncWritableFolder != springPaths.WritableDirectory) { // unitsync created its cache in different folder than is used to start spring -> move it var fi = ArchiveCache.GetCacheFile(unitSync.UnitsyncWritableFolder); if (fi != null) { File.Copy(fi.FullName, Path.Combine(springPaths.WritableDirectory, "cache", fi.Name), true); } } } finally { unitSync?.Dispose(); } }); }; Config config = null; try { config = JsonConvert.DeserializeObject <Config>(File.ReadAllText(startupPath + "/config.json")); } catch (Exception) { } CefWrapper.Initialize(startupPath + "/render", args); var springScanner = new SpringScanner(springPaths); springScanner.Start(); EventHandler <ProgressEventArgs> workHandler = (s, e) => { CefWrapper.ExecuteJavascript("on_spring_scanner_work(" + JsonConvert.SerializeObject(e) + ");"); }; springScanner.WorkStarted += workHandler; springScanner.WorkProgressChanged += workHandler; springScanner.WorkStopped += (s, e) => { CefWrapper.ExecuteJavascript("on_spring_scanner_work(null);"); }; springScanner.LocalResourceAdded += (s, e) => { CefWrapper.ExecuteJavascript("on_spring_scanner_add(" + JsonConvert.SerializeObject(e.Item) + ")"); }; springScanner.LocalResourceRemoved += (s, e) => { CefWrapper.ExecuteJavascript("on_spring_scanner_remove(" + JsonConvert.SerializeObject(e.Item) + ")"); }; var downloader = new PlasmaDownloader.PlasmaDownloader(springScanner, springPaths); //rapid downloader.GetResource(DownloadType.ENGINE, GlobalConst.DefaultEngineOverride); // ZKL's downloader doesn't send events to monitor download progress, so we have to poll it. Timer pollDownloads = new Timer(); pollDownloads.Interval = 250; pollDownloads.Tick += (s, e) => { CefWrapper.ExecuteJavascript("on_downloads_change(" + JsonConvert.SerializeObject(downloader.Downloads) + ")"); }; // Through some WinAPI dark magic it manages to use the message pump in the window that is run by CEF. // Can this be dangerous? pollDownloads.Start(); CefWrapper.RegisterApiFunction( "getEngines", () => { return(new List <string> { "100.0" }); // TODO: stub }); CefWrapper.RegisterApiFunction("getMods", () => { return(springScanner.GetAllModResource()); }); CefWrapper.RegisterApiFunction("getMaps", () => { return(springScanner.GetAllMapResource()); }); CefWrapper.RegisterApiFunction( "downloadEngine", (string engine) => { // Don't let GetAndSwitchEngine() touch the main SpringPaths. var path = new SpringPaths(springPaths.WritableDirectory); downloader.GetResource(DownloadType.ENGINE, engine); }); CefWrapper.RegisterApiFunction("downloadMod", (string game) => { downloader.GetResource(DownloadType.MOD, game); }); CefWrapper.RegisterApiFunction("downloadMap", (string map) => { downloader.GetResource(DownloadType.MAP, map); }); CefWrapper.RegisterApiFunction( "abortDownload", (string name) => { downloader.Downloads.FirstOrDefault(d => d.Name == name)?.Abort(); }); CefWrapper.RegisterApiFunction( "startSpringScript", (string engineVer, string script) => { if (runningSpring != null) { return(null); } // Ultimately we should get rid of the concept of a "current set engine", but for now let's work around it. var path = new SpringPaths(springPaths.WritableDirectory); runningSpring = new Spring(path); runningSpring.SpringExited += (obj, evt) => { CefWrapper.ExecuteJavascript("on_spring_exit(" + (evt.IsCrash ? "true" : "false") + ");"); runningSpring = null; }; try { runningSpring.RunLocalScriptGame(script, engineVer); return(null); } catch (Exception e) { runningSpring = null; return(e.Message); } }); CefWrapper.RegisterApiFunction( "connect", (string host, int port) => { if (connection != null) { connection.RequestClose(); } connection = new TcpTransport(host, port); connection.ConnectAndRun( async(s) => CefWrapper.ExecuteJavascript( $"on_lobby_message({CefWrapper.mangleUtf8(JsonConvert.SerializeObject(s))})"), async() => { }, async(requested) => CefWrapper.ExecuteJavascript( $"on_connection_closed({CefWrapper.mangleUtf8(JsonConvert.SerializeObject(requested))})") ); }); CefWrapper.RegisterApiFunction("disconnect", () => connection?.RequestClose()); CefWrapper.RegisterApiFunction("sendLobbyMessage", (string msg) => connection?.SendLine(CefWrapper.unmangleUtf8(msg) + '\n')); CefWrapper.RegisterApiFunction( "readConfig", () => { try { return(JsonConvert.DeserializeObject(File.ReadAllText(startupPath + "/config.json"))); } catch (FileNotFoundException) { return(null); } }); CefWrapper.RegisterApiFunction("saveConfig", (object conf) => File.WriteAllText(startupPath + "/config.json", JsonConvert.SerializeObject(conf, Formatting.Indented))); CefWrapper.RegisterApiFunction("setFullscreen", (bool fullscreen) => CefWrapper.SetFullscreen(fullscreen)); var fileUrl = new Uri(startupPath + "/zkwl/index.html"); CefWrapper.StartMessageLoop(fileUrl.AbsoluteUri, "black", !config?.lobbyWindowed ?? true); CefWrapper.Deinitialize(); downloader.Dispose(); springScanner.Dispose(); }