update
This commit is contained in:
@@ -120,6 +120,10 @@ type (
|
|||||||
UserName string `json:"userName"` // Player's username at the time of message
|
UserName string `json:"userName"` // Player's username at the time of message
|
||||||
Message string `json:"message"` // Chat message content
|
Message string `json:"message"` // Chat message content
|
||||||
TimeStamp int64 `json:"timeStamp"` // Message timestamp as Unix timestamp in milliseconds
|
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 (
|
@server (
|
||||||
prefix: /api/server/statistics
|
prefix: /api/server/statistics
|
||||||
)
|
)
|
||||||
@@ -242,5 +261,12 @@ service ServerStatistics {
|
|||||||
)
|
)
|
||||||
@handler topPlayTimeHandler
|
@handler topPlayTimeHandler
|
||||||
post /top-play-time (TopPlayTimeReq) returns (TopPlayTimeResp)
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,12 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
Path: "/recent-player-join",
|
Path: "/recent-player-join",
|
||||||
Handler: recentPlayerJoinHandler(serverCtx),
|
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
|
// Get top players by playtime within a specified time range
|
||||||
Method: http.MethodPost,
|
Method: http.MethodPost,
|
||||||
|
|||||||
29
src/internal/handler/topkillerhandler.go
Normal file
29
src/internal/handler/topkillerhandler.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,7 +27,8 @@ func NewRecentChatMessageLogic(ctx context.Context, svcCtx *svc.ServiceContext)
|
|||||||
func (l *RecentChatMessageLogic) RecentChatMessage(req *types.RecentChatMessageReq) (resp *types.RecentChatMessageResp, err error) {
|
func (l *RecentChatMessageLogic) RecentChatMessage(req *types.RecentChatMessageReq) (resp *types.RecentChatMessageResp, err error) {
|
||||||
query := `
|
query := `
|
||||||
SELECT steamid64, player_name, message,
|
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
|
FROM steam_union.chat_log
|
||||||
WHERE message_time >= TO_TIMESTAMP($1 / 1000.0)
|
WHERE message_time >= TO_TIMESTAMP($1 / 1000.0)
|
||||||
AND message_time <= TO_TIMESTAMP($2 / 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
|
var messages []types.RecentChatMessageRespMessage
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var msg types.RecentChatMessageRespMessage
|
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)
|
l.Errorf("Failed to scan chat message: %v", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|||||||
60
src/internal/logic/topkillerlogic.go
Normal file
60
src/internal/logic/topkillerlogic.go
Normal 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
|
||||||
|
}
|
||||||
@@ -24,6 +24,10 @@ type RecentChatMessageRespMessage struct {
|
|||||||
UserName string `json:"userName"` // Player's username at the time of message
|
UserName string `json:"userName"` // Player's username at the time of message
|
||||||
Message string `json:"message"` // Chat message content
|
Message string `json:"message"` // Chat message content
|
||||||
TimeStamp int64 `json:"timeStamp"` // Message timestamp as Unix timestamp in milliseconds
|
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 {
|
type RecentJoinPlayerReq struct {
|
||||||
@@ -59,6 +63,21 @@ type RecentPlayRespPlayer struct {
|
|||||||
PlayTime int64 `json:"playTime"` // Playtime in seconds during the time range
|
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 {
|
type TopPlayTimeReq struct {
|
||||||
TimeRangeStart int64 `json:"timeRangeStart"` // Unix timestamp in milliseconds
|
TimeRangeStart int64 `json:"timeRangeStart"` // Unix timestamp in milliseconds
|
||||||
TimeRangeEnd int64 `json:"timeRangeEnd"` // Unix timestamp in milliseconds
|
TimeRangeEnd int64 `json:"timeRangeEnd"` // Unix timestamp in milliseconds
|
||||||
|
|||||||
Reference in New Issue
Block a user