common

package
v2.49.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 20, 2024 License: MIT Imports: 37 Imported by: 55

Documentation

Overview

this package provides core functionality to yagpdb, important security stuff here

this package provides core functionality to yagpdb, important security stuff here

this package provides core functionality to yagpdb, important security stuff here

Index

Constants

View Source
const CoreServerConfDBSchema = `` /* 237-byte string literal not displayed */
View Source
const ServicesRedisKey = "yag_services"

Variables

View Source
var (
	ErrNotFound    = errors.New("Not found")
	CacheKeyPrefix = "cache_"

	Cache *ccache.Cache
)
View Source
var (
	VERSION = "unknown"

	PQ   *sql.DB
	SQLX *sqlx.DB

	RedisPool *radix.Pool
	CacheSet  = cacheset.NewManager(time.Hour)

	BotSession     *discordgo.Session
	BotUser        *discordgo.User
	BotApplication *discordgo.Application

	RedisPoolSize = 0

	Testing = os.Getenv("YAGPDB_TESTING") != ""

	CurrentRunCounter int64

	NodeID string
)
View Source
var (
	ConfClientID     = config.RegisterOption("yagpdb.clientid", "Client ID of the discord application", nil)
	ConfClientSecret = config.RegisterOption("yagpdb.clientsecret", "Client Secret of the discord application", nil)
	ConfBotToken     = config.RegisterOption("yagpdb.bottoken", "Token of the bot user", nil)
	ConfHost         = config.RegisterOption("yagpdb.host", "Host without the protocol, example: example.com, used by the webserver", nil)
	ConfEmail        = config.RegisterOption("yagpdb.email", "Email used when fetching lets encrypt certificate", "")

	ConfPQHost     = config.RegisterOption("yagpdb.pqhost", "Postgres host", "localhost")
	ConfPQUsername = config.RegisterOption("yagpdb.pqusername", "Postgres user", "postgres")
	ConfPQPassword = config.RegisterOption("yagpdb.pqpassword", "Postgres passoword", "")
	ConfPQDB       = config.RegisterOption("yagpdb.pqdb", "Postgres database", "yagpdb")

	ConfMaxCCR            = config.RegisterOption("yagpdb.max_ccr", "Maximum number of concurrent outgoing requests to discord", 25)
	ConfDisableKeepalives = config.RegisterOption("yagpdb.disable_keepalives", "Disables keepalive connections for outgoing requests to discord, this shouldn't be needed but i had networking issues once so i had to", false)

	ConfTotalShards             = config.RegisterOption("yagpdb.sharding.total_shards", "Total number shards", 0)
	ConfActiveShards            = config.RegisterOption("yagpdb.sharding.active_shards", "Shards active on this hoste, ex: '1-10,25'", "")
	ConfLargeBotShardingEnabled = config.RegisterOption("yagpdb.large_bot_sharding", "Set to enable large bot sharding (for 200k+ guilds)", false)
	ConfBucketsPerNode          = config.RegisterOption("yagpdb.shard.buckets_per_node", "Number of buckets per node", 8)
	ConfShardBucketSize         = config.RegisterOption("yagpdb.shard.shard_bucket_size", "Shards per bucket", 2)
	ConfHttpProxy               = config.RegisterOption("yagpdb.http.proxy", "Proxy Url", "")

	BotOwners []int64
)
View Source
var (
	PluginCategoryCore       = &PluginCategory{Name: "Core", Order: 0}
	PluginCategoryModeration = &PluginCategory{Name: "Moderation", Order: 10}
	PluginCategoryMisc       = &PluginCategory{Name: "Misc", Order: 20}
	PluginCategoryFeeds      = &PluginCategory{Name: "Feeds", Order: 30}
)
View Source
var Adjectives = []string{}/* 4910 elements not displayed */
View Source
var CoreServerConfigCache = rcache.NewInt(coreServerConfigCacheFetcher, time.Minute)
View Source
var DiscordInviteSource = &InviteSource{
	Name:  "Discord",
	Regex: regexp.MustCompile(`(?i)(discord\.gg|discordapp\.com\/+invite|discord\.com\/+invite)(?:\/+#)?\/+([a-zA-Z0-9-]+)`),
}
View Source
var DomainFinderRegex = regexp.MustCompile(`(?i)(?:[a-z\d](?:[a-z\d-]{0,61}[a-z\d])?\.)+[a-z\d][a-z\d-]{0,61}[a-z\d]`)
View Source
var (
	ErrMaxLockAttemptsExceeded = errors.New("Max lock attempts exceeded")
)
View Source
var ExecutedCommandDBSchemas = []string{`
CREATE TABLE IF NOT EXISTS executed_commands (
	id SERIAL PRIMARY KEY,
	created_at TIMESTAMP WITH TIME ZONE NOT NULL,
	updated_at TIMESTAMP WITH TIME ZONE NOT NULL,

	user_id TEXT NOT NULL, -- text not bigint for legacy compatibility
	channel_id TEXT NOT NULL,
	guild_id TEXT,

	command TEXT NOT NULL,
	raw_command TEXT NOT NULL,
	error TEXT,

	time_stamp TIMESTAMP WITH TIME ZONE NOT NULL,
	response_time BIGINT NOT NULL
);
`, `
-- Preexisting tables created prior to sqlboiler are missing non-null constraints,
-- so add them retraoctively.

ALTER TABLE executed_commands ALTER COLUMN created_at SET NOT NULL;
`, `
ALTER TABLE executed_commands ALTER COLUMN updated_at SET NOT NULL;
`, `
ALTER TABLE executed_commands ALTER COLUMN user_id SET NOT NULL;
`, `
ALTER TABLE executed_commands ALTER COLUMN channel_id SET NOT NULL;
`, `
ALTER TABLE executed_commands ALTER COLUMN command SET NOT NULL;
`, `
ALTER TABLE executed_commands ALTER COLUMN raw_command SET NOT NULL;
`, `
ALTER TABLE executed_commands ALTER COLUMN time_stamp SET NOT NULL;
`, `
ALTER TABLE executed_commands ALTER COLUMN response_time SET NOT NULL;
`}
View Source
var ForwardSlashReplacer = strings.NewReplacer("\\", "")
View Source
var LinkRegex = regexp.MustCompile(`(?i)([a-z\d]+://)([\w\W_-]+(?:(?:\.[\w\W_-]+)+))([\w\W.,@?^=%&:/~+#-]*[\w\W@?^=%&/~+#-])`)
View Source
var Nouns = []string{}/* 2444 elements not displayed */
View Source
var (
	Plugins []Plugin
)
View Source
var RedisAddr = loadRedisAddr()
View Source
var ServicePoller = &servicePoller{}
View Source
var ServiceTracker = newServiceTracker()

