Пример #1
0
        public ZkLobbyServer(string geoIPpath, IPlanetwarsEventCreator creator, ITopPlayerProvider topPlayerProvider)
        {
            RatingSystems.Init();

            TopPlayerProvider      = topPlayerProvider;
            PlanetWarsEventCreator = creator;
            var entry = Assembly.GetExecutingAssembly();

            Version = entry.GetName().Version.ToString();
            Engine  = MiscVar.DefaultEngine;

            SpringPaths = new SpringPaths(GlobalConst.SpringieDataDir, false, false);
            Downloader  = new PlasmaDownloader.PlasmaDownloader(null, SpringPaths);
            Downloader.GetResource(DownloadType.ENGINE, MiscVar.DefaultEngine);
            Downloader.PackageDownloader.DoMasterRefresh();

            Game = Downloader.PackageDownloader.GetByTag(GlobalConst.DefaultZkTag).InternalName;

            LoginChecker = new LoginChecker(this, geoIPpath);
            SteamWebApi  = new SteamWebApi(GlobalConst.SteamAppID, new Secrets().GetSteamWebApiKey());
            chatRelay    = new ChatRelay(this, new List <string>()
            {
                "zkdev", "sy", "moddev", "weblobbydev", "ai", "zk", "zkmap", "springboard", GlobalConst.ModeratorChannel, GlobalConst.CoreChannel
            });
            textCommands         = new ServerTextCommands(this);
            ChannelManager       = new ChannelManager(this);
            MatchMaker           = new MatchMaker(this);
            battleListUpdater    = new BattleListUpdater(this);
            PartyManager         = new PartyManager(this);
            PlanetWarsMatchMaker = new PlanetWarsMatchMaker(this);
        }
Пример #2
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);

            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;
        }
Пример #3
0
        public static async Task <bool> DownloadFile(this PlasmaDownloader downloader,
                                                     string desc,
                                                     DownloadType type,
                                                     string name,
                                                     IChobbylaProgress progress, int retries = 0)
        {
            Download down;

            do
            {
                down = downloader.GetResource(type, name);

                if (progress != null)
                {
                    progress.Status   = desc;
                    progress.Download = down;
                }

                var dlTask = down?.WaitHandle.AsTask(TimeSpan.FromMinutes(30));
                if (dlTask != null)
                {
                    await dlTask.ConfigureAwait(false);
                }
            } while (down?.IsAborted != true && down?.IsComplete != true && retries-- > 0);

            if (down?.IsComplete == false)
            {
                if (progress != null)
                {
                    progress.Status = $"Download of {progress.Download.Name} has failed";
                }
                return(false);
            }
            return(true);
        }
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        public void Main()
        {

            Paths = new SpringPaths(Path.Combine(sitePath, "autoregistrator"), false);
            Scanner = new SpringScanner(Paths) { UseUnitSync = true, WatchingEnabled = false};

            Scanner.LocalResourceAdded += (s, e) => Trace.TraceInformation("Autoregistrator new resource found: {0}", e.Item.InternalName);
            Scanner.LocalResourceRemoved += (s, e) => Trace.TraceInformation("Autoregistrator Resource removed: {0}", e.Item.InternalName);

            SpringScanner.MapRegistered += (s, e) => Trace.TraceInformation("Autoregistrator Map registered: {0}", e.MapName);
            SpringScanner.ModRegistered += (s, e) => Trace.TraceInformation("Autoregistrator Mod registered: {0}", e.Data.Name);


            Downloader = new PlasmaDownloader.PlasmaDownloader(Scanner, Paths);
            Downloader.DownloadAdded += (s, e) => Trace.TraceInformation("Autoregistrator Download started: {0}", e.Data.Name);
            Downloader.GetResource(DownloadType.ENGINE, MiscVar.DefaultEngine)?.WaitHandle.WaitOne(); //for ZKL equivalent, see PlasmaShared/GlobalConst.cs
            Scanner.InitialScan();

            Downloader.PackageDownloader.SetMasterRefreshTimer(20);
            Downloader.PackagesChanged += Downloader_PackagesChanged;
            Downloader.PackageDownloader.LoadMasterAndVersions()?.Wait();
            Downloader.GetResource(DownloadType.MOD, "zk:stable")?.WaitHandle.WaitOne();
            Downloader.GetResource(DownloadType.MOD, "zk:test")?.WaitHandle.WaitOne();

            lastStableVersion = Downloader.PackageDownloader.GetByTag("zk:stable").InternalName;

            foreach (var ver in Downloader.PackageDownloader.Repositories.SelectMany(x => x.VersionsByTag).Where(x => x.Key.StartsWith("spring-features")))
            {
                Downloader.GetResource(DownloadType.UNKNOWN, ver.Value.InternalName)?.WaitHandle.WaitOne();
            }

            Scanner.Start(false);

            while (Scanner.GetWorkCost() > 0) Thread.Sleep(1000);
        }
Пример #5
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());*/
        }
Пример #6
0
        public MainForm(SpringPaths paths, IResourcePresenceChecker scanner = null, PlasmaDownloader.PlasmaDownloader downloader = null) {
            InitializeComponent();
            springPaths = paths;
            if (scanner != null) springScanner = scanner;
            else {
                var pl = new PlasmaResourceChecker(springPaths);
                springScanner = pl;
                pl.Start();
            }
            if (downloader != null)  springDownloader = downloader;
            else springDownloader = new PlasmaDownloader.PlasmaDownloader(springScanner, springPaths);

            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 = GlobalConst.DefaultEngineOverride;
        }
Пример #7
0
 public Chobbyla(string rootPath, string chobbyTagOverride, string engineOverride)
 {
     paths = new SpringPaths(rootPath, false);
     chobbyTag = chobbyTagOverride ?? (GlobalConst.Mode == ModeType.Live ? "zkmenu:stable" : "zkmenu:test");
     isDev = chobbyTag == "dev" || chobbyTag == "chobby:dev" || chobbyTag =="zkmenu:dev";
     engine = engineOverride;
     downloader = new PlasmaDownloader.PlasmaDownloader(null, paths);
 }
Пример #8
0
 public Chobbyla(string rootPath, string chobbyTagOverride, string engineOverride)
 {
     paths      = new SpringPaths(rootPath, false, true);
     chobbyTag  = chobbyTagOverride ?? GlobalConst.DefaultChobbyTag;
     isDev      = (chobbyTag == "dev") || (chobbyTag == "chobby:dev") || (chobbyTag == "zkmenu:dev");
     IsSteam    = File.Exists(Path.Combine(paths.WritableDirectory, "steamfolder.txt"));
     engine     = engineOverride;
     downloader = new PlasmaDownloader.PlasmaDownloader(null, paths);
 }
