package manifest import ( "mccl/pkg/util" "regexp" "runtime" ) type Feature int const ( FeatureIsDemoUser Feature = iota FeatureHasCustomResolution FeatureHasQuickPlaysSupport FeatureIsQuickPlaySingleplayer FeatureIsQuickPlayMultiplayer FeatureIsQuickPlayRealms FeatureUnknown ) func (f Feature) String() string { switch f { case FeatureIsDemoUser: return "is_demo_user" case FeatureHasCustomResolution: return "has_custom_resolution" case FeatureHasQuickPlaysSupport: return "has_quick_plays_support" case FeatureIsQuickPlayMultiplayer: return "is_quick_play_multiplayer" case FeatureIsQuickPlayRealms: return "is_quick_play_realms" case FeatureIsQuickPlaySingleplayer: return "is_quick_play_singleplayer" default: return "" } } type Action string const ( ActionAllow Action = "allow" ActionDisallow Action = "disallow" ActionUnknown Action = "" ) type Rule struct { Action Action `json:"action"` Os struct { Name string `json:"name"` Arch string `json:"arch"` Version string `json:"version"` } `json:"os"` Features struct { IsDemoUser bool `json:"is_demo_user"` HasCustomResolution bool `json:"has_custom_resolution"` HasQuickPlaysSupport bool `json:"has_quick_plays_support"` IsQuickPlaySingleplayer bool `json:"is_quick_play_singleplayer"` IsQuickPlayMultiplayer bool `json:"is_quick_play_multiplayer"` IsQuickPlayRealms bool `json:"is_quick_play_realms"` } `json:"features"` } func (r *Rule) GetFeature() Feature { switch { case r.Features.IsDemoUser: return FeatureIsDemoUser case r.Features.HasCustomResolution: return FeatureHasCustomResolution case r.Features.HasQuickPlaysSupport: return FeatureHasQuickPlaysSupport case r.Features.IsQuickPlayMultiplayer: return FeatureIsQuickPlayMultiplayer case r.Features.IsQuickPlaySingleplayer: return FeatureIsQuickPlaySingleplayer case r.Features.IsQuickPlayRealms: return FeatureIsQuickPlayRealms default: return FeatureUnknown } } func (r *Rule) Check() (bool, Feature) { feature := r.GetFeature() osArchOk := true switch r.Os.Arch { case "x86": osArchOk = r.Action == ActionAllow && runtime.GOARCH == "386" case "x86_64": osArchOk = r.Action == ActionAllow && runtime.GOARCH == "amd64" case "arm64": osArchOk = r.Action == ActionAllow && runtime.GOARCH == "arm64" } osName := runtime.GOOS if osName == "darwin" { osName = "osx" } osNameOk := true if r.Os.Name != "" { if r.Action == ActionAllow { osNameOk = r.Os.Name == osName } else { osNameOk = r.Os.Name != osName } } osVersionOk := true if r.Os.Name == osName && r.Os.Version != "" { ver, err := util.OSVersion() if err != nil { return false, feature } ok, _ := regexp.MatchString(r.Os.Version, ver) osVersionOk = ok && r.Action == ActionAllow } return osArchOk && osNameOk && osVersionOk, feature }