commonlibsse_ng\skse/
translation.rs

1// use crate::sys::{root, RE};
2// use std::collections::HashMap;
3// use windows::core::HSTRING;
4
5// #[cfg(feature = "tracing")]
6// use tracing::{error, info, warn};
7
8// pub fn parse_translation(name: &str) {
9//     let scaleform_manager = unsafe { RE::BSScaleformManager::GetSingleton() };
10//     if scaleform_manager.is_null() {
11//         error!("Scaleform manager is not available.");
12//         return;
13//     }
14//     let loader = unsafe { scaleform_manager.as_ref() }.and_then(|m| unsafe { m.loader.as_ref() });
15//     let translator = loader.and_then(|l| l.GetStateAddRef(RE::GFxState_StateType::kTranslator));
16
17//     let scaleform_translator =
18//         translator.and_then(|t| t.downcast_ref::<RE::BSScaleformTranslator>());
19
20//     if scaleform_translator.is_none() {
21//         #[cfg(feature = "tracing")]
22//         warn!("Failed to import translation for {name}");
23//         return;
24//     }
25
26//     let ini_setting_collection = unsafe { RE::INISettingCollection::GetSingleton() };
27
28//     let sv = {
29//         let s = "sLanguage:General";
30//         let len = s.len() as u64;
31//         let s_ptr = s.as_ptr() as u64;
32//         let sv: root::std::string_view = [0; 2];
33//         sv[0] = s_ptr;
34//         sv[1] = len;
35//         sv
36//     };
37//     let setting = unsafe { ini_setting_collection.as_ref().map(|c| c.GetSetting(sv)) };
38
39//     let language = setting
40//         .filter(|s| unsafe {
41//             s.as_ref()
42//                 .map(|s| unsafe { s.GetType() } == RE::Setting_Type::kString)
43//                 .unwrap_or_default()
44//         })
45//         .map(|s| unsafe { s.as_ref() }.and_then(|s| s.c_str().to_string()))
46//         .unwrap_or_else(|| "ENGLISH".to_string());
47
48//     let path = format!("Interface\\Translations\\{}_{}.txt", name, language);
49//     root::std::string;
50//     let mut file_stream = RE::BSResourceNiBinaryStream::new2(&path);
51
52//     if !file_stream.good() {
53//         return;
54//     }
55
56//     info!("Reading translations from {}...", path);
57
58//     let mut bom: u16 = 0;
59//     if file_stream.read_exact(&mut bom).is_err() || bom != 0xFEFF {
60//         error!("BOM Error, file must be encoded in UCS-2 LE.");
61//         return;
62//     }
63
64//     let mut translation_map = HashMap::new();
65//     while let Some(line) = file_stream.read_line_w('\n') {
66//         if line.len() < 4 || !line.starts_with('$') {
67//             continue;
68//         }
69
70//         let trimmed = line.trim_end_matches('\r');
71//         if let Some(delim_idx) = trimmed.find('\t') {
72//             let (key, value) = trimmed.split_at(delim_idx);
73//             let key = key.trim();
74//             let value = value[1..].trim();
75
76//             if let (Some(cached_key), Some(cached_translation)) = (
77//                 RE::BSScaleformTranslator::GetCachedString(key),
78//                 RE::BSScaleformTranslator::GetCachedString(value),
79//             ) {
80//                 translation_map.insert(cached_key, cached_translation);
81//             }
82//         }
83//     }
84
85//     if let Some(translator) = scaleform_translator {
86//         translator.translation_map.extend(translation_map);
87//     }
88// }
89
90// pub fn translate(key: &str) -> Option<String> {
91//     if !key.starts_with('$') {
92//         return None;
93//     }
94
95//     let scaleform_manager = unsafe { RE::BSScaleformManager::GetSingleton() };
96//     let loader = unsafe { scaleform_manager.as_ref().and_then(|m| m.loader.as_ref()) };
97//     let translator = loader.and_then(|l| l.getStateAddRef(RE::GFxState_StateType::kTranslator));
98
99//     let translator = translator?;
100//     let mut result = unsafe { RE::GFxWStringBuffer::new() };
101
102//     let key_utf16 = HSTRING::from(key);
103//     let translate_info = RE::GFxTranslator_TranslateInfo {
104//         key: key_utf16.as_ptr(),
105//         result: &mut result,
106//         instanceName: ::core::ptr::null_mut(),
107//         flags: 0,
108//         pad19: 0,
109//         pad1A: 0,
110//         pad1C: 0,
111//     };
112
113//     translator.translate(&translate_info);
114//     if unsafe { result.empty() } {
115//         return None;
116//     }
117
118//     Some(HSTRING::from(unsafe { result.c_str() }).to_string())
119// }