Пример #9
0
        public static bool DownloadUrl(this PlasmaDownloader downloader,
                                       string desc,
                                       string url,
                                       string filePathTarget,
                                       IChobbylaProgress progress)
        {
            progress.Status = desc;
            var wfd = new WebClient();

            wfd.DownloadFile(url, filePathTarget);
            return(true);
        }
 public string Validate(PlasmaDownloader.PlasmaDownloader downloader, bool waitForDownload = false) {
     var map = GetScriptMap();
     if (map != null) {
         var dl = downloader.GetResource(DownloadType.MAP, map);
         if (waitForDownload) {
             if (dl != null) {
                 dl.WaitHandle.WaitOne();
                 if (dl.IsComplete == false) return "Failed to download map " + map;
             } 
         }
     }
     return null;
 }
Пример #11
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;
        }
Пример #12
0
        public ZkLobbyServer(string geoIPpath, IPlanetwarsEventCreator creator)
        {
            RatingSystems.Init();
            MapRatings.Init();


            PlanetWarsEventCreator = creator;
            var entry = Assembly.GetExecutingAssembly();

            Version = entry.GetName().Version.ToString();
            Engine  = MiscVar.DefaultEngine;

            SpringPaths = new SpringPaths(GlobalConst.SpringieDataDir, false, false);
            Downloader  = new PlasmaDownloader.PlasmaDownloader(null, SpringPaths);
            Downloader.GetResource(DownloadType.ENGINE, MiscVar.DefaultEngine);
            Downloader.PackageDownloader.DoMasterRefresh();

            Game = MiscVar.LastRegisteredZkVersion;

            LoginChecker = new LoginChecker(this, geoIPpath);
            SteamWebApi  = new SteamWebApi(GlobalConst.SteamAppID, new Secrets().GetSteamWebApiKey());
            chatRelay    = new ChatRelay(this, new List <string>()
            {
                "zkdev", "sy", "moddev", "weblobbydev", "ai", "zk", "zkmap", "springboard", GlobalConst.ModeratorChannel, GlobalConst.CoreChannel, "off-topic", "support", "modding", "crashreports"
            });
            textCommands         = new ServerTextCommands(this);
            ChannelManager       = new ChannelManager(this);
            MatchMaker           = new MatchMaker(this);
            battleListUpdater    = new BattleListUpdater(this);
            PartyManager         = new PartyManager(this);
            PlanetWarsMatchMaker = new PlanetWarsMatchMaker(this);
            NewsListManager      = new NewsListManager(this);
            LadderListManager    = new LadderListManager(this);
            ForumListManager     = new ForumListManager(this);

            SpawnAutohosts();

            RatingSystems.GetRatingSystems().ForEach(x => x.RatingsUpdated += (sender, data) =>
            {
                var db           = new ZkDataContext();
                var updatedUsers = ConnectedUsers.Select(c => c.Value.User.AccountID).Intersect(data.affectedPlayers).ToHashSet();
                db.Accounts.Where(acc => updatedUsers.Contains(acc.AccountID)).ForEach(p =>
                {
                    PublishAccountUpdate(p);
                    PublishUserProfileUpdate(p);
                });
            });
        }
Пример #13
0
        public MainForm(SpringPaths paths, IResourcePresenceChecker scanner = null, PlasmaDownloader.PlasmaDownloader downloader = null)
        {
            InitializeComponent();
            springPaths = paths;
            if (scanner != null)
            {
                springScanner = scanner;
            }
            else
            {
                var pl = new PlasmaResourceChecker(springPaths);
                springScanner = pl;
                pl.Start();
            }
            if (downloader != null)
            {
                springDownloader = downloader;
            }
            else
            {
                springDownloader = new PlasmaDownloader.PlasmaDownloader(springScanner, springPaths);
            }

            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 = GlobalConst.DefaultEngineOverride;
        }
Пример #14
0
        public string Validate(PlasmaDownloader.PlasmaDownloader downloader, bool waitForDownload = false)
        {
            var map = GetScriptMap();

            if (map != null)
            {
                var dl = downloader.GetResource(DownloadType.MAP, map);
                if (waitForDownload)
                {
                    if (dl != null)
                    {
                        dl.WaitHandle.WaitOne();
                        if (dl.IsComplete == false)
                        {
                            return("Failed to download map " + map);
                        }
                    }
                }
            }
            return(null);
        }
        public void Generate() {
            Utils.CheckPath(targetFolder);
            var paths = new SpringPaths(targetFolder, false);
            try
            {
                //Directory.Delete(Path.Combine(paths.WritableDirectory, "pool"), true);
                Directory.Delete(Path.Combine(paths.WritableDirectory, "packages"), true);
                Directory.CreateDirectory(Path.Combine(paths.WritableDirectory, "packages"));
            } catch { }
            

            var downloader = new PlasmaDownloader.PlasmaDownloader(null, paths);
            downloader.GetResource(DownloadType.ENGINE, MiscVar.DefaultEngine)?.WaitHandle.WaitOne(); //for ZKL equivalent, see PlasmaShared/GlobalConst.cs
            downloader.GetResource(DownloadType.RAPID, "zk:stable")?.WaitHandle.WaitOne();
            downloader.GetResource(DownloadType.RAPID, "zk:test")?.WaitHandle.WaitOne();

            CopyResources(siteBase, paths, GetResourceList(downloader.PackageDownloader.GetByTag("zk:stable").InternalName, downloader.PackageDownloader.GetByTag("zk:test").InternalName), downloader);

            CopyLobbyProgram();
            CopyExtraImages();
        }
Пример #16
0
 /// <summary>
 /// Validate content files - starts downloads
 /// </summary>
 public string Validate(PlasmaDownloader.PlasmaDownloader downloader, bool waitForDownload)
 {
     foreach (var dep in
              GetDependencies().Where(x => !UnitSync.DependencyExceptions.Contains(x)))
     {
         if (GetBenchmarks(downloader.SpringPaths).Any(y => y.GetSpringName() == dep || y.Name == dep))
         {
             continue;
         }
         var dl = downloader.GetResource(DownloadType.MOD, dep);
         if (dl != null && waitForDownload)
         {
             dl.WaitHandle.WaitOne();
             if (dl.IsComplete == false)
             {
                 return("Failed to download dependency mod " + dep);
             }
         }
     }
     return(null);
 }