ServiceTracker keeps track of the various components of yagpdb in a central location for ease of access

View Source
var StringPerms = map[int64]string{
	discordgo.PermissionViewChannel:        "View Channel",
	discordgo.PermissionSendMessages:       "Send Messages",
	discordgo.PermissionSendTTSMessages:    "Send TTS Messages",
	discordgo.PermissionManageMessages:     "Manage Messages",
	discordgo.PermissionEmbedLinks:         "Embed Links",
	discordgo.PermissionAttachFiles:        "Attach Files",
	discordgo.PermissionReadMessageHistory: "Read Message History",
	discordgo.PermissionMentionEveryone:    "Mention Everyone",
	discordgo.PermissionVoiceConnect:       "Voice Connect",
	discordgo.PermissionVoiceSpeak:         "Voice Speak",
	discordgo.PermissionVoiceMuteMembers:   "Voice Mute Members",
	discordgo.PermissionVoiceDeafenMembers: "Voice Deafen Members",
	discordgo.PermissionVoiceMoveMembers:   "Voice Move Members",
	discordgo.PermissionVoiceUseVAD:        "Voice Use VAD",

	discordgo.PermissionCreateInstantInvite: "Create Instant Invite",
	discordgo.PermissionKickMembers:         "Kick Members",
	discordgo.PermissionBanMembers:          "Ban Members",
	discordgo.PermissionManageRoles:         "Manage Roles",
	discordgo.PermissionManageChannels:      "Manage Channels",
	discordgo.PermissionManageGuild:         "Manage Guild",
	discordgo.PermissionManageWebhooks:      "Manage Webhooks",
	discordgo.PermissionModerateMembers:     "Moderate Members / Timeout Members",
}
View Source
var ThirdpartyDiscordSites = []*InviteSource{
	{Name: "discord.me", Regex: regexp.MustCompile(`(?i)discord\.me\/+.+`)},
	{Name: "invite.gg", Regex: regexp.MustCompile(`(?i)invite\.gg\/+.+`)},
	{Name: "discord.io", Regex: regexp.MustCompile(`(?i)discord\.io\/+.+`)},
	{Name: "discord.li", Regex: regexp.MustCompile(`(?i)discord\.li\/+.+`)},
	{Name: "disboard.org", Regex: regexp.MustCompile(`(?i)disboard\.org\/+server\/+join\/+.+`)},
	{Name: "discordy.com", Regex: regexp.MustCompile(`(?i)discordy\.com\/+server\+.php`)},
}
View Source
var UGCHtmlPolicy = bluemonday.NewPolicy().AllowElements("h1", "h2", "h3", "h4", "h5", "h6", "p", "ol", "ul", "li", "dl", "dd", "dt", "blockquote", "table", "thead", "th", "tr", "td", "tbody", "del", "i", "b")
View Source
var Verbs = []string{}/* 6056 elements not displayed */

