コード例 #1
0
ファイル: Program.cs プロジェクト: bono851212/opera-tools
        public static int Main(string[] args)
        {
            int result;

            try
            {
                ColoredConsole.WriteLine("~WOpera Speed Dial Patch for {0}~N", OperaPatches.Patches[0].StartVersion);
                ColoredConsole.WriteLine("~WCopyright (c) 2013 dqdb~N");
                ColoredConsole.WriteLine();
                ColoredConsole.WriteLine("Thanks to ~WIzer0~N for all patches.");
                ColoredConsole.WriteLine();
                Settings settings = new Settings();
                settings.LoadFromConfigFile();
                settings.LoadFromConsole();
                settings.SaveToConfigFile();
                ColoredConsole.WriteLine();

                string pakFileName = FindLatestOperaPak(settings.OperaFolder);
                if (pakFileName == null)
                {
                    ColoredConsole.WriteLine("~r~WError:~k~R unable to find an ~r~Wopera.pak~N to patch.~N");
                    return(1);
                }

                OperaVersion version;

                try
                {
                    version = GetOperaPakVersion(pakFileName);
                }
                catch (Exception)
                {
                    ColoredConsole.WriteLine("~r~WError:~k~R unable to get version number from ~r~W{0}~k~R.~N", pakFileName);
                    return(1);
                }

                ColoredConsole.WriteLine("Opera version: ~W{0}~N", version);

                OperaPatch operaPatch = OperaPatches.Find(version);
                if (operaPatch == null)
                {
                    operaPatch = OperaPatches.FindWithHeuristics(settings, pakFileName);
                    if (operaPatch == null)
                    {
                        ColoredConsole.WriteLine();
                        ColoredConsole.WriteLine("~r~WError:~k~R this Opera version is not supported yet.~N");
                        return(1);
                    }

                    ColoredConsole.WriteLine();
                    ColoredConsole.WriteLine("Processing ...");
                    ColoredConsole.WriteLine();
                    ColoredConsole.WriteLine("OperaExeOffset: ~W0x{0:x8}~N", operaPatch.ExePatch.Offset);
                    ColoredConsole.WriteLine("SpeeddialLayoutJs: ~W{0}~N", operaPatch.SpeeddialLayoutJs);
                    ColoredConsole.WriteLine("StartPageHtml: ~W{0}~N", operaPatch.StartPageHtml);
                    ColoredConsole.WriteLine("PreinstalledSpeeddialsJs: ~W{0}~N", operaPatch.PreinstalledSpeeddialsJs);
                    ColoredConsole.WriteLine("SpeeddialSuggestionsJs: ~W{0}~N", operaPatch.SpeeddialSuggestionsJs);
                    ColoredConsole.WriteLine("ToolsCss: ~W{0}~N", operaPatch.ToolsCss);
                    ColoredConsole.WriteLine("FilterCss: ~W{0}~N", operaPatch.FilterCss);
                    ColoredConsole.WriteLine();

                    ColoredConsole.WriteLine("~y~KWarning:~k~Y this Opera version is probably supported, but it is ~y~KNOT~k~Y tested yet. Improper patching may have side effects.~N");
                    ColoredConsole.WriteLine();
                    if (!ColoredConsole.Read("I understand the risks: ", false))
                    {
                        return(1);
                    }
                    ColoredConsole.WriteLine();
                }
                else
                {
                    ColoredConsole.WriteLine("Using resource layout for Opera ~W{0}~N - ~W{1}~N builds.", operaPatch.StartVersion, operaPatch.EndVersion);
                    ColoredConsole.WriteLine();
                }

                if (!ColoredConsole.Read("I would like to start patching: ", true))
                {
                    return(1);
                }

                ColoredConsole.WriteLine();

                operaPatch.Apply(settings, pakFileName);
                result = 0;
            }
            catch (Exception ex)
            {
                ColoredConsole.WriteLine();
                if (ex.InnerException == null)
                {
                    ColoredConsole.WriteLine("~r~WError:~k~R {0}~N", ex.Message);
                }
                else
                {
                    ColoredConsole.WriteLine("~r~WError:~k~R {0}~N ----> {1}", ex.Message, ex.InnerException.ToString());
                }
                result = 1;
            }
            return(result);
        }