Пример #17
0
 public static bool UpdatePublicCommunityInfo(this PlasmaDownloader downloader, IChobbylaProgress progress)
 {
     try
     {
         progress.Status = "Loading community news";
         var folder = Path.Combine(downloader.SpringPaths.WritableDirectory, "news");
         if (!Directory.Exists(folder))
         {
             Directory.CreateDirectory(folder);
         }
         var info = GlobalConst.GetContentService().GetPublicCommunityInfo();
         File.WriteAllText(Path.Combine(folder, "community.json"), JsonConvert.SerializeObject(info));
         return(true);
     }
     catch (Exception ex)
     {
         Trace.TraceError("Loading public community info failed: {0}", ex);
         progress.Status = "Loading community news failed";
         return(false);
     }
 }
        /// <summary>
        ///     The main entry point for the application.
        /// </summary>
        public void Main()
        {
            Paths = new SpringPaths(Path.Combine(sitePath, "autoregistrator"), false);

            
            Downloader = new PlasmaDownloader.PlasmaDownloader(null, Paths);
            Downloader.DownloadAdded += (s, e) => Trace.TraceInformation("Autoregistrator Download started: {0}", e.Data.Name);
            Downloader.GetResource(DownloadType.ENGINE, MiscVar.DefaultEngine)?.WaitHandle.WaitOne();
            //for ZKL equivalent, see PlasmaShared/GlobalConst.cs

            UnitSyncer = new UnitSyncer(Paths, MiscVar.DefaultEngine);

            Downloader.PackageDownloader.DoMasterRefresh();
            Downloader.GetResource(DownloadType.RAPID, "zk:stable")?.WaitHandle.WaitOne();
            Downloader.GetResource(DownloadType.RAPID, "zk:test")?.WaitHandle.WaitOne();

            foreach (
                var ver in Downloader.PackageDownloader.Repositories.SelectMany(x => x.VersionsByTag).Where(x => x.Key.StartsWith("spring-features"))) Downloader.GetResource(DownloadType.RAPID, ver.Value.InternalName)?.WaitHandle.WaitOne();

            OnRapidChanged();
        }
Пример #19
0
        /// <summary>
        /// Validates content - starts downloads, return null if all ok so far
        /// </summary>
        public string Validate(PlasmaDownloader.PlasmaDownloader downloader, bool waitDownload = false) {
            if (string.IsNullOrEmpty(Engine)) return "Engine name not set";

            if (StartScript == null) return "Please select a start script - put start scripts in Benchmarks/Scripts folder";
            if (Config == null) return "Please select a config to use - create folders with configs in Benchmarks/Configs folder";

            var de = downloader.GetResource(DownloadType.ENGINE, Engine);
            Download dm = null;

            if (!string.IsNullOrEmpty(Map)) {
                dm = downloader.GetResource(DownloadType.MAP, Map);
            }

            Download dg = null;
            if (!string.IsNullOrEmpty(Game)) {
                var ver = downloader.PackageDownloader.GetByTag(Game);
                if (ver != null) Game = ver.InternalName;
                dg = downloader.GetResource(DownloadType.RAPID, Game);
                }

            if (waitDownload) {
                if (de != null) {
                    de.WaitHandle.WaitOne();
                    if (de.IsComplete == false) return "Failed download of engine " + de.Name;
                } 
                if (dm != null) {
                    dm.WaitHandle.WaitOne();
                    if (dm.IsComplete == false)return "Failed download of map " + dm.Name;
                }
                if (dg != null) {
                    dg.WaitHandle.WaitOne();
                    if (dg.IsComplete == false) return "Failed download of game " + dg.Name;
                } 
            }

            var sVal = StartScript.Validate(downloader, waitDownload);
            if (sVal != null) return sVal;

            return null;
        }
Пример #20
0
        /// <summary>
        ///     The main entry point for the application.
        /// </summary>
        public void Main()
        {
            Paths = new SpringPaths(Path.Combine(sitePath, "autoregistrator"), false, Environment.Is64BitProcess);

            // delete all maps and packages to speed up startup
            DeleteAllPackages();
            DeleteAllMaps();



            Downloader = new PlasmaDownloader.PlasmaDownloader(null, Paths);
            Downloader.DownloadAdded += (s, e) => Trace.TraceInformation("Autoregistrator Download started: {0}", e.Data.Name);
            Downloader.GetResource(DownloadType.ENGINE, GlobalConst.UnitSyncEngine)?.WaitHandle.WaitOne();
            //for ZKL equivalent, see PlasmaShared/GlobalConst.cs

            UnitSyncer = new UnitSyncer(Paths, GlobalConst.UnitSyncEngine);

            Downloader.PackageDownloader.DoMasterRefresh();
            //LoadAllSpringFeatures();

            OnRapidChanged();
        }
Пример #21
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());*/
        }
        public void Generate() {
            Utils.CheckPath(targetFolder);
            var paths = new SpringPaths(null, targetFolder, false);
            try
            {
                //Directory.Delete(Path.Combine(paths.WritableDirectory, "pool"), true);
                Directory.Delete(Path.Combine(paths.WritableDirectory, "packages"), true);
            } catch { }
            

            paths.MakeFolders();
            var downloader = new PlasmaDownloader.PlasmaDownloader(null, paths);
            downloader.GetAndSwitchEngine(GlobalConst.DefaultEngineOverride)?.WaitHandle.WaitOne(); //for ZKL equivalent, see PlasmaShared/GlobalConst.cs
            downloader.PackageDownloader.LoadMasterAndVersions(false).Wait();
            downloader.GetResource(DownloadType.MOD, "zk:stable")?.WaitHandle.WaitOne();
            downloader.GetResource(DownloadType.MOD, "zk:test")?.WaitHandle.WaitOne();

            CopyResources(siteBase, paths, GetResourceList(downloader.PackageDownloader.GetByTag("zk:stable").InternalName, downloader.PackageDownloader.GetByTag("zk:test").InternalName), downloader);

            CopyLobbyProgram();
            CopyExtraImages();
            ScanArchives(paths);
        }
Пример #23
0
 public static bool UpdateFeaturedCustomGameModes(this PlasmaDownloader downloader, IChobbylaProgress progress)
 {
     try
     {
         progress.Status = "Loading custom game modes";
         var folder = Path.Combine(downloader.SpringPaths.WritableDirectory, "CustomModes");
         if (!Directory.Exists(folder))
         {
             Directory.CreateDirectory(folder);
         }
         var modes = GlobalConst.GetContentService().GetFeaturedCustomGameModes();
         foreach (var mode in modes)
         {
             File.WriteAllText(Path.Combine(folder, $"{mode.FileName}.json"), mode.FileContent);
         }
         return(true);
     }
     catch (Exception ex)
     {
         Trace.TraceError("Loading custom game modes failed: {0}", ex);
         progress.Status = "Loading custom game modes failed";
         return(false);
     }
 }
Пример #24
0
        /// <summary>
        ///     The main entry point for the application.
        /// </summary>
        public void Main()
        {
            Paths = new SpringPaths(Path.Combine(sitePath, "autoregistrator"), false, false);


            Downloader = new PlasmaDownloader.PlasmaDownloader(null, Paths);
            Downloader.DownloadAdded += (s, e) => Trace.TraceInformation("Autoregistrator Download started: {0}", e.Data.Name);
            Downloader.GetResource(DownloadType.ENGINE, MiscVar.DefaultEngine)?.WaitHandle.WaitOne();
            //for ZKL equivalent, see PlasmaShared/GlobalConst.cs

            UnitSyncer = new UnitSyncer(Paths, MiscVar.DefaultEngine);

            Downloader.PackageDownloader.DoMasterRefresh();
            Downloader.GetResource(DownloadType.RAPID, "zk:stable")?.WaitHandle.WaitOne();
            Downloader.GetResource(DownloadType.RAPID, "zk:test")?.WaitHandle.WaitOne();

            foreach (
                var ver in Downloader.PackageDownloader.Repositories.SelectMany(x => x.VersionsByTag).Where(x => x.Key.StartsWith("spring-features")))
            {
                Downloader.GetResource(DownloadType.RAPID, ver.Value.InternalName)?.WaitHandle.WaitOne();
            }

            OnRapidChanged();
        }
