Greasy Fork is available in English.

CurseForge汉化文本修正

修改CurseForge的汉化文本

// ==UserScript==
// @name         CurseForge汉化文本修正
// @namespace    https://www.yesterday17.cn/
// @version      1.0.1
// @description  修改CurseForge的汉化文本
// @author       Yesterday17
// @include      *://minecraft.curseforge.com/*
// @run-at       document-start
// ==/UserScript==

"use strict";

(function() {
  const translation = {
    Elerium: {
      ControlPanel: {
        AreYouSureYouWantToDeleteName: "你确定要删除{0}吗?"
      },
      Developer: {
        AreYouSureRemoveRole:
          "Are you sure you would like to delete {0} from the company?"
      },
      Extension: {
        DeveloperWritableChannelSegmentVersion:
          "Developer Writable Channel Segment Version",
        DeveloperWritableChannelSegmentVersionDesc:
          "If present - the extension will be inactive unless the version string in the channel\u0027s developer segment matches this value",
        MobileConfirmDisableHeader:
          "Are you sure you want to disable mobile support?",
        MobileConfirmDisableMessage:
          "When this version is released users will no longer be able access your extension from mobile.",
        RequestIdentityLinkRequired: "Add Tooltip Copy",
        RequestIdentityLinkRequiredWithPurchases:
          "Request Identity Link required with In-Extension Purchases",
        RequiredPerChannelConfigurations: "Required Per Channel Configuration",
        RequiredPerChannelConfigurationsDesc:
          'If present - this must match the per channel configuration string, for activation to proceed. See the \u003ca href="https://dev.twitch.tv/docs/extensions/reference/#set-extension-required-configuration" target="_blank"\u003eSet Extension Required Configuration\u003c/a\u003e Endpoint.'
      },
      Global: { Favorite: "收藏", Unfavorite: "取消收藏" }
    },
    Global: {
      Buttons: {
        Cancel: "取消",
        Create: "创建",
        Delete: "删除",
        Edit: "编辑",
        Push: "Push",
        Update: "更新"
      },
      Calendar: { Month: "本月", Today: "今天", Week: "周" },
      Common: {
        Add: "添加",
        AddCharacter: "添加一个字符",
        AdvancedSearch: "高级搜索",
        Apply: "应用",
        Ascending: "递增",
        ClickHere: "点击这里",
        ColonConnector: ":",
        Comments: "评论",
        Confirm: "确认",
        ConfirmDelete: "您确定要删除{0}吗?",
        Descending: "降序",
        Description: "描述",
        EditMyAccount: "编辑我的帐户",
        EmailErrorMessage: "必须是一个电子邮件地址。",
        EqualErrorMessage: "{0}必须与{1}相等",
        ErrorOccured: "抱歉,处理请求时发生错误。",
        FileContainsVirus: "文件已被病毒感染",
        IntegerValueErrorMessageMaximum: "必须在{0}以下。",
        IntegerValueErrorMessageMinimum: "必须在{0}以上。",
        LengthErrorMessageMaximum:
          "长度最大为{0}。",
        LengthErrorMessageMinimum:
          "长度最小为{0}。",
        Logout: "注销",
        Milliseconds: "{0}毫秒",
        More: "更多",
        MyCharacters: "我的角色",
        Name: "名字",
        New: "New",
        Normal: "正常",
        NumberOfPrivateMessagesAbbr: "{0}条私信",
        PageOf: "第{0}页,共{1}页",
        PageXOfY: "第{0}页,共{1}页",
        PleaseLogIn: "请登录",
        PleaseWaitProcessing: "请稍候,正在处理中…",
        PrivateMessagesAbbr: "PMs",
        QuoteFrom: "引用{0}",
        Remove: "删除",
        RequiredErrorMessage: "此字段是必需的。",
        RestoreContent: "还原内容",
        SelectCharacter: "选择一个字符",
        SimpleSearch: "简单搜索",
        Submit: "提交",
        TestStuff: "这只是一个测试。{0}只鸟。",
        Title: "标题",
        UserAsCharacter: "{0} as",
        UserAvatar: "{0}的头像",
        Username: "用户名",
        WelcomeUser: "欢迎您,{0}!"
      },
      ContentManagement: {
        AddMediaGallery: "添加媒体库",
        ExistingFolders: "现有目录",
        HideAddGallery: "不要添加媒体库",
        Insert: "插入",
        InsertAnImage: "插入图片",
        OnSelectedTemplate: "应用以选择({0})",
        PageFormDoNotSetDate: "不设置日期",
        PageFormSetDate: "设置日期",
        PublishOnTemplate: "发布{0}",
        SelectImage: "选择一张图片"
      },
      Contests: {
        ContestPrizeItemAwardSubject: "你得到了奖励:{0}",
        ContestPrizeItemHtmlBody:
          '你得到了奖励:{1}.\r\n\r\n\u003ca href="{2}" target=_blank\u003e{0}\u003c/a\u003e',
        ContestPrizeItemTextBody:
          "你得到了奖励:{0}.\r\n\r\n访问{1}以领取奖励。",
        YouAreDisqualified: "你已被取消资格!"
      },
      ControlPanel: {
        AddNewHeader: "添加新标题",
        AddSubNavigationLink:
          '\u003cdiv class="header"\u003e新增分导航\u003c/div\u003e添加一个分导航链接',
        BulkConfirm: "你确定要{0}这些项目吗?",
        CompLegacySubscription: "Issue Comp",
        "Contactology Campaigns": "Contactology Campaigns",
        EntitySubscriptionTypes: "Entity Subscription Types",
        LegacySubscriptions: "Legacy Subscriptions",
        LegacySubscriptionSearch: "Search Legacy Subscriptions",
        MenuLegacySubscriptions: "Legacy Subscriptions",
        MinimumPostCount: "Minimum Post Count",
        MovePrivateMessagesPrompt:
          '您确定要将这些私信移动到"${0}"目录内?',
        PushNotification: "推送通知",
        RemoveLinkTooltip:
          '\u003cdiv class="header"\u003e删除链接\u003c/div\u003e删除这从你的网站导航链接。',
        SubscriptionID: "Subscription ID",
        SubscriptionTypeEdit: "Subscription Type Edit",
        SubscriptionTypePush: "Push Subscription Type Notification",
        SubscriptionTypes: "Subscription Types",
        SimpleSearch: "Simple Search"
      },
      Dates: {
        AprilAbbr: "4月",
        AugustAbbr: "8月",
        Days: "{0}天",
        DecemberAbbr: "12月",
        FebruaryAbbr: "2月",
        FridayAbbr: "周五",
        FutureFormat: "{0} from now",
        Hours: "{0}小时",
        JanuaryAbbr: "1月",
        JulyAbbr: "7月",
        JuneAbbr: "6月",
        LessThanOneMinute: "不到一分钟",
        MarchAbbr: "3月",
        MayAbbr: "5月",
        Minutes: "{0}分钟",
        MondayAbbr: "周一",
        NovemberAbbr: "11月",
        OctoberAbbr: "10月",
        OneMinute: "1分钟",
        PastFormat: "{0}前",
        SaturdayAbbr: "周六",
        Seconds: "{0}秒",
        SeptemberAbbr: "9月",
        StandardDateFormat: "{2}年{1}{0}日",
        StandardDateTimeFormat: "{1},{0} {4} {6} {2}:{3}:{5}",
        SundayAbbr: "周日",
        ThursdayAbbr: "周四",
        TuesdayAbbr: "周二",
        WednesdayAbbr: "周三"
      },
      ErrorMessages: {
        NumericPrecisionDecimalDigitCountErrorMessageTemplate:
          "您提供的数值有{0}位小数,而限制为{1}位。",
        TagEmpty: "您不能添加一个空的标签。"
      },
      Files: {
        AddAttachment: "添加此附件",
        ChangeDescription: "更改此附件的说明",
        DeleteAttachment: "删除此附件",
        FileTooLarge: "文件太大,请上传小于{0}的文件。"
      },
      Forums: {
        Add: "添加",
        CreateForum: "创建论坛",
        Delete: "删除",
        EditForum: "编辑论坛",
        GoToFirstUnreadPost: "转到第一个未读的帖子",
        JumpToPage: "跳到页",
        LockThread: "锁定主题",
        Moderator: "主持人",
        Move: "移动",
        OnSelected: "在选择({0})",
        RestoreContentDescription:
          "如果上次输入出错,请单击以恢复上次输入的文本",
        SearchForums: "搜索论坛",
        SelectAll: "全选",
        SendMessage: "发送消息",
        Unread: "未读",
        ViewPosts: "查看帖子",
        ViewProfile: "查看用户信息"
      },
      Languages: {
        Arabic: "阿拉伯语",
        "Brazillian Portugese": "巴西葡萄牙语",
        BritishEnglish: "英语(英国)",
        English: "英语",
        French: "法语",
        German: "德语",
        Greek: "希腊语",
        Indonesian: "印度尼西亚语",
        Italian: "意大利语",
        Japanese: "日语",
        Korean: "汉语",
        LatinAmericanSpanish: "拉丁美洲西班牙语",
        Polish: "波兰语",
        Russian: "俄语",
        SimplifiedChinese: "简体中文",
        Spanish: "西班牙语",
        Swedish: "瑞典语",
        TraditionalChinese: "繁体中文",
        Uzbec: "乌兹别克语",
        Vietnamese: "越南语"
      },
      MailTemplates: {
        ReportBody:
          'Hello {0},\r\n\r\n\u003cp\u003e{6} has reported this \u003ca href="{4}"\u003econtent\u003c/a\u003e on \u003ca href="{7}"\u003e{8}\u003c/a\u003e for the reason {2}.\u003c/p\u003e\r\n\u003cp\u003e{9}\u003c/p\u003e\r\n\u003cp\u003eYou can view the report by \u003ca href="{7}"\u003evisiting the report page\u003c/a\u003e.\u003c/p\u003e\r\n\r\n\u003cp\u003eReported content:\r\n\u003cblockquote\u003e\r\nPosted by \u003ca href="{5}"\u003e{10}\u003c/a\u003e\r\n\u003cp\u003e\r\n{3}\r\n\u003c/p\u003e\r\n\u003c/blockquote\u003e\u003c/p\u003e\r\n\r\n__\r\n\u003cp style="font-size:11px"\u003eTo unsubscribe from these email notifications, go to \u003ca href="{1}"\u003eyour notifications page.\u003c/a\u003e\u003c/p\u003e'
      },
      Polls: {
        AddChoice: "添加选择",
        AddPoll: "添加一项民意调查",
        ChoiceNumberTemplate: "选择#{0}",
        HideResults: "隐藏结果",
        RemoveChoice: "删除选择",
        RemovePoll: "不要添加的民意调查",
        ViewResults: "查看结果"
      },
      Ratings: {
        YouRatedThis:
          "您的打分是{0}星。{2}名用户的平均打分是{1}星。"
      },
      Reporting: { Report: "报告" },
      TinyMCE: { XenonMediaPluginDesc: "从目录中添加文件" },
      Translator: {
        ReportATranslation: "Report a Translation",
        ReportTranslationInstructions:
          "要报告翻译,请单击带有虚线下划线的文本。"
      },
      Upsells: {
        SubscriptionRequiresLogin: "您必须登录才能订阅。"
      },
      UserRegistration: {
        ConfirmPassword: "确认密码",
        Password: "密码",
        RecoverAccountStep2Info2:
          "输入一个新的帐户密码,然后点击\u0027更改密码\u0027按钮。",
        Username: "用户名",
        UsernameIsTaken: "该用户名已被注册。"
      },
      Widgets: {
        LatestPosts: "最新帖子",
        LatestNews: "最新新闻",
        Poll: "调查",
        WhosOnline: "在线用户",
        RandomPicture: "随机图片",
        Calendar: "日历",
        Recruitment: "招聘"
      }
    }
  };

  /**
   * Add localization script
   */
  const script = document.createElement("script");
  script.innerHTML = `Elerium.Localization.populate(7, ${JSON.stringify(
    translation
  )});`;

  /**
   * 匹配规则
   */
  const category = /^\/modpacks|customization|mc-addons|mc-mods|texture-packs|worlds(?:\/[a-zA-Z0-9\-]+)*$/;
  const project = /^\/projects\/[a-zA-Z0-9\-]+$/;
  const files = /^\/projects\/[a-zA-Z0-9\-]+\/files$/;
  const dependencies = /^\/projects\/[a-zA-Z0-9\-]+\/relations\/dependencies$/;
  const dependents = /^\/projects\/[a-zA-Z0-9\-]+\/relations\/dependents$/;

  const dictionary = {
    projects: "项目",
    forum: "论坛",
    "reward-store": "Reward Store",
    dashboard: "Dashboard",
    feedback: "反馈",

    modpack: "整合包",
    customization: "Customization",
    addons: "Addons",
    mods: "模组",
    "texture-packs": "材质包",
    worlds: "世界",

    search: "搜索",
    "new-project": "新建项目",
    popularity: "热度",
    "date-created": "创建时间",
    "last-updated": "最近更新",
    name: "名称",
    "total-downloads": "总下载量",
    relations: "依赖关系"
  };

  document.addEventListener("DOMContentLoaded", function(event) {
    const path = new URL(document.URL).pathname;
    const root = `/${path.split("/")[1]}/${path.split("/")[2]}`;

    // 加载修改过的汉化
    document.head.appendChild(script);

    // 修改全局共通的文本
    document.querySelector("#nav-projects a span").innerText =
      dictionary.projects;
    document.querySelector("#nav-forums a span").innerText = dictionary.forum;
    document.querySelector("#nav-reward-store a span").innerText =
      dictionary["reward-store"];
    document.querySelector("#nav-dashboard a span").innerText =
      dictionary.dashboard;
    document.querySelector("#nav-feedback a span").innerText =
      dictionary.feedback;

    document.querySelectorAll("#nav-projects li a span")[0].innerText =
      dictionary.modpack;
    document.querySelectorAll("#nav-projects li a span")[1].innerText =
      dictionary.customization;
    document.querySelectorAll("#nav-projects li a span")[2].innerText =
      dictionary.addons;
    document.querySelectorAll("#nav-projects li a span")[3].innerText =
      dictionary.mods;
    document.querySelectorAll("#nav-projects li a span")[4].innerText =
      dictionary["texture-packs"];
    document.querySelectorAll("#nav-projects li a span")[5].innerText =
      dictionary.worlds;

    // 搜索框的 placeholder
    document.querySelector(".b-search-input").placeholder =
      dictionary.search + "…";

    if (path == "/") {
    } else if (path == "/projects") {
      // <h2>
      document.querySelectorAll(".category-info h2")[0].innerText =
        dictionary.modpack;
      document.querySelectorAll(".category-info h2")[1].innerText =
        dictionary.customization;
      document.querySelectorAll(".category-info h2")[2].innerText =
        dictionary.addons;
      document.querySelectorAll(".category-info h2")[3].innerText =
        dictionary.mods;
      document.querySelectorAll(".category-info h2")[4].innerText =
        dictionary["texture-packs"];
      document.querySelectorAll(".category-info h2")[5].innerText =
        dictionary.worlds;

      // <p>, description
      const proj_from_reg = /^(\d+) projects by (\d+) authors with more than ([\d,]+) downloads.$/;
      const proj_to = "已有$2位作者创建了$1个项目,总下载次数已超过$3次。";
      for (const node of document.querySelectorAll(".category-info p")) {
        node.innerText = node.innerText.replace(proj_from_reg, proj_to);
      }

      // 按钮:启动项目 -> 新建项目
      for (const node of document.querySelectorAll(
        ".project-category .button span"
      )) {
        node.innerText = dictionary["new-project"];
      }
    } else if (path.match(category)) {
      console.log("category");
      // 新建项目
      document.querySelector(".project-listing-header li a span").innerText =
        dictionary["new-project"];

      // 排序方式
      document.querySelectorAll("#filter-sort option")[0].innerText =
        dictionary["date-created"];
      document.querySelectorAll("#filter-sort option")[1].innerText =
        dictionary["last-updated"];
      document.querySelectorAll("#filter-sort option")[2].innerText =
        dictionary.name;
      document.querySelectorAll("#filter-sort option")[3].innerText =
        dictionary.popularity;
      document.querySelectorAll("#filter-sort option")[4].innerText =
        dictionary["total-downloads"];

      // Prev -> 上一页
      for (let node of document.querySelectorAll('a[rel="prev"]')) {
        if (node.innerText == "Prev") {
          node.innerText = "上一页";
        }
      }

      // Next -> 下一页
      for (let node of document.querySelectorAll('a[rel="next"]')) {
        if (node.innerText == "Next") {
          node.innerText = "下一页";
        }
      }
    } else if (
      path.match(project) ||
      path.match(files) ||
      path.match(dependencies) ||
      path.match(dependents)
    ) {
      // 相同部分同时处理
      document.querySelector(`li a[href="${root}"]`).innerText = "简介";
      document.querySelector(`li a[href="${root}/files"]`).innerText =
        "文件";
      if (document.querySelector(`li a[href="${root}/images"]`)) {
        document.querySelector(`li a[href="${root}/images"]`).innerText =
          "图片";
      }
      document.querySelector(
        `.e-hasSubmenu>a[href="${root}/relations/dependencies"]`
      ).innerText = dictionary.relations;
      // TODO: 对每个页面不同的部分进行细分汉化
      if (path.match(project)) {
        console.log("project");
      } else if (path.match(files)) {
        console.log("files");
      } else if (path.match(dependencies)) {
        console.log("dependencies");
      } else if (path.match(dependents)) {
        console.log("dependents");
      }
    } else {
      console.log("others");
    }
  });
})();