Functions

func AddCPLogEntry

func AddCPLogEntry(user *discordgo.User, guild int64, args ...interface{})

func AddCPLogEntryLegacy

func AddCPLogEntryLegacy(user *discordgo.User, guild int64, args ...interface{})

func AddLogHook

func AddLogHook(hook logrus.Hook)

func AddRole

func AddRole(member *discordgo.Member, role int64, guildID int64) error

func AddRoleDS

func AddRoleDS(ms *dstate.MemberState, role int64) error

func Base64DecodeToString added in v2.33.0

func Base64DecodeToString(str string) (string, error)

func BlockingLockRedisKey

func BlockingLockRedisKey(key string, maxTryDuration time.Duration, maxLockDur int) error

BlockingLockRedisKey blocks until it suceeded to lock the key

func BoolToPointer added in v2.15.2

func BoolToPointer(b bool) *bool

func BotIsOnGuild

func BotIsOnGuild(guildID int64) (bool, error)

func ChannelOrThreadParentID

func ChannelOrThreadParentID(cs *dstate.ChannelState) int64

ChannelOrThreadParentID returns either cs.ID for channels or cs.ParentID for threads

func ContainsInt64Slice

func ContainsInt64Slice(slice []int64, search int64) bool

func ContainsInt64SliceOneOf

func ContainsInt64SliceOneOf(slice []int64, search []int64) bool

ContainsInt64SliceOneOf returns true if slice contains one of search

func ContainsIntSlice

func ContainsIntSlice(slice []int, search int) bool

func ContainsStringSlice

func ContainsStringSlice(strs []string, search string) bool

func ContainsStringSliceFold

func ContainsStringSliceFold(strs []string, search string) bool

func ContextCoreConf

func ContextCoreConf(ctx context.Context) *models.CoreConfig

func CoreConfigSave

func CoreConfigSave(ctx context.Context, m *models.CoreConfig) error

func CoreInit

func CoreInit(loadConfig bool) error

CoreInit initializes the essential parts

func CutStringShort

func CutStringShort(s string, l int) string

CutStringShort stops a strinng at "l"-3 if it's longer than "l" and adds "..."

func DelayedMessageDelete

func DelayedMessageDelete(session *discordgo.Session, delay time.Duration, cID, mID int64)

DelayedMessageDelete Deletes a message after delay

func DiscordError

func DiscordError(err error) (code int, msg string)