Пример #25
0
 public static Task <bool> DownloadFile(this PlasmaDownloader downloader, DownloadType type,
                                        string name,
                                        IChobbylaProgress progress) => DownloadFile(downloader, name, type, name, progress);
Пример #26
0
        public static async Task <bool> UpdateMissions(this PlasmaDownloader downloader, IChobbylaProgress progress)
        {
            try
            {
                progress.Status = "Downloading missions";
                var missions = GlobalConst.GetContentService().GetDefaultMissions();

                var missionsFolder = Path.Combine(downloader.SpringPaths.WritableDirectory, "missions");
                if (!Directory.Exists(missionsFolder))
                {
                    Directory.CreateDirectory(missionsFolder);
                }
                var missionFile = Path.Combine(missionsFolder, "missions.json");

                List <ClientMissionInfo> existing = null;
                if (File.Exists(missionFile))
                {
                    try
                    {
                        existing = JsonConvert.DeserializeObject <List <ClientMissionInfo> >(File.ReadAllText(missionFile));
                    }
                    catch (Exception ex)
                    {
                        Trace.TraceWarning("Error reading mission file {0} : {1}", missionFile, ex);
                    }
                }
                existing = existing ?? new List <ClientMissionInfo>();

                var toDownload =
                    missions.Where(
                        m => !existing.Any(x => (x.MissionID == m.MissionID) && (x.Revision == m.Revision) && (x.DownloadHandle == m.DownloadHandle)))
                    .ToList();

                // download mission files
                foreach (var m in toDownload)
                {
                    if (m.IsScriptMission && (m.Script != null))
                    {
                        m.Script = m.Script.Replace("%MAP%", m.Map);
                    }
                    if (!m.IsScriptMission)
                    {
                        if (!await downloader.DownloadFile("Downloading mission " + m.DisplayName, DownloadType.MISSION, m.DownloadHandle, progress).ConfigureAwait(false))
                        {
                            return(false);
                        }
                    }
                    if (!downloader.DownloadUrl("Downloading image", m.ImageUrl, Path.Combine(missionsFolder, $"{m.MissionID}.png"), progress))
                    {
                        return(false);
                    }
                }

                File.WriteAllText(missionFile, JsonConvert.SerializeObject(missions));

                return(true);
            }
            catch (Exception ex)
            {
                Trace.TraceError("Error updating missions: {0}", ex);
                return(false);
            }
        }
Пример #27
0
        public static void Main(string[] args) {
            try
            {
                //Stopwatch stopWatch = new Stopwatch(); stopWatch.Start();
                Trace.Listeners.Add(new ConsoleTraceListener());
                

                if (Environment.OSVersion.Platform != PlatformID.Unix)
                {
                    var ver = GetNetVersionFromRegistry();
                    if (ver < 378675)
                    {
                        MessageBox.Show(new Form { TopMost = true },
                            "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);

                // extract fonts
                EmbeddedResourceExtractor.ExtractFile("ZeroKLobby.NativeLibs.SM.ttf", "SM.ttf");
                EmbeddedResourceExtractor.ExtractFile("ZeroKLobby.NativeLibs.OpenSans-Regular.ttf", "OpenSans-Regular.ttf");

                Conf = new Config();

                IsSteamFolder = File.Exists(Path.Combine(StartupPath, "steamfolder.txt"));

                SelfUpdater = new SelfUpdater("Zero-K");

                StartupArgs = args;

                try
                {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                }
                catch (Exception ex)
                {
                    Trace.TraceWarning("Failed to set rendering compatibility: {0}", ex);
                }

                if (!Debugger.IsAttached)
                {
                    try
                    {
                        AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
                        Thread.GetDomain().UnhandledException += UnhandledException;
                        Application.ThreadException += Application_ThreadException;
                        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
                    }
                    catch (Exception ex)
                    {
                        Trace.TraceWarning("Failed to set exception handling :{0}", ex);
                    }
                }




                //HttpWebRequest.DefaultCachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
                Trace.TraceInformation("Starting with version {0}", SelfUpdater.CurrentVersion);

                WebRequest.DefaultWebProxy = null;
                ThreadPool.SetMaxThreads(500, 2000);
                ServicePointManager.Expect100Continue = false;
                LoadConfig();

            


                Trace.Listeners.Add(new LogTraceListener());
                if (Environment.OSVersion.Platform != PlatformID.Unix && !Conf.UseExternalBrowser) Utils.SetIeCompatibility(); //set to current IE version

                var contentDir = !string.IsNullOrEmpty(Conf.DataFolder) ? Conf.DataFolder : StartupPath;
                if (!Directory.Exists(contentDir) || !SpringPaths.IsDirectoryWritable(contentDir))
                {
                    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))
                {
                    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(new Form { TopMost = true }, "Move failed, please copy Zero-K.exe to a writable folder");
                    return;
                }

                

                SpringPaths = new SpringPaths(contentDir);

                if (
                MessageBox.Show(new Form() { TopMost = true },
                    "Would you like to try the new lobby program for Zero-K: Chobby?",
                    "New launcher option available",
                    MessageBoxButtons.YesNo,
                    MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    var targetPath = Path.Combine(SpringPaths.WritableDirectory, "Chobby.exe");
                    if (!File.Exists(targetPath))
                    {
                        var wc = new WebClient();
                        wc.DownloadFile(GlobalConst.BaseSiteUrl + "/lobby/Chobby.exe", targetPath);
                    }
                    Process.Start(targetPath);
                    Environment.Exit(0);
                }

                // speed up spring start
                SpringPaths.SpringVersionChanged += (sender, engine) =>
                {
                    ZkData.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();
                            }
                        });
                };

                SaveConfig();


                // write license files
                try
                {
                    var path = SpringPaths.WritableDirectory;
                    var pathGPL = Utils.MakePath(path, "license_GPLv3");
                    var gpl = Encoding.UTF8.GetString(License.GPLv3);
                    if (!File.Exists(pathGPL)) File.WriteAllText(pathGPL, gpl);
                    var pathMIT = Utils.MakePath(path, "license_MIT");
                    var mit = Encoding.UTF8.GetString(License.MITlicense);
                    if (!File.Exists(pathMIT)) File.WriteAllText(pathMIT, mit);
                }
                catch (Exception ex)
                {
                    Trace.TraceError(ex.ToString());
                }


                
                if (Conf.IsFirstRun)
                {
                    if (!IsSteamFolder)
                    {
                        Utils.CreateDesktopShortcut();
                    }
                    if (Environment.OSVersion.Platform != PlatformID.Unix) Utils.RegisterProtocol();
                }

                MetaData = new MetaDataCache(SpringPaths);
                AutoJoinManager = new AutoJoinManager();
                EngineConfigurator = new EngineConfigurator(SpringPaths.WritableDirectory);

                SpringScanner = new PlasmaResourceChecker(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);
                Downloader = new PlasmaDownloader.PlasmaDownloader(SpringScanner, SpringPaths); //rapid
                Downloader.DownloadAdded += (s, e) => Trace.TraceInformation("Download started: {0}", e.Data.Name);
                //Downloader.GetResource(DownloadType.ENGINE, GlobalConst.DefaultEngineOverride);

                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) if (MainWindow != null) MainWindow.navigationControl.Path = "battles";
                };

                TasClient.LoginDenied += (s, e) => Trace.TraceInformation("TASC login denied");
                TasClient.ChannelJoined += (s, e) => { Trace.TraceInformation("TASC channel joined: " + e.Name); };
                TasClient.ConnectionLost += (s, e) => Trace.TraceInformation("Connection lost");
                TasClient.WelcomeReceived += (s, e) =>
                {
                    Downloader.GetResource(DownloadType.ENGINE, e.Engine);
                    Downloader.GetResource(DownloadType.RAPID, e.Game);
                };

                Program.AreYouReadyDialog = new AreYouReadyDialog(TasClient);

                // 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) || TasClient.Ignores.Contains(e.Data.UserName)) e.Cancel = true;
                    }
                };

                TasClient.SiteToLobbyCommandReceived += (eventArgs, o) =>
                {
                    if (MainWindow != null)
                    {
                        MainWindow.navigationControl.Path = o.Command;
                        MainWindow.PopupSelf();
                    }
                };

                ModStore = new ModStore();

                ConnectBar = new ConnectBar(TasClient);
                ToolTip = new ToolTipHandler();
                BrowserInterop = new BrowserInterop(TasClient, Conf);
                BattleIconManager = new BattleIconManager();
                Application.AddMessageFilter(ToolTip);

                SteamHandler = new ZklSteamHandler(TasClient);

                MainWindow = new MainWindow();

                Application.AddMessageFilter(new ScrollMessageFilter());

                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();
                VoteBar = new VoteBar();
                PwBar = new PwBar();
                MatchMakerBar = new MatchMakerBar(TasClient);

                SelfUpdater.ProgramUpdated += s =>
                {
                    Program.MainWindow.InvokeFunc(
                        () => WarningBar.DisplayWarning($"New version of Zero-K launcher downloaded, restart it to apply changes", "Restart", Restart));
                };
                if (!Debugger.IsAttached && !Conf.DisableAutoUpdate && !IsSteamFolder) SelfUpdater.StartChecking();

                if (GlobalConst.Mode != ModeType.Local) SteamHandler.Connect();
                Application.Run(MainWindow);

                ShutDown();
            }
            catch (Exception ex)
            {
                ErrorHandling.HandleException(ex, true);
                if (Debugger.IsAttached) Debugger.Break();
            }
            finally
            {
                ShutDown();
            }
            if (ErrorHandling.HasFatalException && !CloseOnNext)
            {
                if (Debugger.IsAttached) Debugger.Break();
                Application.Restart();
            }
        }
