public UnitsyncResourcePresenceChecker(SpringPaths paths, string engine)
 {
     if (string.IsNullOrEmpty(engine) || !paths.HasEngineVersion(engine))
     {
         Trace.TraceWarning("Engine {0} not found, trying backup", engine);
         engine = paths.GetEngineList().FirstOrDefault();
         if (engine == null) throw new Exception("No engine found for unitsync");
     }
     unitsync = new UnitSync(paths, engine);
 }
Beispiel #2
0
 public void Scan()
 {
     using (var unitsync = new UnitSync(Paths, Engine))
     {
         unitsync.ReInit();
         var archiveCache = unitsync.GetArchiveCache();
         using (var db = new ZkDataContext())
         {
             var registered = db.Resources.Select(x => x.InternalName).ToDictionary(x => x, x => true);
             foreach (var archive in archiveCache.Archives) if (!registered.ContainsKey(archive.Name) && !UnitSync.DependencyExceptions.Contains(archive.Name)) Register(unitsync, archive);
         }
     }
 }
        public void UpdateMission(ZkDataContext db, Mission mission, SpringPaths paths, string engine)
        {
            var file = mission.Mutator.ToArray();
            var targetPath = Path.Combine(paths.WritableDirectory, "games", mission.SanitizedFileName);
            File.WriteAllBytes(targetPath, file);

            Mod modInfo;
            using (var unitsync = new UnitSync(paths, engine))
            {
                modInfo = unitsync.GetResourceFromFileName(targetPath) as Mod;
            }

            File.Delete(targetPath);
            UpdateMission(db, mission, modInfo);
        }
 /// <summary>VerifyUnitSync() check whether unitSync should be initialized and perform unitSync initialization.
 /// </summary> 
 public void VerifyUnitSync()
 {
     if (unitSyncReInitCounter >= UnitSyncReInitFrequency)
     {
         unitSyncAttemptedFolder = null;
         unitSyncReInitCounter = 0;
     }
     if (unitSyncAttemptedFolder != springPaths.UnitSyncDirectory || unitSync==null)
     {
         if (unitSync != null)
         {
             try
             {
                 unitSync.Dispose();
                 unitSync = null;
             }
             catch (Exception ex)
             {
                 Trace.TraceWarning("Error disposing unitsync: {0}", ex);
             }
         }
         unitSyncAttemptedFolder = springPaths.UnitSyncDirectory;
         try
         {
             unitSync = new UnitSync(springPaths);
         }
         catch (Exception ex)
         {
             Trace.TraceWarning("Error initializing unitsync: {0}", ex);
         }
     }
 }
 /// <summary>UnInitUnitsync() check whether SpringScanner have any more mods/map to Unitsynced and call unitsync's UnInit() when there's no more work.
 /// </summary>
 public void UnInitUnitsync()
 {
    //upon completion of any work: dispose unitsync. It can be re-initialize again later by VerifyUnitSync()
     if (unitSync != null && GetWorkCost() < 1)
     {
         try
         {
             unitSync.Dispose();
             unitSync = null;
         }
         catch (Exception ex)
         {
             Trace.TraceWarning("Error disposing unitsync: {0}", ex);
         }
     }
 } 
        void MainThreadFunction()
        {
            try {
                InitialScan();
            } catch (Exception ex) {
                Trace.TraceError("Error in scanner initial scan: {0}",ex);
            }

            try
            {
                var isWorking = false;
                var workDone = 0;
                while (!isDisposed)
                {
                    try {
                        Thread.Sleep(ScannerCycleTime);

                        if (isCacheDirty && DateTime.Now.Subtract(lastCacheSave).TotalSeconds > DirtyCacheSave) {
                            lastCacheSave = DateTime.Now;
                            isCacheDirty = false;
                            SaveCache();
                        }

                        WorkItem workItem;
                        while ((workItem = GetNextWorkItem()) != null) {
                            if (isDisposed) return;

                            if (!isWorking) {
                                isWorking = true;
                                workDone = 0;
                                workTotal = GetWorkCost();
                                WorkStarted(this, new ProgressEventArgs(workDone, workTotal, workItem.CacheItem.FileName));
                            }
                            else {
                                workDone++;
                                workTotal = Math.Max(GetWorkCost(), workTotal);
                                WorkProgressChanged(this,
                                                    new ProgressEventArgs(workDone,
                                                                          workTotal,
                                                                          string.Format("{0} {1}", workItem.Operation, workItem.CacheItem.FileName)));
                            }

                            if (workItem.Operation == WorkItem.OperationType.Hash) PerformHashOperation(workItem);
                            if (workItem.Operation == WorkItem.OperationType.UnitSync) {
                                if (springPaths.UnitSyncDirectory != null) PerformUnitSyncOperation(workItem); // if there is no unitsync, retry later
                                else AddWork(workItem.CacheItem, WorkItem.OperationType.UnitSync, DateTime.Now.AddSeconds(RescheduleServerQuery), false);
                            }
                            if (workItem.Operation == WorkItem.OperationType.ReAskServer) GetResourceData(workItem);
                        }
                        if (isWorking) {
                            isWorking = false;
                            WorkStopped(this, EventArgs.Empty);
                        }
                    } catch (Exception ex) {
                        Trace.TraceError("Exception in scanning thread: {0}",ex);
                    }
                }
            }
            finally
            {
                if (unitSync != null) unitSync.Dispose();
                unitSync = null;
            }
        }
 public void Dispose()
 {
     WatchingEnabled = false;
     isDisposed = true;
     if (unitSync != null) unitSync.Dispose(); //(visual studio recommend a dispose)
     unitSync = null;
     if (isCacheDirty) SaveCache();
     GC.SuppressFinalize(this);
 }
        public event EventHandler<CancelEventArgs<CacheItem>> RetryResourceCheck = delegate { }; // raised before attempting to reconnect to server to check for resource info

        public SpringScanner(SpringPaths springPaths)
        {
            this.SpringPaths = springPaths;
            MetaData = new MetaDataCache(springPaths, this);

            foreach (var folder in springPaths.DataDirectories)
            {
                var modsPath = Utils.MakePath(folder, "games");
                if (Directory.Exists(modsPath)) modsWatchers.Add(new FileSystemWatcher(modsPath));
                var mapsPath = Utils.MakePath(folder, "maps");
                if (Directory.Exists(mapsPath)) mapsWatchers.Add(new FileSystemWatcher(mapsPath));
                var packagesPath = Utils.MakePath(folder, "packages");
                if (Directory.Exists(packagesPath)) packagesWatchers.Add(new FileSystemWatcher(packagesPath));
            }

            SetupWatcherEvents(mapsWatchers);
            SetupWatcherEvents(modsWatchers);
            SetupWatcherEvents(packagesWatchers);

            Directory.CreateDirectory(springPaths.Cache);
            cachePath = Utils.MakePath(springPaths.Cache, "ScannerCache.json");
            Directory.CreateDirectory(Utils.MakePath(springPaths.Cache, "Resources"));

            if (UseUnitSync)
            {
                try
                {
                    unitSync = new UnitSync(springPaths);
                }
                catch (Exception ex)
                {
                    Trace.TraceWarning("UnitSync init failed: {0}",ex);
                }
            }
        }
        public static void Main(string[] args) {
            try
            {
                //Stopwatch stopWatch = new Stopwatch(); stopWatch.Start();
                Trace.Listeners.Add(new ConsoleTraceListener());

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




                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;

                Application.EnableVisualStyles();

                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;
                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(null, contentDir);
                SpringPaths.MakeFolders();

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

                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();
                }

                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 (Conf.EnableUnitSyncPrompt && Environment.OSVersion.Platform != PlatformID.Unix)
                {
                    SpringScanner.UploadUnitsyncData += UnitSyncUploadPrompt.SpringScanner_UploadUnitsyncData;
                    SpringScanner.RetryResourceCheck += 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(SpringScanner, SpringPaths); //rapid
                Downloader.DownloadAdded += (s, e) => Trace.TraceInformation("Download started: {0}", e.Data.Name);
                Downloader.GetAndSwitchEngine(GlobalConst.DefaultEngineOverride ?? TasClient.ServerSpringVersion);

                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");

                // 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.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();

           
                if (!Debugger.IsAttached && !Conf.DisableAutoUpdate && !IsSteamFolder) SelfUpdater.StartChecking();

                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();
            }
        }
        //[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();
        }
