void ReadPlayerInfoFile(string playerFile)
        {
            if (!File.Exists(playerFile))
            {
                throw new FileNotFoundException("Player info file not found!");
            }

            if (transferPath != null)
            {
                throw new NotSupportedException("Session already has a transfer path!");
            }

            string str;

            using (FileStream fs = new FileStream(playerFile, FileMode.Open, FileAccess.Read))
                using (WatcherStream ws = new WatcherStream(fs))
                {
                    ws.Read(out str);
                    ws.Read(out installation);

                    ws.Read(out playerFactionIndex);
                }

            this.name         = Path.GetFileName(str);
            this.transferPath = Path.GetDirectoryName(str);
        }
        void ReadGameFile()
        {
            if (File.Exists(GameFile))
            {
                CodeVersion newVersion;
                string      newMod, newCampaign;
                using (WatcherStream ws = new WatcherStream(sessionFileWatcher, FileMode.Open, FileAccess.Read))
                {
                    ws.Read(out newVersion);
                    ws.Read(out newMod);
                    ws.Read(out newCampaign);

                    ws.Read(out difficulty);
                    ws.Read(out autoSolve);
                    ws.Read(out autoManage);
                    ws.Read(out shortCampaign);
                    ws.Read(out arcadeBattles);
                    ws.Read(out noBattleTimeLimit);
                    ws.Read(out startFactionIndex);
                    ws.Read(out lastPlayedFactionIndex);
                    ws.Read(out turn);
                }

                if ((version != null && newVersion != version) ||
                    (modName != null && !string.Equals(newMod, modName, StringComparison.OrdinalIgnoreCase)) ||
                    (campaignName != null && !string.Equals(newCampaign, campaignName, StringComparison.OrdinalIgnoreCase)))    // version, mod or campaign changed
                {
                    installation = null;
                    throw new NotSupportedException("Player faction should change too!");
                }

                version      = newVersion;
                modName      = newMod;
                campaignName = newCampaign;
            }
            else
            {
                version      = null;
                installation = null;
                modName      = null;
                campaignName = null;

                difficulty             = Difficulty.Unset;
                autoSolve              = false;
                autoManage             = false;
                shortCampaign          = false;
                startFactionIndex      = 0;
                lastPlayedFactionIndex = 0;
            }

            UpdateCurrentFaction();
        }
        void SaveFactionsFile()
        {
            Directory.CreateDirectory(GamePath);

            using (WatcherStream ws = new WatcherStream(factionsFileWatcher, FileMode.Create, FileAccess.Write))
            {
                ws.Write((byte)freeFactionIndices.Count);
                freeFactionIndices.ForEach(i => ws.Write(i));

                ws.Write((byte)takenFactionIndices.Count);
                takenFactionIndices.ForEach(i => ws.Write(i));
            }
        }
        void SavePlayerInfo()
        {
            Directory.CreateDirectory(PlayerPath);

            using (FileStream fs = new FileStream(PlayerFile, FileMode.Create, FileAccess.Write, FileShare.None))
                using (WatcherStream ws = new WatcherStream(fs))
                {
                    // read once
                    ws.Write(GamePath);
                    ws.Write(installation);

                    // info
                    ws.Write(playerFactionIndex);
                }
        }
        void ReadFactionsFile()
        {
            freeFactionIndices.Clear();
            takenFactionIndices.Clear();

            if (File.Exists(FactionsFile))
            {
                using (WatcherStream ws = new WatcherStream(factionsFileWatcher, FileMode.Open, FileAccess.Read))
                {
                    byte count, index;

                    ws.Read(out count);
                    for (int i = 0; i < count; i++)
                    {
                        ws.Read(out index);
                        freeFactionIndices.Add(index);
                    }

                    ws.Read(out count);
                    for (int i = 0; i < count; i++)
                    {
                        ws.Read(out index);
                        takenFactionIndices.Add(index);
                    }
                }
            }

            // in case of desyncs // fixme: warning
            if (playerFactionIndex != 0)
            {
                if (freeFactionIndices.Contains(playerFactionIndex))
                {
                    playerFactionIndex = 0;
                }
                if (!takenFactionIndices.Contains(playerFactionIndex))
                {
                    takenFactionIndices.Add(playerFactionIndex);
                }
            }

            if (OnFactionsChange != null)
            {
                OnFactionsChange(this);
            }

            UpdateCurrentFaction();
        }
        void SaveGameInfo()
        {
            Directory.CreateDirectory(GamePath);

            // game infos & compressed save
            using (WatcherStream ws = new WatcherStream(sessionFileWatcher, FileMode.Create, FileAccess.Write))
            {
                ws.Write(version);
                ws.Write(modName);
                ws.Write(campaignName);

                // game info
                ws.Write(difficulty);
                ws.Write(autoSolve);
                ws.Write(autoManage);
                ws.Write(shortCampaign);
                ws.Write(arcadeBattles);
                ws.Write(noBattleTimeLimit);
                ws.Write(startFactionIndex);
                ws.Write(lastPlayedFactionIndex);
                ws.Write(turn);
            }
        }