Update to Go-1.25.3
Some checks failed
release-tag / release-image (push) Failing after 25s

This commit is contained in:
2025-10-21 07:20:01 +02:00
parent b66b17d095
commit 3c2ae9a10e
3 changed files with 73 additions and 44 deletions

View File

@@ -1,12 +1,12 @@
# -------- Dockerfile (Multi-Stage Build) -------- # -------- Dockerfile (Multi-Stage Build) --------
# 1. Builder-Stage # 1. Builder-Stage
FROM golang:1.24-alpine AS builder FROM golang:1.25-alpine AS builder
WORKDIR /app WORKDIR /app
COPY go.* ./ COPY go.* ./
RUN go mod download RUN go mod download
COPY . . COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /bin/autovoice RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /bin/vocalforge
# 2. Runtime-Stage # 2. Runtime-Stage
FROM alpine:3.22 FROM alpine:3.22
@@ -16,7 +16,7 @@ RUN apk add --no-cache ca-certificates
#RUN mkdir /data #RUN mkdir /data
#RUN mkdir /dynamicsrc #RUN mkdir /dynamicsrc
RUN mkdir /tempsrc RUN mkdir /tempsrc
COPY --from=builder /bin/autovoice /bin/autovoice COPY --from=builder /bin/vocalforge /bin/vocalforge
#COPY ./static /data/static #COPY ./static /data/static
COPY ./language.json /tempsrc/language.json COPY ./language.json /tempsrc/language.json
#COPY ./dynamicsrc /dynamicsrc #COPY ./dynamicsrc /dynamicsrc
@@ -25,13 +25,12 @@ COPY ./language.json /tempsrc/language.json
EXPOSE 8080 EXPOSE 8080
# Environment defaults; können per compose überschrieben werden # Environment defaults; können per compose überschrieben werden
ENV LOBBY_CHANNEL_ID=0 \ ENV PRESENCE_GUILD_ID=0 \
DISCORD_TOKEN=0 \ DB_PATH=/data/guild_config.db \
GUILD_ID=0 \
CATEGORY_ID=0 \
TIMEOUT_MIN=1 \ TIMEOUT_MIN=1 \
CONFIG_PATH=/data/guild_config.json DISCORD_TOKEN=0 \
TRANSLATIONS_FILE=/tempsrc/language.json
VOLUME /data
ENTRYPOINT ["/bin/vocalforge"]
ENTRYPOINT ["/bin/autovoice"]

2
go.mod
View File

@@ -1,6 +1,6 @@
module discord-auto-voice module discord-auto-voice
go 1.24.4 go 1.25.3
require github.com/bwmarrin/discordgo v0.29.0 require github.com/bwmarrin/discordgo v0.29.0

94
main.go
View File