Beispiel #11
0
        private static void Register(UnitSync unitsync, ResourceInfo resource)
        {
            Trace.TraceInformation("UnitSyncer: registering {0}", resource.Name);
            try
            {
                var info = unitsync.GetResourceFromFileName(resource.ArchivePath);

                if (info != null)
                {
                    var serializedData = MetaDataCache.SerializeAndCompressMetaData(info);

                    var map = info as Map;
                    var creator = new TorrentCreator();
                    creator.Path = resource.ArchivePath;
                    var ms = new MemoryStream();
                    creator.Create(ms);

                    byte[] minimap = null;
                    byte[] metalMap = null;
                    byte[] heightMap = null;
                    if (map != null)
                    {
                        minimap = map.Minimap.ToBytes(ImageSize);
                        metalMap = map.Metalmap.ToBytes(ImageSize);
                        heightMap = map.Heightmap.ToBytes(ImageSize);
                    }

                    var hash = Hash.HashBytes(File.ReadAllBytes(resource.ArchivePath));
                    var length = new FileInfo(resource.ArchivePath).Length;

                    Trace.TraceInformation("UnitSyncer: uploading {0} to server", info.Name);

                    ReturnValue e;
                    try
                    {
                        var service = GlobalConst.GetContentService();
                        e = service.RegisterResource(PlasmaServiceVersion,
                            null,
                            hash.ToString(),
                            (int)length,
                            info.ResourceType,
                            resource.ArchiveName,
                            info.Name,
                            serializedData,
                            info.Dependencies,
                            minimap,
                            metalMap,
                            heightMap,
                            ms.ToArray());
                    }
                    catch (Exception ex)
                    {
                        Trace.TraceError("UnitSyncer: Error uploading data to server: {0}", ex);
                        return;
                    }

                    if (e != ReturnValue.Ok) Trace.TraceWarning("UnitSyncer: Resource registering failed: {0}", e);
                }
            }
            catch (Exception ex)
            {
                Trace.TraceError("Error registering resource {0} : {1}", resource.ArchivePath, ex);
            }
        }