commit 06180ed63855b81cd2297538b182c170b7b38a51 Author: cialloo Date: Sat Oct 4 12:48:09 2025 +0800 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..166c309 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/api/ServerStatistics.json +/api/ServerStatistics.yaml +*.exe +/src/src \ No newline at end of file diff --git a/api/ServerStatistics.api b/api/ServerStatistics.api new file mode 100644 index 0000000..9bce4a9 --- /dev/null +++ b/api/ServerStatistics.api @@ -0,0 +1,193 @@ +syntax = "v1" + +info ( + title: "Server Statistics API" + desc: "Server Statistics API" + author: "cialloo" + date: "2025-10-04" + version: "v1" +) + +type ( + PingReq {} + PingResp { + ok bool `json:"ok"` + } +) + +type ( + TotalPlayerJoinReq { + TimeRangeStart int64 `json:"timeRangeStart"` // Unix timestamp in milliseconds + TimeRangeEnd int64 `json:"timeRangeEnd"` // Unix timestamp in milliseconds + } + TotalPlayerJoinResp { + Count int64 `json:"count"` + } +) + +type ( + TotalPlayerCountReq { + TimeRangeStart int64 `json:"timeRangeStart"` // Unix timestamp in milliseconds + TimeRangeEnd int64 `json:"timeRangeEnd"` // Unix timestamp in milliseconds + } + TotalPlayerCountResp { + Count int64 `json:"count"` + } +) + +type ( + TotalPlayTimeReq { + TimeRangeStart int64 `json:"timeRangeStart"` // Unix timestamp in milliseconds + TimeRangeEnd int64 `json:"timeRangeEnd"` // Unix timestamp in milliseconds + } + TotalPlayTimeResp { + TotalPlayTime int64 `json:"totalPlayTime"` // Total playtime in seconds + } +) + +type ( + TotalKillCountReq { + TimeRangeStart int64 `json:"timeRangeStart"` // Unix timestamp in milliseconds + TimeRangeEnd int64 `json:"timeRangeEnd"` // Unix timestamp in milliseconds + HeadshotOnly bool `json:"headshotOnly"` // If true, count only headshot kills + WeaponFilter []string `json:"weaponFilter"` // List of weapon names to filter by (optional) + PlayerFilter []string `json:"playerFilter"` // List of player SteamID64s to filter by (optional) + } + TotalKillCountResp { + TotalKillCount int64 `json:"totalKillCount"` // Total kill count + } +) + +type ( + TotalConnectCountReq { + TimeRangeStart int64 `json:"timeRangeStart"` // Unix timestamp in milliseconds + TimeRangeEnd int64 `json:"timeRangeEnd"` // Unix timestamp in milliseconds + } + TotalConnectCountResp { + TotalConnectCount int64 `json:"totalConnectCount"` // Total connect count + } +) + +type ( + TotalDamageCountReq { + TimeRangeStart int64 `json:"timeRangeStart"` // Unix timestamp in milliseconds + TimeRangeEnd int64 `json:"timeRangeEnd"` // Unix timestamp in milliseconds + WeaponFilter []string `json:"weaponFilter"` // List of weapon names to filter by (optional) + PlayerFilter []string `json:"playerFilter"` // List of player SteamID64s to filter by (optional) + } + TotalDamageCountResp { + TotalDamageCount int64 `json:"totalDamageCount"` // Total damage count + } +) + +type ( + TotalChatMessageCountReq { + TimeRangeStart int64 `json:"timeRangeStart"` // Unix timestamp in milliseconds + TimeRangeEnd int64 `json:"timeRangeEnd"` // Unix timestamp in milliseconds + PlayerFilter []string `json:"playerFilter"` // List of player SteamID64s to filter by (optional) + } + TotalChatMessageCountResp { + TotalChatMessageCount int64 `json:"totalChatMessageCount"` // Total chat message count + } +) + +type ( + RecentJoinPlayerReq { + TimeRangeStart int64 `json:"timeRangeStart"` // Unix timestamp in milliseconds + TimeRangeEnd int64 `json:"timeRangeEnd"` // Unix timestamp in milliseconds + } + RecentJoinPlayerResp { + Players []RecentJoinPlayerRespPlayer `json:"players"` // List of player SteamID64s who joined in the time range + } + RecentJoinPlayerRespPlayer { + SteamID64 string `json:"steamID64"` // Player's SteamID64 + JoinTime int64 `json:"joinTime"` // Join time as Unix timestamp in milliseconds + UserName string `json:"userName"` // Player's username at the time of joining + PlayTime int64 `json:"playTime"` // Playtime in seconds since joining + } +) + +type ( + RecentChatMessageReq { + TimeRangeStart int64 `json:"timeRangeStart"` // Unix timestamp in milliseconds + TimeRangeEnd int64 `json:"timeRangeEnd"` // Unix timestamp in milliseconds + } + RecentChatMessageResp { + Messages []RecentChatMessageRespMessage `json:"messages"` // List of recent chat messages + } + RecentChatMessageRespMessage { + SteamID64 string `json:"steamID64"` // Player's SteamID64 + UserName string `json:"userName"` // Player's username at the time of message + Message string `json:"message"` // Chat message content + TimeStamp int64 `json:"timeStamp"` // Message timestamp as Unix timestamp in milliseconds + } +) + +@server ( + prefix: /api/server/statistics +) +service ServerStatistics { + @doc ( + summary: "Ping the server to check if it's alive" + description: "Ping the server to check if it's alive" + ) + @handler pingHandler + get /ping (PingReq) returns (PingResp) + + @doc ( + summary: "Get recent player joins within a specified time range" + description: "Get recent player joins within a specified time range" + ) + @handler recentPlayerJoinHandler + post /recent-player-join (TotalPlayerJoinReq) returns (TotalPlayerJoinResp) + + @doc ( + summary: "Get total player count within a specified time range" + description: "Get total Total count within a specified time range" + ) + @handler totalPlayerCountHandler + post /total-player-count (TotalPlayerCountReq) returns (TotalPlayerCountResp) + + @doc ( + summary: "Get total kill count within a specified time range" + description: "Get total kill count within a specified time range" + ) + @handler totalKillCountHandler + post /total-kill-count (TotalKillCountReq) returns (TotalKillCountResp) + + @doc ( + summary: "Get total playtime within a specified time range" + description: "Get total playtime within a specified time range" + ) + @handler totalPlayTimeHandler + post /total-play-time (TotalPlayTimeReq) returns (TotalPlayTimeResp) + + @doc ( + summary: "Get total connect count within a specified time range" + description: "Get total connect count within a specified time range" + ) + @handler totalConnectCountHandler + post /total-connect-count (TotalConnectCountReq) returns (TotalConnectCountResp) + + @doc ( + summary: "Get total damage count within a specified time range" + description: "Get total damage count within a specified time range" + ) + @handler totalDamageCountHandler + post /total-damage-count (TotalDamageCountReq) returns (TotalDamageCountResp) + + @doc ( + summary: "Get total chat message count within a specified time range" + description: "Get total chat message count within a specified time range" + ) + @handler totalChatMessageCountHandler + post /total-chat-message-count (TotalChatMessageCountReq) returns (TotalChatMessageCountResp) + + @doc ( + summary: "Get recent players who joined within a specified time range" + description: "Get recent players who joined within a specified time range" + ) + @handler recentJoinPlayerHandler + post /recent-join-player (RecentJoinPlayerReq) returns (RecentJoinPlayerResp) +} + diff --git a/script/goctl/GenApi.ps1 b/script/goctl/GenApi.ps1 new file mode 100644 index 0000000..f395cd3 --- /dev/null +++ b/script/goctl/GenApi.ps1 @@ -0,0 +1,34 @@ +# script should be execute in current `script` directory. + +# Usage: ./genApi.ps1 [-s] +# -s : also run swagger generation and convert to OpenAPI3 + +param( + [switch]$s +) + +# Save the original location +$originalLocation = Get-Location + +# Change to the target directory +Set-Location -Path (Resolve-Path "../../api") + +# format api files +goctl api format -dir . + +# generate go-zero code +goctl api go -api ServerStatistics.api -dir ../src --style=gozero + +# generate swagger and convert to openapi3 only when -s is provided +if ($s) { + # generate swagger + goctl api swagger --api ServerStatistics.api --dir . + + # swagger to openapi3 + npx swagger2openapi -o ServerStatistics.yaml -p ServerStatistics.json +} else { + Write-Host "Skipping swagger and openapi conversion (pass -s to execute)." +} + +# Restore original location (optional but good practice) +Set-Location -Path $originalLocation diff --git a/src/etc/serverstatistics.yaml b/src/etc/serverstatistics.yaml new file mode 100644 index 0000000..8124a7d --- /dev/null +++ b/src/etc/serverstatistics.yaml @@ -0,0 +1,3 @@ +Name: ServerStatistics +Host: 0.0.0.0 +Port: 8888 diff --git a/src/go.mod b/src/go.mod new file mode 100644 index 0000000..29268a8 --- /dev/null +++ b/src/go.mod @@ -0,0 +1,50 @@ +module src + +go 1.24.4 + +require github.com/zeromicro/go-zero v1.9.1 + +require ( + github.com/beorn7/perks v1.0.1 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/fatih/color v1.18.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/golang-jwt/jwt/v4 v4.5.2 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/grafana/pyroscope-go v1.2.7 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.9 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/klauspost/compress v1.17.11 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/openzipkin/zipkin-go v0.4.3 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/prometheus/client_golang v1.21.1 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.62.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + go.opentelemetry.io/otel v1.24.0 // indirect + go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0 // indirect + go.opentelemetry.io/otel/exporters/zipkin v1.24.0 // indirect + go.opentelemetry.io/otel/metric v1.24.0 // indirect + go.opentelemetry.io/otel/sdk v1.24.0 // indirect + go.opentelemetry.io/otel/trace v1.24.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect + go.uber.org/automaxprocs v1.6.0 // indirect + golang.org/x/net v0.35.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/text v0.22.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect + google.golang.org/grpc v1.65.0 // indirect + google.golang.org/protobuf v1.36.5 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) diff --git a/src/go.sum b/src/go.sum new file mode 100644 index 0000000..84515f6 --- /dev/null +++ b/src/go.sum @@ -0,0 +1,132 @@ +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= +github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +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/grafana/pyroscope-go v1.2.7 h1:VWBBlqxjyR0Cwk2W6UrE8CdcdD80GOFNutj0Kb1T8ac= +github.com/grafana/pyroscope-go v1.2.7/go.mod h1:o/bpSLiJYYP6HQtvcoVKiE9s5RiNgjYTj1DhiddP2Pc= +github.com/grafana/pyroscope-go/godeltaprof v0.1.9 h1:c1Us8i6eSmkW+Ez05d3co8kasnuOY813tbMN8i/a3Og= +github.com/grafana/pyroscope-go/godeltaprof v0.1.9/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= +github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg= +github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= +github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= +github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk= +github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= +github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/zeromicro/go-zero v1.9.1 h1:GZCl4jun/ZgZHnSvX3SSNDHf+tEGmEQ8x2Z23xjHa9g= +github.com/zeromicro/go-zero v1.9.1/go.mod h1:bHOl7Xr7EV/iHZWEqsUNJwFc/9WgAMrPpPagYvOaMtY= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4= +go.opentelemetry.io/otel/exporters/jaeger v1.17.0/go.mod h1:nPCqOnEH9rNLKqH/+rrUjiMzHJdV1BlpKcTwRTyKkKI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 h1:t6wl9SPayj+c7lEIFgm4ooDBZVb01IhLB4InpomhRw8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0/go.mod h1:iSDOcsnSA5INXzZtwaBPrKp/lWu/V14Dd+llD0oI2EA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 h1:Mw5xcxMwlqoJd97vwPxA8isEaIoxsta9/Q51+TTJLGE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0/go.mod h1:CQNu9bj7o7mC6U7+CA/schKEYakYXWr79ucDHTMGhCM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0 h1:Xw8U6u2f8DK2XAkGRFV7BBLENgnTGX9i4rQRxJf+/vs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0/go.mod h1:6KW1Fm6R/s6Z3PGXwSJN2K4eT6wQB3vXX6CVnYX9NmM= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0 h1:s0PHtIkN+3xrbDOpt2M8OTG92cWqUESvzh2MxiR5xY8= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0/go.mod h1:hZlFbDbRt++MMPCCfSJfmhkGIWnX1h3XjkfxZUjLrIA= +go.opentelemetry.io/otel/exporters/zipkin v1.24.0 h1:3evrL5poBuh1KF51D9gO/S+N/1msnm4DaBqs/rpXUqY= +go.opentelemetry.io/otel/exporters/zipkin v1.24.0/go.mod h1:0EHgD8R0+8yRhUYJOGR8Hfg2dpiJQxDOszd5smVO9wM= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw= +go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= +go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= +go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= +golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY= +gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= diff --git a/src/internal/config/config.go b/src/internal/config/config.go new file mode 100644 index 0000000..8da153d --- /dev/null +++ b/src/internal/config/config.go @@ -0,0 +1,7 @@ +package config + +import "github.com/zeromicro/go-zero/rest" + +type Config struct { + rest.RestConf +} diff --git a/src/internal/handler/pinghandler.go b/src/internal/handler/pinghandler.go new file mode 100644 index 0000000..465f298 --- /dev/null +++ b/src/internal/handler/pinghandler.go @@ -0,0 +1,29 @@ +package handler + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "src/internal/logic" + "src/internal/svc" + "src/internal/types" +) + +// Ping the server to check if it's alive +func pingHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.PingReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := logic.NewPingLogic(r.Context(), svcCtx) + resp, err := l.Ping(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/src/internal/handler/recentjoinplayerhandler.go b/src/internal/handler/recentjoinplayerhandler.go new file mode 100644 index 0000000..39dd4ff --- /dev/null +++ b/src/internal/handler/recentjoinplayerhandler.go @@ -0,0 +1,29 @@ +package handler + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "src/internal/logic" + "src/internal/svc" + "src/internal/types" +) + +// Get recent players who joined within a specified time range +func recentJoinPlayerHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.RecentJoinPlayerReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := logic.NewRecentJoinPlayerLogic(r.Context(), svcCtx) + resp, err := l.RecentJoinPlayer(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/src/internal/handler/recentplayerjoinhandler.go b/src/internal/handler/recentplayerjoinhandler.go new file mode 100644 index 0000000..d0b02ef --- /dev/null +++ b/src/internal/handler/recentplayerjoinhandler.go @@ -0,0 +1,29 @@ +package handler + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "src/internal/logic" + "src/internal/svc" + "src/internal/types" +) + +// Get recent player joins within a specified time range +func recentPlayerJoinHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.TotalPlayerJoinReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := logic.NewRecentPlayerJoinLogic(r.Context(), svcCtx) + resp, err := l.RecentPlayerJoin(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/src/internal/handler/routes.go b/src/internal/handler/routes.go new file mode 100644 index 0000000..0059d9e --- /dev/null +++ b/src/internal/handler/routes.go @@ -0,0 +1,74 @@ +// Code generated by goctl. DO NOT EDIT. +// goctl 1.8.4 + +package handler + +import ( + "net/http" + + "src/internal/svc" + + "github.com/zeromicro/go-zero/rest" +) + +func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { + server.AddRoutes( + []rest.Route{ + { + // Ping the server to check if it's alive + Method: http.MethodGet, + Path: "/ping", + Handler: pingHandler(serverCtx), + }, + { + // Get recent players who joined within a specified time range + Method: http.MethodPost, + Path: "/recent-join-player", + Handler: recentJoinPlayerHandler(serverCtx), + }, + { + // Get recent player joins within a specified time range + Method: http.MethodPost, + Path: "/recent-player-join", + Handler: recentPlayerJoinHandler(serverCtx), + }, + { + // Get total chat message count within a specified time range + Method: http.MethodPost, + Path: "/total-chat-message-count", + Handler: totalChatMessageCountHandler(serverCtx), + }, + { + // Get total connect count within a specified time range + Method: http.MethodPost, + Path: "/total-connect-count", + Handler: totalConnectCountHandler(serverCtx), + }, + { + // Get total damage count within a specified time range + Method: http.MethodPost, + Path: "/total-damage-count", + Handler: totalDamageCountHandler(serverCtx), + }, + { + // Get total kill count within a specified time range + Method: http.MethodPost, + Path: "/total-kill-count", + Handler: totalKillCountHandler(serverCtx), + }, + { + // Get total playtime within a specified time range + Method: http.MethodPost, + Path: "/total-play-time", + Handler: totalPlayTimeHandler(serverCtx), + }, + { + // Get total player count within a specified time range + Method: http.MethodPost, + Path: "/total-player-count", + Handler: totalPlayerCountHandler(serverCtx), + }, + }, + rest.WithPrefix("/api/server/statistics"), + ) +} diff --git a/src/internal/handler/totalchatmessagecounthandler.go b/src/internal/handler/totalchatmessagecounthandler.go new file mode 100644 index 0000000..a70936a --- /dev/null +++ b/src/internal/handler/totalchatmessagecounthandler.go @@ -0,0 +1,29 @@ +package handler + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "src/internal/logic" + "src/internal/svc" + "src/internal/types" +) + +// Get total chat message count within a specified time range +func totalChatMessageCountHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.TotalChatMessageCountReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := logic.NewTotalChatMessageCountLogic(r.Context(), svcCtx) + resp, err := l.TotalChatMessageCount(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/src/internal/handler/totalconnectcounthandler.go b/src/internal/handler/totalconnectcounthandler.go new file mode 100644 index 0000000..67d8a0d --- /dev/null +++ b/src/internal/handler/totalconnectcounthandler.go @@ -0,0 +1,29 @@ +package handler + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "src/internal/logic" + "src/internal/svc" + "src/internal/types" +) + +// Get total connect count within a specified time range +func totalConnectCountHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.TotalConnectCountReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := logic.NewTotalConnectCountLogic(r.Context(), svcCtx) + resp, err := l.TotalConnectCount(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/src/internal/handler/totaldamagecounthandler.go b/src/internal/handler/totaldamagecounthandler.go new file mode 100644 index 0000000..d54fde5 --- /dev/null +++ b/src/internal/handler/totaldamagecounthandler.go @@ -0,0 +1,29 @@ +package handler + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "src/internal/logic" + "src/internal/svc" + "src/internal/types" +) + +// Get total damage count within a specified time range +func totalDamageCountHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.TotalDamageCountReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := logic.NewTotalDamageCountLogic(r.Context(), svcCtx) + resp, err := l.TotalDamageCount(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/src/internal/handler/totalkillcounthandler.go b/src/internal/handler/totalkillcounthandler.go new file mode 100644 index 0000000..5596472 --- /dev/null +++ b/src/internal/handler/totalkillcounthandler.go @@ -0,0 +1,29 @@ +package handler + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "src/internal/logic" + "src/internal/svc" + "src/internal/types" +) + +// Get total kill count within a specified time range +func totalKillCountHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.TotalKillCountReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := logic.NewTotalKillCountLogic(r.Context(), svcCtx) + resp, err := l.TotalKillCount(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/src/internal/handler/totalplayercounthandler.go b/src/internal/handler/totalplayercounthandler.go new file mode 100644 index 0000000..7daa791 --- /dev/null +++ b/src/internal/handler/totalplayercounthandler.go @@ -0,0 +1,29 @@ +package handler + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "src/internal/logic" + "src/internal/svc" + "src/internal/types" +) + +// Get total player count within a specified time range +func totalPlayerCountHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.TotalPlayerCountReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := logic.NewTotalPlayerCountLogic(r.Context(), svcCtx) + resp, err := l.TotalPlayerCount(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/src/internal/handler/totalplaytimehandler.go b/src/internal/handler/totalplaytimehandler.go new file mode 100644 index 0000000..25906bf --- /dev/null +++ b/src/internal/handler/totalplaytimehandler.go @@ -0,0 +1,29 @@ +package handler + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "src/internal/logic" + "src/internal/svc" + "src/internal/types" +) + +// Get total playtime within a specified time range +func totalPlayTimeHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.TotalPlayTimeReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := logic.NewTotalPlayTimeLogic(r.Context(), svcCtx) + resp, err := l.TotalPlayTime(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/src/internal/logic/pinglogic.go b/src/internal/logic/pinglogic.go new file mode 100644 index 0000000..392321b --- /dev/null +++ b/src/internal/logic/pinglogic.go @@ -0,0 +1,31 @@ +package logic + +import ( + "context" + + "src/internal/svc" + "src/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type PingLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +// Ping the server to check if it's alive +func NewPingLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PingLogic { + return &PingLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *PingLogic) Ping(req *types.PingReq) (resp *types.PingResp, err error) { + // todo: add your logic here and delete this line + + return +} diff --git a/src/internal/logic/recentjoinplayerlogic.go b/src/internal/logic/recentjoinplayerlogic.go new file mode 100644 index 0000000..7fb631b --- /dev/null +++ b/src/internal/logic/recentjoinplayerlogic.go @@ -0,0 +1,31 @@ +package logic + +import ( + "context" + + "src/internal/svc" + "src/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type RecentJoinPlayerLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +// Get recent players who joined within a specified time range +func NewRecentJoinPlayerLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RecentJoinPlayerLogic { + return &RecentJoinPlayerLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *RecentJoinPlayerLogic) RecentJoinPlayer(req *types.RecentJoinPlayerReq) (resp *types.RecentJoinPlayerResp, err error) { + // todo: add your logic here and delete this line + + return +} diff --git a/src/internal/logic/recentplayerjoinlogic.go b/src/internal/logic/recentplayerjoinlogic.go new file mode 100644 index 0000000..27db675 --- /dev/null +++ b/src/internal/logic/recentplayerjoinlogic.go @@ -0,0 +1,31 @@ +package logic + +import ( + "context" + + "src/internal/svc" + "src/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type RecentPlayerJoinLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +// Get recent player joins within a specified time range +func NewRecentPlayerJoinLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RecentPlayerJoinLogic { + return &RecentPlayerJoinLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *RecentPlayerJoinLogic) RecentPlayerJoin(req *types.TotalPlayerJoinReq) (resp *types.TotalPlayerJoinResp, err error) { + // todo: add your logic here and delete this line + + return +} diff --git a/src/internal/logic/totalchatmessagecountlogic.go b/src/internal/logic/totalchatmessagecountlogic.go new file mode 100644 index 0000000..082b453 --- /dev/null +++ b/src/internal/logic/totalchatmessagecountlogic.go @@ -0,0 +1,31 @@ +package logic + +import ( + "context" + + "src/internal/svc" + "src/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type TotalChatMessageCountLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +// Get total chat message count within a specified time range +func NewTotalChatMessageCountLogic(ctx context.Context, svcCtx *svc.ServiceContext) *TotalChatMessageCountLogic { + return &TotalChatMessageCountLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *TotalChatMessageCountLogic) TotalChatMessageCount(req *types.TotalChatMessageCountReq) (resp *types.TotalChatMessageCountResp, err error) { + // todo: add your logic here and delete this line + + return +} diff --git a/src/internal/logic/totalconnectcountlogic.go b/src/internal/logic/totalconnectcountlogic.go new file mode 100644 index 0000000..29cbfe6 --- /dev/null +++ b/src/internal/logic/totalconnectcountlogic.go @@ -0,0 +1,31 @@ +package logic + +import ( + "context" + + "src/internal/svc" + "src/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type TotalConnectCountLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +// Get total connect count within a specified time range +func NewTotalConnectCountLogic(ctx context.Context, svcCtx *svc.ServiceContext) *TotalConnectCountLogic { + return &TotalConnectCountLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *TotalConnectCountLogic) TotalConnectCount(req *types.TotalConnectCountReq) (resp *types.TotalConnectCountResp, err error) { + // todo: add your logic here and delete this line + + return +} diff --git a/src/internal/logic/totaldamagecountlogic.go b/src/internal/logic/totaldamagecountlogic.go new file mode 100644 index 0000000..e2cc662 --- /dev/null +++ b/src/internal/logic/totaldamagecountlogic.go @@ -0,0 +1,31 @@ +package logic + +import ( + "context" + + "src/internal/svc" + "src/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type TotalDamageCountLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +// Get total damage count within a specified time range +func NewTotalDamageCountLogic(ctx context.Context, svcCtx *svc.ServiceContext) *TotalDamageCountLogic { + return &TotalDamageCountLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *TotalDamageCountLogic) TotalDamageCount(req *types.TotalDamageCountReq) (resp *types.TotalDamageCountResp, err error) { + // todo: add your logic here and delete this line + + return +} diff --git a/src/internal/logic/totalkillcountlogic.go b/src/internal/logic/totalkillcountlogic.go new file mode 100644 index 0000000..34e929d --- /dev/null +++ b/src/internal/logic/totalkillcountlogic.go @@ -0,0 +1,31 @@ +package logic + +import ( + "context" + + "src/internal/svc" + "src/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type TotalKillCountLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +// Get total kill count within a specified time range +func NewTotalKillCountLogic(ctx context.Context, svcCtx *svc.ServiceContext) *TotalKillCountLogic { + return &TotalKillCountLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *TotalKillCountLogic) TotalKillCount(req *types.TotalKillCountReq) (resp *types.TotalKillCountResp, err error) { + // todo: add your logic here and delete this line + + return +} diff --git a/src/internal/logic/totalplayercountlogic.go b/src/internal/logic/totalplayercountlogic.go new file mode 100644 index 0000000..edce7e1 --- /dev/null +++ b/src/internal/logic/totalplayercountlogic.go @@ -0,0 +1,31 @@ +package logic + +import ( + "context" + + "src/internal/svc" + "src/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type TotalPlayerCountLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +// Get total player count within a specified time range +func NewTotalPlayerCountLogic(ctx context.Context, svcCtx *svc.ServiceContext) *TotalPlayerCountLogic { + return &TotalPlayerCountLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *TotalPlayerCountLogic) TotalPlayerCount(req *types.TotalPlayerCountReq) (resp *types.TotalPlayerCountResp, err error) { + // todo: add your logic here and delete this line + + return +} diff --git a/src/internal/logic/totalplaytimelogic.go b/src/internal/logic/totalplaytimelogic.go new file mode 100644 index 0000000..3c13826 --- /dev/null +++ b/src/internal/logic/totalplaytimelogic.go @@ -0,0 +1,31 @@ +package logic + +import ( + "context" + + "src/internal/svc" + "src/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type TotalPlayTimeLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +// Get total playtime within a specified time range +func NewTotalPlayTimeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *TotalPlayTimeLogic { + return &TotalPlayTimeLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *TotalPlayTimeLogic) TotalPlayTime(req *types.TotalPlayTimeReq) (resp *types.TotalPlayTimeResp, err error) { + // todo: add your logic here and delete this line + + return +} diff --git a/src/internal/svc/servicecontext.go b/src/internal/svc/servicecontext.go new file mode 100644 index 0000000..05b2085 --- /dev/null +++ b/src/internal/svc/servicecontext.go @@ -0,0 +1,15 @@ +package svc + +import ( + "src/internal/config" +) + +type ServiceContext struct { + Config config.Config +} + +func NewServiceContext(c config.Config) *ServiceContext { + return &ServiceContext{ + Config: c, + } +} diff --git a/src/internal/types/types.go b/src/internal/types/types.go new file mode 100644 index 0000000..1dd67eb --- /dev/null +++ b/src/internal/types/types.go @@ -0,0 +1,112 @@ +// Code generated by goctl. DO NOT EDIT. +// goctl 1.8.4 + +package types + +type PingReq struct { +} + +type PingResp struct { + Ok bool `json:"ok"` +} + +type RecentChatMessageReq struct { + TimeRangeStart int64 `json:"timeRangeStart"` // Unix timestamp in milliseconds + TimeRangeEnd int64 `json:"timeRangeEnd"` // Unix timestamp in milliseconds +} + +type RecentChatMessageResp struct { + Messages []RecentChatMessageRespMessage `json:"messages"` // List of recent chat messages +} + +type RecentChatMessageRespMessage struct { + SteamID64 string `json:"steamID64"` // Player's SteamID64 + UserName string `json:"userName"` // Player's username at the time of message + Message string `json:"message"` // Chat message content + TimeStamp int64 `json:"timeStamp"` // Message timestamp as Unix timestamp in milliseconds +} + +type RecentJoinPlayerReq struct { + TimeRangeStart int64 `json:"timeRangeStart"` // Unix timestamp in milliseconds + TimeRangeEnd int64 `json:"timeRangeEnd"` // Unix timestamp in milliseconds +} + +type RecentJoinPlayerResp struct { + Players []RecentJoinPlayerRespPlayer `json:"players"` // List of player SteamID64s who joined in the time range +} + +type RecentJoinPlayerRespPlayer struct { + SteamID64 string `json:"steamID64"` // Player's SteamID64 + JoinTime int64 `json:"joinTime"` // Join time as Unix timestamp in milliseconds + UserName string `json:"userName"` // Player's username at the time of joining + PlayTime int64 `json:"playTime"` // Playtime in seconds since joining +} + +type TotalChatMessageCountReq struct { + TimeRangeStart int64 `json:"timeRangeStart"` // Unix timestamp in milliseconds + TimeRangeEnd int64 `json:"timeRangeEnd"` // Unix timestamp in milliseconds + PlayerFilter []string `json:"playerFilter"` // List of player SteamID64s to filter by (optional) +} + +type TotalChatMessageCountResp struct { + TotalChatMessageCount int64 `json:"totalChatMessageCount"` // Total chat message count +} + +type TotalConnectCountReq struct { + TimeRangeStart int64 `json:"timeRangeStart"` // Unix timestamp in milliseconds + TimeRangeEnd int64 `json:"timeRangeEnd"` // Unix timestamp in milliseconds +} + +type TotalConnectCountResp struct { + TotalConnectCount int64 `json:"totalConnectCount"` // Total connect count +} + +type TotalDamageCountReq struct { + TimeRangeStart int64 `json:"timeRangeStart"` // Unix timestamp in milliseconds + TimeRangeEnd int64 `json:"timeRangeEnd"` // Unix timestamp in milliseconds + WeaponFilter []string `json:"weaponFilter"` // List of weapon names to filter by (optional) + PlayerFilter []string `json:"playerFilter"` // List of player SteamID64s to filter by (optional) +} + +type TotalDamageCountResp struct { + TotalDamageCount int64 `json:"totalDamageCount"` // Total damage count +} + +type TotalKillCountReq struct { + TimeRangeStart int64 `json:"timeRangeStart"` // Unix timestamp in milliseconds + TimeRangeEnd int64 `json:"timeRangeEnd"` // Unix timestamp in milliseconds + HeadshotOnly bool `json:"headshotOnly"` // If true, count only headshot kills + WeaponFilter []string `json:"weaponFilter"` // List of weapon names to filter by (optional) + PlayerFilter []string `json:"playerFilter"` // List of player SteamID64s to filter by (optional) +} + +type TotalKillCountResp struct { + TotalKillCount int64 `json:"totalKillCount"` // Total kill count +} + +type TotalPlayTimeReq struct { + TimeRangeStart int64 `json:"timeRangeStart"` // Unix timestamp in milliseconds + TimeRangeEnd int64 `json:"timeRangeEnd"` // Unix timestamp in milliseconds +} + +type TotalPlayTimeResp struct { + TotalPlayTime int64 `json:"totalPlayTime"` // Total playtime in seconds +} + +type TotalPlayerCountReq struct { + TimeRangeStart int64 `json:"timeRangeStart"` // Unix timestamp in milliseconds + TimeRangeEnd int64 `json:"timeRangeEnd"` // Unix timestamp in milliseconds +} + +type TotalPlayerCountResp struct { + Count int64 `json:"count"` +} + +type TotalPlayerJoinReq struct { + TimeRangeStart int64 `json:"timeRangeStart"` // Unix timestamp in milliseconds + TimeRangeEnd int64 `json:"timeRangeEnd"` // Unix timestamp in milliseconds +} + +type TotalPlayerJoinResp struct { + Count int64 `json:"count"` +} diff --git a/src/serverstatistics.go b/src/serverstatistics.go new file mode 100644 index 0000000..a7c241a --- /dev/null +++ b/src/serverstatistics.go @@ -0,0 +1,31 @@ +package main + +import ( + "flag" + "fmt" + + "src/internal/config" + "src/internal/handler" + "src/internal/svc" + + "github.com/zeromicro/go-zero/core/conf" + "github.com/zeromicro/go-zero/rest" +) + +var configFile = flag.String("f", "etc/serverstatistics.yaml", "the config file") + +func main() { + flag.Parse() + + var c config.Config + conf.MustLoad(*configFile, &c) + + server := rest.MustNewServer(c.RestConf) + defer server.Stop() + + ctx := svc.NewServiceContext(c) + handler.RegisterHandlers(server, ctx) + + fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port) + server.Start() +}