Draft: big refactor
This commit is contained in:
3
Makefile
3
Makefile
@@ -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
|
||||||
|
|||||||
@@ -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)
|
|
||||||
}
|
|
||||||
@@ -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")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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().
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
26
go.mod
@@ -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
30
go.sum
@@ -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=
|
||||||
|
|||||||
13
go.work.sum
13
go.work.sum
@@ -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=
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -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
121
plays/game.go
Normal 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
|
||||||
|
}
|
||||||
@@ -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)))
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
65
plays/roomWaiting.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -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"
|
||||||
@@ -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"
|
||||||
@@ -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"
|
||||||
@@ -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": {}
|
||||||
@@ -10,11 +10,6 @@
|
|||||||
},
|
},
|
||||||
"basePath": "/",
|
"basePath": "/",
|
||||||
"paths": {
|
"paths": {
|
||||||
"/api/lobby/rooms": {
|
|
||||||
"get": {
|
|
||||||
"responses": {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/api/lobby/users": {
|
"/api/lobby/users": {
|
||||||
"get": {
|
"get": {
|
||||||
"responses": {}
|
"responses": {}
|
||||||
@@ -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: {}
|
||||||
@@ -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)
|
||||||
}
|
}
|
||||||
@@ -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))
|
||||||
@@ -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
60
server/wordle/handlers.go
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
44
server/wordle/wsGetState.go
Normal file
44
server/wordle/wsGetState.go
Normal 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)
|
||||||
|
}
|
||||||
@@ -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
27
types/game.go
Normal 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
89
types/wordle.go
Normal 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()
|
||||||
|
}
|
||||||
@@ -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),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
50
utils/udp.go
Normal 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
48
workflows/wordleServer.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user