Exemple #1
0
        /// <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);
            }
        }
Exemple #2
0
        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]);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
 /// <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))));
 }
Exemple #5
0
 /// <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()));
 }
Exemple #6
0
 /// <summary>
 /// Adds a new Dictionary object to the collection.
 /// </summary>
 /// <param name="dictionary"></param>
 public void AddDictionary(RantDictionary dictionary)
 {
     _wordLists[dictionary.Name] = dictionary;
 }
Exemple #7
0
        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);
            }
        }
Exemple #8
0
        /// <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);
	        }
        }
Exemple #9
0
 /// <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;
 }
Exemple #10
0
 /// <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);
     }
 }
Exemple #11
0
        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;
        }
Exemple #12
0
        /// <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);
                    }
                }
            }
        }
Exemple #13
0
        /// <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);
                    }
                }
            }
        }