DazedTL/modules/wolf.py

2701 lines
116 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Libraries
import json
import os
import re
import util.dazedwrap as dazedwrap
import threading
import time
import traceback
import tiktoken
# Removed concurrent.futures usage for simplicity; running synchronously
from pathlib import Path
from colorama import Fore
from dotenv import load_dotenv
from retry import retry
from tqdm import tqdm
from util.translation import TranslationConfig, translateAI as sharedtranslateAI, getPricingConfig, calculateCost, getPricingConfig, calculateCost
# OpenAI initialization centralized in util/translation.py
# Globals
MODEL = os.getenv("model")
TIMEOUT = int(os.getenv("timeout"))
LANGUAGE = os.getenv("language").capitalize()
from util.paths import PROMPT_PATH, VOCAB_PATH
PROMPT = PROMPT_PATH.read_text(encoding="utf-8")
VOCAB = VOCAB_PATH.read_text(encoding="utf-8")
LOCK = threading.Lock()
WIDTH = int(os.getenv("width"))
LISTWIDTH = int(os.getenv("listWidth"))
NOTEWIDTH = int(os.getenv("noteWidth"))
MAXHISTORY = 10
ESTIMATE = ""
TOKENS = [0, 0]
NAMESLIST = [] # Keep list for consistency
TERMSLIST = [] # Keep list for consistency
NAMES = False # Output a list of all the character names found
BRFLAG = False # If the game uses <br> instead
FIXTEXTWRAP = True # Overwrites textwrap
IGNORETLTEXT = False # Ignores all translated text.
MISMATCH = [] # Lists files that throw a mismatch error (Length of GPT list response is wrong)
FILENAME = None
BRACKETNAMES = False
# Regex - Need to change this if you want to translate from/to other languages. Default is Japanese Regex
LANGREGEX = r"[一-龠ぁ-ゔァ-ヴーa---\uFF61-\uFF9F]+"
# Get pricing configuration based on the model
PRICING_CONFIG = getPricingConfig(MODEL)
INPUTAPICOST = PRICING_CONFIG["inputAPICost"]
OUTPUTAPICOST = PRICING_CONFIG["outputAPICost"]
BATCHSIZE = PRICING_CONFIG["batchSize"]
FREQUENCY_PENALTY = PRICING_CONFIG["frequencyPenalty"]
# tqdm Globals
BAR_FORMAT = "{l_bar}{bar:10}{r_bar}{bar:-10b}"
POSITION = 0
LEAVE = False
PBAR = None
FILENAME = None
# Dialogue / Choices
CODE101 = False
CODE102 = False
# Picture
CODE150 = False
# Set String (Fragile but necessary)
CODE122 = False
# Other
CODE210 = False
CODE300 = False
CODE250 = False
# Database
SCENARIOFLAG = False
OPTIONSFLAG = True
NPCFLAG = False
DBNAMEFLAG = False
DBVALUEFLAG = False
ITEMFLAG = False
STATEFLAG = False
ENEMYFLAG = False
ARMORFLAG = False
WEAPONFLAG = False
SKILLFLAG = False
# Initialize Translation Config
TRANSLATION_CONFIG = TranslationConfig(
model=MODEL,
language=LANGUAGE,
prompt=PROMPT,
vocab=VOCAB,
langRegex=LANGREGEX,
batchSize=BATCHSIZE,
maxHistory=MAXHISTORY,
estimateMode=False # Will be set dynamically based on ESTIMATE
)
LEAVE = False
def handleWOLF(filename, estimate):
global ESTIMATE, TOKENS, FILENAME
ESTIMATE = estimate
FILENAME = filename
# Translate
start = time.time()
translatedData = openFiles(filename)
# Translate
if not estimate:
try:
with open("translated/" + filename, "w", encoding="utf-8", newline="\n") as outFile:
json.dump(translatedData[0], outFile, ensure_ascii=False, indent=4)
except Exception:
traceback.print_exc()
return "Fail"
# Print File
end = time.time()
tqdm.write(getResultString(translatedData, end - start, filename))
with LOCK:
TOKENS[0] += translatedData[1][0]
TOKENS[1] += translatedData[1][1]
# Print Total
totalString = getResultString(["", TOKENS, None], end - start, "TOTAL")
# Print any errors on maps
if len(MISMATCH) > 0:
return totalString + Fore.RED + f"\nMismatch Errors: {MISMATCH}" + Fore.RESET
else:
return totalString
def openFiles(filename):
with open("files/" + filename, "r", encoding="utf-8-sig") as f:
data = json.load(f)
# Map Files
if "'events':" in str(data):
if len(data["events"]) > 0:
translatedData = parseMap(data, filename)
else:
return [data, [0, 0], None]
# Map Files
elif "'types':" in str(data):
translatedData = parseDB(data, filename)
# Other Files
elif "'commands':" in str(data):
translatedData = parseOther(data, filename)
else:
raise NameError(filename + " Not Supported")
return translatedData
def getResultString(translatedData, translationTime, filename):
# File Print String
cost = calculateCost(translatedData[1][0], translatedData[1][1], MODEL)
totalTokenstring = (
Fore.YELLOW + "[Input: " + str(translatedData[1][0]) + "]"
"[Output: "
+ str(translatedData[1][1])
+ "]" "[Cost: ${:,.4f}".format(cost)
+ "]"
)
timeString = Fore.BLUE + "[" + str(round(translationTime, 1)) + "s]"
if translatedData[2] is None:
# Success
return filename + ": " + totalTokenstring + timeString + Fore.GREEN + " \u2713 " + Fore.RESET
else:
# Fail
try:
raise translatedData[2]
except Exception as e:
traceback.print_exc()
errorString = str(e) + Fore.RED
return filename + ": " + totalTokenstring + timeString + Fore.RED + " \u2717 " + errorString + Fore.RESET
def save_progress_json(data, filename):
"""Atomically write current JSON data to translated/filename; skip in estimate mode."""
try:
if ESTIMATE:
return
os.makedirs("translated", exist_ok=True)
tmp_path = os.path.join("translated", f"{filename}.tmp")
final_path = os.path.join("translated", filename)
with open(tmp_path, "w", encoding="utf-8", newline="\n") as outFile:
json.dump(data, outFile, ensure_ascii=False, indent=4)
os.replace(tmp_path, final_path)
except Exception:
traceback.print_exc()
def maybe_save_progress_json(data, filename, tokens):
"""Save JSON progress only when tokens indicate actual translation work."""
try:
if not tokens:
return
if isinstance(tokens, (list, tuple)) and len(tokens) >= 2 and (tokens[0] or tokens[1]):
save_progress_json(data, filename)
except Exception:
traceback.print_exc()
def parseOther(data, filename):
totalTokens = [0, 0]
totalLines = 0
events = data["commands"]
global LOCK
# Thread for each page in file
with tqdm(bar_format=BAR_FORMAT, position=POSITION, leave=LEAVE) as pbar:
pbar.desc = filename
pbar.total = totalLines
translationData = searchCodes(events, pbar, [], filename)
try:
totalTokens[0] += translationData[0]
totalTokens[1] += translationData[1]
except Exception as e:
return [data, totalTokens, e]
finally:
maybe_save_progress_json(data, filename, translationData)
return [data, totalTokens, None]
def parseDB(data, filename):
totalTokens = [0, 0]
totalLines = 0
events = data["types"]
global LOCK
# Thread for each page in file
with tqdm(bar_format=BAR_FORMAT, position=POSITION, leave=LEAVE) as pbar:
pbar.desc = filename
pbar.total = totalLines
translationData = searchDB(events, pbar, [], filename)
try:
totalTokens[0] += translationData[0]
totalTokens[1] += translationData[1]
except Exception as e:
return [data, totalTokens, e]
finally:
maybe_save_progress_json(data, filename, translationData)
return [data, totalTokens, None]
def parseMap(data, filename):
totalTokens = [0, 0]
totalLines = 0
events = data["events"]
global LOCK
# Get total for progress bar
for event in events:
if event is not None:
for page in event["pages"]:
totalLines += len(page["list"])
# Process pages synchronously and persist after each
with tqdm(bar_format=BAR_FORMAT, position=POSITION, total=totalLines, leave=LEAVE) as pbar:
pbar.desc = filename
pbar.total = totalLines
for event in events:
if event is not None:
for page in event["pages"]:
if page is not None:
try:
tt = searchCodes(page["list"], pbar, None, filename)
totalTokens[0] += tt[0]
totalTokens[1] += tt[1]
except Exception as e:
return [data, totalTokens, e]
finally:
maybe_save_progress_json(data, filename, tt)
return [data, totalTokens, None]
def searchCodes(events, pbar, jobList, filename):
# Lists
if jobList:
stringList = jobList[0]
list210 = jobList[1]
list300 = jobList[2]
list150 = jobList[3]
list250 = jobList[4]
list122 = jobList[5]
setData = True
else:
stringList = []
list210 = []
list300 = []
list150 = []
list250 = []
list122 = []
setData = False
# Other
codeList = events
textHistory = []
totalTokens = [0, 0]
translatedText = ""
speaker = ""
nametag = ""
initialJAString = ""
global LOCK, NAMESLIST, MISMATCH, PBAR, FILENAME
FILENAME = filename
PBAR = pbar
# Calculate Total Length
code_flags = {102: CODE102, 122: CODE122, 300: CODE300, 250: CODE250}
totalList = 0
for code_item in codeList:
if code_flags.get(code_item["code"], False):
totalList += 1
pbar.total = totalList
pbar.refresh()
# Begin Parsing File
try:
# Iterate through events
i = 0
while i < len(codeList):
### Event Code: 101 Message
if codeList[i]["code"] == 101 and CODE101 == True:
speakerRegex = r"@\d+\r?\n(.*?)?\r?\n" # Default: r"@\d+\r?\n(.*)?\r?\n""
textRegex = r"@\d+\r?\n.*??\r?\n(.*)" # Default: r"@\d+\r?\n.*?\r?\n(.*)"
# Alternative patterns for messages without @\d+ prefix
speakerRegexAlt = r"^(.*?)\r?\n" # Matches "Name\n"
textRegexAlt = r"^.*?\r?\n(.*)" # Matches text after "Name\n"
# Grab String
jaString = codeList[i]["stringArgs"][0]
speaker = ""
# Grab Speaker
if "\n" in jaString:
match = re.search(speakerRegex, jaString)
if not match:
# Try alternative pattern without @\d+ prefix
match = re.search(speakerRegexAlt, jaString)
if match:
# TL Speaker
response = getSpeaker(match.group(1))
speaker = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Set Name
codeList[i]["stringArgs"][0] = codeList[i]["stringArgs"][0].replace(match.group(1), speaker)
# Grab Only Text
match = re.search(textRegex, jaString, flags=re.DOTALL)
if not match:
# Try alternative pattern without @\d+ prefix
match = re.search(textRegexAlt, jaString, flags=re.DOTALL)
if not match and re.search(LANGREGEX, jaString):
# No speaker pattern found, treat entire string as text to translate
jaString = jaString
initialJAString = jaString
elif match:
jaString = match.group(1)
initialJAString = jaString
else:
jaString = None # Skip non-translatable text
if jaString is not None:
# Remove Textwrap
jaString = jaString.replace("\r", "")
jaString = jaString.replace("\n", " ")
# 1st Pass (Save Text to List)
if not setData:
if speaker == "":
stringList.append(jaString)
else:
stringList.append(f"[{speaker}]: {jaString}")
# 2nd Pass (Set Text)
else:
# Grab Translated String
translatedText = stringList[0]
# Remove speaker
matchSpeakerList = re.findall(r"^(\[.+?\]\s?[|:]\s?)\s?", translatedText)
if len(matchSpeakerList) > 0:
translatedText = translatedText.replace(matchSpeakerList[0], "")
# Textwrap
if FIXTEXTWRAP is True:
translatedText = dazedwrap.wrapText(translatedText, width=WIDTH)
# Set Data
codeList[i]["stringArgs"][0] = codeList[i]["stringArgs"][0].replace(initialJAString, translatedText)
# Reset Data and Pop Item
stringList.pop(0)
### Event Code: 102 Choices
if codeList[i]["code"] == 102 and CODE102 == True:
# Grab Choice List
choiceList = []
jaChoiceList = codeList[i]["stringArgs"]
# Filter Empty
for j in range(len(jaChoiceList)):
if jaChoiceList[j]:
choiceList.append(jaChoiceList[j])
# Translate
if 'jaString' in locals():
choiceString = f"Previous Line: {jaString}\n\nReply with the {LANGUAGE} translation of the dialogue choice"
else:
choiceString = f"Reply with the {LANGUAGE} translation of the dialogue choice"
response = translateAI(
choiceList,
choiceString,
True,
)
translatedChoiceList = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Validate and Set Data
if len(translatedChoiceList) == len(choiceList):
for j in range(len(jaChoiceList)):
if jaChoiceList[j]:
codeList[i]["stringArgs"][j] = translatedChoiceList[0]
translatedChoiceList.pop(0)
### Event Code: 210 Common Event
if codeList[i]["code"] == 210 and CODE210 == True:
# Speaker Event
if "stringArgs" in codeList[i] and codeList[i]["intArgs"][0] == None and len(codeList[i]["stringArgs"]) == 2:
response = getSpeaker(codeList[i]["stringArgs"][1])
totalTokens[1] += response[1][0]
totalTokens[1] += response[1][1]
# Set Data
codeList[i]["stringArgs"][1] = response[0]
# Logs
elif "stringArgs" in codeList[i] and codeList[i]["intArgs"][0] == 500725 and len(codeList[i]["stringArgs"]) == 2:
# Grab String
jaString = codeList[i]["stringArgs"][1]
initialJAString = jaString
# Remove Textwrap
jaString = jaString.replace("\r", "")
jaString = jaString.replace("\n", " ")
# 1st Pass (Save Text to List)
if not setData:
list210.append(jaString)
# 2nd Pass (Set Text)
else:
# Grab Translated String
translatedText = list210[0]
# Textwrap
if FIXTEXTWRAP is True:
translatedText = dazedwrap.wrapText(translatedText, width=WIDTH)
# Set Data
codeList[i]["stringArgs"][1] = translatedText
# Pop Item
list210.pop(0)
### Event Code: 122 SetString
if codeList[i]["code"] == 122 and CODE122 == True:
if "stringArgs" in codeList[i] and len(codeList[i]["stringArgs"]) > 0:
# Grab String
jaString = re.search(r"^\n?(.*)\n?$", codeList[i]["stringArgs"][0])
if jaString:
jaString = jaString.group(1)
else:
jaString = codeList[i]["stringArgs"][0]
originalString = jaString
# Remove Textwrap
jaString = jaString.replace("\r", "")
jaString = jaString.replace("\n", " ")
# Check if this is a translatable string
if (
not re.search(r"\.[\w]+$", jaString)
and jaString != ""
and "_" not in jaString
and '",' not in jaString
and "/" not in jaString
and re.search(LANGREGEX, jaString)
):
# 1st Pass (Save Text to List)
if not setData:
list122.append(jaString)
# 2nd Pass (Set Text)
else:
if len(list122) > 0:
# Grab Translated String
translatedText = list122[0]
# Textwrap
if FIXTEXTWRAP is True:
translatedText = dazedwrap.wrapText(translatedText, width=WIDTH)
# Set Data
codeList[i]["stringArgs"][0] = codeList[i]["stringArgs"][0].replace(originalString, translatedText)
# Pop Item
list122.pop(0)
### Event Code: 150 Picture String
if codeList[i]["code"] == 150 and CODE150 == True:
if "stringArgs" in codeList[i] and len(codeList[i]["stringArgs"]) > 0:
font150 = "\\f[8]"
# Grab String
jaString = codeList[i]["stringArgs"][0]
# Japanses Text Only
if not re.search(r"[一-龠ぁ-ゔァ-ヴーa---]+", jaString):
i += 1
continue
# Remove Textwrap
# jaString = jaString.replace("\n", " ")
# jaString = jaString.replace("\r", "")
# Translate Other Strings [Specific Files Only]
if (
not re.search(r"\.[\w]+$", jaString)
and jaString != ""
and "_" not in jaString
and '",' not in jaString
# and ">" not in jaString
# and "<" not in jaString
):
# Pass 1 (Save Text to List)
if not setData:
list150.append(jaString)
# Pass 2 (Set Text)
else:
translatedText = list150[0]
# Textwrap
# translatedText = dazedwrap.wrapText(translatedText, WIDTH)
# Set String with font formatting
codeList[i]["stringArgs"][0] = re.sub(r'\\f\[(\d+)\]', lambda x: f'\\f[{int(x.group(1))-2}]', translatedText)
# Pop processed item
list150.pop(0)
### Event Code: 300 Common Events
if codeList[i]["code"] == 300 and CODE300 == True and "stringArgs" in codeList[i] and len(codeList[i]["stringArgs"]) > 1:
# Choices
if codeList[i]["stringArgs"][0] == "[共]汎用ウィンドウ生成" or codeList[i]["stringArgs"][0] == "選択肢/確認":
# Grab String
choiceList = codeList[i]["stringArgs"][1].split(",")
# Translate Question
question = codeList[i]['stringArgs'][2]
response = translateAI(question, "Reply with the {LANGUAGE} translation")
translatedText = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Translate Question
jaString = translatedText
codeList[i]['stringArgs'][2] = translatedText
# Translate Choices
if 'jaString' in locals() and jaString:
response = translateAI(choiceList, jaString)
else:
response = translateAI(choiceList, f"Reply with the {LANGUAGE} translation of the dialogue choice")
choiceListTL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Replace Commas
for j in range(len(choiceListTL)):
choiceListTL[j] = choiceListTL[j].replace(", ", "")
# Convert to String and Set
translatedText = ",".join(choiceListTL)
codeList[i]["stringArgs"][1] = translatedText
# Dialogue
elif codeList[i]["stringArgs"][0] == "BTLメッセージ" or codeList[i]["stringArgs"][0] == "X[移]メニュー時文章表示":
jaString = codeList[i]["stringArgs"][1]
# Pass 1
if not setData:
# Remove Textwrap
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
# Append
list300.append(jaString)
# Pass 2
else:
# Add Textwrap and Font
translatedText = dazedwrap.wrapText(list300[0], WIDTH)
list300.pop(0)
# Write to File
codeList[i]["stringArgs"][1] = translatedText
# Dialogue
elif codeList[i]["stringArgs"][0] == "援護文章":
speakerRegex = r"@\d+\r?\n(.*)\r?\n" # Default: r"@\d+\r?\n(.*)\r?\n"
textRegex = r"@?\d*\r?\n?\u3000*([\w\W]+)\r?\n?" # Default: r"@?\d*\r?\n?\u3000*([\w\W]+)\r?\n?"
# Grab String
jaString = codeList[i]["stringArgs"][1]
speaker = ""
# Grab Speaker
if "\n" in jaString or "\r\n" in jaString:
match = re.search(speakerRegex, jaString)
if match:
# TL Speaker
response = getSpeaker(match.group(1))
speaker = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Set nametag and remove from string
codeList[i]["stringArgs"][1] = codeList[i]["stringArgs"][1].replace(match.group(1), speaker)
jaString = jaString.replace(match.group(0), "")
# Grab Only Text
match = re.search(textRegex, jaString)
if match:
jaString = match.group(1)
initialJAString = jaString
# Remove Textwrap
jaString = jaString.replace("\r", "")
jaString = jaString.replace("\n", " ")
# 1st Pass (Save Text to List)
if not setData:
if speaker == "":
list300.append(jaString)
else:
list300.append(f"[{speaker}]: {jaString}")
# 2nd Pass (Set Text)
else:
# Grab Translated String
translatedText = list300[0]
# Remove speaker
matchSpeakerList = re.findall(r"^(\[.+?\]\s?[|:]\s?)\s?", translatedText)
if len(matchSpeakerList) > 0:
translatedText = translatedText.replace(matchSpeakerList[0], "")
# Textwrap
if FIXTEXTWRAP is True:
translatedText = dazedwrap.wrapText(translatedText, width=WIDTH)
# Set Data
codeList[i]["stringArgs"][1] = codeList[i]["stringArgs"][1].replace(initialJAString, translatedText)
# Reset Data and Pop Item
list300.pop(0)
### Event Code: 250 DB Read/Writes
if codeList[i]["code"] == 250 and CODE250 == True:
# Validate size
stringArg = 0
if len(codeList[i]["stringArgs"]) == 4:
if codeList[i]["stringArgs"][1] == "万能ウィンドウ一時DB"\
and codeList[i]["stringArgs"][stringArg] != "":
# Font Size
fontSize = 0
# Grab String
jaString = codeList[i]["stringArgs"][stringArg]
# Remove Textwrap
# jaString = jaString.replace("\r", "")
# jaString = jaString.replace("\n", " ")
# Pass 1 (Save Text to List)
if not setData:
list250.append(jaString)
# Pass 2 (Set Text)
else:
translatedText = list250[0]
list250.pop(0)
# Textwrap
# translatedText = dazedwrap.wrapText(translatedText, WIDTH)
# Add/Replace font formatting
# Remove existing font command if present
translatedText = re.sub(r'\\f\[\d+\]', '', translatedText)
if fontSize:
# Add new font command if fontSize is not 0
if fontSize != "0" and fontSize != 0:
translatedText = f"\\f[{fontSize}]{translatedText}"
# Set Data
codeList[i]["stringArgs"][stringArg] = translatedText
### Iterate
i += 1
# EOF
stringListTL = []
list210TL = []
list150TL = []
list250TL = []
list300TL = []
list122TL = []
setData = False
# String List
if len(stringList) > 0:
pbar.total = len(stringList)
pbar.refresh()
response = translateAI(stringList, textHistory)
stringListTL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
if len(stringListTL) != len(stringList):
with LOCK:
if filename not in MISMATCH:
MISMATCH.append(filename)
else:
setData = True
# 210 List
if len(list210) > 0:
pbar.total = len(list210)
pbar.refresh()
response = translateAI(list210, textHistory)
list210TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
if len(list210TL) != len(list210):
with LOCK:
if filename not in MISMATCH:
MISMATCH.append(filename)
else:
setData = True
# 250 List
if len(list250) > 0:
pbar.total = len(list250)
pbar.refresh()
response = translateAI(list250, textHistory)
list250TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
if len(list250TL) != len(list250):
with LOCK:
if filename not in MISMATCH:
MISMATCH.append(filename)
else:
setData = True
# 300 List
if len(list300) > 0:
pbar.total = len(list300)
pbar.refresh()
response = translateAI(list300, textHistory)
list300TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
if len(list300TL) != len(list300):
with LOCK:
if filename not in MISMATCH:
MISMATCH.append(filename)
else:
setData = True
# 150 List
if len(list150) > 0:
# Progress Bar
pbar.total = len(list150)
pbar.refresh()
# Translate
response = translateAI(
list150,
textHistory,
True,
)
list150TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Check Mismatch
if len(list150TL) != len(list150):
with LOCK:
if filename not in MISMATCH:
MISMATCH.append(filename)
else:
list150 = list150TL
setData = True
# 122 List
if len(list122) > 0:
pbar.total = len(list122)
pbar.refresh()
response = translateAI(list122, textHistory)
list122TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
if len(list122TL) != len(list122):
with LOCK:
if filename not in MISMATCH:
MISMATCH.append(filename)
else:
setData = True
# Update jobList before recursive call
if setData == True:
stringList = []
jobList = [stringListTL, list210TL, list300TL, list150TL, list250TL, list122TL] # Add list122TL
searchCodes(events, pbar, jobList, filename)
else:
# Set Data
events = codeList
except IndexError as e:
traceback.print_exc()
raise Exception(str(e) + "Failed to translate: " + initialJAString) from None
except Exception as e:
traceback.print_exc()
raise Exception(str(e) + "Failed to translate: " + initialJAString) from None
return totalTokens
def formatDramon(jaString):
imageRegex = r"(\r?\n?_[a-zA-Z_\d/.]+\r?\n?)|(@-?\d?\r\n)|(@-?\d?)([^\r]\d?-?\d?[^\r]+?)(\r\n|$)|(_PDC)|(>\r\n)|(^[#])|(\r\n@$)|(/)|(_SS_)|(\r\n[@/]\s?-?\d?\r\n)"
jaString = jaString.replace("\u3000", " ")
jaString = jaString.replace("#", "")
jaString = re.sub(r"([^\r])\n", r"\1\r\n", jaString)
# Grab and Split
jaStringList = re.split(imageRegex, jaString)
# Clean List
cleanedList = [x for x in jaStringList if x is not None and x != "" and x != "\r\n" and x != "_SS_"]
# Iterate Through List
j = 0
translatedText = ""
while j < len(cleanedList):
if (
("@" in cleanedList[j] or "/" in cleanedList[j])
and j < len(cleanedList) - 1
and re.search(r"([@/]-?\d?\r\n)", cleanedList[j]) is None
and ".ogg" not in cleanedList[j]
):
# Setup @
if j > 0 and "@" not in cleanedList[j - 1] and "/" not in cleanedList[j - 1] and "_" not in cleanedList[j - 1]:
cleanedList[j - 1] = cleanedList[j - 1] + cleanedList[j + 1]
else:
cleanedList.insert(j, cleanedList[j + 1])
j += 1
cleanedList[j] = f"\r\n{cleanedList[j]}\r\n"
cleanedList.pop(j + 1)
j += 1
return cleanedList
def handleScenarioScript(jaString, scriptString=""):
# Extract Speaker
# Updated regex to match speaker names with spaces, hyphens, and other characters
# [^\n]+ matches any character except newline and (the speaker name)
scriptRegex = r"\n?(//.*?\n|//.*|/b.*?\n|[^\n]+\d*\r?\n)"
match = re.search(scriptRegex, jaString)
if match:
if "//" in match.group(1):
scriptStringLocal = match.group(1)
jaString = jaString.replace(scriptStringLocal, "")
scriptString += scriptStringLocal
match = re.search(scriptRegex, jaString)
if not match:
return None
else:
if "//" in jaString:
return handleScenarioScript(jaString, scriptString)
return [jaString, match.group(1), scriptString]
else:
return None
# Database
def searchDB(events, pbar, jobList, filename):
# Set Lists
if len(jobList) > 0:
scenarioList = jobList[0]
npcList = jobList[1]
itemList = jobList[2]
stateList = jobList[3]
armorList = jobList[4]
enemyList = jobList[5]
weaponsList = jobList[6]
skillList = jobList[7]
optionsList = jobList[8]
dbNameList = jobList[9]
dbValueList = jobList[10]
setData = True
else:
scenarioList = [[], [], []]
npcList = [[], [], [], []]
itemList = [[], [], [], []]
armorList = [[], []]
enemyList = [[], []]
weaponsList = [[], [], [], []]
skillList = [[], [], [], [], []]
stateList = [[], [], [], [], [], [], [], []]
optionsList = [[], [], []]
dbNameList = [[]]
dbValueList = [[]]
setData = False
# Vars/Globals
totalTokens = [0, 0]
initialJAString = ""
tableList = events
font = ""
global LOCK
global NAMESLIST
global MISMATCH
global PBAR
PBAR = pbar
# Begin Parsing File
try:
for table in tableList:
# Grab NPCs
if table["name"] == "アイドル" and NPCFLAG == True:
with open("log/translations.txt", "a", encoding="utf-8") as file:
if setData:
file.write(f"\n#Actors\n")
for npc in table["data"]:
dataList = npc["data"]
# Parse
for j in range(len(dataList)):
# Name
if dataList[j].get("name") == "出身":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
npcList[0].append(dataList[j].get("value"))
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
# Write Name
file.write(f"{dataList[j].get('value')} ({npcList[0][0]})\n")
# Set Data
dataList[j].update({"value": npcList[0][0]})
npcList[0].pop(0)
# Description
if dataList[j].get("name") == "説明":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
# Remove Textwrap
jaString = dataList[j].get("value")
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
jaString = re.sub(r"[\\]+f\[\d+\]", "", jaString)
# Append Data
npcList[1].append(jaString)
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
# Textwrap
translatedText = npcList[1][0]
translatedText = dazedwrap.wrapText(translatedText, LISTWIDTH)
translatedText = font + translatedText
# Set Data
dataList[j].update({"value": translatedText})
npcList[1].pop(0)
# Grab Scenario
if "デートキャラ" in table["name"] and SCENARIOFLAG == True:
for scenario in table["data"]:
dataList = scenario["data"]
# Parse
for j in range(len(dataList)):
# Name
if dataList[j].get("name") == "NULL":
if dataList[j].get("value"):
jaStringList = re.split(r'\r\n\r\n|\n\n', dataList[j].get("value"))
for jaString in jaStringList:
speakerNum = None
ogString = jaString
# Extract Speaker
speakerList = handleScenarioScript(jaString)
# Handle simple names without speaker pattern
if not speakerList:
# Pass 1 (Grab Data) - Simple name
if setData == False:
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
if jaString.strip():
scenarioList[0].append(jaString)
# Pass 2 (Set Data) - Simple name
else:
if ogString.strip():
translatedText = scenarioList[0][0]
scenarioList[0].pop(0)
dataList[j].update({"value": dataList[j].get("value").replace(ogString, translatedText)})
continue
if speakerList[2]:
jaString = speakerList[0]
speakerNumMatch = re.search(r"(\d+)", speakerList[1])
if speakerNumMatch:
speakerNum = speakerNumMatch.group(1)
speaker = re.sub(r"\d*", "", speakerList[1])
speaker = re.sub(r"/b", "NPC", speaker)
speaker = speaker.replace("\r\n", "")
# Add Speaker
jaString = jaString.replace(speakerList[1], f"[{speaker}]: ")
# Pass 1 (Grab Data)
if setData == False:
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
scenarioList[0].append(jaString)
# Pass 2 (Set Data)
else:
translatedText = scenarioList[0][0]
scenarioList[0].pop(0)
# Remove Speaker before wrapping so WIDTH applies to dialogue only
speakerMatch = re.search(r"\[(.+?)\]\s?[|:]\s?", translatedText)
if speakerMatch:
speaker = speakerMatch.group(1).strip()
match = re.search(r'(^\[.+?\]\s?[|:]\s?)', translatedText)
if match:
translatedText = translatedText.replace(match.group(1), "")
# Wrap text after removing speaker
translatedText = dazedwrap.wrapText(translatedText, WIDTH)
# Redo Old Speaker Format
speaker = speaker.replace("Speaker", "\b")
if speakerNum:
translatedText = f"{speaker}{speakerNum}\r\n{translatedText}"
elif speaker == "NPC":
translatedText = f"/b\r\n{translatedText}"
else:
translatedText = f"{speaker}\r\n{translatedText}"
# Add Script String
if speakerList[2]:
translatedText = f"{speakerList[2]}{translatedText}"
# Set Data
dataList[j].update({"value": dataList[j].get("value").replace(ogString, translatedText)})
# Description
if dataList[j].get("name") == "不正解会話":
if dataList[j].get("value"):
jaStringList = re.split(r'\r\n\r\n|\n\n', dataList[j].get("value"))
for jaString in jaStringList:
speakerNum = None
ogString = jaString
# Extract Speaker
speakerList = handleScenarioScript(jaString)
# Handle simple text without speaker pattern
if not speakerList:
# Pass 1 (Grab Data) - Simple text
if setData == False:
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
if jaString.strip():
scenarioList[1].append(jaString)
# Pass 2 (Set Data) - Simple text
else:
if ogString.strip():
translatedText = scenarioList[1][0]
scenarioList[1].pop(0)
translatedText = dazedwrap.wrapText(translatedText, WIDTH)
dataList[j].update({"value": dataList[j].get("value").replace(ogString, translatedText)})
continue
if speakerList[2]:
jaString = speakerList[0]
speakerNumMatch = re.search(r"(\d+)", speakerList[1])
if speakerNumMatch:
speakerNum = speakerNumMatch.group(1)
speaker = re.sub(r"\d*", "", speakerList[1])
speaker = re.sub(r"/b", "NPC", speaker)
speaker = speaker.replace("\r\n", "")
# Add Speaker
jaString = jaString.replace(speakerList[1], f"[{speaker}]: ")
# Pass 1 (Grab Data)
if setData == False:
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
scenarioList[1].append(jaString)
# Pass 2 (Set Data)
else:
translatedText = scenarioList[1][0]
scenarioList[1].pop(0)
# Remove Speaker before wrapping so WIDTH applies to dialogue only
speakerMatch = re.search(r"\[(.+?)\]\s?[|:]\s?", translatedText)
if speakerMatch:
speaker = speakerMatch.group(1).strip()
match = re.search(r'(^\[.+?\]\s?[|:]\s?)', translatedText)
if match:
translatedText = translatedText.replace(match.group(1), "")
# Wrap text after removing speaker
translatedText = dazedwrap.wrapText(translatedText, WIDTH)
# Redo Old Speaker Format
speaker = speaker.replace("Speaker", "\b")
if speakerNum:
translatedText = f"{speaker}{speakerNum}\r\n{translatedText}"
elif speaker == "NPC":
translatedText = f"/b\r\n{translatedText}"
else:
translatedText = f"{speaker}\r\n{translatedText}"
# Add Script String
if speakerList[2]:
translatedText = f"{speakerList[2]}{translatedText}"
# Set Data
dataList[j].update({"value": dataList[j].get("value").replace(ogString, translatedText)})
# Description
if dataList[j].get("name") == "正解会話":
if dataList[j].get("value"):
jaStringList = re.split(r'\r\n\r\n|\n\n', dataList[j].get("value"))
for jaString in jaStringList:
speakerNum = None
ogString = jaString
# Extract Speaker
speakerList = handleScenarioScript(jaString)
# Handle simple text without speaker pattern
if not speakerList:
# Pass 1 (Grab Data) - Simple text
if setData == False:
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
if jaString.strip():
scenarioList[2].append(jaString)
# Pass 2 (Set Data) - Simple text
else:
if ogString.strip():
translatedText = scenarioList[2][0]
scenarioList[2].pop(0)
translatedText = dazedwrap.wrapText(translatedText, WIDTH)
dataList[j].update({"value": dataList[j].get("value").replace(ogString, translatedText)})
continue
if speakerList[2]:
jaString = speakerList[0]
speakerNumMatch = re.search(r"(\d+)", speakerList[1])
if speakerNumMatch:
speakerNum = speakerNumMatch.group(1)
speaker = re.sub(r"\d*", "", speakerList[1])
speaker = re.sub(r"/b", "NPC", speaker)
speaker = speaker.replace("\r\n", "")
# Add Speaker
jaString = jaString.replace(speakerList[1], f"[{speaker}]: ")
# Pass 1 (Grab Data)
if setData == False:
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
scenarioList[2].append(jaString)
# Pass 2 (Set Data)
else:
translatedText = scenarioList[2][0]
scenarioList[2].pop(0)
# Remove Speaker before wrapping so WIDTH applies to dialogue only
speakerMatch = re.search(r"\[(.+?)\]\s?[|:]\s?", translatedText)
if speakerMatch:
speaker = speakerMatch.group(1).strip()
match = re.search(r'(^\[.+?\]\s?[|:]\s?)', translatedText)
if match:
translatedText = translatedText.replace(match.group(1), "")
# Wrap text after removing speaker
translatedText = dazedwrap.wrapText(translatedText, WIDTH)
# Redo Old Speaker Format
speaker = speaker.replace("Speaker", "\b")
if speakerNum:
translatedText = f"{speaker}{speakerNum}\r\n{translatedText}"
elif speaker == "NPC":
translatedText = f"/b\r\n{translatedText}"
else:
translatedText = f"{speaker}\r\n{translatedText}"
# Add Script String
if speakerList[2]:
translatedText = f"{speakerList[2]}{translatedText}"
# Set Data
dataList[j].update({"value": dataList[j].get("value").replace(ogString, translatedText)})
# Grab Options
if table["name"] == "クイズ" and OPTIONSFLAG == True:
for option in table["data"]:
dataList = option["data"]
# Parse
for j in range(len(dataList)):
# Name
if dataList[j].get("name") == "":
if dataList[j].get("value"):
jaString = dataList[j].get("value")
# Pass 1 (Grab Data)
if setData == False:
optionsList[0].append(jaString)
# Pass 2 (Set Data)
else:
translatedText = optionsList[0][0]
optionsList[0].pop(0)
dataList[j].update({"value": dataList[j].get("value").replace(jaString, translatedText)})
# Description 1
if dataList[j].get("name") == "3":
if dataList[j].get("value"):
jaString = dataList[j].get("value")
# Pass 1 (Grab Data)
if setData == False:
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
optionsList[1].append(jaString)
# Pass 2 (Set Data)
else:
translatedText = optionsList[1][0]
optionsList[1].pop(0)
translatedText = dazedwrap.wrapText(translatedText, LISTWIDTH)
dataList[j].update({"value": dataList[j].get("value").replace(jaString, translatedText)})
# Description 2
if dataList[j].get("name") == "4":
if dataList[j].get("value"):
jaString = dataList[j].get("value")
# Pass 1 (Grab Data)
if setData == False:
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
optionsList[2].append(jaString)
# Pass 2 (Set Data)
else:
translatedText = optionsList[2][0]
optionsList[2].pop(0)
translatedText = dazedwrap.wrapText(translatedText, LISTWIDTH)
dataList[j].update({"value": dataList[j].get("value").replace(jaString, translatedText)})
# Grab DB Names
if table["name"] == "マップ設定" and DBNAMEFLAG == True:
font = None
dbName = table["data"]
for j in range(len(dbName)):
# Pass 1 (Grab Data)
if setData == False:
if dbName[j].get("name") != "":
dbNameList[0].append(dbName[j].get("name"))
# Pass 2 (Set Data)
else:
if dbName[j].get("name") != "":
dbName[j].update({"name": dbNameList[0][0]})
dbNameList[0].pop(0)
# Grab DB Values
if table["name"] == "近況文章" and DBVALUEFLAG == True:
font = 16
subject = ""
for entry in table["data"]:
dbValue = entry["data"]
for j in range(len(dbValue)):
if dbValue[j].get("value"):
jaString = dbValue[j].get("value")
# Speaker
match = re.search(r"(^[\\]+f\[\d+\].+?\r\n).+", jaString)
if match:
subject = match.group(1)
jaString = jaString.replace(subject, "")
# Nuke Textwrap & Font
jaString = jaString.replace("\r", "")
jaString = jaString.replace("\n", " ")
jaString = re.sub(r"[\\]+f\[\d+\]", "", jaString)
# Pass 1 (Grab Data)
if setData == False:
# Append
dbValueList[0].append(jaString)
# Pass 2 (Set Data)
else:
if dbValue[j].get("value"):
translatedText = dbValueList[0][0]
# Textwrap
translatedText = dazedwrap.wrapText(translatedText, 30)
translatedText = translatedText.replace("\n", f"\r\n\\f[{font}]")
# Subject
if subject:
translatedText = f"{subject}{translatedText}"
# Set
dbValue[j].update({"value": translatedText})
dbValueList[0].pop(0)
# Grab Items
if table["name"] == "道具" and ITEMFLAG == True:
# Write Category
if setData:
with open("log/translations.txt", "a", encoding="utf-8") as file:
file.write(f"\n#Items\n")
# Begin Translation
for item in table["data"]:
dataList = item["data"]
# Parse
font = 18
for j in range(len(dataList)):
# Name
if dataList[j].get("name") == "名前":
jaString = dataList[j].get("value")
if jaString != "":
# Pass 1 (Grab Data)
if setData == False:
if jaString != "":
itemList[0].append(jaString)
# Pass 2 (Set Data)
else:
# Write to TL File
with open("log/translations.txt", "a", encoding="utf-8") as file:
file.write(f"{jaString} ({itemList[0][0]})\n")
dataList[j].update({"value": itemList[0][0]})
itemList[0].pop(0)
# Description
if dataList[j].get("name") == "説明":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
# Remove Textwrap & Font
jaString = dataList[j].get("value")
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
jaString = re.sub(r"[\\]+f\[\d+\]", "", jaString)
# Append Data
itemList[1].append(jaString)
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
# Textwrap
translatedText = itemList[1][0]
translatedText = dazedwrap.wrapText(translatedText, LISTWIDTH)
# Font
if font:
translatedText = f"\\f[{font}]{translatedText}"
# Set Data
dataList[j].update({"value": translatedText})
itemList[1].pop(0)
# Log
if dataList[j].get("name") == "使用時文章[戦](人名~":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
# Remove Textwrap
jaString = dataList[j].get("value")
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
jaString = re.sub(r"[\\]+f\[\d+\]", "", jaString)
# Skill Action
if jaString[0] in [
"",
"",
"",
"",
"",
]:
jaString = f"Taro{jaString}"
# Append Data
itemList[2].append(jaString)
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
# Textwrap
translatedText = itemList[2][0]
translatedText = dazedwrap.wrapText(translatedText, LISTWIDTH)
# translatedText = font + translatedText
# Remove Taro
translatedText = re.sub(r"\bTaro\b", "", translatedText)
# Set Data
dataList[j].update({"value": translatedText})
itemList[2].pop(0)
# Description
if dataList[j].get("name") == "使用後文章[移動]":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
# Remove Textwrap
jaString = dataList[j].get("value")
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
jaString = re.sub(r"[\\]+f\[\d+\]", "", jaString)
# Append Data
itemList[3].append(jaString)
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
# Textwrap
translatedText = itemList[3][0]
translatedText = dazedwrap.wrapText(translatedText, LISTWIDTH)
# Font
if font:
translatedText = f"\\f[{font}]{translatedText}"
# Set Data
dataList[j].update({"value": translatedText})
itemList[3].pop(0)
# Grab Armors
if table["name"] == "防具" and ARMORFLAG == True:
font = "24"
for armor in table["data"]:
dataList = armor["data"]
# Parse
for j in range(len(dataList)):
# Name
if dataList[j].get("name") == "名前":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
armorList[0].append(dataList[j].get("value"))
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
dataList[j].update({"value": armorList[0][0]})
armorList[0].pop(0)
# Description
if dataList[j].get("name") == "説明":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
# Remove Textwrap
jaString = dataList[j].get("value")
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
jaString = re.sub(r"[\\]+f\[\d+\]", "", jaString)
# Append Data
armorList[1].append(jaString)
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
# Textwrap
translatedText = armorList[1][0]
translatedText = dazedwrap.wrapText(translatedText, LISTWIDTH)
# Font
if font:
translatedText = f"\\f[{font}]{translatedText}"
# Set Data
dataList[j].update({"value": translatedText})
armorList[1].pop(0)
# Grab Enemies
if table["name"] == "" and ENEMYFLAG == True:
for enemy in table["data"]:
dataList = enemy["data"]
# Parse
for j in range(len(dataList)):
# Name
if dataList[j].get("name") == "敵キャラ名":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
enemyList[0].append(dataList[j].get("value"))
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
dataList[j].update({"value": enemyList[0][0]})
enemyList[0].pop(0)
# Description
if dataList[j].get("name") == "NULL":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
# Remove Textwrap
jaString = dataList[j].get("value")
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
jaString = re.sub(r"[\\]+f\[\d+\]", "", jaString)
# Append Data
enemyList[1].append(jaString)
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
# Textwrap
translatedText = enemyList[1][0]
translatedText = dazedwrap.wrapText(translatedText, LISTWIDTH)
# Font
if font:
translatedText = f"\\f[{font}]{translatedText}"
# Set Data
dataList[j].update({"value": translatedText})
enemyList[1].pop(0)
# Grab Weapons
if table["name"] == "武器" and WEAPONFLAG == True:
font = "24"
for weapon in table["data"]:
dataList = weapon["data"]
# Parse
for j in range(len(dataList)):
# Name
if dataList[j].get("name") == "名前":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
weaponsList[0].append(dataList[j].get("value"))
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
dataList[j].update({"value": weaponsList[0][0]})
weaponsList[0].pop(0)
# Description
if dataList[j].get("name") == "説明":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
# Remove Textwrap
jaString = dataList[j].get("value")
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
jaString = re.sub(r"[\\]+f\[\d+\]", "", jaString)
# Append Data
weaponsList[1].append(jaString)
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
# Textwrap
translatedText = weaponsList[1][0]
translatedText = dazedwrap.wrapText(translatedText, LISTWIDTH)
# Font
if font:
translatedText = f"\\f[{font}]{translatedText}"
# Set Data
dataList[j].update({"value": translatedText})
weaponsList[1].pop(0)
# Grab Skills
if table["name"] == "技能" and SKILLFLAG == True:
font = "24"
for skill in table["data"]:
dataList = skill["data"]
# Parse
for j in range(len(dataList)):
# Name
if dataList[j].get("name") == "名前":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
skillList[0].append(dataList[j].get("value"))
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
dataList[j].update({"value": skillList[0][0]})
skillList[0].pop(0)
# Description
if dataList[j].get("name") == "説明":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
# Remove Textwrap
jaString = dataList[j].get("value")
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
jaString = re.sub(r"[\\]+f\[\d+\]", "", jaString)
# Append Data
skillList[1].append(jaString)
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
# Textwrap
translatedText = skillList[1][0]
translatedText = dazedwrap.wrapText(translatedText, LISTWIDTH)
# Font
if font:
translatedText = f"\\f[{font}]{translatedText}"
# Set Data
dataList[j].update({"value": translatedText})
skillList[1].pop(0)
# Log
if dataList[j].get("name") == "発動時文章":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
# Remove Textwrap
jaString = dataList[j].get("value")
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
jaString = re.sub(r"[\\]+f\[\d+\]", "", jaString)
# Skill Action
if jaString[0] in [
"",
"",
"",
"",
"",
]:
jaString = f"Taro{jaString}"
# Append Data
skillList[2].append(jaString)
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
# Textwrap
translatedText = skillList[2][0]
translatedText = dazedwrap.wrapText(translatedText, LISTWIDTH)
translatedText = font + translatedText
# Remove Taro
translatedText = re.sub(r"\bTaro\b", "", translatedText)
# Set Data
dataList[j].update({"value": translatedText})
skillList[2].pop(0)
# Log
if dataList[j].get("name") == "使用時文章[戦闘](人名~":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
# Remove Textwrap
jaString = dataList[j].get("value")
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
jaString = re.sub(r"[\\]+f\[\d+\]", "", jaString)
# Skill Action
if jaString[0] in [
"",
"",
"",
"",
"",
]:
jaString = f"Taro{jaString}"
# Append Data
skillList[3].append(jaString)
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
# Textwrap
translatedText = skillList[3][0]
translatedText = dazedwrap.wrapText(translatedText, LISTWIDTH)
# Remove Taro
translatedText = re.sub(r"\bTaro\b", "", translatedText)
# Font
translatedText = font + translatedText
# Set Data
dataList[j].update({"value": translatedText})
skillList[3].pop(0)
# Log
if dataList[j].get("name") == "失敗時文章[(対象)]":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
# Remove Textwrap
jaString = dataList[j].get("value")
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
jaString = re.sub(r"[\\]+f\[\d+\]", "", jaString)
# Skill Action
if jaString[0] in [
"",
"",
"",
"",
"",
]:
jaString = f"Taro{jaString}"
# Append Data
skillList[4].append(jaString)
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
# Textwrap
translatedText = skillList[4][0]
translatedText = dazedwrap.wrapText(translatedText, LISTWIDTH)
translatedText = font + translatedText
# Remove Taro
translatedText = re.sub(r"\bTaro\b", "", translatedText)
# Set Data
dataList[j].update({"value": translatedText})
skillList[4].pop(0)
# Grab States
if table["name"] == "ステート" and STATEFLAG == True:
for state in table["data"]:
dataList = state["data"]
# Parse
for j in range(len(dataList)):
# Name
if dataList[j].get("name") == "名前":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
stateList[0].append(dataList[j].get("value"))
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
dataList[j].update({"value": stateList[0][0]})
stateList[0].pop(0)
# Description
if dataList[j].get("name") == "表示名":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
# Remove Textwrap
jaString = dataList[j].get("value")
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
jaString = re.sub(r"[\\]+f\[\d+\]", "", jaString)
# Append Data
stateList[1].append(jaString)
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
# Textwrap
translatedText = stateList[1][0]
translatedText = dazedwrap.wrapText(translatedText, LISTWIDTH)
translatedText = font + translatedText
# Set Data
dataList[j].update({"value": translatedText})
stateList[1].pop(0)
# Log
if dataList[j].get("name") == "付与時文章":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
# Remove Textwrap
jaString = dataList[j].get("value")
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
jaString = re.sub(r"[\\]+f\[\d+\]", "", jaString)
# State Action
if jaString[0] in [
"",
"",
"",
"",
"",
]:
jaString = f"Taro{jaString}"
# Append Data
stateList[2].append(jaString)
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
# Textwrap
translatedText = stateList[2][0]
translatedText = dazedwrap.wrapText(translatedText, LISTWIDTH)
translatedText = font + translatedText
# Remove Taro
translatedText = re.sub(r"\bTaro\b", "", translatedText)
# Set Data
dataList[j].update({"value": translatedText})
stateList[2].pop(0)
# Log
if dataList[j].get("name") == "解除時文章":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
# Remove Textwrap
jaString = dataList[j].get("value")
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
jaString = re.sub(r"[\\]+f\[\d+\]", "", jaString)
# State Action
if jaString[0] in [
"",
"",
"",
"",
"",
]:
jaString = f"Taro{jaString}"
# Append Data
stateList[3].append(jaString)
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
# Textwrap
translatedText = stateList[3][0]
translatedText = dazedwrap.wrapText(translatedText, LISTWIDTH)
translatedText = font + translatedText
# Remove Taro
translatedText = re.sub(r"\bTaro\b", "", translatedText)
# Set Data
dataList[j].update({"value": translatedText})
stateList[3].pop(0)
# Log
if dataList[j].get("name") == "回復時の文章[(人名)]":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
# Remove Textwrap
jaString = dataList[j].get("value")
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
jaString = re.sub(r"[\\]+f\[\d+\]", "", jaString)
# State Action
if jaString[0] in [
"",
"",
"",
"",
"",
]:
jaString = f"Taro{jaString}"
# Append Data
stateList[4].append(jaString)
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
# Textwrap
translatedText = stateList[4][0]
translatedText = dazedwrap.wrapText(translatedText, LISTWIDTH)
translatedText = font + translatedText
# Remove Taro
translatedText = re.sub(r"\bTaro\b", "", translatedText)
# Set Data
dataList[j].update({"value": translatedText})
stateList[4].pop(0)
# Log
if dataList[j].get("name") == "┣ カウンター発動文[対象~":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
# Remove Textwrap
jaString = dataList[j].get("value")
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
jaString = re.sub(r"[\\]+f\[\d+\]", "", jaString)
# State Action
if jaString[0] in [
"",
"",
"",
"",
"",
]:
jaString = f"Taro{jaString}"
# Append Data
stateList[5].append(jaString)
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
# Textwrap
translatedText = stateList[5][0]
translatedText = dazedwrap.wrapText(translatedText, LISTWIDTH)
translatedText = font + translatedText
# Remove Taro
translatedText = re.sub(r"\bTaro\b", "", translatedText)
# Set Data
dataList[j].update({"value": translatedText})
stateList[5].pop(0)
# Log
if dataList[j].get("name") == "尻もち 行動不能 持続3ターン":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
# Remove Textwrap
jaString = dataList[j].get("value")
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
jaString = re.sub(r"[\\]+f\[\d+\]", "", jaString)
# State Action
if jaString[0] in [
"",
"",
"",
"",
"",
]:
jaString = f"Taro{jaString}"
# Append Data
stateList[6].append(jaString)
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
# Textwrap
translatedText = stateList[6][0]
translatedText = dazedwrap.wrapText(translatedText, LISTWIDTH)
translatedText = font + translatedText
# Remove Taro
translatedText = re.sub(r"\bTaro\b", "", translatedText)
# Set Data
dataList[j].update({"value": translatedText})
stateList[6].pop(0)
# Log
if dataList[j].get("name") == "状態異常の説明":
# Pass 1 (Grab Data)
if setData == False:
if dataList[j].get("value") != "":
# Remove Textwrap
jaString = dataList[j].get("value")
jaString = jaString.replace("\n", " ")
jaString = jaString.replace("\r", "")
jaString = re.sub(r"[\\]+f\[\d+\]", "", jaString)
# State Action
if jaString[0] in [
"",
"",
"",
"",
"",
]:
jaString = f"Taro{jaString}"
# Append Data
stateList[7].append(jaString)
# Pass 2 (Set Data)
else:
if dataList[j].get("value") != "":
# Textwrap
translatedText = stateList[7][0]
translatedText = dazedwrap.wrapText(translatedText, LISTWIDTH)
translatedText = font + translatedText
# Remove Taro
translatedText = re.sub(r"\bTaro\b", "", translatedText)
# Set Data
dataList[j].update({"value": translatedText})
stateList[7].pop(0)
# Translation
scenarioListTL = [[], [], []]
optionsListTL = [[], [], []]
npcListTL = [[], [], [], []]
itemListTL = [[], [], [], []]
stateListTL = [[], [], [], [], [], [], [], []]
armorListTL = [[], []]
enemyListTL = [[], []]
weaponsListTL = [[], [], []]
skillListTL = [[], [], [], [], []]
dbNameListTL = [[]]
dbValueListTL = [[]]
translate = False
# NPCs
if len(npcList[0]) > 0:
# Progress Bar
total = 0
for itemArray in npcList:
total += len(itemArray)
pbar.total = total
pbar.refresh()
# Name
response = translateAI(
npcList[0],
"Reply with only the " + LANGUAGE + " translation of the RPG enemy name",
True,
)
nameListTL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 1
response = translateAI(npcList[1], "Reply with only the " + LANGUAGE + " translation")
descListTL1 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 2
response = translateAI(npcList[2], "Reply with only the " + LANGUAGE + " translation")
descListTL2 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 3
response = translateAI(npcList[3], "Reply with only the " + LANGUAGE + " translation")
descListTL3 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Check Mismatch
if (
len(nameListTL) != len(npcList[0])
or len(descListTL1) != len(npcList[1])
or len(descListTL2) != len(npcList[2])
or len(descListTL3) != len(npcList[3])
):
with LOCK:
if filename not in MISMATCH:
MISMATCH.append(filename)
else:
npcListTL = [nameListTL, descListTL1, descListTL2, descListTL3]
translate = True
# SCENARIO
if scenarioList[0] or scenarioList[1]:
# Progress Bar
total = 0
for scenarioArray in scenarioList:
total += len(scenarioArray)
pbar.total = total
pbar.refresh()
# Name
response = translateAI(
scenarioList[0],
"Reply with only the " + LANGUAGE + " translation",
True,
)
nameListTL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 1
response = translateAI(
scenarioList[1],
"reply with only the gender neutral " + LANGUAGE + " translation of the NPC name",
True,
)
descListTL1 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 2
response = translateAI(
scenarioList[2],
"reply with only the gender neutral " + LANGUAGE + " translation of the NPC name",
True,
)
descListTL2 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Check Mismatch
if len(nameListTL) != len(scenarioList[0]) or len(descListTL1) != len(scenarioList[1]) or len(descListTL2) != len(scenarioList[2]):
with LOCK:
if filename not in MISMATCH:
MISMATCH.append(filename)
else:
scenarioListTL = [nameListTL, descListTL1, descListTL2]
translate = True
# OPTIONS
if optionsList[0] or optionsList[1]:
# Progress Bar
total = 0
for optionsArray in optionsList:
total += len(optionsArray)
pbar.total = total
pbar.refresh()
# Name
response = translateAI(
optionsList[0],
"Reply with only the " + LANGUAGE + " translation",
True,
)
nameListTL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 1
response = translateAI(
optionsList[1],
"reply with only the gender neutral " + LANGUAGE + " translation of the NPC name",
True,
)
descListTL1 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 2
response = translateAI(
optionsList[2],
"reply with only the gender neutral " + LANGUAGE + " translation of the NPC name",
True,
)
descListTL2 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Check Mismatch
if len(nameListTL) != len(optionsList[0]) or len(descListTL1) != len(optionsList[1]) or len(descListTL2) != len(optionsList[2]):
with LOCK:
if filename not in MISMATCH:
MISMATCH.append(filename)
else:
optionsListTL = [nameListTL, descListTL1, descListTL2]
translate = True
# ITEMS
if len(itemList[0]) > 0 or len(itemList[1]) > 0:
# Progress Bar
total = 0
for itemArray in itemList:
total += len(itemArray)
pbar.total = total
pbar.refresh()
# Name
response = translateAI(itemList[0], "Reply with only the " + LANGUAGE + " translation")
nameListTL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 1
response = translateAI(itemList[1], "Reply with only the " + LANGUAGE + " translation")
descListTL1 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 2
response = translateAI(itemList[2], "Reply with only the " + LANGUAGE + " translation")
descListTL2 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 3
response = translateAI(itemList[3], "Reply with only the " + LANGUAGE + " translation")
descListTL3 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Check Mismatch
if (
len(nameListTL) != len(itemList[0])
or len(descListTL1) != len(itemList[1])
or len(descListTL2) != len(itemList[2])
or len(descListTL3) != len(itemList[3])
):
with LOCK:
if filename not in MISMATCH:
MISMATCH.append(filename)
else:
itemListTL = [nameListTL, descListTL1, descListTL2, descListTL3]
translate = True
# Armor
if len(armorList[0]) > 0:
# Progress Bar
total = 0
for armorArray in armorList:
total += len(armorArray)
pbar.total = total
pbar.refresh()
# Name
response = translateAI(
armorList[0],
"Reply with only the " + LANGUAGE + " translation of the NPC name",
True,
)
nameListTL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 1
response = translateAI(armorList[1], "Reply with only the " + LANGUAGE + " translation")
descListTL1 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Check Mismatch
if len(nameListTL) != len(armorList[0]) or len(descListTL1) != len(armorList[1]):
with LOCK:
if filename not in MISMATCH:
MISMATCH.append(filename)
else:
armorListTL = [nameListTL, descListTL1]
translate = True
# Enemies
if len(enemyList[0]) > 0:
# Progress Bar
total = 0
for enemyArray in enemyList:
total += len(enemyArray)
pbar.total = total
pbar.refresh()
# Name
response = translateAI(
enemyList[0],
"Reply with only the " + LANGUAGE + " translation of the enemy NPC name",
True,
)
nameListTL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 1
response = translateAI(enemyList[1], "Reply with only the " + LANGUAGE + " translation")
descListTL1 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Check Mismatch
if len(nameListTL) != len(enemyList[0]) or len(descListTL1) != len(enemyList[1]):
with LOCK:
if filename not in MISMATCH:
MISMATCH.append(filename)
else:
enemyListTL = [nameListTL, descListTL1]
translate = True
# Weapons
if len(weaponsList[0]) > 0:
# Progress Bar
total = 0
for weaponsArray in weaponsList:
total += len(weaponsArray)
pbar.total = total
pbar.refresh()
# Name
response = translateAI(
weaponsList[0],
"Reply with only the " + LANGUAGE + " translation of the RPG weapon name",
True,
)
nameListTL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 1
response = translateAI(weaponsList[1], "")
descListTL1 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 2
response = translateAI(weaponsList[2], "")
descListTL2 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Check Mismatch
if len(nameListTL) != len(weaponsList[0]) or len(descListTL1) != len(weaponsList[1]) or len(descListTL2) != len(weaponsList[2]):
with LOCK:
if filename not in MISMATCH:
MISMATCH.append(filename)
else:
weaponsListTL = [nameListTL, descListTL1, descListTL2]
translate = True
# Skills
if len(skillList[0]) > 0:
# Progress Bar
total = 0
for skillArray in skillList:
total += len(skillArray)
pbar.total = total
pbar.refresh()
# Name
response = translateAI(
skillList[0],
"Reply with only the " + LANGUAGE + " translation of the RPG skill name",
True,
)
nameListTL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc
response = translateAI(
skillList[1],
"Reply with only the " + LANGUAGE + " translation of the RPG skill description",
True,
)
descListTL1 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Log 1
response = translateAI(
skillList[2],
"reply with only the gender neutral "
+ LANGUAGE
+ " translation of the action log. Always start the sentence with Taro. For example, Translate 'Taroを倒した' as 'Taro was defeated!'",
True,
)
descListTL2 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Log 2
response = translateAI(
skillList[3],
"reply with only the gender neutral "
+ LANGUAGE
+ " translation of the action log. Always start the sentence with Taro. For example, Translate 'Taroを倒した' as 'Taro was defeated!'",
True,
)
descListTL3 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Log 3
response = translateAI(
skillList[4],
"reply with only the gender neutral "
+ LANGUAGE
+ " translation of the action log. Always start the sentence with Taro. For example, Translate 'Taroを倒した' as 'Taro was defeated!'",
True,
)
descListTL4 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Check Mismatch
if (
len(nameListTL) != len(skillList[0])
or len(descListTL1) != len(skillList[1])
or len(descListTL2) != len(skillList[2])
or len(descListTL3) != len(skillList[3])
or len(descListTL4) != len(skillList[4])
):
with LOCK:
if filename not in MISMATCH:
MISMATCH.append(filename)
else:
skillListTL = [nameListTL, descListTL1, descListTL2, descListTL3, descListTL4]
translate = True
# State
for list in stateList:
if len(list) > 0:
# Progress Bar
total = 0
for stateArray in stateList:
total += len(stateArray)
pbar.total = total
pbar.refresh()
# Name
response = translateAI(
stateList[0],
f"Reply with the {LANGUAGE} translation of the status effect.",
True,
)
nameListTL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 1
response = translateAI(stateList[1], "")
descListTL1 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Log 1
response = translateAI(
stateList[2],
f"Reply with the {LANGUAGE} translation of the status effect.",
True,
)
descListTL2 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Log 2
response = translateAI(
stateList[3],
"reply with only the gender neutral "
+ LANGUAGE
+ " translation of the action log. Always start the sentence with Taro. For example, Translate 'Taroを倒した' as 'Taro was defeated!'",
True,
)
descListTL3 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Log 3
response = translateAI(
stateList[4],
"reply with only the gender neutral "
+ LANGUAGE
+ " translation of the action log. Always start the sentence with Taro. For example, Translate 'Taroを倒した' as 'Taro was defeated!'",
True,
)
descListTL4 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Log 4
response = translateAI(
stateList[5],
"reply with only the gender neutral "
+ LANGUAGE
+ " translation of the action log. Always start the sentence with Taro. For example, Translate 'Taroを倒した' as 'Taro was defeated!'",
True,
)
descListTL5 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Log 1
response = translateAI(
stateList[6],
"reply with only the gender neutral "
+ LANGUAGE
+ " translation of the action log. Always start the sentence with Taro. For example, Translate 'Taroを倒した' as 'Taro was defeated!'",
True,
)
descListTL6 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Log 1
response = translateAI(
stateList[7],
"reply with only the gender neutral "
+ LANGUAGE
+ " translation of the action log. Always start the sentence with Taro. For example, Translate 'Taroを倒した' as 'Taro was defeated!'",
True,
)
descListTL7 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Check Mismatch
if (
len(nameListTL) != len(stateList[0])
or len(descListTL1) != len(stateList[1])
or len(descListTL2) != len(stateList[2])
or len(descListTL3) != len(stateList[3])
or len(descListTL4) != len(stateList[4])
or len(descListTL5) != len(stateList[5])
or len(descListTL6) != len(stateList[6])
):
with LOCK:
if filename not in MISMATCH:
MISMATCH.append(filename)
else:
stateListTL = [
nameListTL,
descListTL1,
descListTL2,
descListTL3,
descListTL4,
descListTL5,
descListTL6,
descListTL7,
]
translate = True
# DB Names
if len(dbNameList[0]) > 0:
# Progress Bar
total = 0
for dbNameArray in dbNameList:
total += len(dbNameArray)
pbar.total = total
pbar.refresh()
# Name
response = translateAI(dbNameList[0], "Reply with only the " + LANGUAGE + " translation")
nameListTL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Check Mismatch
if len(nameListTL) != len(dbNameList[0]):
with LOCK:
if filename not in MISMATCH:
MISMATCH.append(filename)
else:
dbNameListTL = [nameListTL]
translate = True
# DB Values
if len(dbValueList[0]) > 0:
# Progress Bar
total = 0
for dbValueArray in dbValueList:
total += len(dbValueArray)
pbar.total = total
pbar.refresh()
# Name
response = translateAI(dbValueList[0], "Reply with only the " + LANGUAGE + " translation")
valueListTL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Check Mismatch
if len(valueListTL) != len(dbValueList[0]):
with LOCK:
if filename not in MISMATCH:
MISMATCH.append(filename)
else:
dbValueListTL = [valueListTL]
translate = True
# Start Pass 2
if translate == True:
jobList.append(scenarioListTL)
jobList.append(npcListTL)
jobList.append(itemListTL)
jobList.append(stateListTL)
jobList.append(armorListTL)
jobList.append(enemyListTL)
jobList.append(weaponsListTL)
jobList.append(skillListTL)
jobList.append(optionsListTL)
jobList.append(dbNameListTL)
jobList.append(dbValueListTL)
searchDB(events, pbar, jobList, filename)
except IndexError as e:
traceback.print_exc()
raise Exception(str(e) + "Failed to translate: " + initialJAString) from None
except Exception as e:
traceback.print_exc()
raise Exception(str(e) + "Failed to translate: " + initialJAString) from None
return totalTokens
# Save some money and enter the character before translation
def getSpeaker(speaker):
match speaker:
case "ファイン":
return ["Fine", [0, 0]]
case "":
return ["", [0, 0]]
case _:
# Find Speaker
for i in range(len(NAMESLIST)):
if speaker == NAMESLIST[i][0]:
return [NAMESLIST[i][1], [0, 0]]
# Translate and Store Speaker
response = translateAI(
f"{speaker}",
"Reply with the " + LANGUAGE + " translation of the NPC name.",
False,
)
response[0] = response[0].title()
response[0] = response[0].replace("'S", "'s")
response[0] = response[0].replace("Speaker: ", "")
# Retry if name doesn't translate for some reason
if re.search(r"([a-zA-Z?])", response[0]) == None:
response = translateAI(
f"{speaker}",
"Reply with the " + LANGUAGE + " translation of the NPC name.",
False,
)
response[0] = response[0].title()
response[0] = response[0].replace("'S", "'s")
speakerList = [speaker, response[0]]
NAMESLIST.append(speakerList)
return response
return [speaker, [0, 0]]
def translateAI(text, history, history_ctx=None):
"""
Legacy wrapper function for the new shared translation utility.
This maintains compatibility with existing code while using the new shared implementation.
"""
global PBAR, MISMATCH, FILENAME
# Update config estimate mode based on global ESTIMATE
TRANSLATION_CONFIG.estimateMode = bool(ESTIMATE)
# Call the new shared translation function
return sharedtranslateAI(
text=text,
history=history,
config=TRANSLATION_CONFIG,
filename=FILENAME,
pbar=PBAR,
lock=LOCK,
mismatchList=MISMATCH
)