Small adjustments to rpgmaker code

This commit is contained in:
dazedanon 2025-08-24 11:46:20 -05:00
parent 3ce75a9020
commit 7b508d5061
5 changed files with 137 additions and 58 deletions

View file

@ -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:

View file

@ -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)

View file

@ -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♡♡♡"
}

View file

@ -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")

View file

@ -176,3 +176,4 @@ w (lol)
』 (』)
# Game Specific
アルケム (Alchema)