mirror of
https://github.com/xaionaro-go/streamctl.git
synced 2025-10-07 08:20:51 +08:00
Fix panics on empty config
This commit is contained in:
@@ -287,6 +287,9 @@ func ConvertPlatformConfig[T any, S StreamProfile](
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
platCfg *AbstractPlatformConfig,
|
platCfg *AbstractPlatformConfig,
|
||||||
) *PlatformConfig[T, S] {
|
) *PlatformConfig[T, S] {
|
||||||
|
if platCfg == nil {
|
||||||
|
platCfg = &AbstractPlatformConfig{}
|
||||||
|
}
|
||||||
return &PlatformConfig[T, S]{
|
return &PlatformConfig[T, S]{
|
||||||
Enable: platCfg.Enable,
|
Enable: platCfg.Enable,
|
||||||
Config: GetPlatformSpecificConfig[T](ctx, platCfg.Config),
|
Config: GetPlatformSpecificConfig[T](ctx, platCfg.Config),
|
||||||
@@ -299,6 +302,10 @@ func GetPlatformSpecificConfig[T any](
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
platCfgCfg any,
|
platCfgCfg any,
|
||||||
) T {
|
) T {
|
||||||
|
if platCfgCfg == nil {
|
||||||
|
var zeroValue T
|
||||||
|
return zeroValue
|
||||||
|
}
|
||||||
switch platCfgCfg := platCfgCfg.(type) {
|
switch platCfgCfg := platCfgCfg.(type) {
|
||||||
case T:
|
case T:
|
||||||
return platCfgCfg
|
return platCfgCfg
|
||||||
|
@@ -57,6 +57,21 @@ func NewChatHandler(
|
|||||||
close(h.messagesOutChan)
|
close(h.messagesOutChan)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
h.sendMessage(kickcom.ChatMessageV2{
|
||||||
|
ID: "",
|
||||||
|
ChatID: 0,
|
||||||
|
UserID: 0,
|
||||||
|
Content: "test\nmultiline message",
|
||||||
|
Type: "",
|
||||||
|
Metadata: nil,
|
||||||
|
CreatedAt: time.Time{},
|
||||||
|
Sender: kickcom.ChatMessageSenderV2{
|
||||||
|
ID: 0,
|
||||||
|
Slug: "",
|
||||||
|
Username: "test-user",
|
||||||
|
Identity: kickcom.Identity{},
|
||||||
|
},
|
||||||
|
})
|
||||||
err := h.iterate(ctx)
|
err := h.iterate(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf(ctx, "unable to perform an iteration: %w", err)
|
logger.Errorf(ctx, "unable to perform an iteration: %w", err)
|
||||||
|
@@ -3,6 +3,7 @@ package twitch
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/adeithe/go-twitch/irc"
|
"github.com/adeithe/go-twitch/irc"
|
||||||
"github.com/xaionaro-go/streamctl/pkg/observability"
|
"github.com/xaionaro-go/streamctl/pkg/observability"
|
||||||
@@ -47,6 +48,13 @@ func newChatHandler(
|
|||||||
messagesOutChan: make(chan streamcontrol.ChatMessage, 100),
|
messagesOutChan: make(chan streamcontrol.ChatMessage, 100),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h.messagesOutChan <- streamcontrol.ChatMessage{
|
||||||
|
CreatedAt: time.Now(),
|
||||||
|
UserID: "test-twitch-user",
|
||||||
|
MessageID: "test-message-id",
|
||||||
|
Message: "test\nmultiline message",
|
||||||
|
}
|
||||||
|
|
||||||
observability.Go(ctx, func() {
|
observability.Go(ctx, func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
h.client.Close()
|
h.client.Close()
|
||||||
|
@@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/facebookincubator/go-belt/tool/logger"
|
||||||
"github.com/xaionaro-go/streamctl/pkg/observability"
|
"github.com/xaionaro-go/streamctl/pkg/observability"
|
||||||
"github.com/xaionaro-go/streamctl/pkg/streamcontrol"
|
"github.com/xaionaro-go/streamctl/pkg/streamcontrol"
|
||||||
"github.com/xaionaro-go/streamctl/pkg/streamd/api"
|
"github.com/xaionaro-go/streamctl/pkg/streamd/api"
|
||||||
@@ -14,6 +15,7 @@ func (d *StreamD) startListeningForChatMessages(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
platName streamcontrol.PlatformName,
|
platName streamcontrol.PlatformName,
|
||||||
) error {
|
) error {
|
||||||
|
logger.Debugf(ctx, "startListeningForChatMessages(ctx, '%s')", platName)
|
||||||
ctrl, err := d.streamController(ctx, platName)
|
ctrl, err := d.streamController(ctx, platName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to get the just initialized '%s': %w", platName, err)
|
return fmt.Errorf("unable to get the just initialized '%s': %w", platName, err)
|
||||||
@@ -23,6 +25,7 @@ func (d *StreamD) startListeningForChatMessages(
|
|||||||
return fmt.Errorf("unable to get the channel for chat messages of '%s': %w", platName, err)
|
return fmt.Errorf("unable to get the channel for chat messages of '%s': %w", platName, err)
|
||||||
}
|
}
|
||||||
observability.Go(ctx, func() {
|
observability.Go(ctx, func() {
|
||||||
|
logger.Debugf(ctx, "/startListeningForChatMessages(ctx, '%s')", platName)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
|
@@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -22,16 +21,16 @@ import (
|
|||||||
"github.com/xaionaro-go/streamctl/pkg/xsync"
|
"github.com/xaionaro-go/streamctl/pkg/xsync"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (d *StreamD) EXPERIMENTAL_ReinitStreamControllers(ctx context.Context) error {
|
func (d *StreamD) EXPERIMENTAL_ReinitStreamControllers(ctx context.Context) (_err error) {
|
||||||
platNames := make([]streamcontrol.PlatformName, 0, len(d.Config.Backends))
|
logger.Debugf(ctx, "ReinitStreamControllers")
|
||||||
for platName := range d.Config.Backends {
|
defer func() { logger.Debugf(ctx, "/ReinitStreamControllers: %v", _err) }()
|
||||||
platNames = append(platNames, platName)
|
|
||||||
}
|
|
||||||
sort.Slice(platNames, func(i, j int) bool {
|
|
||||||
return platNames[i] < platNames[j]
|
|
||||||
})
|
|
||||||
var result *multierror.Error
|
var result *multierror.Error
|
||||||
for _, platName := range platNames {
|
for _, platName := range []streamcontrol.PlatformName{
|
||||||
|
youtube.ID,
|
||||||
|
twitch.ID,
|
||||||
|
kick.ID,
|
||||||
|
obs.ID,
|
||||||
|
} {
|
||||||
var err error
|
var err error
|
||||||
switch strings.ToLower(string(platName)) {
|
switch strings.ToLower(string(platName)) {
|
||||||
case strings.ToLower(string(obs.ID)):
|
case strings.ToLower(string(obs.ID)):
|
||||||
@@ -76,7 +75,9 @@ func newOBS(
|
|||||||
) {
|
) {
|
||||||
logger.Debugf(ctx, "newOBS(ctx, %#+v, ...)", cfg)
|
logger.Debugf(ctx, "newOBS(ctx, %#+v, ...)", cfg)
|
||||||
defer func() { logger.Debugf(ctx, "/newOBS: %v", _err) }()
|
defer func() { logger.Debugf(ctx, "/newOBS: %v", _err) }()
|
||||||
|
if cfg == nil {
|
||||||
|
cfg = &streamcontrol.AbstractPlatformConfig{}
|
||||||
|
}
|
||||||
platCfg := streamcontrol.ConvertPlatformConfig[
|
platCfg := streamcontrol.ConvertPlatformConfig[
|
||||||
obs.PlatformSpecificConfig, obs.StreamProfile,
|
obs.PlatformSpecificConfig, obs.StreamProfile,
|
||||||
](
|
](
|
||||||
@@ -139,6 +140,9 @@ func newTwitch(
|
|||||||
*twitch.Twitch,
|
*twitch.Twitch,
|
||||||
error,
|
error,
|
||||||
) {
|
) {
|
||||||
|
if cfg == nil {
|
||||||
|
cfg = &streamcontrol.AbstractPlatformConfig{}
|
||||||
|
}
|
||||||
platCfg := streamcontrol.ConvertPlatformConfig[twitch.PlatformSpecificConfig, twitch.StreamProfile](
|
platCfg := streamcontrol.ConvertPlatformConfig[twitch.PlatformSpecificConfig, twitch.StreamProfile](
|
||||||
ctx,
|
ctx,
|
||||||
cfg,
|
cfg,
|
||||||
@@ -210,6 +214,9 @@ func newKick(
|
|||||||
*kick.Kick,
|
*kick.Kick,
|
||||||
error,
|
error,
|
||||||
) {
|
) {
|
||||||
|
if cfg == nil {
|
||||||
|
cfg = &streamcontrol.AbstractPlatformConfig{}
|
||||||
|
}
|
||||||
platCfg := streamcontrol.ConvertPlatformConfig[kick.PlatformSpecificConfig, kick.StreamProfile](
|
platCfg := streamcontrol.ConvertPlatformConfig[kick.PlatformSpecificConfig, kick.StreamProfile](
|
||||||
ctx,
|
ctx,
|
||||||
cfg,
|
cfg,
|
||||||
@@ -222,6 +229,27 @@ func newKick(
|
|||||||
return nil, ErrSkipBackend
|
return nil, ErrSkipBackend
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hadSetNewUserData := false
|
||||||
|
if platCfg.Config.Channel == "" {
|
||||||
|
ok, err := setUserData(ctx, platCfg)
|
||||||
|
if !ok {
|
||||||
|
err := saveCfgFunc(&streamcontrol.AbstractPlatformConfig{
|
||||||
|
Enable: platCfg.Enable,
|
||||||
|
Config: platCfg.Config,
|
||||||
|
StreamProfiles: streamcontrol.ToAbstractStreamProfiles(platCfg.StreamProfiles),
|
||||||
|
Custom: platCfg.Custom,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(ctx, err)
|
||||||
|
}
|
||||||
|
return nil, ErrSkipBackend
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to set user info: %w", err)
|
||||||
|
}
|
||||||
|
hadSetNewUserData = true
|
||||||
|
}
|
||||||
|
|
||||||
logger.Debugf(ctx, "kick config: %#+v", platCfg)
|
logger.Debugf(ctx, "kick config: %#+v", platCfg)
|
||||||
cfg = streamcontrol.ToAbstractPlatformConfig(ctx, platCfg)
|
cfg = streamcontrol.ToAbstractPlatformConfig(ctx, platCfg)
|
||||||
kick, err := kick.New(ctx, *platCfg,
|
kick, err := kick.New(ctx, *platCfg,
|
||||||
@@ -237,6 +265,12 @@ func newKick(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to initialize Kick client: %w", err)
|
return nil, fmt.Errorf("unable to initialize Kick client: %w", err)
|
||||||
}
|
}
|
||||||
|
if hadSetNewUserData {
|
||||||
|
logger.Debugf(ctx, "confirmed new youtube user data, saving it")
|
||||||
|
if err := saveCfgFunc(cfg); err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to save the configuration: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
return kick, nil
|
return kick, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,6 +285,9 @@ func newYouTube(
|
|||||||
*youtube.YouTube,
|
*youtube.YouTube,
|
||||||
error,
|
error,
|
||||||
) {
|
) {
|
||||||
|
if cfg == nil {
|
||||||
|
cfg = &streamcontrol.AbstractPlatformConfig{}
|
||||||
|
}
|
||||||
platCfg := streamcontrol.ConvertPlatformConfig[youtube.PlatformSpecificConfig, youtube.StreamProfile](
|
platCfg := streamcontrol.ConvertPlatformConfig[youtube.PlatformSpecificConfig, youtube.StreamProfile](
|
||||||
ctx,
|
ctx,
|
||||||
cfg,
|
cfg,
|
||||||
|
@@ -318,6 +318,9 @@ func (d *StreamD) setPlatformConfig(
|
|||||||
logger.Debugf(ctx, "setPlatformConfig('%s', '%#+v')", platID, platCfg)
|
logger.Debugf(ctx, "setPlatformConfig('%s', '%#+v')", platID, platCfg)
|
||||||
defer logger.Debugf(ctx, "endof setPlatformConfig('%s', '%#+v')", platID, platCfg)
|
defer logger.Debugf(ctx, "endof setPlatformConfig('%s', '%#+v')", platID, platCfg)
|
||||||
return xsync.DoR1(ctx, &d.ConfigLock, func() error {
|
return xsync.DoR1(ctx, &d.ConfigLock, func() error {
|
||||||
|
if d.Config.Backends == nil {
|
||||||
|
d.Config.Backends = make(streamcontrol.Config)
|
||||||
|
}
|
||||||
d.Config.Backends[platID] = platCfg
|
d.Config.Backends[platID] = platCfg
|
||||||
return d.SaveConfig(ctx)
|
return d.SaveConfig(ctx)
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user