Draft: big refactor

This commit is contained in:
2025-09-16 16:03:27 +08:00
parent f527230f1e
commit c4f2b0af25
42 changed files with 684 additions and 215 deletions

View File

@@ -3,6 +3,7 @@
SWAG ?= ~/go/bin/swag SWAG ?= ~/go/bin/swag
TARGET := $(shell find . -type f -name '*.go') TARGET := $(shell find . -type f -name '*.go')
DEST := server/docs
all: swagger docker install all: swagger docker install
@@ -17,7 +18,7 @@ game: $(TARGET)
swagger: swagger:
$(SWAG) fmt $(SWAG) fmt
$(SWAG) init -o backend/docs -g cmd/serve/backend.go -pdl 1 $(SWAG) init -o $(DEST) -g cmd/serve/backend.go -pdl 1
clean: clean:
-rm -f game -rm -f game

View File

@@ -1,29 +0,0 @@
package api
import (
"net/http"
"gitea.konchin.com/ytshih/inp2025/game/backend/middlewares"
"github.com/uptrace/bunrouter"
)
// GetLobbyRooms
//
// @Router /api/lobby/rooms [get]
func (self *Handlers) GetLobbyRooms(
w http.ResponseWriter,
req bunrouter.Request,
) error {
ctx := req.Context()
rooms, err := self.db.GetRooms(ctx)
if err != nil {
return middlewares.HTTPError{
StatusCode: http.StatusInternalServerError,
Message: "failed to get room",
OriginError: err,
}
}
return bunrouter.JSON(w, rooms)
}

View File

