Skip to content

Commit

Permalink
Add success/code to results. Dont save duplicates to db.
Browse files Browse the repository at this point in the history
  • Loading branch information
leighmacdonald committed Apr 16, 2024
1 parent 798a381 commit c8f3274
Show file tree
Hide file tree
Showing 18 changed files with 298 additions and 149 deletions.
18 changes: 18 additions & 0 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ const AdminNewsPage = loadable(() => import('./page/AdminNewsPage'));
const AdminPeoplePage = loadable(() => import('./page/AdminPeoplePage'));
const AdminReportsPage = loadable(() => import('./page/AdminReportsPage'));
const AdminServersPage = loadable(() => import('./page/AdminServersPage'));
const AdminVotesPage = loadable(() => import('./page/AdminVotesPage'));
const BanPage = loadable(() => import('./page/BanPage'));
const ChatLogPage = loadable(() => import('./page/ChatLogPage'));
const ContestListPage = loadable(() => import('./page/ContestListPage'));
Expand Down Expand Up @@ -90,6 +91,7 @@ const StatsPage = loadable(() => import('./page/StatsPage'));
const StatsWeaponOverallPage = loadable(
() => import('./page/StatsWeaponOverallPage')
);

const WikiPage = loadable(() => import('./page/WikiPage'));

