번역연습하다 알게된 Iavra_MZ_Localization_byNeomaStudio 플러그인으로된 게임 번역법(.jsono)
여기저기 뒤져봐도 번역방법이 안나와있는거 같아서 대략적으로 나마 가이드 라인 비슷한걸 써보려고 합니다 . (아마도 앵간한 대사들은 다 번역이 될것으로 사료됩니다. )
……………… 이미 있는 내용이라믄 내 3시간 돌려줘요…
대략적인 흐름은 …
1.번역할 파일들을 언패킹 해서 (node.js 와 단순한 코드를 활용해서)
2.파일들을 json으로 변환시키고 번역.
3.다시 언패킹해서 집어넣기
준비물 — node.js ,밑에 적어넣은 소스코드 ,저장시엔 utf-8로 저장
MV나 MZ 중 다국어 지원 게임들은 외부 플러그인으로 언어 파일들을 압축해놓은게 있었습니다. (.jsono)
마마노 오쿠니 토도쿠라는 게임인데, 요거를 예시로 설명해드리겠습니다. 요 게임같은경우 스타트를 누르면 일본어, 영어 , 중국어 3개를 지원하는데,
Iavra_MZ_Localization_byNeomaStudio 이 플러그인으로 로컬라이징을 했다는걸 알았습니다.
이 경우 mz 추출툴같은거로 대사 파일이 추출이 안돼더라구요. data의 파일들이 .jsono 로 되어있고 내부는 무려 base64 를 베이스로 한 암호화가 되어있습니다.
다른 데이터들은 일단 차차 생각하기로 하고…. 단순하게 로컬라이징 해서 패키징 되어있다 생각되는 애들이 있습니다.
1.lang - 랭귀지일테고 , 뒤에 en 까지 붙어있는것으로 보아 영어번역이 되어있는녀석들이고 이녀석들을 번역하면 될거같습니다. 일단 전부 복사해서 한 폴더에 집어넣어줍니다.
2.node.js를 다운로드 해서 설치해주세요. (LTS붙은거로 하면될겁니다.)
https://nodejs.org/ko/download
3.번역할 파일들을 복사한 폴더에서 우클릭 터미널을 열어줍니다.
터미널에 npm install lz-string 입력후 엔터.
- 이 시스템에서 스크립트…. 어쩌구 하는 오류가 뜬다면 , Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
입력후 엔터 그후 다시 위에 npm 어쩌구 입력.폴더 내에 메모장같은거 만들어서 converter.js 로 이름 및 확장자를 바꿔주고 메모장이나 노트패드++ 같은거로 열어서 아래 코드를 입력.
소스코드
const fs = require('fs');
const path = require('path');
const LZString = require('lz-string');
const currentDir = process.cwd();
console.log("==================================================");
console.log(" [Iavra 번역 파이프라인] 언팩/리팩 통합 모듈");
console.log("==================================================");
console.log(" [1] 언팩 (.jsono -> .json)");
console.log(" [2] 리팩 (.json -> .jsono)");
console.log("==================================================");
const readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
readline.question('선택: ', (choice) => {
if (choice === '1') runUnpack();
else if (choice === '2') runRepack();
else { console.log("종료"); process.exit(); }
});
// 1. 언팩 프로세스
function runUnpack() {
const files = fs.readdirSync(currentDir).filter(f => f.endsWith('.jsono'));
files.forEach(file => {
const raw = fs.readFileSync(path.join(currentDir, file), 'utf-8');
// N4WAU Base64 전용 필터링: 유효 문자 외 전부 제거
const clean = raw.replace(/[^A-Za-z0-9+/=]/g, '');
const decrypted = LZString.decompressFromBase64(clean);
if (decrypted) {
const outPath = path.join(currentDir, file.replace('.jsono', '.json'));
fs.writeFileSync(outPath, JSON.stringify(JSON.parse(decrypted), null, 4), 'utf-8');
console.log
[성공] 추출: ${file});} else {
console.log
[실패] 해독 불가: ${file});}
});
process.exit();
}
// 2. 리팩 프로세스
function runRepack() {
const targetDir = path.join(currentDir, 'repacking');
if (!fs.existsSync(targetDir)) fs.mkdirSync(targetDir);
const files = fs.readdirSync(currentDir).filter(f => f.endsWith('.json'));
files.forEach(file => {
const raw = fs.readFileSync(path.join(currentDir, file), 'utf-8');
// Base64 압축 봉인
const encrypted = LZString.compressToBase64(JSON.stringify(JSON.parse(raw)));
fs.writeFileSync(path.join(targetDir, file.replace('.json', '.jsono')), encrypted, 'utf-8');
console.log
[성공] 봉인: ${file});});
process.exit();
}
소스코드가 작동하지않을경우 이렇게 수정해주시면 됩니다. gorgon 님 감사합니다.
터미널에서 node converter.js 입력후 엔터 누르면 이렇게 나올겁니다. 1번 입력후 엔터를 누르면 폴더내의 파일들을 알아서 척척해줄겁니다.
그러면 이제 아래 사진같이 나올겁니다 . 하나를 열어보면 ….
h는 엣찌 대사였나 보군요. 이렇게 쭉 나옵니다. 확인하기 쉬운 파일을 찾아서( g 로 된게 글로벌이라 생각되니이걸로) 대충 번역해서 …
※utf-8로 저장해야합니다. 꼭!
그 후 다시 터미널에서 node converter.js 입력후 이번에는 2번을 선택하면, 자동으로 리패킹이라고 폴더를 만들고 거기에 저장됩니다.
안타깝게도 그냥 통째로 하는걸로만 만들어놔서 (자바는 잘 몰라서 제미나이를 이용했습니다. ㅎㅎ;) 전부 리패킹되서 폴더에 들어가 있을겁니다.
여기서 아까 번역한 lang_g 요것만 data로 옮겨서 게임을 실행해보믄…
명칭이랑 타이틀이 바뀐것을 확인할수 있습니다.
대략 번역할 파일들을 훑어본 결과는 저기있는 내용만 번역해도 이미지빼곤 전부 번역할수 있을거 같더라구요….
여담
번역 연습해보겠다고 게임하나 잡고 하다가 나중에는 오기가 생겨서 c++로 소스 열심히 짜다가 파싱부분에서 1차 멘붕 base64 만이 아니라는것에
2차 멘붕와서 제미나이랑 열심히 상담하다 js로 변환해달라고 해서 해봤는데 작동을 안해서 3차 멘붕 그후 내부파일 보여주니 그제서야 토해내더라구요.
저는 여기까지인것 같습니다.
긴글 읽어주셔서 감사하고 행복한 하루 되세요.
대략 ai 번역은 번역탭에 올려놨습니다 . 일단은 …. 나머지는 …. 글쎄요….
s/somisoft
• 157,564 subscribers- 1. 게시물 규정 양식
업로드 시 링크 암호화 & 필수 정보를 기입할 것
- 2. 질문
국룰, 암호화 링크 등 기본사항 질문 금지, 탭 미준수시 차단 및 삭제
- 3. 요청
요청 기준 및 양식 미준수 & 댓글로만 자료 복구 요청 시 차단
- 4. 미성년자 / 근첩 / 페미 / 다중계정
조금이라도 의심되면 선 차단, 후 해명
- 5. 좆목 / 네임드화
닉언, 네임드화 등 친목질 금지
- 6. 분탕 및 어그로 / 혐짤 / 낚시 / 뇌절
해당 카테고리의 차단 기간 및 가중처벌은 처리자 재량으로 판단
- 7. 홍보 / 판촉 / 거래
허용되지 않은 모든 형태의 홍보, 거래, 교환, 조건부 공유 시 차단
- 8. 쌀먹 / 바이러스
조건부 공유 & 수익성 링크 & 고의적인 바이러스 유포 시 갱신차단
- 9. 자료 분류 / AI
미검수 시 표기 필수, 생성형 AI를 사용한 자료의 제목에 AI 미기입 시 차단
- 10. 실사 / 토들러
업로드시 갱신 차단
- 11. 기타 세부 규정은 서브 공지사항 참고