예제 #1
0
        /// <summary>
        /// Creates a new instance to be used for updating dat files
        /// </summary>
        /// <param name="master">The already updated file to be used as a master</param>
        public static DatUpdater Create(Settings.IDatFile master)
        {
            var du = new DatUpdater()
            {
                session = new Session(null)
                {
                    master = master,
                },
            };

            du.Initialize(du.session);

            return(du);
        }
예제 #2
0
        /// <summary>
        /// Lists all accounts using the specified dat file
        /// </summary>
        /// <param name="dat"></param>
        /// <returns></returns>
        public static List <Settings.IGw2Account> GetAccounts(Settings.IDatFile dat)
        {
            var accounts = new List <Settings.IGw2Account>();

            foreach (var a in Util.Accounts.GetGw2Accounts())
            {
                if (a.DatFile == dat)
                {
                    accounts.Add(a);
                }
            }

            return(accounts);
        }
예제 #3
0
        /// <summary>
        /// Lists all accounts using the specified dat file
        /// </summary>
        /// <param name="dat"></param>
        /// <returns></returns>
        public static List <Settings.IAccount> GetAccounts(Settings.IDatFile dat)
        {
            List <Settings.IAccount> accounts = new List <Settings.IAccount>();

            foreach (ushort uid in Settings.Accounts.GetKeys())
            {
                var account = Settings.Accounts[uid];
                if (account.HasValue && account.Value.DatFile == dat)
                {
                    accounts.Add(account.Value);
                }
            }

            return(accounts);
        }
예제 #4
0
        /// <summary>
        /// Updates the Local.dat file based on the supplied master file
        /// </summary>
        public bool Update(Settings.IDatFile dat)
        {
            try
            {
                Update(session, dat);

                dat.IsPending = false;

                return(true);
            }
            catch
            {
                return(false);
            }
        }
예제 #5
0
        private void Snapshot(Settings.IDatFile master)
        {
            Session s;

            lock (this)
            {
                s = new Session(session)
                {
                    master = master,
                };

                if (session != null)
                {
                    session.abort = true;
                }

                session = s;
            }

            try
            {
                using (var r = new BinaryReader(new BufferedStream(File.Open(master.Path, FileMode.Open, FileAccess.Read, FileShare.Read))))
                {
                    var mft = DatFile.ReadMft(r);
                    s.snapshot = new Dictionary <int, int>(mft.entries.Length);

                    foreach (var entry in mft.entries)
                    {
                        if (entry.baseId > 0)
                        {
                            s.snapshot[entry.baseId] = entry.fileId;

                            if (entry.baseId == ID_LOCAL)
                            {
                                r.BaseStream.Position = entry.offset;
                                s.snapshot[0]         = ReadBuild(s.compressor, r.BaseStream, entry);
                            }
                        }
                    }
                }
            }
            catch { }
        }
예제 #6
0
        private void Update(Session s)
        {
            var ids  = Settings.DatFiles.GetKeys();
            var dats = new Settings.IDatFile[ids.Length];
            var i    = 0;

            if (!BitConverter.IsLittleEndian)
            {
                throw new NotSupportedException();
            }

            var hs    = new HashSet <ushort>();
            var queue = new Queue <Settings.IDatFile>(ids.Length);

            foreach (var uid in ids)
            {
                if (s.master.UID == uid)
                {
                    continue;
                }

                var dat = Settings.DatFiles[uid].Value;
                if (dat != null && dat.References > 0 && dat.IsPending)
                {
                    dats[i++] = dat;

                    hs.Add(dat.UID);
                    queue.Enqueue(dat);
                }
            }

            if (i > 0)
            {
                Initialize(s);

                s.task = new Task(DoQueue, TaskCreationOptions.LongRunning);
                s.task.Start();
            }
        }
