This commit is contained in:
2025-10-04 17:46:47 +08:00
parent b9e205356b
commit 14936b7384
6 changed files with 152 additions and 10 deletions

View File

@@ -120,6 +120,10 @@ type (
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
ServerName string `json:"serverName"` // Server name where the message was sent
MapName string `json:"mapName"` // Map name where the message was sent
ServerIP string `json:"serverIP"` // Server IP where the message was sent
ServerPort int `json:"serverPort"` // Server port where the message was sent
}
)
@@ -155,6 +159,21 @@ type (
}
)
type (
TopKillerReq {
TimeRangeStart int64 `json:"timeRangeStart"` // Unix timestamp in milliseconds
TimeRangeEnd int64 `json:"timeRangeEnd"` // Unix timestamp in milliseconds
}
TopKillerResp {
Players []TopKillerRespPlayer `json:"players"` // List of top players by kill count
}
TopKillerRespPlayer {
SteamID64 string `json:"steamID64"` // Player's SteamID64
UserName string `json:"userName"` // Player's username at the time of playing
KillCount int64 `json:"killCount"` // Kill count during the time range
}
)
@server (
prefix: /api/server/statistics
)
@@ -242,5 +261,12 @@ service ServerStatistics {
)
@handler topPlayTimeHandler
post /top-play-time (TopPlayTimeReq) returns (TopPlayTimeResp)
@doc (
summary: "Get top players by kill count within a specified time range"
description: "Get top players by kill count within a specified time range"
)
@handler topKillerHandler
post /top-killer (TopKillerReq) returns (TopKillerResp)
}

View File

@@ -44,6 +44,12 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
Path: "/recent-player-join",
Handler: recentPlayerJoinHandler(serverCtx),
},
{
// Get top players by kill count within a specified time range
Method: http.MethodPost,
Path: "/top-killer",
Handler: topKillerHandler(serverCtx),
},
{
// Get top players by playtime within a specified time range
Method: http.MethodPost,

View File

@@ -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 top players by kill count within a specified time range
func topKillerHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.TopKillerReq
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewTopKillerLogic(r.Context(), svcCtx)
resp, err := l.TopKiller(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}

View File

@@ -27,7 +27,8 @@ func NewRecentChatMessageLogic(ctx context.Context, svcCtx *svc.ServiceContext)
func (l *RecentChatMessageLogic) RecentChatMessage(req *types.RecentChatMessageReq) (resp *types.RecentChatMessageResp, err error) {
query := `
SELECT steamid64, player_name, message,
EXTRACT(EPOCH FROM message_time)::BIGINT * 1000 as timestamp
EXTRACT(EPOCH FROM message_time)::BIGINT * 1000 as timestamp,
server_name, mapname, server_ip, server_port
FROM steam_union.chat_log
WHERE message_time >= TO_TIMESTAMP($1 / 1000.0)
AND message_time <= TO_TIMESTAMP($2 / 1000.0)
@@ -44,7 +45,8 @@ func (l *RecentChatMessageLogic) RecentChatMessage(req *types.RecentChatMessageR
var messages []types.RecentChatMessageRespMessage
for rows.Next() {
var msg types.RecentChatMessageRespMessage
if err := rows.Scan(&msg.SteamID64, &msg.UserName, &msg.Message, &msg.TimeStamp); err != nil {
if err := rows.Scan(&msg.SteamID64, &msg.UserName, &msg.Message, &msg.TimeStamp,
&msg.ServerName, &msg.MapName, &msg.ServerIP, &msg.ServerPort); err != nil {
l.Errorf("Failed to scan chat message: %v", err)
continue
}

View File

@@ -0,0 +1,60 @@
package logic
import (
"context"
"src/internal/svc"
"src/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type TopKillerLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// Get top players by kill count within a specified time range
func NewTopKillerLogic(ctx context.Context, svcCtx *svc.ServiceContext) *TopKillerLogic {
return &TopKillerLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *TopKillerLogic) TopKiller(req *types.TopKillerReq) (resp *types.TopKillerResp, err error) {
query := `
SELECT attacker_steamid64, attacker_name,
COUNT(*) as kill_count
FROM steam_union.event_player_death_log
WHERE event_player_death_time >= TO_TIMESTAMP($1 / 1000.0)
AND event_player_death_time <= TO_TIMESTAMP($2 / 1000.0)
AND attacker_steamid64 > 1
GROUP BY attacker_steamid64, attacker_name
ORDER BY kill_count DESC
LIMIT 100
`
rows, err := l.svcCtx.DB.QueryContext(l.ctx, query, req.TimeRangeStart, req.TimeRangeEnd)
if err != nil {
l.Errorf("Failed to query top killers: %v", err)
return nil, err
}
defer rows.Close()
var players []types.TopKillerRespPlayer
for rows.Next() {
var player types.TopKillerRespPlayer
if err := rows.Scan(&player.SteamID64, &player.UserName, &player.KillCount); err != nil {
l.Errorf("Failed to scan top killer: %v", err)
continue
}
players = append(players, player)
}
return &types.TopKillerResp{
Players: players,
}, nil
}

View File

@@ -24,6 +24,10 @@ type RecentChatMessageRespMessage struct {
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
ServerName string `json:"serverName"` // Server name where the message was sent
MapName string `json:"mapName"` // Map name where the message was sent
ServerIP string `json:"serverIP"` // Server IP where the message was sent
ServerPort int `json:"serverPort"` // Server port where the message was sent
}
type RecentJoinPlayerReq struct {
@@ -59,6 +63,21 @@ type RecentPlayRespPlayer struct {
PlayTime int64 `json:"playTime"` // Playtime in seconds during the time range
}
type TopKillerReq struct {
TimeRangeStart int64 `json:"timeRangeStart"` // Unix timestamp in milliseconds
TimeRangeEnd int64 `json:"timeRangeEnd"` // Unix timestamp in milliseconds
}
type TopKillerResp struct {
Players []TopKillerRespPlayer `json:"players"` // List of top players by kill count
}
type TopKillerRespPlayer struct {
SteamID64 string `json:"steamID64"` // Player's SteamID64
UserName string `json:"userName"` // Player's username at the time of playing
KillCount int64 `json:"killCount"` // Kill count during the time range
}
type TopPlayTimeReq struct {
TimeRangeStart int64 `json:"timeRangeStart"` // Unix timestamp in milliseconds
TimeRangeEnd int64 `json:"timeRangeEnd"` // Unix timestamp in milliseconds