DiscordError extracts the errorcode discord sent us

func DiscordGatewayLogger

func DiscordGatewayLogger(shardID int, connectionID int, msgL int, msgf string, args ...interface{})

func ErrPQIsUniqueViolation

func ErrPQIsUniqueViolation(err error) bool

func ErrWithCaller

func ErrWithCaller(err error) error

func FallbackEmbed

func FallbackEmbed(embed *discordgo.MessageEmbed) string

func FormatList added in v2.2.0

func FormatList(list []string, conjunction string) string

func GenLocalIncrID

func GenLocalIncrID(guildID int64, key string) (int64, error)

GenLocalIncrID creates a new or incremements a existing local id incrememter used to have per guild id's

GenLocalIncrID is deprecated and GenLocalIncrIDPQ should be used instead

func GenLocalIncrIDPQ

func GenLocalIncrIDPQ(tx *sql.Tx, guildID int64, key string) (int64, error)

GenLocalIncrIDPQ creates a new or incremements a existing local id incrememter used to have per guild id's

GenLocalIncrIDPQ differs from GenLocalIncrID in that it uses postgres instead of redis

func GetActiveNodes

func GetActiveNodes() ([]string, error)

func GetBotToken

func GetBotToken() string

func GetCacheData

func GetCacheData(key string) (data []byte, err error)

Items in the cache expire after 1 min

func GetCacheDataJson

func GetCacheDataJson(key string, dest interface{}) error

func GetCoreServerConfCached

func GetCoreServerConfCached(guildID int64) *models.CoreConfig

func GetFixedPrefixLogger

func GetFixedPrefixLogger(prefix string) *logrus.Entry

func GetJoinedServerCount

func GetJoinedServerCount() (int64, error)

func GetPluginLogger

func GetPluginLogger(plugin Plugin) *logrus.Entry

func GetRedisJson

func GetRedisJson(key string, out interface{}) error

GetRedisJson executes a get redis command and unmarshals the value into out

func HumanizeDuration

func HumanizeDuration(precision DurationFormatPrecision, in time.Duration) string

func HumanizePermissions

func HumanizePermissions(perms int64) (res []string)

func HumanizeTime

func HumanizeTime(precision DurationFormatPrecision, in time.Time) string

func Init

func Init() error

Init initializes the rest of the bot

func InitSchemas

func InitSchemas(name string, schemas ...string)

func InitTest

func InitTest()

func InitTestRedis

func InitTestRedis() error

InitTestRedis sets common.RedisPool to a redis pool for unit testing

func IsDiscordErr

func IsDiscordErr(err error, codes ...int) bool

IsDiscordErr returns true if this was a discord error and one of the codes matches

func IsNumber

func IsNumber(v interface{}) bool

func IsOwner

func IsOwner(userID int64) bool

func IsRoleAbove

func IsRoleAbove(a, b *discordgo.Role) bool

IsRoleAbove returns whether role a is above b, checking positions first, and if they're the same (both being 1, new roles always have 1 as position) then it checks by lower id

func KeyGuild

func KeyGuild(guildID int64) string

func KeyGuildChannels

func KeyGuildChannels(guildID int64) string

func LoadConfig

func LoadConfig() (err error)

func LogIgnoreError

func LogIgnoreError(err error, msg string, data logrus.Fields)

func LogLongCallTime

func LogLongCallTime(treshold time.Duration, isErr bool, logMsg string, extraData logrus.Fields, f func())

func MultipleCmds

func MultipleCmds(cmds ...radix.CmdAction) error

func MustParseInt

func MustParseInt(s string) int64

func ParseCodeblock added in v2.25.0

func ParseCodeblock(input string) string

parseCodeblock returns the content wrapped in a Discord markdown block. If no (valid) codeblock was found, the given input is returned back.

func ParseDuration

func ParseDuration(str string) (time.Duration, error)

Parses a time string like 1day3h

func RandomAdjective

func RandomAdjective() string

func RandomNoun

func RandomNoun() string

func RandomVerb added in v2.2.0

