mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2024-11-16 03:32:33 +08:00
chore: logic rules dynamic obtain parameters
Some checks are pending
Trigger CMFA Update / trigger-CMFA-update (push) Waiting to run
Some checks are pending
Trigger CMFA Update / trigger-CMFA-update (push) Waiting to run
This commit is contained in:
parent
5a73d99c6f
commit
beefe37260
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
C "github.com/metacubex/mihomo/constant"
|
C "github.com/metacubex/mihomo/constant"
|
||||||
"github.com/metacubex/mihomo/rules/common"
|
"github.com/metacubex/mihomo/rules/common"
|
||||||
|
@ -13,19 +14,19 @@ import (
|
||||||
|
|
||||||
type Logic struct {
|
type Logic struct {
|
||||||
*common.Base
|
*common.Base
|
||||||
payload string
|
payload string
|
||||||
adapter string
|
adapter string
|
||||||
ruleType C.RuleType
|
ruleType C.RuleType
|
||||||
rules []C.Rule
|
rules []C.Rule
|
||||||
subRules map[string][]C.Rule
|
subRules map[string][]C.Rule
|
||||||
needIP bool
|
|
||||||
needProcess bool
|
payloadOnce sync.Once
|
||||||
}
|
}
|
||||||
|
|
||||||
type ParseRuleFunc func(tp, payload, target string, params []string, subRules map[string][]C.Rule) (C.Rule, error)
|
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) {
|
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)
|
err := logic.parsePayload(fmt.Sprintf("(%s)", payload), parseRule)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -34,15 +35,6 @@ func NewSubRule(payload, adapter string, subRules map[string][]C.Rule, parseRule
|
||||||
if len(logic.rules) != 1 {
|
if len(logic.rules) != 1 {
|
||||||
return nil, fmt.Errorf("Sub-Rule rule must contain one rule")
|
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
|
return logic, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,9 +48,6 @@ func NewNOT(payload string, adapter string, parseRule ParseRuleFunc) (*Logic, er
|
||||||
if len(logic.rules) != 1 {
|
if len(logic.rules) != 1 {
|
||||||
return nil, fmt.Errorf("not rule must contain one rule")
|
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
|
return logic, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,40 +57,15 @@ func NewOR(payload string, adapter string, parseRule ParseRuleFunc) (*Logic, err
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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
|
return logic, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAND(payload string, adapter string, parseRule ParseRuleFunc) (*Logic, error) {
|
func NewAND(payload string, adapter string, parseRule ParseRuleFunc) (*Logic, error) {
|
||||||
logic := &Logic{Base: &common.Base{}, payload: payload, adapter: adapter, ruleType: C.AND}
|
logic := &Logic{Base: &common.Base{}, payload: payload, adapter: adapter, ruleType: C.AND}
|
||||||
err := logic.parsePayload(payload, parseRule)
|
err := logic.parsePayload(payload, parseRule)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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
|
return logic, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,13 +182,6 @@ func (logic *Logic) parsePayload(payload string, parseRule ParseRuleFunc) error
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if rule.ShouldResolveIP() {
|
|
||||||
logic.needIP = true
|
|
||||||
}
|
|
||||||
if rule.ShouldFindProcess() {
|
|
||||||
logic.needProcess = true
|
|
||||||
}
|
|
||||||
|
|
||||||
rules = append(rules, rule)
|
rules = append(rules, rule)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,9 +236,9 @@ func (logic *Logic) Match(metadata *C.Metadata) (bool, string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true, logic.adapter
|
return true, logic.adapter
|
||||||
|
default:
|
||||||
|
return false, ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return false, ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logic *Logic) Adapter() string {
|
func (logic *Logic) Adapter() string {
|
||||||
|
@ -289,15 +246,58 @@ func (logic *Logic) Adapter() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logic *Logic) Payload() string {
|
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
|
return logic.payload
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logic *Logic) ShouldResolveIP() bool {
|
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 {
|
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) {
|
func (logic *Logic) ProviderNames() (names []string) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user