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 PlasmaDownloader(IPlasmaDownloaderConfig config, SpringScanner scanner, SpringPaths springPaths) { SpringPaths = springPaths; Config = config; this.scanner = scanner; //torrentDownloader = new TorrentDownloader(this); packageDownloader = new PackageDownloader(this); }
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; }
public ScannerBar(SpringScanner scanner) { InitializeComponent(); var isDesigner = Process.GetCurrentProcess().ProcessName == "devenv"; // workaround for this.DesignMode not working if (isDesigner) { return; } scanner.WorkStarted += scanner_WorkProgressChanged; scanner.WorkStopped += scanner_WorkStopped; scanner.WorkProgressChanged += scanner_WorkProgressChanged; }
private static void FinalizeShutdown() { HistoryManager.FlushBuffer(); Conf.IsFirstRun = false; if (Conf.DiscardPlayerName == true) { Conf.LobbyPlayerName = ""; } if (Conf.DiscardPassword == true) { Conf.LobbyPlayerPassword = ""; } SaveConfig(); try { if (!Debugger.IsAttached) { mutex.ReleaseMutex(); } } catch { } try { if (ToolTip != null) { ToolTip.Dispose(); } if (Downloader != null) { Downloader.Dispose(); } if (SpringScanner != null) { SpringScanner.Dispose(); } if (SteamHandler != null) { SteamHandler.Dispose(); } } catch { } }
public static void Main(string[] args) { try { //Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); Trace.Listeners.Add(new ConsoleTraceListener()); Trace.Listeners.Add(new LogTraceListener()); /* * if (Environment.OSVersion.Platform != PlatformID.Unix) * { * var ver = GetNetVersionFromRegistry(); * if (ver < 378675) * { * MessageBox.Show("Zero-K launcher needs Microsoft .NET framework 4.5.1\nPlease download and install it first", * "Program is unable to run", MessageBoxButtons.OK, MessageBoxIcon.Error); * } * } */ Directory.SetCurrentDirectory(StartupPath); SelfUpdater = new SelfUpdater("Zero-K_NET4.0"); // if (Process.GetProcesses().Any(x => x.ProcessName.StartsWith("spring_"))) return; // dont start if started from installer StartupArgs = args; Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); if (!Debugger.IsAttached) { AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; Thread.GetDomain().UnhandledException += UnhandledException; Application.ThreadException += Application_ThreadException; Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); } //HttpWebRequest.DefaultCachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore); Trace.TraceInformation("Starting with version {0}", SelfUpdater.CurrentVersion); WebRequest.DefaultWebProxy = null; ThreadPool.SetMaxThreads(500, 2000); ServicePointManager.Expect100Continue = false; if (Environment.OSVersion.Platform != PlatformID.Unix && !Conf.UseExternalBrowser) { Utils.SetIeCompatibility(); } //set to current IE version LoadConfig(); var contentDir = !string.IsNullOrEmpty(Conf.DataFolder) ? Conf.DataFolder : StartupPath; if (!Directory.Exists(contentDir) || !SpringPaths.IsDirectoryWritable(contentDir) || pickInitFolder) { var dc = new SelectWritableFolder() { SelectedPath = SpringPaths.GetMySpringDocPath() }; if (dc.ShowDialog() != DialogResult.OK) { return; } contentDir = dc.SelectedPath; } if (Conf.DataFolder != StartupPath) { Conf.DataFolder = contentDir; } else { Conf.DataFolder = null; } if (!SpringPaths.IsDirectoryWritable(StartupPath) || StartupPath.Contains("Local\\Apps")) { MessageBox.Show( string.Format( "Please use the newly created desktop icon to start Zero-K not this one.\r\nZero-K.exe will be moved to {0}", contentDir), "Startup directory is not writable!"); var newTarget = Path.Combine(contentDir, "Zero-K.exe"); if (SelfUpdater.CheckForUpdate(newTarget, true)) { Conf.Save(Path.Combine(contentDir, Config.ConfigFileName)); Process.Start(newTarget); return; } MessageBox.Show("Move failed, please copy Zero-K.exe to a writable folder"); } if (Conf.IsFirstRun) { Utils.CreateDesktopShortcut(); if (Environment.OSVersion.Platform != PlatformID.Unix) { Utils.RegisterProtocol(); } } SpringPaths = new SpringPaths(null, writableFolderOverride: contentDir); SpringPaths.MakeFolders(); SpringPaths.SetEnginePath(Utils.MakePath(SpringPaths.WritableDirectory, "engine", ZkData.GlobalConst.DefaultEngineOverride ?? TasClient.ServerSpringVersion)); // run unitsync as soon as possible so we don't have to spend several minutes doing it on game start // two problems: // 1) unitsync can only be loaded once, even if in a different directory http://msdn.microsoft.com/en-us/library/ms682586.aspx#factors_that_affect_searching // so if we do it in SpringVersionChanged it'll be done at startup for GlobalConst.DefaultEngineOverride, then for no other engine version // 2) unitsync can't be unloaded http://stackoverflow.com/questions/1371877/how-to-unload-the-dll-using-c // also see EngineDownload.cs //SpringPaths.SpringVersionChanged += (s, e) => //{ // //System.Diagnostics.Trace.TraceInformation("SpringPaths version: {0}", SpringPaths.SpringVersion); // //new PlasmaShared.UnitSyncLib.UnitSync(SpringPaths); // //SpringScanner.VerifyUnitSync(); // //if (SpringScanner != null) SpringScanner.Dispose(); // //SpringScanner = new SpringScanner(SpringPaths); // //SpringScanner.Start(); //}; SaveConfig(); try { if (!Debugger.IsAttached) { var wp = ""; foreach (var c in SpringPaths.WritableDirectory.Where(x => (x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z'))) { wp += c; } mutex = new Mutex(false, "ZeroKLobby" + wp); if (!mutex.WaitOne(10000, false)) { MessageBox.Show( "Another copy of Zero-K lobby is still running" + "\nMake sure the other lobby is closed (check task manager) before starting new one", "There can be only one lobby running", MessageBoxButtons.OK, MessageBoxIcon.Stop); return; } } } catch (AbandonedMutexException) { } FriendManager = new FriendManager(); AutoJoinManager = new AutoJoinManager(); EngineConfigurator = new EngineConfigurator(SpringPaths.WritableDirectory); SpringScanner = new SpringScanner(SpringPaths); SpringScanner.LocalResourceAdded += (s, e) => Trace.TraceInformation("New resource found: {0}", e.Item.InternalName); SpringScanner.LocalResourceRemoved += (s, e) => Trace.TraceInformation("Resource removed: {0}", e.Item.InternalName); if (Program.Conf.EnableUnitSyncPrompt && Environment.OSVersion.Platform != PlatformID.Unix) { SpringScanner.UploadUnitsyncData += MicroForms.UnitSyncUploadPrompt.SpringScanner_UploadUnitsyncData; SpringScanner.RetryResourceCheck += MicroForms.UnitSyncRetryPrompt.SpringScanner_RetryGetResourceInfo; } SpringScanner.MapRegistered += (s, e) => Trace.TraceInformation("Map registered: {0}", e.MapName); SpringScanner.ModRegistered += (s, e) => Trace.TraceInformation("Mod registered: {0}", e.Data.Name); Downloader = new PlasmaDownloader.PlasmaDownloader(Conf, SpringScanner, SpringPaths); //rapid Downloader.DownloadAdded += (s, e) => Trace.TraceInformation("Download started: {0}", e.Data.Name); var isLinux = Environment.OSVersion.Platform == PlatformID.Unix; TasClient = new TasClient(string.Format("ZK {0}{1}", SelfUpdater.CurrentVersion, isLinux ? " linux" : "")); SayCommandHandler = new SayCommandHandler(TasClient); ServerImages = new ServerImagesHandler(SpringPaths, TasClient); // log, for debugging TasClient.Connected += (s, e) => Trace.TraceInformation("TASC connected"); TasClient.LoginAccepted += (s, e) => { Trace.TraceInformation("TASC login accepted"); Trace.TraceInformation("Server is using Spring version {0}", TasClient.ServerSpringVersion); if (Environment.OSVersion.Platform == PlatformID.Unix || Conf.UseExternalBrowser) { MainWindow.navigationControl.Path = "battles"; } }; TasClient.LoginDenied += (s, e) => Trace.TraceInformation("TASC login denied"); TasClient.ChannelJoined += (s, e) => { Trace.TraceInformation("TASC channel joined: " + e.Data.Name); }; TasClient.ConnectionLost += (s, e) => Trace.TraceInformation("Connection lost"); // special handling TasClient.PreviewSaid += (s, e) => { var tas = (TasClient)s; User user = null; if (e.Data.UserName != null) { tas.ExistingUsers.TryGetValue(e.Data.UserName, out user); if ((user != null && user.BanMute) || Conf.IgnoredUsers.Contains(e.Data.UserName)) { e.Cancel = true; } } }; TasClient.Extensions.JsonDataReceived += (eventArgs, o) => { var command = o as ProtocolExtension.SiteToLobbyCommand; if (command != null) { MainWindow.navigationControl.Path = command.SpringLink; MainWindow.PopupSelf(); } }; ConnectBar = new ConnectBar(TasClient); ModStore = new ModStore(); ToolTip = new ToolTipHandler(); BrowserInterop = new BrowserInterop(TasClient, Conf); BattleIconManager = new BattleIconManager(); Application.AddMessageFilter(ToolTip); SteamHandler = new ZklSteamHandler(TasClient); SteamHandler.Connect(); MainWindow = new MainWindow(); Application.AddMessageFilter(new ScrollMessageFilter()); if (Conf.StartMinimized) { MainWindow.WindowState = FormWindowState.Minimized; } else { MainWindow.WindowState = FormWindowState.Normal; } MainWindow.Size = new Size(Math.Min(SystemInformation.VirtualScreen.Width - 30, MainWindow.Width), Math.Min(SystemInformation.VirtualScreen.Height - 30, MainWindow.Height)); //in case user have less space than 1024x768 BattleBar = new BattleBar(); NewVersionBar = new NewVersionBar(SelfUpdater); VoteBar = new VoteBar(); PwBar = new PwBar(); //This make the size of every bar constant (only for height). //We wanted to make them constant because the bar get DPI-scaled twice/thrice/multiple-time (especially for reusable bar). //Setting maximum height upon creation will hopefully make sure it is not DPI-scaled multiple time. var votebarSize = new Size(0, VoteBar.Height); // Reference: http://stackoverflow.com/questions/5314041/set-minimum-window-size-in-c-sharp-net var newversionbarSize = new Size(0, NewVersionBar.Height); var battlebarSize = new Size(0, BattleBar.Height); var connectbarSize = new Size(0, ConnectBar.Height); VoteBar.MinimumSize = votebarSize; //fix minimum size forever VoteBar.MaximumSize = votebarSize; //fix maximum size forever NewVersionBar.MinimumSize = newversionbarSize; NewVersionBar.MaximumSize = newversionbarSize; BattleBar.MinimumSize = battlebarSize; BattleBar.MaximumSize = battlebarSize; ConnectBar.MinimumSize = connectbarSize; ConnectBar.MaximumSize = connectbarSize; //End battlebar size hax if (!Debugger.IsAttached && !Conf.DisableAutoUpdate) { Program.SelfUpdater.StartChecking(); } //if (Conf.IsFirstRun) Utils.OpenWeb(GlobalConst.BaseSiteUrl + "/Wiki/LobbyStart", false); // download primary engine & game MainWindow.Paint += GetSpringZK; Downloader.PackageDownloader.MasterManifestDownloaded += GetSpringZK; // Format and display the TimeSpan value. //stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10); //Trace.TraceInformation("1 Runtime {0}", elapsedTime); Application.Run(MainWindow); ShutDown(); } catch (Exception ex) { ErrorHandling.HandleException(ex, true); } finally { ShutDown(); } if (ErrorHandling.HasFatalException && !Program.CloseOnNext) { Application.Restart(); } }
//[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(); }