Exemple #1
0
        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());*/
        }
Exemple #2
0
 public PlasmaDownloader(IPlasmaDownloaderConfig config, SpringScanner scanner, SpringPaths springPaths)
 {
     SpringPaths  = springPaths;
     Config       = config;
     this.scanner = scanner;
     //torrentDownloader = new TorrentDownloader(this);
     packageDownloader = new PackageDownloader(this);
 }
Exemple #3
0
        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;
        }
Exemple #4
0
        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;
        }
Exemple #5
0
        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 { }
        }
Exemple #6
0
        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();
        }