コード例 #2
0
ファイル: Program.cs プロジェクト: Hanngman/opera-tools
        public static int Main(string[] args)
        {
            int result;

            try
            {
                ColoredConsole.WriteLine("~WOpera Speed Dial Patch (build 20131124)~N");
                ColoredConsole.WriteLine("~WCopyright (c) 2013 dqdb~N");
                ColoredConsole.WriteLine();
                ColoredConsole.WriteLine("Thanks to ~WIzer0~N for all patches.");
                ColoredConsole.WriteLine();
                Settings settings = new Settings();
                settings.LoadFromConfigFile();
                settings.LoadFromConsole();
                settings.SaveToConfigFile();
                ColoredConsole.WriteLine();

                string pakFileName = FindLatestOperaPak(settings.OperaFolder);
                if (pakFileName == null)
                {
                    ColoredConsole.WriteLine("~r~WError:~k~R unable to find an ~r~Wopera.pak~N to patch.~N");
                    return(1);
                }

                OperaVersion version;

                try
                {
                    version = GetOperaPakVersion(pakFileName);
                }
                catch (Exception)
                {
                    ColoredConsole.WriteLine("~r~WError:~k~R unable to get version number from ~r~W{0}~k~R.~N", pakFileName);
                    return(1);
                }

                ColoredConsole.WriteLine("Opera version: ~W{0}~N", version);

                OperaPatch operaPatch = OperaPatches.FindWithHeuristics(settings, pakFileName);
                if (operaPatch == null)
                {
                    ColoredConsole.WriteLine();
                    ColoredConsole.WriteLine("~r~WError:~k~R this Opera version is not supported yet.~N");
                    return(1);
                }

                ColoredConsole.WriteLine();
                ColoredConsole.WriteLine("Processing ...");
                ColoredConsole.WriteLine();
                ColoredConsole.WriteLine("OperaPackHashOffset: ~W0x{0:x8}~N", operaPatch.OperaPakHashOffset);
                ColoredConsole.WriteLine("SpeeddialLayoutJs: ~W{0}~N", operaPatch.SpeeddialLayoutJs);
                ColoredConsole.WriteLine("StartPageHtml: ~W{0}~N", operaPatch.StartPageHtml);
                ColoredConsole.WriteLine("PreinstalledSpeeddialsJs: ~W{0}~N", operaPatch.PreinstalledSpeeddialsJs);
                ColoredConsole.WriteLine("SpeeddialSuggestionsJs: ~W{0}~N", operaPatch.SpeeddialSuggestionsJs);
                ColoredConsole.WriteLine("ToolsCss: ~W{0}~N", operaPatch.ToolsCss);
                ColoredConsole.WriteLine("FilterCss: ~W{0}~N", operaPatch.FilterCss);
                ColoredConsole.WriteLine();

                if (!ColoredConsole.Read("I would like to start patching: ", true))
                {
                    return(1);
                }

                ColoredConsole.WriteLine();

                operaPatch.Apply(settings, pakFileName);
                result = 0;
            }
            catch (Exception ex)
            {
                ColoredConsole.WriteLine();
                if (ex.InnerException == null)
                {
                    ColoredConsole.WriteLine("~r~WError:~k~R {0}~N", ex.Message);
                }
                else
                {
                    ColoredConsole.WriteLine("~r~WError:~k~R {0}~N ----> {1}", ex.Message, ex.InnerException.ToString());
                }
                result = 1;
            }
            return(result);
        }