func RandomVerb() string

func RegisterDBSchemas

func RegisterDBSchemas(name string, schemas ...string)

func RegisterPlugin

func RegisterPlugin(plugin Plugin)

RegisterPlugin registers a plugin, should be called when the bot is starting up

func RemoveRole

func RemoveRole(member *discordgo.Member, role int64, guildID int64) error

func RemoveRoleDS

func RemoveRoleDS(ms *dstate.MemberState, role int64) error

func ReplaceServerInvites

func ReplaceServerInvites(msg string, guildID int64, replacement string) string

func RunCommonRunPlugins

func RunCommonRunPlugins()

RunCommonRunPlugins runs plugins that implement PluginWithCommonRun

func SendOwnerAlert

func SendOwnerAlert(msgf string, args ...interface{})

func SendTempMessage

func SendTempMessage(session *discordgo.Session, duration time.Duration, cID int64, msg string)

SendTempMessage sends a message that gets deleted after duration

func SetCacheData

func SetCacheData(key string, expire int, data []byte) error

Stores an entry in the cache and sets it to expire after expire

func SetCacheDataJson

func SetCacheDataJson(key string, expire int, data interface{}) error

Helper methods

func SetCacheDataJsonSimple

func SetCacheDataJsonSimple(key string, data interface{}) error

func SetCacheDataSimple

func SetCacheDataSimple(key string, data []byte) error

Stores an entry in the cache and sets it to expire after a minute

func SetLogFormatter

func SetLogFormatter(formatter logrus.Formatter)

func SetLoggingLevel

func SetLoggingLevel(level logrus.Level)

func SetRedisJson

func SetRedisJson(key string, value interface{}) error

SetRedisJson marshals the value and runs a set redis command for key

func SetShutdownFunc

func SetShutdownFunc(f func())

func Shutdown

func Shutdown()

func SplitSendMessage

func SplitSendMessage(channelID int64, contents string, allowedMentions discordgo.AllowedMentions) ([]*discordgo.Message, error)

func SqlTX

func SqlTX(f func(tx *sql.Tx) error) error

helper for creating transactions

func TableExists

func TableExists(table string) (b bool, err error)

func TryLockRedisKey

func TryLockRedisKey(key string, maxDur int) (bool, error)

Locks the lock and if succeded sets it to expire after maxdur So that if someting went wrong its not locked forever

func UnlockRedisKey

func UnlockRedisKey(key string)

Types

type BotServiceDetails

type BotServiceDetails struct {
	RunningShards    []int  `json:"running_shards"`
	TotalShards      int    `json:"total_shards"`
	NodeID           string `json:"node_id"`
	OrchestratorMode bool   `json:"orchestrator_mode"`
}

BotServiceDetails is bot service specific details

type CPLogEntryLegacy

type CPLogEntryLegacy struct {
	Timestamp int64  `json:"ts"`
	Action    string `json:"action"`

	TimestampString string `json:"-"`
}

func GetCPLogEntriesLegacy

func GetCPLogEntriesLegacy(guild int64) ([]*CPLogEntryLegacy, error)

type ContextHook

type ContextHook struct{}

func (ContextHook) Fire

func (hook ContextHook) Fire(entry *logrus.Entry) error

func (ContextHook) Levels

func (hook ContextHook) Levels() []logrus.Level

type ContextKey

type ContextKey int
const (
	ContextKeyRedis ContextKey = iota
	ContextKeyDiscordSession
	ContextKeyYagToken
	ContextKeyTemplateData
	ContextKeyUser
	ContextKeyCurrentGuild
	ContextKeyGuildRoles
	ContextKeyParsedForm
	ContextKeyFormOk
	ContextKeyBotMember
	ContextKeyBotPermissions
	ContextKeyHighestBotRole
	ContextKeyLogger
	ContextKeyIsPartial
	ContextKeyUserMember
	ContextKeyCoreConfig
	ContextKeyMemberPermissions
	ContextKeyIsAdmin
	ContextKeyIsReadOnly
)

type DBSchema

