mirror of
https://github.com/MCSManager/MCSManager.git
synced 2025-03-19 16:40:22 +08:00
feat: add useless key scanner
This commit is contained in:
parent
fca4690f21
commit
412f5132fe
@ -1972,7 +1972,6 @@
|
||||
"TXT_CODE_60dd05d5": "Überschreiben Sie das Standard-Image-Arbeitsverzeichnis durch das Datenspeicherverzeichnis",
|
||||
"TXT_CODE_6259357c": "Das Programm muss länger als 6 Sekunden laufen, bevor ein Stopp erzwungen werden kann!",
|
||||
"TXT_CODE_6c232c9c": "Wird zum Mounten zusätzlicher Ordner auf dem Host im Container verwendet und unterstützt zwei variable Zeichenfolgen:",
|
||||
"TXT_CODE_708c10e2": "Paketliste",
|
||||
"TXT_CODE_75bf9192": "Code verwenden",
|
||||
"TXT_CODE_8028e95b": "Geben Sie Ihren Panel-Benutzernamen ein. Falls noch kein Konto vorhanden ist, wird ein neues Konto erstellt",
|
||||
"TXT_CODE_8074a178": "Neues Ablaufdatum:",
|
||||
@ -2021,4 +2020,4 @@
|
||||
"TXT_CODE_a0e19f38": "Instanz löschen",
|
||||
"TXT_CODE_ed81f72d": "Diese Instanz wurde nicht in einem Geschäft gekauft und kann nicht verlängert werden. Bitte kontaktieren Sie den Händler zur Bearbeitung!",
|
||||
"TXT_CODE_f486dbb4": "Instanz erfolgreich gelöscht"
|
||||
}
|
||||
}
|
@ -1972,7 +1972,6 @@
|
||||
"TXT_CODE_3ee20639": "Redemption successful, please remember the following",
|
||||
"TXT_CODE_e1b0aab2": "Password unchanged",
|
||||
"TXT_CODE_a676f2da": "Got it",
|
||||
"TXT_CODE_708c10e2": "Package List",
|
||||
"TXT_CODE_b99cae18": "Products",
|
||||
"TXT_CODE_163e2d0a": "Display instance specifications when merchant mode is enabled",
|
||||
"TXT_CODE_48261ab7": "Merchant Info Card",
|
||||
@ -2019,5 +2018,6 @@
|
||||
"TXT_CODE_7542201a": "Delete instance-related files simultaneously",
|
||||
"TXT_CODE_f486dbb4": "Instance deleted successfully",
|
||||
"TXT_CODE_ed81f72d": "This instance was not purchased from the store and cannot be renewed. Please contact the merchant for processing!",
|
||||
"TXT_CODE_afabf3ca": "Parsing time failed"
|
||||
}
|
||||
"TXT_CODE_afabf3ca": "Parsing time failed",
|
||||
"TXT_CODE_1548649e": "Edit scheduled tasks"
|
||||
}
|
@ -1972,7 +1972,6 @@
|
||||
"TXT_CODE_60dd05d5": "Anular el directorio de trabajo de imagen predeterminado con el directorio de almacenamiento de datos",
|
||||
"TXT_CODE_6259357c": "¡El programa debe ejecutarse durante más de 6 segundos antes de que se pueda forzar su detención!",
|
||||
"TXT_CODE_6c232c9c": "Se utiliza para montar carpetas adicionales en el host en el contenedor, admite dos cadenas de variables:",
|
||||
"TXT_CODE_708c10e2": "Lista de paquetes",
|
||||
"TXT_CODE_75bf9192": "Usar código",
|
||||
"TXT_CODE_8028e95b": "Ingrese su nombre de usuario del panel, se creará una nueva cuenta si no existe",
|
||||
"TXT_CODE_8074a178": "Nueva fecha de vencimiento:",
|
||||
@ -2020,4 +2019,4 @@
|
||||
"TXT_CODE_90508729": "Esta operación eliminará directamente todo el directorio donde se encuentra la instancia y los archivos no se podrán restaurar. ¿Quiere continuar?",
|
||||
"TXT_CODE_a0e19f38": "Eliminar instancia",
|
||||
"TXT_CODE_f486dbb4": "Instancia eliminada exitosamente"
|
||||
}
|
||||
}
|
@ -1972,7 +1972,6 @@
|
||||
"TXT_CODE_60dd05d5": "Remplacer le répertoire de travail de l'image par défaut par le répertoire de stockage de données",
|
||||
"TXT_CODE_6259357c": "Le programme doit s'exécuter pendant plus de 6 secondes avant de pouvoir être forcé à s'arrêter !",
|
||||
"TXT_CODE_6c232c9c": "Utilisé pour monter des dossiers supplémentaires sur l'hôte dans le conteneur, prend en charge deux chaînes variables :",
|
||||
"TXT_CODE_708c10e2": "Liste des paquets",
|
||||
"TXT_CODE_75bf9192": "Utiliser le code",
|
||||
"TXT_CODE_8028e95b": "Entrez votre nom d'utilisateur du panel, un nouveau compte sera créé s'il n'existe pas",
|
||||
"TXT_CODE_8074a178": "Nouvelle date d'expiration :",
|
||||
@ -2021,4 +2020,4 @@
|
||||
"TXT_CODE_a0e19f38": "Supprimer l'instance",
|
||||
"TXT_CODE_ed81f72d": "Cette instance n'a pas été achetée dans un magasin et ne peut pas être renouvelée. Veuillez contacter le marchand pour le traitement !",
|
||||
"TXT_CODE_f486dbb4": "Instance supprimée avec succès"
|
||||
}
|
||||
}
|
@ -1972,7 +1972,6 @@
|
||||
"TXT_CODE_60dd05d5": "デフォルトのイメージ作業ディレクトリをデータストレージディレクトリで上書きします",
|
||||
"TXT_CODE_6259357c": "プログラムは強制的に停止する前に 6 秒以上実行する必要があります。",
|
||||
"TXT_CODE_6c232c9c": "ホスト上の追加のフォルダーをコンテナーにマウントするために使用され、2 つの変数文字列をサポートします。",
|
||||
"TXT_CODE_708c10e2": "パッケージリスト",
|
||||
"TXT_CODE_75bf9192": "コードを使用する",
|
||||
"TXT_CODE_8028e95b": "パネルのユーザー名を入力してください。存在しない場合は新しいアカウントが作成されます",
|
||||
"TXT_CODE_8074a178": "新しい有効期限:",
|
||||
@ -2021,4 +2020,4 @@
|
||||
"TXT_CODE_a0e19f38": "インスタンスの削除",
|
||||
"TXT_CODE_ed81f72d": "このインスタンスはストアから購入されたものではないため、更新することはできません。処理については販売者にお問い合わせください。",
|
||||
"TXT_CODE_f486dbb4": "インスタンスは正常に削除されました"
|
||||
}
|
||||
}
|
@ -1972,7 +1972,6 @@
|
||||
"TXT_CODE_60dd05d5": "기본 이미지 작업 디렉터리를 데이터 저장소 디렉터리로 재정의",
|
||||
"TXT_CODE_6259357c": "프로그램을 강제로 중지하려면 6초 이상 실행되어야 합니다!",
|
||||
"TXT_CODE_6c232c9c": "호스트의 추가 폴더를 컨테이너에 마운트하는 데 사용되며 두 가지 변수 문자열을 지원합니다.",
|
||||
"TXT_CODE_708c10e2": "패키지 목록",
|
||||
"TXT_CODE_75bf9192": "코드 사용",
|
||||
"TXT_CODE_8028e95b": "패널 사용자 이름을 입력하세요. 존재하지 않는 경우 새 계정이 생성됩니다.",
|
||||
"TXT_CODE_8074a178": "새로운 만료일:",
|
||||
@ -2021,4 +2020,4 @@
|
||||
"TXT_CODE_a0e19f38": "인스턴스 삭제",
|
||||
"TXT_CODE_ed81f72d": "이 인스턴스는 상점에서 구매한 것이 아니므로 갱신할 수 없습니다. 처리하려면 판매자에게 문의하세요.",
|
||||
"TXT_CODE_f486dbb4": "인스턴스가 삭제되었습니다."
|
||||
}
|
||||
}
|
@ -1972,7 +1972,6 @@
|
||||
"TXT_CODE_60dd05d5": "Substituir o diretório de trabalho da imagem padrão pelo diretório de armazenamento de dados",
|
||||
"TXT_CODE_6259357c": "O programa deve ser executado por mais de 6 segundos antes de poder ser forçado a parar!",
|
||||
"TXT_CODE_6c232c9c": "Usado para montar pastas adicionais no host no contêiner, suporta duas strings variáveis:",
|
||||
"TXT_CODE_708c10e2": "Lista de pacotes",
|
||||
"TXT_CODE_75bf9192": "Usar código",
|
||||
"TXT_CODE_8028e95b": "Digite seu nome de usuário do painel, uma nova conta será criada se não existir",
|
||||
"TXT_CODE_8074a178": "Nova data de validade:",
|
||||
@ -2021,4 +2020,4 @@
|
||||
"TXT_CODE_a0e19f38": "Excluir instância",
|
||||
"TXT_CODE_ed81f72d": "Esta instância não foi comprada em uma loja e não pode ser renovada. Entre em contato com o comerciante para processamento!",
|
||||
"TXT_CODE_f486dbb4": "Instância excluída com sucesso"
|
||||
}
|
||||
}
|
@ -1972,7 +1972,6 @@
|
||||
"TXT_CODE_60dd05d5": "Переопределить рабочий каталог изображения по умолчанию каталогом хранения данных.",
|
||||
"TXT_CODE_6259357c": "Программа должна работать более 6 секунд, прежде чем ее можно будет принудительно остановить!",
|
||||
"TXT_CODE_6c232c9c": "Используется для монтирования дополнительных папок на хосте в контейнер, поддерживает две переменные строки:",
|
||||
"TXT_CODE_708c10e2": "Список пакетов",
|
||||
"TXT_CODE_75bf9192": "Использовать код",
|
||||
"TXT_CODE_8028e95b": "Введите имя пользователя вашей панели. Будет создана новая учетная запись, если она не существует.",
|
||||
"TXT_CODE_8074a178": "Новая дата истечения срока действия:",
|
||||
@ -2021,4 +2020,4 @@
|
||||
"TXT_CODE_a0e19f38": "Удалить экземпляр",
|
||||
"TXT_CODE_ed81f72d": "Этот экземпляр не был куплен в магазине и не может быть продлен. Пожалуйста, обратитесь к продавцу для обработки!",
|
||||
"TXT_CODE_f486dbb4": "Экземпляр успешно удален"
|
||||
}
|
||||
}
|
@ -1972,7 +1972,6 @@
|
||||
"TXT_CODE_60dd05d5": "Veri depolama dizini ile varsayılan görüntü çalışma dizinini geçersiz kıl",
|
||||
"TXT_CODE_6259357c": "Programın durmaya zorlanabilmesi için 6 saniyeden fazla çalışması gerekir!",
|
||||
"TXT_CODE_6c232c9c": "Ana makinedeki ek klasörleri konteynere eklemek için kullanılır, iki değişken dizeyi destekler:",
|
||||
"TXT_CODE_708c10e2": "Paket Listesi",
|
||||
"TXT_CODE_75bf9192": "Kodu Kullan",
|
||||
"TXT_CODE_8028e95b": "Panel kullanıcı adınızı girin, yoksa yeni hesap oluşturulacak",
|
||||
"TXT_CODE_8074a178": "Yeni Son Kullanma Tarihi:",
|
||||
@ -2021,4 +2020,4 @@
|
||||
"TXT_CODE_ed81f72d": "Bu örnek bir mağazadan satın alınmadı ve yenilenemiyor. İşleme için lütfen satıcıyla iletişime geçin!",
|
||||
"TXT_CODE_f486dbb4": "Örnek başarıyla silindi",
|
||||
"TXT_CODE_10088738": "Silmeyi onayla"
|
||||
}
|
||||
}
|
@ -1941,4 +1941,4 @@
|
||||
"TXT_CODE_6d8bc58d": "儲存失敗,單一標籤最多只支援9個字元!",
|
||||
"TXT_CODE_dc9fb6ce": "儲存失敗,單一實例最多只支援6個標籤!",
|
||||
"TXT_CODE_2082f659": "注意:如果此處為空,則不會綁定檔案管理中的檔案到容器中!"
|
||||
}
|
||||
}
|
@ -6,7 +6,8 @@
|
||||
"preview-build": "cd common && npm install && npm run build",
|
||||
"daemon": "cd daemon && npm run dev",
|
||||
"frontend": "cd frontend && npm run dev",
|
||||
"panel": "cd panel && npm run dev"
|
||||
"panel": "cd panel && npm run dev",
|
||||
"scan-useless-key": "node scripts/useless-key-scanner.mjs ./languages en_US.json . \".js,.ts,.vue,.tsx,.jsx\" \"node_modules/\""
|
||||
},
|
||||
"dependencies": {
|
||||
"crc": "^4.3.2",
|
||||
|
@ -19,27 +19,48 @@ class Database {
|
||||
keysMap = new Map();
|
||||
|
||||
/** @type {Object<string, string>} */
|
||||
sourceLangFile = {};
|
||||
sourceLangMap = {};
|
||||
|
||||
languageDir = "";
|
||||
|
||||
constructor(languageDir = "", languageSourceFileName = "") {
|
||||
this.sourceLangFile = JSON.parse(
|
||||
this.languageDir = languageDir;
|
||||
this.sourceLangMap = JSON.parse(
|
||||
fs.readFileSync(path.join(languageDir, languageSourceFileName), "utf-8")
|
||||
);
|
||||
for (const key in this.sourceLangFile) {
|
||||
for (const key in this.sourceLangMap) {
|
||||
this.keysMap.set(key, false);
|
||||
}
|
||||
}
|
||||
|
||||
rewriteSourceLangFile() {
|
||||
async rewriteSourceLangFile() {
|
||||
for (const [key, value] of this.keysMap) {
|
||||
if (!value) {
|
||||
delete this.sourceLangFile[key];
|
||||
delete this.sourceLangMap[key];
|
||||
}
|
||||
}
|
||||
console.log("Rewrite file:", path.join(LANGUAGE_DIR, LANGUAGE_SOURCE_FILE_NAME));
|
||||
fs.writeFileSync(
|
||||
path.join(LANGUAGE_DIR, LANGUAGE_SOURCE_FILE_NAME),
|
||||
JSON.stringify(this.sourceLangFile, null, 2)
|
||||
JSON.stringify(this.sourceLangMap, null, 2)
|
||||
);
|
||||
for (const filename of await fs.promises.readdir(this.languageDir)) {
|
||||
if (filename.endsWith(".json")) {
|
||||
const otherLangMap = JSON.parse(
|
||||
fs.readFileSync(path.join(this.languageDir, filename), "utf-8")
|
||||
);
|
||||
for (const key in otherLangMap) {
|
||||
if (!this.sourceLangMap[key]) {
|
||||
delete otherLangMap[key];
|
||||
}
|
||||
}
|
||||
console.log("Rewrite other lang file:", path.join(this.languageDir, filename));
|
||||
fs.writeFileSync(
|
||||
path.join(this.languageDir, filename),
|
||||
JSON.stringify(otherLangMap, null, 2)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,7 +106,7 @@ function startThread(langKeys, filesPath, database) {
|
||||
database.keysMap.set(data, true);
|
||||
}
|
||||
if (type === "exit") {
|
||||
console.log(`Thread ${data} scan finished!`);
|
||||
console.log(`Thread ID: ${data} \tScan finished!`);
|
||||
resolve(null);
|
||||
}
|
||||
});
|
||||
@ -96,7 +117,7 @@ async function mainThread() {
|
||||
console.log("process.argv:", process.argv);
|
||||
const database = new Database(LANGUAGE_DIR, LANGUAGE_SOURCE_FILE_NAME);
|
||||
const scannedFiles = await scanCodeFiles(CODE_DIR, [], EXCLUDE_FILES);
|
||||
|
||||
console.log(`Scanned files (${INCLUDE_EXT_NAMES}):`, scannedFiles.length);
|
||||
const promises = [];
|
||||
for (let i = 0; i < scannedFiles.length; i += CONCURRENT_COUNT) {
|
||||
const filesPath = scannedFiles.slice(i, i + CONCURRENT_COUNT);
|
||||
@ -104,9 +125,9 @@ async function mainThread() {
|
||||
}
|
||||
await Promise.all(promises);
|
||||
console.log("Rewrite source lang file...");
|
||||
database.rewriteSourceLangFile();
|
||||
await database.rewriteSourceLangFile();
|
||||
console.log("Rewrite source lang file finished!");
|
||||
const langDir = path.dirname(LANGUAGE_DIR);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
async function worker() {
|
||||
@ -115,14 +136,7 @@ async function worker() {
|
||||
/** @type {Map<string, boolean>} */
|
||||
const langKeys = workerData.langKeys;
|
||||
|
||||
console.log(
|
||||
"New Thread ID:",
|
||||
threadId,
|
||||
"Scan queue size:",
|
||||
filesPath.length,
|
||||
"Lang keys size:",
|
||||
langKeys.size
|
||||
);
|
||||
console.log("Create new thread ID:", threadId, "\tFiles:", filesPath.length);
|
||||
|
||||
async function readOneFile(filePath = "") {
|
||||
const fileContent = await fs.promises.readFile(filePath, "utf-8");
|
||||
|
Loading…
x
Reference in New Issue
Block a user