@@ -30,7 +30,7 @@ var dbPath = func() string {
}() }()
// irgendwo global // irgendwo global
var presenceGuildID = GetENV("DB_PATH", "") var presenceGuildID = GetENV("PRESENCE_GUILD_ID", "")
// ===== Per-Guild Config (in-memory) ===== // ===== Per-Guild Config (in-memory) =====
type GuildConfig struct { type GuildConfig struct {
@@ -174,6 +174,19 @@ func initDB() {
addLanguageColumnIfNotExists() addLanguageColumnIfNotExists()
ensureLobbyRuleTable() ensureLobbyRuleTable()
_, _ = db.Exec(`
CREATE TABLE IF NOT EXISTS eventlog(
id INTEGER PRIMARY KEY AUTOINCREMENT,
guild_id TEXT NOT NULL,
type TEXT NOT NULL, -- z.B. 'vc_created' | 'vc_deleted' | 'member_moved'
channel_id TEXT,
user_id TEXT,
ts INTEGER NOT NULL, -- unix seconds
extra TEXT
);
CREATE INDEX IF NOT EXISTS idx_eventlog_guild_ts ON eventlog(guild_id, ts DESC);
`)
} }
// Close DB connection // Close DB connection
@@ -183,6 +196,21 @@ func closeDB() {
} }
} }
func logEvent(gid, typ, chID, userID string, extra any) {
if db == nil {
return
}
var extraJSON string
if extra != nil {
if b, err := json.Marshal(extra); err == nil {
extraJSON = string(b)
}
}
_, _ = db.Exec(`INSERT INTO eventlog(guild_id, type, channel_id, user_id, ts, extra)
VALUES(?,?,?,?,?,?)`,
gid, typ, chID, userID, time.Now().Unix(), extraJSON)
}
// Laden der Guild-Konfiguration mit Sprache // Laden der Guild-Konfiguration mit Sprache
func loadGuildCfgs() error { func loadGuildCfgs() error {
rows, err := db.Query("SELECT guild_id, lobby_name, category_name, timeout_min, language FROM guild_config") rows, err := db.Query("SELECT guild_id, lobby_name, category_name, timeout_min, language FROM guild_config")
@@ -500,6 +528,10 @@ func createPrivateVCAndMove(
}) })
if err != nil { if err != nil {
return nil, fmt.Errorf("VC-Anlage fehlgeschlagen: %w", err) return nil, fmt.Errorf("VC-Anlage fehlgeschlagen: %w", err)
} else {
logEvent(guildID, "vc_created", newChan.ID, requesterID, map[string]any{
"name": newChan.Name, "timeout_min": timeoutMin,
})
} }
// optionaler Move // optionaler Move
@@ -532,6 +564,9 @@ func createPrivateVCAndMove(
if moveErr != nil { if moveErr != nil {
log.Printf("Move endgültig fehlgeschlagen: %v", moveErr) log.Printf("Move endgültig fehlgeschlagen: %v", moveErr)
} }
if moveErr == nil {
logEvent(guildID, "member_moved", newChan.ID, requesterID, nil)
}
}() }()
} }
@@ -567,6 +602,7 @@ func watchAndCleanup(s *discordgo.Session, guildID, channelID string, timeout ti
if time.Since(lastActive) >= timeout { if time.Since(lastActive) >= timeout {
_, _ = s.ChannelDelete(channelID) _, _ = s.ChannelDelete(channelID)
log.Println(" Deleted channel for guildID: " + guildID + " with ID: " + channelID) log.Println(" Deleted channel for guildID: " + guildID + " with ID: " + channelID)
logEvent(guildID, "vc_deleted", channelID, "", nil)
return return
} }
} }
@@ -1282,39 +1318,33 @@ var privateCommands = []*discordgo.ApplicationCommand{
}, },
} }
func registerCommandsForGuild(s *discordgo.Session, guildID string) {
appID := s.State.User.ID
// Basis-Commands für alle
cmds := make([]*discordgo.ApplicationCommand, 0, len(slashCommands)+len(privateCommands))
cmds = append(cmds, slashCommands...)
// Private Commands nur für Owner-Guild
if presenceGuildID != "" && guildID == presenceGuildID {
cmds = append(cmds, privateCommands...)
}
// Atomar überschreiben → keine Duplikate / keine alten Schemas
created, err := s.ApplicationCommandBulkOverwrite(appID, guildID, cmds)
if err != nil {
log.Printf("BulkOverwrite %s failed: %v", guildID, err)
return
}
createdCmds.Store(guildID, created)
log.Printf("Registered %d commands in guild %s", len(created), guildID)
}
// Handler: Commands registrieren, wenn Bot auf neuen Server kommt // Handler: Commands registrieren, wenn Bot auf neuen Server kommt
func onGuildCreate(s *discordgo.Session, g *discordgo.GuildCreate) { func onGuildCreate(s *discordgo.Session, g *discordgo.GuildCreate) {
appID := s.State.User.ID // Hinweis: GuildCreate feuert auch beim (Re)Connect. Genau das wollen wir hier.
log.Printf("Registriere Commands in neuer Guild: %s (%s)", g.Name, g.ID) log.Printf("GuildCreate: %s (%s) unavailable=%v", g.Name, g.ID, g.Unavailable)
for _, cmd := range slashCommands { registerCommandsForGuild(s, g.ID)
c, err := s.ApplicationCommandCreate(appID, g.ID, cmd)
if err != nil {
log.Printf("Command-Registrierung in %s fehlgeschlagen: %v", g.Name, err)
continue
}
// Commands für die Guild speichern
// Wir verwenden sync.Map, also müssen wir die 'Load' und 'Store' Methoden verwenden.
commands, _ := createdCmds.LoadOrStore(g.ID, []*discordgo.ApplicationCommand{})
commands = append(commands.([]*discordgo.ApplicationCommand), c)
createdCmds.Store(g.ID, commands)
log.Printf("Registriere Command %s in Guild %s", cmd.Name, g.Name)
}
guildID := g.ID
// Privates Kommando nur für die Presence-Guild
if presenceGuildID != "" && guildID == presenceGuildID {
for _, pc := range privateCommands {
if c, err := s.ApplicationCommandCreate(appID, guildID, pc); err != nil {
log.Printf("private cmd %s in %s failed: %v", pc.Name, guildID, err)
} else {
// an bestehende Liste anhängen
if v, ok := createdCmds.Load(guildID); ok {
createdCmds.Store(guildID, append(v.([]*discordgo.ApplicationCommand), c))
}
}
}
}
} }
// ===== Commands Definition ===== // ===== Commands Definition =====