type DBSchema struct {
	Name    string
	Schemas []string
}

type DiscordChannels

type DiscordChannels []*discordgo.Channel

Channels are a collection of Channels

func (DiscordChannels) Len

func (r DiscordChannels) Len() int

func (DiscordChannels) Less

func (r DiscordChannels) Less(i, j int) bool

func (DiscordChannels) Swap

func (r DiscordChannels) Swap(i, j int)

type DiscordRoles

type DiscordRoles []*discordgo.Role

func (DiscordRoles) Len

func (r DiscordRoles) Len() int

func (DiscordRoles) Less

func (r DiscordRoles) Less(i, j int) bool

func (DiscordRoles) Swap

func (r DiscordRoles) Swap(i, j int)

type DurationFormatPrecision

type DurationFormatPrecision int
const (
	DurationPrecisionSeconds DurationFormatPrecision = iota
	DurationPrecisionMinutes
	DurationPrecisionHours
	DurationPrecisionDays
	DurationPrecisionWeeks
	DurationPrecisionYears
)

func (DurationFormatPrecision) FromSeconds

func (d DurationFormatPrecision) FromSeconds(in int64) int64

func (DurationFormatPrecision) String

func (d DurationFormatPrecision) String() string

type GuildWithConnected

type GuildWithConnected struct {
	*discordgo.UserGuild
	Connected bool
}

func GetGuildsWithConnected

func GetGuildsWithConnected(in []*discordgo.UserGuild) ([]*GuildWithConnected, error)

GetGuildsWithConnected Returns a wrapped guild with connected set

type InviteSource

type InviteSource struct {
	Name  string
	Regex *regexp.Regexp
}

func ContainsInvite

func ContainsInvite(s string, checkDiscordSource, checkThirdPartySources bool) *InviteSource

type LoggingTransport

type LoggingTransport struct {
	Inner http.RoundTripper
}

func (*LoggingTransport) RoundTrip

func (t *LoggingTransport) RoundTrip(request *http.Request) (*http.Response, error)

type Plugin

type Plugin interface {
	PluginInfo() *PluginInfo
}

Plugin represents a plugin, all plugins needs to implement this at a bare minimum

type PluginCategory

type PluginCategory struct {
	Name  string
	Order int
}

type PluginInfo

type PluginInfo struct {
	Name     string // Human readable name of the plugin
	SysName  string // snake_case version of the name in lower case
	Category *PluginCategory
}

PluginInfo represents basic plugin information

type PluginWithCommonRun

type PluginWithCommonRun interface {
	CommonRun()
}

PluginWithCommonRun is for plugins that include a function that's always run, no matter if its the webserver frontend, bot or whatever

type STDLogProxy

type STDLogProxy struct{}

func (*STDLogProxy) Write

func (p *STDLogProxy) Write(b []byte) (n int, err error)

type Service

type Service struct {
	Type    ServiceType `json:"type"`
	Name    string      `json:"name"`
	Details string      `json:"details"`

	BotDetails *BotServiceDetails `json:"bot_details"`
	// contains filtered or unexported fields
}

Service represents a service or component of yagpdb

type ServiceHost

type ServiceHost struct {
	InternalAPIAddress string `json:"internal_api_address"`
	Host               string `json:"host"`
	PID                int    `json:"pid"`
	Version            string `json:"version"`

	Services []*Service `json:"services"`
}

ServiceHost represents a process that holds oen or more bot components

type ServiceType

type ServiceType string

ServiceType represents the type of the component

const (
	ServiceTypeBot           ServiceType = "bot"
	ServiceTypeFrontend      ServiceType = "frontend"
	ServiceTypeBGWorker      ServiceType = "bgworker"
	ServiceTypeConfigService ServiceType = "configservice"
	ServiceTypeFeed          ServiceType = "feed"
	ServiceTypeOrchestator   ServiceType = "orchestrator"
)

Directories

Path Synopsis
Package pqkeydb is a simple key-value database on top of postgres
Package pqkeydb is a simple key-value database on top of postgres

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL