Conditions refactor.

This commit is contained in:
ruri
2019-11-02 02:49:49 +01:00
parent 729ddf899d
commit 86cf4cefea
9 changed files with 117 additions and 56 deletions
@@ -1,5 +1,6 @@
using OpenBullet.ViewModels;
using RuriLib;
using RuriLib.Functions.Conditions;
using RuriLib.Models;
using System;
using System.Windows;
@@ -90,7 +91,7 @@ namespace OpenBullet.Pages.StackerBlocks
private void conditionCombobox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var tag = (KeyFullId)(((ComboBox)e.OriginalSource).Tag);
vm.GetKeychainById(tag.ParentId).GetKeyById(tag.KeyId).Condition = (RuriLib.Condition)((ComboBox)e.OriginalSource).SelectedIndex;
vm.GetKeychainById(tag.ParentId).GetKeyById(tag.KeyId).Comparer = (Comparer)((ComboBox)e.OriginalSource).SelectedIndex;
}
private void conditionCombobox_Loaded(object sender, RoutedEventArgs e)
@@ -100,10 +101,10 @@ namespace OpenBullet.Pages.StackerBlocks
return;
tag.ConditionInitialized = true;
foreach (var c in Enum.GetNames(typeof(RuriLib.Condition)))
foreach (var c in Enum.GetNames(typeof(Comparer)))
((ComboBox)e.OriginalSource).Items.Add(c);
((ComboBox)e.OriginalSource).SelectedIndex = (int)vm.GetKeychainById(tag.ParentId).GetKeyById(tag.KeyId).Condition;
((ComboBox)e.OriginalSource).SelectedIndex = (int)vm.GetKeychainById(tag.ParentId).GetKeyById(tag.KeyId).Comparer;
}
private void leftTermCombobox_Loaded(object sender, RoutedEventArgs e)
+2 -1
View File
@@ -1,5 +1,6 @@
using OpenBullet.Pages.StackerBlocks;
using RuriLib;
using RuriLib.Functions.Conditions;
using RuriLib.Models;
using RuriLib.ViewModels;
@@ -12,7 +13,7 @@ namespace OpenBullet.ViewModels
public Key Key { get; set; }
public string LeftTerm { get { return Key.LeftTerm; } set { Key.LeftTerm = value; OnPropertyChanged(); } }
public Condition Condition { get { return Key.Condition; } set { Key.Condition = value; OnPropertyChanged(); } }
public Comparer Comparer { get { return Key.Comparer; } set { Key.Comparer = value; OnPropertyChanged(); } }
public string RightTerm { get { return Key.RightTerm; } set { Key.RightTerm = value; OnPropertyChanged(); } }
public KeyViewModel(Key key, int id, int parentId)
+8 -7
View File
@@ -1,4 +1,5 @@
using RuriLib.LS;
using RuriLib.Functions.Conditions;
using RuriLib.LS;
using RuriLib.Models;
using System;
using System.Collections.Generic;
@@ -68,15 +69,15 @@ namespace RuriLib
if (LineParser.CheckIdentifier(ref input, "KEY") || LineParser.CheckIdentifier(ref input, "KEYCHAIN") || input == "")
{
k.LeftTerm = "<SOURCE>";
k.Condition = Condition.Contains;
k.Comparer = Comparer.Contains;
k.RightTerm = first;
}
// Otherwise use the long syntax
else
{
k.LeftTerm = first;
k.Condition = (Condition)LineParser.ParseEnum(ref input, "Condition", typeof(Condition));
if (k.Condition != Condition.Exists && k.Condition != Condition.DoesNotExist)
k.Comparer = (Comparer)LineParser.ParseEnum(ref input, "Condition", typeof(Comparer));
if (k.Comparer != Comparer.Exists && k.Comparer != Comparer.DoesNotExist)
k.RightTerm = LineParser.ParseLiteral(ref input, "Right Term");
}
@@ -113,7 +114,7 @@ namespace RuriLib
foreach(var k in kc.Keys)
{
if (k.LeftTerm == "<SOURCE>" && k.Condition == Condition.Contains)
if (k.LeftTerm == "<SOURCE>" && k.Comparer == Comparer.Contains)
{
writer
.Indent(2)
@@ -126,9 +127,9 @@ namespace RuriLib
.Indent(2)
.Token("KEY")
.Literal(k.LeftTerm)
.Token(k.Condition);
.Token(k.Comparer);
if (k.Condition != Condition.Exists && k.Condition != Condition.DoesNotExist)
if (k.Comparer != Comparer.Exists && k.Comparer != Comparer.DoesNotExist)
writer.Literal(k.RightTerm);
}
}
+78 -24
View File
@@ -3,12 +3,12 @@ using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
namespace RuriLib
namespace RuriLib.Functions.Conditions
{
/// <summary>
/// The condition on which to base the outcome of a comparison.
/// </summary>
public enum Condition
public enum Comparer
{
/// <summary>A is less than B.</summary>
LessThan,
@@ -44,58 +44,112 @@ namespace RuriLib
/// <summary>
/// Static Class used to check if a condition is true or false.
/// </summary>
public static class ConditionChecker
public static class Condition
{
/// <summary>
/// Verifies if a comparison is true or false.
/// Verifies if a condition is true or false.
/// </summary>
/// <param name="left">The left-hand term in the comparison</param>
/// <param name="condition">The condition of the comparison</param>
/// <param name="right">The right-hand term in the comparison</param>
/// <param name="left">The left term</param>
/// <param name="comparer">The comparison operator</param>
/// <param name="right">The right term</param>
/// <param name="data">The BotData used for variable replacement</param>
/// <returns>Whether the comparison is true or false</returns>
public static bool Verify(string left, Condition condition, string right, BotData data)
/// <returns>Whether the comparison is verified or not.</returns>
public static bool Verify(string left, Comparer comparer, string right, BotData data)
{
return Verify(new KeycheckCondition() { Left = left, Comparer = comparer, Right = right }, data);
}
/// <summary>
/// Verifies if a condition is true or false.
/// </summary>
/// <param name="kcCond">The keycheck condition struct</param>
/// <param name="data">The BotData used for variable replacement</param>
/// <returns>Whether the comparison is verified or not.</returns>
public static bool Verify(KeycheckCondition kcCond, BotData data)
{
var style = NumberStyles.Number | NumberStyles.AllowCurrencySymbol; // Needed when comparing values with a currency symbol
var provider = new CultureInfo("en-US");
var L = BlockBase.ReplaceValuesRecursive(left, data); // The left-hand term can accept recursive values like <LIST[*]>
var r = BlockBase.ReplaceValues(right, data); // The right-hand term cannot
var L = BlockBase.ReplaceValuesRecursive(kcCond.Left, data); // The left-hand term can accept recursive values like <LIST[*]>
var r = BlockBase.ReplaceValues(kcCond.Right, data); // The right-hand term cannot
switch (condition)
switch (kcCond.Comparer)
{
case Condition.EqualTo:
case Comparer.EqualTo:
return L.Any(l => l == r);
case Condition.NotEqualTo:
case Comparer.NotEqualTo:
return L.Any(l => l != r);
case Condition.GreaterThan:
case Comparer.GreaterThan:
return L.Any(l => decimal.Parse(l.Replace(',', '.'), style, provider) > decimal.Parse(r, style, provider));
case Condition.LessThan:
case Comparer.LessThan:
return L.Any(l => decimal.Parse(l.Replace(',', '.'), style, provider) < decimal.Parse(r, style, provider));
case Condition.Contains:
case Comparer.Contains:
return L.Any(l => l.Contains(r));
case Condition.DoesNotContain:
case Comparer.DoesNotContain:
return L.Any(l => !l.Contains(r));
case Condition.Exists:
return L.Any(l => l != left); // Returns true if any replacement took place
case Comparer.Exists:
return L.Any(l => l != kcCond.Left); // Returns true if any replacement took place
case Condition.DoesNotExist:
return L.All(l => l == left); // Returns true if no replacement took place
case Comparer.DoesNotExist:
return L.All(l => l == kcCond.Left); // Returns true if no replacement took place
case Condition.MatchesRegex:
case Comparer.MatchesRegex:
return L.Any(l => Regex.Match(l, r).Success);
case Condition.DoesNotMatchRegex:
case Comparer.DoesNotMatchRegex:
return L.Any(l => !Regex.Match(l, r).Success);
default:
return false;
}
}
/// <summary>
/// Verifies if all the provided conditions are true.
/// </summary>
/// <param name="conditions">The keycheck conditions</param>
/// <param name="data">The BotData used for variable replacement</param>
/// <returns>True if all the conditions are verified.</returns>
public static bool VerifyAll(KeycheckCondition[] conditions, BotData data)
{
return conditions.All(c => Verify(c, data));
}
/// <summary>
/// Verifies if at least one of the provided conditions is true.
/// </summary>
/// <param name="conditions">The keycheck conditions</param>
/// <param name="data">The BotData used for variable replacement</param>
/// <returns>True if any condition is verified.</returns>
public static bool VerifyAny(KeycheckCondition[] conditions, BotData data)
{
return conditions.Any(c => Verify(c, data));
}
}
/// <summary>
/// Represents a condition of a keycheck.
/// </summary>
public struct KeycheckCondition
{
/// <summary>
/// The left term.
/// </summary>
public string Left;
/// <summary>
/// The comparison operator.
/// </summary>
public Comparer Comparer;
/// <summary>
/// The right term.
/// </summary>
public string Right;
}
}
+4 -3
View File
@@ -2,6 +2,7 @@
using IronPython.Hosting;
using IronPython.Runtime;
using Jint;
using RuriLib.Functions.Conditions;
using RuriLib.Models;
using System;
using System.Collections.Generic;
@@ -445,11 +446,11 @@ namespace RuriLib.LS
public static bool ParseCheckCondition(ref string cfLine, BotData data)
{
var first = LineParser.ParseLiteral(ref cfLine, "STRING");
var condition = (Condition)LineParser.ParseEnum(ref cfLine, "CONDITION", typeof(Condition));
var Comparer = (Comparer)LineParser.ParseEnum(ref cfLine, "Comparer", typeof(Comparer));
var second = "";
if (condition != Condition.Exists && condition != Condition.DoesNotExist)
if (Comparer != Comparer.Exists && Comparer != Comparer.DoesNotExist)
second = LineParser.ParseLiteral(ref cfLine, "STRING");
return (ConditionChecker.Verify(first, condition, second, data));
return (Condition.Verify(first, Comparer, second, data));
}
/// <summary>
+9 -8
View File
@@ -1,4 +1,5 @@
using System;
using RuriLib.Functions.Conditions;
using System;
using System.Linq;
using System.Windows.Media;
@@ -23,35 +24,35 @@ namespace RuriLib.LS
return new Action(() =>
{
var name = "";
Condition cond = Condition.EqualTo;
Comparer comparer = Comparer.EqualTo;
switch (field)
{
case "COOKIE":
if(LineParser.Lookahead(ref input) == TokenType.Parameter)
cond = (Condition)LineParser.ParseEnum(ref input, "TYPE", typeof(Condition));
comparer = (Comparer)LineParser.ParseEnum(ref input, "TYPE", typeof(Comparer));
name = LineParser.ParseLiteral(ref input, "NAME");
for (int i=0; i<data.Cookies.Count; i++)
{
var curr = data.Cookies.ToList()[i].Key;
if (ConditionChecker.Verify(curr, cond, name, data)) data.Cookies.Remove(curr);
if (Condition.Verify(curr, comparer, name, data)) data.Cookies.Remove(curr);
}
break;
case "VAR":
if (LineParser.Lookahead(ref input) == TokenType.Parameter)
cond = (Condition)LineParser.ParseEnum(ref input, "TYPE", typeof(Condition));
comparer = (Comparer)LineParser.ParseEnum(ref input, "TYPE", typeof(Comparer));
name = LineParser.ParseLiteral(ref input, "NAME");
data.Variables.Remove(cond, name, data);
data.Variables.Remove(comparer, name, data);
break;
case "GVAR":
if (LineParser.Lookahead(ref input) == TokenType.Parameter)
cond = (Condition)LineParser.ParseEnum(ref input, "TYPE", typeof(Condition));
comparer = (Comparer)LineParser.ParseEnum(ref input, "TYPE", typeof(Comparer));
name = LineParser.ParseLiteral(ref input, "NAME");
try
{
data.GlobalVariables.Remove(cond, name, data);
data.GlobalVariables.Remove(comparer, name, data);
}
catch { }
break;
+6 -5
View File
@@ -1,4 +1,5 @@
using RuriLib.ViewModels;
using RuriLib.Functions.Conditions;
using RuriLib.ViewModels;
namespace RuriLib.Models
{
@@ -11,9 +12,9 @@ namespace RuriLib.Models
/// <summary>The left-hand term for the comparison.</summary>
public string LeftTerm { get { return leftTerm; } set { leftTerm = value; OnPropertyChanged(); } }
private Condition condition = Condition.Contains;
/// <summary>The condition of the comparison.</summary>
public Condition Condition { get { return condition; } set { condition = value; OnPropertyChanged(); } }
private Comparer comparer = Comparer.Contains;
/// <summary>The comparison operator.</summary>
public Comparer Comparer { get { return comparer; } set { comparer = value; OnPropertyChanged(); } }
private string rightTerm = "";
/// <summary>The right-hand term of the comparison.</summary>
@@ -28,7 +29,7 @@ namespace RuriLib.Models
{
try
{
return ConditionChecker.Verify(LeftTerm, Condition, RightTerm, data);
return Condition.Verify(LeftTerm, Comparer, RightTerm, data);
}
catch { return false; } // Return false if e.g. we can't parse the number for a LessThan/GreaterThan comparison.
}
+2 -2
View File
@@ -71,7 +71,7 @@ namespace RuriLib.Models
{
data.Log(new LogEntry(string.Format("Found 'OR' Key {0} {1} {2}",
BlockBase.TruncatePretty(BlockBase.ReplaceValues(key.LeftTerm, data), 20),
key.Condition.ToString(),
key.Comparer.ToString(),
BlockBase.ReplaceValues(key.RightTerm, data)),
Colors.White));
return true;
@@ -88,7 +88,7 @@ namespace RuriLib.Models
{
data.Log(new LogEntry(string.Format("Found 'AND' Key {0} {1} {2}",
BlockBase.TruncatePretty(BlockBase.ReplaceValues(key.LeftTerm, data), 20),
key.Condition.ToString(),
key.Comparer.ToString(),
BlockBase.ReplaceValues(key.RightTerm, data)),
Colors.White));
}
+4 -3
View File
@@ -1,4 +1,5 @@
using Newtonsoft.Json;
using RuriLib.Functions.Conditions;
using System.Collections.Generic;
using System.Linq;
@@ -168,12 +169,12 @@ namespace RuriLib.Models
/// <para>Removes all non-hidden variables if their name matches a condition.</para>
/// <para>The name of the variables in the list are the left-hand term of the comparison.</para>
/// </summary>
/// <param name="cond">The condition type</param>
/// <param name="comparer">The comparison operator</param>
/// <param name="name">The right-hand term of the comparison</param>
/// <param name="data">The BotData object used for variable replacement</param>
public void Remove(Condition cond, string name, BotData data)
public void Remove(Comparer comparer, string name, BotData data)
{
All.RemoveAll(v => ConditionChecker.Verify(v.Name, cond, name, data) && !v.Hidden);
All.RemoveAll(v => Condition.Verify(v.Name, comparer, name, data) && !v.Hidden);
}
/// <summary>