예제 #7
0
        public static int GetBuild(Settings.IDatFile dat)
        {
            try
            {
                using (var r = new BinaryReader(new BufferedStream(File.Open(dat.Path, FileMode.Open, FileAccess.Read, FileShare.Read))))
                {
                    var mft = Dat.DatFile.ReadMft(r);

                    foreach (var entry in mft.entries)
                    {
                        switch (entry.baseId)
                        {
                        case ID_LOCAL:

                            return(ReadBuild(new Archive(), r.BaseStream, entry));
                        }
                    }
                }
            }
            catch { }

            return(0);
        }
예제 #8
0
        private void buttonOK_Click(object sender, EventArgs e)
        {
            if (textAccountName.Text.Length == 0)
            {
                buttonGeneral.Selected = true;
                MessageBox.Show(this, "An identifier / account or display name is required", "Identifier / name required", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            Rectangle windowBounds;

            if (checkWindowed.Checked)
            {
                Rectangle r = ParseWindowSize(textWindowed.Text);
                windowBounds = FixSize(r);
            }
            else
                windowBounds = Rectangle.Empty;

            Settings.IDatFile datFile;

            try
            {
                datFile = GetDatFile();
                selectedFile = null;
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, "An error occured while handling Local.dat.\n\n" + ex.Message, "Failed handling Local.dat", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (this.account == null)
            {
                this.account = Settings.CreateAccount();
                this.account.LastUsedUtc = DateTime.MinValue;
                this.account.CreatedUtc = DateTime.UtcNow;
            }

            this.account.Windowed = checkWindowed.Checked;
            this.account.Name = textAccountName.Text;
            this.account.WindowsAccount = textWindowsAccount.Text;
            this.account.Arguments = textArguments.Text;
            this.account.ShowDaily = checkShowDaily.Checked;
            this.account.DatFile = datFile;
            this.account.WindowBounds = windowBounds;
            this.account.RecordLaunches = checkRecordLaunch.Checked;

            if (checkAutomaticLogin.Checked && textAutoLoginEmail.TextLength > 0 && textAutoLoginPassword.TextLength > 0)
            {
                this.account.AutomaticLoginEmail = textAutoLoginEmail.Text;
                this.account.AutomaticLoginPassword = textAutoLoginPassword.Text;
            }
            else
            {
                this.account.AutomaticLoginEmail = null;
                this.account.AutomaticLoginPassword = null;
            }

            this.DialogResult = System.Windows.Forms.DialogResult.OK;
        }
예제 #9
0
        private Settings.IDatFile GetDatFile()
        {
            if (selectedFile == null)
            {
                if (account != null)
                    return account.DatFile;
                else
                    return null;
            }
            else if (selectedFile.DatFile != null)
            {
                return selectedFile.DatFile;
            }
            else if (selectedFile.Path == null)
            {
                return null;
            }

            Security.Impersonation.IImpersonationToken impersonation = null;

            string username = Util.Users.GetUserName(textWindowsAccount.Text);
            bool isCurrent = Util.Users.IsCurrentUser(username);
            bool userExists = isCurrent;
            bool wasMoved = false;

            string path = null;

            if (!isCurrent)
            {
                try
                {
                    using (var user = Util.Users.GetPrincipal(username))
                    {
                        userExists = user != null;
                    }
                }
                catch { }

                if (userExists)
                {
                    var password = Security.Credentials.GetPassword(username);

                    while (true)
                    {
                        if (password == null)
                        {
                            using (formPassword f = new formPassword("Password for " + username))
                            {
                                if (f.ShowDialog(this) == DialogResult.OK)
                                {
                                    password = f.Password;
                                    Security.Credentials.SetPassword(username, password);
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }

                        try
                        {
                            impersonation = Security.Impersonation.Impersonate(username, Security.Credentials.GetPassword(username));
                            break;
                        }
                        catch (Win32Exception ex)
                        {
                            if (ex.NativeErrorCode == 1326)
                            {
                                password = null;
                                continue;
                            }

                            break;
                        }
                        catch (Exception ex)
                        {
                            break;
                        }
                    }
                }
            }

            if (isCurrent || impersonation != null)
            {
                try
                {
                    string folder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData, Environment.SpecialFolderOption.Create);
                    if (!string.IsNullOrWhiteSpace(folder))
                    {
                        folder = Path.Combine(folder, "Guild Wars 2");
                        if (!Directory.Exists(folder))
                            Directory.CreateDirectory(folder);

                        path = Util.FileUtil.GetTemporaryFileName(folder);

                        try
                        {
                            File.Move(selectedFile.Path, path);
                            wasMoved = true;
                        }
                        catch
                        {
                            try
                            {
                                File.Copy(selectedFile.Path, path, true);
                            }
                            catch (Exception e)
                            {
                                throw e;
                            }
                        }
                    }
                    else
                    {
                        //the user exists, but the account hasn't been set up yet
                    }
                }
                finally
                {
                    if (impersonation != null)
                        impersonation.Dispose();
                }
            }

            if (datFile == null)
                datFile = Settings.CreateDatFile();

            if (path == null)
                datFile.Path = Path.GetFullPath(selectedFile.Path);
            else
            {
                try
                {
                    //now that datFile setting has been created, rename the file from its temp name
                    string _path = Path.Combine(Path.GetDirectoryName(path), "Local." + datFile.UID + ".dat");
                    File.Move(path, _path);
                    path = _path;
                }
                catch { }
                datFile.Path = Path.GetFullPath(path);
            }

            if (!wasMoved)
            {
                try
                {
                    File.Delete(selectedFile.Path);
                }
                catch { }
            }

            return datFile;
        }
예제 #10
0
 /// <summary>
 /// Updates the dat file using the master
 /// </summary>
 public static bool Create(Settings.IDatFile master, Settings.IDatFile dat)
 {
     return(Create(master).Update(dat));
 }
예제 #11
0
        /// <summary>
        /// Waits for a dat file being updated in the background to complete
        /// </summary>
        public void Wait(Settings.IDatFile dat)
        {
            ManualResetEvent waiter = null;
            EventHandler <Settings.IDatFile> onComplete = null;

            while (true)
            {
                var found = false;

                lock (this)
                {
                    if (session != null && session.queued != null && session.queued.Contains(dat.UID))
                    {
                        for (var i = session.queue.Count - 1; i >= 0; --i)
                        {
                            if (session.queue.Peek() == dat)
                            {
                                if (waiter == null)
                                {
                                    waiter     = new ManualResetEvent(false);
                                    onComplete = delegate(object o, Settings.IDatFile d)
                                    {
                                        if (d == dat)
                                        {
                                            DatComplete -= onComplete;
                                            waiter.Set();
                                        }
                                    };
                                    DatComplete += onComplete;
                                }
                                found = true;

                                break;
                            }
                            session.queue.Enqueue(session.queue.Dequeue());
                        }
                    }
                }

                if (waiter != null)
                {
                    if (found && waiter.WaitOne(60000, false))
                    {
                        waiter.Dispose();
                        return;
                    }
                    else
                    {
                        DatComplete -= onComplete;
                        if (!found)
                        {
                            waiter.Dispose();
                            return;
                        }
                    }
                }
                else
                {
                    return;
                }
            }
        }
예제 #12
0
        private void Update(Session s, Settings.IDatFile dat)
        {
            using (var r = new BinaryReader(new BufferedStream(System.IO.File.Open(dat.Path, FileMode.Open, FileAccess.ReadWrite, FileShare.Read))))
            {
                DatFile.Mft mft;
                int         mftEntries;

                if (r.BaseStream.Length > 0)
                {
                    mft        = DatFile.ReadMft(r);
                    mftEntries = mft.entries.Length;
                }
                else
                {
                    mft        = null;
                    mftEntries = 0;
                }
                var blockSize = s.BlockSize;
                var custom    = new Dictionary <int, CustomEntry>();
                var entries   = s.entries;
                var count     = s.entriesCount;
                var remaining = s.snapshot.Count;
                var changed   = false;
                var size      = 0;

                for (var i = 0; i < mftEntries; i++)
                {
                    var entry = mft.entries[i];

                    if (entry.baseId > 0)
                    {
                        if (!changed)
                        {
                            int fileId;
                            if (s.snapshot.TryGetValue(entry.baseId, out fileId))
                            {
                                --remaining;

                                if (fileId != entry.fileId)
                                {
                                    changed = true;
                                }
                                else
                                {
                                    if (entry.baseId == ID_CACHE)
                                    {
                                        var e = FindEntry(s.entries, s.entriesCount, entry.baseId);
                                        if (e != null && e.size != entry.size)
                                        {
                                            changed = true;
                                        }
                                    }
                                }

                                continue;
                            }
                        }

                        if (entry.baseId == entry.fileId && entry.baseId < 100 && entry.size > 0)
                        {
                            if (changed && s.snapshot.ContainsKey(entry.baseId))
                            {
                                continue;
                            }

                            switch (entry.baseId)
                            {
                            case ID_LOCAL:

                                byte[] data;
                                int    position;

                                var build = ReadBuild(s.compressor, r.BaseStream, entry, out data, out position);

                                if (s.build > build)
                                {
                                    changed = true;

                                    //updating the build
                                    //note that this isn't required

                                    var b = BitConverter.GetBytes(s.build);
                                    Array.Copy(b, 0, data, position, 4);

                                    var c = new CustomEntry()
                                    {
                                        compress = true,
                                        data     = data,
                                        entry    = entry,
                                        index    = i,
                                        length   = data.Length,
                                    };

                                    custom[entry.baseId] = c;

                                    entry.offset = long.MaxValue;
                                    entry.size   = data.Length;
                                }

                                break;
                            }

                            entries[count++] = entry;
                            size            += (entry.size / blockSize + 1) * blockSize;
                        }
                    }
                }

                if (!changed && remaining == 0)
                {
                    return;
                }

                size += ((s.entriesCount + count) * 40 / blockSize + 1) * blockSize; //add padding for entries and IDs (24 bytes per entry, 8-16 bytes per id)

                Array.Sort(entries, s.entriesCount, count - s.entriesCount, Comparer <DatFile.MftEntry> .Create(
                               delegate(DatFile.MftEntry a, DatFile.MftEntry b)
                {
                    return(a.offset.CompareTo(b.offset));
                }));

                var buffer = s.buffer2;
                if (buffer == null || buffer.Length < size)
                {
                    s.buffer2 = buffer = new byte[size + 1024 * 1024];
                }

                var ofs  = 0;
                var fofs = s.buffer1.Length;

                for (var i = s.entriesCount; i < count; i++)
                {
                    var e = entries[i];

                    if (e.size == 0)
                    {
                        e.offset = 0;
                        continue;
                    }

                    if (e.offset != long.MaxValue)
                    {
                        r.BaseStream.Position = e.offset;
                        ReadBytes(r, buffer, ofs, e.size);
                    }
                    else
                    {
                        CustomEntry c;
                        if (custom.TryGetValue(e.baseId, out c))
                        {
                            e.size = c.WriteTo(buffer, ofs, s.compressor);
                        }
                    }

                    e.offset = ofs + fofs;
                    ofs     += (e.size / blockSize + 1) * blockSize;
                }

                using (var fs = new Dat.Compression.IO.FileStream(new MemoryStream(buffer), false, true, false))
                {
                    using (var w = new BinaryWriter(fs))
                    {
                        w.BaseStream.Position = ofs;

                        //write ids
                        for (var i = 1; i <= count; i++)
                        {
                            var entry = entries[i - 1];

                            if (entry.baseId > 0)
                            {
                                w.Write(entry.baseId);
                                w.Write(i);

                                if (entry.baseId != entry.fileId)
                                {
                                    w.Write(entry.fileId);
                                    w.Write(i);
                                }
                            }
                        }

                        var e = entries[INDEX_IDS];

                        e.offset = ofs + fofs;
                        e.size   = (int)(w.BaseStream.Position - ofs);
                        e.crc    = fs.CRC;
                        ofs     += (e.size / blockSize + 1) * blockSize;

                        e = entries[INDEX_ENTRIES];
                        w.BaseStream.Position = ofs;
                        fs.ResetCRC();

                        //write entries header
                        w.Write(443835981U);
                        w.Write(0L);
                        w.Write(count + 1);
                        w.Write(0L);

                        //write first set of entries
                        for (var i = 0; i < INDEX_ENTRIES; i++)
                        {
                            WriteEntry(w, entries[i]);
                        }

                        var p0 = w.BaseStream.Position;
                        w.BaseStream.Position += 24; //entry is written last

                        //write remaining entries
                        for (var i = INDEX_ENTRIES + 1; i < count; i++)
                        {
                            WriteEntry(w, entries[i]);
                        }

                        e.offset = ofs + fofs;
                        e.size   = (int)(w.BaseStream.Position - ofs);
                        e.crc    = fs.CRC;
                        ofs     += (e.size / blockSize + 1) * blockSize;

                        s.MftOffset = e.offset;
                        s.MftSize   = e.size;

                        w.BaseStream.Position = p0;
                        WriteEntry(w, entries[INDEX_ENTRIES]);
                    }
                }

                var stream = r.BaseStream;

                stream.Position = 0;
                stream.Write(s.buffer1, 0, s.buffer1.Length);
                stream.Write(buffer, 0, ofs);

                stream.SetLength(stream.Position);
            }
        }
예제 #13
0
        private void DoQueue()
        {
            Session s;

            lock (this)
            {
                s = this.session;
                if (s == null || s.abort)
                {
                    return;
                }
            }

            var q = s.queue;

            Settings.IDatFile dat = null;

            while (true)
            {
                lock (this)
                {
                    if (dat != null)
                    {
                        s.queued.Remove(dat.UID);
                        if (DatComplete != null)
                        {
                            DatComplete(this, dat);
                        }
                    }

                    if (s.abort || q.Count == 0)
                    {
                        if (!s.abort)
                        {
                            session = null;
                            if (Complete != null)
                            {
                                Complete(this, EventArgs.Empty);
                            }
                        }
                        return;
                    }

                    dat = q.Dequeue();
                }

                try
                {
                    Update(s, dat);

                    lock (this)
                    {
                        if (!s.abort)
                        {
                            dat.IsPending = false;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Util.Logging.Log(ex);
                }
            }
        }
예제 #14
0
        private void buttonOK_Click(object sender, EventArgs e)
        {
            const int INDEX_DEFAULT = 0;
            const int INDEX_SHARED  = 1;

            var accounts = GetAccounts();

            byte[] gfxfile     = null;
            var    manualcount = 0;

            var dats     = new Settings.IDatFile[2];
            var gfxs     = new Settings.IGfxFile[2];
            var checkDat = new bool[] { true, true };
            var checkGfx = new bool[] { true, true };

            if (textGw2Path.TextLength > 0 && File.Exists(textGw2Path.Text))
            {
                try
                {
                    var bits = Util.FileUtil.GetExecutableBits(textGw2Path.Text);

                    if (Environment.Is64BitOperatingSystem && bits == 32)
                    {
                        if (Settings.GuildWars2.Arguments.HasValue)
                        {
                            Settings.GuildWars2.Arguments.Value = Util.Args.AddOrReplace(Settings.GuildWars2.Arguments.Value, "32", "-32");
                        }
                        else
                        {
                            Settings.GuildWars2.Arguments.Value = "-32";
                        }
                    }

                    Settings.GuildWars2.Path.Value = textGw2Path.Text;
                }
                catch { }
            }

            checkGfx[INDEX_DEFAULT] = Settings.GuildWars2.Path.HasValue;

            foreach (var a in accounts)
            {
                if (!a.HasCredentials)
                {
                    ++manualcount;
                }
            }

            foreach (var a in accounts)
            {
                var _account = (Settings.IGw2Account)Settings.CreateAccount(Settings.AccountType.GuildWars2);
                var dat      = INDEX_DEFAULT;
                var gfx      = INDEX_DEFAULT;

                _account.Name = a.Name;

                if (a.HasCredentials)
                {
                    _account.Email            = a.Email;
                    _account.Password         = Settings.PasswordString.Create(a.Password);
                    _account.AutologinOptions = Settings.AutologinOptions.Login | Settings.AutologinOptions.Play;

                    dat = INDEX_SHARED;
                }
                else if (panelLogin.Enabled)
                {
                    if (radioLoginRemembered.Checked)
                    {
                        _account.AutomaticRememberedLogin = true;

                        dat = -1;
                    }
                }

                if (panelGraphics.Enabled)
                {
                    if (radioGraphicsShared.Checked)
                    {
                        gfx = INDEX_SHARED;
                    }
                    else
                    {
                        gfx = -1;
                    }
                }

                if (dat == -1 || checkDat[dat] && dats[dat] == null)
                {
                    if (dat != -1)
                    {
                        checkDat[dat] = false;
                    }

                    if (dat == INDEX_DEFAULT)
                    {
                        var path = Client.FileManager.GetDefaultPath(Client.FileManager.FileType.Dat);
                        var f    = dats[dat] = (Settings.IDatFile)Client.FileManager.FindFile(Client.FileManager.FileType.Dat, path);

                        if (f == null && File.Exists(path))
                        {
                            dats[dat] = f = Settings.CreateDatFile();
                            f.Path    = path;
                        }

                        _account.DatFile = dats[dat];
                    }
                    else
                    {
                        var path = CreateTempFile();

                        if (!string.IsNullOrEmpty(path))
                        {
                            var f = Settings.CreateDatFile();
                            f.Path = path;
                            if (dat != -1)
                            {
                                dats[dat] = f;
                            }
                            _account.DatFile = f;
                        }
                    }
                }
                else
                {
                    _account.DatFile = dats[dat];
                }

                if (gfx == -1 || checkGfx[gfx] && gfxs[gfx] == null)
                {
                    if (gfx != -1)
                    {
                        checkGfx[gfx] = false;
                    }

                    if (gfx == INDEX_DEFAULT)
                    {
                        var path = Client.FileManager.GetDefaultPath(Client.FileManager.FileType.Gfx);
                        var f    = gfxs[gfx] = (Settings.IGfxFile)Client.FileManager.FindFile(Client.FileManager.FileType.Gfx, path);

                        if (f == null && File.Exists(path))
                        {
                            gfxs[gfx] = f = Settings.CreateGfxFile();
                            f.Path    = path;
                        }

                        _account.GfxFile = gfxs[gfx];
                    }
                    else
                    {
                        var path = CreateTempFile();

                        if (!string.IsNullOrEmpty(path))
                        {
                            if (gfxfile == null)
                            {
                                gfxfile = ReadGfxData();
                            }

                            if (gfxfile.Length > 0)
                            {
                                try
                                {
                                    File.WriteAllBytes(path, gfxfile);
                                }
                                catch { }
                            }

                            var f = Settings.CreateGfxFile();
                            f.Path = path;
                            if (gfx != -1)
                            {
                                gfxs[gfx] = f;
                            }
                            _account.GfxFile = f;
                        }
                    }
                }
                else
                {
                    _account.GfxFile = gfxs[gfx];
                }

                //note some accounts may be given null dat/gfx files - these will be automatically set on launch to the default files used by gw2
            }

            if (radioAddonsAuto.Checked || radioAddonsManual.Checked)
            {
                var o = Settings.LocalizeAccountExecutionOptions.Enabled;

                if (panelDirectUpdates.Enabled && radioDirectUpdateYes.Checked)
                {
                    o |= Settings.LocalizeAccountExecutionOptions.OnlyIncludeBinFolders;
                }
                if (radioAddonsAuto.Checked)
                {
                    o |= Settings.LocalizeAccountExecutionOptions.AutoSync | Settings.LocalizeAccountExecutionOptions.AutoSyncDeleteUnknowns;
                }

                Settings.GuildWars2.LocalizeAccountExecution.Value = o;
            }

            if (panelDirectUpdates.Enabled && radioDirectUpdateYes.Checked)
            {
                Settings.GuildWars2.DatUpdaterEnabled.Value = true;
                Settings.GuildWars2.UseCustomGw2Cache.Value = true;
            }

            this.DialogResult = System.Windows.Forms.DialogResult.OK;
            this.Close();
        }