/// <summary> /// Adds the tables from the specified dictionary to the package. /// </summary> /// <param name="dictionary">The dictionary to add.</param> public void AddDictionary(RantDictionary dictionary) { if (_tables == null) _tables = new HashSet<RantDictionaryTable>(); foreach (var table in dictionary.GetTables()) { _tables.Add(table); } }
internal RantDictionaryTerm Query(RantDictionary dictionary, Sandbox sb, Query query, CarrierState syncState) { RebuildCache(); int index = !String.IsNullOrEmpty(query.PluralSubtype) && sb.TakePlural() ? GetSubtypeIndex(query.PluralSubtype) : GetSubtypeIndex(query.Subtype); if (index == -1) { return(null); } var filtersEnumerable = query.GetNonClassFilters(); var filters = filtersEnumerable as Filter[] ?? filtersEnumerable.ToArray(); IEnumerable <RantDictionaryEntry> pool = _cache.Filter(query.GetClassFilters().SelectMany(cf => cf.GenerateRequiredSet(sb.RNG)).Distinct(), dictionary, this)?.ToList(); if (pool == null) { return(null); } if (filters.Length > 0) { pool = pool.Where((e, i) => filters.OrderBy(f => f.Priority).All(f => f.Test(dictionary, this, e, index, query))); } if (!pool.Any()) { return(null); } return(query.HasCarrier ? syncState.GetEntry(query.Carrier, index, pool, sb.RNG, dictionary.EnableWeighting && this.EnableWeighting)?[index] : pool.ToList().PickEntry(sb.RNG, dictionary.EnableWeighting && this.EnableWeighting)?[index]); }
internal string Query(RantDictionary dictionary, RNG rng, Query query, QueryState syncState) { var index = String.IsNullOrEmpty(query.Subtype) ? 0 : GetSubtypeIndex(query.Subtype); if (index == -1) { return("[Bad Subtype]"); } var pool = query.ClassFilter.IsEmpty ? _entries : _entries.Where(e => query.ClassFilter.Test(e, query.Exclusive)); if (_hidden.Any()) { var hide = _hidden.Where(hc => !query.ClassFilter.AllowsClass(hc)) .Except(dictionary.IncludedHiddenClasses); pool = pool.Where(e => !hide.Any(e.ContainsClass)); } if (query.RegexFilters.Any()) { pool = query.RegexFilters.Aggregate(pool, (current, regex) => current.Where(e => regex.Item1 == regex.Item2.IsMatch(e.Terms[index].Value))); } if (query.SyllablePredicate != null) { pool = pool.Where(e => query.SyllablePredicate.Test(e.Terms[index].SyllableCount)); } if (!pool.Any()) { return(MissingTerm); } return(syncState.GetEntry(query.Carrier, index, pool, rng)?[index] ?? MissingTerm); }
/// <summary> /// Loads all dictionary (.dic) files from the specified directories and returns a Vocabulary object that contains the loaded dictionaries. /// </summary> /// <param name="directories">The directories from which to load dictionaries.</param> /// <param name="filter">Indicates whether dictionary entries marked with the #nsfw flag should be loaded.</param> /// <returns></returns> public static RantVocabulary FromMultiDirectory(string[] directories, NsfwFilter filter) { return(new RantVocabulary(directories.SelectMany(path => Directory.GetFiles(path, "*.dic", SearchOption.AllDirectories)).Select(file => RantDictionary.FromFile(file, filter)))); }
/// <summary> /// Loads all dictionary (.dic) files from the specified directory and returns a Vocabulary object that contains the loaded dictionaries. /// </summary> /// <param name="directory">The directory from which to load dictionaries.</param> /// <param name="filter">Indicates whether dictionary entries marked with the #nsfw flag should be loaded.</param> /// <returns></returns> public static RantVocabulary FromDirectory(string directory, NsfwFilter filter) { return(new RantVocabulary(Directory.GetFiles(directory, "*.dic", SearchOption.AllDirectories).Select(file => RantDictionary.FromFile(file, filter)).ToList())); }
/// <summary> /// Adds a new Dictionary object to the collection. /// </summary> /// <param name="dictionary"></param> public void AddDictionary(RantDictionary dictionary) { _wordLists[dictionary.Name] = dictionary; }
public IEnumerable <RantDictionaryEntry> Filter(IEnumerable <ClassFilterRule> rules, RantDictionary dictionary, RantDictionaryTable table) { lock (syncObject) { int startIndex = 0; var ruleArray = rules as ClassFilterRule[] ?? rules.ToArray(); HashSet <RantDictionaryEntry> setCached; var set = GetPool(); var hide = table.HiddenClasses // Exclude overridden hidden classes .Except(dictionary.IncludedHiddenClasses) // Exclude hidden classes filtered for .Where(cl => !ruleArray.Any(rule => rule.ShouldMatch && String.Equals(rule.Class, cl, StringComparison.InvariantCultureIgnoreCase))).ToArray(); // Get initial pool if (hide.Length > 0) { // Retrieve the inverse pool of the first hidden class if (!_invCache.TryGetValue(hide[0], out setCached)) { setCached = table.EntriesHash; } } else if (ruleArray.Length > 0) { if (ruleArray[0].ShouldMatch) { if (!_cache.TryGetValue(ruleArray[0].Class, out setCached)) { return(null); } } else { if (!_invCache.TryGetValue(ruleArray[0].Class, out setCached)) { setCached = table.EntriesHash; } } startIndex = 1; } else { setCached = table.EntriesHash; } // Transfer items from cached pool to our new pool and exclude hidden classes foreach (var item in setCached) { if (hide.Length == 0 || !hide.Any(cl => item.ContainsClass(cl))) { set.Add(item); } } // Apply filters by intersecting pools for (int i = startIndex; i < ruleArray.Length; i++) { if (ruleArray[i].ShouldMatch) { if (_cache.TryGetValue(ruleArray[i].Class, out setCached)) { set.IntersectWith(setCached); } else { return(null); } } else { if (_invCache.TryGetValue(ruleArray[i].Class, out setCached)) { set.IntersectWith(setCached); } } } return(set); } }
/// <summary> /// Loads the specified package into the engine. /// </summary> /// <param name="package">The package to load.</param> /// <param name="mergeBehavior">The table merging strategy to employ.</param> public void LoadPackage(RantPackage package, TableMergeBehavior mergeBehavior = TableMergeBehavior.Naive) { if (package == null) throw new ArgumentNullException(nameof(package)); if (_loadedPackages.Contains(RantPackageDependency.Create(package))) return; var patterns = package.GetPatterns(); var tables = package.GetTables(); if (patterns.Any()) { foreach (var pattern in patterns) { _patternCache[pattern.Name] = pattern; if (pattern.Module != null) PackageModules[pattern.Name] = pattern.Module; } } if (tables.Any()) { if (_dictionary == null) { _dictionary = new RantDictionary(tables, mergeBehavior); } else { foreach (var table in tables) { _dictionary.AddTable(table, mergeBehavior); } } } _loadedPackages.Add(RantPackageDependency.Create(package)); foreach (var dependency in package.GetDependencies()) { RantPackage pkg; if (!_resolver.TryResolvePackage(dependency, out pkg)) throw new FileNotFoundException($"Package '{package}' was unable to resolve dependency '{dependency}'"); LoadPackage(pkg, mergeBehavior); } }
/// <summary> /// Creates a new RantEngine object with the specified vocabulary. /// </summary> /// <param name="dictionary">The vocabulary to load in this instance.</param> public RantEngine(RantDictionary dictionary) { _dictionary = dictionary; }
/// <summary> /// Creates a new RantEngine object that loads vocabulary from the specified path. /// </summary> /// <param name="dictionaryPath">The path to the dictionary files to load.</param> public RantEngine(string dictionaryPath) { if (!String.IsNullOrEmpty(dictionaryPath)) { _dictionary = RantDictionary.FromDirectory(dictionaryPath); } }
internal string Query(RantDictionary dictionary, RNG rng, Query query, QueryState syncState) { var index = String.IsNullOrEmpty(query.Subtype) ? 0 : GetSubtypeIndex(query.Subtype); if (index == -1) return "[Bad Subtype]"; var pool = query.ClassFilter.IsEmpty ? _entries : _entries.Where(e => query.ClassFilter.Test(e, query.Exclusive)); if (_hidden.Any()) { var hide = _hidden.Where(hc => !query.ClassFilter.AllowsClass(hc)) .Except(dictionary.IncludedHiddenClasses); pool = pool.Where(e => !hide.Any(e.ContainsClass)); } if (query.RegexFilters.Any()) pool = query.RegexFilters.Aggregate(pool, (current, regex) => current.Where(e => regex.Item1 == regex.Item2.IsMatch(e.Terms[index].Value))); if (query.SyllablePredicate != null) pool = pool.Where(e => query.SyllablePredicate.Test(e.Terms[index].SyllableCount)); if (!pool.Any()) return MissingTerm; return syncState.GetEntry(query.Carrier, index, pool, rng)?[index] ?? MissingTerm; }
/// <summary> /// Loads the package at the specified file path into the engine. /// </summary> /// <param name="path">The path to the package to load.</param> /// <param name="mergeBehavior">The table merging strategy to employ.</param> public void LoadPackage(string path, TableMergeBehavior mergeBehavior = TableMergeBehavior.Naive) { if (String.IsNullOrEmpty(path)) throw new ArgumentException("Path cannot be null nor empty."); if (String.IsNullOrEmpty(Path.GetExtension(path))) { path += ".rantpkg"; } var package = RantPackage.Load(path); var patterns = package.GetPatterns(); var tables = package.GetTables(); if (patterns.Any()) { foreach (var pattern in patterns) _patternCache[pattern.Name] = pattern; } if (tables.Any()) { if (_dictionary == null) { _dictionary = new RantDictionary(tables, mergeBehavior); } else { foreach (var table in tables) { _dictionary.AddTable(table, mergeBehavior); } } } }
/// <summary> /// Loads the specified package into the engine. /// </summary> /// <param name="package">The package to load.</param> /// <param name="mergeBehavior">The table merging strategy to employ.</param> public void LoadPackage(RantPackage package, TableMergeBehavior mergeBehavior = TableMergeBehavior.Naive) { if (package == null) throw new ArgumentNullException(nameof(package)); var patterns = package.GetPatterns(); var tables = package.GetTables(); if (patterns.Any()) { foreach (var pattern in patterns) _patternCache[pattern.Name] = pattern; } if (tables.Any()) { if (_dictionary == null) { _dictionary = new RantDictionary(tables, mergeBehavior); } else { foreach (var table in tables) { _dictionary.AddTable(table, mergeBehavior); } } } }