/*================================================================= File created by Yohann NICOLAS. Localized strings functions. =================================================================*/ #include "INIfile.h" #include "LocalizedStrings.h" #include "common.h" #include const char* LOCALIZED_STRINGS_FILENAME = "PlugY\\LocalizedStrings.ini"; LPWSTR StripGender(LPWSTR text) { if (text[0] == L' ') text++; if (text[0] != L'[') return text; text++; while (text[0] != L']' && text[0] != NULL) text++; text++; return text; } LPCWSTR StripGender(LPCWSTR text) { return StripGender((LPWSTR)text); } ///////////////////////////////////////// Get Local Strings ///////////////////////////////////////// struct LocalizedTypeString { DWORD code; LPSTR itemStr; LPWSTR typeLocalizedString; } *sLocalizedTypeStrings; LPWSTR sLocalizedStrings[100]; int nbLocalizedTypeString = 0; LPWSTR getLocalString(int stringId) { if (stringId < 0 || stringId >= 100) return L""; return sLocalizedStrings[stringId]; } LPCWSTR getLocalTypeString(DWORD code) { for (int i = 0; i < nbLocalizedTypeString; i++) { if (sLocalizedTypeStrings[i].code == code) { //log_msg("Code=%08X\n", code); if (sLocalizedTypeStrings[i].itemStr) return StripGender(D2GetStringFromString(sLocalizedTypeStrings[i].itemStr)); LPWSTR text = StripGender(sLocalizedTypeStrings[i].typeLocalizedString); if (!text || !text[0]) break; return text; } } char itemIdx[5]; itemIdx[0] = (code) & 0xFF; itemIdx[1] = (code >> 8) & 0xFF; itemIdx[2] = (code >> 16) & 0xFF; itemIdx[3] = (code >> 24) & 0xFF; itemIdx[4] = 0; LPWSTR typeName = StripGender(D2GetStringFromString(itemIdx)); if (wcsstr(typeName, L"-not xlated call ken") == NULL) return typeName; static WCHAR itemIdxW[5]; itemIdxW[0] = (code) & 0xFF; itemIdxW[1] = (code >> 8) & 0xFF; itemIdxW[2] = (code >> 16) & 0xFF; itemIdxW[3] = (code >> 24) & 0xFF; itemIdxW[4] = 0; return itemIdxW; } ///////////////////////////////////////// Load Strings ///////////////////////////////////////// #define LOAD(I) loadLocalString(iniFile, I, L#I, key) #define BUFSIZE 0x400 void loadLocalString(INIFileW *iniFile, int id, LPCWSTR section, LPCWSTR key) { WCHAR buffer[BUFSIZE]; iniFile->GetPrivateProfileString(section, key, NULL, buffer, BUFSIZE); int len = wcslen(buffer); if (len == 0) iniFile->GetPrivateProfileString(section, L"ENG", section, buffer, BUFSIZE); len = wcslen(buffer); if (len == 0) { len = wcslen(section); sLocalizedStrings[id] = new WCHAR[len + 1]; wcsncpy(sLocalizedStrings[id], section, len); sLocalizedStrings[id][len] = NULL; return; } int j = 0; int i = 0; if (buffer[0] == L'"' && buffer[len-1] == L'"') { buffer[len-1] = NULL; i++; len -= 2; } sLocalizedStrings[id] = new WCHAR[len + 1]; for (; i nextHeader) || cur[itemKeyLen] == '\r' || cur[itemKeyLen] == '\n' || cur[itemKeyLen] == NULL))// Found { cur += itemKeyLen; end = cur; while (end[0] != '\r' && end[0] != '\n' && end[0] != NULL) end++; sLocalizedTypeStrings[i].itemStr = new char[end - cur + 1]; for (int j = 0; j < end - cur; j++) sLocalizedTypeStrings[i].itemStr[j] = (char)cur[j]; sLocalizedTypeStrings[i].itemStr[end - cur] = NULL; i++; continue; } // Search lng key cur = wcsstr(end + 1, keyString); if (cur == NULL || (nextHeader && cur > nextHeader) || cur[keyLen] == '\r' || cur[keyLen] == '\n' || cur[keyLen] == NULL)// Not found { // Search def key cur = wcsstr(end + 1, defKeyString); if (cur == NULL || (nextHeader && cur > nextHeader) || cur[defKeyLen] == '\r' || cur[defKeyLen] == '\n' || cur[defKeyLen] == NULL)// Not found { sLocalizedTypeStrings[i].typeLocalizedString = new WCHAR[1]; sLocalizedTypeStrings[i].typeLocalizedString[0] = NULL; i++; continue; } cur += defKeyLen; } else cur += keyLen; // Search end value. end = cur; while (end[0] && end[0] != '\r' && end[0] != '\n') end++; // Strip "" if (cur[0] == '"' && (end - 1)[0] == '"') { cur++; end--; } // Strip Gender if (cur[0] == '[') { LPCWSTR tmp = cur; while (tmp[0] && tmp[0] != ']' && tmp[0] != '\r' && tmp[0] != '\n') tmp++; if (tmp[0] == ']') { cur = tmp + 1; end = cur; while (end[0] && end[0] != '[' && end[0] != '\r' && end[0] != '\n' && end[0] != '"') end++; } } // Fill value sLocalizedTypeStrings[i].typeLocalizedString = new WCHAR[end - cur + 1]; _snwprintf(sLocalizedTypeStrings[i].typeLocalizedString, end - cur, cur); sLocalizedTypeStrings[i].typeLocalizedString[end - cur] = NULL; i++; } return nb; } void loadLocalizedStrings(int language) { if (sLocalizedTypeStrings) return; INIFileW *iniFile = new INIFileW; log_msg("***** Load localized Strings *****\n"); if (iniFile->InitReadWrite(LOCALIZED_STRINGS_FILENAME, INIFILE_MPQREAD, 0))//C:\\Jeux\\Blizzard\\D2\\- log_msg("File %s loaded from MPQ.\n\n", LOCALIZED_STRINGS_FILENAME); else if (iniFile->InitReadWrite(LOCALIZED_STRINGS_FILENAME, INIFILE_READ, 0))//C:\\Jeux\\Blizzard\\D2\\- log_msg("File %s loaded from PlugY folder.\n\n", LOCALIZED_STRINGS_FILENAME); else { log_msg("Failed to load %s.\n\n", LOCALIZED_STRINGS_FILENAME); return; } LPCWSTR key; switch (language) { case LNG_ENG: key = L"ENG"; break; case LNG_ESP: key = L"ESP"; break; case LNG_DEU: key = L"DEU"; break; case LNG_FRA: key = L"FRA"; break; case LNG_POR: key = L"POR"; break; case LNG_ITA: key = L"ITA"; break; case LNG_JPN: key = L"JPN"; break; case LNG_KOR: key = L"KOR"; break; case LNG_SIN: key = L"SIN"; break; case LNG_CHI: key = L"CHI"; break; case LNG_POL: key = L"POL"; break; case LNG_RUS: key = L"RUS"; break; case LNG_DEF: key = L"ENG"; break; default: key = L"ENG"; } // Load localized type string nbLocalizedTypeString = GetPrivateProfileStringList(iniFile->m_cache, L"TYPE_", key); // PlugY localized string LOAD(STR_STATS_UNASSIGN_WITH_LIMIT); LOAD(STR_STATS_UNASSIGN_WITHOUT_LIMIT); LOAD(STR_STATS_BASE_MIN); LOAD(STR_SKILLS_UNASSIGN); LOAD(STR_STASH_PREVIOUS_PAGE); LOAD(STR_STASH_NEXT_PAGE); LOAD(STR_TOGGLE_TO_PERSONAL); LOAD(STR_TOGGLE_TO_SHARED); LOAD(STR_TOGGLE_MULTI_DISABLED); LOAD(STR_STASH_PREVIOUS_INDEX); LOAD(STR_STASH_NEXT_INDEX); LOAD(STR_PUT_GOLD); LOAD(STR_TAKE_GOLD); LOAD(STR_PERSONAL_PAGE_NUMBER); LOAD(STR_SHARED_PAGE_NUMBER); LOAD(STR_NO_SELECTED_PAGE); LOAD(STR_SHARED_GOLD_QUANTITY); LOAD(STR_PREVIOUS_PAGE); LOAD(STR_NEXT_PAGE); LOAD(STR_PREVIOUS_RUNE); LOAD(STR_NEXT_RUNE); LOAD(STR_ITEM_LEVEL); LOAD(STR_PAGE_TYPE_CHANGE); // Cube receipt : LOAD(STR_COW_PORTAL); LOAD(STR_PANDEMONIUM_PORTAL); LOAD(STR_PANDEMONIUM_FINAL_PORTAL); LOAD(STR_FULL); LOAD(STR_REPAIR); LOAD(STR_AND); LOAD(STR_RECHARGE); LOAD(STR_DESTROY_FILLERS); LOAD(STR_REMOVE_FILLERS); LOAD(STR_REGENERATE); LOAD(STR_UPGRADE_TO_EXCEPTIONAL); LOAD(STR_UPGRADE_TO_ELITE); LOAD(STR_ETHERAL); LOAD(STR_NOT_ETHERAL); LOAD(STR_NOT_RUNEWORD); LOAD(STR_BASIC); LOAD(STR_EXCEPTIONAL); LOAD(STR_ELITE); LOAD(STR_CRACKED); LOAD(STR_NORMAL); LOAD(STR_SUPERIOR); LOAD(STR_MAGIC); LOAD(STR_SET); LOAD(STR_RARE); LOAD(STR_UNIQUE); LOAD(STR_CRAFTED); LOAD(STR_TEMPERED); LOAD(STR_ITEM); LOAD(STR_ITEM_SAME_TYPE); LOAD(STR_INCLUDE_UPGRADED); LOAD(STR_WITHOUT_SOCKET); LOAD(STR_WITH_SOCKETS); LOAD(STR_WITH_N_SOCKETS); LOAD(STR_ONLY_N_H); LOAD(STR_ONLY_HELL); LOAD(STR_ONLY_CLASS); // Breakpoints : LOAD(STR_MERCENARIES); LOAD(STR_MERC_ACT_1); LOAD(STR_MERC_ACT_2); LOAD(STR_MERC_ACT_3); LOAD(STR_MERC_ACT_5); LOAD(STR_BREAKPOINT); LOAD(STR_BREAKPOINTS); LOAD(STR_BLOCK_FRAMES); LOAD(STR_CASTING_FRAMES); LOAD(STR_HIT_RECOVERY_FRAMES); LOAD(STR_1H_SWINGING_WEAPON); LOAD(STR_OTHER_WEAPONS); LOAD(STR_HUMAN_FORM); LOAD(STR_BEAR_FORM); LOAD(STR_WOLF_FORM); LOAD(STR_VAMPIRE_FORM); LOAD(STR_SPEARS_AND_STAVES); LOAD(STR_LIGHTNING_CHAIN_LIGHTNING); LOAD(STR_OTHER_SPELLS); iniFile->close(); delete iniFile; } /*================================= END OF FILE =================================*/