Skip to content

Commit

Permalink
chore: logic rules dynamic obtain parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
wwqgtxx committed Aug 6, 2024
1 parent 5a73d99 commit beefe37
Showing 1 changed file with 57 additions and 57 deletions.
114 changes: 57 additions & 57 deletions rules/logic/logic.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"regexp"
"strings"
"sync"

C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/rules/common"
Expand All @@ -13,19 +14,19 @@ import (

type Logic struct {
*common.Base
payload string
adapter string
ruleType C.RuleType
rules []C.Rule
subRules map[string][]C.Rule
needIP bool
needProcess bool
payload string
adapter string
ruleType C.RuleType
rules []C.Rule
subRules map[string][]C.Rule

payloadOnce sync.Once
}

type ParseRuleFunc func(tp, payload, target string, params []string, subRules map[string][]C.Rule) (C.Rule, error)

func NewSubRule(payload, adapter string, subRules map[string][]C.Rule, parseRule ParseRuleFunc) (*Logic, error) {
logic := &Logic{Base: &common.Base{}, payload: payload, adapter: adapter, ruleType: C.SubRules}
logic := &Logic{Base: &common.Base{}, payload: payload, adapter: adapter, ruleType: C.SubRules, subRules: subRules}
err := logic.parsePayload(fmt.Sprintf("(%s)", payload), parseRule)
if err != nil {
return nil, err
Expand All @@ -34,15 +35,6 @@ func NewSubRule(payload, adapter string, subRules map[string][]C.Rule, parseRule
if len(logic.rules) != 1 {
return nil, fmt.Errorf("Sub-Rule rule must contain one rule")
}
for _, rule := range subRules[adapter] {
if rule.ShouldResolveIP() {
logic.needIP = true
}
if rule.ShouldFindProcess() {
logic.needProcess = true
}
}
logic.subRules = subRules
return logic, nil
}

Expand All @@ -56,9 +48,6 @@ func NewNOT(payload string, adapter string, parseRule ParseRuleFunc) (*Logic, er
if len(logic.rules) != 1 {
return nil, fmt.Errorf("not rule must contain one rule")
}
logic.needIP = logic.rules[0].ShouldResolveIP()
logic.needProcess = logic.rules[0].ShouldFindProcess()
logic.payload = fmt.Sprintf("(!(%s,%s))", logic.rules[0].RuleType(), logic.rules[0].Payload())
return logic, nil
}

Expand All @@ -68,40 +57,15 @@ func NewOR(payload string, adapter string, parseRule ParseRuleFunc) (*Logic, err
if err != nil {
return nil, err
}

payloads := make([]string, 0, len(logic.rules))
for _, rule := range logic.rules {
payloads = append(payloads, fmt.Sprintf("(%s,%s)", rule.RuleType().String(), rule.Payload()))
if rule.ShouldResolveIP() {
logic.needIP = true
}
if rule.ShouldFindProcess() {
logic.needProcess = true
}
}
logic.payload = fmt.Sprintf("(%s)", strings.Join(payloads, " || "))

return logic, nil
}

func NewAND(payload string, adapter string, parseRule ParseRuleFunc) (*Logic, error) {
logic := &Logic{Base: &common.Base{}, payload: payload, adapter: adapter, ruleType: C.AND}
err := logic.parsePayload(payload, parseRule)
if err != nil {
return nil, err
}

payloads := make([]string, 0, len(logic.rules))
for _, rule := range logic.rules {
payloads = append(payloads, fmt.Sprintf("(%s,%s)", rule.RuleType().String(), rule.Payload()))
if rule.ShouldResolveIP() {
logic.needIP = true
}
if rule.ShouldFindProcess() {
logic.needProcess = true
}
}
logic.payload = fmt.Sprintf("(%s)", strings.Join(payloads, " && "))

return logic, nil
}

Expand Down Expand Up @@ -218,13 +182,6 @@ func (logic *Logic) parsePayload(payload string, parseRule ParseRuleFunc) error
return err
}

if rule.ShouldResolveIP() {
logic.needIP = true
}
if rule.ShouldFindProcess() {
logic.needProcess = true
}

rules = append(rules, rule)
}

Expand Down Expand Up @@ -279,25 +236,68 @@ func (logic *Logic) Match(metadata *C.Metadata) (bool, string) {
}
}
return true, logic.adapter
default:
return false, ""
}

return false, ""
}

func (logic *Logic) Adapter() string {
return logic.adapter
}

func (logic *Logic) Payload() string {
logic.payloadOnce.Do(func() { // a little bit expensive, so only computed once
switch logic.ruleType {
case C.NOT:
logic.payload = fmt.Sprintf("(!(%s,%s))", logic.rules[0].RuleType(), logic.rules[0].Payload())
case C.OR:
payloads := make([]string, 0, len(logic.rules))
for _, rule := range logic.rules {
payloads = append(payloads, fmt.Sprintf("(%s,%s)", rule.RuleType().String(), rule.Payload()))
}
logic.payload = fmt.Sprintf("(%s)", strings.Join(payloads, " || "))
case C.AND:
payloads := make([]string, 0, len(logic.rules))
for _, rule := range logic.rules {
payloads = append(payloads, fmt.Sprintf("(%s,%s)", rule.RuleType().String(), rule.Payload()))
}
logic.payload = fmt.Sprintf("(%s)", strings.Join(payloads, " && "))
default:
}
})
return logic.payload
}

func (logic *Logic) ShouldResolveIP() bool {
return logic.needIP
if logic.ruleType == C.SubRules {
for _, rule := range logic.subRules[logic.adapter] {
if rule.ShouldResolveIP() {
return true
}
}
}
for _, rule := range logic.rules {
if rule.ShouldResolveIP() {
return true
}
}
return false
}

func (logic *Logic) ShouldFindProcess() bool {
return logic.needProcess
if logic.ruleType == C.SubRules {
for _, rule := range logic.subRules[logic.adapter] {
if rule.ShouldFindProcess() {
return true
}
}
}
for _, rule := range logic.rules {
if rule.ShouldFindProcess() {
return true
}
}
return false
}

func (logic *Logic) ProviderNames() (names []string) {
Expand Down

0 comments on commit beefe37

Please sign in to comment.