Пример #28
0
        //[STAThread]
        private static void Main(params string[] args) {
            var startupPath = Path.GetDirectoryName(Path.GetFullPath(Application.ExecutablePath));
            var springPaths = new SpringPaths(null, startupPath);
            Spring runningSpring = null;
            springPaths.MakeFolders();
            TcpTransport connection = null;

            // speed up spring start
            springPaths.SpringVersionChanged += (sender, eventArgs) =>
            {
                Utils.StartAsync(
                    () =>
                    {
                        UnitSync unitSync = null;
                        try
                        {
                            unitSync = new UnitSync(springPaths); // 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.GetAndSwitchEngine(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.GetEngineFolderByVersion(engine), springPaths.WritableDirectory);
                    downloader.GetAndSwitchEngine(engine, path);
                });
            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.GetEngineFolderByVersion(engineVer), springPaths.WritableDirectory);
                    runningSpring = new Spring(path);
                    runningSpring.SpringExited += (obj, evt) =>
                    {
                        CefWrapper.ExecuteJavascript("on_spring_exit(" + (evt.Data ? "true" : "false") + ");");
                        runningSpring = null;
                    };
                    try
                    {
                        runningSpring.StartSpring(script);
                        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();
        }
Пример #29
0
        private void Generate()
        {
            Utils.CheckPath(targetFolder);
            try
            {
                Directory.Delete(Path.Combine(targetFolder, "packages"), true);
                Directory.Delete(Path.Combine(targetFolder, "engine"), true);
                Directory.Delete(Path.Combine(targetFolder, "games"), true);
                Directory.Delete(Path.Combine(targetFolder, "rapid"), true);
                Directory.Delete(Path.Combine(targetFolder, "cache"), true);
                Directory.Delete(Path.Combine(targetFolder, "temp"), true);
                File.Delete(Path.Combine(targetFolder, "missions", "missions.json"));
            }
            catch { }

            var paths      = new SpringPaths(targetFolder, false, false);
            var downloader = new PlasmaDownloader.PlasmaDownloader(null, paths);
            var prog       = new DummyProgress();


            foreach (var plat in Enum.GetValues(typeof(SpringPaths.PlatformType)).Cast <SpringPaths.PlatformType>())
            {
                var sp = new SpringPaths(targetFolder, false, false, plat);
                var dn = new PlasmaDownloader.PlasmaDownloader(null, sp);

                if (!dn.DownloadFile(DownloadType.ENGINE, MiscVar.DefaultEngine, prog).Result)
                {
                    throw new ApplicationException("SteamDepot engine download failed: " + prog.Status);
                }
            }

            downloader.PackageDownloader.DoMasterRefresh();

            var chobbyName = downloader.PackageDownloader.GetByTag(GlobalConst.DefaultChobbyTag).InternalName;

            downloader.RapidHandling = RapidHandling.SdzNameTagForceDownload;

            if (!downloader.DownloadFile(DownloadType.RAPID, chobbyName, prog).Result)
            {
                throw new ApplicationException("SteamDepot chobby download failed: " + prog.Status);
            }
            if (!downloader.DownloadFile(DownloadType.RAPID, GlobalConst.DefaultZkTag, prog).Result)
            {
                throw new ApplicationException("SteamDepot zk download failed: " + prog.Status);
            }

            downloader.RapidHandling = RapidHandling.DefaultSdp;


            var campaignMaps = RegistratorRes.campaignMaps.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim())
                               .ToArray();

            CopyResources(siteBase, paths, GetMapList(campaignMaps), downloader);

            if (!downloader.UpdateMissions(prog).Result)
            {
                throw new ApplicationException("SteamDepot Error updating missions! " + prog.Status);
            }
            if (!downloader.UpdatePublicCommunityInfo(prog))
            {
                throw new ApplicationException("SteamDepot Error updating public community info! " + prog.Status);
            }


            CopyLobbyProgram();
            CopyExtraImages();

            downloader.PackageDownloader.DoMasterRefresh();


            File.WriteAllText(Path.Combine(paths.WritableDirectory, "steam_chobby.txt"), chobbyName);
            File.WriteAllText(Path.Combine(paths.WritableDirectory, "steam_engine.txt"), MiscVar.DefaultEngine);
            File.WriteAllText(Path.Combine(paths.WritableDirectory, "steam_deletesdp.txt"), "1");
        }
Пример #30
0
        private static void CopyResources(string siteBase, SpringPaths paths, List <Resource> resources, PlasmaDownloader.PlasmaDownloader downloader)
        {
            var destMaps   = Path.Combine(paths.WritableDirectory, "maps");
            var sourceMaps = Path.Combine(siteBase, "autoregistrator", "maps");

            foreach (var res in resources)
            {
                Trace.TraceInformation("Copying {0}", res.InternalName);
                if (res.TypeID == ResourceType.Map)
                {
                    var fileName = res.ResourceContentFiles.ToList().Where(x => File.Exists(Path.Combine(sourceMaps, x.FileName))).OrderByDescending(x => x.LinkCount).FirstOrDefault()?.FileName; // get registered file names

                    fileName = fileName ?? res.ResourceContentFiles
                               .Where(x => x.Links != null).SelectMany(x => x.Links.Split('\n'))
                               .Where(x => x != null).Select(x => x.Substring(x.LastIndexOf('/') + 1, x.Length - x.LastIndexOf('/') - 1)).FirstOrDefault(x => !string.IsNullOrEmpty(x) && File.Exists(Path.Combine(sourceMaps, x))); // get filenames from url

                    if (fileName == null)
                    {
                        var prog = new DummyProgress();
                        if (!downloader.DownloadFile(DownloadType.MAP, res.InternalName, prog).Result)
                        {
                            Trace.TraceError("Cannot find map file: {0}", res.InternalName);
                        }
                        continue;
                    }


                    if (!File.Exists(Path.Combine(destMaps, fileName)))
                    {
                        File.Copy(Path.Combine(sourceMaps, fileName), Path.Combine(destMaps, fileName));
                    }
                }
                else if (res.MissionID != null)
                {
                    File.WriteAllBytes(Path.Combine(paths.WritableDirectory, "games", res.Mission.SanitizedFileName), res.Mission.Mutator);
                }
                else
                {
                    downloader.GetResource(DownloadType.RAPID, res.InternalName)?.WaitHandle.WaitOne();
                }
            }
        }
Пример #31
0
        private void Generate()
        {
            Utils.CheckPath(targetFolder);
            try
            {
                Directory.Delete(Path.Combine(targetFolder, "pool"), true);
                Directory.Delete(Path.Combine(targetFolder, "packages"), true);
                Directory.Delete(Path.Combine(targetFolder, "engine"), true);
                Directory.Delete(Path.Combine(targetFolder, "games"), true);
                Directory.Delete(Path.Combine(targetFolder, "rapid"), true);
                File.Delete(Path.Combine(targetFolder, "missions", "missions.json"));
                File.Delete(Path.Combine(targetFolder, "cache", "repositories.json"));
            }
            catch { }

            var paths      = new SpringPaths(targetFolder, false, false);
            var downloader = new PlasmaDownloader.PlasmaDownloader(null, paths);
            var prog       = new DummyProgress();


            foreach (var plat in Enum.GetValues(typeof(SpringPaths.PlatformType)).Cast <SpringPaths.PlatformType>())
            {
                var sp = new SpringPaths(targetFolder, false, false, plat);
                var dn = new PlasmaDownloader.PlasmaDownloader(null, sp);

                if (!dn.DownloadFile(DownloadType.ENGINE, MiscVar.DefaultEngine, prog).Result)
                {
                    throw new ApplicationException("SteamDepot engine download failed: " + prog.Status);
                }
            }

            downloader.PackageDownloader.DoMasterRefresh();

            var chobbyName = downloader.PackageDownloader.GetByTag(GlobalConst.DefaultChobbyTag).InternalName;

            if (!downloader.DownloadFile(DownloadType.RAPID, chobbyName, prog).Result)
            {
                throw new ApplicationException("SteamDepot chobby download failed: " + prog.Status);
            }
            if (!downloader.DownloadFile(DownloadType.RAPID, GlobalConst.DefaultZkTag, prog).Result)
            {
                throw new ApplicationException("SteamDepot zk download failed: " + prog.Status);
            }


            File.WriteAllText(Path.Combine(paths.WritableDirectory, "steam_chobby.txt"), chobbyName);
            File.WriteAllText(Path.Combine(paths.WritableDirectory, "steam_engine.txt"), MiscVar.DefaultEngine);


            CopyResources(siteBase, paths, GetResourceList(), downloader);

            if (!downloader.UpdateMissions(prog).Result)
            {
                throw new ApplicationException("SteamDepot Error updating missions! " + prog.Status);
            }


            CopyLobbyProgram();
            CopyExtraImages();

            Utils.CheckPath(targetFolder);

            downloader.PackageDownloader.DoMasterRefresh();
        }
Пример #32
0
        //[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();
        }
