public Dictionary <string, Dictionary <string, string> > GetToolDict(Export.C cType) { Dictionary <string, Dictionary <string, string> > targetDict = null; switch (cType) { case Export.C.Item: targetDict = this.Item; break; case Export.C.Quest: targetDict = this.Quest; break; case Export.C.Creature: targetDict = this.Creature; break; case Export.C.Loot: targetDict = this.Loot; break; case Export.C.Vendor: targetDict = this.Vendor; break; default: Logger.Log($"Creator type '{cType}' is not defined in Profile.IsKeyDefined(). Please report this issue on GitHub.", Logger.Status.Error, true); return(null); } return(targetDict); }
/// <summary> /// Determines if an appkey is correctly defined in this profile. /// </summary> /// <param name="cType">Export.C type</param> /// <param name="appKey">Valid AppKey</param> /// <returns></returns> internal bool IsKeyDefined(Export.C cType, string appKey) { var targetDir = GetToolDict(cType); foreach (var subD in targetDir) // dictionary in table { if (subD.Value.ContainsKey(appKey)) // Has defiend appkey { string match; subD.Value.TryGetValue(appKey, out match); if (match != null && match != string.Empty) { return(true); } else { Logger.Log($"Profile Error: Appkey '{cType}.{appKey}' is has an invalid definition." + "Disable the AppKey, define a valid SqlKey or report this issue on GitHub.", Logger.Status.Error, true); return(false); } } } // None found, it's disabled return(false); }
public static string GetToolIdAppKey(Export.C toolType) { // Get the ID string appkey for this tool string idAppKey = "fixthis"; switch (toolType) { case Export.C.Creature: idAppKey = "Entry"; break; case Export.C.Item: idAppKey = "EntryId"; break; case Export.C.Loot: idAppKey = "Entry"; break; case Export.C.Quest: idAppKey = "EntryId"; break; case Export.C.Vendor: idAppKey = "NpcEntry"; break; } return(idAppKey); }
public static void DeleteCreation(Export.C type, int id) { Logger.Log($"Requesting to delete {type} {id}"); var relTabIds = GetRelevantTablesAndIds(type, id); foreach (var kvp in relTabIds) { Connection.ExecuteNonQuery($"DELETE FROM {kvp.Key} WHERE {kvp.Value}={id};"); } }
/// <summary> /// Stands for "Get Table name and Key" /// Returns the correct key for the current profile based on the app's equivalent of that key /// </summary> /// <param name="creationType"></param> /// <param name="appKey"></param> /// <param name="specialTableName">For table names that vary based on a setting, replaces %t with this string</param> /// <returns>:0:Table - 1: Sql key</returns> public void gtk(Export.C creationType, string appKey, string specialTableName = "") { // Select correct dictionary to searchfor creation Dictionary <string, Dictionary <string, string> > targetDict = null; switch (creationType) { case Export.C.Creature: targetDict = Profile.Active.Creature; break; case Export.C.Quest: targetDict = Profile.Active.Quest; break; case Export.C.Item: targetDict = Profile.Active.Item; break; case Export.C.Loot: targetDict = Profile.Active.Loot; break; case Export.C.Vendor: targetDict = Profile.Active.Vendor; break; } // Check if the key exists in the profile var table = targetDict.Where(t => // equals in this case is equivalent to null check t.Value.Where(keysDic => keysDic.Key.ToLower() == appKey.ToLower()).FirstOrDefault().Key != null ).FirstOrDefault(); // Key didn't exist in any table, ignore column IsValid = table.Key != null; if (!IsValid) { Logger.Log($"Notice: Export: {creationType.ToString()}.{appKey} not in profile. This isn't always an problem."); return; } // Key exists, generate result SqlTableName = table.Key; // Return table name // Handle unusual table names if (specialTableName != "") { SqlTableName = SqlTableName.Replace("%t", specialTableName); } // Find appkey again and put sqlkey in result SqlKey = table.Value.Where(keys => keys.Key.ToLower() == appKey.ToLower()).First().Value; }
/// <summary> /// Checks if an appKey exists in the profile /// This will not work for lookuptool /// </summary> /// <param name="toolName">Creature, Quest etc</param> /// <param name="appKey">Name of the application key requested</param> /// <returns></returns> public static bool HasAppKey(Export.C tool, string appKey) { try { // Return true if appkey exists in targetTool var targetTool = GetToolDataFromC(tool); return(targetTool.Values.Where(keys => keys.ContainsKey(appKey)).Count() > 0); } catch { Logger.Log($"Application Error: Profile.HasAppKey failed to ({tool.ToString()}, {appKey}. Please report this issue.", Logger.Status.Error, true); return(false); } }
public static string GetPrimaryTable(Export.C toolType) { string idAppKey = GetToolIdAppKey(toolType); try // Find the table name & return it { var targetTool = GetToolDataFromC(toolType); return(targetTool.Where(kp => kp.Value .Where(keys => keys.Key == idAppKey).Count() > 0 ).First().Key); } catch { Logger.Log("Profile Error: Lookup tool failed to find primary table. Profile is not set up correctly."); return("InvalidTable"); } }
/// <summary> /// Returns next ID for the selected tool /// </summary> /// <param name="toolType"></param> /// <returns></returns> internal static int GetNextId(Export.C toolType) { string toolIdAppKey = ProfileHelper.GetToolIdAppKey(toolType); string toolSqlKey = ProfileHelper.GetSqlKey(toolType, toolIdAppKey); string tableName = ProfileHelper.GetPrimaryTable(toolType); string query = $"SELECT MAX({toolSqlKey}) FROM {tableName}"; object result = ExecuteScalar(query, requestConfig: false); if (result == null || result is DBNull) { return(0); } else { return(Convert.ToInt32(result) + 1); } }
public static string GetSqlKey(Export.C toolType, string appKey) { try { // Find the table containing the appkey var targetTool = GetToolDataFromC(toolType); var table = targetTool.Where(kp => kp.Value .Where(keys => keys.Key == appKey).Count() > 0 ).First().Value; // Find it again & return sqlkey return(table.Where(keys => keys.Key == appKey).First().Value); } catch { Logger.Log("Profile Error: Lookup tool failed to find primary table. Profile is not set up correctly."); return("InvalidTable"); } }
public static string GetSqlKey(Export.C toolType, string appKey) { try { // Find the table containing the appkey Logger.Log($"ProfileHelper: GetSqlKey({toolType.ToString()}, {appKey})"); var targetTool = GetToolDataFromC(toolType); var table = targetTool.Where(kp => kp.Value .Where(keys => keys.Key == appKey).Count() > 0 ).First().Value; // Find it again & return sqlkey string result = table.Where(keys => keys.Key == appKey).First().Value; Logger.Log("ProfileHelper: GetSqlKey found SQLKey: {result}"); return(result); } catch { Logger.Log($"Profile Error: Lookup tool failed to find sqlKey for appKey {appKey}. returning 'InvalidAppKey'"); return("InvalidAppKey"); } }
/// <summary> /// Returns visibility if an appkey is correctly defined in this profile. /// </summary> /// <param name="cType">Export.C type</param> /// <param name="appKey">Valid AppKey</param> /// <returns></returns> internal Visibility VisibileIfKeyDefined(Export.C cType, string appKey) { return(IsKeyDefined(cType, appKey) ? Visibility.Visible : Visibility.Collapsed); }
/// <summary> /// Constructor for default fields. Runs gtk to define properties /// </summary> /// <param name="appKey"></param> /// <param name="value"></param> /// <param name="c"></param> /// <param name="specialTableName"></param> public ExpKvp(string appKey, dynamic value, Export.C c, string specialTableName = "") { Value = value; gtk(c, appKey, specialTableName); }
public static Dictionary <string, Dictionary <string, string> > GetToolDataFromC(Export.C toolType) { try { // Find the correct Profile property (equest, creature etc) based on C return((Dictionary <string, Dictionary <string, string> >)Profile.Active.GetType().GetProperty(toolType.ToString()).GetValue(Profile.Active, null)); } catch { Logger.Log($"Application Error: Profile.GetToolDataFromC() failed on {toolType.ToString()} Please report this issue.", Logger.Status.Error, true); return(null); // should be impossible anyway } }
/// <summary> /// Throws warning if an addon table doesn't have table ID defined in customs /// It doesn't validate the values. Only checks for tablename in customs. /// </summary> /// <param name="item"></param> private bool ValidateAddonTableCustoms(Dictionary <string, Dictionary <string, string> > item, Export.C c) { bool result = true; if (item.Count == 1) { return(true); } // Exceptions to the rule. These tables act differently and have a dedicated column in the profile // Lists appkeys in tables which are treated as exceptions. string[] exceptionalAppKeys = new string[] { "ResistanceCreatureId", "SpellCreatureID", "InhabitCreatureID", }; foreach (var table in item.Keys) { string primaryAppKey = ProfileHelper.GetToolIdAppKey(c); if (item[table].ContainsKey(primaryAppKey)) { continue; // this is the primary table & requires no custom } // Check exceptions to the rule bool foundExceptional = false; foreach (var except in exceptionalAppKeys) { if (item[table].ContainsKey(except)) { foundExceptional = true; continue; // Exceptional, move on } } if (foundExceptional) { continue; } // Throw warning if no custom was found for this table if (!EditingProfile.CustomFields.ContainsKey(table)) { Logger.Log($"Warning: You need to define custom keys for all addon tables. Custom key missing for '{table}'. See documentation for more info.", Logger.Status.Warning, true); result = false; } } return(result); }
/// <summary> /// Used for UPDATE queries, determines the correct SqlKeys to base the query on /// </summary> /// <param name="type"></param> /// <param name="id"></param> /// <returns>tablename, id column</returns> public static Dictionary <string, string> GetRelevantTablesAndIds(Export.C type, int id) { // Table name, sqlKey Dictionary <string, string> fieldsToCheck = new Dictionary <string, string>(); string idAppKey = string.Empty; try { // Select correct dictionary to search for creation Dictionary <string, Dictionary <string, string> > targetDict = null; switch (type) { case Export.C.Creature: targetDict = Profile.Active.Creature; idAppKey = "Entry"; break; case Export.C.Quest: targetDict = Profile.Active.Quest; idAppKey = "EntryId"; break; case Export.C.Item: targetDict = Profile.Active.Item; idAppKey = "EntryId"; break; // Other tools allow duplicate IDs and this method doesn't apply to them. // Defining tools here that allow duplicate entry IDs will break UPDATE queries for them because spaghetti. default: return(null); } // Generate list of tables and IDs from profile // Add primary table var primTableData = targetDict .Where(x => x.Value.Keys.Contains(idAppKey)) .First(); fieldsToCheck.Add(primTableData.Key, primTableData.Value[idAppKey]); // Add secondary tables foreach (var tablesDict in Profile.Active.CustomFields) { foreach (var keysDict in tablesDict.Value) { if (keysDict.Key.StartsWith(type.ToString())) { fieldsToCheck.Add(tablesDict.Key, keysDict.Value); } } } // Add special cases if (type == Export.C.Creature) { } // Return result return(fieldsToCheck); } catch (Exception ex) { Logger.Log($"Profile: CanWriteHandleOverride failed to determine ID of a table for {type}. Export failed.", Logger.Status.Error, true); Logger.Log(ex.Message); return(null); // Failed, cancel insert } }
/// <summary> /// Checks if an ID is already in use. Prompts to overwrite if needed. /// Deletes original row with given id if user agrees. /// </summary> /// <param name="type">creation type</param> /// <param name="id">creation id</param> /// <returns>True if user gave permission to insert</returns> public static bool CheckDuplicateHandleOverride(Export.C type, int id) { // Get primary keys to base update queries on var fieldsToCheck = GetRelevantTablesAndIds(type, id); if (fieldsToCheck == null) { return(true); // Irrelevant to this type or error } // Look for duplicates bool alreadyExists = false; try { // Query every relevant table to see if ID already exists foreach (var kvp in fieldsToCheck) { if (kvp.Key.Contains("%t")) { continue; // I'm not gonna even } var result = Connection.ExecuteScalar($"SELECT COUNT(*) AS matches FROM {kvp.Key} WHERE {kvp.Value} = {id};"); if ((dynamic)result > 0) { alreadyExists = true; break; } } } catch (Exception ex) { Logger.Log("Database Error: There was an error looking for duplicates. Creation will not export.", Logger.Status.Error, true); Logger.Log(ex.Message); return(false); // Failed, cancel insert } // Ask if user wants to overwrite if (alreadyExists) { var dr = MessageBox.Show($"WARNING: {type} with ID {id} already exists.{Environment.NewLine}Would you like to replace it?", "Already Exists", MessageBoxButton.YesNoCancel, MessageBoxImage.Warning, MessageBoxResult.No); if (dr == MessageBoxResult.Yes) { // Delete from database foreach (var kvp in fieldsToCheck) { // Handle quest customs if (type == Export.C.Quest) { // Handle %t tablenames if (kvp.Key.Contains("%t")) { string[] starterEnderTypes = new string[] { "creature", "gameobject", }; string overrideTableName = ""; foreach (string replacement in starterEnderTypes) { if (kvp.Key.Contains("queststarter")) { overrideTableName = kvp.Key.Replace("%t", replacement); Connection.ExecuteNonQuery($"DELETE FROM {overrideTableName} WHERE {kvp.Value} = {id};"); } else if (kvp.Key.Contains("questender")) { overrideTableName = kvp.Key.Replace("%t", replacement); Connection.ExecuteNonQuery($"DELETE FROM {overrideTableName} WHERE {kvp.Value} = {id};"); } else { Logger.Log("Profile Error: QuestGiver customs with wildcard only accept tablenames containing 'queststarter' and 'questender'." + Environment.NewLine + "This is because customs have no other way to identify that the custom is in relation to queststarter/ender." + Environment.NewLine + "If this causes issues, it's preferable to just use 'creature_questender' instead of '%t_questender' and starter.", Logger.Status.Error, true); } } } } else if (type == Export.C.Creature) { if (Profile.Active.IsKeyDefined(Export.C.Creature, "SpellCreatureID")) { var d = new ExpKvp("SpellCreatureID", null, Export.C.Creature); Connection.ExecuteNonQuery($"DELETE FROM {d.SqlTableName} WHERE {d.SqlKey} = {id};"); } if (Profile.Active.IsKeyDefined(Export.C.Creature, "ResistanceCreatureId")) { var d = new ExpKvp("ResistanceCreatureId", null, Export.C.Creature); Connection.ExecuteNonQuery($"DELETE FROM {d.SqlTableName} WHERE {d.SqlKey} = {id};"); } if (Profile.Active.IsKeyDefined(Export.C.Creature, "InhabitCreatureID")) { var d = new ExpKvp("InhabitCreatureID", null, Export.C.Creature); Connection.ExecuteNonQuery($"DELETE FROM {d.SqlTableName} WHERE {d.SqlKey} = {id};"); } } // No special, just delete. if (!kvp.Key.Contains("%t")) { Connection.ExecuteNonQuery($"DELETE FROM {kvp.Key} WHERE {kvp.Value} = {id};"); } } return(true); // Duplicate, deleted & permission to insert } else { return(false); // Duplicate found, user does not wish to override } } else { return(true); // Not duplicate, proceed as normal. } }