2022-11-21 04:39:21 +09:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2023-03-07 17:07:14 +09:00
|
|
|
"net"
|
2022-11-21 04:39:21 +09:00
|
|
|
"strconv"
|
|
|
|
|
2023-03-07 17:07:14 +09:00
|
|
|
"git.gensokyo.cafe/kkyy/tgbot_misaka_5882f7/utils"
|
2022-11-21 04:39:21 +09:00
|
|
|
"github.com/go-errors/errors"
|
2023-03-07 17:07:14 +09:00
|
|
|
"github.com/ilyakaznacheev/cleanenv"
|
2022-11-21 04:39:21 +09:00
|
|
|
)
|
|
|
|
|
2023-03-07 17:07:14 +09:00
|
|
|
type ConfigDef struct {
|
|
|
|
AdminUIDs []int64 `env:"TG_ADMIN_UIDS"`
|
|
|
|
TGBotToken string `env:"TG_TOKEN" env-required:""`
|
|
|
|
TGAnnounceCommands bool `env:"TG_ANNOUNCE_CMDS"`
|
2022-11-21 04:39:21 +09:00
|
|
|
|
2023-03-07 17:07:14 +09:00
|
|
|
// API
|
|
|
|
APIMasterKey string `env:"TG_API_MASTER_KEY" env-required:""`
|
|
|
|
APIListen string `env:"TG_API_LISTEN" env-default:"127.0.0.1:8080"`
|
2022-11-21 04:39:21 +09:00
|
|
|
|
2023-03-07 17:07:14 +09:00
|
|
|
// Traffic usage
|
|
|
|
WatchedInterface string `env:"TG_WATCHED_INTERFACE"`
|
|
|
|
MonthlyTrafficLimitGiB int `env:"TG_MONTHLY_TRAFFIC_LIMIT_GIB" env-default:"1000"`
|
2022-11-21 04:39:21 +09:00
|
|
|
|
2023-03-07 17:07:14 +09:00
|
|
|
// Parsed fields
|
|
|
|
adminUidLookup map[int64]struct{}
|
|
|
|
apiListenAddr net.Addr
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *ConfigDef) Parse() error {
|
|
|
|
c.adminUidLookup = make(map[int64]struct{}, len(c.AdminUIDs))
|
|
|
|
for _, u := range c.AdminUIDs {
|
|
|
|
if u <= 0 {
|
|
|
|
return errors.New("invalid admin UID: " + strconv.FormatInt(u, 10))
|
|
|
|
}
|
|
|
|
c.adminUidLookup[u] = struct{}{}
|
|
|
|
}
|
2022-11-21 04:39:21 +09:00
|
|
|
|
2023-03-07 17:07:14 +09:00
|
|
|
// validate API listen
|
|
|
|
ip, port, err := net.SplitHostPort(c.APIListen)
|
|
|
|
if err != nil {
|
|
|
|
return errors.WrapPrefix(err, "invalid API listen address", 0)
|
2022-11-21 04:39:21 +09:00
|
|
|
}
|
2023-03-07 17:07:14 +09:00
|
|
|
if tIP := net.ParseIP(ip); tIP == nil {
|
|
|
|
return errors.New("invalid API listen address: " + ip)
|
|
|
|
}
|
|
|
|
if tPort, err := strconv.Atoi(port); err != nil || tPort <= 0 || tPort > 65535 {
|
|
|
|
return errors.New("invalid API listen port: " + port)
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.WatchedInterface == "" {
|
|
|
|
tIf, err := utils.FindDefaultAdapter()
|
2022-11-21 04:39:21 +09:00
|
|
|
if err != nil {
|
2023-03-07 17:07:14 +09:00
|
|
|
return errors.WrapPrefix(err, "Watched interface is not defined and failed to find a default one.", 0)
|
2022-11-21 04:39:21 +09:00
|
|
|
}
|
2023-03-07 17:07:14 +09:00
|
|
|
c.WatchedInterface = tIf.Name
|
|
|
|
logger.Infof("Watching default interface %s", c.WatchedInterface)
|
2022-11-21 04:39:21 +09:00
|
|
|
}
|
|
|
|
|
2023-03-07 17:07:14 +09:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *ConfigDef) IsAdmin(id int64) bool {
|
|
|
|
_, ok := c.adminUidLookup[id]
|
|
|
|
return ok
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *ConfigDef) GetAPIListenAddr() net.Addr {
|
|
|
|
return c.apiListenAddr
|
|
|
|
}
|
2022-11-23 05:33:23 +09:00
|
|
|
|
2023-03-07 17:07:14 +09:00
|
|
|
func configFromEnv() (*ConfigDef, error) {
|
|
|
|
cfg := ConfigDef{}
|
|
|
|
err := cleanenv.ReadEnv(&cfg)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, 0)
|
2022-11-21 16:17:02 +09:00
|
|
|
}
|
2023-03-07 17:07:14 +09:00
|
|
|
return &cfg, nil
|
|
|
|
}
|
2022-11-21 16:17:02 +09:00
|
|
|
|
2023-03-07 17:07:14 +09:00
|
|
|
var config *ConfigDef
|
|
|
|
|
|
|
|
func LoadCfg() error {
|
|
|
|
cfg, err := configFromEnv()
|
|
|
|
if err != nil {
|
|
|
|
return errors.WrapPrefix(err, "failed to load config from environment", 0)
|
|
|
|
}
|
|
|
|
if err = cfg.Parse(); err != nil {
|
|
|
|
return errors.WrapPrefix(err, "failed to parse config", 0)
|
2022-11-21 04:39:21 +09:00
|
|
|
}
|
|
|
|
|
2023-03-07 17:07:14 +09:00
|
|
|
config = cfg
|
2022-11-21 04:39:21 +09:00
|
|
|
return nil
|
|
|
|
}
|