Пример #33
0
        public async Task<bool> Run()
        {
            try
            {
                var downloader = new PlasmaDownloader.PlasmaDownloader(new SpringScanner(paths) { WatchingEnabled = false, UseUnitSync = false },
                     paths);

                PackageDownloader.Version ver = null;
                string internalName = null;

                if (!isDev)
                {
                    if (!Debugger.IsAttached)
                    {
                        Status = "Checking for self-upgrade";
                        var selfUpdater = new SelfUpdater();
                        selfUpdater.ProgramUpdated += delegate { Application.Restart(); };
                        var task = new Task<bool>(() => selfUpdater.CheckForUpdate());
                        task.Start();
                        await task;
                    }


                    Status = "Updating rapid packages";
                    await downloader.PackageDownloader.LoadMasterAndVersions();
                    Status = "Checking for chobby update";
                    Download = downloader.GetResource(DownloadType.MOD, chobbyTag);
                    var asTask = Download?.WaitHandle.AsTask(TimeSpan.FromMinutes(20));
                    if (asTask != null) await asTask;
                    if (Download?.IsComplete == false)
                    {
                        Status = $"Download of {Download.Name} has failed";
                        return false;
                    }

                    ver = downloader.PackageDownloader.GetByTag(chobbyTag);
                    if (ver == null)
                    {
                        Status = "Rapid package appears to be corrupted, please clear the folder";
                        return false;
                    }

                    internalName = ver.InternalName;
                }
                else internalName = "Chobby $VERSION";


                engine = engine ?? QueryDefaultEngine() ?? ExtractEngineFromLua(ver) ?? GlobalConst.DefaultEngineOverride;


                Status = "Downloading engine";
                Download = downloader.GetResource(DownloadType.ENGINE, engine);
                var engDlTask = Download?.WaitHandle.AsTask(TimeSpan.FromMinutes(20));
                if (engDlTask != null) await engDlTask;
                if (Download?.IsComplete == false)
                {
                    Status = $"Download of engine {Download.Name} has failed";
                    return false;
                }

                if (!isDev)
                {
                    Status = "Extracting default configs";
                    ExtractDefaultConfigs(paths, ver);
                }
                
                Status = "Starting";
                
                

                LaunchChobby(paths, internalName, engine);
                return true;
            }
            catch (Exception ex)
            {
                Trace.TraceError("Unexpected error: {0}", ex);
                Status = "Unexpected error preparing chobby launch: " + ex.Message;
                return false;
            }
        }
