11using System ;
22using System . Collections . Generic ;
33using System . IO ;
4+ using System . Linq ;
45using System . Reflection ;
56using System . Security . Cryptography ;
67using GlobalEnums ;
8+ using Language ;
79using Modding ;
8- using On . UnityEngine . UI ;
10+ using Newtonsoft . Json ;
11+ using Newtonsoft . Json . Converters ;
12+ using SFCore . Utils ;
13+ using TMPro ;
914using UnityEngine ;
1015using Object = UnityEngine . Object ;
1116
1217namespace LanguageSupport
1318{
19+ internal class TmpFontConverter : CustomCreationConverter < TMP_FontAsset >
20+ {
21+ public override TMP_FontAsset Create ( Type objectType )
22+ {
23+ return ScriptableObject . CreateInstance < TMP_FontAsset > ( ) ;
24+ }
25+ }
26+
1427 internal class LanguageSupport : Mod
1528 {
1629 internal static LanguageSupport Instance ;
@@ -67,7 +80,190 @@ private void InitCallbacks()
6780 // Hooks
6881 On . Language . Language . HasLanguageFile += OnLanguageHasLanguageFile ;
6982 On . Language . Language . GetLanguageFileContents += OnLanguageGetLanguageFileContents ;
70- MenuLanguageSetting . RefreshAvailableLanguages += OnMenuLanguageSettingRefreshAvailableLanguages ;
83+ On . UnityEngine . UI . MenuLanguageSetting . RefreshAvailableLanguages += OnMenuLanguageSettingRefreshAvailableLanguages ;
84+ On . UnityEngine . UI . MenuLanguageSetting . PushUpdateOptionList += OnMenuLanguageSettingPushUpdateOptionList ;
85+ On . ChangeFontByLanguage . SetFont += OnChangeFontByLanguageSetFont ;
86+
87+ On . TMPro . TextMeshPro . LoadFontAsset += OnTextMeshProLoadFontAsset ;
88+ On . TMPro . TMP_FontAsset . ReadFontDefinition += OnTMP_FontAssetReadFontDefinition ;
89+ }
90+
91+ private void OnTMP_FontAssetReadFontDefinition ( On . TMPro . TMP_FontAsset . orig_ReadFontDefinition orig , TMP_FontAsset self )
92+ {
93+ Log ( $ "OnTMP_FontAssetReadFontDefinition - { self . GetAttr < TMP_FontAsset , FaceInfo > ( "m_fontInfo" ) } ") ;
94+ Log ( $ "OnTMP_FontAssetReadFontDefinition - { self . GetAttr < TMP_FontAsset , Texture2D > ( "atlas" ) } ") ;
95+ Log ( $ "OnTMP_FontAssetReadFontDefinition - { self . GetAttr < TMP_FontAsset , List < TMP_Glyph > > ( "m_glyphInfoList" ) } ") ;
96+ Log ( $ "OnTMP_FontAssetReadFontDefinition - { self . GetAttr < TMP_FontAsset , Dictionary < int , KerningPair > > ( "m_characterDictionary" ) } ") ;
97+ Log ( $ "OnTMP_FontAssetReadFontDefinition - { self . GetAttr < TMP_FontAsset , KerningTable > ( "m_kerningDictionary" ) } ") ;
98+ Log ( $ "OnTMP_FontAssetReadFontDefinition - { self . GetAttr < TMP_FontAsset , List < TMP_FontAsset > > ( "m_kerningPair" ) } ") ;
99+ Log ( $ "OnTMP_FontAssetReadFontDefinition - { self . GetAttr < TMP_FontAsset , FontCreationSetting > ( "fontCreationSettings" ) } ") ;
100+
101+ orig ( self ) ;
102+ }
103+
104+ private void OnTextMeshProLoadFontAsset ( On . TMPro . TextMeshPro . orig_LoadFontAsset orig , TextMeshPro self )
105+ {
106+ var m_fontAsset = self . GetAttr < TextMeshPro , TMP_FontAsset > ( "m_fontAsset" ) ;
107+ var m_renderer = self . GetAttr < TextMeshPro , Renderer > ( "m_renderer" ) ;
108+ var m_sharedMaterial = self . GetAttr < TextMeshPro , Material > ( "m_sharedMaterial" ) ;
109+
110+ if ( m_fontAsset . name == "noto_serif_thai_bold_tmpro" )
111+ {
112+ Log ( $ "OnTextMeshProLoadFontAsset - { m_fontAsset . characterDictionary } ") ; // ""
113+ if ( m_fontAsset . characterDictionary == null )
114+ {
115+ m_fontAsset . ReadFontDefinition ( ) ;
116+ }
117+ Log ( $ "OnTextMeshProLoadFontAsset - { m_fontAsset . characterDictionary } ") ; // ""
118+ Log ( $ "OnTextMeshProLoadFontAsset - { m_renderer . sharedMaterial } ") ; // "perpetua_tmpro Material (UnityEngine.Material)"
119+ Log ( $ "OnTextMeshProLoadFontAsset - { m_renderer . sharedMaterial . mainTexture } ") ; // "perpetua_tmpro Atlas (UnityEngine.Texture2D)"
120+ Log ( $ "OnTextMeshProLoadFontAsset - { m_fontAsset . atlas } ") ; // ""
121+ Log ( $ "OnTextMeshProLoadFontAsset - { m_fontAsset . material } ") ;
122+ Log ( $ "OnTextMeshProLoadFontAsset - { m_renderer . receiveShadows } ") ;
123+ Log ( $ "OnTextMeshProLoadFontAsset - { m_renderer . shadowCastingMode } ") ;
124+ }
125+
126+ orig ( self ) ;
127+ }
128+
129+ private static AssetBundle abFa = null ;
130+ private static TMP_FontAsset fa = null ;
131+ private static Sprite atlas = null ;
132+
133+ private void OnChangeFontByLanguageSetFont ( On . ChangeFontByLanguage . orig_SetFont orig , ChangeFontByLanguage self )
134+ {
135+ orig ( self ) ;
136+
137+ Log ( 1 ) ;
138+
139+ if ( Language . Language . CurrentLanguage ( ) == LanguageCode . TH )
140+ {
141+ Log ( 2 ) ;
142+
143+ bool json = true ;
144+
145+ if ( json )
146+ {
147+ if ( fa == null )
148+ {
149+ Log ( 3 ) ;
150+ Assembly asm = Assembly . GetExecutingAssembly ( ) ;
151+ Log ( 4 ) ;
152+ using ( Stream s = asm . GetManifestResourceStream ( "LanguageSupport.Resources.noto_serif_thai_bold.json" ) )
153+ {
154+ Log ( 5 ) ;
155+ if ( s == null ) return ;
156+
157+ Log ( 6 ) ;
158+ byte [ ] buffer = new byte [ s . Length ] ;
159+ Log ( 7 ) ;
160+ s . Read ( buffer , 0 , buffer . Length ) ;
161+ Log ( 8 ) ;
162+ s . Dispose ( ) ;
163+
164+ Log ( 9 ) ;
165+ string jsonText = System . Text . Encoding . UTF8 . GetString ( buffer ) ;
166+
167+ Log ( 10 ) ;
168+ fa = JsonConvert . DeserializeObject < TMP_FontAsset > ( jsonText , new TmpFontConverter ( ) ) ;
169+ Log ( 10.5 ) ;
170+ fa . name = "noto_serif_thai_bold_tmpro" ;
171+ Log ( 11 ) ;
172+ Object . DontDestroyOnLoad ( fa ) ;
173+ }
174+
175+ fa . atlas = null ; // texture2d
176+ fa . material = new Material ( Shader . Find ( "GUI/Text Shader" ) ) ;
177+
178+ using ( Stream s = asm . GetManifestResourceStream ( "LanguageSupport.Resources.noto_serif_thai_bold.png" ) )
179+ {
180+ if ( s != null )
181+ {
182+ byte [ ] buffer = new byte [ s . Length ] ;
183+ s . Read ( buffer , 0 , buffer . Length ) ;
184+ s . Dispose ( ) ;
185+
186+ //Create texture from bytes
187+ var tex = new Texture2D ( 2 , 2 ) ;
188+
189+ tex . LoadImage ( buffer , true ) ;
190+
191+ // Create sprite from texture
192+ // Split is to cut off the DreamKing.Resources. and the .png
193+ atlas = Sprite . Create ( tex , new Rect ( 0 , 0 , tex . width , tex . height ) , new Vector2 ( 0.5f , 0.5f ) ) ;
194+ Object . DontDestroyOnLoad ( atlas ) ;
195+ }
196+ }
197+ fa . material . SetTexture ( "_MainTex" , atlas . texture ) ;
198+ fa . atlas = atlas . texture ;
199+
200+ fa . material . SetColor ( "_Color" , Color . white ) ;
201+ }
202+
203+ if ( fa != null )
204+ {
205+ Log ( 20 ) ;
206+ self . GetAttr < ChangeFontByLanguage , TextMeshPro > ( "tmpro" ) . font = fa ;
207+ //var tmp = self.GetAttr<ChangeFontByLanguage, TextMeshPro>("tmpro");
208+ //Log(21);
209+ //tmp.font = fa;
210+ //Log(22);
211+ //self.SetAttr<ChangeFontByLanguage, TextMeshPro>("tmpro", tmp);
212+ }
213+ }
214+ else
215+ {
216+ if ( abFa == null )
217+ {
218+ Log ( 12 ) ;
219+ Assembly asm = Assembly . GetExecutingAssembly ( ) ;
220+ Log ( 13 ) ;
221+ using ( Stream s = asm . GetManifestResourceStream ( "LanguageSupport.Resources.tmprofont" ) )
222+ {
223+ Log ( 14 ) ;
224+ if ( s == null ) return ;
225+
226+ Log ( 15 ) ;
227+ abFa = AssetBundle . LoadFromStream ( s ) ;
228+ Log ( 16 ) ;
229+ Object . DontDestroyOnLoad ( abFa ) ;
230+ }
231+ }
232+
233+ Log ( 17 ) ;
234+
235+ if ( fa == null && abFa != null )
236+ {
237+ Log ( 18 ) ;
238+ fa = abFa . LoadAsset < TMP_FontAsset > ( "noto_serif_thai_bold.asset" ) ;
239+ Log ( 18.5 ) ;
240+ fa . name = "noto_serif_thai_bold_tmpro" ;
241+ Log ( 19 ) ;
242+ Object . DontDestroyOnLoad ( fa ) ;
243+ }
244+
245+ if ( fa != null )
246+ {
247+ Log ( 20 ) ;
248+ var tmp = ( TextMeshPro ) typeof ( ChangeFontByLanguage ) . GetField ( "tmpro" , BindingFlags . Instance | BindingFlags . NonPublic ) . GetValue ( self ) ;
249+ Log ( 21 ) ;
250+ tmp . font = fa ;
251+ Log ( 22 ) ;
252+ typeof ( ChangeFontByLanguage ) . GetField ( "tmpro" , BindingFlags . Instance | BindingFlags . NonPublic ) . SetValue ( self , tmp ) ;
253+ }
254+ }
255+ }
256+ Log ( 23 ) ;
257+ }
258+
259+ private void Log ( string message )
260+ {
261+ Modding . Logger . Log ( message ) ;
262+ Debug . Log ( $ "[SFG Thing] - { message } ") ;
263+ }
264+ private void Log ( object message )
265+ {
266+ Log ( $ "{ message } ") ;
71267 }
72268
73269 private void InitLanguage ( )
@@ -126,53 +322,79 @@ private void InitLanguage()
126322
127323 #endregion
128324
129- typeof ( Language . Language ) . GetMethod ( "LoadAvailableLanguages" , BindingFlags . NonPublic | BindingFlags . Static )
130- . Invoke ( null , null ) ;
325+ Language . Language . LoadAvailableLanguages ( ) ;
131326 Language . Language . LoadLanguage ( ) ;
132327 }
133328
134- private bool OnLanguageHasLanguageFile ( On . Language . Language . orig_HasLanguageFile orig , string lang ,
135- string sheetTitle )
329+ private void OnMenuLanguageSettingPushUpdateOptionList ( On . UnityEngine . UI . MenuLanguageSetting . orig_PushUpdateOptionList orig , UnityEngine . UI . MenuLanguageSetting self )
330+ {
331+ orig ( self ) ;
332+ SupportedLanguages [ ] langs = ( SupportedLanguages [ ] ) self . GetType ( ) . GetField ( "langs" , BindingFlags . NonPublic | BindingFlags . Instance ) . GetValue ( self ) ;
333+ string [ ] array = new string [ langs . Length ] ;
334+ for ( int i = 0 ; i < langs . Length ; i ++ )
335+ {
336+ array [ i ] = ( ( LanguageCode ) langs [ i ] ) . ToString ( ) ;
337+ }
338+ self . SetOptionList ( array ) ;
339+ }
340+
341+ private bool OnLanguageHasLanguageFile ( On . Language . Language . orig_HasLanguageFile orig , string lang , string sheetTitle )
136342 {
137343 var ret = orig ( lang , sheetTitle ) ;
138344 if ( ! ret )
345+ {
139346 if ( File . Exists ( $ "{ DIR } /{ lang } /{ sheetTitle } .txt") )
347+ {
140348 ret = true ;
349+ }
350+ }
141351 return ret ;
142352 }
143353
144- private string OnLanguageGetLanguageFileContents ( On . Language . Language . orig_GetLanguageFileContents orig ,
145- string sheetTitle )
354+ private string OnLanguageGetLanguageFileContents ( On . Language . Language . orig_GetLanguageFileContents orig , string sheetTitle )
146355 {
147- var ret = orig ( sheetTitle ) ;
356+ string ret = orig ( sheetTitle ) ;
148357 if ( ret == string . Empty )
358+ {
149359 if ( File . Exists ( $ "{ DIR } /{ Language . Language . CurrentLanguage ( ) } /{ sheetTitle } .txt") )
360+ {
150361 return File . ReadAllText ( $ "{ DIR } /{ Language . Language . CurrentLanguage ( ) } /{ sheetTitle } .txt") ;
362+ }
363+ }
151364 return ret ;
152365 }
153366
154- private void OnMenuLanguageSettingRefreshAvailableLanguages (
155- MenuLanguageSetting . orig_RefreshAvailableLanguages orig , UnityEngine . UI . MenuLanguageSetting self )
367+ private void OnMenuLanguageSettingRefreshAvailableLanguages ( On . UnityEngine . UI . MenuLanguageSetting . orig_RefreshAvailableLanguages orig , UnityEngine . UI . MenuLanguageSetting self )
156368 {
157369 orig ( self ) ;
158- SupportedLanguages [ ] langs ;
370+ LanguageCode [ ] customLangs ;
159371 if ( GameManager . instance . gameConfig . hideLanguageOption )
160- langs = Enum . GetValues ( typeof ( TestingLanguages ) ) as SupportedLanguages [ ] ;
372+ {
373+ customLangs = ( Enum . GetValues ( typeof ( LanguageCode ) ) as LanguageCode [ ] ) ;
374+ }
161375 else
162- langs = Enum . GetValues ( typeof ( SupportedLanguages ) ) as SupportedLanguages [ ] ;
376+ {
377+ customLangs = ( Enum . GetValues ( typeof ( LanguageCode ) ) as LanguageCode [ ] ) ;
378+ }
163379
164- var finalLangs = new List < SupportedLanguages > ( ( SupportedLanguages [ ] ) self . GetType ( )
165- . GetField ( "langs" , BindingFlags . NonPublic | BindingFlags . Instance ) . GetValue ( self ) ) ;
380+ SupportedLanguages [ ] langs = ( SupportedLanguages [ ] ) self . GetType ( ) . GetField ( "langs" , BindingFlags . NonPublic | BindingFlags . Instance ) . GetValue ( self ) ;
381+ List < SupportedLanguages > finalLangs = new List < SupportedLanguages > ( ) ;
166382
167- foreach ( var l in langs )
168- if ( File . Exists ( $ "{ DIR } /{ l } /General.txt") )
169- finalLangs . Add ( l ) ;
383+ foreach ( var l in customLangs )
384+ {
385+ if ( File . Exists ( $ "{ DIR } /{ l } /General.txt") || ( langs . Contains ( ( SupportedLanguages ) l ) ) )
386+ {
387+ finalLangs . Add ( ( SupportedLanguages ) l ) ;
388+ }
389+ }
170390
171- self . GetType ( ) . GetField ( "langs" , BindingFlags . NonPublic | BindingFlags . Instance )
172- . SetValue ( self , finalLangs . ToArray ( ) ) ;
391+ self . GetType ( ) . GetField ( "langs" , BindingFlags . NonPublic | BindingFlags . Instance ) . SetValue ( self , finalLangs . ToArray ( ) ) ;
173392
174- self . optionList = new string [ finalLangs . Count ] ;
175- for ( var i = 0 ; i < finalLangs . Count ; i ++ ) self . optionList [ i ] = finalLangs [ i ] . ToString ( ) ;
393+ //self.optionList = new string[finalLangs.Count];
394+ //for (int i = 0; i < finalLangs.Count; i++)
395+ //{
396+ // self.optionList[i] = finalLangs[i].ToString();
397+ //}
176398 }
177399 }
178400}
0 commit comments