Small adjustments to rpgmaker code
This commit is contained in:
parent
3ce75a9020
commit
7b508d5061
5 changed files with 137 additions and 58 deletions
|
|
@ -983,7 +983,7 @@ def searchCodes(page, pbar, jobList, filename):
|
|||
|
||||
# Remove any RPGMaker Code at start
|
||||
ffMatchNS = re.search(
|
||||
r"^((?:[\\]+[^cCnNiIkKvVSs{}]+\[[\d\w\W]+?\]?\])+)",
|
||||
r"^((?:[\\]+[^cCnNiIkKvVSs{}]+?\[[\d\w\W]+?\]?\])+)",
|
||||
nextString,
|
||||
)
|
||||
if ffMatchNS != None:
|
||||
|
|
@ -1105,7 +1105,7 @@ def searchCodes(page, pbar, jobList, filename):
|
|||
|
||||
# Remove any RPGMaker Code at start
|
||||
ffMatch = re.search(
|
||||
r"^((?:[\\]+[^cCnNiIkKvVSs{}]+\[[\d\w\W]+?\]?\])+)",
|
||||
r"^((?:[\\]+[^cCnNiIkKvVSs{}]+?\[[\d\w\W]+?\]?\])+)",
|
||||
finalJAString,
|
||||
)
|
||||
if ffMatch != None:
|
||||
|
|
|
|||
|
|
@ -65,14 +65,14 @@ PBAR = None
|
|||
FILENAME = None
|
||||
|
||||
# Dialogue / Choices
|
||||
CODE101 = False
|
||||
CODE102 = False
|
||||
CODE101 = True
|
||||
CODE102 = True
|
||||
|
||||
# Picture
|
||||
CODE150 = False
|
||||
|
||||
# Set String (Fragile but necessary)
|
||||
CODE122 = True
|
||||
CODE122 = False
|
||||
|
||||
# Other
|
||||
CODE210 = False
|
||||
|
|
@ -81,8 +81,8 @@ CODE250 = False
|
|||
|
||||
# Database
|
||||
SCENARIOFLAG = False
|
||||
OPTIONSFLAG = True
|
||||
NPCFLAG = True
|
||||
OPTIONSFLAG = False
|
||||
NPCFLAG = False
|
||||
DBNAMEFLAG = False
|
||||
DBVALUEFLAG = False
|
||||
ITEMFLAG = False
|
||||
|
|
@ -501,8 +501,8 @@ def searchCodes(events, pbar, jobList, filename):
|
|||
and jaString != ""
|
||||
and "_" not in jaString
|
||||
and '",' not in 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:
|
||||
|
|
@ -557,7 +557,7 @@ def searchCodes(events, pbar, jobList, filename):
|
|||
codeList[i]["stringArgs"][1] = translatedText
|
||||
|
||||
# Dialogue
|
||||
elif codeList[i]["stringArgs"][0] == "サイド通知":
|
||||
elif codeList[i]["stringArgs"][0] == "サイド通知" or codeList[i]["stringArgs"][0] == "X[移]メニュー時文章表示":
|
||||
jaString = codeList[i]["stringArgs"][1]
|
||||
|
||||
# Pass 1
|
||||
|
|
@ -909,7 +909,7 @@ def searchDB(events, pbar, jobList, filename):
|
|||
try:
|
||||
for table in tableList:
|
||||
# Grab NPCs
|
||||
if table["name"] == "主人公ステータス" and NPCFLAG == True:
|
||||
if table["name"] == "戦闘コマンド" and NPCFLAG == True:
|
||||
with open("translations.txt", "a", encoding="utf-8") as file:
|
||||
if setData:
|
||||
file.write(f"\n#Actors\n")
|
||||
|
|
@ -919,7 +919,7 @@ def searchDB(events, pbar, jobList, filename):
|
|||
# Parse
|
||||
for j in range(len(dataList)):
|
||||
# Name
|
||||
if dataList[j].get("name") == "キャラ名":
|
||||
if dataList[j].get("name") == "コマンド名":
|
||||
# Pass 1 (Grab Data)
|
||||
if setData == False:
|
||||
if dataList[j].get("value") != "":
|
||||
|
|
@ -936,7 +936,7 @@ def searchDB(events, pbar, jobList, filename):
|
|||
npcList[0].pop(0)
|
||||
|
||||
# Description
|
||||
if dataList[j].get("name") == "肩書き":
|
||||
if dataList[j].get("name") == "コマンドの説明文":
|
||||
# Pass 1 (Grab Data)
|
||||
if setData == False:
|
||||
if dataList[j].get("value") != "":
|
||||
|
|
@ -1258,7 +1258,7 @@ def searchDB(events, pbar, jobList, filename):
|
|||
dbValueList[0].pop(0)
|
||||
|
||||
# Grab Items
|
||||
if table["name"] == "勲章コモン" and ITEMFLAG == True:
|
||||
if table["name"] == "アイテム" and ITEMFLAG == True:
|
||||
# Write Category
|
||||
if setData:
|
||||
with open("translations.txt", "a", encoding="utf-8") as file:
|
||||
|
|
@ -1272,7 +1272,7 @@ def searchDB(events, pbar, jobList, filename):
|
|||
font = 20
|
||||
for j in range(len(dataList)):
|
||||
# Name
|
||||
if dataList[j].get("name") == "勲章名":
|
||||
if dataList[j].get("name") == "アイテム名":
|
||||
jaString = dataList[j].get("value")
|
||||
if jaString != "":
|
||||
# Pass 1 (Grab Data)
|
||||
|
|
@ -1290,7 +1290,7 @@ def searchDB(events, pbar, jobList, filename):
|
|||
itemList[0].pop(0)
|
||||
|
||||
# Description
|
||||
if dataList[j].get("name") == "説明文":
|
||||
if dataList[j].get("name") == "説明文[2行まで可]":
|
||||
# Pass 1 (Grab Data)
|
||||
if setData == False:
|
||||
if dataList[j].get("value") != "":
|
||||
|
|
@ -1356,7 +1356,7 @@ def searchDB(events, pbar, jobList, filename):
|
|||
itemList[2].pop(0)
|
||||
|
||||
# Description
|
||||
if dataList[j].get("name") == "クエスト概要":
|
||||
if dataList[j].get("name") == "使用後文章[移動]":
|
||||
# Pass 1 (Grab Data)
|
||||
if setData == False:
|
||||
if dataList[j].get("value") != "":
|
||||
|
|
@ -1646,11 +1646,13 @@ def searchDB(events, pbar, jobList, filename):
|
|||
# Textwrap
|
||||
translatedText = skillList[3][0]
|
||||
translatedText = dazedwrap.wrapText(translatedText, LISTWIDTH)
|
||||
translatedText = font + translatedText
|
||||
|
||||
# Remove Taro
|
||||
translatedText = re.sub(r"\bTaro\b", "", translatedText)
|
||||
|
||||
# Font
|
||||
translatedText = font + translatedText
|
||||
|
||||
# Set Data
|
||||
dataList[j].update({"value": translatedText})
|
||||
skillList[3].pop(0)
|
||||
|
|
|
|||
|
|
@ -78,11 +78,13 @@ Output:
|
|||
Input:
|
||||
{
|
||||
"Line1": "ハートが可愛いピンク色のチャーム。\n女の子らしさが増すワンポイントアクセサリー。\\\\n\\}\\C[16]«効果»\\C[0] [防御力+1][敏捷性+1][魅力+8][最大HP+10]"
|
||||
"Line2": " \\{\\{\\{“滅茶苦茶に汚してやりてぇ”"
|
||||
"Line2": " \\{\\{\\{“滅茶苦茶に汚してやりてぇ”",
|
||||
"Line3": "イぐぅぅぅう~~~~~~♡♡♡"
|
||||
}
|
||||
|
||||
Output:
|
||||
{
|
||||
"Line1": "A cute pink heart charm.\nA girly accessory that adds a feminine touch.\\\\n\\}\\C[16]«Effect»\\C[0] [Defense +1][Agility +1][Charm +8][Max HP +10]"
|
||||
"Line2": " \\{\\{\\{“I wanna mess her up so fucking bad.”"
|
||||
"Line2": " \\{\\{\\{“I wanna mess her up so fucking bad.”",
|
||||
"Line3": "I'm cummingggg~~~~~~♡♡♡"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -254,7 +254,30 @@ Output ONLY the {config.language} translation in the following format: `Translat
|
|||
return system, user
|
||||
|
||||
|
||||
def translateText(system, user, history, penalty, formatType, model):
|
||||
def createTranslationSchema(numLines):
|
||||
"""Create a JSON schema for translation response based on number of lines"""
|
||||
properties = {}
|
||||
required = []
|
||||
|
||||
for i in range(1, numLines + 1):
|
||||
line_key = f"Line{i}"
|
||||
properties[line_key] = {
|
||||
"type": "string",
|
||||
"description": f"The translated text for Line{i}"
|
||||
}
|
||||
required.append(line_key)
|
||||
|
||||
schema = {
|
||||
"type": "object",
|
||||
"properties": properties,
|
||||
"required": required,
|
||||
"additionalProperties": False
|
||||
}
|
||||
|
||||
return schema
|
||||
|
||||
|
||||
def translateText(system, user, history, penalty, formatType, model, numLines=None):
|
||||
"""Send translation request to OpenAI API"""
|
||||
# Ensure system content is not empty
|
||||
if not system or not str(system).strip():
|
||||
|
|
@ -276,8 +299,17 @@ def translateText(system, user, history, penalty, formatType, model):
|
|||
msg.append({"role": "assistant", "content": history})
|
||||
|
||||
# Response Format
|
||||
if formatType == "json":
|
||||
responseFormat = {"type": "json_object"}
|
||||
if formatType == "json" and numLines is not None:
|
||||
# Use structured output with JSON schema
|
||||
schema = createTranslationSchema(numLines)
|
||||
responseFormat = {
|
||||
"type": "json_schema",
|
||||
"json_schema": {
|
||||
"name": "translation_response",
|
||||
"strict": True,
|
||||
"schema": schema
|
||||
}
|
||||
}
|
||||
else:
|
||||
responseFormat = {"type": "text"}
|
||||
|
||||
|
|
@ -292,21 +324,44 @@ def translateText(system, user, history, penalty, formatType, model):
|
|||
raise ValueError(f"Message {i} has empty content: {message}")
|
||||
|
||||
# Call OpenAI API
|
||||
if "gpt-5" in model:
|
||||
response = openai.chat.completions.create(
|
||||
model=model,
|
||||
response_format=responseFormat,
|
||||
messages=msg,
|
||||
reasoning_effort="minimal"
|
||||
)
|
||||
else:
|
||||
response = openai.chat.completions.create(
|
||||
model=model,
|
||||
response_format=responseFormat,
|
||||
messages=msg,
|
||||
temperature=0,
|
||||
frequency_penalty=penalty
|
||||
)
|
||||
try:
|
||||
if "gpt-5" in model:
|
||||
response = openai.chat.completions.create(
|
||||
model=model,
|
||||
response_format=responseFormat,
|
||||
messages=msg,
|
||||
reasoning_effort="minimal"
|
||||
)
|
||||
else:
|
||||
response = openai.chat.completions.create(
|
||||
model=model,
|
||||
response_format=responseFormat,
|
||||
messages=msg,
|
||||
temperature=0,
|
||||
frequency_penalty=penalty
|
||||
)
|
||||
except Exception as e:
|
||||
# If structured output fails, fallback to json_object
|
||||
if formatType == "json" and "json_schema" in str(responseFormat):
|
||||
responseFormat = {"type": "json_object"}
|
||||
if "gpt-5" in model:
|
||||
response = openai.chat.completions.create(
|
||||
model=model,
|
||||
response_format=responseFormat,
|
||||
messages=msg,
|
||||
reasoning_effort="minimal"
|
||||
)
|
||||
else:
|
||||
response = openai.chat.completions.create(
|
||||
model=model,
|
||||
response_format=responseFormat,
|
||||
messages=msg,
|
||||
temperature=0,
|
||||
frequency_penalty=penalty
|
||||
)
|
||||
else:
|
||||
raise e
|
||||
|
||||
return response
|
||||
|
||||
|
||||
|
|
@ -326,6 +381,7 @@ def cleanTranslatedText(translatedText, language):
|
|||
"】": "]",
|
||||
"【": "[",
|
||||
"é": "e",
|
||||
"’": "'",
|
||||
"this guy": "this bastard",
|
||||
"This guy": "This bastard",
|
||||
"Placeholder Text": "",
|
||||
|
|
@ -363,8 +419,6 @@ def elongateCharacters(text):
|
|||
def extractTranslation(translatedTextList, isList, pbar=None):
|
||||
"""Extract translation from JSON response"""
|
||||
try:
|
||||
translatedTextList = re.sub(r'\\"+\"([^,\n}])', r'\\"\1', translatedTextList)
|
||||
translatedTextList = re.sub(r"(?<![\\])\"+(?![\n,])", r'"', translatedTextList)
|
||||
lineDict = json.loads(translatedTextList)
|
||||
# If it's a batch (i.e., list), extract with tags; otherwise, return the single item.
|
||||
stringList = list(lineDict.values())
|
||||
|
|
@ -486,14 +540,15 @@ def translateAI(text, history, fullPromptFlag, config, filename=None, pbar=None,
|
|||
continue
|
||||
|
||||
# Translate
|
||||
response = translateText(system, user, history, 0.05, formatType, config.model)
|
||||
numLines = len(tItem) if isinstance(tItem, list) else None
|
||||
response = translateText(system, user, history, 0.05, formatType, config.model, numLines)
|
||||
translatedText = response.choices[0].message.content
|
||||
|
||||
# Retry if AI refused
|
||||
if not translatedText or '"error":' in translatedText:
|
||||
response = translateText(
|
||||
f"{system}\n You translate ALL content.",
|
||||
user, history, 0.1, formatType, "gpt-4.1" if config.model == "gpt-5" else "gpt-4o"
|
||||
user, history, 0.1, formatType, "gpt-4.1" if config.model == "gpt-5" else "gpt-4o", numLines
|
||||
)
|
||||
translatedText = response.choices[0].message.content
|
||||
|
||||
|
|
@ -501,33 +556,51 @@ def translateAI(text, history, fullPromptFlag, config, filename=None, pbar=None,
|
|||
totalTokens[0] += response.usage.prompt_tokens
|
||||
totalTokens[1] += response.usage.completion_tokens
|
||||
|
||||
# Clean the translation first for consistency
|
||||
translatedText = cleanTranslatedText(translatedText, config.language)
|
||||
|
||||
# Process translation result
|
||||
if translatedText:
|
||||
translatedText = cleanTranslatedText(translatedText, config.language)
|
||||
|
||||
if isinstance(tItem, list):
|
||||
extractedTranslations = extractTranslation(translatedText, True, pbar)
|
||||
if extractedTranslations is None or len(tItem) != len(extractedTranslations):
|
||||
# Mismatch, try again
|
||||
response = translateText(system, user, history, 0.05, formatType, config.model)
|
||||
response = translateText(system, user, history, 0.05, formatType, config.model, numLines)
|
||||
translatedText = response.choices[0].message.content
|
||||
totalTokens[0] += response.usage.prompt_tokens
|
||||
totalTokens[1] += response.usage.completion_tokens
|
||||
|
||||
# Format and check again
|
||||
# Clean and extract again
|
||||
translatedText = cleanTranslatedText(translatedText, config.language)
|
||||
if isinstance(tItem, list):
|
||||
extractedTranslations = extractTranslation(translatedText, True, pbar)
|
||||
if extractedTranslations is None or len(tItem) != len(extractedTranslations):
|
||||
# Log mismatch
|
||||
with open(config.mismatchLogPath, "a+", encoding="utf-8") as mismatchFile:
|
||||
mismatchFile.write(f"Mismatch: {filename}\n")
|
||||
mismatchFile.write(f"Input:\n{subbedT}\n")
|
||||
mismatchFile.write(f"Output:\n{translatedText}\n")
|
||||
mismatch = True
|
||||
extractedTranslations = extractTranslation(translatedText, True, pbar)
|
||||
if extractedTranslations is None or len(tItem) != len(extractedTranslations):
|
||||
# Format the JSON output for consistent mismatch logging
|
||||
formatted_mismatch_output = translatedText
|
||||
try:
|
||||
parsed_json = json.loads(translatedText)
|
||||
formatted_mismatch_output = json.dumps(parsed_json, indent=4, ensure_ascii=False)
|
||||
except (json.JSONDecodeError, ValueError):
|
||||
pass
|
||||
|
||||
# Log mismatch
|
||||
with open(config.mismatchLogPath, "a+", encoding="utf-8") as mismatchFile:
|
||||
mismatchFile.write(f"Mismatch: {filename}\n")
|
||||
mismatchFile.write(f"Input:\n{subbedT}\n")
|
||||
mismatchFile.write(f"Output:\n{formatted_mismatch_output}\n")
|
||||
mismatch = True
|
||||
|
||||
# Format the JSON output for consistent logging
|
||||
formatted_output = translatedText
|
||||
try:
|
||||
# Try to parse and reformat the JSON for consistent formatting
|
||||
parsed_json = json.loads(translatedText)
|
||||
formatted_output = json.dumps(parsed_json, indent=4, ensure_ascii=False)
|
||||
except (json.JSONDecodeError, ValueError):
|
||||
# If it's not valid JSON, keep the original
|
||||
pass
|
||||
|
||||
logFile.write(f"Input:\n{subbedT}\n")
|
||||
logFile.write(f"Output:\n{translatedText}\n")
|
||||
logFile.write(f"Output:\n{formatted_output}\n")
|
||||
|
||||
# Set results if no mismatch
|
||||
if not mismatch:
|
||||
|
|
@ -544,8 +617,9 @@ def translateAI(text, history, fullPromptFlag, config, filename=None, pbar=None,
|
|||
with lock:
|
||||
pbar.update(len(tItem))
|
||||
else:
|
||||
# Single string translation
|
||||
tList[index] = translatedText.replace("Placeholder Text", "")
|
||||
# Single string translation - clean after getting the raw response
|
||||
cleanedText = cleanTranslatedText(translatedText, config.language)
|
||||
tList[index] = cleanedText.replace("Placeholder Text", "")
|
||||
else:
|
||||
if pbar:
|
||||
pbar.write(f"AI Refused: {tItem}\n")
|
||||
|
|
|
|||
|
|
@ -176,3 +176,4 @@ w (lol)
|
|||
』 (』)
|
||||
|
||||
# Game Specific
|
||||
アルケム (Alchema)
|
||||
|
|
|
|||
Loading…
Reference in a new issue