Пример #34
0
        /// <summary>
        /// Validates content - starts downloads, return null if all ok so far
        /// </summary>
        public string Validate(PlasmaDownloader.PlasmaDownloader downloader, bool waitDownload = false)
        {
            if (string.IsNullOrEmpty(Engine))
            {
                return("Engine name not set");
            }

            if (StartScript == null)
            {
                return("Please select a start script - put start scripts in Benchmarks/Scripts folder");
            }
            if (Config == null)
            {
                return("Please select a config to use - create folders with configs in Benchmarks/Configs folder");
            }

            var      de = downloader.GetResource(DownloadType.ENGINE, Engine);
            Download dm = null;

            if (!string.IsNullOrEmpty(Map))
            {
                dm = downloader.GetResource(DownloadType.MAP, Map);
            }

            Download dg = null;

            if (!string.IsNullOrEmpty(Game))
            {
                var ver = downloader.PackageDownloader.GetByTag(Game);
                if (ver != null)
                {
                    Game = ver.InternalName;
                }
                dg = downloader.GetResource(DownloadType.RAPID, Game);
            }

            if (waitDownload)
            {
                if (de != null)
                {
                    de.WaitHandle.WaitOne();
                    if (de.IsComplete == false)
                    {
                        return("Failed download of engine " + de.Name);
                    }
                }
                if (dm != null)
                {
                    dm.WaitHandle.WaitOne();
                    if (dm.IsComplete == false)
                    {
                        return("Failed download of map " + dm.Name);
                    }
                }
                if (dg != null)
                {
                    dg.WaitHandle.WaitOne();
                    if (dg.IsComplete == false)
                    {
                        return("Failed download of game " + dg.Name);
                    }
                }
            }

            var sVal = StartScript.Validate(downloader, waitDownload);

            if (sVal != null)
            {
                return(sVal);
            }

            return(null);
        }
Пример #35
0
 public BisectForm(SpringPaths springPaths, PlasmaDownloader.PlasmaDownloader downloader)
 {
     this.springPaths = springPaths;
     this.downloader  = downloader;
     InitializeComponent();
 }
Пример #36
0
 /// <summary>
 /// Validate content files - starts downloads
 /// </summary>
 public string Validate(PlasmaDownloader.PlasmaDownloader downloader, bool waitForDownload) {
     foreach (var dep in
         GetDependencies().Where(x => !UnitSync.DependencyExceptions.Contains(x))) {
         if (GetBenchmarks(downloader.SpringPaths).Any(y => y.GetSpringName() == dep || y.Name == dep)) continue;
         var dl = downloader.GetResource(DownloadType.MOD, dep);
         if (dl != null && waitForDownload) {
             dl.WaitHandle.WaitOne();
             if (dl.IsComplete == false) return "Failed to download dependency mod " + dep;
         }
     }
     return null;
 }