コード例 #3
0
ファイル: OperaPatch.cs プロジェクト: Hanngman/opera-tools
        public void Apply(Settings settings, string pakFileName)
        {
            string     originalPakFileName = pakFileName + BackupExtension;
            CssPatches cssPatches          = settings.CssPatches;

            PakFile pakFile = new PakFile();

            ColoredConsole.WriteLine("Reading ~W{0}~N ...", pakFileName);

            if (!File.Exists(originalPakFileName))
            {
                File.Copy(pakFileName, originalPakFileName);
            }
            else
            {
                File.Copy(originalPakFileName, pakFileName, true);
            }

            pakFile.Load(pakFileName);

            const string TEXT_MAX_X_COUNT                     = "  var MAX_X_COUNT = ";
            const string TEXT_MARGIN_X                        = "  var MARGIN_X = ";
            const string TEXT_MARGIN_Y                        = "  var MARGIN_Y = ";
            const string TEXT_DIAL_WIDTH                      = "SpeeddialObject.DIAL_WIDTH = ";
            const string TEXT_DIAL_HEIGHT                     = "SpeeddialObject.DIAL_HEIGHT = ";
            const string TEXT_THUMBNAIL_URL1                  = "    \"size=\" + this.DIAL_WIDTH + \"x\" + this.DIAL_HEIGHT +";
            const string TEXT_THUMBNAIL_URL2                  = "    \"size=\" + (({0:F4} * this.DIAL_WIDTH + 0.5) >> 0) + \"x\" + (({0:F4} * this.DIAL_HEIGHT + 0.5) >> 0) +";
            const string TEXT_CSS_WIDTH                       = "  width: ";
            const string TEXT_CSS_HEIGHT                      = "  height: ";
            const string TEXT_CSS_TOP                         = "  top: ";
            const string TEXT_CSS_LEFT                        = "  left: ";
            const string TEXT_CSS_BACKGROUND_POSITION         = "  background-position: ";
            const string TEXT_PREINSTALLED_CHECK_URL_FUNCTION = "  this.checkURL = function(URL)";
            const string TEXT_PREINSTALLED_CHECK_URL_NEXTLINE = "  {";
            const string TEXT_PREINSTALLED_LAST_LINE          = "}).apply(PreinstalledSpeeddials);";
            const string TEXT_STYLE           = "</style>";
            const string TEXT_DIAL_URL        = "SpeeddialObject.DIAL_URL + ";
            const string TEXT_DIAL_RELOAD_URL = "SpeeddialObject.DIAL_RELOAD_URL +";
            const string TEXT_ADD_DIAL_URL    = "var sdURL = sd_obj.sdURL || SpeeddialObject.DIAL_URL + ";

            string[] lines = pakFile.GetItem(SpeeddialLayoutJs);
            for (int n = 0; n < lines.Length; n++)
            {
                string line = lines[n];
                if (line.StartsWith(TEXT_MAX_X_COUNT))
                {
                    lines[n] = TEXT_MAX_X_COUNT + settings.SpeedDial.Columns.ToString() + ";";
                }
                else if (line.StartsWith(TEXT_MARGIN_X))
                {
                    lines[n] = TEXT_MARGIN_X + settings.SpeedDial.MarginX.ToString() + ";";
                }
                else if (line.StartsWith(TEXT_MARGIN_Y))
                {
                    lines[n] = TEXT_MARGIN_Y + settings.SpeedDial.MarginY.ToString() + ";";
                }
                else if (line.StartsWith(TEXT_DIAL_WIDTH))
                {
                    lines[n] = TEXT_DIAL_WIDTH + settings.SpeedDial.ThumbnailWidth.ToString() + ";";
                }
                else if (line.StartsWith(TEXT_DIAL_HEIGHT))
                {
                    lines[n] = TEXT_DIAL_HEIGHT + settings.SpeedDial.ThumbnailHeight.ToString() + ";";
                }
                else if (settings.SpeedDial.CropPageForThumbnail && line.StartsWith(TEXT_THUMBNAIL_URL1))
                {
                    lines[n] = String.Format(CultureInfo.InvariantCulture, TEXT_THUMBNAIL_URL2, 100.0 / settings.SpeedDial.CropArea);
                }
                else if (settings.SpeedDial.AddCustomThumbnails && line.Contains(TEXT_DIAL_URL))
                {
                    lines[n] = "          PreinstalledSpeeddials.transformURL(this.navigateURL) || (SpeeddialObject.DIAL_URL + encodeURIComponent(this.navigateURL))";
                }
                else if (settings.SpeedDial.AddCustomThumbnails && line.Contains(TEXT_DIAL_RELOAD_URL))
                {
                    lines[n]     = "          PreinstalledSpeeddials.transformURL(this.navigateURL) || (SpeeddialObject.DIAL_RELOAD_URL + encodeURIComponent(this.navigateURL))";
                    lines[n + 1] = "";
                }
            }
            pakFile.SetItem(SpeeddialLayoutJs, lines);

            if (settings.SpeedDial.AddCustomThumbnails)
            {
                lines = pakFile.GetItem(SpeeddialSuggestionsJs);
                for (int n = 0; n < lines.Length; n++)
                {
                    if (lines[n].Contains(TEXT_ADD_DIAL_URL))
                    {
                        lines[n] = "    var sdURL = sd_obj.sdURL || PreinstalledSpeeddials.transformURL(sd_obj.url) || SpeeddialObject.DIAL_URL + encodeURIComponent(sd_obj.url);";
                        break;
                    }
                }
                pakFile.SetItem(SpeeddialSuggestionsJs, lines);
            }

            lines = pakFile.GetItem(StartPageHtml);
            for (int n = 0; n < lines.Length; n++)
            {
                string line = lines[n];
                if (line == ".speeddial")
                {
                    ApplyCssPixelRule(lines, n, TEXT_CSS_WIDTH, settings.SpeedDial.ThumbnailWidth);
                    ApplyCssPixelRule(lines, n, TEXT_CSS_HEIGHT, settings.SpeedDial.ThumbnailHeight);
                    if (settings.SpeedDial.CropPageForThumbnail)
                    {
                        ApplyCssRule(lines, n, TEXT_CSS_BACKGROUND_POSITION, "0% 0%");
                    }
                }
                else if (line == ".dial-thumbnail")
                {
                    ApplyCssPixelRule(lines, n, TEXT_CSS_WIDTH, (settings.SpeedDial.ThumbnailWidth - 36) / 2);
                    ApplyCssPixelRule(lines, n, TEXT_CSS_HEIGHT, (settings.SpeedDial.ThumbnailHeight - 28) / 2);
                }
                else if (line == ".dial-thumbnail:nth-child(2)")
                {
                    ApplyCssPixelRule(lines, n, TEXT_CSS_LEFT, settings.SpeedDial.ThumbnailWidth / 2);
                }
                else if (line == ".dial-thumbnail:nth-child(3)")
                {
                    ApplyCssPixelRule(lines, n, TEXT_CSS_TOP, settings.SpeedDial.ThumbnailHeight / 2 - 1);
                }
                else if (line == ".dial-thumbnail:nth-child(4)")
                {
                    ApplyCssPixelRule(lines, n, TEXT_CSS_LEFT, settings.SpeedDial.ThumbnailWidth / 2);
                    ApplyCssPixelRule(lines, n, TEXT_CSS_TOP, settings.SpeedDial.ThumbnailHeight / 2 - 1);
                }
                else if (line.StartsWith(TEXT_STYLE))
                {
                    lines[n] = TEXT_STYLE + cssPatches.Apply("<style>", "</style>", CssPatchFile.StartPageHtml);
                }
            }
            pakFile.SetItem(StartPageHtml, lines);

            lines = pakFile.GetItem(ToolsCss);
            lines[lines.Length - 1] = cssPatches.Apply("", "", CssPatchFile.ToolsCss);
            pakFile.SetItem(ToolsCss, lines);

            lines = pakFile.GetItem(FilterCss);
            lines[lines.Length - 1] = cssPatches.Apply("", "", CssPatchFile.FilterCss);
            pakFile.SetItem(FilterCss, lines);

            lines = pakFile.GetItem(PreinstalledSpeeddialsJs);
            for (int n = 0; n < lines.Length; n++)
            {
                string line = lines[n];
                if (line == TEXT_PREINSTALLED_CHECK_URL_FUNCTION && n < lines.Length - 1 &&
                    lines[n + 1].StartsWith(TEXT_PREINSTALLED_CHECK_URL_NEXTLINE))
                {
                    lines[n + 1] = TEXT_PREINSTALLED_CHECK_URL_NEXTLINE + (settings.SpeedDial.DisableBuiltInThumbnails ? "return null;" : "");
                }
                else if (settings.SpeedDial.AddCustomThumbnails && line == TEXT_PREINSTALLED_LAST_LINE)
                {
                    StringBuilder sb = new StringBuilder("var _transformData = { re: null, getRe: function(dict) { return new RegExp(\"^.{4,5}:\\\\/\\\\/(?:[^.]+\\\\.)?(\" + _arr_to_regexp(Object.keys(dict)) + \")(?:\\\\/|$)\"); }, thumbnails: { ");
                    bool          f  = false;

                    foreach (KeyValuePair <string, string> kvp in settings.SpeedDial.CustomThumbnails)
                    {
                        if (f)
                        {
                            sb.Append(',');
                        }
                        sb.AppendFormat("\"{0}\": \"{1}\"", kvp.Key, kvp.Value);
                        f = true;
                    }

                    sb.Append("} }; this.transformURL = function(URL) { if (!_transformData.re) _transformData.re = _transformData.getRe(_transformData.thumbnails); var match = _transformData.re.exec(URL); return match ? _transformData.thumbnails[match[1]] : null; };");
                    lines[n] = sb.ToString() + TEXT_PREINSTALLED_LAST_LINE;
                }
            }
            pakFile.SetItem(PreinstalledSpeeddialsJs, lines);

            ColoredConsole.WriteLine("Writing ~W{0}~N ...", pakFileName);

            pakFile.Save(pakFileName + ".temp");
            File.Delete(pakFileName);
            File.Move(pakFileName + ".temp", pakFileName);

            string contentFileName         = Path.Combine(Path.GetDirectoryName(pakFileName), "resources\\default_partner_content.json");
            string originalContentFileName = contentFileName + BackupExtension;

            if (!File.Exists(originalContentFileName) && File.Exists(contentFileName))
            {
                File.Copy(contentFileName, originalContentFileName);
            }
            else if (File.Exists(originalContentFileName))
            {
                File.Copy(originalContentFileName, contentFileName, true);
            }

            if (settings.Search.DeletePartnerSearchEngines)
            {
                File.Delete(contentFileName);
            }

            if (settings.PatchOperaExe)
            {
                string exeFileName         = Path.ChangeExtension(pakFileName, ".exe");
                string originalExeFileName = exeFileName + OperaPatch.BackupExtension;

                ColoredConsole.WriteLine("Reading ~W{0}~N ...", exeFileName);
                if (!File.Exists(originalExeFileName))
                {
                    File.Copy(exeFileName, originalExeFileName);
                }
                else
                {
                    File.Copy(originalExeFileName, exeFileName, true);
                }

                byte[] exeFile  = File.ReadAllBytes(exeFileName);
                byte[] patched  = OperaPatches.GetPakFileHash(pakFileName);
                byte[] original = OperaPatches.GetPakFileHash(originalPakFileName);
                if (exeFile.Length < OperaPakHashOffset + patched.Length)
                {
                    throw new InvalidOperationException("Invalid executable patch: offset error.");
                }

                for (int n = 0; n < original.Length; n++)
                {
                    if (exeFile[OperaPakHashOffset + n] != original[n])
                    {
                        throw new InvalidOperationException("Invalid executable patch: original data do not match.");
                    }

                    exeFile[OperaPakHashOffset + n] = patched[n];
                }

                if (settings.Search.DeletePartnerSearchEngines)
                {
                    byte[] search = Encoding.ASCII.GetBytes(SearchSettings.BuiltinUrl);
                    for (int offset = 0; offset < exeFile.Length - search.Length - 1; offset++)
                    {
                        bool found = true;
                        for (int n = 0; found && n < search.Length; n++)
                        {
                            found = exeFile[offset + n] == search[n];
                        }

                        if (found && exeFile[offset + search.Length] == 0)
                        {
                            byte[] builtin  = BuildSearchSettings(SearchSettings.BuiltinUrl, SearchSettings.BuiltinName, SearchSettings.BuiltinKeyword, SearchSettings.BuiltinFavicon, SearchSettings.BuiltinSuggestionUrl);
                            byte[] default1 = BuildSearchSettings(settings.Search.DefaultUrl, settings.Search.DefaultName, settings.Search.DefaultKeyword, settings.Search.DefaultFavicon, settings.Search.DefaultSuggestionUrl);
                            for (int n = 0; found && n < builtin.Length; n++)
                            {
                                found = exeFile[offset + n] == builtin[n];
                            }

                            if (found)
                            {
                                Array.Copy(default1, 0, exeFile, offset, default1.Length);
                            }
                            else
                            {
                                ColoredConsole.WriteLine("~y~KWarning:~k~Y built-in search engine structure has been changed. You must update SpeedDialPatch.~N");
                            }
                        }
                    }
                }

                ColoredConsole.WriteLine("Writing ~W{0}~N ...", exeFileName);
                File.WriteAllBytes(exeFileName + ".temp", exeFile);
                File.Delete(exeFileName);
                File.Move(exeFileName + ".temp", exeFileName);
            }
        }