From fbbc0b82b4a569ed85e98ca3dd1245ff0dd4381a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Fri, 31 Oct 2025 08:06:11 -0500 Subject: [PATCH 01/17] Update Lighting.tsx --- .../HeroSection/components/TankSandbox/components/Lighting.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/Lighting.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/Lighting.tsx index cc2ddffcd..659c07b4d 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/Lighting.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/Lighting.tsx @@ -65,8 +65,6 @@ export function Lighting() { ] as const; const color = new Color(); - if (isHalloween()) color.set(1, 0, 0); - return ( Date: Fri, 31 Oct 2025 15:07:27 -0500 Subject: [PATCH 02/17] Update isHalloween.ts --- packages/website/src/core/blitzkit/isHalloween.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/website/src/core/blitzkit/isHalloween.ts b/packages/website/src/core/blitzkit/isHalloween.ts index c05deb5f5..d08592f25 100644 --- a/packages/website/src/core/blitzkit/isHalloween.ts +++ b/packages/website/src/core/blitzkit/isHalloween.ts @@ -1,4 +1,5 @@ export function isHalloween() { const data = new Date(); + return false; return data.getMonth() === 9 && data.getDate() === 31; } From 541dfc186b82c4462160ef58f0e918bad6d355a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Mon, 3 Nov 2025 15:45:21 +0000 Subject: [PATCH 03/17] New Crowdin updates (#179) * New translations en.json (Chinese Simplified) * New translations en.json (Chinese Simplified) * New translations en.json (Chinese Simplified) * New translations en.json (Chinese Simplified) --- packages/i18n/strings/zh.json | 300 +++++++++++++++++----------------- 1 file changed, 150 insertions(+), 150 deletions(-) diff --git a/packages/i18n/strings/zh.json b/packages/i18n/strings/zh.json index 3d9c0b04b..38f3debc2 100644 --- a/packages/i18n/strings/zh.json +++ b/packages/i18n/strings/zh.json @@ -1,23 +1,23 @@ { "test": { "default": "测试", - "long": "This is a long test string. You MUST NEVER see this in the UI. My favorite fruit is {fruit} because it has the color of {color}. I like it so much that I will say its name 3 times! {fruit}! {fruit}! {fruit}! Once again, it's {color}, not {not_color}.", + "long": "这是一个测试用长字符串。你绝对不会在用户界面中看见这些。我最喜欢的水果是{fruit}因为它的颜色是{color}的。我如此喜欢它,以至于我会把它的名字念3次!{fruit}!{fruit}!{fruit}!重申一次,它是{color}的而不是{not_color}的。", "fox": "褐色的狐狸迅速地跳过那只懒狗" }, "common": { "name": "BlitzKit", "units": { - "m": "{value}m", - "mm": "{value}mm", - "deg": "{value}°", - "hp": "{value}hp", + "m": "{value} 公尺", + "mm": "{value} 毫米", + "deg": "{value} 度°", + "hp": "{value} 生命值", "x": "x{value}", "percentage": "{value}%", - "deg_s": "{value}°/s" + "deg_s": "{value}度°/秒" }, "gun_types": { - "auto_loader": "弹夹型战车", - "auto_reloader": "自动装填型战车", + "auto_loader": "弹夹型坦克", + "auto_reloader": "自动装填型坦克", "regular": "单发" }, "shells": { @@ -101,8 +101,8 @@ }, "tank_class_short": { "-1": "未识别", - "0": "轻型战车", - "1": "中型战车", + "0": "轻型坦克", + "1": "中型坦克", "2": "重型战车", "3": "驱逐战车" }, @@ -186,11 +186,11 @@ "bot": { "common": { "errors": { - "clan_not_found": "# 找不到军团\n找不到 \"{search}\". 请尝试选从搜索结果中择一个军团。", - "player_not_found": "# Could not find user\nI couldn't find user \"{search}\". Try picking an user from the search result, typing in a valid username, or using the `/link` command.", + "clan_not_found": "# 找不到公会\n找不到\"{search}\"。请尝试从搜索结果中选择一个公会。", + "player_not_found": "# 找不到玩家\n无法找到玩家 “{search}”。 尝试从搜索结果中选择玩家,或输入一个有效的玩家名称, 或使用“/link”命令。", "player_not_linked": "# 使用 `/link` 来开始\n我不知道你是谁,但你今天可以告诉我!", - "tank_name_not_found": "# 找不到坦克\n找不到名称为 \"{search}\"的坦克。", - "tank_id_not_found": "# 找不到坦克\n找不到ID为 \"{search}\"的坦克. 尝试输入坦克的名称。", + "tank_name_not_found": "# 找不到坦克\n找不到名为 “{search}” 的坦克。", + "tank_id_not_found": "# 找不到坦克\n无法找到ID为 “{search}” 的坦克。 请尝试输入坦克的名称而不是数字。", "no_tank_stats": "# 没有这辆战车的数据\n这个玩家没有可用资料。 这可能不是你要找的玩家。", "get_help": "Discord的协助服务器", "uncaught_error": "# BlitzKit 发生错误!\n我们对此感到抱歉。 欢迎加入[官方Discord](https://discord.gg/nDt7AjGJQH),以方便帮助你解决问题。", @@ -284,19 +284,19 @@ "name": "阶级", "description": "阶级", "choices": { - "tier": "坦克等级 {tier_1} - {tier_2}" + "tier": "{tier_1} - {tier_2} 阶" } } }, "periods": { "career": "玩家资料", "today": "今日:", - "days": "{days} days", - "custom": "{day_1} - {day_2} days" + "days": "{days} 天", + "custom": "{day_1} - {day_2} 天" }, "filters": { "none": "无筛选器", - "tier": "坦克等级 {tier}" + "tier": "{tier} 阶" }, "no_data": { "battles_in_period": "在这段时间里没有参与任何战斗", @@ -339,19 +339,19 @@ "body": { "subtitle": "研发", "total": "全部", - "research": "Research: {cost}", - "upgrades": "Upgrades: {cost}", - "purchase": "Purchase: {cost}", - "equipment": "Equipment: {cost}", + "research": "研发:{cost}", + "upgrades": "升级:{cost}", + "purchase": "购买:{cost}", + "equipment": "装备:{cost}", "estimation": "# 这是一个估计值!\n\n这个列表可能包含已经研发过的战车,因为 Wargaming 提供了不正确的资料。 如果可以,请尝试在同一研发线路中提供一个 “起始战车” 。" }, "errors": { - "non_tech_tree": "# {tank} is not on the tech tree\n\nYou cannot research a premium/collector tank.", + "non_tech_tree": "# \"{tank}\" 不在科技树里\n\n你不能研发一个 加值/收藏家 坦克。", "tier_1": "# {tank} 是一级坦克\n\n一级坦克一直是对所有玩家免费解锁的。", - "already_researched": "# {tank} is already researched\n\nTry providing a `starting-tank` when using the command to view the totals for a line you have already researched.", - "start_end_equal": "# {tank} was provided twice\n\nMake sure `starting-tank` and `target-tank` are different.", - "tanks_not_on_line": "# {tank_1} and {tank_2} are not on the same line\n\nMake sure `starting-tank` and `target-tank` are on the same tech-tree line.", - "unordered": "# {tank_1} higher tiered to {tank_2}\n\nMake sure to provide {tank_2} as the `starting-tank` instead as it is the lower tiered tank." + "already_researched": "# \"{tank}\" 已完成研发\n\n请尝试在同一研发线路上提供“起始坦克”, 以查看全部您已研发过的坦克。", + "start_end_equal": "# \"{tank}\" 重复提供了\n\n请确认 \"初始坦克\" 和 \"目标坦克\" 是不同的。", + "tanks_not_on_line": "# “{tank_1}” 和 “{tank_2}” 不在同一个研发线路上\n\n请确认“起始坦克” 和 “目标坦克” 在同一研发线路中。", + "unordered": "# “{tank_1}” 阶级比 “{tank_2}” 高\n\n请以提供 {tank_2} 作为起始坦克,因为它的阶级更低。" } }, "about": { @@ -394,7 +394,7 @@ "wn8": "WN8", "winrate": "胜率", "damage": "伤害", - "unknown_tank": "未知坦克{id}" + "unknown_tank": "未知坦克 {id}" } }, "debug": { @@ -430,12 +430,12 @@ "options": { "threshold": { "name": "阈值", - "description": "The number of days inactive (default: {days} days)" + "description": "未上线天数( 默认:{days} 天)" } }, "body": { - "subtitle": "Inactive for {days}+ days", - "listing": "{days} days" + "subtitle": "{days}+ 天未上线", + "listing": "{days} 天" } }, "full_stats": { @@ -478,7 +478,7 @@ "body": { "accounts_linked": "帐号已绑定", "no_role_permissions": { - "title": "{name} failed to verify", + "title": "{name} 验证失败", "description": "我没有管理身份的权限。" } }, @@ -493,11 +493,11 @@ "options": { "limit": { "name": "限制", - "description": "The max number of clan results (default: {limit})" + "description": "公会结果的最大显示数量 (默认:{limit})" } }, "body": { - "title": "Clan search for {search} in region {region}", + "title": "在地区 {region} 中搜索公会 {search}", "no_results": "没有找到该公会" } }, @@ -507,11 +507,11 @@ "options": { "limit": { "name": "限制", - "description": "The max number of player results (default: {limit})" + "description": "玩家结果的最大显示数量 (默认:{limit})" } }, "body": { - "title": "Player search for {search} in region {region}", + "title": "在地区 {region} 中搜索玩家 {search}", "no_results": "未找到玩家" } }, @@ -531,13 +531,13 @@ "options": { "limit": { "name": "限制", - "description": "How many neighbors to display (default: {count})" + "description": "显示附近有多少玩家(默认:{count})" }, "season": { "name": "赛季", "description": "赛季数 (默认:当前)", "choices": { - "current": "{season} (current)" + "current": "{season} (当前)" } }, "league": { @@ -546,12 +546,12 @@ } }, "body": { - "top_players": "Top {count} players", - "no_participation": "# {player} didn't play rating in season {season}\n\nThis player did not participate in this season or did not get past calibration.", + "top_players": "前 {count} 玩家", + "no_participation": "# {player} 没有在赛季 {season} 中进行过评价战斗\n\n该玩家没有参加该赛季或没有完成校准。", "no_ongoing_season": "# 没有进行中的赛季\n\n目前没有赛季。", - "deleted_player": "删除{id}", + "deleted_player": "已删除玩家 {id}", "neighbors": "对邻居进行评分", - "more": "+ {count} more" + "more": "+ {count} 更多" } }, "today": { @@ -566,7 +566,7 @@ "name": "已拥有的战车", "description": "显示该阶级中所有您已拥有的战车", "body": { - "title": "# {name}'s owned tier {tier} tanks\n\n" + "title": "# {name} 所拥有的 {tier} 阶坦克\n\n" } }, "permissions": { @@ -585,7 +585,7 @@ "description": "检查机器人是否处于活动状态。", "body": { "pong": "Pong 🏓", - "pong_with_time": "Pong 🏓 - {time}ms" + "pong_with_time": "Pong 🏓 - {time} 微秒" }, "subcommands": { "blitzkit": { @@ -602,7 +602,7 @@ "name": "玩家信息", "description": "玩家基本信息", "body": { - "title": "{name}的信息", + "title": "{name} 的信息", "nickname": "昵称", "battles": "战斗场次", "winrate": "胜率", @@ -631,7 +631,7 @@ } }, "errors": { - "no_participation": "# {name}还没有玩过评级模式。", + "no_participation": "# {name} 未曾游玩评价战斗\n\n该玩家未参与本赛季的评价战斗。", "unrecorded_stats": "# 统计数据目前无法使用\n\nWargaming 可能暂停了服务器。 如果有连续的赛季,统计数据可能在24小时内提供。" } } @@ -644,7 +644,7 @@ }, "settings": { "title": "设置", - "description": "调整BlitzKit设置", + "description": "更改 BlitzKit 设置", "dev_mode": "开发者模式", "language": "语言" }, @@ -661,13 +661,13 @@ "select_dialog_title": "搜索坦克", "swap_dialog_title": "交换坦克", "clear_filters": "清除筛选", - "login": "Login to use this", + "login": "登录以使用它", "search_bar_hint": "搜寻战车……", "recent": "最近查看的", "select_all": "全选", "count_singular": "1辆战车", - "count_plural": "{count} tanks", - "sorting_by": "Sorting by {name}", + "count_plural": "{count} 辆坦克", + "sorting_by": "按 {name} 排序", "no_tanks_found": { "body": "找不到战车。", "search_again": "请尝试重新搜索。", @@ -688,7 +688,7 @@ "fire.caliber": "口径", "fire.standardPenetration": "标准炮弹穿透力", "fire.premiumPenetration": "加值炮弹穿透力", - "fire.tertiaryPenetration": "tertiary penetration", + "fire.tertiaryPenetration": "第三种炮弹穿透力", "fire.damage": "炮弹伤害值", "fire.moduleDamage": "模组伤害值", "fire.shellVelocity": "炮弹飞行速度", @@ -730,12 +730,12 @@ }, "home": { "pwa": { - "title": "安装Blitz Kit App", - "new": "NEW", + "title": "安装 BlitzKit 应用程序", + "new": "新增", "checking": "正在检查兼容性……", - "instructions": "Instructions for Apple devices.", + "instructions": "Apple 设备的说明。", "install": "安装", - "dismiss": "忽略" + "dismiss": "取消" }, "discord": { "join_short": "加入超級酷的人群!", @@ -743,16 +743,16 @@ "action": "Discord" }, "hero": { - "credit": "By {name} ❤️" + "credit": "由 {name} 制作 ❤️" }, "hot_tanks": { "title": "受欢迎的坦克", - "subtitle": "Last {days} days" + "subtitle": "过去 {days} 天" }, "other_projects": { "title": "其他酷炫的项目" }, - "help_translate": "Please help translate {name} to {language}!", + "help_translate": "请帮忙将 {name} 翻译成 {language}!", "seo_description": "战车世界闪击战 全方位工具" }, "docs": { @@ -764,49 +764,49 @@ "tools": { "playlist": { "reset": "重置", - "shuffle": "Shuffle", - "remove": "Remove played", - "tracking": "BlitzKit is tracking your battles", + "shuffle": "换一批", + "remove": "移除已游玩的", + "tracking": "BlitzKit 正在追踪您的战斗记录", "sort": { "button": "排序依据", - "last_played": "Last played", - "least_played": "Least played" + "last_played": "最后一次游玩", + "least_played": "最少游玩的" }, "table": { "index": "#", - "never": "Never", - "tank": "战车", - "last_played": "Last played", - "battles": "Career battles", + "never": "从不", + "tank": "坦克", + "last_played": "最后一次游玩", + "battles": "生涯战斗数", "unrecorded": "--", "wins": "胜利" }, "large_warning": { - "title": "That's a lot of tanks!", - "description": "Are you sure you want to create a playlist of {count} tanks? That's {time} hours of gameplay at 50% winrate!", + "title": "坦克数量太多了!", + "description": "您确定要创建包含 {count} 个坦克的游玩列表吗?以50%胜率计算,这需要 {time} 小时的游玩时间!", "cancel": "取消", - "proceed": "Proceed" + "proceed": "继续操作" }, - "generate": "Generate playlist", - "name": "Playlist", - "description": "Tank playlist generator", - "seo_description": "Don't know what to play in World of Tanks Blitz? Use BlitzKit Playlist to get suggestions!", - "button": "Generate", - "pool_size": "{count} possible tanks" + "generate": "创建游玩列表", + "name": "遊玩列表", + "description": "坦克游玩列表生成器", + "seo_description": "想不到在坦克世界闪击战玩什么? 使用BlitzKit 游玩列表来获得建议!", + "button": "生成", + "pool_size": "{count} 辆可生成的坦克" }, "mixer": { - "name": "Mixer", - "button": "Mix and match", - "description": "Mix tank modules", - "seo_description": "Mix and match hulls, turrets, and guns of tanks in World of Tanks Blitz", - "screenshot": "Screenshot", - "randomize": "Randomize" + "name": "组装", + "button": "混合搭配", + "description": "混合坦克模块", + "seo_description": "《坦克世界:闪击战》的车体, 炮塔, 主炮混合搭配", + "screenshot": "屏幕截图", + "randomize": "随机搭配" }, "guess": { "name": "猜坦克", "button": "猜猜看", - "description": "战车剪影小游戏", - "seo_description": "看剪影猜战车", + "description": "坦克剪影小游戏", + "seo_description": "看剪影猜坦克", "search": { "placeholder": "输入你的猜想……", "skip": "跳过", @@ -814,22 +814,22 @@ "next": "下一个", "no_results": "沒有結果" }, - "stats": "{correct} / {total} guessed correctly" + "stats": "猜对了 {correct} / {total}" }, "tankopedia": { "search": "搜索属性……", "name": "战车百科", "button": "搜索战车", - "description": "闪击战战车百科全书", - "seo_description": "战车世界闪击战的所有坦克参数, 装甲, 等等...", - "tank_seo_title": "{name} - Tier {tier} {nationality} {class} | {website} Tankopedia | World of Tanks Blitz (WoTB)", - "tank_seo_description": "{name} armor, statistics, equipment, provisions, and more. {dpm} DPM, {alpha}hp alpha, {penetration}mm penetration, {speed}kph top speed, {health}hp health.", + "description": "闪击战坦克百科全书", + "seo_description": "《坦克世界:闪击战》的所有坦克参数, 装甲, 等等...", + "tank_seo_title": "{name} - {tier} 阶 {nationality} {class} | {website} 坦克百科 | 坦克世界闪击战 (WoTB)", + "tank_seo_description": "{name} 装甲,统计资料,装备,规定配给等。 {dpm} 每分钟伤害, {alpha} 伤害值, {penetration}毫米 穿透, {speed}公里/小時 最高速度, {health} 生命值。", "visualizers": { "reload": { "skip": "跳过" }, "assault": { - "title": "Assault shells" + "title": "突击弹" }, "rotator": { "hull": "车体", @@ -852,10 +852,10 @@ "dead_rail": "死亡铁道" }, "flexibility": { - "yaw": "Yaw", - "pitch": "Pitch", - "min": "Min", - "max": "Max" + "yaw": "水平角度", + "pitch": "俯仰角度", + "min": "最少俯角", + "max": "最大仰角" } }, "sandbox": { @@ -901,15 +901,15 @@ "track": "履带" }, "status": { - "penetration": "{damage}hp penetration", + "penetration": "{damage}生命值 击穿", "blocked": "抵挡伤害", "ricochet": "跳弹", - "splash": "{damage}hp splash" + "splash": "{damage}生命值 溅射" }, "stats": { - "thickness_and_angle": "{thickness}mm {angle}°", - "nominal": "{thickness}mm nominal", - "ricochet_loss": "{loss}% penetration" + "thickness_and_angle": "{thickness}毫米 {angle}度°", + "nominal": "{thickness}毫米 装甲厚度", + "ricochet_loss": "{loss}% 击穿" } } }, @@ -929,13 +929,13 @@ "compare": "比较", "swap": { "button": "调换", - "title": "调换战车" + "title": "调换坦克" }, "vanilla": "原版", "opentest": "开放测试", "full_name": "全称", "nation": "国别", - "class": "战车车型", + "class": "坦克车型", "tier": "阶级", "type": "战车类型", "dev_id": "开发参数:ID", @@ -947,20 +947,20 @@ "tech_tree": { "title": "科技树", "battle": "一场比赛", - "battles": "{count} battles", - "route": "Route {index} of {count}" + "battles": "{count} 战斗场次", + "route": "路线 {index} / {count}" }, "game_modes": { "title": "游戏模式技能" }, "review": { "title": "回顾影片", - "join": "Apply to {name} YouTuber program" + "join": "应用到 {name} YouTuber程序" }, "configuration": { "title": "配置设定", "modules": { - "title": "战车模块", + "title": "坦克模块", "stock": "白板", "upgrade": "顶级配置" }, @@ -975,7 +975,7 @@ "consumables": { "title": "消耗品", "clear": "清除", - "info": "黄色高亮消耗品不影响战车参数。" + "info": "黄色高亮消耗品不影响坦克参数。" }, "skills": { "title": "乘员技能", @@ -991,15 +991,15 @@ "title": "属性", "compare": { "label": "比较", - "class": "Tier {tier} {class}", - "tier": "All of tier {tier}", - "all": "所有战车" + "class": "{tier}阶 {class}", + "tier": "所有 {tier} 阶", + "all": "所有坦克" }, "values": { - "shell_index": "Shell {index}", - "at_distance": "At {distance}m", + "shell_index": "炮弹 {index}", + "at_distance": "在 {distance} 公尺", "at_distance_slider_label": "距离", - "dispersion_at_distance": "Dispersion at {distance}m", + "dispersion_at_distance": "在 {distance} 公尺的扩散度", "gun_flexibility": "炮管转动界限", "speed": "速度", "terrain_coefficients": "地形系数", @@ -1015,13 +1015,13 @@ "dpmEffective": "60秒内生效", "shells": "炮弹 ", "mostOptimalShellIndex": "最优炮弹", - "shellReloads": "Reloads", + "shellReloads": "装填时间", "shellReload": "装填时间", "intraClip": "炮弹装填", "caliber": "口径", "penetration": "穿深", "damage": "伤害", - "damageWithoutAssault": "Damage without assault shells", + "damageWithoutAssault": "无突击弹的伤害", "clipDamage": "弹匣伤害期望值", "moduleDamage": "模组伤害", "explosionRadius": "溅射半径", @@ -1101,14 +1101,14 @@ }, "compare": { "name": "比较", - "button": "战车比较", - "description": "比较战车参数", - "seo_description": "比较《战车世界:闪击战》中的战车参数和装备配置", + "button": "坦克比较", + "description": "比较坦克参数", + "seo_description": "比较《坦克世界:闪击战》中的坦克参数和装备配置", "actions": { "add": { "button": "添加", - "title": "添加战车", - "description": "选择要加入比较的战车" + "title": "添加坦克", + "description": "选择要加入比较的坦克" }, "clear": "清除", "deltas": { @@ -1144,20 +1144,20 @@ }, "performance": { "name": "性能表现", - "button": "查看战车", - "description": "战车性能统计", - "seo_description": "最好的战车及其在战车世界闪击战中的表现", + "button": "查看坦克", + "description": "坦克性能统计", + "seo_description": "最好的坦克及其在《坦克世界:闪击战》中的表现", "estimation": { - "body": "Estimated stats based on {count} players. Updated {age} ago.", - "hours": "{count} hours", - "minutes": "{count} minutes" + "body": "基于 {count} 个玩家的估计数据。更新于 {age} 之前。", + "hours": "{count} 小时", + "minutes": "{count} 分钟" }, "player_count": { "label": "玩家数量" }, "table": { "tanks": { - "header": "战车", + "header": "坦克", "total": "全部" }, "stats": { @@ -1181,18 +1181,18 @@ "name": "图库", "button": "浏览全部", "description": "Blitz玩家头像", - "seo_description": "所有战车世界闪击战玩家头像", - "last_updated": "Last updated on {time}", + "seo_description": "所有《坦克世界:闪击战》玩家头像", + "last_updated": "最后更新于 {time}", "search": { "hint": "搜索頭像……", - "results": "{count} avatars" + "results": "{count} 头像" } }, "session": { "name": "场次", "button": "开始追踪", "description": "即时场次统计", - "seo_description": "在游玩 战车世界闪击战 时,实时追踪你的统计数据", + "seo_description": "在游玩《坦克世界:闪击战》时,实时追踪你的统计数据", "search": { "lookup": "查询玩家以开始使用", "hint": "搜索玩家……", @@ -1200,14 +1200,14 @@ "no_results": "找不到玩家" }, "controls": { - "title": "Tracking {name}", - "subtitle": "Since {time}", + "title": "正在追踪 {name}", + "subtitle": "起始于 {time}", "reset": "重置", "change": "变更" }, "no_cc": { "title": "你正在尝试追踪一个 CC 帐戶", - "body": "CC(社群贡献者)账戶没有公开的战车统计数据。 我们正在为CC账戶添加嵌入功能,敬请期待。", + "body": "CC(社群贡献者)账戶没有公开的坦克统计数据。 我们正在为CC账戶添加嵌入功能,敬请期待。", "alright": "好的" }, "no_battles": { @@ -1215,16 +1215,16 @@ "hint": "去玩一场游戏吧" }, "table": { - "tank": "战车", + "tank": "坦克", "total": "全部", "remove": "移除" } }, "tier_list": { "name": "阶级列表", - "button": "排名战车", - "description": "战车世界闪击战 战车等级排名", - "seo_description": "基于玩家评分和统计表现,从最佳到最差排名的《战车世界:闪击战》战车等级列表", + "button": "排名坦克", + "description": "《坦克世界:闪击战》坦克等级排名", + "seo_description": "基于玩家评分和统计表现,从最佳到最差排名的《坦克世界:闪击战》坦克等级列表", "buttons": { "reset": "重置", "share": "分享" @@ -1234,7 +1234,7 @@ "name": "嵌入", "button": "立即创建", "description": "用于串流的嵌入", - "seo_description": "创建具有极高自订化的《战车世界:闪击战》串流嵌入功能", + "seo_description": "创建具有极高自订化的《坦克世界:闪击战》串流嵌入功能", "coming_soon": "更多嵌入功能即将推出。", "suggest": "建议与想法", "preview": { @@ -1261,7 +1261,7 @@ "cancel": "取消", "success": { "title": "拷贝 URL", - "info": "Generated the URL for {name}. The embed will start tracking as soon as the URL is pasted. Reset at any time by right-clicking on PC or long-pressing on mobile and then selecting \"Reset\".", + "info": "已为 {name} 生成 URL。 当 URL 粘贴后,嵌入功能将开始追踪。 您可以随时在 PC 上点击右键或手机上长按并选择「重置」来重置。", "back": "返回", "copy": "拷贝 URL" } @@ -1285,13 +1285,13 @@ "height": "高度", "showTotal": "显示总计", "listGap": "列表间距", - "listMaxTanks": "最多战车数量", + "listMaxTanks": "最多坦克数量", "cardRadius": "卡片半径", "cardHeaderBackgroundColor": "卡片标题背景颜色", "cardHeaderPadding": "卡片标题內间距", "cardTitle": "卡片标题", - "cardTitleTypeColor": "卡片标题(战车类型)颜色", - "cardTitleClassIcon": "卡片标题(战车车型)颜色", + "cardTitleTypeColor": "卡片标题(坦克类型)颜色", + "cardTitleClassIcon": "卡片标题(坦克车型)颜色", "cardBodyBackgroundColor": "卡片內容背景颜色", "cardBodyPadding": "卡片內容內間距", "columnGap": "栏间距", @@ -1312,13 +1312,13 @@ "name": "图表", "button": "瘋狂研究", "description": "大量图标", - "seo_description": "有关战车世界闪击战 战车、玩家与事件的各种图表与图形" + "seo_description": "有关《坦克世界:闪击战》坦克、玩家与事件的各种图表与图形" }, "rating": { "name": "评价战斗", "button": "查看排行榜", "description": "完整评价战斗排行榜", - "seo_description": "《战车世界:闪击战》即时及已存档的完整评分排行榜" + "seo_description": "《坦克世界:闪击战》即时及已存档的完整评分排行榜" }, "discord": { "name": "Discord机器人", @@ -1336,7 +1336,7 @@ "name": "玩家", "button": "查询玩家", "description": "定期玩家统计", - "seo_description": "战车世界闪击战 定期玩家统计" + "seo_description": "《坦克世界:闪击战》定期玩家统计" }, "home": { "name": "主页", @@ -1345,14 +1345,14 @@ "seo_description": "开始使用 BlitzKit" }, "api": { - "name": "API", - "button": "To the docs", - "description": "BlitzKit hosted API", - "seo_description": "BlitzKit hosted static API for World of Tanks Blitz" + "name": "应用程序接口(API)", + "button": "前往文档", + "description": "BlitzKit 已托管的应用程序接口(API)", + "seo_description": "BlitzKit 托管的《坦克世界:闪击战》静态应用程序接口(API)" } }, "footer": { - "motto": "战车世界闪击战 全方位工具", + "motto": "《坦克世界:闪击战》全方位工具", "copyright": "本网站与 Wargaming战游网 或任何服务无关", "about": { "title": "关于", From e5fc2faad797cfa5a3b9ea9ceebac76821ba783e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Wed, 5 Nov 2025 14:43:21 -0600 Subject: [PATCH 04/17] Update youtubers.ts --- packages/core/src/blitzkit/youtubers.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/core/src/blitzkit/youtubers.ts b/packages/core/src/blitzkit/youtubers.ts index b9f8d46f3..bec974ebe 100644 --- a/packages/core/src/blitzkit/youtubers.ts +++ b/packages/core/src/blitzkit/youtubers.ts @@ -6,4 +6,5 @@ export const youtubers = [ { id: 'UCLMEfqtlwLDN-UXX21RiEww', name: 'WoT Blitz Best Replays' }, { id: 'UC3fZbetRUFoJL0IEN7IhG0Q', name: 'EconomicsMate' }, { id: 'UCtsUVwBlhEnUunAKLn2dtsg', name: 'Megalion69' }, + { id: 'UCJjATWiGfOHoQYfutEwAIIg', name: 'WoTB Joe' }, ]; From ec977899fb54d08e5ce5e8fc3f889920843aadef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Wed, 5 Nov 2025 20:44:13 +0000 Subject: [PATCH 05/17] New translations en.json (Russian) (#180) --- packages/i18n/strings/ru.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/i18n/strings/ru.json b/packages/i18n/strings/ru.json index a1e7e3880..fa8779880 100644 --- a/packages/i18n/strings/ru.json +++ b/packages/i18n/strings/ru.json @@ -661,7 +661,7 @@ "select_dialog_title": "Поиск танка", "swap_dialog_title": "Заменить танк", "clear_filters": "Сбросить фильтры", - "login": "Войти, чтобы воспользоваться", + "login": "Войдите, чтобы воспользоваться", "search_bar_hint": "Поиск танков...", "recent": "Недавние", "select_all": "Выбрать всё", From 1210baa545e05bab9eaffe642e5fc210d4438fa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Thu, 6 Nov 2025 09:39:27 -0600 Subject: [PATCH 06/17] fix: env type --- bun.lock | 9 +++++++-- packages/core/package.json | 1 + packages/core/src/blitzkit/asset.ts | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/bun.lock b/bun.lock index 56e6af4e9..8e8802475 100644 --- a/bun.lock +++ b/bun.lock @@ -66,6 +66,7 @@ "@octokit/rest": "^22.0.0", "@prisma/client": "^6.16.2", "@types/adm-zip": "^0.5.7", + "@types/bun": "^1.3.1", "@types/lodash-es": "^4.17.12", "@types/lz4js": "^0.2.1", "@types/three": "^0.180.0", @@ -911,7 +912,7 @@ "@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="], - "@types/bun": ["@types/bun@1.3.0", "", { "dependencies": { "bun-types": "1.3.0" } }, "sha512-+lAGCYjXjip2qY375xX/scJeVRmZ5cY0wyHYyCYxNcdEXrQ4AOe3gACgd4iQ8ksOslJtW4VNxBJ8llUwc3a6AA=="], + "@types/bun": ["@types/bun@1.3.1", "", { "dependencies": { "bun-types": "1.3.1" } }, "sha512-4jNMk2/K9YJtfqwoAa28c8wK+T7nvJFOjxI4h/7sORWcypRNxBpr+TPNaCfVWq70tLCJsqoFwcf0oI0JU/fvMQ=="], "@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="], @@ -1115,7 +1116,7 @@ "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], - "bun-types": ["bun-types@1.3.0", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-u8X0thhx+yJ0KmkxuEo9HAtdfgCBaM/aI9K90VQcQioAmkVp3SG3FkwWGibUFz3WdXAdcsqOcbU40lK7tbHdkQ=="], + "bun-types": ["bun-types@1.3.1", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-NMrcy7smratanWJ2mMXdpatalovtxVggkj11bScuWuiOoXTiKIu2eVS1/7qbyI/4yHedtsn175n4Sm4JcdHLXw=="], "c12": ["c12@3.1.0", "", { "dependencies": { "chokidar": "^4.0.3", "confbox": "^0.2.2", "defu": "^6.1.4", "dotenv": "^16.6.1", "exsolve": "^1.0.7", "giget": "^2.0.0", "jiti": "^2.4.2", "ohash": "^2.0.11", "pathe": "^2.0.3", "perfect-debounce": "^1.0.0", "pkg-types": "^2.2.0", "rc9": "^2.1.2" }, "peerDependencies": { "magicast": "^0.3.5" }, "optionalPeers": ["magicast"] }, "sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw=="], @@ -2553,6 +2554,8 @@ "@blitzkit/bot/prisma": ["prisma@6.17.1", "", { "dependencies": { "@prisma/config": "6.17.1", "@prisma/engines": "6.17.1" }, "peerDependencies": { "typescript": ">=5.1.0" }, "optionalPeers": ["typescript"], "bin": { "prisma": "build/index.js" } }, "sha512-ac6h0sM1Tg3zu8NInY+qhP/S9KhENVaw9n1BrGKQVFu05JT5yT5Qqqmb8tMRIE3ZXvVj4xcRA5yfrsy4X7Yy5g=="], + "@blitzkit/scripts/@types/bun": ["@types/bun@1.3.0", "", { "dependencies": { "bun-types": "1.3.0" } }, "sha512-+lAGCYjXjip2qY375xX/scJeVRmZ5cY0wyHYyCYxNcdEXrQ4AOe3gACgd4iQ8ksOslJtW4VNxBJ8llUwc3a6AA=="], + "@blitzkit/website/vite": ["vite@7.1.9", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-4nVGliEpxmhCL8DslSAUdxlB6+SMrhB0a1v5ijlh1xB1nEPuy1mxaHxysVucLHuWryAxLWg6a5ei+U4TLn/rFg=="], "@discordjs/rest/@discordjs/collection": ["@discordjs/collection@2.1.1", "", {}, "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg=="], @@ -2697,6 +2700,8 @@ "@blitzkit/bot/prisma/@prisma/engines": ["@prisma/engines@6.17.1", "", { "dependencies": { "@prisma/debug": "6.17.1", "@prisma/engines-version": "6.17.1-1.272a37d34178c2894197e17273bf937f25acdeac", "@prisma/fetch-engine": "6.17.1", "@prisma/get-platform": "6.17.1" } }, "sha512-D95Ik3GYZkqZ8lSR4EyFOJ/tR33FcYRP8kK61o+WMsyD10UfJwd7+YielflHfKwiGodcqKqoraWw8ElAgMDbPw=="], + "@blitzkit/scripts/@types/bun/bun-types": ["bun-types@1.3.0", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-u8X0thhx+yJ0KmkxuEo9HAtdfgCBaM/aI9K90VQcQioAmkVp3SG3FkwWGibUFz3WdXAdcsqOcbU40lK7tbHdkQ=="], + "@octokit/endpoint/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@25.1.0", "", {}, "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA=="], "@octokit/graphql/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@25.1.0", "", {}, "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA=="], diff --git a/packages/core/package.json b/packages/core/package.json index 8f22483fb..964bc4308 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -10,6 +10,7 @@ "@octokit/rest": "^22.0.0", "@prisma/client": "^6.16.2", "@types/adm-zip": "^0.5.7", + "@types/bun": "^1.3.1", "@types/lodash-es": "^4.17.12", "@types/lz4js": "^0.2.1", "@types/three": "^0.180.0", diff --git a/packages/core/src/blitzkit/asset.ts b/packages/core/src/blitzkit/asset.ts index c28d5b65c..adfd8d5db 100644 --- a/packages/core/src/blitzkit/asset.ts +++ b/packages/core/src/blitzkit/asset.ts @@ -1,4 +1,4 @@ -import { assertSecret } from './assertSecret'; +import { assertSecret } from "./assertSecret"; export function asset(path: string) { return `${assertSecret(import.meta.env.PUBLIC_ASSET_BASE)}/${path}`; From cbde48d41bd06135cb895053986eb79238f03320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Thu, 6 Nov 2025 09:40:11 -0600 Subject: [PATCH 07/17] fix: PUBLIC_ASSET_BASE --- .github/workflows/reviews.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/reviews.yml b/.github/workflows/reviews.yml index c59523fae..12135e668 100644 --- a/.github/workflows/reviews.yml +++ b/.github/workflows/reviews.yml @@ -17,6 +17,7 @@ env: GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }} PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }} GH_TOKEN: ${{ secrets.GH_TOKEN }} + PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }} jobs: build: From 49fab2111384d69f22f3442c3ddbb55cf8dd2484 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Thu, 6 Nov 2025 09:52:47 -0600 Subject: [PATCH 08/17] fix: use relative script --- .github/workflows/reviews.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reviews.yml b/.github/workflows/reviews.yml index 12135e668..d3fd70594 100644 --- a/.github/workflows/reviews.yml +++ b/.github/workflows/reviews.yml @@ -35,4 +35,4 @@ jobs: - run: bun run setup - name: Find reviews - run: bun packages/scripts/src/reviews.ts + run: bun run build:reviews From b963ef0981f9072a5d080de387b3178ea973c99f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Thu, 6 Nov 2025 09:54:06 -0600 Subject: [PATCH 09/17] fix: name --- packages/scripts/src/reviews.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/scripts/src/reviews.ts b/packages/scripts/src/reviews.ts index 5d3cf7571..2affaae30 100644 --- a/packages/scripts/src/reviews.ts +++ b/packages/scripts/src/reviews.ts @@ -70,7 +70,7 @@ for (const tank of tanksSanitized) { ), }; - console.log(`${++done} done; found ${items.length} for ${tank.name}`); + console.log(`${++done} done; found ${items.length} for ${tank.name.locales.en}`); await new Promise((resolve) => setTimeout(resolve, 1000 / 5)); } catch (error) { From 975d579d21ea34ab3c858dc0f2733503ee87541e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Fri, 7 Nov 2025 22:39:13 +0000 Subject: [PATCH 10/17] New translations en.json (Russian) (#181) --- packages/i18n/strings/ru.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/i18n/strings/ru.json b/packages/i18n/strings/ru.json index fa8779880..3b3652e75 100644 --- a/packages/i18n/strings/ru.json +++ b/packages/i18n/strings/ru.json @@ -908,7 +908,7 @@ }, "stats": { "thickness_and_angle": "{thickness}мм {angle}°", - "nominal": "{thickness}1мм номинала", + "nominal": "{thickness}мм номинала", "ricochet_loss": "{loss}% пробития" } } From e063719caac6e837be77e39aee2558009e59d4d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Wed, 12 Nov 2025 10:22:27 -0600 Subject: [PATCH 11/17] debug --- packages/scripts/src/protos.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/scripts/src/protos.ts b/packages/scripts/src/protos.ts index 016110dcb..8ce4d86f2 100644 --- a/packages/scripts/src/protos.ts +++ b/packages/scripts/src/protos.ts @@ -14,6 +14,8 @@ const exec = promisify(execSync); let executableFileExtension: string; +console.log(await readdir("node_modules/.bin")); + if (existsSync("node_modules/.bin/protoc-gen-ts_proto.exe")) { executableFileExtension = ".exe"; } else { @@ -32,7 +34,7 @@ for (const root of roots) { while (files.length > 0) { let command = [ "protoc", - `--plugin=./node_modules/.bin/protoc-gen-ts_proto${executableFileExtension}`, + `--plugin=node_modules/.bin/protoc-gen-ts_proto${executableFileExtension}`, "--ts_proto_opt=esModuleInterop=true", "--ts_proto_opt=oneof=unions-value", // "--ts_proto_opt=removeEnumPrefix=true", From 45097f198c84d2e4d28a3aad782b8b1acfb4e3ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Wed, 12 Nov 2025 10:23:22 -0600 Subject: [PATCH 12/17] debug --- packages/scripts/src/protos.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/scripts/src/protos.ts b/packages/scripts/src/protos.ts index 8ce4d86f2..77914e2f1 100644 --- a/packages/scripts/src/protos.ts +++ b/packages/scripts/src/protos.ts @@ -14,7 +14,7 @@ const exec = promisify(execSync); let executableFileExtension: string; -console.log(await readdir("node_modules/.bin")); +console.log(await readdir("../../node_modules/.bin")); if (existsSync("node_modules/.bin/protoc-gen-ts_proto.exe")) { executableFileExtension = ".exe"; From 98de246578d9a09059880fdd96cf2ba97eaeb3c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Wed, 12 Nov 2025 10:24:38 -0600 Subject: [PATCH 13/17] mooooooove --- packages/scripts/src/protos.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/scripts/src/protos.ts b/packages/scripts/src/protos.ts index 77914e2f1..13538ac56 100644 --- a/packages/scripts/src/protos.ts +++ b/packages/scripts/src/protos.ts @@ -14,9 +14,7 @@ const exec = promisify(execSync); let executableFileExtension: string; -console.log(await readdir("../../node_modules/.bin")); - -if (existsSync("node_modules/.bin/protoc-gen-ts_proto.exe")) { +if (existsSync("../../node_modules/.bin/protoc-gen-ts_proto.exe")) { executableFileExtension = ".exe"; } else { executableFileExtension = ""; @@ -34,7 +32,7 @@ for (const root of roots) { while (files.length > 0) { let command = [ "protoc", - `--plugin=node_modules/.bin/protoc-gen-ts_proto${executableFileExtension}`, + `--plugin=../../node_modules/.bin/protoc-gen-ts_proto${executableFileExtension}`, "--ts_proto_opt=esModuleInterop=true", "--ts_proto_opt=oneof=unions-value", // "--ts_proto_opt=removeEnumPrefix=true", From d4e1f99ce22ca4902baf2f6033e624b920a47b34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Wed, 12 Nov 2025 11:00:02 -0600 Subject: [PATCH 14/17] fix: mk dir --- .github/workflows/assets.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/assets.yml b/.github/workflows/assets.yml index 777430625..da6e48eda 100644 --- a/.github/workflows/assets.yml +++ b/.github/workflows/assets.yml @@ -117,10 +117,10 @@ jobs: env: ARCHIVE_URL: ${{ github.event.inputs.archive_url }} run: | + mkdir -p temp/game wget -q -O temp/archive.zip $ARCHIVE_URL unzip -q temp/archive.zip -d temp/archive rm temp/archive.zip - mkdir -p temp/game mv temp/archive/app/* temp/game - name: (WGPKG) Download client From 9dcf7441c9e6390a2c3ce55c5505c1e39411d8e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Wed, 12 Nov 2025 13:50:17 -0600 Subject: [PATCH 15/17] feat: start of patch notes --- .vscode/settings.json | 3 + package.json | 3 +- packages/scripts/package.json | 3 +- packages/scripts/src/patchNotes.ts | 190 +++++++++++++++++++++++++++++ 4 files changed, 197 insertions(+), 2 deletions(-) create mode 100644 packages/scripts/src/patchNotes.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 5d988642b..105b58ef8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -150,6 +150,7 @@ "ownedtanks", "padder", "partytown", + "patchnotes", "PIXELFORMAT", "playerachievements", "playerinfo", @@ -164,6 +165,8 @@ "protobuf", "protoc", "protos", + "proxyclient", + "prunestrings", "Pyogenics", "ratingleaderboard", "raycaster", diff --git a/package.json b/package.json index d399c7b36..52ea35bdf 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,8 @@ "build:reviews": "cd packages/scripts && bun build:reviews", "build:ids": "cd packages/scripts && bun build:ids", "prunestrings": "cd packages/scripts && bun prunestrings", - "setup": "bun install && bun run build:prisma && bun run build:protos && bun run build:proxyclient" + "setup": "bun install && bun run build:prisma && bun run build:protos && bun run build:proxyclient", + "patchnotes": "cd packages/scripts && bun run patchnotes" }, "type": "module", "workspaces": [ diff --git a/packages/scripts/package.json b/packages/scripts/package.json index d6af45ab8..45ddcc9e6 100644 --- a/packages/scripts/package.json +++ b/packages/scripts/package.json @@ -43,7 +43,8 @@ "build:ratingleaderboard": "bun src/buildRatingLeaderboard.ts", "build:proxyclient": "bun src/buildProxyClient.ts", "prunestrings": "bun src/pruneStrings.ts", - "build:protos": "bun src/protos.ts" + "build:protos": "bun src/protos.ts", + "patchnotes": "bun src/patchNotes.ts" }, "type": "module" } diff --git a/packages/scripts/src/patchNotes.ts b/packages/scripts/src/patchNotes.ts new file mode 100644 index 000000000..e31e2a844 --- /dev/null +++ b/packages/scripts/src/patchNotes.ts @@ -0,0 +1,190 @@ +import { + availableProvisions, + fetchConsumableDefinitions, + fetchEquipmentDefinitions, + fetchProvisionDefinitions, + fetchTankDefinitions, + TankDefinition, +} from "@blitzkit/core"; +import { checkConsumableProvisionInclusivity } from "@blitzkit/core/src/blitzkit/checkConsumableProvisionInclusivity"; +import { writeFile } from "fs/promises"; +import { isEqual } from "lodash-es"; + +const domain = "https://opentest.blitzkit.app"; + +import.meta.env.PUBLIC_ASSET_BASE = "https://blitzkit.github.io/assets"; +const currentTankDefinitions = await fetchTankDefinitions(); +const currentConsumableDefinitions = await fetchConsumableDefinitions(); +const currentProvisionDefinitions = await fetchProvisionDefinitions(); +const currentEquipmentDefinitions = await fetchEquipmentDefinitions(); + +import.meta.env.PUBLIC_ASSET_BASE = "https://blitzkit.github.io/assets-preview"; +const previewTankDefinitions = await fetchTankDefinitions(); +const previewConsumableDefinitions = await fetchConsumableDefinitions(); +const previewProvisionDefinitions = await fetchProvisionDefinitions(); +const previewEquipmentDefinitions = await fetchEquipmentDefinitions(); + +let notes = "# BlitzKit OpenTest Patch Notes\n\n"; + +const newTanks: TankDefinition[] = []; + +for (const id in previewTankDefinitions.tanks) { + if (!(id in currentTankDefinitions.tanks)) { + newTanks.push(previewTankDefinitions.tanks[id]); + } +} + +newTanks.sort((a, b) => b.tier - a.tier); + +if (newTanks.length > 0) { + notes += "## New Tanks\n\n"; + + for (const tank of newTanks) { + notes += `- [${tank.name.locales.en}](${domain}/tanks/${tank.slug})\n`; + } + + notes += "\n"; +} + +const changedTanks: [TankDefinition, TankDefinition][] = []; + +for (const stringId in previewTankDefinitions.tanks) { + const id = Number(stringId); + + if (newTanks.some((tank) => tank.id === id)) continue; + + const current = currentTankDefinitions.tanks[id]; + const preview = previewTankDefinitions.tanks[id]; + + if (isEqual(current, preview)) continue; + + changedTanks.push([current, preview]); +} + +changedTanks.sort((a, b) => b[1].tier - a[1].tier); + +if (changedTanks.length > 0) { + notes += "## Changed Tanks\n\n"; + + for (const [current, preview] of changedTanks) { + const currentTurret = current.turrets.at(-1)!; + const previewTurret = preview.turrets.at(-1)!; + const currentGun = currentTurret.guns.at(-1)!; + const previewGun = previewTurret.guns.at(-1)!; + + const currentConsumables = Object.values( + currentConsumableDefinitions.consumables + ).filter((consumable) => + checkConsumableProvisionInclusivity(consumable, current, currentGun) + ); + const previewConsumables = Object.values( + previewConsumableDefinitions.consumables + ).filter((consumable) => + checkConsumableProvisionInclusivity(consumable, preview, previewGun) + ); + const addedConsumables = previewConsumables.filter( + (previewConsumable) => + !currentConsumables.some( + (currentConsumable) => currentConsumable.id === previewConsumable.id + ) + ); + const removedConsumables = currentConsumables.filter( + (currentConsumable) => + !previewConsumables.some( + (previewConsumable) => previewConsumable.id === currentConsumable.id + ) + ); + + const currentProvisions = availableProvisions( + current, + currentGun, + currentProvisionDefinitions + ); + const previewProvisions = availableProvisions( + preview, + previewGun, + previewProvisionDefinitions + ); + const addedProvisions = previewProvisions.filter( + (previewProvision) => + !currentProvisions.some( + (currentProvision) => currentProvision.id === previewProvision.id + ) + ); + const removedProvisions = currentProvisions.filter( + (currentProvision) => + !previewProvisions.some( + (previewProvision) => previewProvision.id === currentProvision.id + ) + ); + + const currentEquipment = currentEquipmentDefinitions.presets[ + current.equipment_preset + ].slots + .map(({ left, right }) => [left, right]) + .flat(); + const previewEquipment = previewEquipmentDefinitions.presets[ + preview.equipment_preset + ].slots + .map(({ left, right }) => [left, right]) + .flat(); + const addedEquipment = previewEquipment + .filter( + (previewEquipment) => + !currentEquipment.some( + (currentEquipment) => currentEquipment === previewEquipment + ) + ) + .map((id) => previewEquipmentDefinitions.equipments[id]); + const removedEquipment = currentEquipment + .filter( + (currentEquipment) => + !previewEquipment.some( + (previewEquipment) => previewEquipment === currentEquipment + ) + ) + .map((id) => currentEquipmentDefinitions.equipments[id]); + + // notes += `- [${preview.name.locales.en}](${domain}/tanks/${preview.slug})\n`; + notes += `- ${preview.name.locales.en}\n`; + + if (addedConsumables.length + removedConsumables.length > 0) { + notes += ` - Consumables: `; + notes += [ + ...addedConsumables.map( + (consumable) => `🟢 ${consumable.name.locales.en}` + ), + ...removedConsumables.map( + (consumable) => `🔴 ${consumable.name.locales.en}` + ), + ].join(", "); + notes += `\n`; + } + + if (addedProvisions.length + removedProvisions.length > 0) { + notes += ` - Provisions: `; + notes += [ + ...addedProvisions.map( + (provision) => `🟢 ${provision.name.locales.en}` + ), + ...removedProvisions.map( + (provision) => `🔴 ${provision.name.locales.en}` + ), + ].join(", "); + notes += `\n`; + } + + if (addedEquipment.length + removedEquipment.length > 0) { + notes += ` - Equipment: `; + notes += [ + ...addedEquipment.map((equipment) => `🟢 ${equipment.name.locales.en}`), + ...removedEquipment.map( + (equipment) => `🔴 ${equipment.name.locales.en}` + ), + ].join(", "); + notes += `\n`; + } + } +} + +await writeFile("../../temp/patch-notes.md", notes); From cd8083ae30141564640498a16decadb6b8f8c93e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Wed, 12 Nov 2025 14:10:02 -0600 Subject: [PATCH 16/17] feat: more patchnotes --- packages/scripts/src/patchNotes.ts | 120 +++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/packages/scripts/src/patchNotes.ts b/packages/scripts/src/patchNotes.ts index e31e2a844..2ba208f63 100644 --- a/packages/scripts/src/patchNotes.ts +++ b/packages/scripts/src/patchNotes.ts @@ -1,14 +1,21 @@ import { availableProvisions, + createDefaultProvisions, + createDefaultSkills, fetchConsumableDefinitions, fetchEquipmentDefinitions, + fetchModelDefinitions, fetchProvisionDefinitions, + fetchSkillDefinitions, fetchTankDefinitions, TankDefinition, } from "@blitzkit/core"; import { checkConsumableProvisionInclusivity } from "@blitzkit/core/src/blitzkit/checkConsumableProvisionInclusivity"; +import strings from "@blitzkit/i18n/strings/en.json"; import { writeFile } from "fs/promises"; import { isEqual } from "lodash-es"; +import { tankCharacteristics } from "../../website/src/core/blitzkit/tankCharacteristics"; +import { genericDefaultEquipmentMatrix } from "../../website/src/stores/duel/constants"; const domain = "https://opentest.blitzkit.app"; @@ -17,12 +24,16 @@ const currentTankDefinitions = await fetchTankDefinitions(); const currentConsumableDefinitions = await fetchConsumableDefinitions(); const currentProvisionDefinitions = await fetchProvisionDefinitions(); const currentEquipmentDefinitions = await fetchEquipmentDefinitions(); +const currentSkillDefinitions = await fetchSkillDefinitions(); +const currentModelDefinitions = await fetchModelDefinitions(); import.meta.env.PUBLIC_ASSET_BASE = "https://blitzkit.github.io/assets-preview"; const previewTankDefinitions = await fetchTankDefinitions(); const previewConsumableDefinitions = await fetchConsumableDefinitions(); const previewProvisionDefinitions = await fetchProvisionDefinitions(); const previewEquipmentDefinitions = await fetchEquipmentDefinitions(); +const previewSkillDefinitions = await fetchSkillDefinitions(); +const previewModelDefinitions = await fetchModelDefinitions(); let notes = "# BlitzKit OpenTest Patch Notes\n\n"; @@ -71,6 +82,14 @@ if (changedTanks.length > 0) { const previewTurret = preview.turrets.at(-1)!; const currentGun = currentTurret.guns.at(-1)!; const previewGun = previewTurret.guns.at(-1)!; + const currentShell = currentGun.shells[0]; + const previewShell = previewGun.shells[0]; + const currentEngine = current.engines.at(-1)!; + const previewEngine = preview.engines.at(-1)!; + const currentTracks = current.tracks.at(-1)!; + const previewTracks = preview.tracks.at(-1)!; + const currentTankModel = currentModelDefinitions.models[current.id]; + const previewTankModel = previewModelDefinitions.models[preview.id]; const currentConsumables = Object.values( currentConsumableDefinitions.consumables @@ -145,6 +164,82 @@ if (changedTanks.length > 0) { ) .map((id) => currentEquipmentDefinitions.equipments[id]); + const currentCharacteristics = tankCharacteristics( + { + tank: current, + gun: currentGun, + shell: currentShell, + applyDynamicArmor: false, + applyReactiveArmor: false, + applySpallLiner: false, + assaultDistance: 0, + crewSkills: createDefaultSkills(currentSkillDefinitions), + camouflage: true, + consumables: [], + engine: currentEngine, + provisions: createDefaultProvisions( + current, + currentGun, + currentProvisionDefinitions + ), + equipmentMatrix: genericDefaultEquipmentMatrix, + stockEngine: current.engines[0], + stockGun: current.turrets[0].guns[0], + stockTrack: current.tracks[0], + stockTurret: current.turrets[0], + track: currentTracks, + turret: currentTurret, + }, + { + equipmentDefinitions: currentEquipmentDefinitions, + provisionDefinitions: currentProvisionDefinitions, + tankModelDefinition: currentTankModel, + } + ); + const previewCharacteristics = tankCharacteristics( + { + tank: preview, + gun: previewGun, + shell: previewShell, + applyDynamicArmor: false, + applyReactiveArmor: false, + applySpallLiner: false, + assaultDistance: 0, + crewSkills: createDefaultSkills(previewSkillDefinitions), + camouflage: true, + consumables: [], + engine: previewEngine, + provisions: createDefaultProvisions( + preview, + previewGun, + previewProvisionDefinitions + ), + equipmentMatrix: genericDefaultEquipmentMatrix, + stockEngine: preview.engines[0], + stockGun: preview.turrets[0].guns[0], + stockTrack: preview.tracks[0], + stockTurret: preview.turrets[0], + track: previewTracks, + turret: previewTurret, + }, + { + equipmentDefinitions: previewEquipmentDefinitions, + provisionDefinitions: previewProvisionDefinitions, + tankModelDefinition: previewTankModel, + } + ); + const changedCharacteristics: string[] = []; + + for (const key in currentCharacteristics) { + const characteristicKey = key as keyof typeof currentCharacteristics; + if ( + currentCharacteristics[characteristicKey] !== + previewCharacteristics[characteristicKey] + ) { + changedCharacteristics.push(characteristicKey); + } + } + // notes += `- [${preview.name.locales.en}](${domain}/tanks/${preview.slug})\n`; notes += `- ${preview.name.locales.en}\n`; @@ -184,6 +279,31 @@ if (changedTanks.length > 0) { ].join(", "); notes += `\n`; } + + if (changedCharacteristics.length > 0) { + notes += ` - Characteristics:\n`; + + for (const characteristicUntyped of changedCharacteristics) { + const characteristic = + characteristicUntyped as keyof typeof currentCharacteristics; + const name = + strings.website.tools.tankopedia.characteristics.values[ + characteristic + ]; + const before = currentCharacteristics[characteristic]; + const after = previewCharacteristics[characteristic]; + + notes += ` - ${ + typeof before === "number" && typeof after === "number" + ? after > before + ? "⬆️" + : "🔻" + : "✏️" + } ${name}: \`${ + typeof before === "number" ? before.toFixed(2) : before + }\` → \`${typeof after === "number" ? after.toFixed(2) : after}\`\n`; + } + } } } From e4429f15bdb0886ea2ff4afe142313db30e5ff53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Wed, 12 Nov 2025 14:18:54 -0600 Subject: [PATCH 17/17] feat: moar!! --- packages/scripts/src/patchNotes.ts | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/scripts/src/patchNotes.ts b/packages/scripts/src/patchNotes.ts index 2ba208f63..9f132b3bf 100644 --- a/packages/scripts/src/patchNotes.ts +++ b/packages/scripts/src/patchNotes.ts @@ -9,6 +9,7 @@ import { fetchSkillDefinitions, fetchTankDefinitions, TankDefinition, + tankIcon, } from "@blitzkit/core"; import { checkConsumableProvisionInclusivity } from "@blitzkit/core/src/blitzkit/checkConsumableProvisionInclusivity"; import strings from "@blitzkit/i18n/strings/en.json"; @@ -47,11 +48,13 @@ for (const id in previewTankDefinitions.tanks) { newTanks.sort((a, b) => b.tier - a.tier); +import.meta.env.PUBLIC_ASSET_BASE = "https://blitzkit.github.io/assets-preview"; if (newTanks.length > 0) { notes += "## New Tanks\n\n"; for (const tank of newTanks) { - notes += `- [${tank.name.locales.en}](${domain}/tanks/${tank.slug})\n`; + notes += `### [${tank.name.locales.en}](${domain}/tanks/${tank.slug})\n`; + notes += `![](${tankIcon(tank.id)})\n\n`; } notes += "\n"; @@ -74,6 +77,7 @@ for (const stringId in previewTankDefinitions.tanks) { changedTanks.sort((a, b) => b[1].tier - a[1].tier); +import.meta.env.PUBLIC_ASSET_BASE = "https://blitzkit.github.io/assets"; if (changedTanks.length > 0) { notes += "## Changed Tanks\n\n"; @@ -240,11 +244,11 @@ if (changedTanks.length > 0) { } } - // notes += `- [${preview.name.locales.en}](${domain}/tanks/${preview.slug})\n`; - notes += `- ${preview.name.locales.en}\n`; + notes += `### [${preview.name.locales.en}](${domain}/tanks/${preview.slug})\n`; + notes += `![](${tankIcon(preview.id)})\n\n`; if (addedConsumables.length + removedConsumables.length > 0) { - notes += ` - Consumables: `; + notes += `Consumables: `; notes += [ ...addedConsumables.map( (consumable) => `🟢 ${consumable.name.locales.en}` @@ -257,7 +261,7 @@ if (changedTanks.length > 0) { } if (addedProvisions.length + removedProvisions.length > 0) { - notes += ` - Provisions: `; + notes += `Provisions: `; notes += [ ...addedProvisions.map( (provision) => `🟢 ${provision.name.locales.en}` @@ -270,7 +274,7 @@ if (changedTanks.length > 0) { } if (addedEquipment.length + removedEquipment.length > 0) { - notes += ` - Equipment: `; + notes += `-Equipment: `; notes += [ ...addedEquipment.map((equipment) => `🟢 ${equipment.name.locales.en}`), ...removedEquipment.map( @@ -281,7 +285,7 @@ if (changedTanks.length > 0) { } if (changedCharacteristics.length > 0) { - notes += ` - Characteristics:\n`; + notes += `Characteristics:\n`; for (const characteristicUntyped of changedCharacteristics) { const characteristic = @@ -293,7 +297,7 @@ if (changedTanks.length > 0) { const before = currentCharacteristics[characteristic]; const after = previewCharacteristics[characteristic]; - notes += ` - ${ + notes += `- ${ typeof before === "number" && typeof after === "number" ? after > before ? "⬆️"