diff --git a/GK6X/Program.cs b/GK6X/Program.cs index fb0bc69..0ec45a6 100644 --- a/GK6X/Program.cs +++ b/GK6X/Program.cs @@ -205,6 +205,164 @@ static void Run(bool asGUI) case "gui": WebGUI.Run(); break; + case "gui_to_txt": + { + if (string.IsNullOrEmpty(WebGUI.UserDataPath)) + { + Log("Load GUI first"); + } + else + { + string userDataPath = WebGUI.UserDataPath; + int accountId = 0; + string accountDir = Path.Combine(userDataPath, "Account", accountId.ToString()); + if (Directory.Exists(accountDir)) + { + foreach (KeyboardDevice device in KeyboardDeviceManager.GetConnectedDevices()) + { + string deviceDir = Path.Combine(userDataPath, "Account", accountId.ToString(), "Devices", device.State.ModelId.ToString()); + if (Directory.Exists(deviceDir)) + { + Dictionary macrosById = new Dictionary(); + UserDataFile userDataFile = new UserDataFile(); + foreach (string file in Directory.GetFiles(deviceDir, "*.cmf")) + { + string config = Encoding.UTF8.GetString(CMFile.Load(file)); + Dictionary data = MiniJSON.Json.Deserialize(config) as Dictionary; + int modelIndex = (int)Convert.ChangeType(data["ModeIndex"], typeof(int)); + KeyboardLayer layer = (KeyboardLayer)modelIndex; + + ////////////////////////////////////////// + // Keys / macros (NOTE: Macros on different layers might wipe each other. look into.) + ////////////////////////////////////////// + for (int i = 0; i < 2; i++) + { + string setStr = i == 0 ? "KeySet" : "FnKeySet"; + if (data.ContainsKey(setStr)) + { + List keys = data[setStr] as List; + foreach (object keyObj in keys) + { + Dictionary key = keyObj as Dictionary; + int keyIndex = (int)Convert.ChangeType(key["Index"], typeof(int)); + uint driverValue = KeyValues.UnusedKeyValue; + string driverValueStr = (string)key["DriverValue"]; + if (driverValueStr.StartsWith("0x")) + { + if (uint.TryParse(driverValueStr.Substring(2), System.Globalization.NumberStyles.HexNumber, null, out driverValue)) + { + if (KeyValues.GetKeyType(driverValue) == DriverValueType.Macro && key.ContainsKey("Task")) + { + Dictionary task = key["Task"] as Dictionary; + if (task != null && (string)task["Type"] == "Macro") + { + Dictionary taskData = task["Data"] as Dictionary; + string macroGuid = (string)taskData["GUID"]; + string macroFile = Path.Combine(userDataPath, "Account", accountId.ToString(), "Macro", macroGuid + ".cms"); + if (File.Exists(macroFile)) + { + UserDataFile.Macro macro = new UserDataFile.Macro(null); + macro.LoadFile(macroFile); + macro.RepeatCount = (byte)Convert.ChangeType(taskData["Repeats"], typeof(byte)); + macro.RepeatType = (MacroRepeatType)(byte)Convert.ChangeType(taskData["StopMode"], typeof(byte)); + macro.Id = KeyValues.GetKeyData2(driverValue); + macrosById[macro.Id] = macro; + userDataFile.Macros[macroGuid] = macro; + } + } + } + } + else + { + driverValue = KeyValues.UnusedKeyValue; + } + } + if (keyIndex >= 0 && keyIndex < device.State.MaxLogicCode && driverValue != KeyValues.UnusedKeyValue) + { + KeyboardState.Key keyInfo = device.State.GetKeyByLogicCode(keyIndex); + if (keyInfo != null) + { + Dictionary vals = userDataFile.FindOrAddLayer(layer, i > 0).Keys; + if (Enum.IsDefined(typeof(DriverValue), driverValue)) + { + vals[keyInfo.DriverValueName.ToLower()] = driverValue; + } + else + { + Log("Failed to map index " + keyIndex + " to " + driverValue + " on layer " + layer + + (i > 0 ? " fn" : string.Empty)); + } + } + } + } + } + } + + ////////////////////////////////////////// + // Lighting + ////////////////////////////////////////// + Dictionary effects = new Dictionary(); + string[] leHeaders = { "ModeLE", "DriverLE" }; + foreach (string leHeader in leHeaders) + { + if (data.ContainsKey(leHeader)) + { + List leEntries = data[leHeader] as List; + if (leEntries == null) + { + // There's only one ModeLE + leEntries = new List(); + leEntries.Add(data[leHeader]); + } + foreach (object entry in leEntries) + { + Dictionary modeLE = entry as Dictionary; + string leGuid = (string)modeLE["GUID"]; + if (!string.IsNullOrEmpty(leGuid)) + { + string filePath = Path.Combine(userDataPath, "Account", accountId.ToString(), "LE", leGuid + ".le"); + if (!effects.ContainsKey(leGuid) && File.Exists(filePath)) + { + UserDataFile.LightingEffect le = new UserDataFile.LightingEffect(userDataFile, null); + le.Load(device.State, Encoding.UTF8.GetString(CMFile.Load(filePath))); + le.Layers.Add(layer); + userDataFile.LightingEffects[leGuid] = le; + effects[leGuid] = le; + } + } + else + { + object leDataObj; + if (modeLE.TryGetValue("LEData", out leDataObj)) + { + Dictionary leData = leDataObj as Dictionary; + if (leData != null) + { + // This should be static lighting data only + UserDataFile.LightingEffect le = new UserDataFile.LightingEffect(userDataFile, null); + le.LoadStatic(device.State, leData); + le.Layers.Add(layer); + userDataFile.LightingEffects[Guid.NewGuid().ToString()] = le; + } + } + } + } + } + } + } + userDataFile.SaveFromGUI(device.State, Path.Combine(UserDataPath, device.State.ModelId + "_exported.txt")); + Log("Done"); + break; + } + } + } + else + { + Log("Account settings not found for account id " + accountId); + } + } + } + break; case "gui_le": { string userDataPath = WebGUI.UserDataPath; diff --git a/GK6X/UserDataFile.cs b/GK6X/UserDataFile.cs index 91d791b..d2a1abc 100644 --- a/GK6X/UserDataFile.cs +++ b/GK6X/UserDataFile.cs @@ -302,6 +302,32 @@ public class Param public bool UseRawValues; } + public static Dictionary Discover() + { + Dictionary names = new Dictionary(); + string path = Path.Combine(Program.DataBasePath, "lighting"); + if (Directory.Exists(path)) + { + foreach (string file in Directory.GetFiles(path, "*.le")) + { + try + { + string str = File.ReadAllText(file); + Dictionary json = Json.Deserialize(str) as Dictionary; + string guid; + if (json != null && Json.TryGetValue(json, "GUID", out guid)) + { + names[guid.ToLower()] = Path.GetFileNameWithoutExtension(file); + } + } + catch + { + } + } + } + return names; + } + public bool Load(KeyboardState keyboard) { try @@ -655,7 +681,7 @@ private bool TryParseDriverValue(string str, out DriverValue result, out string return false; } - private Layer FindOrAddLayer(KeyboardLayer layer, bool fn) + public Layer FindOrAddLayer(KeyboardLayer layer, bool fn) { Dictionary layers = fn ? FnLayers : Layers; Layer result; @@ -1217,5 +1243,83 @@ private void Load(KeyboardState keyboard, string file, params GroupType[] groups } } } + + public void SaveFromGUI(KeyboardState keyboard, string path) + { + StringBuilder sb = new StringBuilder(); + if (Macros.Count > 0) + { + foreach (Macro macro in Macros.Values) + { + sb.AppendLine("[Macro(" + macro.Name + "," + macro.DefaultDelay + "," + macro.RepeatType + "," + macro.RepeatCount + ")]"); + foreach (Macro.Action action in macro.Actions) + { + string delayStr = action.Delay > 0 ? ":" + action.Delay : string.Empty; + string modifierStr = action.Modifier != DriverValueModifer.None ? action.Modifier.ToString() : string.Empty; + string keyStr = (!string.IsNullOrEmpty(modifierStr) ? "+" : string.Empty) + (action.KeyCode > 0 ? ((DriverValue)KeyValues.GetLongDriverValue(action.KeyCode)).ToString() : string.Empty); + if (!string.IsNullOrEmpty(modifierStr) || !string.IsNullOrEmpty(keyStr)) + { + sb.AppendLine(action.Type + ":" + modifierStr + keyStr + delayStr); + } + } + sb.AppendLine(); + } + sb.AppendLine(); + } + + if (LightingEffects.Count > 0) + { + // TODO: Copy lighting effect file over from data file + Dictionary names = LightingEffect.Discover(); + foreach (KeyValuePair le in LightingEffects) + { + string name; + if (le.Value.Layers.Count > 0 && names.TryGetValue(le.Key.ToLower(), out name)) + { + sb.AppendLine("Lighting[(" + name + ")," + string.Join(",", le.Value.Layers) + "]"); + } + } + sb.AppendLine(); + } + + + for (int i = 0; i < 2; i++) + { + foreach (KeyValuePair layer in i == 0 ? Layers : FnLayers) + { + sb.AppendLine("[" + (i > 0 ? "Fn" : string.Empty) + layer.Key + "]"); + uint[] defaultDriverValues = i > 0 ? keyboard.GetLayer(layer.Key).FnKeySet : keyboard.GetLayer(layer.Key).KeySet; + for (int j = 0; j < keyboard.MaxLogicCode; j++) + { + KeyboardState.Key key = keyboard.GetKeyByLogicCode(j); + if (key != null && j < defaultDriverValues.Length) + { + uint driverValue = layer.Value.GetKey(key); + if (driverValue != KeyValues.UnusedKeyValue && driverValue != defaultDriverValues[j]) + { + switch (KeyValues.GetKeyType(driverValue)) + { + case DriverValueType.Macro: + { + byte macroId = KeyValues.GetKeyData2(driverValue); + Macro macro = Macros.Values.FirstOrDefault(x => x.Id == macroId); + if (macro != null) + { + sb.AppendLine((DriverValue)defaultDriverValues[j] + ":Macro(" + macro.Name + ")"); + } + } + break; + default: + sb.AppendLine((DriverValue)defaultDriverValues[j] + ":" + (DriverValue)driverValue); + break; + } + } + } + } + sb.AppendLine(); + } + } + File.WriteAllText(path, sb.ToString()); + } } }