diff --git a/go.mod b/go.mod index 07e23d3..049d4f2 100644 --- a/go.mod +++ b/go.mod @@ -39,6 +39,7 @@ require ( dario.cat/mergo v1.0.0 // indirect fyne.io/systray v1.11.0 // indirect github.com/BurntSushi/toml v1.4.0 // indirect + github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 // indirect github.com/MicahParks/jwkset v0.5.20 // indirect github.com/MicahParks/keyfunc/v3 v3.3.5 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect @@ -219,6 +220,7 @@ require ( ) require ( + github.com/BurntSushi/xgbutil v0.0.0-20190907113008-ad855c713046 github.com/onsi/gomega v1.30.0 // indirect github.com/phuslu/goid v1.0.1 // indirect github.com/pion/datachannel v1.5.6 // indirect diff --git a/go.sum b/go.sum index c974d82..6fee4b0 100644 --- a/go.sum +++ b/go.sum @@ -52,7 +52,10 @@ github.com/AgustinSRG/go-child-process-manager v1.0.1/go.mod h1:JgXUSAhyOo1awWbB github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/BurntSushi/xgbutil v0.0.0-20190907113008-ad855c713046 h1:O/r2Sj+8QcMF7V5IcmiE2sMFV2q3J47BEirxbXJAdzA= +github.com/BurntSushi/xgbutil v0.0.0-20190907113008-ad855c713046/go.mod h1:uw9h2sd4WWHOPdJ13MQpwK5qYWKYDumDqxWWIknEQ+k= github.com/DataDog/gostackparse v0.6.0 h1:egCGQviIabPwsyoWpGvIBGrEnNWez35aEO7OJ1vBI4o= github.com/DataDog/gostackparse v0.6.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM= github.com/DexterLB/mpvipc v0.0.0-20230829142118-145d6eabdc37 h1:/oQBAuySCcme0DLhicWkr7FaAT5nh1XbbbnCMR2WdPA= diff --git a/pkg/expression/eval.go b/pkg/expression/eval.go new file mode 100644 index 0000000..1d51a7e --- /dev/null +++ b/pkg/expression/eval.go @@ -0,0 +1,33 @@ +package expression + +import ( + "bytes" + "fmt" + "text/template" +) + +func Eval[T any]( + expr Expression, + evalCtx any, +) (T, error) { + var result T + + tmpl, err := template.New("").Funcs(funcMap).Parse(string(expr)) + if err != nil { + return result, fmt.Errorf("unable to parse the template: %w", err) + } + + var buf bytes.Buffer + err = tmpl.Execute(&buf, evalCtx) + if err != nil { + return result, fmt.Errorf("unable to execute the template: %w", err) + } + + value := buf.String() + _, err = fmt.Sscanf(value, "%v", &result) + if err != nil { + return result, fmt.Errorf("unable to scan value '%v' into %T: %w", value, result, err) + } + + return result, nil +} diff --git a/pkg/expression/expression.go b/pkg/expression/expression.go new file mode 100644 index 0000000..6b2ee25 --- /dev/null +++ b/pkg/expression/expression.go @@ -0,0 +1,3 @@ +package expression + +type Expression string diff --git a/pkg/serializable/registry.go b/pkg/serializable/registry.go new file mode 100644 index 0000000..8a03976 --- /dev/null +++ b/pkg/serializable/registry.go @@ -0,0 +1,29 @@ +package serializable + +import ( + registrylib "github.com/xaionaro-go/streamctl/pkg/serializable/registry" +) + +var localRegistry = registrylib.New[any]() + +func RegisterType[T any]() { + var sample T + localRegistry.RegisterType(sample) +} + +func NewByTypeName[T any](typeName string) (T, bool) { + result := localRegistry.NewByTypeName(typeName) + casted, ok := result.(T) + return casted, ok +} + +func ListTypeNames[T any]() []string { + names := localRegistry.ListTypeNames() + var result []string + for _, name := range names { + if _, ok := localRegistry.NewByTypeName(name).(T); ok { + result = append(result, name) + } + } + return result +} diff --git a/pkg/streamcontrol/obs/types/registry/registry.go b/pkg/serializable/registry/registry.go similarity index 50% rename from pkg/streamcontrol/obs/types/registry/registry.go rename to pkg/serializable/registry/registry.go index 34db031..affdfea 100644 --- a/pkg/streamcontrol/obs/types/registry/registry.go +++ b/pkg/serializable/registry/registry.go @@ -1,8 +1,10 @@ package registry import ( + "fmt" "reflect" "sort" + "strings" "github.com/iancoleman/strcase" ) @@ -18,11 +20,19 @@ func New[T any]() *Registry[T] { } func typeOf(v any) reflect.Type { - return reflect.ValueOf(v).Type().Elem() + return reflect.Indirect(reflect.ValueOf(v)).Type() } func ToTypeName[T any](sample T) string { - return strcase.ToSnake(typeOf(sample).Name()) + name := typeOf(sample).Name() + name = strings.ReplaceAll(name, "github.com/xaionaro-go/streamctl/pkg/streamd/config/", "") + name = strings.ReplaceAll(name, "eventquery/", "") + name = strings.ReplaceAll(name, "eventquery.", "") + name = strings.ReplaceAll(name, "event/", "") + name = strings.ReplaceAll(name, "event.", "") + name = strings.ReplaceAll(name, "action/", "") + name = strings.ReplaceAll(name, "action.", "") + return strcase.ToSnake(name) } func (r *Registry[T]) RegisterType(sample T) { @@ -30,7 +40,11 @@ func (r *Registry[T]) RegisterType(sample T) { } func (r *Registry[T]) NewByTypeName(typeName string) T { - return reflect.New(r.Types[typeName]).Interface().(T) + t := r.Types[typeName] + if t == nil { + panic(fmt.Errorf("type '%s' is not registered", typeName)) + } + return reflect.New(t).Interface().(T) } func (r *Registry[T]) ListTypeNames() []string { diff --git a/pkg/serializable/serializable.go b/pkg/serializable/serializable.go new file mode 100644 index 0000000..bcc5d37 --- /dev/null +++ b/pkg/serializable/serializable.go @@ -0,0 +1,69 @@ +package serializable + +import ( + "fmt" + "runtime/debug" + + "github.com/goccy/go-yaml" + "github.com/xaionaro-go/streamctl/pkg/serializable/registry" +) + +type serializableInterface interface { + yaml.BytesMarshaler + yaml.BytesUnmarshaler +} + +type Serializable[T any] struct { + Value T +} + +type serializable[T any] struct { + Type string `yaml:"type"` + Value T `yaml:",inline"` +} + +var _ serializableInterface = (*Serializable[struct{}])(nil) + +func (s *Serializable[T]) UnmarshalYAML(b []byte) (_err error) { + defer func() { + if r := recover(); r != nil { + _err = fmt.Errorf("got a panic: %v\n%s", r, debug.Stack()) + } + }() + + intermediate := serializable[struct{}]{} + err := yaml.Unmarshal(b, &intermediate) + if err != nil { + return fmt.Errorf("unable to unmarshal the intermediate structure for %T: %w", s.Value, err) + } + + if intermediate.Type == "" { + return fmt.Errorf("'type' is not set") + } + + value, ok := NewByTypeName[T](intermediate.Type) + if !ok { + return fmt.Errorf("unknown/unregistered value type name: '%v'", intermediate.Type) + } + + err = yaml.Unmarshal(b, value) + if err != nil { + return fmt.Errorf("unable to unmarshal the %T structure: %w", s.Value, err) + } + + s.Value = value + return nil +} + +func (s Serializable[T]) MarshalYAML() (_ []byte, _err error) { + defer func() { + if r := recover(); r != nil { + _err = fmt.Errorf("got a panic: %v\n%s", r, debug.Stack()) + } + }() + + return yaml.Marshal(serializable[T]{ + Type: registry.ToTypeName(s.Value), + Value: s.Value, + }) +} diff --git a/pkg/streamcontrol/obs/config.go b/pkg/streamcontrol/obs/config.go index 7629c47..4d9dc24 100644 --- a/pkg/streamcontrol/obs/config.go +++ b/pkg/streamcontrol/obs/config.go @@ -8,9 +8,6 @@ import ( const ID = types.ID type Config = types.Config -type SceneName = types.SceneName -type SceneRule = types.SceneRule -type SceneRules = types.SceneRules type StreamProfile = types.StreamProfile type PlatformSpecificConfig = types.PlatformSpecificConfig diff --git a/pkg/streamcontrol/obs/types/action/action.go b/pkg/streamcontrol/obs/types/action/action.go deleted file mode 100644 index e522a90..0000000 --- a/pkg/streamcontrol/obs/types/action/action.go +++ /dev/null @@ -1,28 +0,0 @@ -package action - -func init() { - registry.RegisterType((*ElementShowHide)(nil)) - registry.RegisterType((*WindowCaptureSetSource)(nil)) -} - -type Action interface { - isAction() -} - -type ValueExpression string - -type ElementShowHide struct { - ElementName *string `yaml:"element_name,omitempty" json:"element_name,omitempty"` - ElementUUID *string `yaml:"element_uuid,omitempty" json:"element_uuid,omitempty"` - ValueExpression ValueExpression `yaml:"value_expression,omitempty" json:"value_expression,omitempty"` -} - -func (ElementShowHide) isAction() {} - -type WindowCaptureSetSource struct { - ElementName *string `yaml:"element_name,omitempty" json:"element_name,omitempty"` - ElementUUID *string `yaml:"element_uuid,omitempty" json:"element_uuid,omitempty"` - ValueExpression ValueExpression `yaml:"value_expression,omitempty" json:"value_expression,omitempty"` -} - -func (WindowCaptureSetSource) isAction() {} diff --git a/pkg/streamcontrol/obs/types/action/registry.go b/pkg/streamcontrol/obs/types/action/registry.go deleted file mode 100644 index 1b8267d..0000000 --- a/pkg/streamcontrol/obs/types/action/registry.go +++ /dev/null @@ -1,15 +0,0 @@ -package action - -import ( - registrylib "github.com/xaionaro-go/streamctl/pkg/streamcontrol/obs/types/registry" -) - -var registry = registrylib.New[Action]() - -func NewByTypeName(typeName string) Action { - return registry.NewByTypeName(typeName) -} - -func ListTypeNames() []string { - return registry.ListTypeNames() -} diff --git a/pkg/streamcontrol/obs/types/config.go b/pkg/streamcontrol/obs/types/config.go index b11cba5..4ca583f 100644 --- a/pkg/streamcontrol/obs/types/config.go +++ b/pkg/streamcontrol/obs/types/config.go @@ -6,14 +6,10 @@ import ( const ID = streamctl.PlatformName("obs") -type SceneName string - type PlatformSpecificConfig struct { Host string Port uint16 Password string `yaml:"pass" json:"pass"` - - SceneRulesByScene map[SceneName]SceneRules `yaml:"scene_rules" json:"scene_rules"` } type Config = streamctl.PlatformConfig[PlatformSpecificConfig, StreamProfile] diff --git a/pkg/streamcontrol/obs/types/scene_rule.go b/pkg/streamcontrol/obs/types/scene_rule.go deleted file mode 100644 index 60ec6fc..0000000 --- a/pkg/streamcontrol/obs/types/scene_rule.go +++ /dev/null @@ -1,128 +0,0 @@ -package types - -import ( - "fmt" - "runtime/debug" - - "github.com/xaionaro-go/streamctl/pkg/streamcontrol/obs/types/action" - "github.com/xaionaro-go/streamctl/pkg/streamcontrol/obs/types/registry" - "github.com/xaionaro-go/streamctl/pkg/streamcontrol/obs/types/trigger" - "gopkg.in/yaml.v2" -) - -type SceneRules []SceneRule - -type SceneRule struct { - Description string `yaml:"description,omitempty" json:"description,omitempty"` - TriggerQuery trigger.Query `yaml:"trigger" json:"trigger"` - Action action.Action `yaml:"action" json:"action"` -} - -func (sr *SceneRule) UnmarshalYAML(b []byte) (_err error) { - defer func() { - if r := recover(); r != nil { - _err = fmt.Errorf("got a panic: %v\n%s", r, debug.Stack()) - } - }() - if sr == nil { - return fmt.Errorf("nil SceneRule") - } - - intermediate := serializableSceneRule{} - err := yaml.Unmarshal(b, &intermediate) - if err != nil { - return fmt.Errorf("unable to unmarshal the MonitorElementConfig: %w", err) - } - - triggerQueryType, _ := intermediate.Trigger["type"].(string) - if triggerQueryType == "" { - return fmt.Errorf("trigger type is not set") - } - - actionType, _ := intermediate.Action["type"].(string) - if actionType == "" { - return fmt.Errorf("action type is not set") - } - - triggerQuery := trigger.NewByTypeName(triggerQueryType) - if triggerQuery == nil { - return fmt.Errorf("unknown trigger type name: '%v'", triggerQueryType) - } - - action := action.NewByTypeName(actionType) - if action == nil { - return fmt.Errorf("unknown action type name: '%v'", actionType) - } - - *sr = SceneRule{ - Description: intermediate.Description, - TriggerQuery: triggerQuery, - Action: action, - } - return nil -} - -func (sr SceneRule) MarshalYAML() (b []byte, _err error) { - defer func() { - if r := recover(); r != nil { - _err = fmt.Errorf("got a panic: %v\n%s", r, debug.Stack()) - } - }() - - triggerBytes, err := yaml.Marshal(sr.TriggerQuery) - if err != nil { - return nil, fmt.Errorf( - "unable to serialize the trigger %T:%#+v: %w", - sr.TriggerQuery, - sr.TriggerQuery, - err, - ) - } - - triggerMap := map[string]any{} - err = yaml.Unmarshal(triggerBytes, &triggerMap) - if err != nil { - return nil, fmt.Errorf( - "unable to unserialize the trigger '%s' into a map: %w", - triggerBytes, - err, - ) - } - - triggerMap["type"] = registry.ToTypeName(sr.TriggerQuery) - - actionBytes, err := yaml.Marshal(sr.Action) - if err != nil { - return nil, fmt.Errorf( - "unable to serialize the action %T:%#+v: %w", - sr.Action, - sr.Action, - err, - ) - } - - actionMap := map[string]any{} - err = yaml.Unmarshal(actionBytes, &actionMap) - if err != nil { - return nil, fmt.Errorf( - "unable to unserialize the action '%s' into a map: %w", - actionBytes, - err, - ) - } - - actionMap["type"] = registry.ToTypeName(sr.Action) - - intermediate := serializableSceneRule{ - Description: sr.Description, - Trigger: triggerMap, - Action: actionMap, - } - return yaml.Marshal(intermediate) -} - -type serializableSceneRule struct { - Description string `yaml:"description,omitempty" json:"description,omitempty"` - Trigger map[string]any `yaml:"trigger" json:"trigger"` - Action map[string]any `yaml:"action" json:"action"` -} diff --git a/pkg/streamcontrol/obs/types/trigger/registry.go b/pkg/streamcontrol/obs/types/trigger/registry.go deleted file mode 100644 index 5c8688b..0000000 --- a/pkg/streamcontrol/obs/types/trigger/registry.go +++ /dev/null @@ -1,15 +0,0 @@ -package trigger - -import ( - registrylib "github.com/xaionaro-go/streamctl/pkg/streamcontrol/obs/types/registry" -) - -var registry = registrylib.New[Query]() - -func NewByTypeName(typeName string) Query { - return registry.NewByTypeName(typeName) -} - -func ListQueryTypeNames() []string { - return registry.ListTypeNames() -} diff --git a/pkg/streamd/api/streamd.go b/pkg/streamd/api/streamd.go index 55cb460..6a9613b 100644 --- a/pkg/streamd/api/streamd.go +++ b/pkg/streamd/api/streamd.go @@ -9,9 +9,10 @@ import ( "github.com/xaionaro-go/obs-grpc-proxy/protobuf/go/obs_grpc" "github.com/xaionaro-go/streamctl/pkg/player" "github.com/xaionaro-go/streamctl/pkg/streamcontrol" - "github.com/xaionaro-go/streamctl/pkg/streamcontrol/obs" "github.com/xaionaro-go/streamctl/pkg/streamd/cache" "github.com/xaionaro-go/streamctl/pkg/streamd/config" + "github.com/xaionaro-go/streamctl/pkg/streamd/config/action" + "github.com/xaionaro-go/streamctl/pkg/streamd/config/event" "github.com/xaionaro-go/streamctl/pkg/streamd/grpc/go/streamd_grpc" "github.com/xaionaro-go/streamctl/pkg/streampanel/consts" sptypes "github.com/xaionaro-go/streamctl/pkg/streamplayer/types" @@ -29,7 +30,10 @@ type StreamD interface { SaveConfig(ctx context.Context) error GetConfig(ctx context.Context) (*config.Config, error) SetConfig(ctx context.Context, cfg *config.Config) error - IsBackendEnabled(ctx context.Context, id streamcontrol.PlatformName) (bool, error) + IsBackendEnabled( + ctx context.Context, + id streamcontrol.PlatformName, + ) (bool, error) OBSOLETE_IsGITInitialized(ctx context.Context) (bool, error) StartStream( ctx context.Context, @@ -46,8 +50,16 @@ type StreamD interface { profile streamcontrol.AbstractStreamProfile, customArgs ...any, ) error - SetTitle(ctx context.Context, platID streamcontrol.PlatformName, title string) error - SetDescription(ctx context.Context, platID streamcontrol.PlatformName, description string) error + SetTitle( + ctx context.Context, + platID streamcontrol.PlatformName, + title string, + ) error + SetDescription( + ctx context.Context, + platID streamcontrol.PlatformName, + description string, + ) error ApplyProfile( ctx context.Context, platID streamcontrol.PlatformName, @@ -55,7 +67,10 @@ type StreamD interface { customArgs ...any, ) error OBSOLETE_GitRelogin(ctx context.Context) error - GetBackendData(ctx context.Context, platID streamcontrol.PlatformName) (any, error) + GetBackendData( + ctx context.Context, + platID streamcontrol.PlatformName, + ) (any, error) Restart(ctx context.Context) error EXPERIMENTAL_ReinitStreamControllers(ctx context.Context) error GetStreamStatus( @@ -63,7 +78,11 @@ type StreamD interface { platID streamcontrol.PlatformName, ) (*streamcontrol.StreamStatus, error) GetVariable(ctx context.Context, key consts.VarKey) ([]byte, error) - GetVariableHash(ctx context.Context, key consts.VarKey, hashType crypto.Hash) ([]byte, error) + GetVariableHash( + ctx context.Context, + key consts.VarKey, + hashType crypto.Hash, + ) ([]byte, error) SetVariable(ctx context.Context, key consts.VarKey, value []byte) error OBS(ctx context.Context) (obs_grpc.OBSServer, context.CancelFunc, error) @@ -169,39 +188,89 @@ type StreamD interface { streamID streamtypes.StreamID, ) (*StreamPlayer, error) - StreamPlayerProcessTitle(ctx context.Context, streamID StreamID) (string, error) - StreamPlayerOpenURL(ctx context.Context, streamID StreamID, link string) error + StreamPlayerProcessTitle( + ctx context.Context, + streamID StreamID, + ) (string, error) + StreamPlayerOpenURL( + ctx context.Context, + streamID StreamID, + link string, + ) error StreamPlayerGetLink(ctx context.Context, streamID StreamID) (string, error) - StreamPlayerEndChan(ctx context.Context, streamID StreamID) (<-chan struct{}, error) + StreamPlayerEndChan( + ctx context.Context, + streamID StreamID, + ) (<-chan struct{}, error) StreamPlayerIsEnded(ctx context.Context, streamID StreamID) (bool, error) - StreamPlayerGetPosition(ctx context.Context, streamID StreamID) (time.Duration, error) - StreamPlayerGetLength(ctx context.Context, streamID StreamID) (time.Duration, error) - StreamPlayerSetSpeed(ctx context.Context, streamID StreamID, speed float64) error - StreamPlayerSetPause(ctx context.Context, streamID StreamID, pause bool) error + StreamPlayerGetPosition( + ctx context.Context, + streamID StreamID, + ) (time.Duration, error) + StreamPlayerGetLength( + ctx context.Context, + streamID StreamID, + ) (time.Duration, error) + StreamPlayerSetSpeed( + ctx context.Context, + streamID StreamID, + speed float64, + ) error + StreamPlayerSetPause( + ctx context.Context, + streamID StreamID, + pause bool, + ) error StreamPlayerStop(ctx context.Context, streamID StreamID) error StreamPlayerClose(ctx context.Context, streamID StreamID) error SubscribeToConfigChanges(ctx context.Context) (<-chan DiffConfig, error) SubscribeToStreamsChanges(ctx context.Context) (<-chan DiffStreams, error) - SubscribeToStreamServersChanges(ctx context.Context) (<-chan DiffStreamServers, error) - SubscribeToStreamDestinationsChanges(ctx context.Context) (<-chan DiffStreamDestinations, error) - SubscribeToIncomingStreamsChanges(ctx context.Context) (<-chan DiffIncomingStreams, error) - SubscribeToStreamForwardsChanges(ctx context.Context) (<-chan DiffStreamForwards, error) - SubscribeToStreamPlayersChanges(ctx context.Context) (<-chan DiffStreamPlayers, error) + SubscribeToStreamServersChanges( + ctx context.Context, + ) (<-chan DiffStreamServers, error) + SubscribeToStreamDestinationsChanges( + ctx context.Context, + ) (<-chan DiffStreamDestinations, error) + SubscribeToIncomingStreamsChanges( + ctx context.Context, + ) (<-chan DiffIncomingStreams, error) + SubscribeToStreamForwardsChanges( + ctx context.Context, + ) (<-chan DiffStreamForwards, error) + SubscribeToStreamPlayersChanges( + ctx context.Context, + ) (<-chan DiffStreamPlayers, error) - AddTimer(ctx context.Context, triggerAt time.Time, action TimerAction) (TimerID, error) + AddTimer( + ctx context.Context, + triggerAt time.Time, + action Action, + ) (TimerID, error) RemoveTimer(ctx context.Context, timerID TimerID) error ListTimers(ctx context.Context) ([]Timer, error) - AddOBSSceneRule(ctx context.Context, sceneName SceneName, sceneRule SceneRule) error - UpdateOBSSceneRule( + AddTriggerRule( ctx context.Context, - sceneName SceneName, - idx uint64, - sceneRule SceneRule, + triggerRule *config.TriggerRule, + ) (TriggerRuleID, error) + UpdateTriggerRule( + ctx context.Context, + ruleID TriggerRuleID, + triggerRule *config.TriggerRule, + ) error + RemoveTriggerRule( + ctx context.Context, + ruleID TriggerRuleID, + ) error + ListTriggerRules( + ctx context.Context, + ) (TriggerRules, error) + + SubmitEvent( + ctx context.Context, + event event.Event, ) error - RemoveOBSSceneRule(ctx context.Context, sceneName SceneName, idx uint64) error - ListOBSSceneRules(ctx context.Context, sceneName SceneName) (SceneRules, error) } type StreamPlayer = sstypes.StreamPlayer @@ -252,7 +321,9 @@ type DestinationID = streamtypes.DestinationID type OBSInstanceID = streamtypes.OBSInstanceID type StreamForwardingQuirks = sstypes.ForwardingQuirks + type RestartUntilYoutubeRecognizesStream = sstypes.RestartUntilYoutubeRecognizesStream + type StartAfterYoutubeRecognizedStream = sstypes.StartAfterYoutubeRecognizedStream type DiffConfig struct{} @@ -263,51 +334,16 @@ type DiffIncomingStreams struct{} type DiffStreamForwards struct{} type DiffStreamPlayers struct{} -/* - AddTimer(ctx context.Context, triggerAt time.Time, action TimerAction) (TimerID, error) - RemoveTimer(ctx context.Context, timerID TimerID) error - ListTimers(ctx context.Context) ([]Timer, error) -*/ - -type TimerAction interface { - timerAction() // just to enable build-time type checks -} - type TimerID uint64 type Timer struct { ID TimerID TriggerAt time.Time - Action TimerAction + Action Action } -type TimerActionNoop struct{} +type Action = action.Action -var _ TimerAction = (*TimerActionNoop)(nil) - -func (*TimerActionNoop) timerAction() {} - -type TimerActionStartStream struct { - PlatID streamcontrol.PlatformName - Title string - Description string - Profile streamcontrol.AbstractStreamProfile - CustomArgs []any -} - -var _ TimerAction = (*TimerActionStartStream)(nil) - -func (*TimerActionStartStream) timerAction() {} - -type TimerActionEndStream struct { - PlatID streamcontrol.PlatformName -} - -var _ TimerAction = (*TimerActionEndStream)(nil) - -func (*TimerActionEndStream) timerAction() {} - -type SceneName = obs.SceneName - -type SceneRule = obs.SceneRule -type SceneRules = obs.SceneRules +type TriggerRuleID uint64 +type TriggerRule = config.TriggerRule +type TriggerRules = config.TriggerRules diff --git a/pkg/streamd/client/client.go b/pkg/streamd/client/client.go index f1ff31b..13723d0 100644 --- a/pkg/streamd/client/client.go +++ b/pkg/streamd/client/client.go @@ -28,6 +28,7 @@ import ( youtube "github.com/xaionaro-go/streamctl/pkg/streamcontrol/youtube/types" "github.com/xaionaro-go/streamctl/pkg/streamd/api" streamdconfig "github.com/xaionaro-go/streamctl/pkg/streamd/config" + "github.com/xaionaro-go/streamctl/pkg/streamd/config/event" "github.com/xaionaro-go/streamctl/pkg/streamd/grpc/go/streamd_grpc" "github.com/xaionaro-go/streamctl/pkg/streamd/grpc/goconv" "github.com/xaionaro-go/streamctl/pkg/streampanel/consts" @@ -2422,7 +2423,7 @@ func (c *Client) GetLoggingLevel( func (c *Client) AddTimer( ctx context.Context, triggerAt time.Time, - action api.TimerAction, + action api.Action, ) (api.TimerID, error) { actionGRPC, err := goconv.ActionGo2GRPC(action) if err != nil { @@ -2529,33 +2530,142 @@ func (c *Client) ListTimers( return result, nil } -func (c *Client) AddOBSSceneRule( +func (c *Client) AddTriggerRule( ctx context.Context, - sceneName obs.SceneName, - sceneRule obs.SceneRule, + triggerRule *api.TriggerRule, +) (api.TriggerRuleID, error) { + triggerRuleGRPC, err := goconv.TriggerRuleGo2GRPC(triggerRule) + if err != nil { + return 0, fmt.Errorf("unable to convert the trigger rule %#+v: %w", triggerRule, err) + } + resp, err := withStreamDClient(ctx, c, func( + ctx context.Context, + client streamd_grpc.StreamDClient, + conn io.Closer, + ) (*streamd_grpc.AddTriggerRuleReply, error) { + return callWrapper( + ctx, + c, + client.AddTriggerRule, + &streamd_grpc.AddTriggerRuleRequest{ + Rule: triggerRuleGRPC, + }, + ) + }) + if err != nil { + return 0, fmt.Errorf("unable to add the trigger rule %#+v: %w", triggerRule, err) + } + return api.TriggerRuleID(resp.GetRuleID()), nil +} + +func (c *Client) UpdateTriggerRule( + ctx context.Context, + ruleID api.TriggerRuleID, + triggerRule *api.TriggerRule, ) error { - + triggerRuleGRPC, err := goconv.TriggerRuleGo2GRPC(triggerRule) + if err != nil { + return fmt.Errorf("unable to convert the trigger rule %#+v: %w", ruleID, triggerRule, err) + } + _, err = withStreamDClient(ctx, c, func( + ctx context.Context, + client streamd_grpc.StreamDClient, + conn io.Closer, + ) (*streamd_grpc.UpdateTriggerRuleReply, error) { + return callWrapper( + ctx, + c, + client.UpdateTriggerRule, + &streamd_grpc.UpdateTriggerRuleRequest{ + RuleID: uint64(ruleID), + Rule: triggerRuleGRPC, + }, + ) + }) + if err != nil { + return fmt.Errorf("unable to update the trigger rule %d to %#+v: %w", ruleID, triggerRule, err) + } + return nil } - -func (c *Client) UpdateOBSSceneRule( +func (c *Client) RemoveTriggerRule( ctx context.Context, - sceneName obs.SceneName, - idx uint64, - sceneRule obs.SceneRule, + ruleID api.TriggerRuleID, ) error { - + _, err := withStreamDClient(ctx, c, func( + ctx context.Context, + client streamd_grpc.StreamDClient, + conn io.Closer, + ) (*streamd_grpc.RemoveTriggerRuleReply, error) { + return callWrapper( + ctx, + c, + client.RemoveTriggerRule, + &streamd_grpc.RemoveTriggerRuleRequest{ + RuleID: uint64(ruleID), + }, + ) + }) + if err != nil { + return fmt.Errorf("unable to remove the rule %d: %w", ruleID, err) + } + return nil } -func (c *Client) RemoveOBSSceneRule( + +func (c *Client) ListTriggerRules( ctx context.Context, - sceneName obs.SceneName, - idx uint64, +) (api.TriggerRules, error) { + response, err := withStreamDClient(ctx, c, func( + ctx context.Context, + client streamd_grpc.StreamDClient, + conn io.Closer, + ) (*streamd_grpc.ListTriggerRulesReply, error) { + return callWrapper( + ctx, + c, + client.ListTriggerRules, + &streamd_grpc.ListTriggerRulesRequest{}, + ) + }) + if err != nil { + return nil, fmt.Errorf("unable to list the rules: %w", err) + } + + rules := response.GetRules() + result := make(api.TriggerRules, 0, len(rules)) + for _, ruleGRPC := range rules { + rule, err := goconv.TriggerRuleGRPC2Go(ruleGRPC) + if err != nil { + return nil, fmt.Errorf("unable to convert the trigger rule %#+v: %w", rule, err) + } + result = append(result, rule) + } + return result, nil +} + +func (c *Client) SubmitEvent( + ctx context.Context, + event event.Event, ) error { - -} - -func (c *Client) ListOBSSceneRules( - ctx context.Context, - sceneName obs.SceneName, -) (obs.SceneRules, error) { - + eventGRPC, err := goconv.EventGo2GRPC(event) + if err != nil { + return fmt.Errorf("unable to convert the event: %w", err) + } + _, err = withStreamDClient(ctx, c, func( + ctx context.Context, + client streamd_grpc.StreamDClient, + conn io.Closer, + ) (*streamd_grpc.SubmitEventReply, error) { + return callWrapper( + ctx, + c, + client.SubmitEvent, + &streamd_grpc.SubmitEventRequest{ + Event: eventGRPC, + }, + ) + }) + if err != nil { + return fmt.Errorf("unable to submit the event: %w", err) + } + return nil } diff --git a/pkg/streamd/config/action/action.go b/pkg/streamd/config/action/action.go new file mode 100644 index 0000000..ab642ac --- /dev/null +++ b/pkg/streamd/config/action/action.go @@ -0,0 +1,70 @@ +package action + +import ( + "github.com/xaionaro-go/streamctl/pkg/expression" + "github.com/xaionaro-go/streamctl/pkg/serializable" + "github.com/xaionaro-go/streamctl/pkg/streamcontrol" +) + +func init() { + serializable.RegisterType[Noop]() + serializable.RegisterType[OBSElementShowHide]() + serializable.RegisterType[OBSWindowCaptureSetSource]() + serializable.RegisterType[StartStream]() + serializable.RegisterType[EndStream]() +} + +type Action interface { + isAction() // just to enable build-time type checks +} + +type ValueExpression = expression.Expression + +type OBSElementShowHide struct { + ElementName *string `yaml:"element_name,omitempty" json:"element_name,omitempty"` + ElementUUID *string `yaml:"element_uuid,omitempty" json:"element_uuid,omitempty"` + ValueExpression ValueExpression `yaml:"value_expression,omitempty" json:"value_expression,omitempty"` +} + +var _ Action = (*OBSElementShowHide)(nil) + +func (OBSElementShowHide) isAction() {} + +type OBSWindowCaptureSetSource struct { + ElementName *string `yaml:"element_name,omitempty" json:"element_name,omitempty"` + ElementUUID *string `yaml:"element_uuid,omitempty" json:"element_uuid,omitempty"` + ValueExpression ValueExpression `yaml:"value_expression,omitempty" json:"value_expression,omitempty"` +} + +var _ Action = (*OBSWindowCaptureSetSource)(nil) + +func (OBSWindowCaptureSetSource) isAction() {} + +type Noop struct{} + +var _ Action = (*Noop)(nil) + +func (*Noop) isAction() {} + +type StartStream struct { + PlatID streamcontrol.PlatformName + Title string + Description string + Profile streamcontrol.AbstractStreamProfile + CustomArgs []any + + //lint:ignore U1000 this field is used by reflection + uiDisable struct{} // currently out current reflect-y generator of fyne-Entry-ies does not support interfaces like field 'Profile' here, so we just forbid using this action. +} + +var _ Action = (*StartStream)(nil) + +func (*StartStream) isAction() {} + +type EndStream struct { + PlatID streamcontrol.PlatformName +} + +var _ Action = (*EndStream)(nil) + +func (*EndStream) isAction() {} diff --git a/pkg/streamd/config/config.go b/pkg/streamd/config/config.go index 8e28e79..f0a102e 100644 --- a/pkg/streamd/config/config.go +++ b/pkg/streamd/config/config.go @@ -26,6 +26,7 @@ type config struct { ProfileMetadata map[streamcontrol.ProfileName]ProfileMetadata StreamServer streamserver.Config `yaml:"stream_server"` Monitor MonitorConfig + TriggerRules TriggerRules `yaml:"trigger_rules"` } type Config config diff --git a/pkg/streamcontrol/obs/types/trigger/query.go b/pkg/streamd/config/event/event.go similarity index 71% rename from pkg/streamcontrol/obs/types/trigger/query.go rename to pkg/streamd/config/event/event.go index 339aa0f..e283a71 100644 --- a/pkg/streamcontrol/obs/types/trigger/query.go +++ b/pkg/streamd/config/event/event.go @@ -1,16 +1,13 @@ -package trigger +package event + +import "github.com/xaionaro-go/streamctl/pkg/serializable" func init() { - //registry.RegisterType((*Not)(nil)) - registry.RegisterType((*WindowFocusChange)(nil)) + serializable.RegisterType[WindowFocusChange]() } -type Query interface { - isTriggerQuery() -} - -type Not struct { - Query `yaml:"query"` +type Event interface { + isEvent() // just to enable build-time type checks } type WindowFocusChange struct { @@ -23,4 +20,4 @@ type WindowFocusChange struct { uiComment struct{} `uicomment:"This action will also add field .IsFocused to the event."` } -func (WindowFocusChange) isTriggerQuery() {} +func (WindowFocusChange) isEvent() {} diff --git a/pkg/streamd/config/event/eventquery/event_query.go b/pkg/streamd/config/event/eventquery/event_query.go new file mode 100644 index 0000000..21c5608 --- /dev/null +++ b/pkg/streamd/config/event/eventquery/event_query.go @@ -0,0 +1,27 @@ +package eventquery + +import ( + "github.com/xaionaro-go/streamctl/pkg/serializable" + "github.com/xaionaro-go/streamctl/pkg/streamd/config/event" +) + +func init() { + serializable.RegisterType[EventType[event.WindowFocusChange]]() +} + +type EventQuery interface { + Match(event.Event) bool +} + +type Event serializable.Serializable[event.Event] + +func (ev Event) Match(cmp event.Event) bool { + return ev.Value == cmp +} + +type EventType[T event.Event] struct{} + +func (EventType[T]) Match(ev event.Event) bool { + _, ok := ev.(T) + return ok +} diff --git a/pkg/streamd/config/trigger_rule.go b/pkg/streamd/config/trigger_rule.go new file mode 100644 index 0000000..b176222 --- /dev/null +++ b/pkg/streamd/config/trigger_rule.go @@ -0,0 +1,94 @@ +package config + +import ( + "encoding/json" + "fmt" + + "github.com/goccy/go-yaml" + + "github.com/xaionaro-go/streamctl/pkg/serializable" + "github.com/xaionaro-go/streamctl/pkg/serializable/registry" + "github.com/xaionaro-go/streamctl/pkg/streamd/config/action" + "github.com/xaionaro-go/streamctl/pkg/streamd/config/event" + "github.com/xaionaro-go/streamctl/pkg/streamd/config/event/eventquery" +) + +type TriggerRules []*TriggerRule +type Event = event.Event +type EventQuery = eventquery.EventQuery + +type TriggerRule struct { + Description string `yaml:"description,omitempty" json:"description,omitempty"` + EventQuery eventquery.EventQuery `yaml:"trigger" json:"trigger"` + Action action.Action `yaml:"action" json:"action"` +} + +var _ yaml.BytesMarshaler = (*TriggerRule)(nil) +var _ yaml.BytesUnmarshaler = (*TriggerRule)(nil) + +func (tr *TriggerRule) UnmarshalYAML(b []byte) (_err error) { + if tr == nil { + return fmt.Errorf("nil TriggerRule") + } + + intermediate := serializableTriggerRule{} + err := yaml.Unmarshal(b, &intermediate) + if err != nil { + return fmt.Errorf("unable to unmarshal the TriggerRule: %w", err) + } + + *tr = TriggerRule{ + Description: intermediate.Description, + EventQuery: intermediate.EventQuery.Value, + Action: intermediate.Action.Value, + } + return nil +} + +func (tr TriggerRule) MarshalYAML() (b []byte, _err error) { + return yaml.Marshal(serializableTriggerRule{ + Description: "", + EventQuery: serializable.Serializable[eventquery.EventQuery]{Value: tr.EventQuery}, + Action: serializable.Serializable[action.Action]{Value: tr.Action}, + }) +} + +type serializableTriggerRule struct { + Description string `yaml:"description,omitempty" json:"description,omitempty"` + EventQuery serializable.Serializable[eventquery.EventQuery] `yaml:"trigger" json:"trigger"` + Action serializable.Serializable[action.Action] `yaml:"action" json:"action"` +} + +func (tr TriggerRule) String() string { + descr := tr.Description + if descr != "" { + descr += ": " + } + eventQueryJSON := string(tryJSON(tr.EventQuery)) + if eventQueryJSON != "{}" { + eventQueryJSON = ":" + eventQueryJSON + } else { + eventQueryJSON = "" + } + actionJSON := string(tryJSON(tr.Action)) + if actionJSON != "{}" { + actionJSON = ":" + actionJSON + } else { + actionJSON = "" + } + return fmt.Sprintf( + "%s%s%s -> %s%s", + descr, + typeName(tr.EventQuery), eventQueryJSON, + typeName(tr.Action), actionJSON, + ) +} + +func typeName(value any) string { + return registry.ToTypeName(value) +} + +func tryJSON(value any) []byte { + b, _ := json.Marshal(value) + return b +} diff --git a/pkg/streamd/events.go b/pkg/streamd/events.go new file mode 100644 index 0000000..f695c55 --- /dev/null +++ b/pkg/streamd/events.go @@ -0,0 +1,82 @@ +package streamd + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/facebookincubator/go-belt/tool/logger" + "github.com/xaionaro-go/streamctl/pkg/expression" + "github.com/xaionaro-go/streamctl/pkg/observability" + "github.com/xaionaro-go/streamctl/pkg/streamd/config/action" + "github.com/xaionaro-go/streamctl/pkg/streamd/config/event" + "github.com/xaionaro-go/streamctl/pkg/xsync" +) + +func (d *StreamD) SubmitEvent( + ctx context.Context, + ev event.Event, +) error { + return xsync.DoA2R1(ctx, &d.ConfigLock, d.submitEvent, ctx, ev) +} + +func objToMap(obj any) map[string]any { + b, err := json.Marshal(obj) + if err != nil { + panic(err) + } + m := map[string]any{} + err = json.Unmarshal(b, &m) + if err != nil { + panic(err) + } + return m +} + +func (d *StreamD) submitEvent( + ctx context.Context, + ev event.Event, +) error { + exprCtx := objToMap(ev) + for _, rule := range d.Config.TriggerRules { + if rule.EventQuery.Match(ev) { + observability.Go(ctx, func() { + err := d.doAction(ctx, rule.Action, exprCtx) + if err != nil { + logger.Errorf(ctx, "unable to perform action %#+v: %w", rule.Action, err) + } + }) + } + } + return nil +} + +func (d *StreamD) doAction( + ctx context.Context, + a action.Action, + exprCtx any, +) error { + switch a := a.(type) { + case *action.Noop: + return nil + case *action.StartStream: + return d.StartStream(ctx, a.PlatID, a.Title, a.Description, a.Profile, a.CustomArgs...) + case *action.EndStream: + return d.EndStream(ctx, a.PlatID) + case *action.OBSElementShowHide: + value, err := expression.Eval[bool](a.ValueExpression, exprCtx) + if err != nil { + return fmt.Errorf("unable to Eval() the expression '%s': %w", a.ValueExpression, err) + } + return d.OBSElementSetShow( + ctx, + SceneElementIdentifier{ + Name: a.ElementName, + UUID: a.ElementUUID, + }, + value, + ) + default: + return fmt.Errorf("unknown action type: %T", a) + } +} diff --git a/pkg/streamd/grpc/go/streamd_grpc/streamd.pb.go b/pkg/streamd/grpc/go/streamd_grpc/streamd.pb.go index f3699c4..4909091 100644 --- a/pkg/streamd/grpc/go/streamd_grpc/streamd.pb.go +++ b/pkg/streamd/grpc/go/streamd_grpc/streamd.pb.go @@ -226,6 +226,52 @@ func (PlayerType) EnumDescriptor() ([]byte, []int) { return file_streamd_proto_rawDescGZIP(), []int{3} } +type EventType int32 + +const ( + EventType_eventWindowFocusChange EventType = 0 + EventType_eventOBSSceneChange EventType = 1 +) + +// Enum value maps for EventType. +var ( + EventType_name = map[int32]string{ + 0: "eventWindowFocusChange", + 1: "eventOBSSceneChange", + } + EventType_value = map[string]int32{ + "eventWindowFocusChange": 0, + "eventOBSSceneChange": 1, + } +) + +func (x EventType) Enum() *EventType { + p := new(EventType) + *p = x + return p +} + +func (x EventType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (EventType) Descriptor() protoreflect.EnumDescriptor { + return file_streamd_proto_enumTypes[4].Descriptor() +} + +func (EventType) Type() protoreflect.EnumType { + return &file_streamd_proto_enumTypes[4] +} + +func (x EventType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use EventType.Descriptor instead. +func (EventType) EnumDescriptor() ([]byte, []int) { + return file_streamd_proto_rawDescGZIP(), []int{4} +} + type PingRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -7059,6 +7105,213 @@ func (*NoopRequest) Descriptor() ([]byte, []int) { return file_streamd_proto_rawDescGZIP(), []int{145} } +type OBSActionElementShowHide struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ElementName *string `protobuf:"bytes,1,opt,name=elementName,proto3,oneof" json:"elementName,omitempty"` + ElementUUID *string `protobuf:"bytes,2,opt,name=elementUUID,proto3,oneof" json:"elementUUID,omitempty"` + ValueExpression string `protobuf:"bytes,3,opt,name=valueExpression,proto3" json:"valueExpression,omitempty"` +} + +func (x *OBSActionElementShowHide) Reset() { + *x = OBSActionElementShowHide{} + if protoimpl.UnsafeEnabled { + mi := &file_streamd_proto_msgTypes[146] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OBSActionElementShowHide) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OBSActionElementShowHide) ProtoMessage() {} + +func (x *OBSActionElementShowHide) ProtoReflect() protoreflect.Message { + mi := &file_streamd_proto_msgTypes[146] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OBSActionElementShowHide.ProtoReflect.Descriptor instead. +func (*OBSActionElementShowHide) Descriptor() ([]byte, []int) { + return file_streamd_proto_rawDescGZIP(), []int{146} +} + +func (x *OBSActionElementShowHide) GetElementName() string { + if x != nil && x.ElementName != nil { + return *x.ElementName + } + return "" +} + +func (x *OBSActionElementShowHide) GetElementUUID() string { + if x != nil && x.ElementUUID != nil { + return *x.ElementUUID + } + return "" +} + +func (x *OBSActionElementShowHide) GetValueExpression() string { + if x != nil { + return x.ValueExpression + } + return "" +} + +type OBSActionWindowCaptureSetSource struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ElementName *string `protobuf:"bytes,1,opt,name=elementName,proto3,oneof" json:"elementName,omitempty"` + ElementUUID *string `protobuf:"bytes,2,opt,name=elementUUID,proto3,oneof" json:"elementUUID,omitempty"` + ValueExpression string `protobuf:"bytes,3,opt,name=valueExpression,proto3" json:"valueExpression,omitempty"` +} + +func (x *OBSActionWindowCaptureSetSource) Reset() { + *x = OBSActionWindowCaptureSetSource{} + if protoimpl.UnsafeEnabled { + mi := &file_streamd_proto_msgTypes[147] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OBSActionWindowCaptureSetSource) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OBSActionWindowCaptureSetSource) ProtoMessage() {} + +func (x *OBSActionWindowCaptureSetSource) ProtoReflect() protoreflect.Message { + mi := &file_streamd_proto_msgTypes[147] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OBSActionWindowCaptureSetSource.ProtoReflect.Descriptor instead. +func (*OBSActionWindowCaptureSetSource) Descriptor() ([]byte, []int) { + return file_streamd_proto_rawDescGZIP(), []int{147} +} + +func (x *OBSActionWindowCaptureSetSource) GetElementName() string { + if x != nil && x.ElementName != nil { + return *x.ElementName + } + return "" +} + +func (x *OBSActionWindowCaptureSetSource) GetElementUUID() string { + if x != nil && x.ElementUUID != nil { + return *x.ElementUUID + } + return "" +} + +func (x *OBSActionWindowCaptureSetSource) GetValueExpression() string { + if x != nil { + return x.ValueExpression + } + return "" +} + +type OBSAction struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to OBSActionOneOf: + // + // *OBSAction_ElementShowHide + // *OBSAction_WindowCaptureSetSource + OBSActionOneOf isOBSAction_OBSActionOneOf `protobuf_oneof:"OBSActionOneOf"` +} + +func (x *OBSAction) Reset() { + *x = OBSAction{} + if protoimpl.UnsafeEnabled { + mi := &file_streamd_proto_msgTypes[148] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OBSAction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OBSAction) ProtoMessage() {} + +func (x *OBSAction) ProtoReflect() protoreflect.Message { + mi := &file_streamd_proto_msgTypes[148] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OBSAction.ProtoReflect.Descriptor instead. +func (*OBSAction) Descriptor() ([]byte, []int) { + return file_streamd_proto_rawDescGZIP(), []int{148} +} + +func (m *OBSAction) GetOBSActionOneOf() isOBSAction_OBSActionOneOf { + if m != nil { + return m.OBSActionOneOf + } + return nil +} + +func (x *OBSAction) GetElementShowHide() *OBSActionElementShowHide { + if x, ok := x.GetOBSActionOneOf().(*OBSAction_ElementShowHide); ok { + return x.ElementShowHide + } + return nil +} + +func (x *OBSAction) GetWindowCaptureSetSource() *OBSActionWindowCaptureSetSource { + if x, ok := x.GetOBSActionOneOf().(*OBSAction_WindowCaptureSetSource); ok { + return x.WindowCaptureSetSource + } + return nil +} + +type isOBSAction_OBSActionOneOf interface { + isOBSAction_OBSActionOneOf() +} + +type OBSAction_ElementShowHide struct { + ElementShowHide *OBSActionElementShowHide `protobuf:"bytes,1,opt,name=elementShowHide,proto3,oneof"` +} + +type OBSAction_WindowCaptureSetSource struct { + WindowCaptureSetSource *OBSActionWindowCaptureSetSource `protobuf:"bytes,2,opt,name=windowCaptureSetSource,proto3,oneof"` +} + +func (*OBSAction_ElementShowHide) isOBSAction_OBSActionOneOf() {} + +func (*OBSAction_WindowCaptureSetSource) isOBSAction_OBSActionOneOf() {} + type Action struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -7069,13 +7322,14 @@ type Action struct { // *Action_NoopRequest // *Action_StartStreamRequest // *Action_EndStreamRequest + // *Action_ObsAction ActionOneof isAction_ActionOneof `protobuf_oneof:"ActionOneof"` } func (x *Action) Reset() { *x = Action{} if protoimpl.UnsafeEnabled { - mi := &file_streamd_proto_msgTypes[146] + mi := &file_streamd_proto_msgTypes[149] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7088,7 +7342,7 @@ func (x *Action) String() string { func (*Action) ProtoMessage() {} func (x *Action) ProtoReflect() protoreflect.Message { - mi := &file_streamd_proto_msgTypes[146] + mi := &file_streamd_proto_msgTypes[149] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7101,7 +7355,7 @@ func (x *Action) ProtoReflect() protoreflect.Message { // Deprecated: Use Action.ProtoReflect.Descriptor instead. func (*Action) Descriptor() ([]byte, []int) { - return file_streamd_proto_rawDescGZIP(), []int{146} + return file_streamd_proto_rawDescGZIP(), []int{149} } func (m *Action) GetActionOneof() isAction_ActionOneof { @@ -7132,6 +7386,13 @@ func (x *Action) GetEndStreamRequest() *EndStreamRequest { return nil } +func (x *Action) GetObsAction() *OBSAction { + if x, ok := x.GetActionOneof().(*Action_ObsAction); ok { + return x.ObsAction + } + return nil +} + type isAction_ActionOneof interface { isAction_ActionOneof() } @@ -7148,12 +7409,18 @@ type Action_EndStreamRequest struct { EndStreamRequest *EndStreamRequest `protobuf:"bytes,3,opt,name=endStreamRequest,proto3,oneof"` } +type Action_ObsAction struct { + ObsAction *OBSAction `protobuf:"bytes,4,opt,name=obsAction,proto3,oneof"` +} + func (*Action_NoopRequest) isAction_ActionOneof() {} func (*Action_StartStreamRequest) isAction_ActionOneof() {} func (*Action_EndStreamRequest) isAction_ActionOneof() {} +func (*Action_ObsAction) isAction_ActionOneof() {} + type AddTimerRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -7166,7 +7433,7 @@ type AddTimerRequest struct { func (x *AddTimerRequest) Reset() { *x = AddTimerRequest{} if protoimpl.UnsafeEnabled { - mi := &file_streamd_proto_msgTypes[147] + mi := &file_streamd_proto_msgTypes[150] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7179,7 +7446,7 @@ func (x *AddTimerRequest) String() string { func (*AddTimerRequest) ProtoMessage() {} func (x *AddTimerRequest) ProtoReflect() protoreflect.Message { - mi := &file_streamd_proto_msgTypes[147] + mi := &file_streamd_proto_msgTypes[150] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7192,7 +7459,7 @@ func (x *AddTimerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AddTimerRequest.ProtoReflect.Descriptor instead. func (*AddTimerRequest) Descriptor() ([]byte, []int) { - return file_streamd_proto_rawDescGZIP(), []int{147} + return file_streamd_proto_rawDescGZIP(), []int{150} } func (x *AddTimerRequest) GetTriggerAtUnixNano() int64 { @@ -7220,7 +7487,7 @@ type AddTimerReply struct { func (x *AddTimerReply) Reset() { *x = AddTimerReply{} if protoimpl.UnsafeEnabled { - mi := &file_streamd_proto_msgTypes[148] + mi := &file_streamd_proto_msgTypes[151] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7233,7 +7500,7 @@ func (x *AddTimerReply) String() string { func (*AddTimerReply) ProtoMessage() {} func (x *AddTimerReply) ProtoReflect() protoreflect.Message { - mi := &file_streamd_proto_msgTypes[148] + mi := &file_streamd_proto_msgTypes[151] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7246,7 +7513,7 @@ func (x *AddTimerReply) ProtoReflect() protoreflect.Message { // Deprecated: Use AddTimerReply.ProtoReflect.Descriptor instead. func (*AddTimerReply) Descriptor() ([]byte, []int) { - return file_streamd_proto_rawDescGZIP(), []int{148} + return file_streamd_proto_rawDescGZIP(), []int{151} } func (x *AddTimerReply) GetTimerID() int64 { @@ -7267,7 +7534,7 @@ type RemoveTimerRequest struct { func (x *RemoveTimerRequest) Reset() { *x = RemoveTimerRequest{} if protoimpl.UnsafeEnabled { - mi := &file_streamd_proto_msgTypes[149] + mi := &file_streamd_proto_msgTypes[152] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7280,7 +7547,7 @@ func (x *RemoveTimerRequest) String() string { func (*RemoveTimerRequest) ProtoMessage() {} func (x *RemoveTimerRequest) ProtoReflect() protoreflect.Message { - mi := &file_streamd_proto_msgTypes[149] + mi := &file_streamd_proto_msgTypes[152] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7293,7 +7560,7 @@ func (x *RemoveTimerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveTimerRequest.ProtoReflect.Descriptor instead. func (*RemoveTimerRequest) Descriptor() ([]byte, []int) { - return file_streamd_proto_rawDescGZIP(), []int{149} + return file_streamd_proto_rawDescGZIP(), []int{152} } func (x *RemoveTimerRequest) GetTimerID() int64 { @@ -7312,7 +7579,7 @@ type RemoveTimerReply struct { func (x *RemoveTimerReply) Reset() { *x = RemoveTimerReply{} if protoimpl.UnsafeEnabled { - mi := &file_streamd_proto_msgTypes[150] + mi := &file_streamd_proto_msgTypes[153] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7325,7 +7592,7 @@ func (x *RemoveTimerReply) String() string { func (*RemoveTimerReply) ProtoMessage() {} func (x *RemoveTimerReply) ProtoReflect() protoreflect.Message { - mi := &file_streamd_proto_msgTypes[150] + mi := &file_streamd_proto_msgTypes[153] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7338,7 +7605,7 @@ func (x *RemoveTimerReply) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveTimerReply.ProtoReflect.Descriptor instead. func (*RemoveTimerReply) Descriptor() ([]byte, []int) { - return file_streamd_proto_rawDescGZIP(), []int{150} + return file_streamd_proto_rawDescGZIP(), []int{153} } type Timer struct { @@ -7354,7 +7621,7 @@ type Timer struct { func (x *Timer) Reset() { *x = Timer{} if protoimpl.UnsafeEnabled { - mi := &file_streamd_proto_msgTypes[151] + mi := &file_streamd_proto_msgTypes[154] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7367,7 +7634,7 @@ func (x *Timer) String() string { func (*Timer) ProtoMessage() {} func (x *Timer) ProtoReflect() protoreflect.Message { - mi := &file_streamd_proto_msgTypes[151] + mi := &file_streamd_proto_msgTypes[154] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7380,7 +7647,7 @@ func (x *Timer) ProtoReflect() protoreflect.Message { // Deprecated: Use Timer.ProtoReflect.Descriptor instead. func (*Timer) Descriptor() ([]byte, []int) { - return file_streamd_proto_rawDescGZIP(), []int{151} + return file_streamd_proto_rawDescGZIP(), []int{154} } func (x *Timer) GetTimerID() int64 { @@ -7413,7 +7680,7 @@ type ListTimersRequest struct { func (x *ListTimersRequest) Reset() { *x = ListTimersRequest{} if protoimpl.UnsafeEnabled { - mi := &file_streamd_proto_msgTypes[152] + mi := &file_streamd_proto_msgTypes[155] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7426,7 +7693,7 @@ func (x *ListTimersRequest) String() string { func (*ListTimersRequest) ProtoMessage() {} func (x *ListTimersRequest) ProtoReflect() protoreflect.Message { - mi := &file_streamd_proto_msgTypes[152] + mi := &file_streamd_proto_msgTypes[155] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7439,7 +7706,7 @@ func (x *ListTimersRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListTimersRequest.ProtoReflect.Descriptor instead. func (*ListTimersRequest) Descriptor() ([]byte, []int) { - return file_streamd_proto_rawDescGZIP(), []int{152} + return file_streamd_proto_rawDescGZIP(), []int{155} } type ListTimersReply struct { @@ -7453,7 +7720,7 @@ type ListTimersReply struct { func (x *ListTimersReply) Reset() { *x = ListTimersReply{} if protoimpl.UnsafeEnabled { - mi := &file_streamd_proto_msgTypes[153] + mi := &file_streamd_proto_msgTypes[156] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7466,7 +7733,7 @@ func (x *ListTimersReply) String() string { func (*ListTimersReply) ProtoMessage() {} func (x *ListTimersReply) ProtoReflect() protoreflect.Message { - mi := &file_streamd_proto_msgTypes[153] + mi := &file_streamd_proto_msgTypes[156] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7479,7 +7746,7 @@ func (x *ListTimersReply) ProtoReflect() protoreflect.Message { // Deprecated: Use ListTimersReply.ProtoReflect.Descriptor instead. func (*ListTimersReply) Descriptor() ([]byte, []int) { - return file_streamd_proto_rawDescGZIP(), []int{153} + return file_streamd_proto_rawDescGZIP(), []int{156} } func (x *ListTimersReply) GetTimers() []*Timer { @@ -7489,6 +7756,974 @@ func (x *ListTimersReply) GetTimers() []*Timer { return nil } +type EventQueryAnd struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Queries []*Event `protobuf:"bytes,1,rep,name=queries,proto3" json:"queries,omitempty"` +} + +func (x *EventQueryAnd) Reset() { + *x = EventQueryAnd{} + if protoimpl.UnsafeEnabled { + mi := &file_streamd_proto_msgTypes[157] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EventQueryAnd) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EventQueryAnd) ProtoMessage() {} + +func (x *EventQueryAnd) ProtoReflect() protoreflect.Message { + mi := &file_streamd_proto_msgTypes[157] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EventQueryAnd.ProtoReflect.Descriptor instead. +func (*EventQueryAnd) Descriptor() ([]byte, []int) { + return file_streamd_proto_rawDescGZIP(), []int{157} +} + +func (x *EventQueryAnd) GetQueries() []*Event { + if x != nil { + return x.Queries + } + return nil +} + +type EventQueryOr struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Queries []*Event `protobuf:"bytes,1,rep,name=queries,proto3" json:"queries,omitempty"` +} + +func (x *EventQueryOr) Reset() { + *x = EventQueryOr{} + if protoimpl.UnsafeEnabled { + mi := &file_streamd_proto_msgTypes[158] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EventQueryOr) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EventQueryOr) ProtoMessage() {} + +func (x *EventQueryOr) ProtoReflect() protoreflect.Message { + mi := &file_streamd_proto_msgTypes[158] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EventQueryOr.ProtoReflect.Descriptor instead. +func (*EventQueryOr) Descriptor() ([]byte, []int) { + return file_streamd_proto_rawDescGZIP(), []int{158} +} + +func (x *EventQueryOr) GetQueries() []*Event { + if x != nil { + return x.Queries + } + return nil +} + +type EventQueryNot struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Query *Event `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` +} + +func (x *EventQueryNot) Reset() { + *x = EventQueryNot{} + if protoimpl.UnsafeEnabled { + mi := &file_streamd_proto_msgTypes[159] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EventQueryNot) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EventQueryNot) ProtoMessage() {} + +func (x *EventQueryNot) ProtoReflect() protoreflect.Message { + mi := &file_streamd_proto_msgTypes[159] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EventQueryNot.ProtoReflect.Descriptor instead. +func (*EventQueryNot) Descriptor() ([]byte, []int) { + return file_streamd_proto_rawDescGZIP(), []int{159} +} + +func (x *EventQueryNot) GetQuery() *Event { + if x != nil { + return x.Query + } + return nil +} + +type EventOBSSceneChange struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SceneName string `protobuf:"bytes,1,opt,name=sceneName,proto3" json:"sceneName,omitempty"` +} + +func (x *EventOBSSceneChange) Reset() { + *x = EventOBSSceneChange{} + if protoimpl.UnsafeEnabled { + mi := &file_streamd_proto_msgTypes[160] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EventOBSSceneChange) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EventOBSSceneChange) ProtoMessage() {} + +func (x *EventOBSSceneChange) ProtoReflect() protoreflect.Message { + mi := &file_streamd_proto_msgTypes[160] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EventOBSSceneChange.ProtoReflect.Descriptor instead. +func (*EventOBSSceneChange) Descriptor() ([]byte, []int) { + return file_streamd_proto_rawDescGZIP(), []int{160} +} + +func (x *EventOBSSceneChange) GetSceneName() string { + if x != nil { + return x.SceneName + } + return "" +} + +type EventWindowFocusChange struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + WindowID *uint64 `protobuf:"varint,1,opt,name=windowID,proto3,oneof" json:"windowID,omitempty"` + WindowTitle *string `protobuf:"bytes,2,opt,name=windowTitle,proto3,oneof" json:"windowTitle,omitempty"` + WindowTitlePartial *string `protobuf:"bytes,3,opt,name=windowTitlePartial,proto3,oneof" json:"windowTitlePartial,omitempty"` + UserID *uint64 `protobuf:"varint,4,opt,name=userID,proto3,oneof" json:"userID,omitempty"` +} + +func (x *EventWindowFocusChange) Reset() { + *x = EventWindowFocusChange{} + if protoimpl.UnsafeEnabled { + mi := &file_streamd_proto_msgTypes[161] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EventWindowFocusChange) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EventWindowFocusChange) ProtoMessage() {} + +func (x *EventWindowFocusChange) ProtoReflect() protoreflect.Message { + mi := &file_streamd_proto_msgTypes[161] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EventWindowFocusChange.ProtoReflect.Descriptor instead. +func (*EventWindowFocusChange) Descriptor() ([]byte, []int) { + return file_streamd_proto_rawDescGZIP(), []int{161} +} + +func (x *EventWindowFocusChange) GetWindowID() uint64 { + if x != nil && x.WindowID != nil { + return *x.WindowID + } + return 0 +} + +func (x *EventWindowFocusChange) GetWindowTitle() string { + if x != nil && x.WindowTitle != nil { + return *x.WindowTitle + } + return "" +} + +func (x *EventWindowFocusChange) GetWindowTitlePartial() string { + if x != nil && x.WindowTitlePartial != nil { + return *x.WindowTitlePartial + } + return "" +} + +func (x *EventWindowFocusChange) GetUserID() uint64 { + if x != nil && x.UserID != nil { + return *x.UserID + } + return 0 +} + +type EventQuery struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to EventQueryOneOf: + // + // *EventQuery_And + // *EventQuery_Or + // *EventQuery_Not + // *EventQuery_EventType + // *EventQuery_Event + EventQueryOneOf isEventQuery_EventQueryOneOf `protobuf_oneof:"EventQueryOneOf"` +} + +func (x *EventQuery) Reset() { + *x = EventQuery{} + if protoimpl.UnsafeEnabled { + mi := &file_streamd_proto_msgTypes[162] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EventQuery) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EventQuery) ProtoMessage() {} + +func (x *EventQuery) ProtoReflect() protoreflect.Message { + mi := &file_streamd_proto_msgTypes[162] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EventQuery.ProtoReflect.Descriptor instead. +func (*EventQuery) Descriptor() ([]byte, []int) { + return file_streamd_proto_rawDescGZIP(), []int{162} +} + +func (m *EventQuery) GetEventQueryOneOf() isEventQuery_EventQueryOneOf { + if m != nil { + return m.EventQueryOneOf + } + return nil +} + +func (x *EventQuery) GetAnd() *EventQueryAnd { + if x, ok := x.GetEventQueryOneOf().(*EventQuery_And); ok { + return x.And + } + return nil +} + +func (x *EventQuery) GetOr() *EventQueryOr { + if x, ok := x.GetEventQueryOneOf().(*EventQuery_Or); ok { + return x.Or + } + return nil +} + +func (x *EventQuery) GetNot() *EventQueryNot { + if x, ok := x.GetEventQueryOneOf().(*EventQuery_Not); ok { + return x.Not + } + return nil +} + +func (x *EventQuery) GetEventType() EventType { + if x, ok := x.GetEventQueryOneOf().(*EventQuery_EventType); ok { + return x.EventType + } + return EventType_eventWindowFocusChange +} + +func (x *EventQuery) GetEvent() *Event { + if x, ok := x.GetEventQueryOneOf().(*EventQuery_Event); ok { + return x.Event + } + return nil +} + +type isEventQuery_EventQueryOneOf interface { + isEventQuery_EventQueryOneOf() +} + +type EventQuery_And struct { + And *EventQueryAnd `protobuf:"bytes,1,opt,name=and,proto3,oneof"` +} + +type EventQuery_Or struct { + Or *EventQueryOr `protobuf:"bytes,2,opt,name=or,proto3,oneof"` +} + +type EventQuery_Not struct { + Not *EventQueryNot `protobuf:"bytes,3,opt,name=not,proto3,oneof"` +} + +type EventQuery_EventType struct { + EventType EventType `protobuf:"varint,4,opt,name=eventType,proto3,enum=streamd.EventType,oneof"` +} + +type EventQuery_Event struct { + Event *Event `protobuf:"bytes,5,opt,name=event,proto3,oneof"` +} + +func (*EventQuery_And) isEventQuery_EventQueryOneOf() {} + +func (*EventQuery_Or) isEventQuery_EventQueryOneOf() {} + +func (*EventQuery_Not) isEventQuery_EventQueryOneOf() {} + +func (*EventQuery_EventType) isEventQuery_EventQueryOneOf() {} + +func (*EventQuery_Event) isEventQuery_EventQueryOneOf() {} + +type Event struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to EventOneOf: + // + // *Event_ObsSceneChange + // *Event_WindowFocusChange + EventOneOf isEvent_EventOneOf `protobuf_oneof:"EventOneOf"` +} + +func (x *Event) Reset() { + *x = Event{} + if protoimpl.UnsafeEnabled { + mi := &file_streamd_proto_msgTypes[163] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Event) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Event) ProtoMessage() {} + +func (x *Event) ProtoReflect() protoreflect.Message { + mi := &file_streamd_proto_msgTypes[163] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Event.ProtoReflect.Descriptor instead. +func (*Event) Descriptor() ([]byte, []int) { + return file_streamd_proto_rawDescGZIP(), []int{163} +} + +func (m *Event) GetEventOneOf() isEvent_EventOneOf { + if m != nil { + return m.EventOneOf + } + return nil +} + +func (x *Event) GetObsSceneChange() *EventOBSSceneChange { + if x, ok := x.GetEventOneOf().(*Event_ObsSceneChange); ok { + return x.ObsSceneChange + } + return nil +} + +func (x *Event) GetWindowFocusChange() *EventWindowFocusChange { + if x, ok := x.GetEventOneOf().(*Event_WindowFocusChange); ok { + return x.WindowFocusChange + } + return nil +} + +type isEvent_EventOneOf interface { + isEvent_EventOneOf() +} + +type Event_ObsSceneChange struct { + ObsSceneChange *EventOBSSceneChange `protobuf:"bytes,1,opt,name=obsSceneChange,proto3,oneof"` +} + +type Event_WindowFocusChange struct { + WindowFocusChange *EventWindowFocusChange `protobuf:"bytes,2,opt,name=windowFocusChange,proto3,oneof"` +} + +func (*Event_ObsSceneChange) isEvent_EventOneOf() {} + +func (*Event_WindowFocusChange) isEvent_EventOneOf() {} + +type TriggerRule struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Description string `protobuf:"bytes,1,opt,name=Description,proto3" json:"Description,omitempty"` + EventQuery *EventQuery `protobuf:"bytes,2,opt,name=eventQuery,proto3" json:"eventQuery,omitempty"` + Action *Action `protobuf:"bytes,3,opt,name=action,proto3" json:"action,omitempty"` +} + +func (x *TriggerRule) Reset() { + *x = TriggerRule{} + if protoimpl.UnsafeEnabled { + mi := &file_streamd_proto_msgTypes[164] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TriggerRule) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TriggerRule) ProtoMessage() {} + +func (x *TriggerRule) ProtoReflect() protoreflect.Message { + mi := &file_streamd_proto_msgTypes[164] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TriggerRule.ProtoReflect.Descriptor instead. +func (*TriggerRule) Descriptor() ([]byte, []int) { + return file_streamd_proto_rawDescGZIP(), []int{164} +} + +func (x *TriggerRule) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *TriggerRule) GetEventQuery() *EventQuery { + if x != nil { + return x.EventQuery + } + return nil +} + +func (x *TriggerRule) GetAction() *Action { + if x != nil { + return x.Action + } + return nil +} + +type ListTriggerRulesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ListTriggerRulesRequest) Reset() { + *x = ListTriggerRulesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_streamd_proto_msgTypes[165] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListTriggerRulesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListTriggerRulesRequest) ProtoMessage() {} + +func (x *ListTriggerRulesRequest) ProtoReflect() protoreflect.Message { + mi := &file_streamd_proto_msgTypes[165] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListTriggerRulesRequest.ProtoReflect.Descriptor instead. +func (*ListTriggerRulesRequest) Descriptor() ([]byte, []int) { + return file_streamd_proto_rawDescGZIP(), []int{165} +} + +type ListTriggerRulesReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Rules []*TriggerRule `protobuf:"bytes,1,rep,name=rules,proto3" json:"rules,omitempty"` +} + +func (x *ListTriggerRulesReply) Reset() { + *x = ListTriggerRulesReply{} + if protoimpl.UnsafeEnabled { + mi := &file_streamd_proto_msgTypes[166] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListTriggerRulesReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListTriggerRulesReply) ProtoMessage() {} + +func (x *ListTriggerRulesReply) ProtoReflect() protoreflect.Message { + mi := &file_streamd_proto_msgTypes[166] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListTriggerRulesReply.ProtoReflect.Descriptor instead. +func (*ListTriggerRulesReply) Descriptor() ([]byte, []int) { + return file_streamd_proto_rawDescGZIP(), []int{166} +} + +func (x *ListTriggerRulesReply) GetRules() []*TriggerRule { + if x != nil { + return x.Rules + } + return nil +} + +type AddTriggerRuleRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Rule *TriggerRule `protobuf:"bytes,1,opt,name=rule,proto3" json:"rule,omitempty"` +} + +func (x *AddTriggerRuleRequest) Reset() { + *x = AddTriggerRuleRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_streamd_proto_msgTypes[167] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddTriggerRuleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddTriggerRuleRequest) ProtoMessage() {} + +func (x *AddTriggerRuleRequest) ProtoReflect() protoreflect.Message { + mi := &file_streamd_proto_msgTypes[167] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddTriggerRuleRequest.ProtoReflect.Descriptor instead. +func (*AddTriggerRuleRequest) Descriptor() ([]byte, []int) { + return file_streamd_proto_rawDescGZIP(), []int{167} +} + +func (x *AddTriggerRuleRequest) GetRule() *TriggerRule { + if x != nil { + return x.Rule + } + return nil +} + +type AddTriggerRuleReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RuleID uint64 `protobuf:"varint,1,opt,name=ruleID,proto3" json:"ruleID,omitempty"` +} + +func (x *AddTriggerRuleReply) Reset() { + *x = AddTriggerRuleReply{} + if protoimpl.UnsafeEnabled { + mi := &file_streamd_proto_msgTypes[168] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddTriggerRuleReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddTriggerRuleReply) ProtoMessage() {} + +func (x *AddTriggerRuleReply) ProtoReflect() protoreflect.Message { + mi := &file_streamd_proto_msgTypes[168] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddTriggerRuleReply.ProtoReflect.Descriptor instead. +func (*AddTriggerRuleReply) Descriptor() ([]byte, []int) { + return file_streamd_proto_rawDescGZIP(), []int{168} +} + +func (x *AddTriggerRuleReply) GetRuleID() uint64 { + if x != nil { + return x.RuleID + } + return 0 +} + +type RemoveTriggerRuleRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RuleID uint64 `protobuf:"varint,1,opt,name=ruleID,proto3" json:"ruleID,omitempty"` +} + +func (x *RemoveTriggerRuleRequest) Reset() { + *x = RemoveTriggerRuleRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_streamd_proto_msgTypes[169] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveTriggerRuleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveTriggerRuleRequest) ProtoMessage() {} + +func (x *RemoveTriggerRuleRequest) ProtoReflect() protoreflect.Message { + mi := &file_streamd_proto_msgTypes[169] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemoveTriggerRuleRequest.ProtoReflect.Descriptor instead. +func (*RemoveTriggerRuleRequest) Descriptor() ([]byte, []int) { + return file_streamd_proto_rawDescGZIP(), []int{169} +} + +func (x *RemoveTriggerRuleRequest) GetRuleID() uint64 { + if x != nil { + return x.RuleID + } + return 0 +} + +type RemoveTriggerRuleReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *RemoveTriggerRuleReply) Reset() { + *x = RemoveTriggerRuleReply{} + if protoimpl.UnsafeEnabled { + mi := &file_streamd_proto_msgTypes[170] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveTriggerRuleReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveTriggerRuleReply) ProtoMessage() {} + +func (x *RemoveTriggerRuleReply) ProtoReflect() protoreflect.Message { + mi := &file_streamd_proto_msgTypes[170] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemoveTriggerRuleReply.ProtoReflect.Descriptor instead. +func (*RemoveTriggerRuleReply) Descriptor() ([]byte, []int) { + return file_streamd_proto_rawDescGZIP(), []int{170} +} + +type UpdateTriggerRuleRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RuleID uint64 `protobuf:"varint,1,opt,name=ruleID,proto3" json:"ruleID,omitempty"` + Rule *TriggerRule `protobuf:"bytes,2,opt,name=rule,proto3" json:"rule,omitempty"` +} + +func (x *UpdateTriggerRuleRequest) Reset() { + *x = UpdateTriggerRuleRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_streamd_proto_msgTypes[171] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateTriggerRuleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateTriggerRuleRequest) ProtoMessage() {} + +func (x *UpdateTriggerRuleRequest) ProtoReflect() protoreflect.Message { + mi := &file_streamd_proto_msgTypes[171] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateTriggerRuleRequest.ProtoReflect.Descriptor instead. +func (*UpdateTriggerRuleRequest) Descriptor() ([]byte, []int) { + return file_streamd_proto_rawDescGZIP(), []int{171} +} + +func (x *UpdateTriggerRuleRequest) GetRuleID() uint64 { + if x != nil { + return x.RuleID + } + return 0 +} + +func (x *UpdateTriggerRuleRequest) GetRule() *TriggerRule { + if x != nil { + return x.Rule + } + return nil +} + +type UpdateTriggerRuleReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *UpdateTriggerRuleReply) Reset() { + *x = UpdateTriggerRuleReply{} + if protoimpl.UnsafeEnabled { + mi := &file_streamd_proto_msgTypes[172] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateTriggerRuleReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateTriggerRuleReply) ProtoMessage() {} + +func (x *UpdateTriggerRuleReply) ProtoReflect() protoreflect.Message { + mi := &file_streamd_proto_msgTypes[172] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateTriggerRuleReply.ProtoReflect.Descriptor instead. +func (*UpdateTriggerRuleReply) Descriptor() ([]byte, []int) { + return file_streamd_proto_rawDescGZIP(), []int{172} +} + +type SubmitEventRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Event *Event `protobuf:"bytes,1,opt,name=event,proto3" json:"event,omitempty"` +} + +func (x *SubmitEventRequest) Reset() { + *x = SubmitEventRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_streamd_proto_msgTypes[173] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubmitEventRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubmitEventRequest) ProtoMessage() {} + +func (x *SubmitEventRequest) ProtoReflect() protoreflect.Message { + mi := &file_streamd_proto_msgTypes[173] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubmitEventRequest.ProtoReflect.Descriptor instead. +func (*SubmitEventRequest) Descriptor() ([]byte, []int) { + return file_streamd_proto_rawDescGZIP(), []int{173} +} + +func (x *SubmitEventRequest) GetEvent() *Event { + if x != nil { + return x.Event + } + return nil +} + +type SubmitEventReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *SubmitEventReply) Reset() { + *x = SubmitEventReply{} + if protoimpl.UnsafeEnabled { + mi := &file_streamd_proto_msgTypes[174] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubmitEventReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubmitEventReply) ProtoMessage() {} + +func (x *SubmitEventReply) ProtoReflect() protoreflect.Message { + mi := &file_streamd_proto_msgTypes[174] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubmitEventReply.ProtoReflect.Descriptor instead. +func (*SubmitEventReply) Descriptor() ([]byte, []int) { + return file_streamd_proto_rawDescGZIP(), []int{174} +} + var File_streamd_proto protoreflect.FileDescriptor var file_streamd_proto_rawDesc = []byte{ @@ -8100,451 +9335,617 @@ var file_streamd_proto_rawDesc = []byte{ 0x79, 0x65, 0x72, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x22, 0x0d, 0x0a, 0x0b, 0x4e, 0x6f, 0x6f, - 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xe9, 0x01, 0x0a, 0x06, 0x41, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x0b, 0x6e, 0x6f, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x64, 0x2e, 0x4e, 0x6f, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, - 0x52, 0x0b, 0x6e, 0x6f, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4d, 0x0a, - 0x12, 0x73, 0x74, 0x61, 0x72, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x73, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x12, 0x73, 0x74, 0x61, 0x72, 0x74, 0x53, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x47, 0x0a, 0x10, - 0x65, 0x6e, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, - 0x2e, 0x45, 0x6e, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x48, 0x00, 0x52, 0x10, 0x65, 0x6e, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x0d, 0x0a, 0x0b, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, - 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x68, 0x0a, 0x0f, 0x41, 0x64, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x72, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x11, 0x74, 0x72, 0x69, 0x67, 0x67, - 0x65, 0x72, 0x41, 0x74, 0x55, 0x6e, 0x69, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x11, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x41, 0x74, 0x55, 0x6e, 0x69, - 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x12, 0x27, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, - 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x29, - 0x0a, 0x0d, 0x41, 0x64, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, - 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x49, 0x44, 0x22, 0x2e, 0x0a, 0x12, 0x52, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x49, 0x44, 0x22, 0x12, 0x0a, 0x10, 0x52, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x78, 0x0a, - 0x05, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x49, - 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x49, 0x44, - 0x12, 0x2c, 0x0a, 0x11, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x41, 0x74, 0x55, 0x6e, 0x69, - 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x74, 0x72, 0x69, - 0x67, 0x67, 0x65, 0x72, 0x41, 0x74, 0x55, 0x6e, 0x69, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x12, 0x27, - 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, - 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x13, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x54, - 0x69, 0x6d, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x39, 0x0a, 0x0f, - 0x4c, 0x69, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, - 0x26, 0x0a, 0x06, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x0e, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x52, - 0x06, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x73, 0x2a, 0x66, 0x0a, 0x0c, 0x4c, 0x6f, 0x67, 0x67, 0x69, - 0x6e, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x08, 0x0a, 0x04, 0x6e, 0x6f, 0x6e, 0x65, 0x10, - 0x00, 0x12, 0x09, 0x0a, 0x05, 0x66, 0x61, 0x74, 0x61, 0x6c, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, - 0x70, 0x61, 0x6e, 0x69, 0x63, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x10, 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x10, 0x04, 0x12, - 0x08, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x10, 0x05, 0x12, 0x09, 0x0a, 0x05, 0x64, 0x65, 0x62, - 0x75, 0x67, 0x10, 0x06, 0x12, 0x09, 0x0a, 0x05, 0x74, 0x72, 0x61, 0x63, 0x65, 0x10, 0x07, 0x2a, - 0x19, 0x0a, 0x08, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0d, 0x0a, 0x09, 0x48, - 0x41, 0x53, 0x48, 0x5f, 0x53, 0x48, 0x41, 0x31, 0x10, 0x00, 0x2a, 0x35, 0x0a, 0x10, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0d, - 0x0a, 0x09, 0x55, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x10, 0x00, 0x12, 0x08, 0x0a, - 0x04, 0x52, 0x54, 0x53, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x52, 0x54, 0x4d, 0x50, 0x10, - 0x02, 0x2a, 0x49, 0x0a, 0x0a, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x12, 0x0a, 0x0e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x41, 0x75, 0x74, - 0x6f, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x54, 0x79, 0x70, - 0x65, 0x4c, 0x69, 0x62, 0x56, 0x4c, 0x43, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x6c, 0x61, - 0x79, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x4d, 0x50, 0x56, 0x10, 0x02, 0x32, 0xa9, 0x30, 0x0a, - 0x07, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x12, 0x32, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, - 0x12, 0x14, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, - 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0f, - 0x53, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, - 0x1f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x6f, 0x67, - 0x67, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1d, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x6f, - 0x67, 0x67, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, - 0x00, 0x12, 0x53, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x4c, - 0x65, 0x76, 0x65, 0x6c, 0x12, 0x1f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x47, - 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, - 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, - 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x12, 0x19, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x47, 0x65, - 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, - 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x09, 0x53, 0x65, 0x74, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x19, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, - 0x2e, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x17, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x0a, - 0x53, 0x61, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x2e, 0x73, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x61, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, - 0x2e, 0x53, 0x61, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, - 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x18, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x54, - 0x6f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x28, - 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, - 0x62, 0x65, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x64, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x22, - 0x00, 0x30, 0x01, 0x12, 0x44, 0x0a, 0x0a, 0x52, 0x65, 0x73, 0x65, 0x74, 0x43, 0x61, 0x63, 0x68, - 0x65, 0x12, 0x1a, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x52, 0x65, 0x73, 0x65, - 0x74, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, - 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x43, 0x61, 0x63, - 0x68, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x09, 0x49, 0x6e, 0x69, - 0x74, 0x43, 0x61, 0x63, 0x68, 0x65, 0x12, 0x19, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, - 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x17, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x49, 0x6e, 0x69, 0x74, - 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x0b, - 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1b, 0x2e, 0x73, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, - 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x09, 0x45, 0x6e, 0x64, 0x53, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x12, 0x19, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x45, 0x6e, 0x64, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, - 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x45, 0x6e, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x53, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x2e, 0x73, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x73, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x56, 0x0a, - 0x10, 0x49, 0x73, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x64, 0x12, 0x20, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x49, 0x73, 0x42, 0x61, - 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x49, 0x73, - 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, - 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, - 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1e, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x64, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x64, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x62, 0x0a, 0x19, 0x53, 0x75, 0x62, 0x73, 0x63, - 0x72, 0x69, 0x62, 0x65, 0x54, 0x6f, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x43, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x73, 0x12, 0x29, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, - 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x54, 0x6f, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x16, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x3b, 0x0a, 0x07, 0x52, - 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x17, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, - 0x2e, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x15, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, - 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x08, 0x53, 0x65, 0x74, 0x54, - 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, - 0x65, 0x74, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, - 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x54, 0x69, 0x74, 0x6c, - 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x0e, 0x53, 0x65, 0x74, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x73, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x73, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x4a, 0x0a, 0x0c, 0x41, 0x70, - 0x70, 0x6c, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x1c, 0x2e, 0x73, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x64, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, - 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x4a, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1c, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, - 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x70, 0x6c, 0x79, - 0x22, 0x00, 0x12, 0x47, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, - 0x65, 0x12, 0x1b, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x56, - 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, - 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, - 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0f, 0x47, - 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1f, - 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, - 0x61, 0x62, 0x6c, 0x65, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1d, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x61, 0x72, - 0x69, 0x61, 0x62, 0x6c, 0x65, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, - 0x12, 0x47, 0x0a, 0x0b, 0x53, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x12, - 0x1b, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x56, 0x61, 0x72, - 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x73, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, - 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x92, 0x01, 0x0a, 0x24, 0x45, 0x58, - 0x50, 0x45, 0x52, 0x49, 0x4d, 0x45, 0x4e, 0x54, 0x41, 0x4c, 0x5f, 0x52, 0x65, 0x69, 0x6e, 0x69, - 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, - 0x72, 0x73, 0x12, 0x34, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x45, 0x58, 0x50, - 0x45, 0x52, 0x49, 0x4d, 0x45, 0x4e, 0x54, 0x41, 0x4c, 0x5f, 0x52, 0x65, 0x69, 0x6e, 0x69, 0x74, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x64, 0x2e, 0x45, 0x58, 0x50, 0x45, 0x52, 0x49, 0x4d, 0x45, 0x4e, 0x54, 0x41, 0x4c, 0x5f, - 0x52, 0x65, 0x69, 0x6e, 0x69, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x62, - 0x0a, 0x14, 0x4f, 0x42, 0x53, 0x4f, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x46, 0x65, 0x74, 0x63, 0x68, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x24, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, - 0x2e, 0x4f, 0x42, 0x53, 0x4f, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x46, 0x65, 0x74, 0x63, 0x68, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x73, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4f, 0x42, 0x53, 0x4f, 0x4c, 0x45, 0x54, 0x45, 0x5f, - 0x46, 0x65, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, - 0x22, 0x00, 0x12, 0x5c, 0x0a, 0x10, 0x4f, 0x42, 0x53, 0x4f, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x47, - 0x69, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x23, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, - 0x2e, 0x4f, 0x42, 0x53, 0x4f, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x47, 0x65, 0x74, 0x47, 0x69, 0x74, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4f, 0x42, 0x53, 0x4f, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x47, - 0x65, 0x74, 0x47, 0x69, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, - 0x12, 0x5f, 0x0a, 0x13, 0x4f, 0x42, 0x53, 0x4f, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x47, 0x69, 0x74, - 0x52, 0x65, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x23, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x64, 0x2e, 0x4f, 0x42, 0x53, 0x4f, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x47, 0x69, 0x74, 0x52, 0x65, - 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4f, 0x42, 0x53, 0x4f, 0x4c, 0x45, 0x54, 0x45, 0x5f, - 0x47, 0x69, 0x74, 0x52, 0x65, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, - 0x00, 0x12, 0x5f, 0x0a, 0x18, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x54, 0x6f, - 0x4f, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x28, 0x2e, - 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, - 0x65, 0x54, 0x6f, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x64, 0x2e, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x00, - 0x30, 0x01, 0x12, 0x53, 0x0a, 0x0f, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4f, 0x41, 0x75, 0x74, - 0x68, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, - 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x43, 0x6f, 0x64, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, - 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x43, 0x6f, 0x64, 0x65, - 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x53, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x21, 0x2e, 0x73, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, - 0x22, 0x00, 0x12, 0x59, 0x0a, 0x11, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x21, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x64, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x73, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x56, 0x0a, - 0x10, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x12, 0x20, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x6f, 0x70, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, - 0x6f, 0x70, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, - 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x74, 0x0a, 0x1f, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, - 0x62, 0x65, 0x54, 0x6f, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x2f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x64, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x54, 0x6f, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x73, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x68, 0x0a, 0x16, 0x4c, - 0x69, 0x73, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, - 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, - 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x62, 0x0a, 0x14, 0x41, 0x64, 0x64, 0x53, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x2e, - 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x41, 0x64, - 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x6b, 0x0a, 0x17, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x65, 0x73, 0x74, 0x69, - 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, + 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xb2, 0x01, 0x0a, 0x18, 0x4f, 0x42, 0x53, + 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x68, 0x6f, + 0x77, 0x48, 0x69, 0x64, 0x65, 0x12, 0x25, 0x0a, 0x0b, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x65, 0x6c, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x25, 0x0a, 0x0b, + 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x55, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x48, 0x01, 0x52, 0x0b, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x55, 0x49, 0x44, + 0x88, 0x01, 0x01, 0x12, 0x28, 0x0a, 0x0f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x78, 0x70, 0x72, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x0e, 0x0a, + 0x0c, 0x5f, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x42, 0x0e, 0x0a, + 0x0c, 0x5f, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x55, 0x49, 0x44, 0x22, 0xb9, 0x01, + 0x0a, 0x1f, 0x4f, 0x42, 0x53, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, + 0x77, 0x43, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x12, 0x25, 0x0a, 0x0b, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x25, 0x0a, 0x0b, 0x65, 0x6c, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x55, 0x55, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, + 0x0b, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x55, 0x49, 0x44, 0x88, 0x01, 0x01, 0x12, + 0x28, 0x0a, 0x0f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x45, + 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x65, 0x6c, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x65, 0x6c, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x55, 0x49, 0x44, 0x22, 0xd0, 0x01, 0x0a, 0x09, 0x4f, 0x42, + 0x53, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4d, 0x0a, 0x0f, 0x65, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x53, 0x68, 0x6f, 0x77, 0x48, 0x69, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x21, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4f, 0x42, 0x53, 0x41, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x68, 0x6f, 0x77, 0x48, + 0x69, 0x64, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x68, + 0x6f, 0x77, 0x48, 0x69, 0x64, 0x65, 0x12, 0x62, 0x0a, 0x16, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, + 0x43, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, + 0x2e, 0x4f, 0x42, 0x53, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, + 0x43, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x48, 0x00, 0x52, 0x16, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x43, 0x61, 0x70, 0x74, 0x75, 0x72, + 0x65, 0x53, 0x65, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x10, 0x0a, 0x0e, 0x4f, 0x42, + 0x53, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x6e, 0x65, 0x4f, 0x66, 0x22, 0x9d, 0x02, 0x0a, + 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x0b, 0x6e, 0x6f, 0x6f, 0x70, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4e, 0x6f, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x6e, 0x6f, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x4d, 0x0a, 0x12, 0x73, 0x74, 0x61, 0x72, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x12, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x47, 0x0a, 0x10, 0x65, 0x6e, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x45, 0x6e, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x10, 0x65, 0x6e, 0x64, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x09, 0x6f, 0x62, 0x73, + 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4f, 0x42, 0x53, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x48, 0x00, 0x52, 0x09, 0x6f, 0x62, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x0d, 0x0a, + 0x0b, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x68, 0x0a, 0x0f, + 0x41, 0x64, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x2c, 0x0a, 0x11, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x41, 0x74, 0x55, 0x6e, 0x69, 0x78, + 0x4e, 0x61, 0x6e, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x74, 0x72, 0x69, 0x67, + 0x67, 0x65, 0x72, 0x41, 0x74, 0x55, 0x6e, 0x69, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x12, 0x27, 0x0a, + 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0x0a, 0x0d, 0x41, 0x64, 0x64, 0x54, 0x69, 0x6d, + 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x72, + 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x49, + 0x44, 0x22, 0x2e, 0x0a, 0x12, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x72, + 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x49, + 0x44, 0x22, 0x12, 0x0a, 0x10, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, + 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x78, 0x0a, 0x05, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x18, + 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x07, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x49, 0x44, 0x12, 0x2c, 0x0a, 0x11, 0x74, 0x72, 0x69, 0x67, + 0x67, 0x65, 0x72, 0x41, 0x74, 0x55, 0x6e, 0x69, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x11, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x41, 0x74, 0x55, 0x6e, + 0x69, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x12, 0x27, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, + 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x13, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x22, 0x39, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, + 0x72, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x26, 0x0a, 0x06, 0x74, 0x69, 0x6d, 0x65, 0x72, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x64, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x52, 0x06, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x73, 0x22, + 0x39, 0x0a, 0x0d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x6e, 0x64, + 0x12, 0x28, 0x0a, 0x07, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x52, 0x07, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x22, 0x38, 0x0a, 0x0c, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x72, 0x12, 0x28, 0x0a, 0x07, 0x71, 0x75, + 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x07, 0x71, 0x75, 0x65, + 0x72, 0x69, 0x65, 0x73, 0x22, 0x35, 0x0a, 0x0d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x4e, 0x6f, 0x74, 0x12, 0x24, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x33, 0x0a, 0x13, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x4f, 0x42, 0x53, 0x53, 0x63, 0x65, 0x6e, 0x65, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x63, 0x65, 0x6e, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x63, 0x65, 0x6e, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x22, 0xf1, 0x01, 0x0a, 0x16, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, + 0x46, 0x6f, 0x63, 0x75, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x1f, 0x0a, 0x08, 0x77, + 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, + 0x08, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x49, 0x44, 0x88, 0x01, 0x01, 0x12, 0x25, 0x0a, 0x0b, + 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x48, 0x01, 0x52, 0x0b, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x54, 0x69, 0x74, 0x6c, 0x65, + 0x88, 0x01, 0x01, 0x12, 0x33, 0x0a, 0x12, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x54, 0x69, 0x74, + 0x6c, 0x65, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, + 0x02, 0x52, 0x12, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x50, 0x61, + 0x72, 0x74, 0x69, 0x61, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, + 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x48, 0x03, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, + 0x49, 0x44, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, + 0x49, 0x44, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x54, 0x69, 0x74, + 0x6c, 0x65, 0x42, 0x15, 0x0a, 0x13, 0x5f, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x54, 0x69, 0x74, + 0x6c, 0x65, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x75, 0x73, + 0x65, 0x72, 0x49, 0x44, 0x22, 0xfc, 0x01, 0x0a, 0x0a, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x12, 0x2a, 0x0a, 0x03, 0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x16, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x6e, 0x64, 0x48, 0x00, 0x52, 0x03, 0x61, 0x6e, 0x64, 0x12, + 0x27, 0x0a, 0x02, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x4f, 0x72, 0x48, 0x00, 0x52, 0x02, 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x03, 0x6e, 0x6f, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4e, 0x6f, 0x74, 0x48, 0x00, 0x52, + 0x03, 0x6e, 0x6f, 0x74, 0x12, 0x32, 0x0a, 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x64, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x09, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x64, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x42, 0x11, 0x0a, 0x0f, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x6e, + 0x65, 0x4f, 0x66, 0x22, 0xae, 0x01, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x46, 0x0a, + 0x0e, 0x6f, 0x62, 0x73, 0x53, 0x63, 0x65, 0x6e, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4f, 0x42, 0x53, 0x53, 0x63, 0x65, 0x6e, 0x65, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x6f, 0x62, 0x73, 0x53, 0x63, 0x65, 0x6e, 0x65, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x4f, 0x0a, 0x11, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x46, + 0x6f, 0x63, 0x75, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x46, 0x6f, 0x63, 0x75, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x48, 0x00, 0x52, 0x11, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x46, 0x6f, 0x63, 0x75, 0x73, + 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x0c, 0x0a, 0x0a, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4f, + 0x6e, 0x65, 0x4f, 0x66, 0x22, 0x8d, 0x01, 0x0a, 0x0b, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, + 0x52, 0x75, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, + 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x27, 0x0a, 0x06, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x19, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x69, 0x67, + 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, + 0x43, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x75, + 0x6c, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x64, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, + 0x75, 0x6c, 0x65, 0x73, 0x22, 0x41, 0x0a, 0x15, 0x41, 0x64, 0x64, 0x54, 0x72, 0x69, 0x67, 0x67, + 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, + 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, + 0x65, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x22, 0x2d, 0x0a, 0x13, 0x41, 0x64, 0x64, 0x54, 0x72, + 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x16, + 0x0a, 0x06, 0x72, 0x75, 0x6c, 0x65, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, + 0x72, 0x75, 0x6c, 0x65, 0x49, 0x44, 0x22, 0x32, 0x0a, 0x18, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x75, 0x6c, 0x65, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x06, 0x72, 0x75, 0x6c, 0x65, 0x49, 0x44, 0x22, 0x18, 0x0a, 0x16, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x52, + 0x65, 0x70, 0x6c, 0x79, 0x22, 0x5c, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x72, + 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x16, 0x0a, 0x06, 0x72, 0x75, 0x6c, 0x65, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x06, 0x72, 0x75, 0x6c, 0x65, 0x49, 0x44, 0x12, 0x28, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, + 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x75, + 0x6c, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, 0x67, + 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x3a, 0x0a, 0x12, + 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x24, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x12, 0x0a, 0x10, 0x53, 0x75, 0x62, 0x6d, + 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x2a, 0x66, 0x0a, 0x0c, + 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x08, 0x0a, 0x04, + 0x6e, 0x6f, 0x6e, 0x65, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x66, 0x61, 0x74, 0x61, 0x6c, 0x10, + 0x01, 0x12, 0x09, 0x0a, 0x05, 0x70, 0x61, 0x6e, 0x69, 0x63, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, + 0x6e, 0x67, 0x10, 0x04, 0x12, 0x08, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x10, 0x05, 0x12, 0x09, + 0x0a, 0x05, 0x64, 0x65, 0x62, 0x75, 0x67, 0x10, 0x06, 0x12, 0x09, 0x0a, 0x05, 0x74, 0x72, 0x61, + 0x63, 0x65, 0x10, 0x07, 0x2a, 0x19, 0x0a, 0x08, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x0d, 0x0a, 0x09, 0x48, 0x41, 0x53, 0x48, 0x5f, 0x53, 0x48, 0x41, 0x31, 0x10, 0x00, 0x2a, + 0x35, 0x0a, 0x10, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, + 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x52, 0x54, 0x53, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, + 0x52, 0x54, 0x4d, 0x50, 0x10, 0x02, 0x2a, 0x49, 0x0a, 0x0a, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x54, 0x79, + 0x70, 0x65, 0x41, 0x75, 0x74, 0x6f, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x6c, 0x61, 0x79, + 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x4c, 0x69, 0x62, 0x56, 0x4c, 0x43, 0x10, 0x01, 0x12, 0x11, + 0x0a, 0x0d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x4d, 0x50, 0x56, 0x10, + 0x02, 0x2a, 0x40, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, + 0x0a, 0x16, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x46, 0x6f, 0x63, + 0x75, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x4f, 0x42, 0x53, 0x53, 0x63, 0x65, 0x6e, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x10, 0x01, 0x32, 0xd2, 0x33, 0x0a, 0x07, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x12, + 0x32, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x64, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, + 0x79, 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0f, 0x53, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, + 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x1f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, + 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x64, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x76, 0x65, + 0x6c, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4c, + 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x1f, 0x2e, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, + 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, + 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x41, 0x0a, + 0x09, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x19, 0x2e, 0x73, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, + 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, + 0x12, 0x41, 0x0a, 0x09, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x19, 0x2e, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x70, 0x6c, + 0x79, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x0a, 0x53, 0x61, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x1a, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x61, 0x76, 0x65, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x61, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x18, 0x53, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x28, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, + 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x15, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x44, 0x0a, 0x0a, 0x52, 0x65, + 0x73, 0x65, 0x74, 0x43, 0x61, 0x63, 0x68, 0x65, 0x12, 0x1a, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x64, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x52, + 0x65, 0x73, 0x65, 0x74, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, + 0x12, 0x41, 0x0a, 0x09, 0x49, 0x6e, 0x69, 0x74, 0x43, 0x61, 0x63, 0x68, 0x65, 0x12, 0x19, 0x2e, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x43, 0x61, 0x63, 0x68, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x64, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x43, 0x61, 0x63, 0x68, 0x65, 0x52, 0x65, 0x70, 0x6c, + 0x79, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x12, 0x1b, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x19, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x09, + 0x45, 0x6e, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x19, 0x2e, 0x73, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x64, 0x2e, 0x45, 0x6e, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x45, + 0x6e, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, + 0x53, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x1f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x47, 0x65, 0x74, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x47, 0x65, + 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x10, 0x49, 0x73, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, + 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x20, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x64, 0x2e, 0x49, 0x73, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x45, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x49, 0x73, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x45, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x0e, + 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1e, + 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, + 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, + 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, + 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x62, + 0x0a, 0x19, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x54, 0x6f, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x29, 0x2e, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x54, + 0x6f, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, + 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x22, 0x00, + 0x30, 0x01, 0x12, 0x3b, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x17, 0x2e, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, + 0x2e, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, + 0x3e, 0x0a, 0x08, 0x53, 0x65, 0x74, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x2e, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, + 0x53, 0x65, 0x74, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, + 0x50, 0x0a, 0x0e, 0x53, 0x65, 0x74, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x1e, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x44, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1c, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x44, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, + 0x00, 0x12, 0x4a, 0x0a, 0x0c, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x12, 0x1c, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x41, 0x70, 0x70, 0x6c, + 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1a, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x50, + 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x4a, 0x0a, + 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1c, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x6b, 0x0a, 0x17, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x27, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x73, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, - 0x79, 0x22, 0x00, 0x12, 0x83, 0x01, 0x0a, 0x24, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, - 0x65, 0x54, 0x6f, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x34, 0x2e, 0x73, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, - 0x54, 0x6f, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x59, 0x0a, 0x11, 0x41, 0x64, 0x64, - 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x21, - 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x49, 0x6e, 0x63, 0x6f, - 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x49, - 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x70, - 0x6c, 0x79, 0x22, 0x00, 0x12, 0x62, 0x0a, 0x14, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, 0x6e, - 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x24, 0x2e, 0x73, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, 0x6e, 0x63, - 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x52, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, - 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, - 0x23, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, - 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x7a, 0x0a, 0x21, 0x53, 0x75, 0x62, - 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x54, 0x6f, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x31, - 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, - 0x62, 0x65, 0x54, 0x6f, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x49, 0x6e, 0x63, 0x6f, - 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x5c, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x73, 0x12, 0x22, 0x2e, 0x73, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x20, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x73, 0x52, 0x65, 0x70, 0x6c, - 0x79, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x10, 0x41, 0x64, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x20, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x64, 0x2e, 0x41, 0x64, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x46, 0x6f, 0x72, 0x77, 0x61, - 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x46, 0x6f, 0x72, - 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x13, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x46, 0x6f, 0x72, 0x77, 0x61, - 0x72, 0x64, 0x12, 0x23, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x64, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x46, 0x6f, - 0x72, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x13, - 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x46, 0x6f, 0x72, 0x77, - 0x61, 0x72, 0x64, 0x12, 0x23, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x52, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, - 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x46, - 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x77, 0x0a, - 0x20, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x54, 0x6f, 0x53, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, - 0x73, 0x12, 0x30, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x75, 0x62, 0x73, - 0x63, 0x72, 0x69, 0x62, 0x65, 0x54, 0x6f, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x46, 0x6f, 0x72, - 0x77, 0x61, 0x72, 0x64, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x73, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x5e, 0x0a, 0x16, 0x57, 0x61, 0x69, 0x74, 0x46, 0x6f, - 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, - 0x12, 0x26, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x57, 0x61, 0x69, 0x74, 0x46, - 0x6f, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, - 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, - 0x65, 0x72, 0x22, 0x00, 0x30, 0x01, 0x12, 0x53, 0x0a, 0x0f, 0x41, 0x64, 0x64, 0x53, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x73, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, - 0x79, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x73, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, - 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x5c, 0x0a, 0x12, 0x52, - 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, - 0x72, 0x12, 0x22, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, - 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, - 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x5c, 0x0a, 0x12, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, - 0x22, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, - 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x53, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x12, 0x21, 0x2e, 0x73, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, - 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, - 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, - 0x47, 0x65, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, - 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, - 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x74, 0x0a, 0x1f, 0x53, 0x75, 0x62, 0x73, 0x63, - 0x72, 0x69, 0x62, 0x65, 0x54, 0x6f, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, - 0x65, 0x72, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x2f, 0x2e, 0x73, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x54, 0x6f, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x43, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x73, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, - 0x65, 0x72, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x56, 0x0a, - 0x10, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4f, 0x70, 0x65, - 0x6e, 0x12, 0x20, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4f, 0x70, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4f, 0x70, 0x65, 0x6e, 0x52, 0x65, - 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x6e, 0x0a, 0x18, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, - 0x6c, 0x61, 0x79, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x69, 0x74, 0x6c, - 0x65, 0x12, 0x28, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, - 0x69, 0x74, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x73, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, - 0x65, 0x72, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x52, 0x65, - 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x13, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, - 0x6c, 0x61, 0x79, 0x65, 0x72, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x23, 0x2e, 0x73, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, - 0x79, 0x65, 0x72, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, - 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x61, 0x0a, 0x13, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x45, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x12, 0x23, 0x2e, - 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, - 0x61, 0x79, 0x65, 0x72, 0x45, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x45, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, - 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x30, 0x01, 0x12, 0x5f, 0x0a, 0x13, 0x53, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x73, 0x45, 0x6e, 0x64, 0x65, 0x64, - 0x12, 0x23, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x73, 0x45, 0x6e, 0x64, 0x65, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x73, 0x45, 0x6e, - 0x64, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x6b, 0x0a, 0x17, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x47, 0x65, 0x74, 0x50, - 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, - 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, - 0x6c, 0x61, 0x79, 0x65, 0x72, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x65, 0x0a, 0x15, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x47, 0x65, 0x74, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, - 0x12, 0x25, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x47, 0x65, 0x74, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x47, 0x65, - 0x74, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x62, - 0x0a, 0x14, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x65, - 0x74, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x24, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, - 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x65, 0x74, - 0x53, 0x70, 0x65, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x73, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, - 0x79, 0x65, 0x72, 0x53, 0x65, 0x74, 0x53, 0x70, 0x65, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, - 0x22, 0x00, 0x12, 0x62, 0x0a, 0x14, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, - 0x65, 0x72, 0x53, 0x65, 0x74, 0x50, 0x61, 0x75, 0x73, 0x65, 0x12, 0x24, 0x2e, 0x73, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, - 0x72, 0x53, 0x65, 0x74, 0x50, 0x61, 0x75, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x22, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x65, 0x74, 0x50, 0x61, 0x75, 0x73, 0x65, 0x52, - 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x10, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x20, 0x2e, 0x73, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, - 0x72, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, - 0x79, 0x65, 0x72, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x59, - 0x0a, 0x11, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x43, 0x6c, - 0x6f, 0x73, 0x65, 0x12, 0x21, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, - 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x43, 0x6c, 0x6f, - 0x73, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x08, 0x41, 0x64, 0x64, - 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x18, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, - 0x41, 0x64, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x16, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x54, 0x69, 0x6d, - 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x0b, 0x52, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x52, 0x65, + 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x0b, 0x47, 0x65, 0x74, + 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1b, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, - 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, - 0x22, 0x00, 0x12, 0x44, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x73, - 0x12, 0x1a, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, - 0x69, 0x6d, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x73, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x72, - 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x11, 0x5a, 0x0f, 0x67, 0x6f, 0x2f, 0x73, + 0x47, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, + 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, + 0x65, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, + 0x47, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x48, 0x61, 0x73, 0x68, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, + 0x2e, 0x47, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x48, 0x61, 0x73, 0x68, + 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x0b, 0x53, 0x65, 0x74, 0x56, 0x61, + 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1b, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, + 0x2e, 0x53, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x65, + 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, + 0x12, 0x92, 0x01, 0x0a, 0x24, 0x45, 0x58, 0x50, 0x45, 0x52, 0x49, 0x4d, 0x45, 0x4e, 0x54, 0x41, + 0x4c, 0x5f, 0x52, 0x65, 0x69, 0x6e, 0x69, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x12, 0x34, 0x2e, 0x73, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x64, 0x2e, 0x45, 0x58, 0x50, 0x45, 0x52, 0x49, 0x4d, 0x45, 0x4e, 0x54, 0x41, 0x4c, + 0x5f, 0x52, 0x65, 0x69, 0x6e, 0x69, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x32, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x45, 0x58, 0x50, 0x45, 0x52, 0x49, + 0x4d, 0x45, 0x4e, 0x54, 0x41, 0x4c, 0x5f, 0x52, 0x65, 0x69, 0x6e, 0x69, 0x74, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, + 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x62, 0x0a, 0x14, 0x4f, 0x42, 0x53, 0x4f, 0x4c, 0x45, 0x54, + 0x45, 0x5f, 0x46, 0x65, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x24, 0x2e, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4f, 0x42, 0x53, 0x4f, 0x4c, 0x45, 0x54, 0x45, + 0x5f, 0x46, 0x65, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4f, 0x42, + 0x53, 0x4f, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x46, 0x65, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x5c, 0x0a, 0x10, 0x4f, 0x42, 0x53, + 0x4f, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x47, 0x69, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x23, 0x2e, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4f, 0x42, 0x53, 0x4f, 0x4c, 0x45, 0x54, 0x45, + 0x5f, 0x47, 0x65, 0x74, 0x47, 0x69, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4f, 0x42, 0x53, + 0x4f, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x47, 0x65, 0x74, 0x47, 0x69, 0x74, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x13, 0x4f, 0x42, 0x53, 0x4f, 0x4c, + 0x45, 0x54, 0x45, 0x5f, 0x47, 0x69, 0x74, 0x52, 0x65, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x23, + 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4f, 0x42, 0x53, 0x4f, 0x4c, 0x45, 0x54, + 0x45, 0x5f, 0x47, 0x69, 0x74, 0x52, 0x65, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4f, 0x42, + 0x53, 0x4f, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x47, 0x69, 0x74, 0x52, 0x65, 0x6c, 0x6f, 0x67, 0x69, + 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x18, 0x53, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x62, 0x65, 0x54, 0x6f, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x73, 0x12, 0x28, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, + 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x54, 0x6f, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, + 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x00, 0x30, 0x01, 0x12, 0x53, 0x0a, 0x0f, 0x53, 0x75, 0x62, + 0x6d, 0x69, 0x74, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1f, 0x2e, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4f, 0x41, 0x75, + 0x74, 0x68, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4f, 0x41, + 0x75, 0x74, 0x68, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x59, + 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x73, 0x12, 0x21, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x11, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x21, + 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x10, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x20, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x74, 0x0a, 0x1f, + 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x54, 0x6f, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, + 0x2f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x62, 0x65, 0x54, 0x6f, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1c, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x22, 0x00, + 0x30, 0x01, 0x12, 0x68, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x2e, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x62, 0x0a, 0x14, + 0x41, 0x64, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x41, + 0x64, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x73, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x65, + 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, + 0x12, 0x6b, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x2e, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x65, 0x73, 0x74, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x6b, 0x0a, + 0x17, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x65, 0x73, + 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, + 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x25, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x83, 0x01, 0x0a, 0x24, 0x53, + 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x54, 0x6f, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x73, 0x12, 0x34, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x75, + 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x54, 0x6f, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, + 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, + 0x12, 0x59, 0x0a, 0x11, 0x41, 0x64, 0x64, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x21, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, + 0x41, 0x64, 0x64, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x62, 0x0a, 0x14, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x12, 0x24, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x73, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x69, + 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, + 0x5f, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x23, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x69, + 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, + 0x12, 0x7a, 0x0a, 0x21, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x54, 0x6f, 0x49, + 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x31, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, + 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x54, 0x6f, 0x49, 0x6e, 0x63, 0x6f, 0x6d, + 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x64, 0x2e, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x5c, 0x0a, 0x12, + 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, + 0x64, 0x73, 0x12, 0x22, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x46, 0x6f, 0x72, 0x77, 0x61, + 0x72, 0x64, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x10, 0x41, 0x64, + 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x20, + 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1e, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, + 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x23, 0x2e, 0x73, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x64, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, + 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, + 0x79, 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x13, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x23, 0x2e, 0x73, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x21, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x22, 0x00, 0x12, 0x77, 0x0a, 0x20, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, + 0x65, 0x54, 0x6f, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, + 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x30, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x64, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x54, 0x6f, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x73, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x73, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x46, 0x6f, 0x72, 0x77, 0x61, + 0x72, 0x64, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x5e, 0x0a, + 0x16, 0x57, 0x61, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x75, + 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x12, 0x26, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x64, 0x2e, 0x57, 0x61, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x18, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x22, 0x00, 0x30, 0x01, 0x12, 0x53, 0x0a, + 0x0f, 0x41, 0x64, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, + 0x12, 0x1f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1d, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, + 0x22, 0x00, 0x12, 0x5c, 0x0a, 0x12, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x22, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, + 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, + 0x12, 0x5c, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x22, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, + 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, + 0x79, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x73, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x59, + 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, + 0x65, 0x72, 0x73, 0x12, 0x21, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, + 0x72, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0f, 0x47, 0x65, 0x74, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x74, + 0x0a, 0x1f, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x54, 0x6f, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x73, 0x12, 0x2f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x62, 0x65, 0x54, 0x6f, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, + 0x79, 0x65, 0x72, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x22, 0x00, 0x30, 0x01, 0x12, 0x56, 0x0a, 0x10, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, + 0x61, 0x79, 0x65, 0x72, 0x4f, 0x70, 0x65, 0x6e, 0x12, 0x20, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4f, + 0x70, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, + 0x72, 0x4f, 0x70, 0x65, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x6e, 0x0a, 0x18, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x28, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x50, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x54, 0x69, 0x74, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x13, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x47, 0x65, 0x74, 0x4c, + 0x69, 0x6e, 0x6b, 0x12, 0x23, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, + 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x47, + 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x61, 0x0a, + 0x13, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x45, 0x6e, 0x64, + 0x43, 0x68, 0x61, 0x6e, 0x12, 0x23, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x45, 0x6e, 0x64, 0x43, 0x68, + 0x61, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, + 0x45, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x30, 0x01, + 0x12, 0x5f, 0x0a, 0x13, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, + 0x49, 0x73, 0x45, 0x6e, 0x64, 0x65, 0x64, 0x12, 0x23, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x73, + 0x45, 0x6e, 0x64, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, + 0x79, 0x65, 0x72, 0x49, 0x73, 0x45, 0x6e, 0x64, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, + 0x00, 0x12, 0x6b, 0x0a, 0x17, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, + 0x72, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x2e, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, + 0x79, 0x65, 0x72, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x47, 0x65, 0x74, 0x50, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x65, + 0x0a, 0x15, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x47, 0x65, + 0x74, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x25, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x47, 0x65, + 0x74, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, + 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, + 0x6c, 0x61, 0x79, 0x65, 0x72, 0x47, 0x65, 0x74, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x52, 0x65, + 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x62, 0x0a, 0x14, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, + 0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x65, 0x74, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x24, 0x2e, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, + 0x61, 0x79, 0x65, 0x72, 0x53, 0x65, 0x74, 0x53, 0x70, 0x65, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x65, 0x74, 0x53, 0x70, 0x65, + 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x62, 0x0a, 0x14, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x65, 0x74, 0x50, 0x61, 0x75, 0x73, + 0x65, 0x12, 0x24, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x65, 0x74, 0x50, 0x61, 0x75, 0x73, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x65, + 0x74, 0x50, 0x61, 0x75, 0x73, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x56, 0x0a, + 0x10, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x74, 0x6f, + 0x70, 0x12, 0x20, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, + 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x11, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, + 0x6c, 0x61, 0x79, 0x65, 0x72, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x12, 0x21, 0x2e, 0x73, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, 0x61, 0x79, 0x65, + 0x72, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6c, + 0x61, 0x79, 0x65, 0x72, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, + 0x12, 0x3e, 0x0a, 0x08, 0x41, 0x64, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x18, 0x2e, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, + 0x2e, 0x41, 0x64, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, + 0x12, 0x47, 0x0a, 0x0b, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, + 0x1b, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x54, 0x69, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x69, 0x6d, + 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x0a, 0x4c, 0x69, 0x73, + 0x74, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x73, 0x12, 0x1a, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x64, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, + 0x56, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x75, + 0x6c, 0x65, 0x73, 0x12, 0x20, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, + 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x54, 0x72, + 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x1e, 0x2e, 0x73, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x75, + 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x73, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x75, + 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x11, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x21, + 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, + 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x72, + 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x21, 0x2e, 0x73, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x64, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, + 0x72, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, + 0x67, 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, + 0x47, 0x0a, 0x0b, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, + 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x64, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x11, 0x5a, 0x0f, 0x67, 0x6f, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x64, 0x5f, 0x67, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } @@ -8561,189 +9962,211 @@ func file_streamd_proto_rawDescGZIP() []byte { return file_streamd_proto_rawDescData } -var file_streamd_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_streamd_proto_msgTypes = make([]protoimpl.MessageInfo, 154) +var file_streamd_proto_enumTypes = make([]protoimpl.EnumInfo, 5) +var file_streamd_proto_msgTypes = make([]protoimpl.MessageInfo, 175) var file_streamd_proto_goTypes = []interface{}{ (LoggingLevel)(0), // 0: streamd.LoggingLevel (HashType)(0), // 1: streamd.HashType (StreamServerType)(0), // 2: streamd.StreamServerType (PlayerType)(0), // 3: streamd.PlayerType - (*PingRequest)(nil), // 4: streamd.PingRequest - (*PingReply)(nil), // 5: streamd.PingReply - (*SetLoggingLevelRequest)(nil), // 6: streamd.SetLoggingLevelRequest - (*SetLoggingLevelReply)(nil), // 7: streamd.SetLoggingLevelReply - (*GetLoggingLevelRequest)(nil), // 8: streamd.GetLoggingLevelRequest - (*GetLoggingLevelReply)(nil), // 9: streamd.GetLoggingLevelReply - (*GetConfigRequest)(nil), // 10: streamd.GetConfigRequest - (*GetConfigReply)(nil), // 11: streamd.GetConfigReply - (*SetConfigRequest)(nil), // 12: streamd.SetConfigRequest - (*SetConfigReply)(nil), // 13: streamd.SetConfigReply - (*SaveConfigRequest)(nil), // 14: streamd.SaveConfigRequest - (*SaveConfigReply)(nil), // 15: streamd.SaveConfigReply - (*ResetCacheRequest)(nil), // 16: streamd.ResetCacheRequest - (*ResetCacheReply)(nil), // 17: streamd.ResetCacheReply - (*InitCacheRequest)(nil), // 18: streamd.InitCacheRequest - (*InitCacheReply)(nil), // 19: streamd.InitCacheReply - (*StartStreamRequest)(nil), // 20: streamd.StartStreamRequest - (*StartStreamReply)(nil), // 21: streamd.StartStreamReply - (*EndStreamRequest)(nil), // 22: streamd.EndStreamRequest - (*EndStreamReply)(nil), // 23: streamd.EndStreamReply - (*GetStreamStatusRequest)(nil), // 24: streamd.GetStreamStatusRequest - (*GetStreamStatusReply)(nil), // 25: streamd.GetStreamStatusReply - (*GetBackendInfoRequest)(nil), // 26: streamd.GetBackendInfoRequest - (*GetBackendInfoReply)(nil), // 27: streamd.GetBackendInfoReply - (*IsBackendEnabledRequest)(nil), // 28: streamd.IsBackendEnabledRequest - (*IsBackendEnabledReply)(nil), // 29: streamd.IsBackendEnabledReply - (*RestartRequest)(nil), // 30: streamd.RestartRequest - (*RestartReply)(nil), // 31: streamd.RestartReply - (*SetTitleRequest)(nil), // 32: streamd.SetTitleRequest - (*SetTitleReply)(nil), // 33: streamd.SetTitleReply - (*SetDescriptionRequest)(nil), // 34: streamd.SetDescriptionRequest - (*SetDescriptionReply)(nil), // 35: streamd.SetDescriptionReply - (*ApplyProfileRequest)(nil), // 36: streamd.ApplyProfileRequest - (*ApplyProfileReply)(nil), // 37: streamd.ApplyProfileReply - (*UpdateStreamRequest)(nil), // 38: streamd.UpdateStreamRequest - (*UpdateStreamReply)(nil), // 39: streamd.UpdateStreamReply - (*EXPERIMENTAL_ReinitStreamControllersRequest)(nil), // 40: streamd.EXPERIMENTAL_ReinitStreamControllersRequest - (*EXPERIMENTAL_ReinitStreamControllersReply)(nil), // 41: streamd.EXPERIMENTAL_ReinitStreamControllersReply - (*OBSOLETE_FetchConfigRequest)(nil), // 42: streamd.OBSOLETE_FetchConfigRequest - (*OBSOLETE_FetchConfigReply)(nil), // 43: streamd.OBSOLETE_FetchConfigReply - (*OBSOLETE_GetGitInfoRequest)(nil), // 44: streamd.OBSOLETE_GetGitInfoRequest - (*OBSOLETE_GetGitInfoReply)(nil), // 45: streamd.OBSOLETE_GetGitInfoReply - (*OBSOLETE_GitReloginRequest)(nil), // 46: streamd.OBSOLETE_GitReloginRequest - (*OBSOLETE_GitReloginReply)(nil), // 47: streamd.OBSOLETE_GitReloginReply - (*SubscribeToOAuthRequestsRequest)(nil), // 48: streamd.SubscribeToOAuthRequestsRequest - (*OAuthRequest)(nil), // 49: streamd.OAuthRequest - (*GetVariableRequest)(nil), // 50: streamd.GetVariableRequest - (*GetVariableReply)(nil), // 51: streamd.GetVariableReply - (*GetVariableHashRequest)(nil), // 52: streamd.GetVariableHashRequest - (*GetVariableHashReply)(nil), // 53: streamd.GetVariableHashReply - (*SetVariableRequest)(nil), // 54: streamd.SetVariableRequest - (*SetVariableReply)(nil), // 55: streamd.SetVariableReply - (*SubmitOAuthCodeRequest)(nil), // 56: streamd.SubmitOAuthCodeRequest - (*SubmitOAuthCodeReply)(nil), // 57: streamd.SubmitOAuthCodeReply - (*TLSCertificate)(nil), // 58: streamd.TLSCertificate - (*PrivateKey)(nil), // 59: streamd.PrivateKey - (*StreamServer)(nil), // 60: streamd.StreamServer - (*StreamServerStatistics)(nil), // 61: streamd.StreamServerStatistics - (*StreamServerWithStatistics)(nil), // 62: streamd.StreamServerWithStatistics - (*ListStreamServersRequest)(nil), // 63: streamd.ListStreamServersRequest - (*ListStreamServersReply)(nil), // 64: streamd.ListStreamServersReply - (*StartStreamServerRequest)(nil), // 65: streamd.StartStreamServerRequest - (*StartStreamServerReply)(nil), // 66: streamd.StartStreamServerReply - (*StopStreamServerRequest)(nil), // 67: streamd.StopStreamServerRequest - (*StopStreamServerReply)(nil), // 68: streamd.StopStreamServerReply - (*StreamDestination)(nil), // 69: streamd.StreamDestination - (*ListStreamDestinationsRequest)(nil), // 70: streamd.ListStreamDestinationsRequest - (*ListStreamDestinationsReply)(nil), // 71: streamd.ListStreamDestinationsReply - (*AddStreamDestinationRequest)(nil), // 72: streamd.AddStreamDestinationRequest - (*AddStreamDestinationReply)(nil), // 73: streamd.AddStreamDestinationReply - (*UpdateStreamDestinationRequest)(nil), // 74: streamd.UpdateStreamDestinationRequest - (*UpdateStreamDestinationReply)(nil), // 75: streamd.UpdateStreamDestinationReply - (*RemoveStreamDestinationRequest)(nil), // 76: streamd.RemoveStreamDestinationRequest - (*RemoveStreamDestinationReply)(nil), // 77: streamd.RemoveStreamDestinationReply - (*IncomingStream)(nil), // 78: streamd.IncomingStream - (*AddIncomingStreamRequest)(nil), // 79: streamd.AddIncomingStreamRequest - (*AddIncomingStreamReply)(nil), // 80: streamd.AddIncomingStreamReply - (*RemoveIncomingStreamRequest)(nil), // 81: streamd.RemoveIncomingStreamRequest - (*RemoveIncomingStreamReply)(nil), // 82: streamd.RemoveIncomingStreamReply - (*ListIncomingStreamsRequest)(nil), // 83: streamd.ListIncomingStreamsRequest - (*ListIncomingStreamsReply)(nil), // 84: streamd.ListIncomingStreamsReply - (*RestartUntilYoutubeRecognizesStream)(nil), // 85: streamd.RestartUntilYoutubeRecognizesStream - (*StartAfterYoutubeRecognizedStream)(nil), // 86: streamd.StartAfterYoutubeRecognizedStream - (*StreamForwardQuirks)(nil), // 87: streamd.StreamForwardQuirks - (*StreamForward)(nil), // 88: streamd.StreamForward - (*StreamForwardStatistics)(nil), // 89: streamd.StreamForwardStatistics - (*StreamForwardWithStatistics)(nil), // 90: streamd.StreamForwardWithStatistics - (*ListStreamForwardsRequest)(nil), // 91: streamd.ListStreamForwardsRequest - (*ListStreamForwardsReply)(nil), // 92: streamd.ListStreamForwardsReply - (*AddStreamForwardRequest)(nil), // 93: streamd.AddStreamForwardRequest - (*AddStreamForwardReply)(nil), // 94: streamd.AddStreamForwardReply - (*UpdateStreamForwardRequest)(nil), // 95: streamd.UpdateStreamForwardRequest - (*UpdateStreamForwardReply)(nil), // 96: streamd.UpdateStreamForwardReply - (*RemoveStreamForwardRequest)(nil), // 97: streamd.RemoveStreamForwardRequest - (*RemoveStreamForwardReply)(nil), // 98: streamd.RemoveStreamForwardReply - (*WaitForStreamPublisherRequest)(nil), // 99: streamd.WaitForStreamPublisherRequest - (*StreamPublisher)(nil), // 100: streamd.StreamPublisher - (*StreamPlaybackConfig)(nil), // 101: streamd.StreamPlaybackConfig - (*StreamPlayerConfig)(nil), // 102: streamd.StreamPlayerConfig - (*AddStreamPlayerRequest)(nil), // 103: streamd.AddStreamPlayerRequest - (*AddStreamPlayerReply)(nil), // 104: streamd.AddStreamPlayerReply - (*RemoveStreamPlayerRequest)(nil), // 105: streamd.RemoveStreamPlayerRequest - (*RemoveStreamPlayerReply)(nil), // 106: streamd.RemoveStreamPlayerReply - (*UpdateStreamPlayerRequest)(nil), // 107: streamd.UpdateStreamPlayerRequest - (*UpdateStreamPlayerReply)(nil), // 108: streamd.UpdateStreamPlayerReply - (*ListStreamPlayersRequest)(nil), // 109: streamd.ListStreamPlayersRequest - (*ListStreamPlayersReply)(nil), // 110: streamd.ListStreamPlayersReply - (*GetStreamPlayerRequest)(nil), // 111: streamd.GetStreamPlayerRequest - (*GetStreamPlayerReply)(nil), // 112: streamd.GetStreamPlayerReply - (*StreamPlayerOpenRequest)(nil), // 113: streamd.StreamPlayerOpenRequest - (*StreamPlayerOpenReply)(nil), // 114: streamd.StreamPlayerOpenReply - (*StreamPlayerProcessTitleRequest)(nil), // 115: streamd.StreamPlayerProcessTitleRequest - (*StreamPlayerProcessTitleReply)(nil), // 116: streamd.StreamPlayerProcessTitleReply - (*StreamPlayerGetLinkRequest)(nil), // 117: streamd.StreamPlayerGetLinkRequest - (*StreamPlayerGetLinkReply)(nil), // 118: streamd.StreamPlayerGetLinkReply - (*StreamPlayerEndChanRequest)(nil), // 119: streamd.StreamPlayerEndChanRequest - (*StreamPlayerEndChanReply)(nil), // 120: streamd.StreamPlayerEndChanReply - (*StreamPlayerIsEndedRequest)(nil), // 121: streamd.StreamPlayerIsEndedRequest - (*StreamPlayerIsEndedReply)(nil), // 122: streamd.StreamPlayerIsEndedReply - (*StreamPlayerGetPositionRequest)(nil), // 123: streamd.StreamPlayerGetPositionRequest - (*StreamPlayerGetPositionReply)(nil), // 124: streamd.StreamPlayerGetPositionReply - (*StreamPlayerGetLengthRequest)(nil), // 125: streamd.StreamPlayerGetLengthRequest - (*StreamPlayerGetLengthReply)(nil), // 126: streamd.StreamPlayerGetLengthReply - (*StreamPlayerSetSpeedRequest)(nil), // 127: streamd.StreamPlayerSetSpeedRequest - (*StreamPlayerSetSpeedReply)(nil), // 128: streamd.StreamPlayerSetSpeedReply - (*StreamPlayerSetPauseRequest)(nil), // 129: streamd.StreamPlayerSetPauseRequest - (*StreamPlayerSetPauseReply)(nil), // 130: streamd.StreamPlayerSetPauseReply - (*StreamPlayerStopRequest)(nil), // 131: streamd.StreamPlayerStopRequest - (*StreamPlayerStopReply)(nil), // 132: streamd.StreamPlayerStopReply - (*StreamPlayerCloseRequest)(nil), // 133: streamd.StreamPlayerCloseRequest - (*StreamPlayerCloseReply)(nil), // 134: streamd.StreamPlayerCloseReply - (*SubscribeToConfigChangesRequest)(nil), // 135: streamd.SubscribeToConfigChangesRequest - (*ConfigChange)(nil), // 136: streamd.ConfigChange - (*SubscribeToStreamsChangesRequest)(nil), // 137: streamd.SubscribeToStreamsChangesRequest - (*StreamsChange)(nil), // 138: streamd.StreamsChange - (*SubscribeToStreamServersChangesRequest)(nil), // 139: streamd.SubscribeToStreamServersChangesRequest - (*StreamServersChange)(nil), // 140: streamd.StreamServersChange - (*SubscribeToStreamDestinationsChangesRequest)(nil), // 141: streamd.SubscribeToStreamDestinationsChangesRequest - (*StreamDestinationsChange)(nil), // 142: streamd.StreamDestinationsChange - (*SubscribeToIncomingStreamsChangesRequest)(nil), // 143: streamd.SubscribeToIncomingStreamsChangesRequest - (*IncomingStreamsChange)(nil), // 144: streamd.IncomingStreamsChange - (*SubscribeToStreamForwardsChangesRequest)(nil), // 145: streamd.SubscribeToStreamForwardsChangesRequest - (*StreamForwardsChange)(nil), // 146: streamd.StreamForwardsChange - (*SubscribeToStreamPlayersChangesRequest)(nil), // 147: streamd.SubscribeToStreamPlayersChangesRequest - (*StreamPlayersChange)(nil), // 148: streamd.StreamPlayersChange - (*NoopRequest)(nil), // 149: streamd.NoopRequest - (*Action)(nil), // 150: streamd.Action - (*AddTimerRequest)(nil), // 151: streamd.AddTimerRequest - (*AddTimerReply)(nil), // 152: streamd.AddTimerReply - (*RemoveTimerRequest)(nil), // 153: streamd.RemoveTimerRequest - (*RemoveTimerReply)(nil), // 154: streamd.RemoveTimerReply - (*Timer)(nil), // 155: streamd.Timer - (*ListTimersRequest)(nil), // 156: streamd.ListTimersRequest - (*ListTimersReply)(nil), // 157: streamd.ListTimersReply - (*player_grpc.OpenRequest)(nil), // 158: player.OpenRequest - (*player_grpc.OpenReply)(nil), // 159: player.OpenReply - (*player_grpc.ProcessTitleRequest)(nil), // 160: player.ProcessTitleRequest - (*player_grpc.ProcessTitleReply)(nil), // 161: player.ProcessTitleReply - (*player_grpc.GetLinkRequest)(nil), // 162: player.GetLinkRequest - (*player_grpc.GetLinkReply)(nil), // 163: player.GetLinkReply - (*player_grpc.EndChanRequest)(nil), // 164: player.EndChanRequest - (*player_grpc.EndChanReply)(nil), // 165: player.EndChanReply - (*player_grpc.IsEndedRequest)(nil), // 166: player.IsEndedRequest - (*player_grpc.IsEndedReply)(nil), // 167: player.IsEndedReply - (*player_grpc.GetPositionRequest)(nil), // 168: player.GetPositionRequest - (*player_grpc.GetPositionReply)(nil), // 169: player.GetPositionReply - (*player_grpc.GetLengthRequest)(nil), // 170: player.GetLengthRequest - (*player_grpc.GetLengthReply)(nil), // 171: player.GetLengthReply - (*player_grpc.SetSpeedRequest)(nil), // 172: player.SetSpeedRequest - (*player_grpc.SetSpeedReply)(nil), // 173: player.SetSpeedReply - (*player_grpc.SetPauseRequest)(nil), // 174: player.SetPauseRequest - (*player_grpc.SetPauseReply)(nil), // 175: player.SetPauseReply - (*player_grpc.StopRequest)(nil), // 176: player.StopRequest - (*player_grpc.StopReply)(nil), // 177: player.StopReply - (*player_grpc.CloseRequest)(nil), // 178: player.CloseRequest - (*player_grpc.CloseReply)(nil), // 179: player.CloseReply + (EventType)(0), // 4: streamd.EventType + (*PingRequest)(nil), // 5: streamd.PingRequest + (*PingReply)(nil), // 6: streamd.PingReply + (*SetLoggingLevelRequest)(nil), // 7: streamd.SetLoggingLevelRequest + (*SetLoggingLevelReply)(nil), // 8: streamd.SetLoggingLevelReply + (*GetLoggingLevelRequest)(nil), // 9: streamd.GetLoggingLevelRequest + (*GetLoggingLevelReply)(nil), // 10: streamd.GetLoggingLevelReply + (*GetConfigRequest)(nil), // 11: streamd.GetConfigRequest + (*GetConfigReply)(nil), // 12: streamd.GetConfigReply + (*SetConfigRequest)(nil), // 13: streamd.SetConfigRequest + (*SetConfigReply)(nil), // 14: streamd.SetConfigReply + (*SaveConfigRequest)(nil), // 15: streamd.SaveConfigRequest + (*SaveConfigReply)(nil), // 16: streamd.SaveConfigReply + (*ResetCacheRequest)(nil), // 17: streamd.ResetCacheRequest + (*ResetCacheReply)(nil), // 18: streamd.ResetCacheReply + (*InitCacheRequest)(nil), // 19: streamd.InitCacheRequest + (*InitCacheReply)(nil), // 20: streamd.InitCacheReply + (*StartStreamRequest)(nil), // 21: streamd.StartStreamRequest + (*StartStreamReply)(nil), // 22: streamd.StartStreamReply + (*EndStreamRequest)(nil), // 23: streamd.EndStreamRequest + (*EndStreamReply)(nil), // 24: streamd.EndStreamReply + (*GetStreamStatusRequest)(nil), // 25: streamd.GetStreamStatusRequest + (*GetStreamStatusReply)(nil), // 26: streamd.GetStreamStatusReply + (*GetBackendInfoRequest)(nil), // 27: streamd.GetBackendInfoRequest + (*GetBackendInfoReply)(nil), // 28: streamd.GetBackendInfoReply + (*IsBackendEnabledRequest)(nil), // 29: streamd.IsBackendEnabledRequest + (*IsBackendEnabledReply)(nil), // 30: streamd.IsBackendEnabledReply + (*RestartRequest)(nil), // 31: streamd.RestartRequest + (*RestartReply)(nil), // 32: streamd.RestartReply + (*SetTitleRequest)(nil), // 33: streamd.SetTitleRequest + (*SetTitleReply)(nil), // 34: streamd.SetTitleReply + (*SetDescriptionRequest)(nil), // 35: streamd.SetDescriptionRequest + (*SetDescriptionReply)(nil), // 36: streamd.SetDescriptionReply + (*ApplyProfileRequest)(nil), // 37: streamd.ApplyProfileRequest + (*ApplyProfileReply)(nil), // 38: streamd.ApplyProfileReply + (*UpdateStreamRequest)(nil), // 39: streamd.UpdateStreamRequest + (*UpdateStreamReply)(nil), // 40: streamd.UpdateStreamReply + (*EXPERIMENTAL_ReinitStreamControllersRequest)(nil), // 41: streamd.EXPERIMENTAL_ReinitStreamControllersRequest + (*EXPERIMENTAL_ReinitStreamControllersReply)(nil), // 42: streamd.EXPERIMENTAL_ReinitStreamControllersReply + (*OBSOLETE_FetchConfigRequest)(nil), // 43: streamd.OBSOLETE_FetchConfigRequest + (*OBSOLETE_FetchConfigReply)(nil), // 44: streamd.OBSOLETE_FetchConfigReply + (*OBSOLETE_GetGitInfoRequest)(nil), // 45: streamd.OBSOLETE_GetGitInfoRequest + (*OBSOLETE_GetGitInfoReply)(nil), // 46: streamd.OBSOLETE_GetGitInfoReply + (*OBSOLETE_GitReloginRequest)(nil), // 47: streamd.OBSOLETE_GitReloginRequest + (*OBSOLETE_GitReloginReply)(nil), // 48: streamd.OBSOLETE_GitReloginReply + (*SubscribeToOAuthRequestsRequest)(nil), // 49: streamd.SubscribeToOAuthRequestsRequest + (*OAuthRequest)(nil), // 50: streamd.OAuthRequest + (*GetVariableRequest)(nil), // 51: streamd.GetVariableRequest + (*GetVariableReply)(nil), // 52: streamd.GetVariableReply + (*GetVariableHashRequest)(nil), // 53: streamd.GetVariableHashRequest + (*GetVariableHashReply)(nil), // 54: streamd.GetVariableHashReply + (*SetVariableRequest)(nil), // 55: streamd.SetVariableRequest + (*SetVariableReply)(nil), // 56: streamd.SetVariableReply + (*SubmitOAuthCodeRequest)(nil), // 57: streamd.SubmitOAuthCodeRequest + (*SubmitOAuthCodeReply)(nil), // 58: streamd.SubmitOAuthCodeReply + (*TLSCertificate)(nil), // 59: streamd.TLSCertificate + (*PrivateKey)(nil), // 60: streamd.PrivateKey + (*StreamServer)(nil), // 61: streamd.StreamServer + (*StreamServerStatistics)(nil), // 62: streamd.StreamServerStatistics + (*StreamServerWithStatistics)(nil), // 63: streamd.StreamServerWithStatistics + (*ListStreamServersRequest)(nil), // 64: streamd.ListStreamServersRequest + (*ListStreamServersReply)(nil), // 65: streamd.ListStreamServersReply + (*StartStreamServerRequest)(nil), // 66: streamd.StartStreamServerRequest + (*StartStreamServerReply)(nil), // 67: streamd.StartStreamServerReply + (*StopStreamServerRequest)(nil), // 68: streamd.StopStreamServerRequest + (*StopStreamServerReply)(nil), // 69: streamd.StopStreamServerReply + (*StreamDestination)(nil), // 70: streamd.StreamDestination + (*ListStreamDestinationsRequest)(nil), // 71: streamd.ListStreamDestinationsRequest + (*ListStreamDestinationsReply)(nil), // 72: streamd.ListStreamDestinationsReply + (*AddStreamDestinationRequest)(nil), // 73: streamd.AddStreamDestinationRequest + (*AddStreamDestinationReply)(nil), // 74: streamd.AddStreamDestinationReply + (*UpdateStreamDestinationRequest)(nil), // 75: streamd.UpdateStreamDestinationRequest + (*UpdateStreamDestinationReply)(nil), // 76: streamd.UpdateStreamDestinationReply + (*RemoveStreamDestinationRequest)(nil), // 77: streamd.RemoveStreamDestinationRequest + (*RemoveStreamDestinationReply)(nil), // 78: streamd.RemoveStreamDestinationReply + (*IncomingStream)(nil), // 79: streamd.IncomingStream + (*AddIncomingStreamRequest)(nil), // 80: streamd.AddIncomingStreamRequest + (*AddIncomingStreamReply)(nil), // 81: streamd.AddIncomingStreamReply + (*RemoveIncomingStreamRequest)(nil), // 82: streamd.RemoveIncomingStreamRequest + (*RemoveIncomingStreamReply)(nil), // 83: streamd.RemoveIncomingStreamReply + (*ListIncomingStreamsRequest)(nil), // 84: streamd.ListIncomingStreamsRequest + (*ListIncomingStreamsReply)(nil), // 85: streamd.ListIncomingStreamsReply + (*RestartUntilYoutubeRecognizesStream)(nil), // 86: streamd.RestartUntilYoutubeRecognizesStream + (*StartAfterYoutubeRecognizedStream)(nil), // 87: streamd.StartAfterYoutubeRecognizedStream + (*StreamForwardQuirks)(nil), // 88: streamd.StreamForwardQuirks + (*StreamForward)(nil), // 89: streamd.StreamForward + (*StreamForwardStatistics)(nil), // 90: streamd.StreamForwardStatistics + (*StreamForwardWithStatistics)(nil), // 91: streamd.StreamForwardWithStatistics + (*ListStreamForwardsRequest)(nil), // 92: streamd.ListStreamForwardsRequest + (*ListStreamForwardsReply)(nil), // 93: streamd.ListStreamForwardsReply + (*AddStreamForwardRequest)(nil), // 94: streamd.AddStreamForwardRequest + (*AddStreamForwardReply)(nil), // 95: streamd.AddStreamForwardReply + (*UpdateStreamForwardRequest)(nil), // 96: streamd.UpdateStreamForwardRequest + (*UpdateStreamForwardReply)(nil), // 97: streamd.UpdateStreamForwardReply + (*RemoveStreamForwardRequest)(nil), // 98: streamd.RemoveStreamForwardRequest + (*RemoveStreamForwardReply)(nil), // 99: streamd.RemoveStreamForwardReply + (*WaitForStreamPublisherRequest)(nil), // 100: streamd.WaitForStreamPublisherRequest + (*StreamPublisher)(nil), // 101: streamd.StreamPublisher + (*StreamPlaybackConfig)(nil), // 102: streamd.StreamPlaybackConfig + (*StreamPlayerConfig)(nil), // 103: streamd.StreamPlayerConfig + (*AddStreamPlayerRequest)(nil), // 104: streamd.AddStreamPlayerRequest + (*AddStreamPlayerReply)(nil), // 105: streamd.AddStreamPlayerReply + (*RemoveStreamPlayerRequest)(nil), // 106: streamd.RemoveStreamPlayerRequest + (*RemoveStreamPlayerReply)(nil), // 107: streamd.RemoveStreamPlayerReply + (*UpdateStreamPlayerRequest)(nil), // 108: streamd.UpdateStreamPlayerRequest + (*UpdateStreamPlayerReply)(nil), // 109: streamd.UpdateStreamPlayerReply + (*ListStreamPlayersRequest)(nil), // 110: streamd.ListStreamPlayersRequest + (*ListStreamPlayersReply)(nil), // 111: streamd.ListStreamPlayersReply + (*GetStreamPlayerRequest)(nil), // 112: streamd.GetStreamPlayerRequest + (*GetStreamPlayerReply)(nil), // 113: streamd.GetStreamPlayerReply + (*StreamPlayerOpenRequest)(nil), // 114: streamd.StreamPlayerOpenRequest + (*StreamPlayerOpenReply)(nil), // 115: streamd.StreamPlayerOpenReply + (*StreamPlayerProcessTitleRequest)(nil), // 116: streamd.StreamPlayerProcessTitleRequest + (*StreamPlayerProcessTitleReply)(nil), // 117: streamd.StreamPlayerProcessTitleReply + (*StreamPlayerGetLinkRequest)(nil), // 118: streamd.StreamPlayerGetLinkRequest + (*StreamPlayerGetLinkReply)(nil), // 119: streamd.StreamPlayerGetLinkReply + (*StreamPlayerEndChanRequest)(nil), // 120: streamd.StreamPlayerEndChanRequest + (*StreamPlayerEndChanReply)(nil), // 121: streamd.StreamPlayerEndChanReply + (*StreamPlayerIsEndedRequest)(nil), // 122: streamd.StreamPlayerIsEndedRequest + (*StreamPlayerIsEndedReply)(nil), // 123: streamd.StreamPlayerIsEndedReply + (*StreamPlayerGetPositionRequest)(nil), // 124: streamd.StreamPlayerGetPositionRequest + (*StreamPlayerGetPositionReply)(nil), // 125: streamd.StreamPlayerGetPositionReply + (*StreamPlayerGetLengthRequest)(nil), // 126: streamd.StreamPlayerGetLengthRequest + (*StreamPlayerGetLengthReply)(nil), // 127: streamd.StreamPlayerGetLengthReply + (*StreamPlayerSetSpeedRequest)(nil), // 128: streamd.StreamPlayerSetSpeedRequest + (*StreamPlayerSetSpeedReply)(nil), // 129: streamd.StreamPlayerSetSpeedReply + (*StreamPlayerSetPauseRequest)(nil), // 130: streamd.StreamPlayerSetPauseRequest + (*StreamPlayerSetPauseReply)(nil), // 131: streamd.StreamPlayerSetPauseReply + (*StreamPlayerStopRequest)(nil), // 132: streamd.StreamPlayerStopRequest + (*StreamPlayerStopReply)(nil), // 133: streamd.StreamPlayerStopReply + (*StreamPlayerCloseRequest)(nil), // 134: streamd.StreamPlayerCloseRequest + (*StreamPlayerCloseReply)(nil), // 135: streamd.StreamPlayerCloseReply + (*SubscribeToConfigChangesRequest)(nil), // 136: streamd.SubscribeToConfigChangesRequest + (*ConfigChange)(nil), // 137: streamd.ConfigChange + (*SubscribeToStreamsChangesRequest)(nil), // 138: streamd.SubscribeToStreamsChangesRequest + (*StreamsChange)(nil), // 139: streamd.StreamsChange + (*SubscribeToStreamServersChangesRequest)(nil), // 140: streamd.SubscribeToStreamServersChangesRequest + (*StreamServersChange)(nil), // 141: streamd.StreamServersChange + (*SubscribeToStreamDestinationsChangesRequest)(nil), // 142: streamd.SubscribeToStreamDestinationsChangesRequest + (*StreamDestinationsChange)(nil), // 143: streamd.StreamDestinationsChange + (*SubscribeToIncomingStreamsChangesRequest)(nil), // 144: streamd.SubscribeToIncomingStreamsChangesRequest + (*IncomingStreamsChange)(nil), // 145: streamd.IncomingStreamsChange + (*SubscribeToStreamForwardsChangesRequest)(nil), // 146: streamd.SubscribeToStreamForwardsChangesRequest + (*StreamForwardsChange)(nil), // 147: streamd.StreamForwardsChange + (*SubscribeToStreamPlayersChangesRequest)(nil), // 148: streamd.SubscribeToStreamPlayersChangesRequest + (*StreamPlayersChange)(nil), // 149: streamd.StreamPlayersChange + (*NoopRequest)(nil), // 150: streamd.NoopRequest + (*OBSActionElementShowHide)(nil), // 151: streamd.OBSActionElementShowHide + (*OBSActionWindowCaptureSetSource)(nil), // 152: streamd.OBSActionWindowCaptureSetSource + (*OBSAction)(nil), // 153: streamd.OBSAction + (*Action)(nil), // 154: streamd.Action + (*AddTimerRequest)(nil), // 155: streamd.AddTimerRequest + (*AddTimerReply)(nil), // 156: streamd.AddTimerReply + (*RemoveTimerRequest)(nil), // 157: streamd.RemoveTimerRequest + (*RemoveTimerReply)(nil), // 158: streamd.RemoveTimerReply + (*Timer)(nil), // 159: streamd.Timer + (*ListTimersRequest)(nil), // 160: streamd.ListTimersRequest + (*ListTimersReply)(nil), // 161: streamd.ListTimersReply + (*EventQueryAnd)(nil), // 162: streamd.EventQueryAnd + (*EventQueryOr)(nil), // 163: streamd.EventQueryOr + (*EventQueryNot)(nil), // 164: streamd.EventQueryNot + (*EventOBSSceneChange)(nil), // 165: streamd.EventOBSSceneChange + (*EventWindowFocusChange)(nil), // 166: streamd.EventWindowFocusChange + (*EventQuery)(nil), // 167: streamd.EventQuery + (*Event)(nil), // 168: streamd.Event + (*TriggerRule)(nil), // 169: streamd.TriggerRule + (*ListTriggerRulesRequest)(nil), // 170: streamd.ListTriggerRulesRequest + (*ListTriggerRulesReply)(nil), // 171: streamd.ListTriggerRulesReply + (*AddTriggerRuleRequest)(nil), // 172: streamd.AddTriggerRuleRequest + (*AddTriggerRuleReply)(nil), // 173: streamd.AddTriggerRuleReply + (*RemoveTriggerRuleRequest)(nil), // 174: streamd.RemoveTriggerRuleRequest + (*RemoveTriggerRuleReply)(nil), // 175: streamd.RemoveTriggerRuleReply + (*UpdateTriggerRuleRequest)(nil), // 176: streamd.UpdateTriggerRuleRequest + (*UpdateTriggerRuleReply)(nil), // 177: streamd.UpdateTriggerRuleReply + (*SubmitEventRequest)(nil), // 178: streamd.SubmitEventRequest + (*SubmitEventReply)(nil), // 179: streamd.SubmitEventReply + (*player_grpc.OpenRequest)(nil), // 180: player.OpenRequest + (*player_grpc.OpenReply)(nil), // 181: player.OpenReply + (*player_grpc.ProcessTitleRequest)(nil), // 182: player.ProcessTitleRequest + (*player_grpc.ProcessTitleReply)(nil), // 183: player.ProcessTitleReply + (*player_grpc.GetLinkRequest)(nil), // 184: player.GetLinkRequest + (*player_grpc.GetLinkReply)(nil), // 185: player.GetLinkReply + (*player_grpc.EndChanRequest)(nil), // 186: player.EndChanRequest + (*player_grpc.EndChanReply)(nil), // 187: player.EndChanReply + (*player_grpc.IsEndedRequest)(nil), // 188: player.IsEndedRequest + (*player_grpc.IsEndedReply)(nil), // 189: player.IsEndedReply + (*player_grpc.GetPositionRequest)(nil), // 190: player.GetPositionRequest + (*player_grpc.GetPositionReply)(nil), // 191: player.GetPositionReply + (*player_grpc.GetLengthRequest)(nil), // 192: player.GetLengthRequest + (*player_grpc.GetLengthReply)(nil), // 193: player.GetLengthReply + (*player_grpc.SetSpeedRequest)(nil), // 194: player.SetSpeedRequest + (*player_grpc.SetSpeedReply)(nil), // 195: player.SetSpeedReply + (*player_grpc.SetPauseRequest)(nil), // 196: player.SetPauseRequest + (*player_grpc.SetPauseReply)(nil), // 197: player.SetPauseReply + (*player_grpc.StopRequest)(nil), // 198: player.StopRequest + (*player_grpc.StopReply)(nil), // 199: player.StopReply + (*player_grpc.CloseRequest)(nil), // 200: player.CloseRequest + (*player_grpc.CloseReply)(nil), // 201: player.CloseReply } var file_streamd_proto_depIdxs = []int32{ 0, // 0: streamd.SetLoggingLevelRequest.loggingLevel:type_name -> streamd.LoggingLevel @@ -8751,200 +10174,229 @@ var file_streamd_proto_depIdxs = []int32{ 1, // 2: streamd.GetVariableHashRequest.hashType:type_name -> streamd.HashType 1, // 3: streamd.GetVariableHashReply.hashType:type_name -> streamd.HashType 2, // 4: streamd.StreamServer.serverType:type_name -> streamd.StreamServerType - 58, // 5: streamd.StreamServer.ServerCert:type_name -> streamd.TLSCertificate - 59, // 6: streamd.StreamServer.ServerKey:type_name -> streamd.PrivateKey - 60, // 7: streamd.StreamServerWithStatistics.config:type_name -> streamd.StreamServer - 61, // 8: streamd.StreamServerWithStatistics.statistics:type_name -> streamd.StreamServerStatistics - 62, // 9: streamd.ListStreamServersReply.streamServers:type_name -> streamd.StreamServerWithStatistics - 60, // 10: streamd.StartStreamServerRequest.config:type_name -> streamd.StreamServer - 69, // 11: streamd.ListStreamDestinationsReply.streamDestinations:type_name -> streamd.StreamDestination - 69, // 12: streamd.AddStreamDestinationRequest.config:type_name -> streamd.StreamDestination - 69, // 13: streamd.UpdateStreamDestinationRequest.config:type_name -> streamd.StreamDestination - 78, // 14: streamd.ListIncomingStreamsReply.incomingStreams:type_name -> streamd.IncomingStream - 85, // 15: streamd.StreamForwardQuirks.restartUntilYoutubeRecognizesStream:type_name -> streamd.RestartUntilYoutubeRecognizesStream - 86, // 16: streamd.StreamForwardQuirks.startAfterYoutubeRecognizedStream:type_name -> streamd.StartAfterYoutubeRecognizedStream - 87, // 17: streamd.StreamForward.quirks:type_name -> streamd.StreamForwardQuirks - 88, // 18: streamd.StreamForwardWithStatistics.config:type_name -> streamd.StreamForward - 89, // 19: streamd.StreamForwardWithStatistics.statistics:type_name -> streamd.StreamForwardStatistics - 90, // 20: streamd.ListStreamForwardsReply.streamForwards:type_name -> streamd.StreamForwardWithStatistics - 88, // 21: streamd.AddStreamForwardRequest.config:type_name -> streamd.StreamForward - 88, // 22: streamd.UpdateStreamForwardRequest.config:type_name -> streamd.StreamForward - 88, // 23: streamd.RemoveStreamForwardRequest.config:type_name -> streamd.StreamForward + 59, // 5: streamd.StreamServer.ServerCert:type_name -> streamd.TLSCertificate + 60, // 6: streamd.StreamServer.ServerKey:type_name -> streamd.PrivateKey + 61, // 7: streamd.StreamServerWithStatistics.config:type_name -> streamd.StreamServer + 62, // 8: streamd.StreamServerWithStatistics.statistics:type_name -> streamd.StreamServerStatistics + 63, // 9: streamd.ListStreamServersReply.streamServers:type_name -> streamd.StreamServerWithStatistics + 61, // 10: streamd.StartStreamServerRequest.config:type_name -> streamd.StreamServer + 70, // 11: streamd.ListStreamDestinationsReply.streamDestinations:type_name -> streamd.StreamDestination + 70, // 12: streamd.AddStreamDestinationRequest.config:type_name -> streamd.StreamDestination + 70, // 13: streamd.UpdateStreamDestinationRequest.config:type_name -> streamd.StreamDestination + 79, // 14: streamd.ListIncomingStreamsReply.incomingStreams:type_name -> streamd.IncomingStream + 86, // 15: streamd.StreamForwardQuirks.restartUntilYoutubeRecognizesStream:type_name -> streamd.RestartUntilYoutubeRecognizesStream + 87, // 16: streamd.StreamForwardQuirks.startAfterYoutubeRecognizedStream:type_name -> streamd.StartAfterYoutubeRecognizedStream + 88, // 17: streamd.StreamForward.quirks:type_name -> streamd.StreamForwardQuirks + 89, // 18: streamd.StreamForwardWithStatistics.config:type_name -> streamd.StreamForward + 90, // 19: streamd.StreamForwardWithStatistics.statistics:type_name -> streamd.StreamForwardStatistics + 91, // 20: streamd.ListStreamForwardsReply.streamForwards:type_name -> streamd.StreamForwardWithStatistics + 89, // 21: streamd.AddStreamForwardRequest.config:type_name -> streamd.StreamForward + 89, // 22: streamd.UpdateStreamForwardRequest.config:type_name -> streamd.StreamForward + 89, // 23: streamd.RemoveStreamForwardRequest.config:type_name -> streamd.StreamForward 3, // 24: streamd.StreamPlayerConfig.playerType:type_name -> streamd.PlayerType - 101, // 25: streamd.StreamPlayerConfig.streamPlaybackConfig:type_name -> streamd.StreamPlaybackConfig - 102, // 26: streamd.AddStreamPlayerRequest.config:type_name -> streamd.StreamPlayerConfig - 102, // 27: streamd.UpdateStreamPlayerRequest.config:type_name -> streamd.StreamPlayerConfig - 102, // 28: streamd.ListStreamPlayersReply.players:type_name -> streamd.StreamPlayerConfig - 102, // 29: streamd.GetStreamPlayerReply.config:type_name -> streamd.StreamPlayerConfig - 158, // 30: streamd.StreamPlayerOpenRequest.request:type_name -> player.OpenRequest - 159, // 31: streamd.StreamPlayerOpenReply.reply:type_name -> player.OpenReply - 160, // 32: streamd.StreamPlayerProcessTitleRequest.request:type_name -> player.ProcessTitleRequest - 161, // 33: streamd.StreamPlayerProcessTitleReply.reply:type_name -> player.ProcessTitleReply - 162, // 34: streamd.StreamPlayerGetLinkRequest.request:type_name -> player.GetLinkRequest - 163, // 35: streamd.StreamPlayerGetLinkReply.reply:type_name -> player.GetLinkReply - 164, // 36: streamd.StreamPlayerEndChanRequest.request:type_name -> player.EndChanRequest - 165, // 37: streamd.StreamPlayerEndChanReply.reply:type_name -> player.EndChanReply - 166, // 38: streamd.StreamPlayerIsEndedRequest.request:type_name -> player.IsEndedRequest - 167, // 39: streamd.StreamPlayerIsEndedReply.reply:type_name -> player.IsEndedReply - 168, // 40: streamd.StreamPlayerGetPositionRequest.request:type_name -> player.GetPositionRequest - 169, // 41: streamd.StreamPlayerGetPositionReply.reply:type_name -> player.GetPositionReply - 170, // 42: streamd.StreamPlayerGetLengthRequest.request:type_name -> player.GetLengthRequest - 171, // 43: streamd.StreamPlayerGetLengthReply.reply:type_name -> player.GetLengthReply - 172, // 44: streamd.StreamPlayerSetSpeedRequest.request:type_name -> player.SetSpeedRequest - 173, // 45: streamd.StreamPlayerSetSpeedReply.reply:type_name -> player.SetSpeedReply - 174, // 46: streamd.StreamPlayerSetPauseRequest.request:type_name -> player.SetPauseRequest - 175, // 47: streamd.StreamPlayerSetPauseReply.reply:type_name -> player.SetPauseReply - 176, // 48: streamd.StreamPlayerStopRequest.request:type_name -> player.StopRequest - 177, // 49: streamd.StreamPlayerStopReply.reply:type_name -> player.StopReply - 178, // 50: streamd.StreamPlayerCloseRequest.request:type_name -> player.CloseRequest - 179, // 51: streamd.StreamPlayerCloseReply.reply:type_name -> player.CloseReply - 149, // 52: streamd.Action.noopRequest:type_name -> streamd.NoopRequest - 20, // 53: streamd.Action.startStreamRequest:type_name -> streamd.StartStreamRequest - 22, // 54: streamd.Action.endStreamRequest:type_name -> streamd.EndStreamRequest - 150, // 55: streamd.AddTimerRequest.action:type_name -> streamd.Action - 150, // 56: streamd.Timer.action:type_name -> streamd.Action - 155, // 57: streamd.ListTimersReply.timers:type_name -> streamd.Timer - 4, // 58: streamd.StreamD.Ping:input_type -> streamd.PingRequest - 6, // 59: streamd.StreamD.SetLoggingLevel:input_type -> streamd.SetLoggingLevelRequest - 8, // 60: streamd.StreamD.GetLoggingLevel:input_type -> streamd.GetLoggingLevelRequest - 10, // 61: streamd.StreamD.GetConfig:input_type -> streamd.GetConfigRequest - 12, // 62: streamd.StreamD.SetConfig:input_type -> streamd.SetConfigRequest - 14, // 63: streamd.StreamD.SaveConfig:input_type -> streamd.SaveConfigRequest - 135, // 64: streamd.StreamD.SubscribeToConfigChanges:input_type -> streamd.SubscribeToConfigChangesRequest - 16, // 65: streamd.StreamD.ResetCache:input_type -> streamd.ResetCacheRequest - 18, // 66: streamd.StreamD.InitCache:input_type -> streamd.InitCacheRequest - 20, // 67: streamd.StreamD.StartStream:input_type -> streamd.StartStreamRequest - 22, // 68: streamd.StreamD.EndStream:input_type -> streamd.EndStreamRequest - 24, // 69: streamd.StreamD.GetStreamStatus:input_type -> streamd.GetStreamStatusRequest - 28, // 70: streamd.StreamD.IsBackendEnabled:input_type -> streamd.IsBackendEnabledRequest - 26, // 71: streamd.StreamD.GetBackendInfo:input_type -> streamd.GetBackendInfoRequest - 137, // 72: streamd.StreamD.SubscribeToStreamsChanges:input_type -> streamd.SubscribeToStreamsChangesRequest - 30, // 73: streamd.StreamD.Restart:input_type -> streamd.RestartRequest - 32, // 74: streamd.StreamD.SetTitle:input_type -> streamd.SetTitleRequest - 34, // 75: streamd.StreamD.SetDescription:input_type -> streamd.SetDescriptionRequest - 36, // 76: streamd.StreamD.ApplyProfile:input_type -> streamd.ApplyProfileRequest - 38, // 77: streamd.StreamD.UpdateStream:input_type -> streamd.UpdateStreamRequest - 50, // 78: streamd.StreamD.GetVariable:input_type -> streamd.GetVariableRequest - 52, // 79: streamd.StreamD.GetVariableHash:input_type -> streamd.GetVariableHashRequest - 54, // 80: streamd.StreamD.SetVariable:input_type -> streamd.SetVariableRequest - 40, // 81: streamd.StreamD.EXPERIMENTAL_ReinitStreamControllers:input_type -> streamd.EXPERIMENTAL_ReinitStreamControllersRequest - 42, // 82: streamd.StreamD.OBSOLETE_FetchConfig:input_type -> streamd.OBSOLETE_FetchConfigRequest - 44, // 83: streamd.StreamD.OBSOLETE_GitInfo:input_type -> streamd.OBSOLETE_GetGitInfoRequest - 46, // 84: streamd.StreamD.OBSOLETE_GitRelogin:input_type -> streamd.OBSOLETE_GitReloginRequest - 48, // 85: streamd.StreamD.SubscribeToOAuthRequests:input_type -> streamd.SubscribeToOAuthRequestsRequest - 56, // 86: streamd.StreamD.SubmitOAuthCode:input_type -> streamd.SubmitOAuthCodeRequest - 63, // 87: streamd.StreamD.ListStreamServers:input_type -> streamd.ListStreamServersRequest - 65, // 88: streamd.StreamD.StartStreamServer:input_type -> streamd.StartStreamServerRequest - 67, // 89: streamd.StreamD.StopStreamServer:input_type -> streamd.StopStreamServerRequest - 139, // 90: streamd.StreamD.SubscribeToStreamServersChanges:input_type -> streamd.SubscribeToStreamServersChangesRequest - 70, // 91: streamd.StreamD.ListStreamDestinations:input_type -> streamd.ListStreamDestinationsRequest - 72, // 92: streamd.StreamD.AddStreamDestination:input_type -> streamd.AddStreamDestinationRequest - 74, // 93: streamd.StreamD.UpdateStreamDestination:input_type -> streamd.UpdateStreamDestinationRequest - 76, // 94: streamd.StreamD.RemoveStreamDestination:input_type -> streamd.RemoveStreamDestinationRequest - 141, // 95: streamd.StreamD.SubscribeToStreamDestinationsChanges:input_type -> streamd.SubscribeToStreamDestinationsChangesRequest - 79, // 96: streamd.StreamD.AddIncomingStream:input_type -> streamd.AddIncomingStreamRequest - 81, // 97: streamd.StreamD.RemoveIncomingStream:input_type -> streamd.RemoveIncomingStreamRequest - 83, // 98: streamd.StreamD.ListIncomingStreams:input_type -> streamd.ListIncomingStreamsRequest - 143, // 99: streamd.StreamD.SubscribeToIncomingStreamsChanges:input_type -> streamd.SubscribeToIncomingStreamsChangesRequest - 91, // 100: streamd.StreamD.ListStreamForwards:input_type -> streamd.ListStreamForwardsRequest - 93, // 101: streamd.StreamD.AddStreamForward:input_type -> streamd.AddStreamForwardRequest - 95, // 102: streamd.StreamD.UpdateStreamForward:input_type -> streamd.UpdateStreamForwardRequest - 97, // 103: streamd.StreamD.RemoveStreamForward:input_type -> streamd.RemoveStreamForwardRequest - 145, // 104: streamd.StreamD.SubscribeToStreamForwardsChanges:input_type -> streamd.SubscribeToStreamForwardsChangesRequest - 99, // 105: streamd.StreamD.WaitForStreamPublisher:input_type -> streamd.WaitForStreamPublisherRequest - 103, // 106: streamd.StreamD.AddStreamPlayer:input_type -> streamd.AddStreamPlayerRequest - 105, // 107: streamd.StreamD.RemoveStreamPlayer:input_type -> streamd.RemoveStreamPlayerRequest - 107, // 108: streamd.StreamD.UpdateStreamPlayer:input_type -> streamd.UpdateStreamPlayerRequest - 109, // 109: streamd.StreamD.ListStreamPlayers:input_type -> streamd.ListStreamPlayersRequest - 111, // 110: streamd.StreamD.GetStreamPlayer:input_type -> streamd.GetStreamPlayerRequest - 147, // 111: streamd.StreamD.SubscribeToStreamPlayersChanges:input_type -> streamd.SubscribeToStreamPlayersChangesRequest - 113, // 112: streamd.StreamD.StreamPlayerOpen:input_type -> streamd.StreamPlayerOpenRequest - 115, // 113: streamd.StreamD.StreamPlayerProcessTitle:input_type -> streamd.StreamPlayerProcessTitleRequest - 117, // 114: streamd.StreamD.StreamPlayerGetLink:input_type -> streamd.StreamPlayerGetLinkRequest - 119, // 115: streamd.StreamD.StreamPlayerEndChan:input_type -> streamd.StreamPlayerEndChanRequest - 121, // 116: streamd.StreamD.StreamPlayerIsEnded:input_type -> streamd.StreamPlayerIsEndedRequest - 123, // 117: streamd.StreamD.StreamPlayerGetPosition:input_type -> streamd.StreamPlayerGetPositionRequest - 125, // 118: streamd.StreamD.StreamPlayerGetLength:input_type -> streamd.StreamPlayerGetLengthRequest - 127, // 119: streamd.StreamD.StreamPlayerSetSpeed:input_type -> streamd.StreamPlayerSetSpeedRequest - 129, // 120: streamd.StreamD.StreamPlayerSetPause:input_type -> streamd.StreamPlayerSetPauseRequest - 131, // 121: streamd.StreamD.StreamPlayerStop:input_type -> streamd.StreamPlayerStopRequest - 133, // 122: streamd.StreamD.StreamPlayerClose:input_type -> streamd.StreamPlayerCloseRequest - 151, // 123: streamd.StreamD.AddTimer:input_type -> streamd.AddTimerRequest - 153, // 124: streamd.StreamD.RemoveTimer:input_type -> streamd.RemoveTimerRequest - 156, // 125: streamd.StreamD.ListTimers:input_type -> streamd.ListTimersRequest - 5, // 126: streamd.StreamD.Ping:output_type -> streamd.PingReply - 7, // 127: streamd.StreamD.SetLoggingLevel:output_type -> streamd.SetLoggingLevelReply - 9, // 128: streamd.StreamD.GetLoggingLevel:output_type -> streamd.GetLoggingLevelReply - 11, // 129: streamd.StreamD.GetConfig:output_type -> streamd.GetConfigReply - 13, // 130: streamd.StreamD.SetConfig:output_type -> streamd.SetConfigReply - 15, // 131: streamd.StreamD.SaveConfig:output_type -> streamd.SaveConfigReply - 136, // 132: streamd.StreamD.SubscribeToConfigChanges:output_type -> streamd.ConfigChange - 17, // 133: streamd.StreamD.ResetCache:output_type -> streamd.ResetCacheReply - 19, // 134: streamd.StreamD.InitCache:output_type -> streamd.InitCacheReply - 21, // 135: streamd.StreamD.StartStream:output_type -> streamd.StartStreamReply - 23, // 136: streamd.StreamD.EndStream:output_type -> streamd.EndStreamReply - 25, // 137: streamd.StreamD.GetStreamStatus:output_type -> streamd.GetStreamStatusReply - 29, // 138: streamd.StreamD.IsBackendEnabled:output_type -> streamd.IsBackendEnabledReply - 27, // 139: streamd.StreamD.GetBackendInfo:output_type -> streamd.GetBackendInfoReply - 138, // 140: streamd.StreamD.SubscribeToStreamsChanges:output_type -> streamd.StreamsChange - 31, // 141: streamd.StreamD.Restart:output_type -> streamd.RestartReply - 33, // 142: streamd.StreamD.SetTitle:output_type -> streamd.SetTitleReply - 35, // 143: streamd.StreamD.SetDescription:output_type -> streamd.SetDescriptionReply - 37, // 144: streamd.StreamD.ApplyProfile:output_type -> streamd.ApplyProfileReply - 39, // 145: streamd.StreamD.UpdateStream:output_type -> streamd.UpdateStreamReply - 51, // 146: streamd.StreamD.GetVariable:output_type -> streamd.GetVariableReply - 53, // 147: streamd.StreamD.GetVariableHash:output_type -> streamd.GetVariableHashReply - 55, // 148: streamd.StreamD.SetVariable:output_type -> streamd.SetVariableReply - 41, // 149: streamd.StreamD.EXPERIMENTAL_ReinitStreamControllers:output_type -> streamd.EXPERIMENTAL_ReinitStreamControllersReply - 43, // 150: streamd.StreamD.OBSOLETE_FetchConfig:output_type -> streamd.OBSOLETE_FetchConfigReply - 45, // 151: streamd.StreamD.OBSOLETE_GitInfo:output_type -> streamd.OBSOLETE_GetGitInfoReply - 47, // 152: streamd.StreamD.OBSOLETE_GitRelogin:output_type -> streamd.OBSOLETE_GitReloginReply - 49, // 153: streamd.StreamD.SubscribeToOAuthRequests:output_type -> streamd.OAuthRequest - 57, // 154: streamd.StreamD.SubmitOAuthCode:output_type -> streamd.SubmitOAuthCodeReply - 64, // 155: streamd.StreamD.ListStreamServers:output_type -> streamd.ListStreamServersReply - 66, // 156: streamd.StreamD.StartStreamServer:output_type -> streamd.StartStreamServerReply - 68, // 157: streamd.StreamD.StopStreamServer:output_type -> streamd.StopStreamServerReply - 140, // 158: streamd.StreamD.SubscribeToStreamServersChanges:output_type -> streamd.StreamServersChange - 71, // 159: streamd.StreamD.ListStreamDestinations:output_type -> streamd.ListStreamDestinationsReply - 73, // 160: streamd.StreamD.AddStreamDestination:output_type -> streamd.AddStreamDestinationReply - 75, // 161: streamd.StreamD.UpdateStreamDestination:output_type -> streamd.UpdateStreamDestinationReply - 77, // 162: streamd.StreamD.RemoveStreamDestination:output_type -> streamd.RemoveStreamDestinationReply - 142, // 163: streamd.StreamD.SubscribeToStreamDestinationsChanges:output_type -> streamd.StreamDestinationsChange - 80, // 164: streamd.StreamD.AddIncomingStream:output_type -> streamd.AddIncomingStreamReply - 82, // 165: streamd.StreamD.RemoveIncomingStream:output_type -> streamd.RemoveIncomingStreamReply - 84, // 166: streamd.StreamD.ListIncomingStreams:output_type -> streamd.ListIncomingStreamsReply - 144, // 167: streamd.StreamD.SubscribeToIncomingStreamsChanges:output_type -> streamd.IncomingStreamsChange - 92, // 168: streamd.StreamD.ListStreamForwards:output_type -> streamd.ListStreamForwardsReply - 94, // 169: streamd.StreamD.AddStreamForward:output_type -> streamd.AddStreamForwardReply - 96, // 170: streamd.StreamD.UpdateStreamForward:output_type -> streamd.UpdateStreamForwardReply - 98, // 171: streamd.StreamD.RemoveStreamForward:output_type -> streamd.RemoveStreamForwardReply - 146, // 172: streamd.StreamD.SubscribeToStreamForwardsChanges:output_type -> streamd.StreamForwardsChange - 100, // 173: streamd.StreamD.WaitForStreamPublisher:output_type -> streamd.StreamPublisher - 104, // 174: streamd.StreamD.AddStreamPlayer:output_type -> streamd.AddStreamPlayerReply - 106, // 175: streamd.StreamD.RemoveStreamPlayer:output_type -> streamd.RemoveStreamPlayerReply - 108, // 176: streamd.StreamD.UpdateStreamPlayer:output_type -> streamd.UpdateStreamPlayerReply - 110, // 177: streamd.StreamD.ListStreamPlayers:output_type -> streamd.ListStreamPlayersReply - 112, // 178: streamd.StreamD.GetStreamPlayer:output_type -> streamd.GetStreamPlayerReply - 148, // 179: streamd.StreamD.SubscribeToStreamPlayersChanges:output_type -> streamd.StreamPlayersChange - 114, // 180: streamd.StreamD.StreamPlayerOpen:output_type -> streamd.StreamPlayerOpenReply - 116, // 181: streamd.StreamD.StreamPlayerProcessTitle:output_type -> streamd.StreamPlayerProcessTitleReply - 118, // 182: streamd.StreamD.StreamPlayerGetLink:output_type -> streamd.StreamPlayerGetLinkReply - 120, // 183: streamd.StreamD.StreamPlayerEndChan:output_type -> streamd.StreamPlayerEndChanReply - 122, // 184: streamd.StreamD.StreamPlayerIsEnded:output_type -> streamd.StreamPlayerIsEndedReply - 124, // 185: streamd.StreamD.StreamPlayerGetPosition:output_type -> streamd.StreamPlayerGetPositionReply - 126, // 186: streamd.StreamD.StreamPlayerGetLength:output_type -> streamd.StreamPlayerGetLengthReply - 128, // 187: streamd.StreamD.StreamPlayerSetSpeed:output_type -> streamd.StreamPlayerSetSpeedReply - 130, // 188: streamd.StreamD.StreamPlayerSetPause:output_type -> streamd.StreamPlayerSetPauseReply - 132, // 189: streamd.StreamD.StreamPlayerStop:output_type -> streamd.StreamPlayerStopReply - 134, // 190: streamd.StreamD.StreamPlayerClose:output_type -> streamd.StreamPlayerCloseReply - 152, // 191: streamd.StreamD.AddTimer:output_type -> streamd.AddTimerReply - 154, // 192: streamd.StreamD.RemoveTimer:output_type -> streamd.RemoveTimerReply - 157, // 193: streamd.StreamD.ListTimers:output_type -> streamd.ListTimersReply - 126, // [126:194] is the sub-list for method output_type - 58, // [58:126] is the sub-list for method input_type - 58, // [58:58] is the sub-list for extension type_name - 58, // [58:58] is the sub-list for extension extendee - 0, // [0:58] is the sub-list for field type_name + 102, // 25: streamd.StreamPlayerConfig.streamPlaybackConfig:type_name -> streamd.StreamPlaybackConfig + 103, // 26: streamd.AddStreamPlayerRequest.config:type_name -> streamd.StreamPlayerConfig + 103, // 27: streamd.UpdateStreamPlayerRequest.config:type_name -> streamd.StreamPlayerConfig + 103, // 28: streamd.ListStreamPlayersReply.players:type_name -> streamd.StreamPlayerConfig + 103, // 29: streamd.GetStreamPlayerReply.config:type_name -> streamd.StreamPlayerConfig + 180, // 30: streamd.StreamPlayerOpenRequest.request:type_name -> player.OpenRequest + 181, // 31: streamd.StreamPlayerOpenReply.reply:type_name -> player.OpenReply + 182, // 32: streamd.StreamPlayerProcessTitleRequest.request:type_name -> player.ProcessTitleRequest + 183, // 33: streamd.StreamPlayerProcessTitleReply.reply:type_name -> player.ProcessTitleReply + 184, // 34: streamd.StreamPlayerGetLinkRequest.request:type_name -> player.GetLinkRequest + 185, // 35: streamd.StreamPlayerGetLinkReply.reply:type_name -> player.GetLinkReply + 186, // 36: streamd.StreamPlayerEndChanRequest.request:type_name -> player.EndChanRequest + 187, // 37: streamd.StreamPlayerEndChanReply.reply:type_name -> player.EndChanReply + 188, // 38: streamd.StreamPlayerIsEndedRequest.request:type_name -> player.IsEndedRequest + 189, // 39: streamd.StreamPlayerIsEndedReply.reply:type_name -> player.IsEndedReply + 190, // 40: streamd.StreamPlayerGetPositionRequest.request:type_name -> player.GetPositionRequest + 191, // 41: streamd.StreamPlayerGetPositionReply.reply:type_name -> player.GetPositionReply + 192, // 42: streamd.StreamPlayerGetLengthRequest.request:type_name -> player.GetLengthRequest + 193, // 43: streamd.StreamPlayerGetLengthReply.reply:type_name -> player.GetLengthReply + 194, // 44: streamd.StreamPlayerSetSpeedRequest.request:type_name -> player.SetSpeedRequest + 195, // 45: streamd.StreamPlayerSetSpeedReply.reply:type_name -> player.SetSpeedReply + 196, // 46: streamd.StreamPlayerSetPauseRequest.request:type_name -> player.SetPauseRequest + 197, // 47: streamd.StreamPlayerSetPauseReply.reply:type_name -> player.SetPauseReply + 198, // 48: streamd.StreamPlayerStopRequest.request:type_name -> player.StopRequest + 199, // 49: streamd.StreamPlayerStopReply.reply:type_name -> player.StopReply + 200, // 50: streamd.StreamPlayerCloseRequest.request:type_name -> player.CloseRequest + 201, // 51: streamd.StreamPlayerCloseReply.reply:type_name -> player.CloseReply + 151, // 52: streamd.OBSAction.elementShowHide:type_name -> streamd.OBSActionElementShowHide + 152, // 53: streamd.OBSAction.windowCaptureSetSource:type_name -> streamd.OBSActionWindowCaptureSetSource + 150, // 54: streamd.Action.noopRequest:type_name -> streamd.NoopRequest + 21, // 55: streamd.Action.startStreamRequest:type_name -> streamd.StartStreamRequest + 23, // 56: streamd.Action.endStreamRequest:type_name -> streamd.EndStreamRequest + 153, // 57: streamd.Action.obsAction:type_name -> streamd.OBSAction + 154, // 58: streamd.AddTimerRequest.action:type_name -> streamd.Action + 154, // 59: streamd.Timer.action:type_name -> streamd.Action + 159, // 60: streamd.ListTimersReply.timers:type_name -> streamd.Timer + 168, // 61: streamd.EventQueryAnd.queries:type_name -> streamd.Event + 168, // 62: streamd.EventQueryOr.queries:type_name -> streamd.Event + 168, // 63: streamd.EventQueryNot.query:type_name -> streamd.Event + 162, // 64: streamd.EventQuery.and:type_name -> streamd.EventQueryAnd + 163, // 65: streamd.EventQuery.or:type_name -> streamd.EventQueryOr + 164, // 66: streamd.EventQuery.not:type_name -> streamd.EventQueryNot + 4, // 67: streamd.EventQuery.eventType:type_name -> streamd.EventType + 168, // 68: streamd.EventQuery.event:type_name -> streamd.Event + 165, // 69: streamd.Event.obsSceneChange:type_name -> streamd.EventOBSSceneChange + 166, // 70: streamd.Event.windowFocusChange:type_name -> streamd.EventWindowFocusChange + 167, // 71: streamd.TriggerRule.eventQuery:type_name -> streamd.EventQuery + 154, // 72: streamd.TriggerRule.action:type_name -> streamd.Action + 169, // 73: streamd.ListTriggerRulesReply.rules:type_name -> streamd.TriggerRule + 169, // 74: streamd.AddTriggerRuleRequest.rule:type_name -> streamd.TriggerRule + 169, // 75: streamd.UpdateTriggerRuleRequest.rule:type_name -> streamd.TriggerRule + 168, // 76: streamd.SubmitEventRequest.event:type_name -> streamd.Event + 5, // 77: streamd.StreamD.Ping:input_type -> streamd.PingRequest + 7, // 78: streamd.StreamD.SetLoggingLevel:input_type -> streamd.SetLoggingLevelRequest + 9, // 79: streamd.StreamD.GetLoggingLevel:input_type -> streamd.GetLoggingLevelRequest + 11, // 80: streamd.StreamD.GetConfig:input_type -> streamd.GetConfigRequest + 13, // 81: streamd.StreamD.SetConfig:input_type -> streamd.SetConfigRequest + 15, // 82: streamd.StreamD.SaveConfig:input_type -> streamd.SaveConfigRequest + 136, // 83: streamd.StreamD.SubscribeToConfigChanges:input_type -> streamd.SubscribeToConfigChangesRequest + 17, // 84: streamd.StreamD.ResetCache:input_type -> streamd.ResetCacheRequest + 19, // 85: streamd.StreamD.InitCache:input_type -> streamd.InitCacheRequest + 21, // 86: streamd.StreamD.StartStream:input_type -> streamd.StartStreamRequest + 23, // 87: streamd.StreamD.EndStream:input_type -> streamd.EndStreamRequest + 25, // 88: streamd.StreamD.GetStreamStatus:input_type -> streamd.GetStreamStatusRequest + 29, // 89: streamd.StreamD.IsBackendEnabled:input_type -> streamd.IsBackendEnabledRequest + 27, // 90: streamd.StreamD.GetBackendInfo:input_type -> streamd.GetBackendInfoRequest + 138, // 91: streamd.StreamD.SubscribeToStreamsChanges:input_type -> streamd.SubscribeToStreamsChangesRequest + 31, // 92: streamd.StreamD.Restart:input_type -> streamd.RestartRequest + 33, // 93: streamd.StreamD.SetTitle:input_type -> streamd.SetTitleRequest + 35, // 94: streamd.StreamD.SetDescription:input_type -> streamd.SetDescriptionRequest + 37, // 95: streamd.StreamD.ApplyProfile:input_type -> streamd.ApplyProfileRequest + 39, // 96: streamd.StreamD.UpdateStream:input_type -> streamd.UpdateStreamRequest + 51, // 97: streamd.StreamD.GetVariable:input_type -> streamd.GetVariableRequest + 53, // 98: streamd.StreamD.GetVariableHash:input_type -> streamd.GetVariableHashRequest + 55, // 99: streamd.StreamD.SetVariable:input_type -> streamd.SetVariableRequest + 41, // 100: streamd.StreamD.EXPERIMENTAL_ReinitStreamControllers:input_type -> streamd.EXPERIMENTAL_ReinitStreamControllersRequest + 43, // 101: streamd.StreamD.OBSOLETE_FetchConfig:input_type -> streamd.OBSOLETE_FetchConfigRequest + 45, // 102: streamd.StreamD.OBSOLETE_GitInfo:input_type -> streamd.OBSOLETE_GetGitInfoRequest + 47, // 103: streamd.StreamD.OBSOLETE_GitRelogin:input_type -> streamd.OBSOLETE_GitReloginRequest + 49, // 104: streamd.StreamD.SubscribeToOAuthRequests:input_type -> streamd.SubscribeToOAuthRequestsRequest + 57, // 105: streamd.StreamD.SubmitOAuthCode:input_type -> streamd.SubmitOAuthCodeRequest + 64, // 106: streamd.StreamD.ListStreamServers:input_type -> streamd.ListStreamServersRequest + 66, // 107: streamd.StreamD.StartStreamServer:input_type -> streamd.StartStreamServerRequest + 68, // 108: streamd.StreamD.StopStreamServer:input_type -> streamd.StopStreamServerRequest + 140, // 109: streamd.StreamD.SubscribeToStreamServersChanges:input_type -> streamd.SubscribeToStreamServersChangesRequest + 71, // 110: streamd.StreamD.ListStreamDestinations:input_type -> streamd.ListStreamDestinationsRequest + 73, // 111: streamd.StreamD.AddStreamDestination:input_type -> streamd.AddStreamDestinationRequest + 75, // 112: streamd.StreamD.UpdateStreamDestination:input_type -> streamd.UpdateStreamDestinationRequest + 77, // 113: streamd.StreamD.RemoveStreamDestination:input_type -> streamd.RemoveStreamDestinationRequest + 142, // 114: streamd.StreamD.SubscribeToStreamDestinationsChanges:input_type -> streamd.SubscribeToStreamDestinationsChangesRequest + 80, // 115: streamd.StreamD.AddIncomingStream:input_type -> streamd.AddIncomingStreamRequest + 82, // 116: streamd.StreamD.RemoveIncomingStream:input_type -> streamd.RemoveIncomingStreamRequest + 84, // 117: streamd.StreamD.ListIncomingStreams:input_type -> streamd.ListIncomingStreamsRequest + 144, // 118: streamd.StreamD.SubscribeToIncomingStreamsChanges:input_type -> streamd.SubscribeToIncomingStreamsChangesRequest + 92, // 119: streamd.StreamD.ListStreamForwards:input_type -> streamd.ListStreamForwardsRequest + 94, // 120: streamd.StreamD.AddStreamForward:input_type -> streamd.AddStreamForwardRequest + 96, // 121: streamd.StreamD.UpdateStreamForward:input_type -> streamd.UpdateStreamForwardRequest + 98, // 122: streamd.StreamD.RemoveStreamForward:input_type -> streamd.RemoveStreamForwardRequest + 146, // 123: streamd.StreamD.SubscribeToStreamForwardsChanges:input_type -> streamd.SubscribeToStreamForwardsChangesRequest + 100, // 124: streamd.StreamD.WaitForStreamPublisher:input_type -> streamd.WaitForStreamPublisherRequest + 104, // 125: streamd.StreamD.AddStreamPlayer:input_type -> streamd.AddStreamPlayerRequest + 106, // 126: streamd.StreamD.RemoveStreamPlayer:input_type -> streamd.RemoveStreamPlayerRequest + 108, // 127: streamd.StreamD.UpdateStreamPlayer:input_type -> streamd.UpdateStreamPlayerRequest + 110, // 128: streamd.StreamD.ListStreamPlayers:input_type -> streamd.ListStreamPlayersRequest + 112, // 129: streamd.StreamD.GetStreamPlayer:input_type -> streamd.GetStreamPlayerRequest + 148, // 130: streamd.StreamD.SubscribeToStreamPlayersChanges:input_type -> streamd.SubscribeToStreamPlayersChangesRequest + 114, // 131: streamd.StreamD.StreamPlayerOpen:input_type -> streamd.StreamPlayerOpenRequest + 116, // 132: streamd.StreamD.StreamPlayerProcessTitle:input_type -> streamd.StreamPlayerProcessTitleRequest + 118, // 133: streamd.StreamD.StreamPlayerGetLink:input_type -> streamd.StreamPlayerGetLinkRequest + 120, // 134: streamd.StreamD.StreamPlayerEndChan:input_type -> streamd.StreamPlayerEndChanRequest + 122, // 135: streamd.StreamD.StreamPlayerIsEnded:input_type -> streamd.StreamPlayerIsEndedRequest + 124, // 136: streamd.StreamD.StreamPlayerGetPosition:input_type -> streamd.StreamPlayerGetPositionRequest + 126, // 137: streamd.StreamD.StreamPlayerGetLength:input_type -> streamd.StreamPlayerGetLengthRequest + 128, // 138: streamd.StreamD.StreamPlayerSetSpeed:input_type -> streamd.StreamPlayerSetSpeedRequest + 130, // 139: streamd.StreamD.StreamPlayerSetPause:input_type -> streamd.StreamPlayerSetPauseRequest + 132, // 140: streamd.StreamD.StreamPlayerStop:input_type -> streamd.StreamPlayerStopRequest + 134, // 141: streamd.StreamD.StreamPlayerClose:input_type -> streamd.StreamPlayerCloseRequest + 155, // 142: streamd.StreamD.AddTimer:input_type -> streamd.AddTimerRequest + 157, // 143: streamd.StreamD.RemoveTimer:input_type -> streamd.RemoveTimerRequest + 160, // 144: streamd.StreamD.ListTimers:input_type -> streamd.ListTimersRequest + 170, // 145: streamd.StreamD.ListTriggerRules:input_type -> streamd.ListTriggerRulesRequest + 172, // 146: streamd.StreamD.AddTriggerRule:input_type -> streamd.AddTriggerRuleRequest + 174, // 147: streamd.StreamD.RemoveTriggerRule:input_type -> streamd.RemoveTriggerRuleRequest + 176, // 148: streamd.StreamD.UpdateTriggerRule:input_type -> streamd.UpdateTriggerRuleRequest + 178, // 149: streamd.StreamD.SubmitEvent:input_type -> streamd.SubmitEventRequest + 6, // 150: streamd.StreamD.Ping:output_type -> streamd.PingReply + 8, // 151: streamd.StreamD.SetLoggingLevel:output_type -> streamd.SetLoggingLevelReply + 10, // 152: streamd.StreamD.GetLoggingLevel:output_type -> streamd.GetLoggingLevelReply + 12, // 153: streamd.StreamD.GetConfig:output_type -> streamd.GetConfigReply + 14, // 154: streamd.StreamD.SetConfig:output_type -> streamd.SetConfigReply + 16, // 155: streamd.StreamD.SaveConfig:output_type -> streamd.SaveConfigReply + 137, // 156: streamd.StreamD.SubscribeToConfigChanges:output_type -> streamd.ConfigChange + 18, // 157: streamd.StreamD.ResetCache:output_type -> streamd.ResetCacheReply + 20, // 158: streamd.StreamD.InitCache:output_type -> streamd.InitCacheReply + 22, // 159: streamd.StreamD.StartStream:output_type -> streamd.StartStreamReply + 24, // 160: streamd.StreamD.EndStream:output_type -> streamd.EndStreamReply + 26, // 161: streamd.StreamD.GetStreamStatus:output_type -> streamd.GetStreamStatusReply + 30, // 162: streamd.StreamD.IsBackendEnabled:output_type -> streamd.IsBackendEnabledReply + 28, // 163: streamd.StreamD.GetBackendInfo:output_type -> streamd.GetBackendInfoReply + 139, // 164: streamd.StreamD.SubscribeToStreamsChanges:output_type -> streamd.StreamsChange + 32, // 165: streamd.StreamD.Restart:output_type -> streamd.RestartReply + 34, // 166: streamd.StreamD.SetTitle:output_type -> streamd.SetTitleReply + 36, // 167: streamd.StreamD.SetDescription:output_type -> streamd.SetDescriptionReply + 38, // 168: streamd.StreamD.ApplyProfile:output_type -> streamd.ApplyProfileReply + 40, // 169: streamd.StreamD.UpdateStream:output_type -> streamd.UpdateStreamReply + 52, // 170: streamd.StreamD.GetVariable:output_type -> streamd.GetVariableReply + 54, // 171: streamd.StreamD.GetVariableHash:output_type -> streamd.GetVariableHashReply + 56, // 172: streamd.StreamD.SetVariable:output_type -> streamd.SetVariableReply + 42, // 173: streamd.StreamD.EXPERIMENTAL_ReinitStreamControllers:output_type -> streamd.EXPERIMENTAL_ReinitStreamControllersReply + 44, // 174: streamd.StreamD.OBSOLETE_FetchConfig:output_type -> streamd.OBSOLETE_FetchConfigReply + 46, // 175: streamd.StreamD.OBSOLETE_GitInfo:output_type -> streamd.OBSOLETE_GetGitInfoReply + 48, // 176: streamd.StreamD.OBSOLETE_GitRelogin:output_type -> streamd.OBSOLETE_GitReloginReply + 50, // 177: streamd.StreamD.SubscribeToOAuthRequests:output_type -> streamd.OAuthRequest + 58, // 178: streamd.StreamD.SubmitOAuthCode:output_type -> streamd.SubmitOAuthCodeReply + 65, // 179: streamd.StreamD.ListStreamServers:output_type -> streamd.ListStreamServersReply + 67, // 180: streamd.StreamD.StartStreamServer:output_type -> streamd.StartStreamServerReply + 69, // 181: streamd.StreamD.StopStreamServer:output_type -> streamd.StopStreamServerReply + 141, // 182: streamd.StreamD.SubscribeToStreamServersChanges:output_type -> streamd.StreamServersChange + 72, // 183: streamd.StreamD.ListStreamDestinations:output_type -> streamd.ListStreamDestinationsReply + 74, // 184: streamd.StreamD.AddStreamDestination:output_type -> streamd.AddStreamDestinationReply + 76, // 185: streamd.StreamD.UpdateStreamDestination:output_type -> streamd.UpdateStreamDestinationReply + 78, // 186: streamd.StreamD.RemoveStreamDestination:output_type -> streamd.RemoveStreamDestinationReply + 143, // 187: streamd.StreamD.SubscribeToStreamDestinationsChanges:output_type -> streamd.StreamDestinationsChange + 81, // 188: streamd.StreamD.AddIncomingStream:output_type -> streamd.AddIncomingStreamReply + 83, // 189: streamd.StreamD.RemoveIncomingStream:output_type -> streamd.RemoveIncomingStreamReply + 85, // 190: streamd.StreamD.ListIncomingStreams:output_type -> streamd.ListIncomingStreamsReply + 145, // 191: streamd.StreamD.SubscribeToIncomingStreamsChanges:output_type -> streamd.IncomingStreamsChange + 93, // 192: streamd.StreamD.ListStreamForwards:output_type -> streamd.ListStreamForwardsReply + 95, // 193: streamd.StreamD.AddStreamForward:output_type -> streamd.AddStreamForwardReply + 97, // 194: streamd.StreamD.UpdateStreamForward:output_type -> streamd.UpdateStreamForwardReply + 99, // 195: streamd.StreamD.RemoveStreamForward:output_type -> streamd.RemoveStreamForwardReply + 147, // 196: streamd.StreamD.SubscribeToStreamForwardsChanges:output_type -> streamd.StreamForwardsChange + 101, // 197: streamd.StreamD.WaitForStreamPublisher:output_type -> streamd.StreamPublisher + 105, // 198: streamd.StreamD.AddStreamPlayer:output_type -> streamd.AddStreamPlayerReply + 107, // 199: streamd.StreamD.RemoveStreamPlayer:output_type -> streamd.RemoveStreamPlayerReply + 109, // 200: streamd.StreamD.UpdateStreamPlayer:output_type -> streamd.UpdateStreamPlayerReply + 111, // 201: streamd.StreamD.ListStreamPlayers:output_type -> streamd.ListStreamPlayersReply + 113, // 202: streamd.StreamD.GetStreamPlayer:output_type -> streamd.GetStreamPlayerReply + 149, // 203: streamd.StreamD.SubscribeToStreamPlayersChanges:output_type -> streamd.StreamPlayersChange + 115, // 204: streamd.StreamD.StreamPlayerOpen:output_type -> streamd.StreamPlayerOpenReply + 117, // 205: streamd.StreamD.StreamPlayerProcessTitle:output_type -> streamd.StreamPlayerProcessTitleReply + 119, // 206: streamd.StreamD.StreamPlayerGetLink:output_type -> streamd.StreamPlayerGetLinkReply + 121, // 207: streamd.StreamD.StreamPlayerEndChan:output_type -> streamd.StreamPlayerEndChanReply + 123, // 208: streamd.StreamD.StreamPlayerIsEnded:output_type -> streamd.StreamPlayerIsEndedReply + 125, // 209: streamd.StreamD.StreamPlayerGetPosition:output_type -> streamd.StreamPlayerGetPositionReply + 127, // 210: streamd.StreamD.StreamPlayerGetLength:output_type -> streamd.StreamPlayerGetLengthReply + 129, // 211: streamd.StreamD.StreamPlayerSetSpeed:output_type -> streamd.StreamPlayerSetSpeedReply + 131, // 212: streamd.StreamD.StreamPlayerSetPause:output_type -> streamd.StreamPlayerSetPauseReply + 133, // 213: streamd.StreamD.StreamPlayerStop:output_type -> streamd.StreamPlayerStopReply + 135, // 214: streamd.StreamD.StreamPlayerClose:output_type -> streamd.StreamPlayerCloseReply + 156, // 215: streamd.StreamD.AddTimer:output_type -> streamd.AddTimerReply + 158, // 216: streamd.StreamD.RemoveTimer:output_type -> streamd.RemoveTimerReply + 161, // 217: streamd.StreamD.ListTimers:output_type -> streamd.ListTimersReply + 171, // 218: streamd.StreamD.ListTriggerRules:output_type -> streamd.ListTriggerRulesReply + 173, // 219: streamd.StreamD.AddTriggerRule:output_type -> streamd.AddTriggerRuleReply + 175, // 220: streamd.StreamD.RemoveTriggerRule:output_type -> streamd.RemoveTriggerRuleReply + 177, // 221: streamd.StreamD.UpdateTriggerRule:output_type -> streamd.UpdateTriggerRuleReply + 179, // 222: streamd.StreamD.SubmitEvent:output_type -> streamd.SubmitEventReply + 150, // [150:223] is the sub-list for method output_type + 77, // [77:150] is the sub-list for method input_type + 77, // [77:77] is the sub-list for extension type_name + 77, // [77:77] is the sub-list for extension extendee + 0, // [0:77] is the sub-list for field type_name } func init() { file_streamd_proto_init() } @@ -10706,7 +12158,7 @@ func file_streamd_proto_init() { } } file_streamd_proto_msgTypes[146].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Action); i { + switch v := v.(*OBSActionElementShowHide); i { case 0: return &v.state case 1: @@ -10718,7 +12170,7 @@ func file_streamd_proto_init() { } } file_streamd_proto_msgTypes[147].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddTimerRequest); i { + switch v := v.(*OBSActionWindowCaptureSetSource); i { case 0: return &v.state case 1: @@ -10730,7 +12182,7 @@ func file_streamd_proto_init() { } } file_streamd_proto_msgTypes[148].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddTimerReply); i { + switch v := v.(*OBSAction); i { case 0: return &v.state case 1: @@ -10742,7 +12194,7 @@ func file_streamd_proto_init() { } } file_streamd_proto_msgTypes[149].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RemoveTimerRequest); i { + switch v := v.(*Action); i { case 0: return &v.state case 1: @@ -10754,7 +12206,7 @@ func file_streamd_proto_init() { } } file_streamd_proto_msgTypes[150].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RemoveTimerReply); i { + switch v := v.(*AddTimerRequest); i { case 0: return &v.state case 1: @@ -10766,7 +12218,7 @@ func file_streamd_proto_init() { } } file_streamd_proto_msgTypes[151].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Timer); i { + switch v := v.(*AddTimerReply); i { case 0: return &v.state case 1: @@ -10778,7 +12230,7 @@ func file_streamd_proto_init() { } } file_streamd_proto_msgTypes[152].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListTimersRequest); i { + switch v := v.(*RemoveTimerRequest); i { case 0: return &v.state case 1: @@ -10790,6 +12242,42 @@ func file_streamd_proto_init() { } } file_streamd_proto_msgTypes[153].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveTimerReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_streamd_proto_msgTypes[154].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Timer); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_streamd_proto_msgTypes[155].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListTimersRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_streamd_proto_msgTypes[156].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListTimersReply); i { case 0: return &v.state @@ -10801,6 +12289,222 @@ func file_streamd_proto_init() { return nil } } + file_streamd_proto_msgTypes[157].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EventQueryAnd); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_streamd_proto_msgTypes[158].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EventQueryOr); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_streamd_proto_msgTypes[159].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EventQueryNot); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_streamd_proto_msgTypes[160].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EventOBSSceneChange); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_streamd_proto_msgTypes[161].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EventWindowFocusChange); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_streamd_proto_msgTypes[162].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EventQuery); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_streamd_proto_msgTypes[163].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Event); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_streamd_proto_msgTypes[164].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TriggerRule); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_streamd_proto_msgTypes[165].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListTriggerRulesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_streamd_proto_msgTypes[166].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListTriggerRulesReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_streamd_proto_msgTypes[167].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddTriggerRuleRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_streamd_proto_msgTypes[168].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddTriggerRuleReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_streamd_proto_msgTypes[169].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveTriggerRuleRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_streamd_proto_msgTypes[170].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveTriggerRuleReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_streamd_proto_msgTypes[171].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateTriggerRuleRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_streamd_proto_msgTypes[172].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateTriggerRuleReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_streamd_proto_msgTypes[173].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubmitEventRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_streamd_proto_msgTypes[174].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubmitEventReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_streamd_proto_msgTypes[21].OneofWrappers = []interface{}{} file_streamd_proto_msgTypes[54].OneofWrappers = []interface{}{ @@ -10811,18 +12515,37 @@ func file_streamd_proto_init() { } file_streamd_proto_msgTypes[56].OneofWrappers = []interface{}{} file_streamd_proto_msgTypes[95].OneofWrappers = []interface{}{} - file_streamd_proto_msgTypes[146].OneofWrappers = []interface{}{ + file_streamd_proto_msgTypes[146].OneofWrappers = []interface{}{} + file_streamd_proto_msgTypes[147].OneofWrappers = []interface{}{} + file_streamd_proto_msgTypes[148].OneofWrappers = []interface{}{ + (*OBSAction_ElementShowHide)(nil), + (*OBSAction_WindowCaptureSetSource)(nil), + } + file_streamd_proto_msgTypes[149].OneofWrappers = []interface{}{ (*Action_NoopRequest)(nil), (*Action_StartStreamRequest)(nil), (*Action_EndStreamRequest)(nil), + (*Action_ObsAction)(nil), + } + file_streamd_proto_msgTypes[161].OneofWrappers = []interface{}{} + file_streamd_proto_msgTypes[162].OneofWrappers = []interface{}{ + (*EventQuery_And)(nil), + (*EventQuery_Or)(nil), + (*EventQuery_Not)(nil), + (*EventQuery_EventType)(nil), + (*EventQuery_Event)(nil), + } + file_streamd_proto_msgTypes[163].OneofWrappers = []interface{}{ + (*Event_ObsSceneChange)(nil), + (*Event_WindowFocusChange)(nil), } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_streamd_proto_rawDesc, - NumEnums: 4, - NumMessages: 154, + NumEnums: 5, + NumMessages: 175, NumExtensions: 0, NumServices: 1, }, diff --git a/pkg/streamd/grpc/go/streamd_grpc/streamd_grpc.pb.go b/pkg/streamd/grpc/go/streamd_grpc/streamd_grpc.pb.go index 685b7df..972fa89 100644 --- a/pkg/streamd/grpc/go/streamd_grpc/streamd_grpc.pb.go +++ b/pkg/streamd/grpc/go/streamd_grpc/streamd_grpc.pb.go @@ -90,6 +90,11 @@ type StreamDClient interface { AddTimer(ctx context.Context, in *AddTimerRequest, opts ...grpc.CallOption) (*AddTimerReply, error) RemoveTimer(ctx context.Context, in *RemoveTimerRequest, opts ...grpc.CallOption) (*RemoveTimerReply, error) ListTimers(ctx context.Context, in *ListTimersRequest, opts ...grpc.CallOption) (*ListTimersReply, error) + ListTriggerRules(ctx context.Context, in *ListTriggerRulesRequest, opts ...grpc.CallOption) (*ListTriggerRulesReply, error) + AddTriggerRule(ctx context.Context, in *AddTriggerRuleRequest, opts ...grpc.CallOption) (*AddTriggerRuleReply, error) + RemoveTriggerRule(ctx context.Context, in *RemoveTriggerRuleRequest, opts ...grpc.CallOption) (*RemoveTriggerRuleReply, error) + UpdateTriggerRule(ctx context.Context, in *UpdateTriggerRuleRequest, opts ...grpc.CallOption) (*UpdateTriggerRuleReply, error) + SubmitEvent(ctx context.Context, in *SubmitEventRequest, opts ...grpc.CallOption) (*SubmitEventReply, error) } type streamDClient struct { @@ -942,6 +947,51 @@ func (c *streamDClient) ListTimers(ctx context.Context, in *ListTimersRequest, o return out, nil } +func (c *streamDClient) ListTriggerRules(ctx context.Context, in *ListTriggerRulesRequest, opts ...grpc.CallOption) (*ListTriggerRulesReply, error) { + out := new(ListTriggerRulesReply) + err := c.cc.Invoke(ctx, "/streamd.StreamD/ListTriggerRules", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *streamDClient) AddTriggerRule(ctx context.Context, in *AddTriggerRuleRequest, opts ...grpc.CallOption) (*AddTriggerRuleReply, error) { + out := new(AddTriggerRuleReply) + err := c.cc.Invoke(ctx, "/streamd.StreamD/AddTriggerRule", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *streamDClient) RemoveTriggerRule(ctx context.Context, in *RemoveTriggerRuleRequest, opts ...grpc.CallOption) (*RemoveTriggerRuleReply, error) { + out := new(RemoveTriggerRuleReply) + err := c.cc.Invoke(ctx, "/streamd.StreamD/RemoveTriggerRule", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *streamDClient) UpdateTriggerRule(ctx context.Context, in *UpdateTriggerRuleRequest, opts ...grpc.CallOption) (*UpdateTriggerRuleReply, error) { + out := new(UpdateTriggerRuleReply) + err := c.cc.Invoke(ctx, "/streamd.StreamD/UpdateTriggerRule", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *streamDClient) SubmitEvent(ctx context.Context, in *SubmitEventRequest, opts ...grpc.CallOption) (*SubmitEventReply, error) { + out := new(SubmitEventReply) + err := c.cc.Invoke(ctx, "/streamd.StreamD/SubmitEvent", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // StreamDServer is the server API for StreamD service. // All implementations must embed UnimplementedStreamDServer // for forward compatibility @@ -1014,6 +1064,11 @@ type StreamDServer interface { AddTimer(context.Context, *AddTimerRequest) (*AddTimerReply, error) RemoveTimer(context.Context, *RemoveTimerRequest) (*RemoveTimerReply, error) ListTimers(context.Context, *ListTimersRequest) (*ListTimersReply, error) + ListTriggerRules(context.Context, *ListTriggerRulesRequest) (*ListTriggerRulesReply, error) + AddTriggerRule(context.Context, *AddTriggerRuleRequest) (*AddTriggerRuleReply, error) + RemoveTriggerRule(context.Context, *RemoveTriggerRuleRequest) (*RemoveTriggerRuleReply, error) + UpdateTriggerRule(context.Context, *UpdateTriggerRuleRequest) (*UpdateTriggerRuleReply, error) + SubmitEvent(context.Context, *SubmitEventRequest) (*SubmitEventReply, error) mustEmbedUnimplementedStreamDServer() } @@ -1225,6 +1280,21 @@ func (UnimplementedStreamDServer) RemoveTimer(context.Context, *RemoveTimerReque func (UnimplementedStreamDServer) ListTimers(context.Context, *ListTimersRequest) (*ListTimersReply, error) { return nil, status.Errorf(codes.Unimplemented, "method ListTimers not implemented") } +func (UnimplementedStreamDServer) ListTriggerRules(context.Context, *ListTriggerRulesRequest) (*ListTriggerRulesReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListTriggerRules not implemented") +} +func (UnimplementedStreamDServer) AddTriggerRule(context.Context, *AddTriggerRuleRequest) (*AddTriggerRuleReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method AddTriggerRule not implemented") +} +func (UnimplementedStreamDServer) RemoveTriggerRule(context.Context, *RemoveTriggerRuleRequest) (*RemoveTriggerRuleReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method RemoveTriggerRule not implemented") +} +func (UnimplementedStreamDServer) UpdateTriggerRule(context.Context, *UpdateTriggerRuleRequest) (*UpdateTriggerRuleReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateTriggerRule not implemented") +} +func (UnimplementedStreamDServer) SubmitEvent(context.Context, *SubmitEventRequest) (*SubmitEventReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method SubmitEvent not implemented") +} func (UnimplementedStreamDServer) mustEmbedUnimplementedStreamDServer() {} // UnsafeStreamDServer may be embedded to opt out of forward compatibility for this service. @@ -2492,6 +2562,96 @@ func _StreamD_ListTimers_Handler(srv interface{}, ctx context.Context, dec func( return interceptor(ctx, in, info, handler) } +func _StreamD_ListTriggerRules_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListTriggerRulesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StreamDServer).ListTriggerRules(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/streamd.StreamD/ListTriggerRules", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StreamDServer).ListTriggerRules(ctx, req.(*ListTriggerRulesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _StreamD_AddTriggerRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AddTriggerRuleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StreamDServer).AddTriggerRule(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/streamd.StreamD/AddTriggerRule", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StreamDServer).AddTriggerRule(ctx, req.(*AddTriggerRuleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _StreamD_RemoveTriggerRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RemoveTriggerRuleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StreamDServer).RemoveTriggerRule(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/streamd.StreamD/RemoveTriggerRule", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StreamDServer).RemoveTriggerRule(ctx, req.(*RemoveTriggerRuleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _StreamD_UpdateTriggerRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateTriggerRuleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StreamDServer).UpdateTriggerRule(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/streamd.StreamD/UpdateTriggerRule", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StreamDServer).UpdateTriggerRule(ctx, req.(*UpdateTriggerRuleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _StreamD_SubmitEvent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SubmitEventRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StreamDServer).SubmitEvent(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/streamd.StreamD/SubmitEvent", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StreamDServer).SubmitEvent(ctx, req.(*SubmitEventRequest)) + } + return interceptor(ctx, in, info, handler) +} + // StreamD_ServiceDesc is the grpc.ServiceDesc for StreamD service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -2731,6 +2891,26 @@ var StreamD_ServiceDesc = grpc.ServiceDesc{ MethodName: "ListTimers", Handler: _StreamD_ListTimers_Handler, }, + { + MethodName: "ListTriggerRules", + Handler: _StreamD_ListTriggerRules_Handler, + }, + { + MethodName: "AddTriggerRule", + Handler: _StreamD_AddTriggerRule_Handler, + }, + { + MethodName: "RemoveTriggerRule", + Handler: _StreamD_RemoveTriggerRule_Handler, + }, + { + MethodName: "UpdateTriggerRule", + Handler: _StreamD_UpdateTriggerRule_Handler, + }, + { + MethodName: "SubmitEvent", + Handler: _StreamD_SubmitEvent_Handler, + }, }, Streams: []grpc.StreamDesc{ { diff --git a/pkg/streamd/grpc/goconv/action.go b/pkg/streamd/grpc/goconv/action.go new file mode 100644 index 0000000..26d99b4 --- /dev/null +++ b/pkg/streamd/grpc/goconv/action.go @@ -0,0 +1,113 @@ +package goconv + +import ( + "fmt" + + "github.com/xaionaro-go/streamctl/pkg/expression" + "github.com/xaionaro-go/streamctl/pkg/streamcontrol" + "github.com/xaionaro-go/streamctl/pkg/streamd/config/action" + "github.com/xaionaro-go/streamctl/pkg/streamd/grpc/go/streamd_grpc" +) + +func ActionGRPC2Go( + actionGRPC *streamd_grpc.Action, +) (action.Action, error) { + var result action.Action + switch a := actionGRPC.ActionOneof.(type) { + case *streamd_grpc.Action_NoopRequest: + result = &action.Noop{} + case *streamd_grpc.Action_StartStreamRequest: + platID := streamcontrol.PlatformName(a.StartStreamRequest.PlatID) + profile, err := ProfileGRPC2Go(platID, a.StartStreamRequest.GetProfile()) + if err != nil { + return nil, err + } + result = &action.StartStream{ + PlatID: platID, + Title: a.StartStreamRequest.Title, + Description: a.StartStreamRequest.Description, + Profile: profile, + CustomArgs: nil, + } + case *streamd_grpc.Action_EndStreamRequest: + result = &action.EndStream{ + PlatID: streamcontrol.PlatformName(a.EndStreamRequest.PlatID), + } + case *streamd_grpc.Action_ObsAction: + switch o := a.ObsAction.OBSActionOneOf.(type) { + case *streamd_grpc.OBSAction_ElementShowHide: + result = &action.OBSElementShowHide{ + ElementName: o.ElementShowHide.ElementName, + ElementUUID: o.ElementShowHide.ElementUUID, + ValueExpression: expression.Expression(o.ElementShowHide.ValueExpression), + } + case *streamd_grpc.OBSAction_WindowCaptureSetSource: + result = &action.OBSWindowCaptureSetSource{ + ElementName: o.WindowCaptureSetSource.ElementName, + ElementUUID: o.WindowCaptureSetSource.ElementUUID, + ValueExpression: expression.Expression(o.WindowCaptureSetSource.ValueExpression), + } + default: + return nil, fmt.Errorf("unexpected OBS action type: %T", o) + } + default: + return nil, fmt.Errorf("unexpected action type: %T", a) + } + return result, nil +} + +func ActionGo2GRPC( + input action.Action, +) (*streamd_grpc.Action, error) { + result := streamd_grpc.Action{} + switch a := input.(type) { + case *action.Noop: + result.ActionOneof = &streamd_grpc.Action_NoopRequest{} + case *action.StartStream: + profileString, err := ProfileGo2GRPC(a.Profile) + if err != nil { + return nil, fmt.Errorf("unable to serialize the profile: %w", err) + } + result.ActionOneof = &streamd_grpc.Action_StartStreamRequest{ + StartStreamRequest: &streamd_grpc.StartStreamRequest{ + PlatID: string(a.PlatID), + Title: a.Title, + Description: a.Description, + Profile: profileString, + }, + } + case *action.EndStream: + result.ActionOneof = &streamd_grpc.Action_EndStreamRequest{ + EndStreamRequest: &streamd_grpc.EndStreamRequest{ + PlatID: string(a.PlatID), + }, + } + case *action.OBSElementShowHide: + result.ActionOneof = &streamd_grpc.Action_ObsAction{ + ObsAction: &streamd_grpc.OBSAction{ + OBSActionOneOf: &streamd_grpc.OBSAction_ElementShowHide{ + ElementShowHide: &streamd_grpc.OBSActionElementShowHide{ + ElementName: a.ElementName, + ElementUUID: a.ElementUUID, + ValueExpression: string(a.ValueExpression), + }, + }, + }, + } + case *action.OBSWindowCaptureSetSource: + result.ActionOneof = &streamd_grpc.Action_ObsAction{ + ObsAction: &streamd_grpc.OBSAction{ + OBSActionOneOf: &streamd_grpc.OBSAction_WindowCaptureSetSource{ + WindowCaptureSetSource: &streamd_grpc.OBSActionWindowCaptureSetSource{ + ElementName: a.ElementName, + ElementUUID: a.ElementUUID, + ValueExpression: string(a.ValueExpression), + }, + }, + }, + } + default: + return nil, fmt.Errorf("unknown action type: %T", a) + } + return &result, nil +} diff --git a/pkg/streamd/grpc/goconv/event.go b/pkg/streamd/grpc/goconv/event.go new file mode 100644 index 0000000..3c6c645 --- /dev/null +++ b/pkg/streamd/grpc/goconv/event.go @@ -0,0 +1,51 @@ +package goconv + +import ( + "fmt" + + "github.com/xaionaro-go/streamctl/pkg/streamd/config" + "github.com/xaionaro-go/streamctl/pkg/streamd/config/event" + "github.com/xaionaro-go/streamctl/pkg/streamd/grpc/go/streamd_grpc" +) + +func EventGo2GRPC(in event.Event) (*streamd_grpc.Event, error) { + switch q := in.(type) { + case *event.WindowFocusChange: + return &streamd_grpc.Event{ + EventOneOf: &streamd_grpc.Event_WindowFocusChange{ + WindowFocusChange: triggerGo2GRPCWindowFocusChange(q), + }, + }, nil + default: + return nil, fmt.Errorf("conversion of type %T is not implemented, yet", q) + } +} + +func triggerGo2GRPCWindowFocusChange(q *event.WindowFocusChange) *streamd_grpc.EventWindowFocusChange { + return &streamd_grpc.EventWindowFocusChange{ + WindowID: q.WindowID, + WindowTitle: q.WindowTitle, + WindowTitlePartial: q.WindowTitlePartial, + UserID: q.UserID, + } +} + +func EventGRPC2Go(in *streamd_grpc.Event) (config.Event, error) { + switch q := in.EventOneOf.(type) { + case *streamd_grpc.Event_WindowFocusChange: + return triggerGRPC2GoWindowFocusChange(q.WindowFocusChange), nil + default: + return nil, fmt.Errorf("conversion of type %T is not implemented, yet", q) + } +} + +func triggerGRPC2GoWindowFocusChange( + q *streamd_grpc.EventWindowFocusChange, +) config.Event { + return &event.WindowFocusChange{ + WindowID: q.WindowID, + WindowTitle: q.WindowTitle, + WindowTitlePartial: q.WindowTitlePartial, + UserID: q.UserID, + } +} diff --git a/pkg/streamd/grpc/goconv/event_query.go b/pkg/streamd/grpc/goconv/event_query.go new file mode 100644 index 0000000..3fb0cea --- /dev/null +++ b/pkg/streamd/grpc/goconv/event_query.go @@ -0,0 +1,55 @@ +package goconv + +import ( + "fmt" + + "github.com/xaionaro-go/streamctl/pkg/streamd/config" + "github.com/xaionaro-go/streamctl/pkg/streamd/config/event" + "github.com/xaionaro-go/streamctl/pkg/streamd/config/event/eventquery" + "github.com/xaionaro-go/streamctl/pkg/streamd/grpc/go/streamd_grpc" +) + +func EventQueryGo2GRPC(in eventquery.EventQuery) (*streamd_grpc.EventQuery, error) { + switch q := in.(type) { + case *eventquery.Event: + ev, err := EventGo2GRPC(q.Value) + if err != nil { + return nil, fmt.Errorf("unable to convert event: %w", err) + } + return &streamd_grpc.EventQuery{ + EventQueryOneOf: &streamd_grpc.EventQuery_Event{ + Event: ev, + }, + }, nil + case *eventquery.EventType[event.WindowFocusChange]: + return &streamd_grpc.EventQuery{ + EventQueryOneOf: &streamd_grpc.EventQuery_EventType{ + EventType: streamd_grpc.EventType_eventWindowFocusChange, + }, + }, nil + default: + return nil, fmt.Errorf("conversion of type %T is not implemented, yet", q) + } +} + +func EventQueryGRPC2Go(in *streamd_grpc.EventQuery) (config.EventQuery, error) { + switch q := in.GetEventQueryOneOf().(type) { + case *streamd_grpc.EventQuery_Event: + ev, err := EventGRPC2Go(q.Event) + if err != nil { + return nil, fmt.Errorf("unable to convert event: %w", err) + } + return &eventquery.Event{ + Value: ev, + }, nil + case *streamd_grpc.EventQuery_EventType: + switch q.EventType { + case streamd_grpc.EventType_eventWindowFocusChange: + return &eventquery.EventType[event.WindowFocusChange]{}, nil + default: + return nil, fmt.Errorf("unable to convert event type %v", q.EventType) + } + default: + return nil, fmt.Errorf("conversion of type %T is not implemented, yet", q) + } +} diff --git a/pkg/streamd/grpc/goconv/timer_action.go b/pkg/streamd/grpc/goconv/timer_action.go deleted file mode 100644 index f2d99bb..0000000 --- a/pkg/streamd/grpc/goconv/timer_action.go +++ /dev/null @@ -1,67 +0,0 @@ -package goconv - -import ( - "fmt" - - "github.com/xaionaro-go/streamctl/pkg/streamcontrol" - "github.com/xaionaro-go/streamctl/pkg/streamd/api" - "github.com/xaionaro-go/streamctl/pkg/streamd/grpc/go/streamd_grpc" -) - -func ActionGRPC2Go(actionGRPC *streamd_grpc.Action) (api.TimerAction, error) { - var action api.TimerAction - switch actionRaw := actionGRPC.ActionOneof.(type) { - case *streamd_grpc.Action_NoopRequest: - action = &api.TimerActionNoop{} - case *streamd_grpc.Action_StartStreamRequest: - platID := streamcontrol.PlatformName(actionRaw.StartStreamRequest.PlatID) - profile, err := ProfileGRPC2Go(platID, actionRaw.StartStreamRequest.GetProfile()) - if err != nil { - return nil, err - } - action = &api.TimerActionStartStream{ - PlatID: platID, - Title: actionRaw.StartStreamRequest.Title, - Description: actionRaw.StartStreamRequest.Description, - Profile: profile, - CustomArgs: nil, - } - case *streamd_grpc.Action_EndStreamRequest: - action = &api.TimerActionEndStream{ - PlatID: streamcontrol.PlatformName(actionRaw.EndStreamRequest.PlatID), - } - default: - return nil, fmt.Errorf("unexpected timer action: %T", actionRaw) - } - return action, nil -} - -func ActionGo2GRPC(action api.TimerAction) (*streamd_grpc.Action, error) { - resultAction := streamd_grpc.Action{} - switch action := action.(type) { - case *api.TimerActionNoop: - resultAction.ActionOneof = &streamd_grpc.Action_NoopRequest{} - case *api.TimerActionStartStream: - profileString, err := ProfileGo2GRPC(action.Profile) - if err != nil { - return nil, fmt.Errorf("unable to serialize the profile: %w", err) - } - resultAction.ActionOneof = &streamd_grpc.Action_StartStreamRequest{ - StartStreamRequest: &streamd_grpc.StartStreamRequest{ - PlatID: string(action.PlatID), - Title: action.Title, - Description: action.Description, - Profile: profileString, - }, - } - case *api.TimerActionEndStream: - resultAction.ActionOneof = &streamd_grpc.Action_EndStreamRequest{ - EndStreamRequest: &streamd_grpc.EndStreamRequest{ - PlatID: string(action.PlatID), - }, - } - default: - return nil, fmt.Errorf("unknown action type: %T", action) - } - return &resultAction, nil -} diff --git a/pkg/streamd/grpc/goconv/trigger_rule.go b/pkg/streamd/grpc/goconv/trigger_rule.go new file mode 100644 index 0000000..51e1061 --- /dev/null +++ b/pkg/streamd/grpc/goconv/trigger_rule.go @@ -0,0 +1,50 @@ +package goconv + +import ( + "fmt" + + "github.com/xaionaro-go/streamctl/pkg/streamd/api" + "github.com/xaionaro-go/streamctl/pkg/streamd/grpc/go/streamd_grpc" +) + +func TriggerRuleGo2GRPC( + rule *api.TriggerRule, +) (*streamd_grpc.TriggerRule, error) { + resultEventQuery, err := EventQueryGo2GRPC( + rule.EventQuery, + ) + if err != nil { + return nil, fmt.Errorf("unable to convert the trigger query: %w", err) + } + + resultAction, err := ActionGo2GRPC(rule.Action) + if err != nil { + return nil, fmt.Errorf("unable to convert the action: %w", err) + } + + return &streamd_grpc.TriggerRule{ + Description: rule.Description, + EventQuery: resultEventQuery, + Action: resultAction, + }, nil +} + +func TriggerRuleGRPC2Go( + rule *streamd_grpc.TriggerRule, +) (*api.TriggerRule, error) { + resultEventQuery, err := EventQueryGRPC2Go(rule.GetEventQuery()) + if err != nil { + return nil, fmt.Errorf("unable to convert the trigger query: %w", err) + } + + resultAction, err := ActionGRPC2Go(rule.GetAction()) + if err != nil { + return nil, fmt.Errorf("unable to convert the action: %w", err) + } + + return &api.TriggerRule{ + Description: rule.GetDescription(), + EventQuery: resultEventQuery, + Action: resultAction, + }, nil +} diff --git a/pkg/streamd/grpc/streamd.proto b/pkg/streamd/grpc/streamd.proto index fbc97b2..b872b82 100644 --- a/pkg/streamd/grpc/streamd.proto +++ b/pkg/streamd/grpc/streamd.proto @@ -79,6 +79,13 @@ service StreamD { rpc AddTimer(AddTimerRequest) returns (AddTimerReply) {} rpc RemoveTimer(RemoveTimerRequest) returns (RemoveTimerReply) {} rpc ListTimers(ListTimersRequest) returns (ListTimersReply) {} + + rpc ListTriggerRules(ListTriggerRulesRequest) returns (ListTriggerRulesReply) {} + rpc AddTriggerRule(AddTriggerRuleRequest) returns (AddTriggerRuleReply) {} + rpc RemoveTriggerRule(RemoveTriggerRuleRequest) returns (RemoveTriggerRuleReply) {} + rpc UpdateTriggerRule(UpdateTriggerRuleRequest) returns (UpdateTriggerRuleReply) {} + + rpc SubmitEvent(SubmitEventRequest) returns (SubmitEventReply) {} } message PingRequest { @@ -534,11 +541,31 @@ message StreamPlayersChange {} message NoopRequest {} +message OBSActionElementShowHide { + optional string elementName = 1; + optional string elementUUID = 2; + string valueExpression = 3; +} + +message OBSActionWindowCaptureSetSource { + optional string elementName = 1; + optional string elementUUID = 2; + string valueExpression = 3; +} + +message OBSAction { + oneof OBSActionOneOf { + OBSActionElementShowHide elementShowHide = 1; + OBSActionWindowCaptureSetSource windowCaptureSetSource = 2; + } +} + message Action { oneof ActionOneof { NoopRequest noopRequest = 1; StartStreamRequest startStreamRequest = 2; EndStreamRequest endStreamRequest = 3; + OBSAction obsAction = 4; } } @@ -565,3 +592,79 @@ message ListTimersRequest {} message ListTimersReply { repeated Timer timers = 1; } + +message EventQueryAnd { + repeated Event queries = 1; +} + +message EventQueryOr { + repeated Event queries = 1; +} + +message EventQueryNot { + Event query = 1; +} + +message EventOBSSceneChange { + string sceneName = 1; +} + +message EventWindowFocusChange { + optional uint64 windowID = 1; + optional string windowTitle = 2; + optional string windowTitlePartial = 3; + optional uint64 userID = 4; +} + +message EventQuery { + oneof EventQueryOneOf { + EventQueryAnd and = 1; + EventQueryOr or = 2; + EventQueryNot not = 3; + EventType eventType = 4; + Event event = 5; + } +} + +enum EventType { + eventWindowFocusChange = 0; + eventOBSSceneChange = 1; +} + +message Event { + oneof EventOneOf { + EventOBSSceneChange obsSceneChange = 1; + EventWindowFocusChange windowFocusChange = 2; + } +} + +message TriggerRule { + string Description = 1; + EventQuery eventQuery = 2; + Action action = 3; +} + +message ListTriggerRulesRequest {} +message ListTriggerRulesReply { + repeated TriggerRule rules = 1; +} +message AddTriggerRuleRequest { + TriggerRule rule = 1; +} +message AddTriggerRuleReply { + uint64 ruleID = 1; +} +message RemoveTriggerRuleRequest { + uint64 ruleID = 1; +} +message RemoveTriggerRuleReply {} +message UpdateTriggerRuleRequest { + uint64 ruleID = 1; + TriggerRule rule = 2; +} +message UpdateTriggerRuleReply {} + +message SubmitEventRequest { + Event event = 1; +} +message SubmitEventReply {} diff --git a/pkg/streamd/obs.go b/pkg/streamd/obs.go new file mode 100644 index 0000000..86c1c7e --- /dev/null +++ b/pkg/streamd/obs.go @@ -0,0 +1,174 @@ +package streamd + +import ( + "bytes" + "context" + "fmt" + "time" + + "github.com/andreykaipov/goobs" + "github.com/chai2010/webp" + "github.com/facebookincubator/go-belt/tool/logger" + "github.com/xaionaro-go/obs-grpc-proxy/pkg/obsgrpcproxy" + "github.com/xaionaro-go/obs-grpc-proxy/protobuf/go/obs_grpc" + "github.com/xaionaro-go/streamctl/pkg/observability" + "github.com/xaionaro-go/streamctl/pkg/streamcontrol/obs" + "github.com/xaionaro-go/streamctl/pkg/streamd/config" + "github.com/xaionaro-go/streamctl/pkg/streamd/consts" + "github.com/xaionaro-go/streamctl/pkg/streamtypes" + "github.com/xaionaro-go/streamctl/pkg/xsync" +) + +func (d *StreamD) OBS( + ctx context.Context, +) (obs_grpc.OBSServer, context.CancelFunc, error) { + logger.Tracef(ctx, "OBS()") + defer logger.Tracef(ctx, "/OBS()") + + proxy := obsgrpcproxy.New( + ctx, + func(ctx context.Context) (*goobs.Client, context.CancelFunc, error) { + logger.Tracef(ctx, "OBS proxy getting client") + defer logger.Tracef(ctx, "/OBS proxy getting client") + obs := xsync.RDoR1(ctx, &d.ControllersLocker, func() *obs.OBS { + return d.StreamControllers.OBS + }) + if obs == nil { + return nil, nil, fmt.Errorf("connection to OBS is not initialized") + } + + client, err := obs.GetClient() + logger.Tracef(ctx, "getting OBS client result: %v %v", client, err) + if err != nil { + return nil, nil, err + } + + return client, func() { + err := client.Disconnect() + if err != nil { + logger.Errorf(ctx, "unable to disconnect from OBS: %w", err) + } else { + logger.Tracef(ctx, "disconnected from OBS") + } + }, nil + }, + ) + return proxy, func() {}, nil +} + +func getOBSImageBytes( + ctx context.Context, + obsServer obs_grpc.OBSServer, + el config.MonitorElementConfig, + obsState *streamtypes.OBSState, +) ([]byte, time.Time, error) { + img, nextUpdateAt, err := el.Source.GetImage(ctx, obsServer, el, obsState) + if err != nil { + return nil, time.Now(). + Add(time.Second), + fmt.Errorf( + "unable to get the image from the source: %w", + err, + ) + } + + for _, filter := range el.Filters { + img = filter.Filter(ctx, img) + } + + var out bytes.Buffer + err = webp.Encode(&out, img, &webp.Options{ + Lossless: el.ImageLossless, + Quality: float32(el.ImageQuality), + Exact: false, + }) + if err != nil { + return nil, time.Now().Add(time.Second), fmt.Errorf("unable to encode the image: %w", err) + } + + return out.Bytes(), nextUpdateAt, nil +} + +func (d *StreamD) initImageTaker(ctx context.Context) error { + for elName, el := range d.Config.Monitor.Elements { + if el.Source == nil { + continue + } + if _, ok := el.Source.(*config.MonitorSourceDummy); ok { + continue + } + { + elName, el := elName, el + _ = el + observability.Go(ctx, func() { + logger.Debugf(ctx, "taker of image '%s'", elName) + defer logger.Debugf(ctx, "/taker of image '%s'", elName) + + obsServer, obsServerClose, err := d.OBS(ctx) + if obsServerClose != nil { + defer obsServerClose() + } + if err != nil { + logger.Errorf(ctx, "unable to init connection with OBS: %w", err) + return + } + + for { + var ( + imgBytes []byte + nextUpdateAt time.Time + err error + ) + + waitUntilNextIteration := func() bool { + if nextUpdateAt.IsZero() { + return false + } + select { + case <-ctx.Done(): + return false + case <-time.After(time.Until(nextUpdateAt)): + return true + } + } + + imgBytes, nextUpdateAt, err = getOBSImageBytes(ctx, obsServer, el, &d.OBSState) + if err != nil { + logger.Errorf(ctx, "unable to get the image of '%s': %v", elName, err) + if !waitUntilNextIteration() { + return + } + continue + } + + err = d.SetVariable(ctx, consts.VarKeyImage(consts.ImageID(elName)), imgBytes) + if err != nil { + logger.Errorf(ctx, "unable to save the image of '%s': %w", elName, err) + if !waitUntilNextIteration() { + return + } + continue + } + + if !waitUntilNextIteration() { + return + } + } + }) + } + } + return nil +} + +type SceneElementIdentifier struct { + Name *string + UUID *string +} + +func (d *StreamD) OBSElementSetShow( + ctx context.Context, + elID SceneElementIdentifier, + shouldShow bool, +) error { + return fmt.Errorf("not implemented, yet") +} diff --git a/pkg/streamd/server/grpc.go b/pkg/streamd/server/grpc.go index 8fb187d..ea4c27f 100644 --- a/pkg/streamd/server/grpc.go +++ b/pkg/streamd/server/grpc.go @@ -69,9 +69,15 @@ func (grpc *GRPCServer) Ping( ) (*streamd_grpc.PingReply, error) { var payload strings.Builder extraSize := req.GetRequestExtraPayloadSize() - totalSize := len(req.GetPayloadToReturn()) + int(extraSize) + totalSize := len( + req.GetPayloadToReturn(), + ) + int( + extraSize, + ) if totalSize > 65535 { - return nil, fmt.Errorf("requested a too big payload") + return nil, fmt.Errorf( + "requested a too big payload", + ) } payload.WriteString(req.GetPayloadToReturn()) payload.WriteString(strings.Repeat("0", int(extraSize))) @@ -83,9 +89,13 @@ func (grpc *GRPCServer) Ping( func (grpc *GRPCServer) Close() error { err := &multierror.Error{} ctx := context.TODO() - hs := xsync.DoR1(ctx, &grpc.OAuthURLHandlerLocker, func() oauthURLHandlers { - return grpc.OAuthURLHandlers - }) + hs := xsync.DoR1( + ctx, + &grpc.OAuthURLHandlerLocker, + func() oauthURLHandlers { + return grpc.OAuthURLHandlers + }, + ) for listenPort, sender := range hs { _ = sender // TODO: invent sender.Close() delete(grpc.OAuthURLHandlers, listenPort) @@ -93,7 +103,9 @@ func (grpc *GRPCServer) Close() error { return err.ErrorOrNil() } -func (grpc *GRPCServer) invalidateCache(ctx context.Context) { +func (grpc *GRPCServer) invalidateCache( + ctx context.Context, +) { grpc.MemoizeDataValue.InvalidateCache(ctx) } @@ -101,9 +113,15 @@ func (grpc *GRPCServer) SetLoggingLevel( ctx context.Context, req *streamd_grpc.SetLoggingLevelRequest, ) (*streamd_grpc.SetLoggingLevelReply, error) { - err := grpc.StreamD.SetLoggingLevel(ctx, goconv.LoggingLevelGRPC2Go(req.GetLoggingLevel())) + err := grpc.StreamD.SetLoggingLevel( + ctx, + goconv.LoggingLevelGRPC2Go(req.GetLoggingLevel()), + ) if err != nil { - return nil, fmt.Errorf("unable to set the logging level: %w", err) + return nil, fmt.Errorf( + "unable to set the logging level: %w", + err, + ) } return &streamd_grpc.SetLoggingLevelReply{}, nil } @@ -114,7 +132,10 @@ func (grpc *GRPCServer) GetLoggingLevel( ) (*streamd_grpc.GetLoggingLevelReply, error) { level, err := grpc.StreamD.GetLoggingLevel(ctx) if err != nil { - return nil, fmt.Errorf("unable to query the logging level: %w", err) + return nil, fmt.Errorf( + "unable to query the logging level: %w", + err, + ) } return &streamd_grpc.GetLoggingLevelReply{ LoggingLevel: goconv.LoggingLevelGo2GRPC(level), @@ -127,12 +148,18 @@ func (grpc *GRPCServer) GetConfig( ) (*streamd_grpc.GetConfigReply, error) { cfg, err := grpc.StreamD.GetConfig(ctx) if err != nil { - return nil, fmt.Errorf("unable to get the config: %w", err) + return nil, fmt.Errorf( + "unable to get the config: %w", + err, + ) } var buf bytes.Buffer _, err = cfg.WriteTo(&buf) if err != nil { - return nil, fmt.Errorf("unable to serialize the config: %w", err) + return nil, fmt.Errorf( + "unable to serialize the config: %w", + err, + ) } return &streamd_grpc.GetConfigReply{ Config: buf.String(), @@ -149,12 +176,18 @@ func (grpc *GRPCServer) SetConfig( var result config.Config _, err := result.Read([]byte(req.Config)) if err != nil { - return nil, fmt.Errorf("unable to unserialize the config: %w", err) + return nil, fmt.Errorf( + "unable to unserialize the config: %w", + err, + ) } err = grpc.StreamD.SetConfig(ctx, &result) if err != nil { - return nil, fmt.Errorf("unable to set the config: %w", err) + return nil, fmt.Errorf( + "unable to set the config: %w", + err, + ) } grpc.invalidateCache(ctx) @@ -167,7 +200,10 @@ func (grpc *GRPCServer) SaveConfig( ) (*streamd_grpc.SaveConfigReply, error) { err := grpc.StreamD.SaveConfig(ctx) if err != nil { - return nil, fmt.Errorf("unable to save the config: %w", err) + return nil, fmt.Errorf( + "unable to save the config: %w", + err, + ) } grpc.invalidateCache(ctx) return &streamd_grpc.SaveConfigReply{}, nil @@ -179,7 +215,10 @@ func (grpc *GRPCServer) ResetCache( ) (*streamd_grpc.ResetCacheReply, error) { err := grpc.StreamD.ResetCache(ctx) if err != nil { - return nil, fmt.Errorf("unable to reset the cache: %w", err) + return nil, fmt.Errorf( + "unable to reset the cache: %w", + err, + ) } grpc.invalidateCache(ctx) return &streamd_grpc.ResetCacheReply{}, nil @@ -191,7 +230,10 @@ func (grpc *GRPCServer) InitCache( ) (*streamd_grpc.InitCacheReply, error) { err := grpc.StreamD.InitCache(ctx) if err != nil { - return nil, fmt.Errorf("unable to init the cache: %w", err) + return nil, fmt.Errorf( + "unable to init the cache: %w", + err, + ) } grpc.invalidateCache(ctx) return &streamd_grpc.InitCacheReply{}, nil @@ -201,14 +243,25 @@ func (grpc *GRPCServer) StartStream( ctx context.Context, req *streamd_grpc.StartStreamRequest, ) (*streamd_grpc.StartStreamReply, error) { - logger.Debugf(ctx, "grpc:StartStream: raw profile: %#+v", req.Profile) + logger.Debugf( + ctx, + "grpc:StartStream: raw profile: %#+v", + req.Profile, + ) platID := streamcontrol.PlatformName(req.GetPlatID()) - profile, err := goconv.ProfileGRPC2Go(platID, req.GetProfile()) + profile, err := goconv.ProfileGRPC2Go( + platID, + req.GetProfile(), + ) if err != nil { return nil, err } - logger.Debugf(ctx, "grpc:StartStream: parsed: %#+v", profile) + logger.Debugf( + ctx, + "grpc:StartStream: parsed: %#+v", + profile, + ) err = grpc.StreamD.StartStream( ctx, @@ -218,7 +271,10 @@ func (grpc *GRPCServer) StartStream( profile, ) if err != nil { - return nil, fmt.Errorf("unable to start the stream: %w", err) + return nil, fmt.Errorf( + "unable to start the stream: %w", + err, + ) } grpc.invalidateCache(ctx) @@ -229,9 +285,15 @@ func (grpc *GRPCServer) EndStream( ctx context.Context, req *streamd_grpc.EndStreamRequest, ) (*streamd_grpc.EndStreamReply, error) { - err := grpc.StreamD.EndStream(ctx, streamcontrol.PlatformName(req.GetPlatID())) + err := grpc.StreamD.EndStream( + ctx, + streamcontrol.PlatformName(req.GetPlatID()), + ) if err != nil { - return nil, fmt.Errorf("unable to end the stream: %w", err) + return nil, fmt.Errorf( + "unable to end the stream: %w", + err, + ) } grpc.invalidateCache(ctx) return &streamd_grpc.EndStreamReply{}, nil @@ -241,7 +303,10 @@ func (grpc *GRPCServer) IsBackendEnabled( ctx context.Context, req *streamd_grpc.IsBackendEnabledRequest, ) (*streamd_grpc.IsBackendEnabledReply, error) { - enabled, err := grpc.StreamD.IsBackendEnabled(ctx, streamcontrol.PlatformName(req.GetPlatID())) + enabled, err := grpc.StreamD.IsBackendEnabled( + ctx, + streamcontrol.PlatformName(req.GetPlatID()), + ) if err != nil { return nil, fmt.Errorf( "unable to check if backend '%s' is enabled: %w", @@ -259,17 +324,29 @@ func (grpc *GRPCServer) GetBackendInfo( req *streamd_grpc.GetBackendInfoRequest, ) (*streamd_grpc.GetBackendInfoReply, error) { platID := streamcontrol.PlatformName(req.GetPlatID()) - isEnabled, err := grpc.StreamD.IsBackendEnabled(ctx, platID) + isEnabled, err := grpc.StreamD.IsBackendEnabled( + ctx, + platID, + ) if err != nil { - return nil, fmt.Errorf("unable to check if the backend is enabled: %w", err) + return nil, fmt.Errorf( + "unable to check if the backend is enabled: %w", + err, + ) } data, err := grpc.StreamD.GetBackendData(ctx, platID) if err != nil { - return nil, fmt.Errorf("unable to get the backend info: %w", err) + return nil, fmt.Errorf( + "unable to get the backend info: %w", + err, + ) } dataSerialized, err := json.Marshal(data) if err != nil { - return nil, fmt.Errorf("unable to serialize the backend info: %w", err) + return nil, fmt.Errorf( + "unable to serialize the backend info: %w", + err, + ) } return &streamd_grpc.GetBackendInfoReply{ @@ -327,14 +404,26 @@ func (grpc *GRPCServer) ApplyProfile( platID := streamcontrol.PlatformName(req.GetPlatID()) profile, err := platcollection.NewStreamProfile(platID) if err != nil { - return nil, fmt.Errorf("unable to build a profile for platform '%s': %w", platID, err) + return nil, fmt.Errorf( + "unable to build a profile for platform '%s': %w", + platID, + err, + ) } err = yaml.Unmarshal([]byte(req.GetProfile()), profile) if err != nil { - return nil, fmt.Errorf("unable to unserialize the profile '%s': %w", req.GetProfile(), err) + return nil, fmt.Errorf( + "unable to unserialize the profile '%s': %w", + req.GetProfile(), + err, + ) } - logger.Debugf(ctx, "unserialized profile: %#+v", profile) + logger.Debugf( + ctx, + "unserialized profile: %#+v", + profile, + ) err = grpc.StreamD.ApplyProfile( ctx, @@ -342,7 +431,11 @@ func (grpc *GRPCServer) ApplyProfile( profile, ) if err != nil { - return nil, fmt.Errorf("unable to apply the profile %#+v: %w", profile, err) + return nil, fmt.Errorf( + "unable to apply the profile %#+v: %w", + profile, + err, + ) } return &streamd_grpc.ApplyProfileReply{}, nil } @@ -354,14 +447,26 @@ func (grpc *GRPCServer) UpdateStream( platID := streamcontrol.PlatformName(req.GetPlatID()) profile, err := platcollection.NewStreamProfile(platID) if err != nil { - return nil, fmt.Errorf("unable to build a profile for platform '%s': %w", platID, err) + return nil, fmt.Errorf( + "unable to build a profile for platform '%s': %w", + platID, + err, + ) } err = yaml.Unmarshal([]byte(req.GetProfile()), profile) if err != nil { - return nil, fmt.Errorf("unable to unserialize the profile '%s': %w", req.GetProfile(), err) + return nil, fmt.Errorf( + "unable to unserialize the profile '%s': %w", + req.GetProfile(), + err, + ) } - logger.Debugf(ctx, "unserialized profile: %#+v", profile) + logger.Debugf( + ctx, + "unserialized profile: %#+v", + profile, + ) err = grpc.StreamD.UpdateStream( ctx, @@ -371,7 +476,10 @@ func (grpc *GRPCServer) UpdateStream( profile, ) if err != nil { - return nil, fmt.Errorf("unable to update stream details: %w", err) + return nil, fmt.Errorf( + "unable to update stream details: %w", + err, + ) } return &streamd_grpc.UpdateStreamReply{}, nil } @@ -380,9 +488,14 @@ func (grpc *GRPCServer) EXPERIMENTAL_ReinitStreamControllers( ctx context.Context, in *streamd_grpc.EXPERIMENTAL_ReinitStreamControllersRequest, ) (*streamd_grpc.EXPERIMENTAL_ReinitStreamControllersReply, error) { - err := grpc.StreamD.EXPERIMENTAL_ReinitStreamControllers(ctx) + err := grpc.StreamD.EXPERIMENTAL_ReinitStreamControllers( + ctx, + ) if err != nil { - return nil, fmt.Errorf("StreamD returned an error: %w", err) + return nil, fmt.Errorf( + "StreamD returned an error: %w", + err, + ) } return &streamd_grpc.EXPERIMENTAL_ReinitStreamControllersReply{}, nil @@ -394,7 +507,10 @@ func (grpc *GRPCServer) OBSOLETE_FetchConfig( ) (*streamd_grpc.OBSOLETE_FetchConfigReply, error) { err := grpc.StreamD.FetchConfig(ctx) if err != nil { - return nil, fmt.Errorf("unable to fetch the config: %w", err) + return nil, fmt.Errorf( + "unable to fetch the config: %w", + err, + ) } grpc.invalidateCache(ctx) return &streamd_grpc.OBSOLETE_FetchConfigReply{}, nil @@ -404,9 +520,14 @@ func (grpc *GRPCServer) OBSOLETE_GitInfo( ctx context.Context, req *streamd_grpc.OBSOLETE_GetGitInfoRequest, ) (*streamd_grpc.OBSOLETE_GetGitInfoReply, error) { - isEnabled, err := grpc.StreamD.OBSOLETE_IsGITInitialized(ctx) + isEnabled, err := grpc.StreamD.OBSOLETE_IsGITInitialized( + ctx, + ) if err != nil { - return nil, fmt.Errorf("unable to get the git info: %w", err) + return nil, fmt.Errorf( + "unable to get the git info: %w", + err, + ) } return &streamd_grpc.OBSOLETE_GetGitInfoReply{ IsInitialized: isEnabled, @@ -437,9 +558,16 @@ func (grpc *GRPCServer) GetStreamStatus( } platID := streamcontrol.PlatformName(req.GetPlatID()) - streamStatus, err := grpc.StreamD.GetStreamStatus(ctx, platID) + streamStatus, err := grpc.StreamD.GetStreamStatus( + ctx, + platID, + ) if err != nil { - return nil, fmt.Errorf("unable to get the stream status of '%s': %w", platID, err) + return nil, fmt.Errorf( + "unable to get the stream status of '%s': %w", + platID, + err, + ) } var startedAt *int64 @@ -449,9 +577,14 @@ func (grpc *GRPCServer) GetStreamStatus( var customData string if streamStatus.CustomData != nil { - customDataSerialized, err := json.Marshal(streamStatus.CustomData) + customDataSerialized, err := json.Marshal( + streamStatus.CustomData, + ) if err != nil { - return nil, fmt.Errorf("unable to serialize the custom data: %w", err) + return nil, fmt.Errorf( + "unable to serialize the custom data: %w", + err, + ) } customData = string(customDataSerialized) } @@ -470,10 +603,18 @@ func (grpc *GRPCServer) SubscribeToOAuthRequests( ctx, cancelFn := context.WithCancel(sender.Context()) _uuid, err := uuid.NewRandom() if err != nil { - logger.Errorf(ctx, "unable to generate an UUID: %v", err) + logger.Errorf( + ctx, + "unable to generate an UUID: %v", + err, + ) } - logger.Tracef(sender.Context(), "SubscribeToOAuthRequests(): UUID:%s", _uuid) + logger.Tracef( + sender.Context(), + "SubscribeToOAuthRequests(): UUID:%s", + _uuid, + ) defer func() { logger.Tracef(sender.Context(), "/SubscribeToOAuthRequests(): UUID:%s: %v", _uuid, _ret) }() listenPort := uint16(req.ListenPort) @@ -498,12 +639,19 @@ func (grpc *GRPCServer) SubscribeToOAuthRequests( if req == nil { continue } - unansweredRequests = append(unansweredRequests, req) + unansweredRequests = append( + unansweredRequests, + req, + ) } }) for _, req := range unansweredRequests { - logger.Tracef(ctx, "re-sending an unanswered request to a new client: %#+v", *req) + logger.Tracef( + ctx, + "re-sending an unanswered request to a new client: %#+v", + *req, + ) err := sender.Send(req) errmon.ObserveErrorCtx(ctx, err) } @@ -512,7 +660,10 @@ func (grpc *GRPCServer) SubscribeToOAuthRequests( streamD.AddOAuthListenPort(listenPort) } - logger.Tracef(ctx, "waiting for the subscription to be cancelled") + logger.Tracef( + ctx, + "waiting for the subscription to be cancelled", + ) <-ctx.Done() grpc.OAuthURLHandlerLocker.Do(ctx, func() { delete(grpc.OAuthURLHandlers[listenPort], _uuid) @@ -541,14 +692,28 @@ func (grpc *GRPCServer) OpenBrowser( ) (_ret error) { logger.Debugf(ctx, "OpenBrowser(ctx, '%s')", url) defer func() { - logger.Debugf(ctx, "/OpenBrowser(ctx, '%s'): %v", url, _ret) + logger.Debugf( + ctx, + "/OpenBrowser(ctx, '%s'): %v", + url, + _ret, + ) }() // TODO: Stop abusing the function for OAuthURLs here! Implement a separate function, or // at least rename the old one. - logger.Warnf(ctx, "FIXME: Do not use OAuthURLs for 'OpenBrowser'!") + logger.Warnf( + ctx, + "FIXME: Do not use OAuthURLs for 'OpenBrowser'!", + ) - return xsync.DoA2R1(ctx, &grpc.OAuthURLHandlerLocker, grpc.openBrowser, ctx, url) + return xsync.DoA2R1( + ctx, + &grpc.OAuthURLHandlerLocker, + grpc.openBrowser, + ctx, + url, + ) } func (grpc *GRPCServer) openBrowser( @@ -562,7 +727,11 @@ func (grpc *GRPCServer) openBrowser( count := 0 for _, handlers := range grpc.OAuthURLHandlers { - logger.Debugf(ctx, "OpenOAuthURL() sending %#+v", req) + logger.Debugf( + ctx, + "OpenOAuthURL() sending %#+v", + req, + ) var resultErr *multierror.Error for _, handler := range handlers { count++ @@ -570,7 +739,10 @@ func (grpc *GRPCServer) openBrowser( if err != nil { err = multierror.Append( resultErr, - fmt.Errorf("unable to send oauth request: %w", err), + fmt.Errorf( + "unable to send oauth request: %w", + err, + ), ) } } @@ -588,7 +760,13 @@ func (grpc *GRPCServer) OpenOAuthURL( platID streamcontrol.PlatformName, authURL string, ) (_ret error) { - logger.Debugf(ctx, "OpenOAuthURL(ctx, %d, '%s', '%s')", listenPort, platID, authURL) + logger.Debugf( + ctx, + "OpenOAuthURL(ctx, %d, '%s', '%s')", + listenPort, + platID, + authURL, + ) defer func() { logger.Debugf( ctx, @@ -638,7 +816,13 @@ func (grpc *GRPCServer) openOAuthURL( for _, handler := range handlers { err := handler.Sender.Send(&req) if err != nil { - err = multierror.Append(resultErr, fmt.Errorf("unable to send oauth request: %w", err)) + err = multierror.Append( + resultErr, + fmt.Errorf( + "unable to send oauth request: %w", + err, + ), + ) } } return resultErr.ErrorOrNil() @@ -651,7 +835,11 @@ func (grpc *GRPCServer) GetVariable( key := consts.VarKey(req.GetKey()) b, err := grpc.StreamD.GetVariable(ctx, key) if err != nil { - return nil, fmt.Errorf("unable to get variable '%s': %w", key, err) + return nil, fmt.Errorf( + "unable to get variable '%s': %w", + key, + err, + ) } return &streamd_grpc.GetVariableReply{ @@ -670,13 +858,24 @@ func (grpc *GRPCServer) GetVariableHash( case streamd_grpc.HashType_HASH_SHA1: hashType = crypto.SHA1 default: - return nil, fmt.Errorf("unexpected hash type: %v", hashTypeIn) + return nil, fmt.Errorf( + "unexpected hash type: %v", + hashTypeIn, + ) } key := consts.VarKey(req.GetKey()) - b, err := grpc.StreamD.GetVariableHash(ctx, key, hashType) + b, err := grpc.StreamD.GetVariableHash( + ctx, + key, + hashType, + ) if err != nil { - return nil, fmt.Errorf("unable to get variable '%s': %w", key, err) + return nil, fmt.Errorf( + "unable to get variable '%s': %w", + key, + err, + ) } return &streamd_grpc.GetVariableHashReply{ @@ -691,9 +890,17 @@ func (grpc *GRPCServer) SetVariable( req *streamd_grpc.SetVariableRequest, ) (*streamd_grpc.SetVariableReply, error) { key := consts.VarKey(req.GetKey()) - err := grpc.StreamD.SetVariable(ctx, key, req.GetValue()) + err := grpc.StreamD.SetVariable( + ctx, + key, + req.GetValue(), + ) if err != nil { - return nil, fmt.Errorf("unable to set variable '%s': %w", key, err) + return nil, fmt.Errorf( + "unable to set variable '%s': %w", + key, + err, + ) } return &streamd_grpc.SetVariableReply{}, nil @@ -704,7 +911,10 @@ func (grpc *GRPCServer) SubmitOAuthCode( req *streamd_grpc.SubmitOAuthCodeRequest, ) (*streamd_grpc.SubmitOAuthCodeReply, error) { grpc.UnansweredOAuthRequestsLocker.Do(ctx, func() { - delete(grpc.UnansweredOAuthRequests, streamcontrol.PlatformName(req.PlatID)) + delete( + grpc.UnansweredOAuthRequests, + streamcontrol.PlatformName(req.PlatID), + ) }) _, err := grpc.StreamD.SubmitOAuthCode(ctx, req) @@ -732,16 +942,26 @@ func (grpc *GRPCServer) ListStreamServers( srv.Options(), ) if err != nil { - return nil, fmt.Errorf("unable to convert the server server value: %w", err) + return nil, fmt.Errorf( + "unable to convert the server server value: %w", + err, + ) } - result = append(result, &streamd_grpc.StreamServerWithStatistics{ - Config: srvGRPC, - Statistics: &streamd_grpc.StreamServerStatistics{ - NumBytesConsumerWrote: int64(srv.NumBytesConsumerWrote), - NumBytesProducerRead: int64(srv.NumBytesProducerRead), + result = append( + result, + &streamd_grpc.StreamServerWithStatistics{ + Config: srvGRPC, + Statistics: &streamd_grpc.StreamServerStatistics{ + NumBytesConsumerWrote: int64( + srv.NumBytesConsumerWrote, + ), + NumBytesProducerRead: int64( + srv.NumBytesProducerRead, + ), + }, }, - }) + ) } return &streamd_grpc.ListStreamServersReply{ StreamServers: result, @@ -752,7 +972,10 @@ func (grpc *GRPCServer) StartStreamServer( ctx context.Context, req *streamd_grpc.StartStreamServerRequest, ) (*streamd_grpc.StartStreamServerReply, error) { - srvType, addr, opts, err := goconv.StreamServerConfigGRPC2Go(ctx, req.GetConfig()) + srvType, addr, opts, err := goconv.StreamServerConfigGRPC2Go( + ctx, + req.GetConfig(), + ) if err != nil { return nil, fmt.Errorf( "unable to convert the stream server config %#+v: %w", @@ -800,11 +1023,14 @@ func (grpc *GRPCServer) ListStreamDestinations( var result []*streamd_grpc.StreamDestination for _, dst := range dsts { - result = append(result, &streamd_grpc.StreamDestination{ - DestinationID: string(dst.ID), - Url: dst.URL, - StreamKey: dst.StreamKey, - }) + result = append( + result, + &streamd_grpc.StreamDestination{ + DestinationID: string(dst.ID), + Url: dst.URL, + StreamKey: dst.StreamKey, + }, + ) } return &streamd_grpc.ListStreamDestinationsReply{ StreamDestinations: result, @@ -817,7 +1043,9 @@ func (grpc *GRPCServer) AddStreamDestination( ) (*streamd_grpc.AddStreamDestinationReply, error) { err := grpc.StreamD.AddStreamDestination( ctx, - api.DestinationID(req.GetConfig().GetDestinationID()), + api.DestinationID( + req.GetConfig().GetDestinationID(), + ), req.GetConfig().GetUrl(), req.GetConfig().GetStreamKey(), ) @@ -833,7 +1061,9 @@ func (grpc *GRPCServer) UpdateStreamDestination( ) (*streamd_grpc.UpdateStreamDestinationReply, error) { err := grpc.StreamD.UpdateStreamDestination( ctx, - api.DestinationID(req.GetConfig().GetDestinationID()), + api.DestinationID( + req.GetConfig().GetDestinationID(), + ), req.GetConfig().GetUrl(), req.GetConfig().GetStreamKey(), ) @@ -861,7 +1091,10 @@ func (grpc *GRPCServer) AddIncomingStream( ctx context.Context, req *streamd_grpc.AddIncomingStreamRequest, ) (*streamd_grpc.AddIncomingStreamReply, error) { - err := grpc.StreamD.AddIncomingStream(ctx, api.StreamID(req.GetStreamID())) + err := grpc.StreamD.AddIncomingStream( + ctx, + api.StreamID(req.GetStreamID()), + ) if err != nil { return nil, err } @@ -872,7 +1105,10 @@ func (grpc *GRPCServer) RemoveIncomingStream( ctx context.Context, req *streamd_grpc.RemoveIncomingStreamRequest, ) (*streamd_grpc.RemoveIncomingStreamReply, error) { - err := grpc.StreamD.RemoveIncomingStream(ctx, api.StreamID(req.GetStreamID())) + err := grpc.StreamD.RemoveIncomingStream( + ctx, + api.StreamID(req.GetStreamID()), + ) if err != nil { return nil, err } @@ -892,9 +1128,12 @@ func (grpc *GRPCServer) ListIncomingStreams( var result []*streamd_grpc.IncomingStream for _, s := range inStreams { - result = append(result, &streamd_grpc.IncomingStream{ - StreamID: string(s.StreamID), - }) + result = append( + result, + &streamd_grpc.IncomingStream{ + StreamID: string(s.StreamID), + }, + ) } return &streamd_grpc.ListIncomingStreamsReply{ IncomingStreams: result, @@ -948,7 +1187,9 @@ func (grpc *GRPCServer) AddStreamForward( err := grpc.StreamD.AddStreamForward( ctx, api.StreamID(req.GetConfig().GetStreamID()), - api.DestinationID(req.GetConfig().GetDestinationID()), + api.DestinationID( + req.GetConfig().GetDestinationID(), + ), cfg.Enabled, api.StreamForwardingQuirks{ RestartUntilYoutubeRecognizesStream: api.RestartUntilYoutubeRecognizesStream{ @@ -979,7 +1220,9 @@ func (grpc *GRPCServer) UpdateStreamForward( err := grpc.StreamD.UpdateStreamForward( ctx, api.StreamID(req.GetConfig().GetStreamID()), - api.DestinationID(req.GetConfig().GetDestinationID()), + api.DestinationID( + req.GetConfig().GetDestinationID(), + ), cfg.Enabled, api.StreamForwardingQuirks{ RestartUntilYoutubeRecognizesStream: api.RestartUntilYoutubeRecognizesStream{ @@ -1009,7 +1252,9 @@ func (grpc *GRPCServer) RemoveStreamForward( err := grpc.StreamD.RemoveStreamForward( ctx, api.StreamID(req.GetConfig().GetStreamID()), - api.DestinationID(req.GetConfig().GetDestinationID()), + api.DestinationID( + req.GetConfig().GetDestinationID(), + ), ) if err != nil { return nil, err @@ -1022,9 +1267,18 @@ func (grpc *GRPCServer) WaitForStreamPublisher( sender streamd_grpc.StreamD_WaitForStreamPublisherServer, ) (_ret error) { ctx := sender.Context() - logger.Tracef(ctx, "WaitForStreamPublisher(): StreamID:%s", req.GetStreamID()) + logger.Tracef( + ctx, + "WaitForStreamPublisher(): StreamID:%s", + req.GetStreamID(), + ) defer func() { - logger.Tracef(ctx, "/WaitForStreamPublisher(): StreamID:%s: %v", req.GetStreamID(), _ret) + logger.Tracef( + ctx, + "/WaitForStreamPublisher(): StreamID:%s: %v", + req.GetStreamID(), + _ret, + ) }() ch, err := grpc.StreamD.WaitForStreamPublisher( @@ -1049,9 +1303,18 @@ func (grpc *GRPCServer) AddStreamPlayer( req *streamd_grpc.AddStreamPlayerRequest, ) (_ret *streamd_grpc.AddStreamPlayerReply, _err error) { cfg := req.GetConfig() - logger.Tracef(ctx, "AddStreamPlayer(): StreamID:%s", cfg.StreamID) + logger.Tracef( + ctx, + "AddStreamPlayer(): StreamID:%s", + cfg.StreamID, + ) defer func() { - logger.Tracef(ctx, "/AddStreamPlayer(): StreamID:%s: %v", cfg.StreamID, _err) + logger.Tracef( + ctx, + "/AddStreamPlayer(): StreamID:%s: %v", + cfg.StreamID, + _err, + ) }() err := grpc.StreamD.AddStreamPlayer( @@ -1059,7 +1322,9 @@ func (grpc *GRPCServer) AddStreamPlayer( streamtypes.StreamID(cfg.GetStreamID()), goconv.StreamPlayerTypeGRPC2Go(cfg.PlayerType), cfg.GetDisabled(), - goconv.StreamPlaybackConfigGRPC2Go(cfg.GetStreamPlaybackConfig()), + goconv.StreamPlaybackConfigGRPC2Go( + cfg.GetStreamPlaybackConfig(), + ), ) if err != nil { return nil, err @@ -1071,9 +1336,18 @@ func (grpc *GRPCServer) RemoveStreamPlayer( ctx context.Context, req *streamd_grpc.RemoveStreamPlayerRequest, ) (_req *streamd_grpc.RemoveStreamPlayerReply, _err error) { - logger.Tracef(ctx, "AddStreamPlayer(): StreamID:%s", req.GetStreamID()) + logger.Tracef( + ctx, + "AddStreamPlayer(): StreamID:%s", + req.GetStreamID(), + ) defer func() { - logger.Tracef(ctx, "/AddStreamPlayer(): StreamID:%s: %v", req.GetStreamID(), _err) + logger.Tracef( + ctx, + "/AddStreamPlayer(): StreamID:%s: %v", + req.GetStreamID(), + _err, + ) }() err := grpc.StreamD.RemoveStreamPlayer( @@ -1091,9 +1365,18 @@ func (grpc *GRPCServer) UpdateStreamPlayer( req *streamd_grpc.UpdateStreamPlayerRequest, ) (_req *streamd_grpc.UpdateStreamPlayerReply, _err error) { cfg := req.GetConfig() - logger.Debugf(ctx, "UpdateStreamPlayer(): StreamID:%s", cfg.StreamID) + logger.Debugf( + ctx, + "UpdateStreamPlayer(): StreamID:%s", + cfg.StreamID, + ) defer func() { - logger.Debugf(ctx, "/UpdateStreamPlayer(): StreamID:%s: %v", cfg.StreamID, _err) + logger.Debugf( + ctx, + "/UpdateStreamPlayer(): StreamID:%s: %v", + cfg.StreamID, + _err, + ) }() err := grpc.StreamD.UpdateStreamPlayer( @@ -1101,7 +1384,9 @@ func (grpc *GRPCServer) UpdateStreamPlayer( streamtypes.StreamID(cfg.GetStreamID()), goconv.StreamPlayerTypeGRPC2Go(cfg.PlayerType), cfg.GetDisabled(), - goconv.StreamPlaybackConfigGRPC2Go(cfg.GetStreamPlaybackConfig()), + goconv.StreamPlaybackConfigGRPC2Go( + cfg.GetStreamPlaybackConfig(), + ), ) if err != nil { return nil, err @@ -1117,14 +1402,25 @@ func (grpc *GRPCServer) ListStreamPlayers( if err != nil { return nil, err } - result := make([]*streamd_grpc.StreamPlayerConfig, 0, len(players)) + result := make( + []*streamd_grpc.StreamPlayerConfig, + 0, + len(players), + ) for _, player := range players { - result = append(result, &streamd_grpc.StreamPlayerConfig{ - StreamID: string(player.StreamID), - PlayerType: goconv.StreamPlayerTypeGo2GRPC(player.PlayerType), - Disabled: player.Disabled, - StreamPlaybackConfig: goconv.StreamPlaybackConfigGo2GRPC(&player.StreamPlaybackConfig), - }) + result = append( + result, + &streamd_grpc.StreamPlayerConfig{ + StreamID: string(player.StreamID), + PlayerType: goconv.StreamPlayerTypeGo2GRPC( + player.PlayerType, + ), + Disabled: player.Disabled, + StreamPlaybackConfig: goconv.StreamPlaybackConfigGo2GRPC( + &player.StreamPlaybackConfig, + ), + }, + ) } return &streamd_grpc.ListStreamPlayersReply{ Players: result, @@ -1134,16 +1430,23 @@ func (grpc *GRPCServer) GetStreamPlayer( ctx context.Context, req *streamd_grpc.GetStreamPlayerRequest, ) (*streamd_grpc.GetStreamPlayerReply, error) { - player, err := grpc.StreamD.GetStreamPlayer(ctx, streamtypes.StreamID(req.GetStreamID())) + player, err := grpc.StreamD.GetStreamPlayer( + ctx, + streamtypes.StreamID(req.GetStreamID()), + ) if err != nil { return nil, err } return &streamd_grpc.GetStreamPlayerReply{ Config: &streamd_grpc.StreamPlayerConfig{ - StreamID: string(player.StreamID), - PlayerType: goconv.StreamPlayerTypeGo2GRPC(player.PlayerType), - Disabled: player.Disabled, - StreamPlaybackConfig: goconv.StreamPlaybackConfigGo2GRPC(&player.StreamPlaybackConfig), + StreamID: string(player.StreamID), + PlayerType: goconv.StreamPlayerTypeGo2GRPC( + player.PlayerType, + ), + Disabled: player.Disabled, + StreamPlaybackConfig: goconv.StreamPlaybackConfigGo2GRPC( + &player.StreamPlaybackConfig, + ), }, }, nil } @@ -1185,7 +1488,10 @@ func (grpc *GRPCServer) StreamPlayerGetLink( ctx context.Context, req *streamd_grpc.StreamPlayerGetLinkRequest, ) (*streamd_grpc.StreamPlayerGetLinkReply, error) { - link, err := grpc.StreamD.StreamPlayerGetLink(ctx, streamtypes.StreamID(req.GetStreamID())) + link, err := grpc.StreamD.StreamPlayerGetLink( + ctx, + streamtypes.StreamID(req.GetStreamID()), + ) if err != nil { return nil, err } @@ -1201,7 +1507,10 @@ func (grpc *GRPCServer) StreamPlayerEndChan( ) error { ctx, cancelFn := context.WithCancel(srv.Context()) defer cancelFn() - ch, err := grpc.StreamD.StreamPlayerEndChan(ctx, streamtypes.StreamID(req.GetStreamID())) + ch, err := grpc.StreamD.StreamPlayerEndChan( + ctx, + streamtypes.StreamID(req.GetStreamID()), + ) if err != nil { return err } @@ -1218,7 +1527,10 @@ func (grpc *GRPCServer) StreamPlayerIsEnded( ctx context.Context, req *streamd_grpc.StreamPlayerIsEndedRequest, ) (*streamd_grpc.StreamPlayerIsEndedReply, error) { - isEnded, err := grpc.StreamD.StreamPlayerIsEnded(ctx, streamtypes.StreamID(req.GetStreamID())) + isEnded, err := grpc.StreamD.StreamPlayerIsEnded( + ctx, + streamtypes.StreamID(req.GetStreamID()), + ) if err != nil { return nil, err } @@ -1232,7 +1544,10 @@ func (grpc *GRPCServer) StreamPlayerGetPosition( ctx context.Context, req *streamd_grpc.StreamPlayerGetPositionRequest, ) (*streamd_grpc.StreamPlayerGetPositionReply, error) { - pos, err := grpc.StreamD.StreamPlayerGetPosition(ctx, streamtypes.StreamID(req.GetStreamID())) + pos, err := grpc.StreamD.StreamPlayerGetPosition( + ctx, + streamtypes.StreamID(req.GetStreamID()), + ) if err != nil { return nil, err } @@ -1246,7 +1561,10 @@ func (grpc *GRPCServer) StreamPlayerGetLength( ctx context.Context, req *streamd_grpc.StreamPlayerGetLengthRequest, ) (*streamd_grpc.StreamPlayerGetLengthReply, error) { - l, err := grpc.StreamD.StreamPlayerGetPosition(ctx, streamtypes.StreamID(req.GetStreamID())) + l, err := grpc.StreamD.StreamPlayerGetPosition( + ctx, + streamtypes.StreamID(req.GetStreamID()), + ) if err != nil { return nil, err } @@ -1292,7 +1610,10 @@ func (grpc *GRPCServer) StreamPlayerStop( ctx context.Context, req *streamd_grpc.StreamPlayerStopRequest, ) (*streamd_grpc.StreamPlayerStopReply, error) { - err := grpc.StreamD.StreamPlayerStop(ctx, streamtypes.StreamID(req.GetStreamID())) + err := grpc.StreamD.StreamPlayerStop( + ctx, + streamtypes.StreamID(req.GetStreamID()), + ) if err != nil { return nil, err } @@ -1304,7 +1625,10 @@ func (grpc *GRPCServer) StreamPlayerClose( ctx context.Context, req *streamd_grpc.StreamPlayerCloseRequest, ) (*streamd_grpc.StreamPlayerCloseReply, error) { - err := grpc.StreamD.StreamPlayerClose(ctx, streamtypes.StreamID(req.GetStreamID())) + err := grpc.StreamD.StreamPlayerClose( + ctx, + streamtypes.StreamID(req.GetStreamID()), + ) if err != nil { return nil, err } @@ -1339,7 +1663,11 @@ func wrapChan[T any, E any]( var result T err := sender.Send(&result) if err != nil { - return fmt.Errorf("unable to send %#+v: %w", result, err) + return fmt.Errorf( + "unable to send %#+v: %w", + result, + err, + ) } } } @@ -1371,6 +1699,7 @@ func (grpc *GRPCServer) SubscribeToStreamServersChanges( srv, ) } + func (grpc *GRPCServer) SubscribeToStreamDestinationsChanges( req *streamd_grpc.SubscribeToStreamDestinationsChangesRequest, srv streamd_grpc.StreamD_SubscribeToStreamDestinationsChangesServer, @@ -1414,16 +1743,29 @@ func (grpc *GRPCServer) AddTimer( req *streamd_grpc.AddTimerRequest, ) (*streamd_grpc.AddTimerReply, error) { triggerAtUnixNano := req.GetTriggerAtUnixNano() - triggerAt := time.Unix(triggerAtUnixNano/1000000000, triggerAtUnixNano%1000000000) + triggerAt := time.Unix( + triggerAtUnixNano/1000000000, + triggerAtUnixNano%1000000000, + ) action, err := goconv.ActionGRPC2Go(req.Action) if err != nil { - return nil, fmt.Errorf("unable to convert the action: %w", err) + return nil, fmt.Errorf( + "unable to convert the action: %w", + err, + ) } - timerID, err := grpc.StreamD.AddTimer(ctx, triggerAt, action) + timerID, err := grpc.StreamD.AddTimer( + ctx, + triggerAt, + action, + ) if err != nil { - return nil, fmt.Errorf("unable to add timer: %w", err) + return nil, fmt.Errorf( + "unable to add timer: %w", + err, + ) } return &streamd_grpc.AddTimerReply{ @@ -1434,7 +1776,10 @@ func (grpc *GRPCServer) RemoveTimer( ctx context.Context, req *streamd_grpc.RemoveTimerRequest, ) (*streamd_grpc.RemoveTimerReply, error) { - err := grpc.StreamD.RemoveTimer(ctx, api.TimerID(req.GetTimerID())) + err := grpc.StreamD.RemoveTimer( + ctx, + api.TimerID(req.GetTimerID()), + ) if err != nil { return nil, err } @@ -1451,9 +1796,14 @@ func (grpc *GRPCServer) ListTimers( var result []*streamd_grpc.Timer for _, timer := range timers { - resultAction, err := goconv.ActionGo2GRPC(timer.Action) + resultAction, err := goconv.ActionGo2GRPC( + timer.Action, + ) if err != nil { - return nil, fmt.Errorf("unable to convert the action: %w", err) + return nil, fmt.Errorf( + "unable to convert the action: %w", + err, + ) } result = append(result, &streamd_grpc.Timer{ TimerID: int64(timer.ID), @@ -1465,3 +1815,101 @@ func (grpc *GRPCServer) ListTimers( Timers: result, }, nil } + +func (grpc *GRPCServer) ListTriggerRules( + ctx context.Context, + req *streamd_grpc.ListTriggerRulesRequest, +) (*streamd_grpc.ListTriggerRulesReply, error) { + rules, err := grpc.StreamD.ListTriggerRules(ctx) + if err != nil { + return nil, err + } + + var result []*streamd_grpc.TriggerRule + for _, rule := range rules { + triggerRule, err := goconv.TriggerRuleGo2GRPC(rule) + if err != nil { + return nil, fmt.Errorf( + "unable to convert the trigger rule: %w", + err, + ) + } + result = append( + result, + triggerRule, + ) + } + return &streamd_grpc.ListTriggerRulesReply{ + Rules: result, + }, nil +} + +func (grpc *GRPCServer) AddTriggerRule( + ctx context.Context, + req *streamd_grpc.AddTriggerRuleRequest, +) (*streamd_grpc.AddTriggerRuleReply, error) { + + triggerRule, err := goconv.TriggerRuleGRPC2Go(req.GetRule()) + if err != nil { + return nil, fmt.Errorf("unable to convert the trigger rule: %w", err) + } + + ruleID, err := grpc.StreamD.AddTriggerRule(ctx, triggerRule) + if err != nil { + return nil, fmt.Errorf("unable to add timer: %w", err) + } + + return &streamd_grpc.AddTriggerRuleReply{ + RuleID: uint64(ruleID), + }, nil +} + +func (grpc *GRPCServer) RemoveTriggerRule( + ctx context.Context, + req *streamd_grpc.RemoveTriggerRuleRequest, +) (*streamd_grpc.RemoveTriggerRuleReply, error) { + err := grpc.StreamD.RemoveTriggerRule( + ctx, + api.TriggerRuleID(req.GetRuleID()), + ) + if err != nil { + return nil, err + } + return &streamd_grpc.RemoveTriggerRuleReply{}, nil +} + +func (grpc *GRPCServer) UpdateTriggerRule( + ctx context.Context, + req *streamd_grpc.UpdateTriggerRuleRequest, +) (*streamd_grpc.UpdateTriggerRuleReply, error) { + triggerRule, err := goconv.TriggerRuleGRPC2Go(req.GetRule()) + if err != nil { + return nil, fmt.Errorf("unable to convert the trigger rule: %w", err) + } + + err = grpc.StreamD.UpdateTriggerRule( + ctx, + api.TriggerRuleID(req.GetRuleID()), + triggerRule, + ) + if err != nil { + return nil, err + } + return &streamd_grpc.UpdateTriggerRuleReply{}, nil +} + +func (grpc *GRPCServer) SubmitEvent( + ctx context.Context, + req *streamd_grpc.SubmitEventRequest, +) (*streamd_grpc.SubmitEventReply, error) { + event, err := goconv.EventGRPC2Go(req.GetEvent()) + if err != nil { + return nil, fmt.Errorf("unable to convert the trigger rule: %w", err) + } + + err = grpc.StreamD.SubmitEvent(ctx, event) + if err != nil { + return nil, err + } + return &streamd_grpc.SubmitEventReply{}, nil +} diff --git a/pkg/streamd/streamd.go b/pkg/streamd/streamd.go index 37963c3..3c72964 100644 --- a/pkg/streamd/streamd.go +++ b/pkg/streamd/streamd.go @@ -1,7 +1,6 @@ package streamd import ( - "bytes" "context" "crypto" "fmt" @@ -11,15 +10,11 @@ import ( "sync/atomic" "time" - "github.com/andreykaipov/goobs" eventbus "github.com/asaskevich/EventBus" - "github.com/chai2010/webp" "github.com/facebookincubator/go-belt" "github.com/facebookincubator/go-belt/tool/experimental/errmon" "github.com/facebookincubator/go-belt/tool/logger" "github.com/hashicorp/go-multierror" - "github.com/xaionaro-go/obs-grpc-proxy/pkg/obsgrpcproxy" - "github.com/xaionaro-go/obs-grpc-proxy/protobuf/go/obs_grpc" "github.com/xaionaro-go/streamctl/pkg/observability" "github.com/xaionaro-go/streamctl/pkg/player" "github.com/xaionaro-go/streamctl/pkg/repository" @@ -175,110 +170,6 @@ func (d *StreamD) Run(ctx context.Context) (_ret error) { // TODO: delete the fe return nil } -func getOBSImageBytes( - ctx context.Context, - obsServer obs_grpc.OBSServer, - el config.MonitorElementConfig, - obsState *streamtypes.OBSState, -) ([]byte, time.Time, error) { - img, nextUpdateAt, err := el.Source.GetImage(ctx, obsServer, el, obsState) - if err != nil { - return nil, time.Now(). - Add(time.Second), - fmt.Errorf( - "unable to get the image from the source: %w", - err, - ) - } - - for _, filter := range el.Filters { - img = filter.Filter(ctx, img) - } - - var out bytes.Buffer - err = webp.Encode(&out, img, &webp.Options{ - Lossless: el.ImageLossless, - Quality: float32(el.ImageQuality), - Exact: false, - }) - if err != nil { - return nil, time.Now().Add(time.Second), fmt.Errorf("unable to encode the image: %w", err) - } - - return out.Bytes(), nextUpdateAt, nil -} - -func (d *StreamD) initImageTaker(ctx context.Context) error { - for elName, el := range d.Config.Monitor.Elements { - if el.Source == nil { - continue - } - if _, ok := el.Source.(*config.MonitorSourceDummy); ok { - continue - } - { - elName, el := elName, el - _ = el - observability.Go(ctx, func() { - logger.Debugf(ctx, "taker of image '%s'", elName) - defer logger.Debugf(ctx, "/taker of image '%s'", elName) - - obsServer, obsServerClose, err := d.OBS(ctx) - if obsServerClose != nil { - defer obsServerClose() - } - if err != nil { - logger.Errorf(ctx, "unable to init connection with OBS: %w", err) - return - } - - for { - var ( - imgBytes []byte - nextUpdateAt time.Time - err error - ) - - waitUntilNextIteration := func() bool { - if nextUpdateAt.IsZero() { - return false - } - select { - case <-ctx.Done(): - return false - case <-time.After(time.Until(nextUpdateAt)): - return true - } - } - - imgBytes, nextUpdateAt, err = getOBSImageBytes(ctx, obsServer, el, &d.OBSState) - if err != nil { - logger.Errorf(ctx, "unable to get the image of '%s': %v", elName, err) - if !waitUntilNextIteration() { - return - } - continue - } - - err = d.SetVariable(ctx, consts.VarKeyImage(consts.ImageID(elName)), imgBytes) - if err != nil { - logger.Errorf(ctx, "unable to save the image of '%s': %w", elName, err) - if !waitUntilNextIteration() { - return - } - continue - } - - if !waitUntilNextIteration() { - return - } - } - }) - } - } - return nil -} - func (d *StreamD) InitStreamServer(ctx context.Context) (_err error) { logger.Debugf(ctx, "InitStreamServer") defer logger.Debugf(ctx, "/InitStreamServer: %v", _err) @@ -973,43 +864,6 @@ func (d *StreamD) SetVariable( return nil } -func (d *StreamD) OBS( - ctx context.Context, -) (obs_grpc.OBSServer, context.CancelFunc, error) { - logger.Tracef(ctx, "OBS()") - defer logger.Tracef(ctx, "/OBS()") - - proxy := obsgrpcproxy.New( - ctx, - func(ctx context.Context) (*goobs.Client, context.CancelFunc, error) { - logger.Tracef(ctx, "OBS proxy getting client") - defer logger.Tracef(ctx, "/OBS proxy getting client") - obs := xsync.RDoR1(ctx, &d.ControllersLocker, func() *obs.OBS { - return d.StreamControllers.OBS - }) - if obs == nil { - return nil, nil, fmt.Errorf("connection to OBS is not initialized") - } - - client, err := obs.GetClient() - logger.Tracef(ctx, "getting OBS client result: %v %v", client, err) - if err != nil { - return nil, nil, err - } - - return client, func() { - err := client.Disconnect() - if err != nil { - logger.Errorf(ctx, "unable to disconnect from OBS: %w", err) - } else { - logger.Tracef(ctx, "disconnected from OBS") - } - }, nil - }, - ) - return proxy, func() {}, nil -} - func (d *StreamD) SubmitOAuthCode( ctx context.Context, req *streamd_grpc.SubmitOAuthCodeRequest, @@ -1816,7 +1670,7 @@ func (d *StreamD) GetLoggingLevel(ctx context.Context) (logger.Level, error) { func (d *StreamD) AddTimer( ctx context.Context, triggerAt time.Time, - action api.TimerAction, + action api.Action, ) (api.TimerID, error) { return xsync.DoA3R2(ctx, &d.TimersLocker, d.addTimer, ctx, triggerAt, action) } @@ -1824,7 +1678,7 @@ func (d *StreamD) AddTimer( func (d *StreamD) addTimer( ctx context.Context, triggerAt time.Time, - action api.TimerAction, + action api.Action, ) (api.TimerID, error) { logger.Debugf(ctx, "addTimer(ctx, %v, %v)", triggerAt, action) defer logger.Debugf(ctx, "/addTimer(ctx, %v, %v)", triggerAt, action) diff --git a/pkg/streamd/timer.go b/pkg/streamd/timer.go index c6d0ecf..b3eef08 100644 --- a/pkg/streamd/timer.go +++ b/pkg/streamd/timer.go @@ -21,7 +21,7 @@ func NewTimer( streamD *StreamD, timerID api.TimerID, triggerAt time.Time, - action api.TimerAction, + action api.Action, ) *Timer { return &Timer{ StreamD: streamD, @@ -108,29 +108,8 @@ func (t *Timer) trigger(ctx context.Context) { } }) - switch action := t.Timer.Action.(type) { - case *api.TimerActionNoop: - return - case *api.TimerActionStartStream: - err := t.StreamD.StartStream( - ctx, - action.PlatID, - action.Title, - action.Description, - action.Profile, - ) - if err != nil { - logger.Errorf(ctx, "unable to start stream by timer %d (%#+v): %v", t.Timer.ID, t.Timer, err) - } - case *api.TimerActionEndStream: - err := t.StreamD.EndStream( - ctx, - action.PlatID, - ) - if err != nil { - logger.Errorf(ctx, "unable to end stream by timer %d (%#+v): %v", t.Timer.ID, t.Timer, err) - } - default: - logger.Error(ctx, "unknown action type: %t", action) + err := t.StreamD.doAction(ctx, t.Timer.Action, nil) + if err != nil { + logger.Errorf(ctx, "unable to perform action %#+v: %w", t.Timer.Action, err) } } diff --git a/pkg/streamd/trigger_rules.go b/pkg/streamd/trigger_rules.go new file mode 100644 index 0000000..006661a --- /dev/null +++ b/pkg/streamd/trigger_rules.go @@ -0,0 +1,107 @@ +package streamd + +import ( + "context" + "fmt" + + "github.com/facebookincubator/go-belt/tool/logger" + "github.com/xaionaro-go/streamctl/pkg/streamd/api" + "github.com/xaionaro-go/streamctl/pkg/xsync" +) + +func (d *StreamD) AddTriggerRule( + ctx context.Context, + triggerRule *api.TriggerRule, +) (api.TriggerRuleID, error) { + logger.Debugf(ctx, "AddTriggerRule(ctx, %#+v)", triggerRule) + defer logger.Debugf(ctx, "/AddTriggerRule(ctx, %#+v)", triggerRule) + ruleID, err := d.addTriggerRuleToConfig(ctx, triggerRule) + if err != nil { + return 0, fmt.Errorf("unable to add the trigger rule to config: %w", err) + } + return ruleID, nil +} + +func (d *StreamD) addTriggerRuleToConfig( + ctx context.Context, + triggerRule *api.TriggerRule, +) (api.TriggerRuleID, error) { + return xsync.DoR2(ctx, &d.ConfigLock, func() (api.TriggerRuleID, error) { + ruleID := api.TriggerRuleID(len(d.Config.TriggerRules)) + d.Config.TriggerRules = append(d.Config.TriggerRules, triggerRule) + if err := d.SaveConfig(ctx); err != nil { + return ruleID, fmt.Errorf("unable to save the config: %w", err) + } + return ruleID, nil + }) +} + +func (d *StreamD) UpdateTriggerRule( + ctx context.Context, + ruleID api.TriggerRuleID, + triggerRule *api.TriggerRule, +) error { + logger.Debugf(ctx, "UpdateTriggerRule(ctx, %v, %#+v)", ruleID, triggerRule) + defer logger.Debugf(ctx, "/UpdateTriggerRule(ctx, %v, %#+v)", ruleID, triggerRule) + if err := d.updateTriggerRuleInConfig(ctx, ruleID, triggerRule); err != nil { + return fmt.Errorf("unable to update the trigger rule %d in the config: %w", ruleID, err) + } + return nil +} + +func (d *StreamD) updateTriggerRuleInConfig( + ctx context.Context, + ruleID api.TriggerRuleID, + triggerRule *api.TriggerRule, +) error { + return xsync.DoR1(ctx, &d.ConfigLock, func() error { + if ruleID >= api.TriggerRuleID(len(d.Config.TriggerRules)) { + return fmt.Errorf("rule %d does not exist", ruleID) + } + d.Config.TriggerRules[ruleID] = triggerRule + if err := d.SaveConfig(ctx); err != nil { + return fmt.Errorf("unable to save the config: %w", err) + } + return nil + }) +} + +func (d *StreamD) RemoveTriggerRule( + ctx context.Context, + ruleID api.TriggerRuleID, +) error { + logger.Debugf(ctx, "RemoveTriggerRule(ctx, %v)", ruleID) + defer logger.Debugf(ctx, "/RemoveTriggerRule(ctx, %v)", ruleID) + if err := d.removeTriggerRuleFromConfig(ctx, ruleID); err != nil { + return fmt.Errorf("unable to remove the trigger rule %d from the config: %w", ruleID, err) + } + return nil +} + +func (d *StreamD) removeTriggerRuleFromConfig( + ctx context.Context, + ruleID api.TriggerRuleID, +) error { + return xsync.DoR1(ctx, &d.ConfigLock, func() error { + if ruleID >= api.TriggerRuleID(len(d.Config.TriggerRules)) { + return fmt.Errorf("rule %d does not exist", ruleID) + } + d.Config.TriggerRules = append(d.Config.TriggerRules[:ruleID], d.Config.TriggerRules[ruleID+1:]...) + if err := d.SaveConfig(ctx); err != nil { + return fmt.Errorf("unable to save the config: %w", err) + } + return nil + }) +} + +func (d *StreamD) ListTriggerRules( + ctx context.Context, +) (api.TriggerRules, error) { + logger.Debugf(ctx, "ListTriggerRules(ctx)") + defer logger.Debugf(ctx, "/ListTriggerRules(ctx)") + return xsync.DoR2(ctx, &d.ConfigLock, func() (api.TriggerRules, error) { + rules := make(api.TriggerRules, len(d.Config.TriggerRules)) + copy(rules, d.Config.TriggerRules) + return rules, nil + }) +} diff --git a/pkg/streampanel/obs.go b/pkg/streampanel/obs.go index 6db5e9f..2e454da 100644 --- a/pkg/streampanel/obs.go +++ b/pkg/streampanel/obs.go @@ -4,16 +4,6 @@ import ( "context" "fmt" - "fyne.io/fyne/v2" - "fyne.io/fyne/v2/container" - "fyne.io/fyne/v2/dialog" - "fyne.io/fyne/v2/theme" - "fyne.io/fyne/v2/widget" - "github.com/xaionaro-go/streamctl/pkg/observability" - "github.com/xaionaro-go/streamctl/pkg/streamcontrol/obs" - "github.com/xaionaro-go/streamctl/pkg/streamcontrol/obs/types/action" - "github.com/xaionaro-go/streamctl/pkg/streamcontrol/obs/types/registry" - "github.com/xaionaro-go/streamctl/pkg/streamcontrol/obs/types/trigger" "github.com/xaionaro-go/streamctl/pkg/streamd/config" ) @@ -29,159 +19,3 @@ func (p *Panel) setStreamDConfig( } return nil } - -func (p *Panel) openSetupOBSSceneRulesWindow( - ctx context.Context, - sceneName obs.SceneName, -) { - w := p.app.NewWindow(AppName + ": Setup scene rules") - resizeWindow(w, fyne.NewSize(1000, 1000)) - - var refreshContent func() - - refreshContent = func() { - sceneRules, err := p.StreamD.ListOBSSceneRules(ctx, sceneName) - if err != nil { - p.DisplayError(err) - return - } - - var objs []fyne.CanvasObject - for idx, sceneRule := range sceneRules { - objs = append(objs, container.NewHBox( - widget.NewButtonWithIcon("", theme.SettingsIcon(), func() { - p.openAddOrEditSceneRuleWindow( - ctx, - "Edit scene rule", - sceneRule, - func( - ctx context.Context, - sceneRule obs.SceneRule, - ) error { - p.StreamD.UpdateOBSSceneRule(ctx, sceneName, uint64(idx), sceneRule) - observability.Go(ctx, refreshContent) - return nil - }, - ) - }), - widget.NewButtonWithIcon("", theme.ContentRemoveIcon(), func() { - cw := dialog.NewConfirm( - "Delete scene rule", - "Are you sure you want to delete the stream rule?", - func(b bool) { - if !b { - return - } - p.StreamD.RemoveOBSSceneRule(ctx, sceneName, uint64(idx)) - observability.Go(ctx, refreshContent) - }, - p.mainWindow, - ) - cw.Show() - }), - )) - } - - w.SetContent(container.NewBorder( - nil, - widget.NewButtonWithIcon("Add rule", theme.ContentAddIcon(), func() { - p.openAddOrEditSceneRuleWindow( - ctx, - "Add scene rule", - obs.SceneRule{}, - func( - ctx context.Context, - sceneRule obs.SceneRule, - ) error { - p.StreamD.AddOBSSceneRule(ctx, sceneName, sceneRule) - observability.Go(ctx, refreshContent) - return nil - }, - ) - }), - nil, - nil, - objs..., - )) - } - refreshContent() - w.Show() -} - -func (p *Panel) openAddOrEditSceneRuleWindow( - ctx context.Context, - title string, - sceneRule obs.SceneRule, - commitFn func(context.Context, obs.SceneRule) error, -) { - w := p.app.NewWindow(AppName + ": " + title) - resizeWindow(w, fyne.NewSize(1000, 1000)) - - triggerQueryTypeList := trigger.ListQueryTypeNames() - triggerQueryValues := map[string]trigger.Query{} - for _, typeName := range triggerQueryTypeList { - triggerQueryValues[typeName] = trigger.NewByTypeName(typeName) - } - if sceneRule.TriggerQuery == nil { - sceneRule.TriggerQuery = triggerQueryValues[triggerQueryTypeList[0]] - } - triggerQueryValues[registry.ToTypeName(sceneRule.TriggerQuery)] = sceneRule.TriggerQuery - - actionTypeList := action.ListTypeNames() - actionValues := map[string]action.Action{} - for _, typeName := range actionTypeList { - actionValues[typeName] = action.NewByTypeName(typeName) - } - if sceneRule.Action == nil { - sceneRule.Action = actionValues[actionTypeList[0]] - } - actionValues[registry.ToTypeName(sceneRule.Action)] = sceneRule.Action - - var refreshContent func() - refreshContent = func() { - triggerSelector := widget.NewSelect(triggerQueryTypeList, func(s string) { - if s == registry.ToTypeName(sceneRule.TriggerQuery) { - return - } - sceneRule.TriggerQuery = triggerQueryValues[s] - refreshContent() - }) - triggerSelector.SetSelected(registry.ToTypeName(sceneRule.TriggerQuery)) - triggerFields := makeFieldsFor(sceneRule.TriggerQuery) - - actionSelector := widget.NewSelect(actionTypeList, func(s string) { - if s == registry.ToTypeName(sceneRule.Action) { - return - } - sceneRule.Action = actionValues[s] - refreshContent() - }) - actionSelector.SetSelected(registry.ToTypeName(sceneRule.Action)) - actionFields := makeFieldsFor(sceneRule.Action) - - w.SetContent(container.NewBorder( - nil, - widget.NewButton("Save", func() { - err := commitFn(ctx, sceneRule) - if err != nil { - p.DisplayError(err) - return - } - w.Close() - }), - nil, - nil, - container.NewVBox( - widget.NewLabel("Trigger:"), - triggerSelector, - container.NewVBox(triggerFields...), - widget.NewLabel("Action:"), - actionSelector, - container.NewVBox(actionFields...), - ), - )) - } - - refreshContent() - w.Show() -} diff --git a/pkg/streampanel/panel.go b/pkg/streampanel/panel.go index e8267b6..8a5eb23 100644 --- a/pkg/streampanel/panel.go +++ b/pkg/streampanel/panel.go @@ -1924,10 +1924,6 @@ func (p *Panel) initMainWindow( streamInfoContainer, ) - setupSceneRulesButton := widget.NewButton("Setup scene rules", func() { - p.openSetupOBSSceneRulesWindow(ctx, obs.SceneName(p.obsSelectScene.Selected)) - }) - p.obsSelectScene = widget.NewSelect(nil, func(s string) { logger.Debugf(ctx, "OBS scene is changed to '%s'", s) obsServer, obsServerClose, err := p.StreamD.OBS(ctx) @@ -1944,13 +1940,7 @@ func (p *Panel) initMainWindow( if err != nil { p.DisplayError(fmt.Errorf("unable to set the OBS scene: %w", err)) } - setupSceneRulesButton.Enable() }) - - if p.obsSelectScene.Selected == "" { - setupSceneRulesButton.Disable() - } - obsPage := container.NewBorder( nil, nil, @@ -1958,7 +1948,6 @@ func (p *Panel) initMainWindow( nil, container.NewVBox( container.NewHBox(widget.NewLabel("Scene:"), p.obsSelectScene), - setupSceneRulesButton, ), ) @@ -2014,6 +2003,8 @@ func (p *Panel) initMainWindow( )) timersUI := NewTimersUI(ctx, p) + triggersUI := NewTriggerRulesUI(ctx, p) + moreControlPage := container.NewBorder( nil, nil, @@ -2022,6 +2013,8 @@ func (p *Panel) initMainWindow( container.NewVBox( timersUI.CanvasObject, widget.NewSeparator(), + triggersUI.CanvasObject, + widget.NewSeparator(), ), ) diff --git a/pkg/streampanel/reflect.go b/pkg/streampanel/reflect.go index b88a439..dc2ae10 100644 --- a/pkg/streampanel/reflect.go +++ b/pkg/streampanel/reflect.go @@ -14,6 +14,25 @@ func makeFieldsFor( return reflectMakeFieldsFor(reflect.ValueOf(obj), reflect.ValueOf(obj).Type(), nil, "") } +func isUIDisabled( + obj any, +) bool { + return reflectIsUIDisabled(reflect.ValueOf(obj)) +} + +func reflectIsUIDisabled( + v reflect.Value, +) bool { + v = reflect.Indirect(v) + t := v.Type() + for i := 0; i < t.NumField(); i++ { + if t.Field(i).Name == "uiDisable" { + return true + } + } + return false +} + func reflectMakeFieldsFor( v reflect.Value, t reflect.Type, @@ -53,6 +72,9 @@ func reflectMakeFieldsFor( fv := v.Field(i) ft := t.Field(i) if ft.PkgPath != "" { + if ft.Name == "uiDisable" { + return nil + } tag := ft.Tag.Get("uicomment") if tag != "" { result = append(result, widget.NewLabel(tag)) @@ -67,7 +89,7 @@ func reflectMakeFieldsFor( } return result default: - panic(fmt.Errorf("internal error: support of %v is not implemented, yet", t.Kind())) + panic(fmt.Errorf("internal error: %s: support of %v is not implemented, yet", namePrefix, t.Kind())) } } diff --git a/pkg/streampanel/template.go b/pkg/streampanel/template.go index 85541cc..2b2f2a8 100644 --- a/pkg/streampanel/template.go +++ b/pkg/streampanel/template.go @@ -1,62 +1,11 @@ package streampanel import ( - "bytes" - "fmt" - "io" - "net/http" "strings" - "text/template" + + "github.com/xaionaro-go/streamctl/pkg/expression" ) -var funcMap = map[string]interface{}{ - "devnull": func(args ...any) string { - return "" - }, - "httpGET": func(urlString string) string { - resp, err := http.Get(urlString) - if err != nil { - panic(err) - } - defer resp.Body.Close() - - b, err := io.ReadAll(resp.Body) - if err != nil { - panic(err) - } - - return string(b) - }, - "httpGETIgnoreErrors": func(urlString string) string { - resp, err := http.Get(urlString) - if err != nil { - return "" - } - defer resp.Body.Close() - - b, err := io.ReadAll(resp.Body) - if err != nil { - return "" - } - - return string(b) - }, -} - -func expandTemplate(tpl string) (string, error) { - parsed, err := template.New("").Funcs(funcMap).Parse(tpl) - if err != nil { - return "", fmt.Errorf("unable to parse the template: %w", err) - } - - var buf bytes.Buffer - if err = parsed.Execute(&buf, nil); err != nil { - return "", fmt.Errorf("unable to execute the template: %w", err) - } - - return buf.String(), nil -} - func splitWithQuotes(s string) []string { var result []string var current string @@ -97,7 +46,7 @@ func splitWithQuotes(s string) []string { } func expandCommand(cmdString string) ([]string, error) { - cmdStringExpanded, err := expandTemplate(cmdString) + cmdStringExpanded, err := expression.Eval[string](expression.Expression(cmdString), nil) if err != nil { return nil, err } diff --git a/pkg/streampanel/timers.go b/pkg/streampanel/timers.go index f0a1bf8..754d5a2 100644 --- a/pkg/streampanel/timers.go +++ b/pkg/streampanel/timers.go @@ -18,18 +18,12 @@ import ( obs "github.com/xaionaro-go/streamctl/pkg/streamcontrol/obs/types" twitch "github.com/xaionaro-go/streamctl/pkg/streamcontrol/twitch/types" youtube "github.com/xaionaro-go/streamctl/pkg/streamcontrol/youtube/types" - "github.com/xaionaro-go/streamctl/pkg/streamd/api" + "github.com/xaionaro-go/streamctl/pkg/streamd/config/action" "github.com/xaionaro-go/streamctl/pkg/xcontext" "github.com/xaionaro-go/streamctl/pkg/xfyne" "github.com/xaionaro-go/streamctl/pkg/xsync" ) -var closedChan = make(chan struct{}) - -func init() { - close(closedChan) -} - type timersUI struct { locker xsync.Mutex CanvasObject fyne.CanvasObject @@ -137,11 +131,11 @@ func (ui *timersUI) refreshFromRemote( var triggerAt time.Time for _, timer := range timers { switch timer.Action.(type) { - case *api.TimerActionNoop: + case *action.Noop: continue - case *api.TimerActionStartStream: + case *action.StartStream: continue - case *api.TimerActionEndStream: + case *action.EndStream: triggerAt = timer.TriggerAt default: continue @@ -258,7 +252,7 @@ func (ui *timersUI) kickOffRemotely( twitch.ID, obs.ID, } { - _, err := streamD.AddTimer(ctx, deadline, &api.TimerActionEndStream{ + _, err := streamD.AddTimer(ctx, deadline, &action.EndStream{ PlatID: platID, }) if err != nil { diff --git a/pkg/streampanel/trigger_rules.go b/pkg/streampanel/trigger_rules.go new file mode 100644 index 0000000..651d0a6 --- /dev/null +++ b/pkg/streampanel/trigger_rules.go @@ -0,0 +1,231 @@ +package streampanel + +import ( + "context" + "fmt" + + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/container" + "fyne.io/fyne/v2/dialog" + "fyne.io/fyne/v2/theme" + "fyne.io/fyne/v2/widget" + "github.com/facebookincubator/go-belt/tool/logger" + "github.com/xaionaro-go/streamctl/pkg/observability" + "github.com/xaionaro-go/streamctl/pkg/serializable" + "github.com/xaionaro-go/streamctl/pkg/serializable/registry" + "github.com/xaionaro-go/streamctl/pkg/streamd/api" + "github.com/xaionaro-go/streamctl/pkg/streamd/config" + "github.com/xaionaro-go/streamctl/pkg/streamd/config/action" + "github.com/xaionaro-go/streamctl/pkg/streamd/config/event/eventquery" +) + +type triggerRulesUI struct { + CanvasObject fyne.CanvasObject + panel *Panel +} + +func NewTriggerRulesUI( + ctx context.Context, + panel *Panel, +) *triggerRulesUI { + ui := &triggerRulesUI{ + panel: panel, + } + + button := widget.NewButtonWithIcon( + "Setup trigger rules", + theme.SettingsIcon(), func() { + ui.openSetupWindow(ctx) + }, + ) + ui.CanvasObject = container.NewVBox( + button, + ) + return ui +} + +func (ui *triggerRulesUI) openSetupWindow(ctx context.Context) { + w := ui.panel.app.NewWindow(AppName + ": Setup trigger rules") + resizeWindow(w, fyne.NewSize(1000, 1000)) + + var refreshContent func() bool + + refreshContent = func() bool { + triggerRules, err := ui.panel.StreamD.ListTriggerRules(ctx) + if err != nil { + ui.panel.DisplayError(err) + return false + } + + var objs []fyne.CanvasObject + for idx, triggerRule := range triggerRules { + objs = append(objs, container.NewHBox( + widget.NewButtonWithIcon("", theme.SettingsIcon(), func() { + ui.openAddOrEditSceneRuleWindow( + ctx, + "Edit trigger rule", + *triggerRule, + func( + ctx context.Context, + triggerRule *config.TriggerRule, + ) error { + err := ui.panel.StreamD.UpdateTriggerRule(ctx, api.TriggerRuleID(idx), triggerRule) + if err != nil { + return err + } + observability.Go(ctx, func() { refreshContent() }) + return nil + }, + ) + }), + widget.NewButtonWithIcon("", theme.ContentRemoveIcon(), func() { + cw := dialog.NewConfirm( + "Delete scene rule", + "Are you sure you want to delete the stream rule?", + func(b bool) { + if !b { + return + } + err := ui.panel.StreamD.RemoveTriggerRule(ctx, api.TriggerRuleID(idx)) + if err != nil { + ui.panel.DisplayError(err) + return + } + observability.Go(ctx, func() { refreshContent() }) + }, + ui.panel.mainWindow, + ) + cw.Show() + }), + widget.NewLabel(fmt.Sprintf("%v", triggerRule)), + )) + } + + w.SetContent(container.NewBorder( + nil, + widget.NewButtonWithIcon("Add rule", theme.ContentAddIcon(), func() { + ui.openAddOrEditSceneRuleWindow( + ctx, + "Add scene rule", + config.TriggerRule{}, + func( + ctx context.Context, + triggerRule *config.TriggerRule, + ) error { + _, err := ui.panel.StreamD.AddTriggerRule(ctx, triggerRule) + if err != nil { + return err + } + observability.Go(ctx, func() { refreshContent() }) + return nil + }, + ) + }), + nil, + nil, + container.NewVBox( + objs..., + ), + )) + return true + } + if !refreshContent() { + w.Close() + return + } + w.Show() +} + +func (ui *triggerRulesUI) openAddOrEditSceneRuleWindow( + ctx context.Context, + title string, + triggerRule config.TriggerRule, + commitFn func(context.Context, *config.TriggerRule) error, +) { + w := ui.panel.app.NewWindow(AppName + ": " + title) + resizeWindow(w, fyne.NewSize(1000, 1000)) + + var triggerQueryTypeList []string + _triggerQueryTypeList := serializable.ListTypeNames[eventquery.EventQuery]() + triggerQueryValues := map[string]eventquery.EventQuery{} + for _, typeName := range _triggerQueryTypeList { + value, _ := serializable.NewByTypeName[eventquery.EventQuery](typeName) + if isUIDisabled(value) { + continue + } + triggerQueryValues[typeName] = value + triggerQueryTypeList = append(triggerQueryTypeList, typeName) + } + if triggerRule.EventQuery == nil { + triggerRule.EventQuery = triggerQueryValues[triggerQueryTypeList[0]] + } + triggerQueryValues[registry.ToTypeName(triggerRule.EventQuery)] = triggerRule.EventQuery + + var actionTypeList []string + _actionTypeList := serializable.ListTypeNames[action.Action]() + actionValues := map[string]action.Action{} + for _, typeName := range _actionTypeList { + value, _ := serializable.NewByTypeName[action.Action](typeName) + if isUIDisabled(value) { + continue + } + actionValues[typeName] = value + actionTypeList = append(actionTypeList, typeName) + } + if triggerRule.Action == nil { + triggerRule.Action = actionValues[actionTypeList[0]] + } + actionValues[registry.ToTypeName(triggerRule.Action)] = triggerRule.Action + + var refreshContent func() + refreshContent = func() { + triggerSelector := widget.NewSelect(triggerQueryTypeList, func(s string) { + if s == registry.ToTypeName(triggerRule.EventQuery) { + return + } + triggerRule.EventQuery = triggerQueryValues[s] + refreshContent() + }) + curEventQueryType := registry.ToTypeName(triggerRule.EventQuery) + triggerSelector.SetSelected(curEventQueryType) + logger.Debugf(ctx, "trigger: selector %v: cur: %v (%T)", triggerQueryTypeList, curEventQueryType, triggerRule.EventQuery) + triggerFields := makeFieldsFor(triggerRule.EventQuery) + + actionSelector := widget.NewSelect(actionTypeList, func(s string) { + if s == registry.ToTypeName(triggerRule.Action) { + return + } + triggerRule.Action = actionValues[s] + refreshContent() + }) + curActionType := registry.ToTypeName(triggerRule.Action) + actionSelector.SetSelected(curActionType) + logger.Debugf(ctx, "action: selector %v: cur: %v (%T)", actionTypeList, curActionType, triggerRule.Action) + actionFields := makeFieldsFor(triggerRule.Action) + + w.SetContent(container.NewBorder( + nil, + widget.NewButton("Save", func() { + err := commitFn(ctx, &triggerRule) + if err != nil { + ui.panel.DisplayError(err) + return + } + w.Close() + }), + nil, + nil, + container.NewVBox( + widget.NewLabel("Trigger:"), + triggerSelector, + container.NewVBox(triggerFields...), + widget.NewLabel("Action:"), + actionSelector, + container.NewVBox(actionFields...), + ), + )) + } + + refreshContent() + w.Show() +} diff --git a/pkg/windowmanagerhandler/window_manager_handler.go b/pkg/windowmanagerhandler/window_manager_handler.go new file mode 100644 index 0000000..ed4b226 --- /dev/null +++ b/pkg/windowmanagerhandler/window_manager_handler.go @@ -0,0 +1,27 @@ +package windowmanagerhandler + +import ( + "context" + "fmt" +) + +type WindowManagerHandler struct { + *PlatformSpecificWindowManagerHandler +} + +func New() (*WindowManagerHandler, error) { + wmh := &WindowManagerHandler{} + if err := wmh.init(); err != nil { + return nil, fmt.Errorf("unable to initialize a window manager handler: %w", err) + } + return wmh, nil +} + +func (wmh *WindowManagerHandler) WindowFocusChangeChan(ctx context.Context) <-chan WindowFocusChange { + return wmh.PlatformSpecificWindowManagerHandler.WindowFocusChangeChan(ctx) +} + +type WindowFocusChange struct { + WindowID WindowID + WindowTitle string +} diff --git a/pkg/windowmanagerhandler/window_manager_handler_linux.go b/pkg/windowmanagerhandler/window_manager_handler_linux.go new file mode 100644 index 0000000..ab9283e --- /dev/null +++ b/pkg/windowmanagerhandler/window_manager_handler_linux.go @@ -0,0 +1,27 @@ +//go:build linux +// +build linux + +package windowmanagerhandler + +import ( + "context" + "os" +) + +type WindowID uint64 + +type XWMOrWaylandWM interface { + WindowFocusChangeChan(ctx context.Context) <-chan WindowFocusChange +} + +type PlatformSpecificWindowManagerHandler struct { + XWMOrWaylandWM +} + +func (wmh *WindowManagerHandler) init() error { + if os.Getenv("DISPLAY") != "" { + return wmh.initUsingXServer() + } else { + return wmh.initUsingWayland() + } +} diff --git a/pkg/windowmanagerhandler/window_manager_handler_linux_wayland.go b/pkg/windowmanagerhandler/window_manager_handler_linux_wayland.go new file mode 100644 index 0000000..a0c9c34 --- /dev/null +++ b/pkg/windowmanagerhandler/window_manager_handler_linux_wayland.go @@ -0,0 +1,9 @@ +package windowmanagerhandler + +import ( + "fmt" +) + +func (wmh *WindowManagerHandler) initUsingWayland() error { + return fmt.Errorf("support of Wayland is not implemented, yet") +} diff --git a/pkg/windowmanagerhandler/window_manager_handler_linux_xserver.go b/pkg/windowmanagerhandler/window_manager_handler_linux_xserver.go new file mode 100644 index 0000000..ee82b14 --- /dev/null +++ b/pkg/windowmanagerhandler/window_manager_handler_linux_xserver.go @@ -0,0 +1,80 @@ +//go:build linux +// +build linux + +package windowmanagerhandler + +import ( + "context" + "fmt" + "os" + "time" + + "github.com/BurntSushi/xgb/xproto" + "github.com/BurntSushi/xgbutil" + "github.com/BurntSushi/xgbutil/ewmh" + "github.com/facebookincubator/go-belt/tool/logger" + "github.com/xaionaro-go/streamctl/pkg/observability" +) + +type XWindowManagerHandler struct { + *xgbutil.XUtil +} + +func (wmh *WindowManagerHandler) initUsingXServer() error { + x, err := xgbutil.NewConn() + if err != nil { + return fmt.Errorf("unable to connect to X-server using DISPLAY '%s': %w", os.Getenv("DISPLAY"), err) + } + wmh.XWMOrWaylandWM = &XWindowManagerHandler{ + XUtil: x, + } + return nil +} + +func (wmh *XWindowManagerHandler) WindowFocusChangeChan(ctx context.Context) <-chan WindowFocusChange { + logger.Debugf(ctx, "WindowFocusChangeChan") + ch := make(chan WindowFocusChange) + + observability.Go(ctx, func() { + defer logger.Debugf(ctx, "/WindowFocusChangeChan") + defer func() { + close(ch) + }() + + prevClientID := xproto.Window(0) + t := time.NewTicker(200 * time.Millisecond) + defer t.Stop() + + for { + select { + case <-ctx.Done(): + return + case <-t.C: + } + + clientID, err := ewmh.ActiveWindowGet(wmh.XUtil) + if err != nil { + logger.Errorf(ctx, "unable to get active window: %w", err) + continue + } + + if clientID == prevClientID { + continue + } + prevClientID = clientID + + name, err := ewmh.WmNameGet(wmh.XUtil, clientID) + if err != nil { + logger.Errorf(ctx, "unable to get the name of the active window (%d): %w", clientID, err) + continue + } + + ch <- WindowFocusChange{ + WindowID: WindowID(clientID), + WindowTitle: name, + } + } + }) + + return ch +} diff --git a/pkg/windowmanagerhandler/window_manager_handler_other.go b/pkg/windowmanagerhandler/window_manager_handler_other.go new file mode 100644 index 0000000..ddb7632 --- /dev/null +++ b/pkg/windowmanagerhandler/window_manager_handler_other.go @@ -0,0 +1,16 @@ +//go:build !linux +// +build !linux + +package windowmanagerhandler + +import ( + "context" + "fmt" +) + +type PlatformSpecificWindowManagerHandler struct{} +type WindowID struct{} + +func (wmh *WindowManagerHandler) init(context.Context) error { + return fmt.Errorf("the support of window manager handler for this platform is not implemented, yet") +}