1 parent
fd14b54d8a
commit
0f370167db
9 files changed
+18
-134
No files matched your search
@@ -1,12 +1,9 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
// Комбобокс в общем тёмном стиле окна.
|
||||
ComboBox {
|
||||
id: darkCombo
|
||||
|
||||
// Та же стрелка, что у комбобоксов профиля и версии на главном окне,
|
||||
// вместо двойного шеврона Basic-стиля.
|
||||
indicator: Image {
|
||||
width: 10; height: 10
|
||||
x: darkCombo.width - width - 12
|
||||
|
||||
+1
-20
@@ -4,22 +4,16 @@ import QtQuick
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 2.15
|
||||
|
||||
// Выбор сборки Java отдельным окном: слева типы, справа сами версии с поиском.
|
||||
// Устроено так же, как выбор версии Minecraft, но выбранное здесь ещё и
|
||||
// качается — в отличие от версий игры, где загрузку начинает сама сборка.
|
||||
Dialog {
|
||||
id: picker
|
||||
|
||||
required property var backend
|
||||
|
||||
// Сборка, с которой окно открылось: по «Отмене» выбор к ней и возвращается.
|
||||
property string selectedId: ""
|
||||
property string category: "java"
|
||||
property string filterText: ""
|
||||
property bool installedOnly: false
|
||||
|
||||
// Java, ниже которой выбранной версии игры не запуститься. 0 — версия игры
|
||||
// не выбрана, предупреждать не о чем.
|
||||
property int requiredMajor: 0
|
||||
|
||||
signal runtimeChosen(string runtimeId)
|
||||
@@ -43,8 +37,6 @@ Dialog {
|
||||
{ key: "jre", title: Loc.t.common.java.kind.jre, hint: Loc.t.java.filter.temurinJre }
|
||||
]
|
||||
|
||||
// Каталог приходит из C++ уже отсортированным (новые сверху, скачанные
|
||||
// первыми), поэтому здесь только отбор — порядок не трогаем.
|
||||
readonly property var visibleEntries: {
|
||||
const query = picker.filterText.trim().toLowerCase()
|
||||
const source = picker.backend.javaCatalog
|
||||
@@ -107,7 +99,6 @@ Dialog {
|
||||
runtimeList.positionViewAtIndex(index, ListView.Center)
|
||||
}
|
||||
|
||||
// «Выбрать» и скачивает: сборка, которой нет на диске, запуску не поможет.
|
||||
function acceptSelection() {
|
||||
const entry = picker.selectedEntry
|
||||
if (!entry)
|
||||
@@ -138,7 +129,6 @@ Dialog {
|
||||
contentItem: RowLayout {
|
||||
spacing: 0
|
||||
|
||||
// ── Типы сборок ─────────────────────────────────────────────────
|
||||
Rectangle {
|
||||
Layout.preferredWidth: 170
|
||||
Layout.fillHeight: true
|
||||
@@ -195,8 +185,6 @@ Dialog {
|
||||
|
||||
Item { width: 1; height: 8 }
|
||||
|
||||
// Требование выбранной сборки — чтобы не пришлось держать в
|
||||
// голове, какая Java нужна какой версии игры.
|
||||
Text {
|
||||
width: parent.width - 4
|
||||
visible: picker.requiredMajor > 0
|
||||
@@ -215,7 +203,6 @@ Dialog {
|
||||
color: "#333333"
|
||||
}
|
||||
|
||||
// ── Версии ──────────────────────────────────────────────────────
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
@@ -317,8 +304,7 @@ Dialog {
|
||||
required property int index
|
||||
|
||||
readonly property bool chosen: picker.selectedId === runtimeRow.modelData.id
|
||||
// Сборка ниже требования игры выбирается, но помечается: она
|
||||
// может пригодиться для другой сборки.
|
||||
|
||||
readonly property bool tooOld: picker.requiredMajor > 0
|
||||
&& runtimeRow.modelData.major < picker.requiredMajor
|
||||
|
||||
@@ -353,8 +339,6 @@ Dialog {
|
||||
}
|
||||
|
||||
Text {
|
||||
// Колонка растянута якорями, поэтому её ширина
|
||||
// задана, а не выведена из детей — цикла тут нет.
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
color: runtimeRow.chosen ? "#1e1e1e"
|
||||
@@ -388,8 +372,6 @@ Dialog {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
// Сборки весят по двести мегабайт — удалять их нужно
|
||||
// прямо здесь, иначе папка лаунчера растёт молча.
|
||||
Image {
|
||||
visible: runtimeRow.modelData.installed
|
||||
source: "images/Trash.svg"
|
||||
@@ -430,7 +412,6 @@ Dialog {
|
||||
}
|
||||
}
|
||||
|
||||
// Пустая категория, ничего не нашлось или каталог ещё не пришёл.
|
||||
Text {
|
||||
anchors.centerIn: runtimeList
|
||||
width: runtimeList.width - 20
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
// Подпись + поле ввода одной колонкой — используется в настройках.
|
||||
Column {
|
||||
id: labelled
|
||||
|
||||
@@ -10,7 +9,6 @@ Column {
|
||||
property string label: ""
|
||||
property string placeholder: ""
|
||||
|
||||
// Правка закончена: поле потеряло фокус или пользователь нажал Enter.
|
||||
signal editingFinished()
|
||||
|
||||
spacing: 3
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
// Один модлоадер в карточке сборки: чекбокс и, когда он отмечен, список версий
|
||||
// именно под выбранную версию Minecraft.
|
||||
//
|
||||
// Совместимость проверять не нужно: backend.loaderVersions() отдаёт список уже
|
||||
// под конкретную версию игры, поэтому несовместимой строки в нём не бывает.
|
||||
// Пустой список — это «лоадер не поддерживает эту версию игры», и он тоже
|
||||
// показывается словами, а не пустым выпадающим списком.
|
||||
Column {
|
||||
id: loaderRow
|
||||
|
||||
@@ -15,21 +8,13 @@ Column {
|
||||
required property string loaderKey
|
||||
required property string title
|
||||
|
||||
// Версия Minecraft, выбранная в карточке. Её смена сбрасывает выбор.
|
||||
property string gameVersion: ""
|
||||
|
||||
property alias checked: box.checked
|
||||
property string selectedVersion: ""
|
||||
property var entries: []
|
||||
|
||||
// Пользователь щёлкнул чекбокс — карточка снимет отметки с остальных
|
||||
// лоадеров: одновременно в .minecraft может жить только один.
|
||||
signal userChecked()
|
||||
// Отметка или версия изменились — карточке пора сохранить сборку.
|
||||
signal changed()
|
||||
|
||||
// Ставится, пока карточка заполняет строку данными сборки: в это время
|
||||
// обработчики не должны считать изменения пользовательскими.
|
||||
property bool applying: false
|
||||
|
||||
spacing: 4
|
||||
@@ -42,16 +27,9 @@ Column {
|
||||
return -1
|
||||
}
|
||||
|
||||
// Единственное место, где меняются entries и selectedVersion. Через него
|
||||
// проходят все три пути — кэш, ответ сети и заполнение из сборки, — потому
|
||||
// что выбранная версия обязана существовать в списке под текущую версию
|
||||
// игры. Раньше проверял только путь из сети, и версия лоадера от прошлой
|
||||
// версии игры доживала до сохранения сборки.
|
||||
function applyEntries(list) {
|
||||
loaderRow.entries = list
|
||||
|
||||
// Список отсортирован новыми вперёд, поэтому максимально доступная
|
||||
// версия для этой версии игры — всегда первая строка.
|
||||
if (loaderRow.versionIndex(loaderRow.selectedVersion) < 0) {
|
||||
const fallback = list.length > 0 ? list[0].version : ""
|
||||
const changedValue = loaderRow.selectedVersion !== fallback
|
||||
@@ -68,26 +46,20 @@ Column {
|
||||
loaderRow.applyEntries([])
|
||||
return
|
||||
}
|
||||
// Сначала из кэша — список появляется мгновенно, — потом обновление сети.
|
||||
loaderRow.applyEntries(loaderRow.backend.loaderVersions(loaderRow.loaderKey,
|
||||
loaderRow.gameVersion))
|
||||
loaderRow.backend.refreshLoaderVersions(loaderRow.loaderKey, loaderRow.gameVersion)
|
||||
}
|
||||
|
||||
// Заполнение из сохранённой сборки: без сигналов changed().
|
||||
function applyBuild(loader, loaderVersion) {
|
||||
loaderRow.applying = true
|
||||
box.checked = loader === loaderRow.loaderKey
|
||||
// Версию из сборки берём как пожелание: если под выбранную версию игры
|
||||
// её нет, applyEntries() заменит её на максимально доступную.
|
||||
loaderRow.selectedVersion = box.checked ? loaderVersion : ""
|
||||
loaderRow.reload()
|
||||
loaderRow.applying = false
|
||||
}
|
||||
|
||||
onGameVersionChanged: {
|
||||
// Сборка лоадера привязана к версии игры: под новой версией прежний
|
||||
// выбор недействителен, и список перезапрашивается заново.
|
||||
loaderRow.selectedVersion = ""
|
||||
loaderRow.reload()
|
||||
}
|
||||
|
||||
@@ -4,19 +4,12 @@ import QtQuick
|
||||
import QtQuick.Controls 2.15
|
||||
import QtWebEngine
|
||||
|
||||
// Вход в аккаунт Microsoft — то же самое, что делает официальный лаунчер:
|
||||
// страница входа показывается внутри приложения, а лаунчер ждёт, когда браузер
|
||||
// уйдёт на redirect_uri с кодом авторизации в адресе.
|
||||
Dialog {
|
||||
id: msLogin
|
||||
|
||||
required property var backend
|
||||
|
||||
// Окно ничего не знает про тосты главного окна: о неудаче сообщает сигналом.
|
||||
signal failed(string message)
|
||||
|
||||
// Код уже отдан backend — второй раз по тому же адресу не реагируем:
|
||||
// WebEngineView успевает сообщить об urlChanged несколько раз.
|
||||
property bool codeTaken: false
|
||||
|
||||
anchors.centerIn: parent
|
||||
@@ -32,8 +25,6 @@ Dialog {
|
||||
open()
|
||||
}
|
||||
|
||||
// Разбор адреса живёт в C++: правила совпадения должны совпадать с теми,
|
||||
// по которым сервис строит сам redirect_uri.
|
||||
function handleUrl(url) {
|
||||
if (codeTaken)
|
||||
return
|
||||
@@ -76,9 +67,6 @@ Dialog {
|
||||
}
|
||||
|
||||
contentItem: Item {
|
||||
// Профиль без storageName — значит без диска: куки живут только пока
|
||||
// работает лаунчер и в общий браузер не попадают. За выбор аккаунта в
|
||||
// пределах сессии отвечает prompt=select_account в адресе входа.
|
||||
WebEngineProfilePrototype {
|
||||
id: msProfile
|
||||
}
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
// Плашка хода долгой операции в левом нижнем углу: не задевает кнопку запуска,
|
||||
// сообщение по центру и кнопки папки с настройками.
|
||||
Rectangle {
|
||||
id: panel
|
||||
|
||||
property string title: ""
|
||||
property string status: ""
|
||||
// -1 — итог ещё неизвестен, показываем «…» вместо процентов.
|
||||
property double fraction: -1
|
||||
// Необязательная вторая строка: мегабайты у загрузки, путь у архивации.
|
||||
property string detail: ""
|
||||
property bool cancellable: true
|
||||
|
||||
|
||||
@@ -3,23 +3,11 @@ pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
// Готовые сезонные сборки с сервера лаунчера: таблица со всем, что нужно
|
||||
// решить, ставить её или нет, и одна кнопка, которая делает всё остальное —
|
||||
// заводит сборку, ставит версию игры, модлоадер, Java и раскладывает файлы.
|
||||
//
|
||||
// Таблица собрана из Row фиксированных колонок, а не из TableView: в проекте
|
||||
// нет ни одной модели QAbstractItemModel, а строки приходят готовыми
|
||||
// QVariantMap — заводить ради семи колонок отдельную модель незачем.
|
||||
Dialog {
|
||||
id: seasons
|
||||
|
||||
required property var backend
|
||||
|
||||
// Выбранная строка. Хранится по id, а не по индексу: список обновляется
|
||||
// под руками, и индекс после обновления указывал бы на другую сборку.
|
||||
property string selectedId: ""
|
||||
|
||||
// Ширины колонок в одном месте: их повторяют и шапка, и делегат.
|
||||
readonly property var columns: [
|
||||
{ key: "name", title: Loc.t.common.header.name, width: 250, align: Text.AlignLeft },
|
||||
{ key: "minecraftVersion", title: Loc.t.common.header.version, width: 90, align: Text.AlignLeft },
|
||||
@@ -34,8 +22,6 @@ Dialog {
|
||||
padding: 0
|
||||
width: 960
|
||||
height: 560
|
||||
// Пока идёт установка, окно закрывается только кнопкой: случайный щелчок
|
||||
// мимо не должен спрятать единственную видимую отмену.
|
||||
closePolicy: seasons.backend.seasonalInstalling
|
||||
? Popup.NoAutoClose
|
||||
: (Popup.CloseOnEscape | Popup.CloseOnPressOutside)
|
||||
@@ -47,8 +33,6 @@ Dialog {
|
||||
border.width: 1
|
||||
}
|
||||
|
||||
// Строки приходят из C++ уже отсортированными и сведёнными с локальными
|
||||
// записями — здесь только показ.
|
||||
readonly property var entries: seasons.backend.seasonalCatalog
|
||||
|
||||
readonly property var selectedEntry: {
|
||||
@@ -79,7 +63,6 @@ Dialog {
|
||||
return String(entry[key])
|
||||
}
|
||||
|
||||
// Свежий кэш отвечает без сети, поэтому дёргаем при каждом открытии.
|
||||
onAboutToShow: seasons.backend.refreshSeasonalCatalog(false)
|
||||
|
||||
header: Item {
|
||||
@@ -101,7 +84,6 @@ Dialog {
|
||||
|
||||
contentItem: Item {
|
||||
|
||||
// ── Шапка таблицы ───────────────────────────────────────────────
|
||||
Row {
|
||||
id: tableHeader
|
||||
anchors.top: parent.top
|
||||
@@ -139,9 +121,6 @@ Dialog {
|
||||
color: "#333333"
|
||||
}
|
||||
|
||||
// ── Сообщение вместо таблицы ────────────────────────────────────
|
||||
// Пустой список и ошибка выглядят одинаково пустыми, поэтому причина
|
||||
// показывается прямо на месте строк.
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
width: parent.width - 80
|
||||
@@ -157,7 +136,6 @@ Dialog {
|
||||
: seasons.backend.seasonalCatalogError)
|
||||
}
|
||||
|
||||
// ── Строки ──────────────────────────────────────────────────────
|
||||
ListView {
|
||||
id: buildList
|
||||
anchors.top: headerLine.bottom
|
||||
@@ -243,8 +221,6 @@ Dialog {
|
||||
color: "#333333"
|
||||
}
|
||||
|
||||
// Описание и размер выбранной сборки: они длинные и в таблицу не
|
||||
// помещаются, а решение принимается по ним.
|
||||
Column {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 18
|
||||
@@ -314,8 +290,6 @@ Dialog {
|
||||
id: installButton
|
||||
width: 150
|
||||
height: 36
|
||||
// Установка занимает и панель загрузки, и .minecraft целиком:
|
||||
// пока лаунчер занят чем угодно, вторую начинать нельзя.
|
||||
enabled: seasons.selectedEntry !== null && !seasons.backend.busy
|
||||
contentItem: Text {
|
||||
text: seasons.selectedEntry && seasons.selectedEntry.updateAvailable
|
||||
|
||||
@@ -4,25 +4,16 @@ import QtQuick
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 2.15
|
||||
|
||||
// Выбор версии Minecraft отдельным окном: слева категории, справа сами версии
|
||||
// с поиском сверху.
|
||||
//
|
||||
// Раньше это был выпадающий список на всю тысячу версий: найти в нём бету 1.7
|
||||
// можно было только поиском по точному номеру. Категории делят список на
|
||||
// обозримые части, а поиск работает внутри выбранной.
|
||||
Dialog {
|
||||
id: picker
|
||||
|
||||
required property var backend
|
||||
|
||||
// Версия, с которой окно открылось: по «Отмене» выбор к ней и возвращается.
|
||||
property string selectedId: ""
|
||||
property string category: "release"
|
||||
property string filterText: ""
|
||||
property bool installedOnly: false
|
||||
|
||||
// Выбранная версия подтверждена кнопкой или двойным щелчком. Имя не
|
||||
// accepted(): такой сигнал у Dialog уже есть, и переопределить его нельзя.
|
||||
signal versionChosen(string versionId)
|
||||
|
||||
modal: true
|
||||
@@ -46,8 +37,6 @@ Dialog {
|
||||
{ key: "other", title: Loc.t.version.filter.other }
|
||||
]
|
||||
|
||||
// Каталог приходит из C++ уже отсортированным (новые сверху), поэтому здесь
|
||||
// только отбор — порядок не трогаем.
|
||||
readonly property var visibleEntries: {
|
||||
const query = picker.filterText.trim().toLowerCase()
|
||||
const source = picker.backend.versionCatalog
|
||||
@@ -69,7 +58,6 @@ Dialog {
|
||||
picker.selectedId = versionId
|
||||
picker.filterText = ""
|
||||
searchField.text = ""
|
||||
// Открываемся на категории текущей версии, а не всегда на релизах.
|
||||
picker.category = picker.categoryOf(versionId)
|
||||
picker.backend.refreshVersionCatalog()
|
||||
picker.open()
|
||||
@@ -117,9 +105,6 @@ Dialog {
|
||||
return false
|
||||
}
|
||||
|
||||
// Спрашиваем до удаления: версию придётся качать заново, а профили
|
||||
// модлоадеров поверх неё — переустанавливать. Id запоминаем здесь:
|
||||
// к моменту ответа строка под курсором может быть уже другой.
|
||||
function askRemove(versionId) {
|
||||
const info = picker.backend.versionRemovalInfo(versionId)
|
||||
if (!info || info.installed !== true)
|
||||
@@ -133,8 +118,6 @@ Dialog {
|
||||
|
||||
function performRemove(versionId) {
|
||||
picker.backend.removeVersion(versionId)
|
||||
// Профиль модлоадера был в каталоге только потому, что установлен:
|
||||
// после удаления строка исчезает совсем, и выбор надо снять.
|
||||
if (picker.selectedId === versionId && !picker.catalogHas(versionId))
|
||||
picker.selectedId = ""
|
||||
picker.revealSelected()
|
||||
@@ -305,7 +288,6 @@ Dialog {
|
||||
contentItem: RowLayout {
|
||||
spacing: 0
|
||||
|
||||
// ── Категории ───────────────────────────────────────────────────
|
||||
Rectangle {
|
||||
Layout.preferredWidth: 150
|
||||
Layout.fillHeight: true
|
||||
@@ -358,7 +340,6 @@ Dialog {
|
||||
color: "#333333"
|
||||
}
|
||||
|
||||
// ── Версии ──────────────────────────────────────────────────────
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
@@ -493,8 +474,6 @@ Dialog {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
// Версия весит от десятков мегабайт, а галочка рядом —
|
||||
// единственное место, где видно, что именно скачано.
|
||||
Image {
|
||||
visible: versionRow.modelData.installed
|
||||
source: "images/Trash.svg"
|
||||
@@ -531,7 +510,6 @@ Dialog {
|
||||
}
|
||||
}
|
||||
|
||||
// Пустая категория, ничего не нашлось или манифест ещё не пришёл.
|
||||
Text {
|
||||
anchors.centerIn: versionList
|
||||
width: versionList.width - 20
|
||||
|
||||
+17
-17
@@ -40,7 +40,7 @@
|
||||
"en": "Open mods folder"
|
||||
},
|
||||
"app.tooltip.seasonal": {
|
||||
"ru": "Сезонные сборки от команды Мельника",
|
||||
"ru": "Сезонные сборки от команды Galeon'а",
|
||||
"en": "Seasonal builds from Galeon team"
|
||||
},
|
||||
"app.tooltip.settings": {
|
||||
@@ -156,8 +156,8 @@
|
||||
"en": "The Microsoft account owns the game but has no game profile yet. Sign in to the official launcher once and pick a nickname."
|
||||
},
|
||||
"auth.msa.error.noWebEngine": {
|
||||
"ru": "Эта сборка лаунчера собрана без Qt WebEngine — показать окно входа Microsoft нечем",
|
||||
"en": "This launcher build was made without Qt WebEngine — there is nothing to show the Microsoft sign-in window with"
|
||||
"ru": "Эта сборка лаунчера собрана без Qt WebEngine",
|
||||
"en": "This launcher build was made without Qt WebEngine"
|
||||
},
|
||||
"auth.msa.error.noXboxProfile": {
|
||||
"ru": "К аккаунту Microsoft не привязан профиль Xbox. Создайте его на xbox.com и повторите вход.",
|
||||
@@ -196,8 +196,8 @@
|
||||
"en": "The Microsoft session has expired — sign in to the account again (%1)"
|
||||
},
|
||||
"auth.msa.error.windowUnavailable": {
|
||||
"ru": "Окно входа Microsoft недоступно: сборка без Qt WebEngine",
|
||||
"en": "The Microsoft sign-in window is unavailable: this build has no Qt WebEngine"
|
||||
"ru": "Окно входа Microsoft недоступно",
|
||||
"en": "The Microsoft sign-in window is unavailable"
|
||||
},
|
||||
"auth.msa.error.xboxNoToken": {
|
||||
"ru": "Xbox Live не вернул токен",
|
||||
@@ -288,8 +288,8 @@
|
||||
"en": "Pick a version"
|
||||
},
|
||||
"build.error.closeGameFilesMoving": {
|
||||
"ru": "Сначала закройте игру — её файлы сейчас переносятся",
|
||||
"en": "Close the game first — its files are being moved right now"
|
||||
"ru": "Файлы игры в процессе переноса, сначала закройте игру",
|
||||
"en": "Game files are being moved, close the game first"
|
||||
},
|
||||
"build.error.filesIncomplete": {
|
||||
"ru": "Файлы сборки установлены не полностью: %1\nПовторите установку сборки.",
|
||||
@@ -328,8 +328,8 @@
|
||||
"en": "The build was not switched: %1"
|
||||
},
|
||||
"build.error.switchFailedDirty": {
|
||||
"ru": "Сборка не переключена: %1\nСодержимое .minecraft осталось разобранным — повторите переключение.",
|
||||
"en": "The build was not switched: %1\nThe contents of .minecraft are left half-applied — switch again."
|
||||
"ru": "Сборка не переключена: %1\n Повторите переключение.",
|
||||
"en": "The build was not switched: %1\n Switch again."
|
||||
},
|
||||
"build.error.versionNotInstalled": {
|
||||
"ru": "Версия «%1» из сборки «%2» не установлена в %3",
|
||||
@@ -340,8 +340,8 @@
|
||||
"en": "Build \"%1\" will be removed and cannot be recovered."
|
||||
},
|
||||
"build.hint.removingLast": {
|
||||
"ru": "Это последняя сборка. Содержимое .minecraft останется на месте.",
|
||||
"en": "This is the last build. The contents of .minecraft will stay where they are."
|
||||
"ru": "Последняя сборка, файлы из корня игры не удаляются.",
|
||||
"en": "Last build. The contents of .minecraft will stay."
|
||||
},
|
||||
"build.label.active": {
|
||||
"ru": "активна",
|
||||
@@ -360,8 +360,8 @@
|
||||
"en": "Server address"
|
||||
},
|
||||
"build.placeholder.name": {
|
||||
"ru": "как её видно в списке",
|
||||
"en": "as it appears in the list"
|
||||
"ru": "Введите наименование",
|
||||
"en": "Write a name"
|
||||
},
|
||||
"build.placeholder.serverAddress": {
|
||||
"ru": "host:port (необязательно)",
|
||||
@@ -384,8 +384,8 @@
|
||||
"en": "Build \"%1\": %2"
|
||||
},
|
||||
"build.status.ready": {
|
||||
"ru": "Всё на месте, сборку можно запускать",
|
||||
"en": "Everything is in place, the build can be launched"
|
||||
"ru": "Готова к запуску",
|
||||
"en": "Ready to launch"
|
||||
},
|
||||
"build.title.numbered": {
|
||||
"ru": "Сборка %1",
|
||||
@@ -396,8 +396,8 @@
|
||||
"en": "Remove the build?"
|
||||
},
|
||||
"build.warning.archiveGoesToo": {
|
||||
"ru": "Вместе с ней удалится её архив: моды, конфиги и миры этой сборки восстановить будет нельзя.",
|
||||
"en": "Its archive goes with it: the mods, configs and worlds of this build cannot be recovered."
|
||||
"ru": "Внимание, при удалении так же очищаются пользовательские сохранённые архивы.",
|
||||
"en": "Attention, after removing from the list all saved files will be deleted."
|
||||
},
|
||||
"build.warning.archiveNotRemoved": {
|
||||
"ru": "Сборка «%1» удалена, но её архив в %2 стереть не удалось",
|
||||
|
||||
Reference in new issue
Block a user