darts support
This commit is contained in:
parent
e0aaf536a0
commit
ecaad893ba
2
go.mod
2
go.mod
|
|
@ -18,6 +18,8 @@ require (
|
||||||
golang.org/x/crypto v0.36.0
|
golang.org/x/crypto v0.36.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
require github.com/gorilla/websocket v1.5.3 // indirect
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||||
github.com/andybalholm/brotli v1.1.1 // indirect
|
github.com/andybalholm/brotli v1.1.1 // indirect
|
||||||
|
|
|
||||||
2
go.sum
2
go.sum
|
|
@ -63,6 +63,8 @@ github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVI
|
||||||
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/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
|
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/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||||
|
|
|
||||||
|
|
@ -249,6 +249,35 @@ type VolleyballResultResponse struct {
|
||||||
Bet365ID string `json:"bet365_id"`
|
Bet365ID string `json:"bet365_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DartsResultResponse struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
SportID string `json:"sport_id"`
|
||||||
|
Time string `json:"time"`
|
||||||
|
TimeStatus string `json:"time_status"`
|
||||||
|
League struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
CC string `json:"cc"`
|
||||||
|
} `json:"league"`
|
||||||
|
Home struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
ImageID string `json:"image_id"`
|
||||||
|
CC string `json:"cc"`
|
||||||
|
} `json:"home"`
|
||||||
|
Away struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
ImageID string `json:"image_id"`
|
||||||
|
CC string `json:"cc"`
|
||||||
|
} `json:"away"`
|
||||||
|
SS string `json:"ss"`
|
||||||
|
InplayCreatedAt string `json:"inplay_created_at"`
|
||||||
|
InplayUpdatedAt string `json:"inplay_updated_at"`
|
||||||
|
ConfirmedAt string `json:"confirmed_at"`
|
||||||
|
Bet365ID string `json:"bet365_id"`
|
||||||
|
}
|
||||||
|
|
||||||
type Score struct {
|
type Score struct {
|
||||||
Home string `json:"home"`
|
Home string `json:"home"`
|
||||||
Away string `json:"away"`
|
Away string `json:"away"`
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,23 @@ const (
|
||||||
VOLLEYBALL_SET_ONE_TOTAL_ODD_EVEN VolleyballMarket = 910218
|
VOLLEYBALL_SET_ONE_TOTAL_ODD_EVEN VolleyballMarket = 910218
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type DartsMarket int64
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Main
|
||||||
|
DARTS_MATCH_WINNER DartsMarket = 703 // match_winner
|
||||||
|
DARTS_MATCH_DOUBLE DartsMarket = 150228 // match_double
|
||||||
|
DARTS_MATCH_TREBLE DartsMarket = 150230 // match_treble
|
||||||
|
DARTS_CORRECT_LEG_SCORE DartsMarket = 150015 // correct_leg_score
|
||||||
|
DARTS_TOTAL_LEGS DartsMarket = 150117 // total_legs
|
||||||
|
|
||||||
|
DARTS_MOST_HUNDERED_EIGHTYS DartsMarket = 150030 // "most_180s"
|
||||||
|
DARTS_TOTAL_HUNDERED_EIGHTYS DartsMarket = 150012 // total_180s
|
||||||
|
DARTS_MOST_HUNDERED_EIGHTYS_HANDICAP DartsMarket = 150227 // most_180s_handicap
|
||||||
|
DARTS_PLAYER_HUNDERED_EIGHTYS DartsMarket = 150121 // player_180s
|
||||||
|
DARTS_FIRST_DART DartsMarket = 150125 // first_dart
|
||||||
|
)
|
||||||
|
|
||||||
// TODO: Move this into the database so that it can be modified dynamically
|
// TODO: Move this into the database so that it can be modified dynamically
|
||||||
|
|
||||||
var SupportedMarkets = map[int64]bool{
|
var SupportedMarkets = map[int64]bool{
|
||||||
|
|
@ -221,4 +238,17 @@ var SupportedMarkets = map[int64]bool{
|
||||||
int64(VOLLEYBALL_SET_ONE_LINES): false,
|
int64(VOLLEYBALL_SET_ONE_LINES): false,
|
||||||
int64(VOLLEYBALL_SET_ONE_TO_GO_TO_EXTRA_POINTS): false,
|
int64(VOLLEYBALL_SET_ONE_TO_GO_TO_EXTRA_POINTS): false,
|
||||||
int64(VOLLEYBALL_SET_ONE_TOTAL_ODD_EVEN): false,
|
int64(VOLLEYBALL_SET_ONE_TOTAL_ODD_EVEN): false,
|
||||||
|
|
||||||
|
// Darts Markets
|
||||||
|
int64(DARTS_MATCH_WINNER): true,
|
||||||
|
int64(DARTS_TOTAL_LEGS): true,
|
||||||
|
int64(DARTS_CORRECT_LEG_SCORE): false,
|
||||||
|
int64(DARTS_MATCH_DOUBLE): false,
|
||||||
|
int64(DARTS_MATCH_TREBLE): false,
|
||||||
|
|
||||||
|
int64(DARTS_MOST_HUNDERED_EIGHTYS): false,
|
||||||
|
int64(DARTS_TOTAL_HUNDERED_EIGHTYS): false,
|
||||||
|
int64(DARTS_MOST_HUNDERED_EIGHTYS_HANDICAP): false,
|
||||||
|
int64(DARTS_PLAYER_HUNDERED_EIGHTYS): false,
|
||||||
|
int64(DARTS_FIRST_DART): false,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -297,6 +297,30 @@ func evaluateTotalOverUnder(outcome domain.BetOutcome, score struct{ Home, Away
|
||||||
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid odd header: %s", outcome.OddHeader)
|
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid odd header: %s", outcome.OddHeader)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func evaluateTotalLegs(outcome domain.BetOutcome, score struct{ Home, Away int }) (domain.OutcomeStatus, error) {
|
||||||
|
total, err := strconv.ParseFloat(outcome.OddName, 64)
|
||||||
|
if err != nil {
|
||||||
|
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid : %s", outcome.OddName)
|
||||||
|
}
|
||||||
|
|
||||||
|
totalLegs := float64(score.Home + score.Away)
|
||||||
|
|
||||||
|
switch outcome.OddHeader {
|
||||||
|
case "Over":
|
||||||
|
if totalLegs > total {
|
||||||
|
return domain.OUTCOME_STATUS_WIN, nil
|
||||||
|
}
|
||||||
|
return domain.OUTCOME_STATUS_LOSS, nil
|
||||||
|
case "Under":
|
||||||
|
if totalLegs < total {
|
||||||
|
return domain.OUTCOME_STATUS_WIN, nil
|
||||||
|
}
|
||||||
|
return domain.OUTCOME_STATUS_LOSS, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid odd header: %s", outcome.OddHeader)
|
||||||
|
}
|
||||||
|
|
||||||
func evaluateResultAndTotal(outcome domain.BetOutcome, score struct{ Home, Away int }) (domain.OutcomeStatus, error) {
|
func evaluateResultAndTotal(outcome domain.BetOutcome, score struct{ Home, Away int }) (domain.OutcomeStatus, error) {
|
||||||
|
|
||||||
// The handicap will be in the format "U {float}" or "O {float}"
|
// The handicap will be in the format "U {float}" or "O {float}"
|
||||||
|
|
|
||||||
|
|
@ -233,6 +233,12 @@ func (s *Service) FetchResult(ctx context.Context, eventID, oddID, marketID, spo
|
||||||
s.logger.Error("Failed to parse cricket", "event id", eventID, "market_id", marketID, "error", err)
|
s.logger.Error("Failed to parse cricket", "event id", eventID, "market_id", marketID, "error", err)
|
||||||
return domain.CreateResult{}, err
|
return domain.CreateResult{}, err
|
||||||
}
|
}
|
||||||
|
case domain.DARTS:
|
||||||
|
result, err = s.parseDarts(resultResp.Results[0], eventID, oddID, marketID, outcome)
|
||||||
|
if err != nil {
|
||||||
|
s.logger.Error("Failed to parse cricket", "event id", eventID, "market_id", marketID, "error", err)
|
||||||
|
return domain.CreateResult{}, err
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
s.logger.Error("Unsupported sport", "sport", sportID)
|
s.logger.Error("Unsupported sport", "sport", sportID)
|
||||||
return domain.CreateResult{}, fmt.Errorf("unsupported sport: %v", sportID)
|
return domain.CreateResult{}, fmt.Errorf("unsupported sport: %v", sportID)
|
||||||
|
|
@ -387,6 +393,34 @@ func (s *Service) parseVolleyball(response json.RawMessage, eventID, oddID, mark
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) parseDarts(response json.RawMessage, eventID, oddID, marketID int64, outcome domain.BetOutcome) (domain.CreateResult, error) {
|
||||||
|
var dartsRes domain.DartsResultResponse
|
||||||
|
|
||||||
|
if err := json.Unmarshal(response, &dartsRes); err != nil {
|
||||||
|
}
|
||||||
|
if dartsRes.TimeStatus != "3" {
|
||||||
|
s.logger.Warn("Match not yet completed", "event_id", eventID)
|
||||||
|
return domain.CreateResult{}, fmt.Errorf("match not yet completed")
|
||||||
|
}
|
||||||
|
|
||||||
|
// result for dart is limited
|
||||||
|
// only ss is given, format with 2-4
|
||||||
|
status, err := s.evaluateDartsOutcome(outcome, dartsRes)
|
||||||
|
if err != nil {
|
||||||
|
s.logger.Error("Failed to evaluate outcome", "event_id", eventID, "market_id", marketID, "error", err)
|
||||||
|
return domain.CreateResult{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain.CreateResult{
|
||||||
|
BetOutcomeID: 0,
|
||||||
|
EventID: eventID,
|
||||||
|
OddID: oddID,
|
||||||
|
MarketID: marketID,
|
||||||
|
Status: status,
|
||||||
|
}, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func parseScore(home string, away string) struct{ Home, Away int } {
|
func parseScore(home string, away string) struct{ Home, Away int } {
|
||||||
homeVal, _ := strconv.Atoi(strings.TrimSpace(home))
|
homeVal, _ := strconv.Atoi(strings.TrimSpace(home))
|
||||||
awaVal, _ := strconv.Atoi(strings.TrimSpace(away))
|
awaVal, _ := strconv.Atoi(strings.TrimSpace(away))
|
||||||
|
|
@ -605,3 +639,21 @@ func (s *Service) evaluateVolleyballOutcome(outcome domain.BetOutcome, res domai
|
||||||
|
|
||||||
return domain.OUTCOME_STATUS_PENDING, nil
|
return domain.OUTCOME_STATUS_PENDING, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) evaluateDartsOutcome(outcome domain.BetOutcome, res domain.DartsResultResponse) (domain.OutcomeStatus, error) {
|
||||||
|
if !domain.SupportedMarkets[outcome.MarketID] {
|
||||||
|
s.logger.Warn("Unsupported market type", "market_name", outcome.MarketName)
|
||||||
|
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("unsupported market type: %s", outcome.MarketName)
|
||||||
|
}
|
||||||
|
|
||||||
|
score := parseSS(res.SS)
|
||||||
|
|
||||||
|
switch outcome.MarketID {
|
||||||
|
case int64(domain.DARTS_MATCH_WINNER):
|
||||||
|
return evaluateFullTimeResult(outcome, score)
|
||||||
|
case int64(domain.DARTS_TOTAL_LEGS):
|
||||||
|
return evaluateTotalLegs(outcome, score)
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain.OUTCOME_STATUS_PENDING, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
2
makefile
2
makefile
|
|
@ -43,7 +43,7 @@ migrations/up:
|
||||||
.PHONY: postgres
|
.PHONY: postgres
|
||||||
postgres:
|
postgres:
|
||||||
@echo 'Running postgres db...'
|
@echo 'Running postgres db...'
|
||||||
docker compose -f compose.db.yaml exec postgres psql -U root -d gh
|
docker compose -f docker-compose.yml exec postgres psql -U root -d gh
|
||||||
|
|
||||||
.PHONY: swagger
|
.PHONY: swagger
|
||||||
swagger:
|
swagger:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user