@@ -6,6 +6,7 @@ import (
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
"github.com/go-resty/resty/v2" "github.com/go-resty/resty/v2"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"go.uber.org/zap"
) )
var RootCmd = &cobra.Command{ var RootCmd = &cobra.Command{
@@ -15,25 +16,35 @@ var RootCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
appname := "game-tui" appname := "game-tui"
tracing.InitTracer(appname) tracing.InitTracer(appname)
defer tracing.DeferTracer()
tracing.Logger.
Info("client up")
client := resty.New(). client := resty.New().
SetBaseURL(args[0]). SetBaseURL(args[0]).
SetDisableWarn(true) SetDisableWarn(true)
queue := []*tea.Program{} queue := []*tea.Program{}
queue = append(queue, queue = append(queue, tea.NewProgram(
tea.NewProgram(plays.NewLanding(plays.NewBase(client)))) plays.NewLanding(plays.NewBase(client))))
for len(queue) > 0 { for len(queue) > 0 {
program := queue[0] program := queue[0]
queue = queue[1:] queue = queue[1:]
tracing.Logger.Info("run program")
res, err := program.Run() res, err := program.Run()
if err != nil { if err != nil {
tracing.Logger.Error("program failed",
zap.Error(err))
panic(err) panic(err)
} }
err = res.(plays.Next).Next(&queue) err = res.(plays.Next).Next(&queue)
if err != nil { if err != nil {
tracing.Logger.Error("failed to generate next program",
zap.Error(err))
panic(err) panic(err)
} }
} }
@@ -41,4 +52,7 @@ var RootCmd = &cobra.Command{
} }
func init() { func init() {
RootCmd.Flags().
String("otel-endpoint", "localhost:4317",
"endpoint for otlp exporter to connect")
} }

View File

@@ -16,11 +16,11 @@ import (
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"go.uber.org/zap" "go.uber.org/zap"
_ "gitea.konchin.com/ytshih/inp2025/game/backend/docs"
"gitea.konchin.com/ytshih/inp2025/game/backend/handlers/api"
"gitea.konchin.com/ytshih/inp2025/game/backend/handlers/auth"
"gitea.konchin.com/ytshih/inp2025/game/backend/middlewares"
"gitea.konchin.com/ytshih/inp2025/game/implements" "gitea.konchin.com/ytshih/inp2025/game/implements"
"gitea.konchin.com/ytshih/inp2025/game/server/backend/api"
"gitea.konchin.com/ytshih/inp2025/game/server/backend/auth"
_ "gitea.konchin.com/ytshih/inp2025/game/server/docs"
"gitea.konchin.com/ytshih/inp2025/game/server/middlewares"
"gitea.konchin.com/ytshih/inp2025/game/tracing" "gitea.konchin.com/ytshih/inp2025/game/tracing"
"gitea.konchin.com/ytshih/inp2025/game/utils" "gitea.konchin.com/ytshih/inp2025/game/utils"
) )
@@ -36,15 +36,16 @@ var backendCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
ctx := cmd.Context() ctx := cmd.Context()
tracing.InitTracer("game backend") tracing.InitTracer("game backend")
defer tracing.DeferTracer()
tracing.Logger.Ctx(ctx). tracing.Logger.
Debug("connect to sql", Debug("connect to sql",
zap.String("sql.url", zap.String("sql.url",
"file:"+viper.GetString("sqlite-file")+"?cache=shared&mode=rwc")) "file:"+viper.GetString("sqlite-file")+"?cache=shared&mode=rwc"))
sqldb, err := sql.Open(sqliteshim.ShimName, sqldb, err := sql.Open(sqliteshim.ShimName,
"file:"+viper.GetString("sqlite-file")+"?cache=shared&mode=rwc") "file:"+viper.GetString("sqlite-file")+"?cache=shared&mode=rwc")
if err != nil { if err != nil {
tracing.Logger.Ctx(ctx). tracing.Logger.
Panic("failed to init sqlite", Panic("failed to init sqlite",
zap.Error(err)) zap.Error(err))
panic(err) panic(err)
@@ -52,7 +53,7 @@ var backendCmd = &cobra.Command{
bunDB := bun.NewDB(sqldb, sqlitedialect.New()) bunDB := bun.NewDB(sqldb, sqlitedialect.New())
bunDB.AddQueryHook(bunotel.NewQueryHook(bunotel.WithDBName("sqlite"))) bunDB.AddQueryHook(bunotel.NewQueryHook(bunotel.WithDBName("sqlite")))
if err := utils.InitDB(ctx, bunDB); err != nil { if err := utils.InitDB(ctx, bunDB); err != nil {
tracing.Logger.Ctx(ctx). tracing.Logger.
Panic("failed to init db schema", Panic("failed to init db schema",
zap.Error(err)) zap.Error(err))
panic(err) panic(err)
@@ -91,7 +92,7 @@ var backendCmd = &cobra.Command{
apiGroup.GET("/lobby/users", apiGroup.GET("/lobby/users",
apiHandlers.GetLobbyUsers) apiHandlers.GetLobbyUsers)
tracing.Logger.Ctx(ctx). tracing.Logger.
Info("http server up", Info("http server up",
zap.String("http.port", viper.GetString("port"))) zap.String("http.port", viper.GetString("port")))
@@ -101,6 +102,8 @@ var backendCmd = &cobra.Command{
} }
func init() { func init() {
backendCmd.Flags().
String("otel-endpoint", "backend-otelcol:4317", "otelcol endpoint")
backendCmd.Flags(). backendCmd.Flags().
String("port", "8080", "Port to listen on") String("port", "8080", "Port to listen on")
backendCmd.Flags(). backendCmd.Flags().

View File

@@ -1,9 +1,28 @@
--- ---
services: services:
backend-otelcol:
image: otel/opentelemetry-collector-contrib
command:
- --config=/etc/otelcol/config.yaml
volumes:
- ./docker/otelcol/config.yaml:/etc/otelcol/config.yaml
backend: backend:
build: build:
context: . context: .
env_file: ./backend/.env env_file: ./server/.env
ports: ports:
- 8081:8080 - 8081:8080
restart: unless-stopped restart: unless-stopped
depends_on:
- backend-otelcol
client-otelcol:
image: otel/opentelemetry-collector-contrib
command:
- --config=/etc/otelcol/config.yaml
ports:
- 4317:4317
- 4318:4318
volumes:
- ./docker/otelcol/config.yaml:/etc/otelcol/config.yaml

View File

@@ -1,19 +1,17 @@
receivers: receivers:
otlp: otlp:
protocols: protocols:
http: 0.0.0.0:4138 grpc:
grpc: 0.0.0.0:4137 endpoint: 0.0.0.0:4317
http:
processors: endpoint: 0.0.0.0:4318
batch:
exporters: exporters:
logging: debug:
loglevel: debug verbosity: detailed
service: service:
pipelines: pipelines:
logs: logs:
receivers: [otlp] receivers: [otlp]
processors: [batch] exporters: [debug]
exporters: [logging]

26
go.mod
View File

@@ -23,7 +23,7 @@ require (
github.com/KyleBanks/depth v1.2.1 // indirect github.com/KyleBanks/depth v1.2.1 // indirect
github.com/atotto/clipboard v0.1.4 // indirect github.com/atotto/clipboard v0.1.4 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/cenkalti/backoff/v5 v5.0.2 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect
github.com/charmbracelet/bubbles v0.21.0 // indirect github.com/charmbracelet/bubbles v0.21.0 // indirect
github.com/charmbracelet/bubbletea v1.3.7 // indirect github.com/charmbracelet/bubbletea v1.3.7 // indirect
github.com/charmbracelet/colorprofile v0.3.2 // indirect github.com/charmbracelet/colorprofile v0.3.2 // indirect
@@ -44,7 +44,8 @@ require (
github.com/go-resty/resty/v2 v2.16.5 // indirect github.com/go-resty/resty/v2 v2.16.5 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect github.com/gorilla/websocket v1.5.3 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect
github.com/josharian/intern v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect
@@ -77,28 +78,31 @@ require (
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/bridges/otelzap v0.13.0 // indirect
go.opentelemetry.io/contrib/instrumentation/runtime v0.62.0 // indirect go.opentelemetry.io/contrib/instrumentation/runtime v0.62.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.13.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.13.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.37.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.37.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 // indirect
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0 // indirect
go.opentelemetry.io/otel/log v0.13.0 // indirect go.opentelemetry.io/otel/log v0.14.0 // indirect
go.opentelemetry.io/otel/metric v1.38.0 // indirect go.opentelemetry.io/otel/metric v1.38.0 // indirect
go.opentelemetry.io/otel/sdk v1.38.0 // indirect go.opentelemetry.io/otel/sdk v1.38.0 // indirect
go.opentelemetry.io/otel/sdk/log v0.13.0 // indirect go.opentelemetry.io/otel/sdk/log v0.14.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect
go.opentelemetry.io/proto/otlp v1.7.0 // indirect go.opentelemetry.io/proto/otlp v1.7.1 // indirect
go.uber.org/multierr v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect
golang.org/x/exp v0.0.0-20250711185948-6ae5c78190dc // indirect golang.org/x/exp v0.0.0-20250711185948-6ae5c78190dc // indirect
golang.org/x/net v0.42.0 // indirect golang.org/x/net v0.43.0 // indirect
golang.org/x/sys v0.36.0 // indirect golang.org/x/sys v0.36.0 // indirect
golang.org/x/text v0.28.0 // indirect golang.org/x/text v0.28.0 // indirect
golang.org/x/tools v0.35.0 // indirect golang.org/x/tools v0.35.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect
google.golang.org/grpc v1.73.0 // indirect google.golang.org/grpc v1.75.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect google.golang.org/protobuf v1.36.8 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
modernc.org/libc v1.66.3 // indirect modernc.org/libc v1.66.3 // indirect
modernc.org/mathutil v1.7.1 // indirect modernc.org/mathutil v1.7.1 // indirect

30
go.sum
View File

@@ -6,6 +6,8 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8=
github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
github.com/charmbracelet/bubbles v0.21.0 h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u6mfQdFs= github.com/charmbracelet/bubbles v0.21.0 h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u6mfQdFs=
github.com/charmbracelet/bubbles v0.21.0/go.mod h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg= github.com/charmbracelet/bubbles v0.21.0/go.mod h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg=
github.com/charmbracelet/bubbletea v1.3.7 h1:FNaEEFEenOEPnZsY9MI64thl2c84MI66+1QaQbxGOl4= github.com/charmbracelet/bubbletea v1.3.7 h1:FNaEEFEenOEPnZsY9MI64thl2c84MI66+1QaQbxGOl4=
@@ -67,8 +69,12 @@ github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17k
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
@@ -181,18 +187,26 @@ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavM
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/contrib/bridges/otelzap v0.13.0 h1:aBKdhLVieqvwWe9A79UHI/0vgp2t/s2euY8X59pGRlw=
go.opentelemetry.io/contrib/bridges/otelzap v0.13.0/go.mod h1:SYqtxLQE7iINgh6WFuVi2AI70148B8EI35DSk0Wr8m4=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg=
go.opentelemetry.io/contrib/instrumentation/runtime v0.62.0 h1:ZIt0ya9/y4WyRIzfLC8hQRRsWg0J9M9GyaGtIMiElZI= go.opentelemetry.io/contrib/instrumentation/runtime v0.62.0 h1:ZIt0ya9/y4WyRIzfLC8hQRRsWg0J9M9GyaGtIMiElZI=
go.opentelemetry.io/contrib/instrumentation/runtime v0.62.0/go.mod h1:F1aJ9VuiKWOlWwKdTYDUp1aoS0HzQxg38/VLxKmhm5U= go.opentelemetry.io/contrib/instrumentation/runtime v0.62.0/go.mod h1:F1aJ9VuiKWOlWwKdTYDUp1aoS0HzQxg38/VLxKmhm5U=
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0 h1:OMqPldHt79PqWKOMYIAQs3CxAi7RLgPxwfFSwr4ZxtM=
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0/go.mod h1:1biG4qiqTxKiUCtoWDPpL3fB3KxVwCiGw81j3nKMuHE=
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.13.0 h1:zUfYw8cscHHLwaY8Xz3fiJu+R59xBnkgq2Zr1lwmK/0= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.13.0 h1:zUfYw8cscHHLwaY8Xz3fiJu+R59xBnkgq2Zr1lwmK/0=
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.13.0/go.mod h1:514JLMCcFLQFS8cnTepOk6I09cKWJ5nGHBxHrMJ8Yfg= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.13.0/go.mod h1:514JLMCcFLQFS8cnTepOk6I09cKWJ5nGHBxHrMJ8Yfg=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.37.0 h1:9PgnL3QNlj10uGxExowIDIZu66aVBwWhXmbOp1pa6RA= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.37.0 h1:9PgnL3QNlj10uGxExowIDIZu66aVBwWhXmbOp1pa6RA=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.37.0/go.mod h1:0ineDcLELf6JmKfuo0wvvhAVMuxWFYvkTin2iV4ydPQ= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.37.0/go.mod h1:0ineDcLELf6JmKfuo0wvvhAVMuxWFYvkTin2iV4ydPQ=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 h1:bDMKF3RUSxshZ5OjOTi8rsHGaPKsAt76FaqgvIUySLc= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 h1:bDMKF3RUSxshZ5OjOTi8rsHGaPKsAt76FaqgvIUySLc=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0/go.mod h1:dDT67G/IkA46Mr2l9Uj7HsQVwsjASyV9SjGofsiUZDA= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0/go.mod h1:dDT67G/IkA46Mr2l9Uj7HsQVwsjASyV9SjGofsiUZDA=
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0 h1:SNhVp/9q4Go/XHBkQ1/d5u9P/U+L1yaGPoi0x+mStaI= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0 h1:SNhVp/9q4Go/XHBkQ1/d5u9P/U+L1yaGPoi0x+mStaI=
@@ -201,18 +215,24 @@ go.opentelemetry.io/otel/log v0.6.0 h1:nH66tr+dmEgW5y+F9LanGJUBYPrRgP4g2EkmPE3Le
go.opentelemetry.io/otel/log v0.6.0/go.mod h1:KdySypjQHhP069JX0z/t26VHwa8vSwzgaKmXtIB3fJM= go.opentelemetry.io/otel/log v0.6.0/go.mod h1:KdySypjQHhP069JX0z/t26VHwa8vSwzgaKmXtIB3fJM=
go.opentelemetry.io/otel/log v0.13.0 h1:yoxRoIZcohB6Xf0lNv9QIyCzQvrtGZklVbdCoyb7dls= go.opentelemetry.io/otel/log v0.13.0 h1:yoxRoIZcohB6Xf0lNv9QIyCzQvrtGZklVbdCoyb7dls=
go.opentelemetry.io/otel/log v0.13.0/go.mod h1:INKfG4k1O9CL25BaM1qLe0zIedOpvlS5Z7XgSbmN83E= go.opentelemetry.io/otel/log v0.13.0/go.mod h1:INKfG4k1O9CL25BaM1qLe0zIedOpvlS5Z7XgSbmN83E=
go.opentelemetry.io/otel/log v0.14.0 h1:2rzJ+pOAZ8qmZ3DDHg73NEKzSZkhkGIua9gXtxNGgrM=
go.opentelemetry.io/otel/log v0.14.0/go.mod h1:5jRG92fEAgx0SU/vFPxmJvhIuDU9E1SUnEQrMlJpOno=
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
go.opentelemetry.io/otel/sdk/log v0.13.0 h1:I3CGUszjM926OphK8ZdzF+kLqFvfRY/IIoFq/TjwfaQ= go.opentelemetry.io/otel/sdk/log v0.13.0 h1:I3CGUszjM926OphK8ZdzF+kLqFvfRY/IIoFq/TjwfaQ=
go.opentelemetry.io/otel/sdk/log v0.13.0/go.mod h1:lOrQyCCXmpZdN7NchXb6DOZZa1N5G1R2tm5GMMTpDBw= go.opentelemetry.io/otel/sdk/log v0.13.0/go.mod h1:lOrQyCCXmpZdN7NchXb6DOZZa1N5G1R2tm5GMMTpDBw=
go.opentelemetry.io/otel/sdk/log v0.14.0 h1:JU/U3O7N6fsAXj0+CXz21Czg532dW2V4gG1HE/e8Zrg=
go.opentelemetry.io/otel/sdk/log v0.14.0/go.mod h1:imQvII+0ZylXfKU7/wtOND8Hn4OpT3YUoIgqJVksUkM=
go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os=
go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo=
go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4=
go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
@@ -226,6 +246,8 @@ golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -248,12 +270,20 @@ golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw
google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 h1:ToEetK57OidYuqD4Q5w+vfEnPvPpuTwedCNVohYJfNk= google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 h1:ToEetK57OidYuqD4Q5w+vfEnPvPpuTwedCNVohYJfNk=
google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7 h1:FiusG7LWj+4byqhbvmB+Q93B/mOxJLN2DTozDuZm4EU= google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7 h1:FiusG7LWj+4byqhbvmB+Q93B/mOxJLN2DTozDuZm4EU=
google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:kXqgZtrWaf6qS3jZOCnCH7WYfrvFjkC51bM8fz3RsCA= google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:kXqgZtrWaf6qS3jZOCnCH7WYfrvFjkC51bM8fz3RsCA=
google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY=
google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 h1:pFyd6EwwL2TqFf8emdthzeX+gZE1ElRq3iM8pui4KBY= google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 h1:pFyd6EwwL2TqFf8emdthzeX+gZE1ElRq3iM8pui4KBY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc=
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4=
google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=
google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@@ -1,6 +1,7 @@
cel.dev/expr v0.16.1 h1:NR0+oFYzR1CqLFhTAqg3ql59G9VfN8fKq1TCHJ6gq1g= cel.dev/expr v0.16.1 h1:NR0+oFYzR1CqLFhTAqg3ql59G9VfN8fKq1TCHJ6gq1g=
cel.dev/expr v0.16.1/go.mod h1:AsGA5zb3WruAEQeQng1RZdGEXmBj0jvMWh6l5SnNuC8= cel.dev/expr v0.16.1/go.mod h1:AsGA5zb3WruAEQeQng1RZdGEXmBj0jvMWh6l5SnNuC8=
cel.dev/expr v0.23.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= cel.dev/expr v0.23.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE= cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE=
cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U= cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U=
cloud.google.com/go/auth v0.13.0 h1:8Fu8TZy167JkW8Tj3q7dIkr2v4cndv41ouecJx0PAHs= cloud.google.com/go/auth v0.13.0 h1:8Fu8TZy167JkW8Tj3q7dIkr2v4cndv41ouecJx0PAHs=
@@ -9,6 +10,7 @@ cloud.google.com/go/auth/oauth2adapt v0.2.6 h1:V6a6XDu2lTwPZWOawrAa9HUK+DB2zfJyT
cloud.google.com/go/auth/oauth2adapt v0.2.6/go.mod h1:AlmsELtlEBnaNTL7jCj8VQFLy6mbZv0s4Q7NGBeQ5E8= cloud.google.com/go/auth/oauth2adapt v0.2.6/go.mod h1:AlmsELtlEBnaNTL7jCj8VQFLy6mbZv0s4Q7NGBeQ5E8=
cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I=
cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg=
cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo=
cloud.google.com/go/iam v1.2.2 h1:ozUSofHUGf/F4tCNy/mu9tHLTaxZFLOUiKzjcgWHGIA= cloud.google.com/go/iam v1.2.2 h1:ozUSofHUGf/F4tCNy/mu9tHLTaxZFLOUiKzjcgWHGIA=
cloud.google.com/go/iam v1.2.2/go.mod h1:0Ys8ccaZHdI1dEUilwzqng/6ps2YB6vRsjIe00/+6JY= cloud.google.com/go/iam v1.2.2/go.mod h1:0Ys8ccaZHdI1dEUilwzqng/6ps2YB6vRsjIe00/+6JY=
cloud.google.com/go/monitoring v1.21.2 h1:FChwVtClH19E7pJ+e0xUhJPGksctZNVOk2UhMmblmdU= cloud.google.com/go/monitoring v1.21.2 h1:FChwVtClH19E7pJ+e0xUhJPGksctZNVOk2UhMmblmdU=
@@ -18,6 +20,7 @@ cloud.google.com/go/storage v1.49.0/go.mod h1:k1eHhhpLvrPjVGfo0mOUPEJ4Y2+a/Hv5Pi
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 h1:3c8yed4lgqTt+oTQ+JNMDo+F4xprBf+O/il4ZC0nRLw= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 h1:3c8yed4lgqTt+oTQ+JNMDo+F4xprBf+O/il4ZC0nRLw=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0/go.mod h1:obipzmGjfSjam60XLwGfqUkJsfiheAl+TUjG+4yzyPM= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0/go.mod h1:obipzmGjfSjam60XLwGfqUkJsfiheAl+TUjG+4yzyPM=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0/go.mod h1:yAZHSGnqScoU556rBOVkwLze6WP5N+U11RHuWaGVxwY= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0/go.mod h1:yAZHSGnqScoU556rBOVkwLze6WP5N+U11RHuWaGVxwY=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0/go.mod h1:Cz6ft6Dkn3Et6l2v2a9/RpN7epQ1GtDlO6lj8bEcOvw=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.48.1 h1:UQ0AhxogsIRZDkElkblfnwjc3IaltCm2HUMvezQaL7s= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.48.1 h1:UQ0AhxogsIRZDkElkblfnwjc3IaltCm2HUMvezQaL7s=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.48.1/go.mod h1:jyqM3eLpJ3IbIFDTKVz2rF9T/xWGW0rIriGwnz8l9Tk= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.48.1/go.mod h1:jyqM3eLpJ3IbIFDTKVz2rF9T/xWGW0rIriGwnz8l9Tk=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.1 h1:8nn+rsCvTq9axyEh382S0PFLBeaFwNsT43IrPWzctRU= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.1 h1:8nn+rsCvTq9axyEh382S0PFLBeaFwNsT43IrPWzctRU=
@@ -42,6 +45,7 @@ github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod
github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8ETbOasdwEV+avkR75ZzsVV9WI= github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8ETbOasdwEV+avkR75ZzsVV9WI=
github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0=
github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
github.com/envoyproxy/go-control-plane v0.13.1 h1:vPfJZCkob6yTMEgS+0TwfTUfbHjfy/6vOJ8hUWX/uXE= github.com/envoyproxy/go-control-plane v0.13.1 h1:vPfJZCkob6yTMEgS+0TwfTUfbHjfy/6vOJ8hUWX/uXE=
@@ -55,7 +59,9 @@ github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2T
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA=
github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
github.com/golang/glog v1.2.5/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
@@ -109,19 +115,24 @@ go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/contrib/detectors/gcp v1.29.0 h1:TiaiXB4DpGD3sdzNlYQxruQngn5Apwzi1X0DRhuGvDQ= go.opentelemetry.io/contrib/detectors/gcp v1.29.0 h1:TiaiXB4DpGD3sdzNlYQxruQngn5Apwzi1X0DRhuGvDQ=
go.opentelemetry.io/contrib/detectors/gcp v1.29.0/go.mod h1:GW2aWZNwR2ZxDLdv8OyC2G8zkRoQBuURgV7RPQgcPoU= go.opentelemetry.io/contrib/detectors/gcp v1.29.0/go.mod h1:GW2aWZNwR2ZxDLdv8OyC2G8zkRoQBuURgV7RPQgcPoU=
go.opentelemetry.io/contrib/detectors/gcp v1.35.0/go.mod h1:qGWP8/+ILwMRIUf9uIVLloR1uo5ZYAslM4O6OqUi1DA= go.opentelemetry.io/contrib/detectors/gcp v1.35.0/go.mod h1:qGWP8/+ILwMRIUf9uIVLloR1uo5ZYAslM4O6OqUi1DA=
go.opentelemetry.io/contrib/detectors/gcp v1.36.0/go.mod h1:IbBN8uAIIx734PTonTPxAxnjc2pQTxWNkwfstZ+6H2k=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 h1:r6I7RJCN86bpD/FQwedZ0vSixDpwuWREjW9oRMsmqDc= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 h1:r6I7RJCN86bpD/FQwedZ0vSixDpwuWREjW9oRMsmqDc=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0/go.mod h1:B9yO6b04uB80CzjedvewuqDhxJxi11s7/GtiGa8bAjI= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0/go.mod h1:B9yO6b04uB80CzjedvewuqDhxJxi11s7/GtiGa8bAjI=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8=
go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8=
go.opentelemetry.io/otel/log/logtest v0.14.0/go.mod h1:IuguGt8XVP4XA4d2oEEDMVDBBCesMg8/tSGWDjuKfoA=
go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8=
go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok= go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok=
go.opentelemetry.io/otel/sdk/log/logtest v0.13.0/go.mod h1:QOGiAJHl+fob8Nu85ifXfuQYmJTFAvcrxL6w5/tu168= go.opentelemetry.io/otel/sdk/log/logtest v0.13.0/go.mod h1:QOGiAJHl+fob8Nu85ifXfuQYmJTFAvcrxL6w5/tu168=
go.opentelemetry.io/otel/sdk/log/logtest v0.14.0/go.mod h1:dCU8aEL6q+L9cYTqcVOk8rM9Tp8WdnHOPLiBgp0SGOA=
go.opentelemetry.io/otel/sdk/metric v1.29.0/go.mod h1:6zZLdCl2fkauYoZIOn/soQIDSWFmNSRcICarHfuhNJQ= go.opentelemetry.io/otel/sdk/metric v1.29.0/go.mod h1:6zZLdCl2fkauYoZIOn/soQIDSWFmNSRcICarHfuhNJQ=
go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
@@ -131,11 +142,13 @@ golang.org/x/telemetry v0.0.0-20250710130107-8d8967aff50b/go.mod h1:4ZwOYna0/zsO
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0= golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0=
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg= golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools/go/expect v0.1.0-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= golang.org/x/tools/go/expect v0.1.0-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY=
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8= golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
google.golang.org/api v0.215.0 h1:jdYF4qnyczlEz2ReWIsosNLDuzXyvFHJtI5gcr0J7t0= google.golang.org/api v0.215.0 h1:jdYF4qnyczlEz2ReWIsosNLDuzXyvFHJtI5gcr0J7t0=
google.golang.org/api v0.215.0/go.mod h1:fta3CVtuJYOEdugLNWm6WodzOS8KdFckABwN4I40hzY= google.golang.org/api v0.215.0/go.mod h1:fta3CVtuJYOEdugLNWm6WodzOS8KdFckABwN4I40hzY=
google.golang.org/genproto v0.0.0-20241118233622-e639e219e697/go.mod h1:JJrvXBWRZaFMxBufik1a4RpFw4HhgVtBBWQeQgUj2cc= google.golang.org/genproto v0.0.0-20241118233622-e639e219e697/go.mod h1:JJrvXBWRZaFMxBufik1a4RpFw4HhgVtBBWQeQgUj2cc=

View File

@@ -38,16 +38,6 @@ func (self *BunDatabase) GetUserStatuses(
return ret, err return ret, err
} }
func (self *BunDatabase) GetRooms(
ctx context.Context,
) ([]models.Room, error) {
var ret []models.Room
err := self.db.NewSelect().
Model(&ret).
Scan(ctx)
return ret, err
}
func (self *BunDatabase) InsertUser( func (self *BunDatabase) InsertUser(
ctx context.Context, ctx context.Context,
user models.User, user models.User,
@@ -81,16 +71,6 @@ func (self *BunDatabase) InsertUserStatus(
return err return err
} }
func (self *BunDatabase) InsertRoom(
ctx context.Context,
room models.Room,
) error {
_, err := self.db.NewInsert().
Model(&room).
Exec(ctx)
return err
}
func (self *BunDatabase) DeleteUserStatus( func (self *BunDatabase) DeleteUserStatus(
ctx context.Context, ctx context.Context,
username string, username string,
@@ -101,14 +81,3 @@ func (self *BunDatabase) DeleteUserStatus(
Exec(ctx) Exec(ctx)
return err return err
} }
func (self *BunDatabase) DeleteRoom(
ctx context.Context,
roomId int,
) error {
_, err := self.db.NewDelete().
Model(&models.Room{Id: roomId}).
WherePK().
Exec(ctx)
return err
}

View File

@@ -16,10 +16,6 @@ type Database interface {
ctx context.Context, ctx context.Context,
) ([]models.UserStatus, error) ) ([]models.UserStatus, error)
GetRooms(
ctx context.Context,
) ([]models.Room, error)
InsertUser( InsertUser(
ctx context.Context, ctx context.Context,
user models.User, user models.User,
@@ -30,18 +26,8 @@ type Database interface {
userStatus models.UserStatus, userStatus models.UserStatus,
) error ) error
InsertRoom(
ctx context.Context,
room models.Room,
) error
DeleteUserStatus( DeleteUserStatus(
ctx context.Context, ctx context.Context,
username string, username string,
) error ) error
DeleteRoom(
ctx context.Context,
roomId int,
) error
} }

View File

@@ -1,47 +0,0 @@
package models
import (
"fmt"
"github.com/uptrace/bun"
)
type RoomType int
const (
RoomTypeWordle RoomType = iota
)
var (
RoomTypeStr = []string{"Wordle"}
)
type RoomStatus int
const (
RoomStatusWaiting RoomStatus = iota
RoomStatusPlaying
RoomStatusEnded
)
var (
RoomStatusStr = []string{"Waiting", "Playing", "Ended"}
)
type Room struct {
bun.BaseModel `bun:"table:room"`
Id int `bun:"id,pk,autoincrement"`
Creater string `bun:"creater"`
Type RoomType `bun:"type"`
Status RoomStatus `bun:"status"`
}
func (self Room) View() string {
return fmt.Sprintf("%2d. %10s %10s [%s]",
self.Id,
self.Creater,
RoomTypeStr[self.Type],
RoomStatusStr[self.Status],
)
}

View File

@@ -21,11 +21,13 @@ func Tick(d time.Duration) tea.Cmd {
type Base struct { type Base struct {
client *resty.Client client *resty.Client
username string
} }
func NewBase(client *resty.Client) *Base { func NewBase(client *resty.Client) *Base {
return &Base{ return &Base{
client: client, client: client,
username: "",
} }
} }

121
plays/game.go Normal file
View File

@@ -0,0 +1,121 @@
package plays
import (
"fmt"
"net/url"
"sync"
"gitea.konchin.com/ytshih/inp2025/game/server/wordle"
"gitea.konchin.com/ytshih/inp2025/game/types"
tea "github.com/charmbracelet/bubbletea"
"github.com/gorilla/websocket"
"github.com/vmihailenco/msgpack/v5"
)
type Game struct {
*Base
server url.URL
mutex sync.RWMutex
state types.WordleState
input string
}
func (m *Game) GetState() {
c, _, err := websocket.DefaultDialer.Dial(m.server.String(), nil)
if err != nil {
panic(fmt.Errorf("failed to dial, %w", err))
}
defer c.Close()
for {
_, b, err := c.ReadMessage()
switch err.(type) {
case nil:
var state types.WordleState
if err := msgpack.Unmarshal(b, &state); err != nil {
panic(fmt.Errorf("failed to unmarshal state, %w", err))
}
m.mutex.Lock()
m.state = state
m.mutex.Unlock()
case *websocket.CloseError:
return
default:
panic(fmt.Errorf("failed to read message, %w", err))
}
}
}
func NewGame(base *Base, server url.URL) *Game {
m := &Game{
Base: base,
server: server,
state: types.NewWordleState(),
input: "",
}
go m.GetState()
return m
}
func (m *Game) Init() tea.Cmd {
return tea.Batch(tea.ClearScreen)
}
func (m *Game) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if _, cmd := m.Base.Update(msg); cmd != nil {
return m, cmd
}
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.Type {
case tea.KeyBackspace:
if len(m.input) > 0 {
m.input = m.input[:len(m.input)-1]
}
case tea.KeyEnter:
if len(m.input) == types.MaxLength {
return m, tea.Quit
}
case tea.KeyRunes:
if len(m.input) < types.MaxLength {
m.input = m.input + string(msg.Runes)
}
}
}
return m, nil
}
func (m *Game) View() string {
m.mutex.RLock()
ret := m.state.View()
m.mutex.RUnlock()
return ret
}
func (m *Game) Next(queue *[]*tea.Program) error {
if len(m.input) == types.MaxLength {
b, err := msgpack.Marshal(wordle.Operation{
Type: wordle.OperationTypeGuess,
Username: m.username,
})
if err != nil {
return err
}
_, err = m.Base.client.R().
SetBody(b).
Post("/api/guess")
if err != nil {
return err
}
*queue = append(*queue,
tea.NewProgram(NewGame(m.Base, m.server)))
}
return nil
}

View File

@@ -14,7 +14,7 @@ import (
) )
var ( var (
lobbyChoices = []string{"No-op", "Logout"} lobbyChoices = []string{"No-op", "Create Room", "Logout"}
) )
type Lobby struct { type Lobby struct {
@@ -25,18 +25,18 @@ type Lobby struct {
updateCh chan struct{} updateCh chan struct{}
users []models.UserStatus users []models.UserStatus
rooms []models.Room rooms []types.Room
} }
func NewLobby(base *Base) *Lobby { func NewLobby(base *Base) *Lobby {
m := Lobby{ m := &Lobby{
Base: base, Base: base,
choice: "", choice: "",
cursor: 0, cursor: 0,
updateCh: make(chan struct{}, 1), updateCh: make(chan struct{}, 1),
} }
return &m return m
} }
func updateLobbyInfo(m *Lobby) error { func updateLobbyInfo(m *Lobby) error {
@@ -58,7 +58,8 @@ func updateLobbyInfo(m *Lobby) error {
} }
m.users = users m.users = users
var rooms []models.Room var rooms []types.Room
// TODO: scan rooms
_, err = m.Base.client.R(). _, err = m.Base.client.R().
SetResult(&rooms). SetResult(&rooms).
ForceContentType("application/json"). ForceContentType("application/json").
@@ -147,6 +148,9 @@ func (m *Lobby) Next(queue *[]*tea.Program) error {
case "No-op": case "No-op":
*queue = append(*queue, *queue = append(*queue,
tea.NewProgram(NewLobby(m.Base))) tea.NewProgram(NewLobby(m.Base)))
case "Create Room":
*queue = append(*queue,
tea.NewProgram(NewRoomWaiting(m.Base)))
case "Logout": case "Logout":
*queue = append(*queue, *queue = append(*queue,
tea.NewProgram(NewLogout(m.Base))) tea.NewProgram(NewLogout(m.Base)))

View File

@@ -125,6 +125,7 @@ func (m *Login) Next(queue *[]*tea.Program) error {
if resp.StatusCode() == http.StatusOK { if resp.StatusCode() == http.StatusOK {
m.Base.client. m.Base.client.
SetBasicAuth(username, password) SetBasicAuth(username, password)
m.Base.username = username
*queue = append(*queue, *queue = append(*queue,
tea.NewProgram(NewLobby(m.Base))) tea.NewProgram(NewLobby(m.Base)))
} else { } else {

View File

@@ -123,18 +123,20 @@ func (m *Register) Next(queue *[]*tea.Program) error {
}). }).
Post("/auth/register") Post("/auth/register")
switch resp.StatusCode() { if err == nil && resp.StatusCode() == http.StatusOK {
case http.StatusOK:
*queue = append(*queue, *queue = append(*queue,
tea.NewProgram(NewLogin(m.Base))) tea.NewProgram(NewLogin(m.Base)))
} else {
switch resp.StatusCode() {
case http.StatusBadRequest: case http.StatusBadRequest:
*queue = append(*queue, *queue = append(*queue,
tea.NewProgram(NewRedirect("Username already exist"))) tea.NewProgram(NewRedirect("Username already exist")))
*queue = append(*queue, *queue = append(*queue,
tea.NewProgram(NewRegister(m.Base))) tea.NewProgram(NewRegister(m.Base)))
case http.StatusInternalServerError: default:
return err return err
} }
}
return nil return nil
} }

65
plays/roomWaiting.go Normal file
View File

@@ -0,0 +1,65 @@
package plays
import (
"strings"
"gitea.konchin.com/ytshih/inp2025/game/types"
tea "github.com/charmbracelet/bubbletea"
)
type RoomWaiting struct {
*Base
doneCh chan struct{}
}
func NewRoomWaiting(base *Base) *RoomWaiting {
m := &RoomWaiting{
base: base,
doneCh: make(chan struct{}),
}
return &m
}
func updateRoomWaitingInfo(m *RoomWaiting) error {
for {
select {
case <-m.doneCh:
return nil
}
}
}
func (m *RoomWaiting) Init() tea.Cmd {
go updateRoomWaitingInfo(m)
return tea.Sequence(tea.ClearScreen, Tick(refreshTick))
}
func (m *RoomWaiting) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if _, cmd := m.Base.Update(msg); cmd != nil {
return m, cmd
}
switch msg := msg.(type) {
case types.TickMsg:
return m, Tick(refreshTick)
}
return m, nil
}
func (m *RoomWaiting) View() string {
var b strings.Builder
b.WriteString("waiting for user to join ...")
return b.String()
}
func (m *RoomWaiting) Next(queue *[]*tea.Program) error {
m.doneCh <- struct{}{}
switch m.choice {
case "":
*queue = append(*queue,
tea.NewProgram)
}
}

View File

@@ -3,7 +3,7 @@ package api
import ( import (
"net/http" "net/http"
"gitea.konchin.com/ytshih/inp2025/game/backend/middlewares" "gitea.konchin.com/ytshih/inp2025/game/server/middlewares"
"github.com/uptrace/bunrouter" "github.com/uptrace/bunrouter"
) )

View File

@@ -4,7 +4,7 @@ import (
"database/sql" "database/sql"
"net/http" "net/http"
"gitea.konchin.com/ytshih/inp2025/game/backend/middlewares" "gitea.konchin.com/ytshih/inp2025/game/server/middlewares"
"github.com/uptrace/bunrouter" "github.com/uptrace/bunrouter"
) )

View File

@@ -3,8 +3,8 @@ package auth
import ( import (
"net/http" "net/http"
"gitea.konchin.com/ytshih/inp2025/game/backend/middlewares"
"gitea.konchin.com/ytshih/inp2025/game/models" "gitea.konchin.com/ytshih/inp2025/game/models"
"gitea.konchin.com/ytshih/inp2025/game/server/middlewares"
"gitea.konchin.com/ytshih/inp2025/game/types" "gitea.konchin.com/ytshih/inp2025/game/types"
"gitea.konchin.com/ytshih/inp2025/game/utils" "gitea.konchin.com/ytshih/inp2025/game/utils"
"github.com/uptrace/bunrouter" "github.com/uptrace/bunrouter"

View File

@@ -3,8 +3,8 @@ package auth
import ( import (
"net/http" "net/http"
"gitea.konchin.com/ytshih/inp2025/game/backend/middlewares"
"gitea.konchin.com/ytshih/inp2025/game/models" "gitea.konchin.com/ytshih/inp2025/game/models"
"gitea.konchin.com/ytshih/inp2025/game/server/middlewares"
"gitea.konchin.com/ytshih/inp2025/game/types" "gitea.konchin.com/ytshih/inp2025/game/types"
"gitea.konchin.com/ytshih/inp2025/game/utils" "gitea.konchin.com/ytshih/inp2025/game/utils"
"github.com/uptrace/bunrouter" "github.com/uptrace/bunrouter"

View File

@@ -5,8 +5,8 @@ import (
"io" "io"
"net/http" "net/http"
"gitea.konchin.com/ytshih/inp2025/game/backend/middlewares"
"gitea.konchin.com/ytshih/inp2025/game/models" "gitea.konchin.com/ytshih/inp2025/game/models"
"gitea.konchin.com/ytshih/inp2025/game/server/middlewares"
"gitea.konchin.com/ytshih/inp2025/game/types" "gitea.konchin.com/ytshih/inp2025/game/types"
"gitea.konchin.com/ytshih/inp2025/game/utils" "gitea.konchin.com/ytshih/inp2025/game/utils"
"github.com/uptrace/bunrouter" "github.com/uptrace/bunrouter"

View File

@@ -18,11 +18,6 @@ const docTemplate = `{
"host": "{{.Host}}", "host": "{{.Host}}",
"basePath": "{{.BasePath}}", "basePath": "{{.BasePath}}",
"paths": { "paths": {
"/api/lobby/rooms": {
"get": {
"responses": {}
}
},
"/api/lobby/users": { "/api/lobby/users": {
"get": { "get": {
"responses": {} "responses": {}

View File

@@ -10,11 +10,6 @@
}, },
"basePath": "/", "basePath": "/",
"paths": { "paths": {
"/api/lobby/rooms": {
"get": {
"responses": {}
}
},
"/api/lobby/users": { "/api/lobby/users": {
"get": { "get": {
"responses": {} "responses": {}

View File

@@ -14,9 +14,6 @@ info:
title: Intro. to Network Programming Game title: Intro. to Network Programming Game
version: 0.0.1-alpha version: 0.0.1-alpha
paths: paths:
/api/lobby/rooms:
get:
responses: {}
/api/lobby/users: /api/lobby/users:
get: get:
responses: {} responses: {}

View File

@@ -11,7 +11,7 @@ func (self *Handlers) AccessLog(
next bunrouter.HandlerFunc, next bunrouter.HandlerFunc,
) bunrouter.HandlerFunc { ) bunrouter.HandlerFunc {
return func(w http.ResponseWriter, req bunrouter.Request) error { return func(w http.ResponseWriter, req bunrouter.Request) error {
tracing.Logger.Ctx(req.Context()). tracing.Logger.
Info(req.Method + " " + req.Params().Route()) Info(req.Method + " " + req.Params().Route())
return next(w, req) return next(w, req)
} }

View File

@@ -35,7 +35,7 @@ func (self *Handlers) Auth(
} }
if dbUser.Password != password { if dbUser.Password != password {
tracing.Logger.Ctx(ctx). tracing.Logger.
Debug("password input", Debug("password input",
zap.String("input.password", password), zap.String("input.password", password),
zap.String("dbuser.password", dbUser.Password)) zap.String("dbuser.password", dbUser.Password))

View File

@@ -45,7 +45,7 @@ func (self *Handlers) ErrorHandler(
httpErr = err httpErr = err
default: default:
tracing.Logger.Ctx(ctx). tracing.Logger.
Error("unhandled error", Error("unhandled error",
zap.Error(err)) zap.Error(err))
httpErr = NewHTTPError(err) httpErr = NewHTTPError(err)
@@ -60,20 +60,20 @@ func (self *Handlers) ErrorHandler(
if 500 <= httpErr.StatusCode && httpErr.StatusCode <= 599 { if 500 <= httpErr.StatusCode && httpErr.StatusCode <= 599 {
span.SetStatus(codes.Error, err.Error()) span.SetStatus(codes.Error, err.Error())
if httpErr.OriginError == nil { if httpErr.OriginError == nil {
tracing.Logger.Ctx(ctx). tracing.Logger.
Error(httpErr.Message) Error(httpErr.Message)
} else { } else {
tracing.Logger.Ctx(ctx). tracing.Logger.
Error(httpErr.Message, Error(httpErr.Message,
zap.Error(httpErr.OriginError)) zap.Error(httpErr.OriginError))
} }
} else { } else {
span.SetStatus(codes.Ok, "") span.SetStatus(codes.Ok, "")
if httpErr.OriginError == nil { if httpErr.OriginError == nil {
tracing.Logger.Ctx(ctx). tracing.Logger.
Warn(httpErr.Message) Warn(httpErr.Message)
} else { } else {
tracing.Logger.Ctx(ctx). tracing.Logger.
Warn(httpErr.Message, Warn(httpErr.Message,
zap.Error(httpErr.OriginError)) zap.Error(httpErr.OriginError))
} }

60
server/wordle/handlers.go Normal file
View File

@@ -0,0 +1,60 @@
package wordle
import (
"gitea.konchin.com/ytshih/inp2025/game/types"
"github.com/gorilla/websocket"
)
type OperationType int
const (
OperationTypeGuess OperationType = iota
)
type Operation struct {
Type OperationType
Username string
Guess string
}
type Handlers struct {
state types.WordleState
ans string
upgrader websocket.Upgrader
opCh chan Operation
subs []*chan types.WordleState
}
func NewHandlers() *Handlers {
ret := &Handlers{
upgrader: websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
},
subs: nil,
}
go ret.GameFlow()
return ret
}
func (self *Handlers) GameFlow() {
for op := range self.opCh {
switch op.Type {
case OperationTypeGuess:
self.state.CurrentGuess++
if self.state.CurrentGuess >= len(self.state.Users) {
for username, user := range self.state.Users {
user.History = append(user.History,
types.NewWord(op.Guess, self.ans))
self.state.Users[username] = user
}
for _, sub := range self.subs {
*sub <- self.state
}
}
}
}
}

View File

@@ -0,0 +1,44 @@
package wordle
import (
"net/http"
"gitea.konchin.com/ytshih/inp2025/game/server/middlewares"
"gitea.konchin.com/ytshih/inp2025/game/types"
"gitea.konchin.com/ytshih/inp2025/game/utils"
"github.com/gorilla/websocket"
"github.com/uptrace/bunrouter"
"github.com/vmihailenco/msgpack/v5"
)
func (self *Handlers) WSGetState(
w http.ResponseWriter,
req bunrouter.Request,
) error {
c, err := self.upgrader.Upgrade(w, req.Request, nil)
if err != nil {
return middlewares.HTTPError{
StatusCode: http.StatusInternalServerError,
Message: "failed to upgrade websocket",
OriginError: err,
}
}
defer c.Close()
dataCh := make(chan types.WordleState)
self.subs = append(self.subs, &dataCh)
for data := range dataCh {
b, err := msgpack.Marshal(data)
if err != nil {
return middlewares.HTTPError{
StatusCode: http.StatusInternalServerError,
Message: "failed to marshal data into msgpack",
OriginError: err,
}
}
c.WriteMessage(websocket.BinaryMessage, b)
}
return utils.Success(w)
}

View File

@@ -1,33 +1,42 @@
package tracing package tracing
import ( import (
"context"
"github.com/spf13/viper" "github.com/spf13/viper"
"github.com/uptrace/opentelemetry-go-extra/otelzap" "go.opentelemetry.io/contrib/bridges/otelzap"
"go.opentelemetry.io/otel" "go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc"
"go.opentelemetry.io/otel/sdk/log"
"go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/trace"
"go.uber.org/zap" "go.uber.org/zap"
) )
var ( var (
Provider *log.LoggerProvider
Tracer trace.Tracer Tracer trace.Tracer
Logger *otelzap.Logger Logger *zap.Logger
version string = "0.0.1-alpha" version string = "0.0.1-alpha"
) )
func InitTracer(appname string) { func InitTracer(appname string) {
Tracer = otel.Tracer(appname) ctx := context.Background()
exp, err := otlploggrpc.New(ctx,
var l *zap.Logger otlploggrpc.WithInsecure(),
var err error otlploggrpc.WithEndpoint(viper.GetString("otel-endpoint")))
if viper.GetBool("zap-production") {
l, err = zap.NewProduction()
} else {
l, err = zap.NewDevelopment()
}
if err != nil { if err != nil {
panic(err) panic(err)
} }
Logger = otelzap.New(l) Provider = log.NewLoggerProvider(
log.WithProcessor(log.NewBatchProcessor(exp)))
otelCore := otelzap.NewCore(appname,
otelzap.WithLoggerProvider(Provider))
Logger = zap.New(otelCore, zap.AddCaller())
}
func DeferTracer() {
Logger.Sync()
Provider.Shutdown(context.Background())
} }

27
types/game.go Normal file
View File

@@ -0,0 +1,27 @@
package types
import "fmt"
type RoomStatus int
const (
RoomStatusWaiting RoomStatus = iota
RoomStatusPlaying
RoomStatusEnded
)
var (
RoomStatusStr = []string{"Waiting", "Playing", "Ended"}
)
type Room struct {
Creater string
Status RoomStatus
}
func (self Room) View() string {
return fmt.Sprintf("%10s [%s]",
self.Creater,
RoomStatusStr[self.Status],
)
}

89
types/wordle.go Normal file
View File

@@ -0,0 +1,89 @@
package types
import (
"strings"
"github.com/charmbracelet/lipgloss"
)
type CharStatus int
const (
CharStatusA CharStatus = iota
CharStatusB
CharStatusC
)
type Char struct {
Char rune `msgpack:"char"`
Status CharStatus `msgpack:"status"`
}
func NewChar() Char {
return Char{
Char: 0x0,
Status: CharStatusC,
}
}
func (self Char) View() string {
style := lipgloss.NewStyle()
switch self.Status {
case CharStatusA:
style = style.Background(lipgloss.Color("#00ff00"))
case CharStatusB:
style = style.Background(lipgloss.Color("#ffff00"))
case CharStatusC:
style = style.Background(lipgloss.Color("#808080"))
}
return style.Render(string(self.Char))
}
type Word struct {
Chars []Char `msgpack:"chars"`
}
func NewWord(word, ans string) Word {
return Word{
Chars: nil,
}
}
func (self Word) View() string {
var b strings.Builder
for _, char := range self.Chars {
b.WriteString(char.View())
b.WriteRune('\n')
}
return b.String()
}
const (
MaxLength = 5
)
type UserState struct {
History []Word `msgpack:"history"`
Input string
}
type WordleState struct {
Users map[string]UserState `msgpack:"users"`
CurrentGuess int
}
func NewWordleState() WordleState {
return WordleState{
Users: nil,
}
}
func (self WordleState) View() string {
var b strings.Builder
return b.String()
}

View File

@@ -11,6 +11,5 @@ func InitDB(ctx context.Context, db *bun.DB) error {
return db.ResetModel(ctx, return db.ResetModel(ctx,
(*models.User)(nil), (*models.User)(nil),
(*models.UserStatus)(nil), (*models.UserStatus)(nil),
(*models.Room)(nil),
) )
} }

View File

@@ -14,7 +14,7 @@ func ReadConfig(ctx context.Context) {
viper.AddConfigPath(".") viper.AddConfigPath(".")
if err := viper.ReadInConfig(); err != nil { if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); !ok { if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
tracing.Logger.Ctx(ctx). tracing.Logger.
Panic("failed to read config file", Panic("failed to read config file",
zap.Error(err)) zap.Error(err))
panic(err) panic(err)

50
utils/udp.go Normal file
View File

@@ -0,0 +1,50 @@
package workflows
import (
"fmt"
"net"
"github.com/vmihailenco/msgpack/v5"
)
type UDPPayload struct {
MagicNumber int `msgpack:"magicNumber"`
Data string `msgpack:"data"`
}
const (
BUFFER_SIZE int = 1024
MAGIC_NUMBER int = 114514
)
func ListenUDP(port string) (string, error) {
addr, err := net.ResolveUDPAddr("udp", ":"+port)
if err != nil {
return nil, fmt.Errorf("failed to resolve address, %w", err)
}
conn, err := net.ListenUDP("udp", addr)
if err != nil {
return nil, fmt.Errorf("failed to listen on addr '%v', %w", addr, err)
}
defer conn.Close()
for {
buffer := make([]byte, BUFFER_SIZE)
n, clientAddr, err := conn.ReadFromUDP(buffer)
if err != nil {
continue
}
var payload UDPPayload
err = msgpack.Unmarshal(buffer[:n], &payload)
if err == nil && payload.MagicNumber == MAGIC_NUMBER {
return payload.Data
}
}
}
func SendPayload(endpoint, data string) error {
}

48
workflows/wordleServer.go Normal file
View File

@@ -0,0 +1,48 @@
package workflows
import (
"context"
"net/http"
"gitea.konchin.com/ytshih/inp2025/game/implements"
"gitea.konchin.com/ytshih/inp2025/game/server/middlewares"
"gitea.konchin.com/ytshih/inp2025/game/server/wordle"
"gitea.konchin.com/ytshih/inp2025/game/tracing"
"github.com/uptrace/bunrouter"
"go.uber.org/zap"
)
type ShutdownFunc = func()
func WordleServer(addr string) ShutdownFunc {
handlers := wordle.NewHandlers()
middlewareHandlers := middlewares.NewHandlers(
implements.NewBunDatabase(nil))
router := bunrouter.New()
apiGroup := router.NewGroup("/api").
Use(middlewareHandlers.ErrorHandler)
apiGroup.GET("/state",
handlers.WSGetState)
apiGroup.POST("/guess",
handlers.WSPostGuess)
httpServer = &http.Server{
Addr: addr,
Handler: http.Handler(router),
}
if err := httpServer.ListenAndServe(); err != http.ErrServerClosed {
tracing.Logger.Panic("failed to start http server",
zap.Error(err))
panic(err)
}
return func() {
if err := httpServer.Shutdown(context.Background()); err != nil {
tracing.Logger.Panic("failed to shutdown server",
zap.Error(err))
panic(err)
}
}
}