Пример #37
0
        public static void Main(string[] args)
        {
            try
            {
                //Stopwatch stopWatch = new Stopwatch(); stopWatch.Start();
                Trace.Listeners.Add(new ConsoleTraceListener());


                if (Environment.OSVersion.Platform != PlatformID.Unix)
                {
                    var ver = GetNetVersionFromRegistry();
                    if (ver < 378675)
                    {
                        MessageBox.Show(new Form {
                            TopMost = true
                        },
                                        "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);

                // extract fonts
                EmbeddedResourceExtractor.ExtractFile("ZeroKLobby.NativeLibs.SM.ttf", "SM.ttf");
                EmbeddedResourceExtractor.ExtractFile("ZeroKLobby.NativeLibs.OpenSans-Regular.ttf", "OpenSans-Regular.ttf");

                Conf = new Config();

                IsSteamFolder = File.Exists(Path.Combine(StartupPath, "steamfolder.txt"));

                SelfUpdater = new SelfUpdater("Zero-K");

                StartupArgs = args;

                try
                {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                }
                catch (Exception ex)
                {
                    Trace.TraceWarning("Failed to set rendering compatibility: {0}", ex);
                }

                if (!Debugger.IsAttached)
                {
                    try
                    {
                        AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
                        Thread.GetDomain().UnhandledException += UnhandledException;
                        Application.ThreadException += Application_ThreadException;
                        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
                    }
                    catch (Exception ex)
                    {
                        Trace.TraceWarning("Failed to set exception handling :{0}", ex);
                    }
                }



                //HttpWebRequest.DefaultCachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
                Trace.TraceInformation("Starting with version {0}", SelfUpdater.CurrentVersion);

                WebRequest.DefaultWebProxy = null;
                ThreadPool.SetMaxThreads(500, 2000);
                ServicePointManager.Expect100Continue = false;
                LoadConfig();



                Trace.Listeners.Add(new LogTraceListener());
                if (Environment.OSVersion.Platform != PlatformID.Unix && !Conf.UseExternalBrowser)
                {
                    Utils.SetIeCompatibility();                                                                                //set to current IE version
                }
                var contentDir = !string.IsNullOrEmpty(Conf.DataFolder) ? Conf.DataFolder : StartupPath;
                if (!Directory.Exists(contentDir) || !SpringPaths.IsDirectoryWritable(contentDir))
                {
                    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))
                {
                    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(new Form {
                        TopMost = true
                    }, "Move failed, please copy Zero-K.exe to a writable folder");
                    return;
                }



                SpringPaths = new SpringPaths(contentDir, true, true);

                if (
                    MessageBox.Show(new Form()
                {
                    TopMost = true
                },
                                    "WARNING: Zero-K lobby is now obsolete. Starting Chobby instead, ok? ",
                                    "WARNING: launcher obsolete",
                                    MessageBoxButtons.YesNo,
                                    MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    var targetPath = Path.Combine(SpringPaths.WritableDirectory, "Chobby.exe");
                    if (!File.Exists(targetPath))
                    {
                        var wc = new WebClient();
                        wc.DownloadFile(GlobalConst.BaseSiteUrl + "/lobby/Chobby.exe", targetPath);
                    }
                    Process.Start(targetPath);
                    Environment.Exit(0);
                }

                // speed up spring start
                SpringPaths.SpringVersionChanged += (sender, engine) =>
                {
                    ZkData.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();
                        }
                    });
                };

                SaveConfig();


                // write license files
                try
                {
                    var path    = SpringPaths.WritableDirectory;
                    var pathGPL = Utils.MakePath(path, "license_GPLv3");
                    var gpl     = Encoding.UTF8.GetString(License.GPLv3);
                    if (!File.Exists(pathGPL))
                    {
                        File.WriteAllText(pathGPL, gpl);
                    }
                    var pathMIT = Utils.MakePath(path, "license_MIT");
                    var mit     = Encoding.UTF8.GetString(License.MITlicense);
                    if (!File.Exists(pathMIT))
                    {
                        File.WriteAllText(pathMIT, mit);
                    }
                }
                catch (Exception ex)
                {
                    Trace.TraceError(ex.ToString());
                }



                if (Conf.IsFirstRun)
                {
                    if (!IsSteamFolder)
                    {
                        Utils.CreateDesktopShortcut();
                    }
                    if (Environment.OSVersion.Platform != PlatformID.Unix)
                    {
                        Utils.RegisterProtocol();
                    }
                }

                MetaData           = new MetaDataCache(SpringPaths);
                AutoJoinManager    = new AutoJoinManager();
                EngineConfigurator = new EngineConfigurator(SpringPaths.WritableDirectory);

                SpringScanner = new PlasmaResourceChecker(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);
                Downloader = new PlasmaDownloader.PlasmaDownloader(SpringScanner, SpringPaths); //rapid
                Downloader.DownloadAdded += (s, e) => Trace.TraceInformation("Download started: {0}", e.Data.Name);
                //Downloader.GetResource(DownloadType.ENGINE, GlobalConst.DefaultEngineOverride);

                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)
                    {
                        if (MainWindow != null)
                        {
                            MainWindow.navigationControl.Path = "battles";
                        }
                    }
                };

                TasClient.LoginDenied     += (s, e) => Trace.TraceInformation("TASC login denied");
                TasClient.ChannelJoined   += (s, e) => { Trace.TraceInformation("TASC channel joined: " + e.Name); };
                TasClient.ConnectionLost  += (s, e) => Trace.TraceInformation("Connection lost");
                TasClient.WelcomeReceived += (s, e) =>
                {
                    Downloader.GetResource(DownloadType.ENGINE, e.Engine);
                    Downloader.GetResource(DownloadType.RAPID, e.Game);
                };

                Program.AreYouReadyDialog = new AreYouReadyDialog(TasClient);

                // 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) || TasClient.Ignores.Contains(e.Data.UserName))
                        {
                            e.Cancel = true;
                        }
                    }
                };

                TasClient.SiteToLobbyCommandReceived += (eventArgs, o) =>
                {
                    if (MainWindow != null)
                    {
                        MainWindow.navigationControl.Path = o.Command;
                        MainWindow.PopupSelf();
                    }
                };

                ModStore = new ModStore();

                ConnectBar        = new ConnectBar(TasClient);
                ToolTip           = new ToolTipHandler();
                BrowserInterop    = new BrowserInterop(TasClient, Conf);
                BattleIconManager = new BattleIconManager();
                Application.AddMessageFilter(ToolTip);

                SteamHandler = new ZklSteamHandler(TasClient);

                MainWindow = new MainWindow();

                Application.AddMessageFilter(new ScrollMessageFilter());

                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();
                VoteBar       = new VoteBar();
                PwBar         = new PwBar();
                MatchMakerBar = new MatchMakerBar(TasClient);

                SelfUpdater.ProgramUpdated += s =>
                {
                    Program.MainWindow.InvokeFunc(
                        () => WarningBar.DisplayWarning($"New version of Zero-K launcher downloaded, restart it to apply changes", "Restart", Restart));
                };
                if (!Debugger.IsAttached && !Conf.DisableAutoUpdate && !IsSteamFolder)
                {
                    SelfUpdater.StartChecking();
                }

                if (GlobalConst.Mode != ModeType.Local)
                {
                    SteamHandler.Connect();
                }
                Application.Run(MainWindow);

                ShutDown();
            }
            catch (Exception ex)
            {
                ErrorHandling.HandleException(ex, true);
                if (Debugger.IsAttached)
                {
                    Debugger.Break();
                }
            }
            finally
            {
                ShutDown();
            }
            if (ErrorHandling.HasFatalException && !CloseOnNext)
            {
                if (Debugger.IsAttached)
                {
                    Debugger.Break();
                }
                Application.Restart();
            }
        }
        private static void CopyResources(string siteBase, SpringPaths paths, List<Resource> resources, PlasmaDownloader.PlasmaDownloader downloader) {
            var destMaps = Path.Combine(paths.WritableDirectory, "maps");
            var sourceMaps = Path.Combine(siteBase, "autoregistrator", "maps");
            var sourceMetadata = Path.Combine(siteBase, "Resources");
            var targetMetadata = Path.Combine(paths.Cache, "Resources");
            if (!Directory.Exists(targetMetadata)) Directory.CreateDirectory(targetMetadata);

            foreach (var res in resources)
            {
                Trace.TraceInformation("Copying {0}", res.InternalName);
                if (res.TypeID == ResourceType.Map)
                {
                    var fileName = res.ResourceContentFiles.ToList().Where(x=>File.Exists(Path.Combine(sourceMaps, x.FileName))).OrderByDescending(x => x.LinkCount).FirstOrDefault()?.FileName; // get registered file names

                    fileName = fileName?? res.ResourceContentFiles
                        .SelectMany(x => x.Links.Split('\n'))
                        .Where(x => x != null).Select(x=> x.Substring(x.LastIndexOf('/')+1, x.Length - x.LastIndexOf('/') - 1)).FirstOrDefault(x => !string.IsNullOrEmpty(x) && File.Exists(Path.Combine(sourceMaps,x))); // get filenames from url

                    if (fileName == null) Trace.TraceError("Cannot find map file: {0}", res.InternalName);


                    if (!File.Exists(Path.Combine(destMaps, fileName))) File.Copy(Path.Combine(sourceMaps, fileName), Path.Combine(destMaps, fileName));
                } else if (res.MissionID != null) File.WriteAllBytes(Path.Combine(paths.WritableDirectory, "games", res.Mission.SanitizedFileName), res.Mission.Mutator);
                else downloader.GetResource(DownloadType.UNKNOWN, res.InternalName)?.WaitHandle.WaitOne();

                foreach (var metaName in new[] { res.MinimapName, res.HeightmapName, res.MetalmapName, res.MetadataName, res.ThumbnailName })
                {
                    Trace.TraceInformation("Copying resource: {0}", metaName);
                    var src = Path.Combine(sourceMetadata, metaName);
                    var dst = Path.Combine(targetMetadata, metaName);
                    if (!File.Exists(dst) && File.Exists(src))
                    {
                        File.Copy(src, dst);
                    }
                }
            }
        }