1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
namespace OpenRCT2.Legacy.ObjectExporter
open System
open System.Collections.Generic
open System.IO
open System.Text
module Localisation =
type ObjectStrings = IDictionary<string, IDictionary<string, string>>
let private toMutableDictionary (d: IDictionary<'TKey, 'TValue>) =
new Dictionary<'TKey, 'TValue>(d)
// seq (a, b, c) -> seq { (a, seq { (b, c) }) }
let private groupByT1of3 (items: ('a * 'b * 'c) seq) =
items
|> Seq.groupBy (fun (key, _, _) -> key)
|> Seq.map (fun (key, value) ->
let newValue =
value
|> Seq.map (fun (_, b, c) -> (b, c))
(key, newValue))
let private getObjectStringsFromLanguageFile (path: string) =
printfn "Reading object strings from %s" (Path.GetFileName path)
let (|Object|_|) (s : string) =
let st = s.Trim()
if (st.StartsWith("[") && st.EndsWith("]")) then
Some (st.Substring(1, st.Length - 2))
else
None
let (|Property|_|) (name: string) (s : string) =
let st = s.Trim()
match st.IndexOf(':') with
| -1 -> None
| i ->
let left = st.Remove(i).Trim()
let right = st.Substring(i + 1)
if left = name then Some (right.Trim())
else None
let mutable curObject = None
let mutable curStrings = []
let items = new ResizeArray<string * (string * string) list>()
let lines = File.ReadAllLines path
for line in lines do
let addString key value =
curStrings <- (key, value) :: curStrings
match line with
| Object s ->
match curObject with
| None -> ()
| Some obj ->
// Add the strings for the object
items.Add (obj, curStrings)
curObject <- Some s
curStrings <- []
| Property "STR_NAME" s -> addString "name" s
| Property "STR_DESC" s -> addString "description" s
| Property "STR_CPTY" s -> addString "capacity" s
| _ -> ()
items
let getOpenObjectStrings languageDirectory : IDictionary<string, ObjectStrings> =
languageDirectory
|> Directory.GetFiles
|> Seq.map (fun f ->
let lang = Path.GetFileNameWithoutExtension f
getObjectStringsFromLanguageFile f
|> Seq.map (fun (objName, strings) -> (objName, lang, strings))
|> Seq.toList)
|> Seq.collect id
|> groupByT1of3
|> Seq.map (fun (objName, entries) ->
let objectToStrings =
entries
|> Seq.map (fun (lang, strings) ->
strings
|> Seq.map (fun (key, str) -> (key, lang, str)))
|> Seq.collect id
|> groupByT1of3
|> Seq.map (fun (key, value) ->
let langToStrings =
value
|> Seq.map (fun (lang, str) -> (lang, str))
|> dict
(key, langToStrings))
|> dict
(objName, objectToStrings))
|> dict
let overlayStrings (overlayStrings: ObjectStrings) (strings: ObjectStrings) : ObjectStrings =
let newStrings = toMutableDictionary strings
for kvp in Seq.toArray newStrings do
newStrings.[kvp.Key] <- toMutableDictionary kvp.Value
for kvp in overlayStrings do
// Get language to string dictionary
let sKey =
match newStrings.TryGetValue kvp.Key with
| true, l2s ->
let l2s = toMutableDictionary l2s
newStrings.[kvp.Key] <- l2s
l2s
| _ ->
let l2s = new Dictionary<string, string>()
newStrings.[kvp.Key] <- l2s
l2s
// Overlay strings
for kvp2 in kvp.Value do
sKey.Item(kvp2.Key) <- kvp2.Value
newStrings :> ObjectStrings
let decodeStringFromRCT2 language s =
let decodedBytes =
let rec decode s =
match s with
| [] -> []
| 255uy :: a :: b :: tail -> [a; b] @ decode tail
| c :: tail -> c :: decode tail
s
|> Array.toList
|> decode
|> List.toArray
let codepage =
match language with
| "ja-JP" -> 932
| "ko-KR" -> 949
| "zh-CN" -> 936
| "zh-TW" -> 950
| _ -> 1252
Encoding.GetEncoding(codepage)
.GetString(decodedBytes)
|