export const App = ({ initialTheme }: AppProps): JSX.Element => {
Expand Down Expand Up @@ -644,6 +646,22 @@ export const App = ({ initialTheme }: AppProps): JSX.Element => {
</ErrorBoundary>
}
/>
<Route
path={
'/admin/votes'
}
element={
<ErrorBoundary>
<PrivateRoute
permission={
PermissionLevel.Moderator
}
>
<AdminVotesPage />
</PrivateRoute>
</ErrorBoundary>
}
/>
<Route
path={
'/admin/contests'
Expand Down
2 changes: 2 additions & 0 deletions internal/chat/chat_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@ type chatRepository struct {
}

func NewChatRepository(database database.Database, personUsecase domain.PersonUsecase, wordFilterUsecase domain.WordFilterUsecase,
matchUsecase domain.MatchUsecase,
broadcaster *fp.Broadcaster[logparse.EventType, logparse.ServerEvent],
) domain.ChatRepository {
return &chatRepository{
db: database,
personUsecase: personUsecase,
wordFilterUsecase: wordFilterUsecase,
matchUsecase: matchUsecase,
broadcaster: broadcaster,
WarningChan: make(chan domain.NewUserWarning),
}
Expand Down
2 changes: 1 addition & 1 deletion internal/cmd/refresh.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func refreshFiltersCmd() *cobra.Command {
banRepository := ban.NewBanSteamRepository(dbUsecase, personUsecase, networkUsecase)
banGroupUsecase := steamgroup.NewBanGroupUsecase(steamgroup.NewSteamGroupRepository(dbUsecase))
banUsecase := ban.NewBanSteamUsecase(banRepository, personUsecase, configUsecase, discordUsecase, banGroupUsecase, reportUsecase, stateUsecase)
chatRepository := chat.NewChatRepository(dbUsecase, personUsecase, wordFilterUsecase, eventBroadcaster)
chatRepository := chat.NewChatRepository(dbUsecase, personUsecase, wordFilterUsecase, nil, eventBroadcaster)
chatUsecase := chat.NewChatUsecase(configUsecase, chatRepository, wordFilterUsecase, stateUsecase, banUsecase,
personUsecase, discordUsecase)

Expand Down
17 changes: 12 additions & 5 deletions internal/cmd/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import (
"github.com/leighmacdonald/gbans/internal/srcds"
"github.com/leighmacdonald/gbans/internal/state"
"github.com/leighmacdonald/gbans/internal/steamgroup"
"github.com/leighmacdonald/gbans/internal/votes"
"github.com/leighmacdonald/gbans/internal/wiki"
"github.com/leighmacdonald/gbans/internal/wordfilter"
"github.com/leighmacdonald/gbans/pkg/fp"
Expand Down Expand Up @@ -149,6 +150,8 @@ func serveCmd() *cobra.Command { //nolint:maintidx
return
}

go networkUsecase.Start(ctx)

assetRepository := asset.NewS3Repository(dbUsecase, minioClient, conf.S3.Region)
if errInit := assetRepository.Init(ctx); errInit != nil {
slog.Error("Failed to ensure s3 buckets exist", log.ErrAttr(errInit))
Expand Down Expand Up @@ -183,8 +186,13 @@ func serveCmd() *cobra.Command { //nolint:maintidx
ban.NewBanNetRepository(dbUsecase)

apu := appeal.NewAppealUsecase(appeal.NewAppealRepository(dbUsecase), banUsecase, personUsecase, discordUsecase, configUsecase)
matchRepo := match.NewMatchRepository(eventBroadcaster, dbUsecase, personUsecase, serversUsecase, discordUsecase, stateUsecase, weaponsMap)
go matchRepo.Start(ctx)

matchUsecase := match.NewMatchUsecase(matchRepo, stateUsecase, serversUsecase, discordUsecase)

chatRepository := chat.NewChatRepository(dbUsecase, personUsecase, wordFilterUsecase, eventBroadcaster)
chatRepository := chat.NewChatRepository(dbUsecase, personUsecase, wordFilterUsecase, matchUsecase, eventBroadcaster)
go chatRepository.Start(ctx)

chatUsecase := chat.NewChatUsecase(configUsecase, chatRepository, wordFilterUsecase, stateUsecase, banUsecase, personUsecase, discordUsecase)
go chatUsecase.Start(ctx)
Expand All @@ -196,10 +204,6 @@ func serveCmd() *cobra.Command { //nolint:maintidx

go forumUsecase.Start(ctx)

matchRepo := match.NewMatchRepository(eventBroadcaster, dbUsecase, personUsecase, serversUsecase, discordUsecase, stateUsecase, weaponsMap)
go matchRepo.Start(ctx)

matchUsecase := match.NewMatchUsecase(matchRepo, stateUsecase, serversUsecase, discordUsecase)
newsUsecase := news.NewNewsUsecase(news.NewNewsRepository(dbUsecase))
notificationUsecase := notification.NewNotificationUsecase(notification.NewNotificationRepository(dbUsecase), personUsecase)
patreonUsecase := patreon.NewPatreonUsecase(patreon.NewPatreonRepository(dbUsecase))
Expand All @@ -212,6 +216,9 @@ func serveCmd() *cobra.Command { //nolint:maintidx
authUsecase := auth.NewAuthUsecase(auth.NewAuthRepository(dbUsecase), configUsecase, personUsecase, banUsecase, serversUsecase)
go authUsecase.Start(ctx)

voteUsecase := votes.NewVoteUsecase(votes.NewVoteRepository(dbUsecase), personUsecase, matchUsecase, discordUsecase, eventBroadcaster)
go voteUsecase.Start(ctx)

contestUsecase := contest.NewContestUsecase(contest.NewContestRepository(dbUsecase))

// start workers
Expand Down
6 changes: 3 additions & 3 deletions internal/database/migrations/000083_vote_logs.up.sql
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ create table vote_result
(
vote_id serial primary key,
server_id int not null references server (server_id),
match_id uuid not null references match (match_id),
source_id bigint not null references person (steam_id),
target_id bigint references person (steam_id),
passed bool not null,
name text not null,
success bool not null,
name text not null default '',
code int not null default 0,
created_on timestamp not null
);

Expand Down
13 changes: 13 additions & 0 deletions internal/discord/responses.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io"
"net"
"sort"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -1105,3 +1106,15 @@ func NotificationMessage(message string, link string) *discordgo.MessageEmbed {

return msgEmbed.Embed().Truncate().MessageEmbed
}

func VoteResultMessage(result domain.VoteResult) *discordgo.MessageEmbed {
msgEmbed := NewEmbed("Vote Result")
msgEmbed.Embed().
AddField("Initiator", result.SourceID.String()).
AddField("Target", result.TargetID.String()).
AddField("Code", fmt.Sprintf("%d", result.Code)).
AddField("Success", strconv.FormatBool(result.Success)).
AddField("Server", fmt.Sprintf("%d", result.ServerID))

return msgEmbed.Embed().Truncate().MessageEmbed
}
1 change: 1 addition & 0 deletions internal/domain/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import "context"

type ChatRepository interface {
GetPersonMessage(ctx context.Context, messageID int64) (QueryChatHistoryResult, error)
Start(ctx context.Context)
TopChatters(ctx context.Context, count uint64) ([]TopChatterResult, error)
AddChatHistory(ctx context.Context, message *PersonMessage) error
QueryChatHistory(ctx context.Context, filters ChatHistoryQueryFilter) ([]QueryChatHistoryResult, int64, error)
Expand Down
1 change: 1 addition & 0 deletions internal/domain/net.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type NetworkUsecase interface {
IsMatch(addr netip.Addr) (string, bool)
AddWhitelist(id int, network *net.IPNet)
RemoveWhitelist(id int)
Start(ctx context.Context)
AddRemoteSource(ctx context.Context, name string, url string) (int64, error)
QueryNetwork(ctx context.Context, ip netip.Addr) (NetworkDetails, error)
}
Expand Down
8 changes: 6 additions & 2 deletions internal/domain/vote.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package domain

import (
"context"
"time"

"github.com/gofrs/uuid/v5"
"github.com/leighmacdonald/gbans/pkg/logparse"
"github.com/leighmacdonald/steamid/v4/steamid"
"time"
)

type VoteQueryFilter struct {
Expand All @@ -22,7 +24,7 @@ type VoteRepository interface {
}

type VoteUsecase interface {
Query(ctx context.Context, filter VoteQueryFilter) ([]VoteResult, error)
Query(ctx context.Context, filter VoteQueryFilter) ([]VoteResult, int64, error)
Start(ctx context.Context)
}

Expand All @@ -33,5 +35,7 @@ type VoteResult struct {
TargetID steamid.SteamID
Valid int
Name string
Success bool
Code logparse.VoteCode
CreatedOn time.Time
}
76 changes: 0 additions & 76 deletions internal/state/state_usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"fmt"
"log/slog"
"net"
"os"
"strings"
"sync"
"time"
Expand Down Expand Up @@ -61,8 +60,6 @@ func (s *stateUsecase) Start(ctx context.Context) error {

s.updateSrcdsLogSecrets(ctx)

go s.logReader(ctx, s.configUsecase.Config().Debug.WriteUnhandledLogEvents)

// TODO run on server Config changes
s.updateSrcdsLogSecrets(ctx)

Expand All @@ -71,79 +68,6 @@ func (s *stateUsecase) Start(ctx context.Context) error {
return nil
}

// logReader is the fan-out orchestrator for game log events
// Registering receivers can be accomplished with app.eb.Broadcaster.
func (s *stateUsecase) logReader(ctx context.Context, writeUnhandled bool) {
var file *os.File

if writeUnhandled {
var errCreateFile error
file, errCreateFile = os.Create("./unhandled_messages.log")

if errCreateFile != nil {
slog.Error("Failed to open debug message log", log.ErrAttr(errCreateFile))
} else {
defer func() {
if errClose := file.Close(); errClose != nil {
slog.Error("Failed to close unhandled_messages.log", log.ErrAttr(errClose))
}
}()
}
}

parser := logparse.NewLogParser()

// playerStateCache := newPlayerCache(app.logger)
for {
select {
case logFile := <-s.logFileChan:
emitted := 0
failed := 0
unknown := 0
ignored := 0

for _, logLine := range logFile.Lines {
parseResult, errParse := parser.Parse(logLine)
if errParse != nil {
continue
}

newServerEvent := logparse.ServerEvent{
ServerName: logFile.ServerName,
ServerID: logFile.ServerID,
Results: parseResult,
}

if newServerEvent.EventType == logparse.IgnoredMsg {
ignored++

continue
} else if newServerEvent.EventType == logparse.UnknownMsg {
unknown++

if writeUnhandled {
if _, errWrite := file.WriteString(logLine + "\n"); errWrite != nil {
slog.Error("Failed to write debug log", log.ErrAttr(errWrite))
}
}
}

s.broadcaster.Emit(newServerEvent.EventType, newServerEvent)

emitted++
}

slog.Debug("Completed emitting logfile events",
slog.Int("ok", emitted), slog.Int("failed", failed),
slog.Int("unknown", unknown), slog.Int("ignored", ignored))
case <-ctx.Done():
slog.Debug("logReader shutting down")

return
}
}
}

func (s *stateUsecase) updateSrcdsLogSecrets(ctx context.Context) {
newSecrets := map[int]logparse.ServerIDMap{}
serversCtx, cancelServers := context.WithTimeout(ctx, time.Second*5)
Expand Down
35 changes: 16 additions & 19 deletions internal/votes/vote_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,19 @@ package votes

import (
"context"

sq "github.com/Masterminds/squirrel"
"github.com/leighmacdonald/gbans/internal/database"
"github.com/leighmacdonald/gbans/internal/domain"
"github.com/leighmacdonald/gbans/pkg/fp"
"github.com/leighmacdonald/gbans/pkg/logparse"
"github.com/leighmacdonald/steamid/v4/steamid"
)

type voteRepository struct {
db database.Database
personUsecase domain.PersonUsecase
matchUsecase domain.MatchUsecase
broadcaster *fp.Broadcaster[logparse.EventType, logparse.ServerEvent]
db database.Database
}

func NewVoteRepository(database database.Database, personUsecase domain.PersonUsecase, matchUsecase domain.MatchUsecase, broadcaster *fp.Broadcaster[logparse.EventType, logparse.ServerEvent]) domain.VoteRepository {
return &voteRepository{
db: database,
personUsecase: personUsecase,
matchUsecase: matchUsecase,
broadcaster: broadcaster,
}
func NewVoteRepository(database database.Database) domain.VoteRepository {
return &voteRepository{db: database}
}

func (r voteRepository) Query(ctx context.Context, filter domain.VoteQueryFilter) ([]domain.VoteResult, error) {
Expand All @@ -32,15 +23,19 @@ func (r voteRepository) Query(ctx context.Context, filter domain.VoteQueryFilter
if filter.SourceID.Valid() {
constraints = append(constraints, sq.Eq{"source_id": filter.SourceID.Int64()})
}

if filter.TargetID.Valid() {
constraints = append(constraints, sq.Eq{"target_id": filter.TargetID.Int64()})
}

if !filter.MatchID.IsNil() {
constraints = append(constraints, sq.Eq{"match_id": filter.MatchID.String()})
}

if filter.ServerID > 0 {
constraints = append(constraints, sq.Eq{"server_id": filter.ServerID})
}

if filter.Name != "" {
constraints = append(constraints, sq.Eq{"name": filter.Name})
}
Expand Down Expand Up @@ -69,6 +64,7 @@ func (r voteRepository) Query(ctx context.Context, filter domain.VoteQueryFilter
targetID *int64
result domain.VoteResult
)

if errScan := rows.Scan(&result.ServerID, &result.MatchID, &sourceID, &targetID, &result.Valid, &result.Name, &result.CreatedOn); errScan != nil {
return nil, r.db.DBErr(errScan)
}
Expand All @@ -88,11 +84,12 @@ func (r voteRepository) AddResult(ctx context.Context, voteResult domain.VoteRes
return r.db.DBErr(r.db.ExecInsertBuilder(ctx, r.db.Builder().
Insert("vote_result").
SetMap(map[string]interface{}{
"server_id": voteResult.ServerID,
"match_id": voteResult.MatchID,
"source_id": voteResult.SourceID,
"target_id": voteResult.TargetID,
"valid": voteResult.Valid,
"name": voteResult.Name,
"server_id": voteResult.ServerID,
"source_id": voteResult.SourceID,
"target_id": voteResult.TargetID,
"success": voteResult.Success,
"name": voteResult.Name,
"code": voteResult.Code,
"created_on": voteResult.CreatedOn,
})))
}
Loading

0 comments on commit c8f3274

Please sign in to comment.