|
|
|
@ -10,6 +10,7 @@ import (
|
|
|
|
|
"net/url"
|
|
|
|
|
"os"
|
|
|
|
|
"os/signal"
|
|
|
|
|
"runtime/pprof"
|
|
|
|
|
"sort"
|
|
|
|
|
"strconv"
|
|
|
|
|
"strings"
|
|
|
|
@ -41,6 +42,7 @@ const (
|
|
|
|
|
var (
|
|
|
|
|
dbFile = flag.String("db", "", "SQlite database file path.")
|
|
|
|
|
debug = flag.Bool("debug", false, "Set log level to DEBUG.")
|
|
|
|
|
cpuProfile = flag.String("cpuprofile", "", "Output file for pprof profiling.")
|
|
|
|
|
|
|
|
|
|
store *themis.Store
|
|
|
|
|
tracer trace.Tracer
|
|
|
|
@ -66,6 +68,17 @@ func main() {
|
|
|
|
|
log.Logger = log.Logger.Hook(correlation.TraceContextHook{})
|
|
|
|
|
zerolog.DurationFieldUnit = time.Millisecond
|
|
|
|
|
|
|
|
|
|
if *cpuProfile != "" && os.Getenv("ENV") != "production" {
|
|
|
|
|
log.Info().Str("file", *cpuProfile).Msg("starting profiler")
|
|
|
|
|
|
|
|
|
|
f, err := os.Create(*cpuProfile)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Fatal().Err(err).Msg("failed to create cpu profile output file")
|
|
|
|
|
}
|
|
|
|
|
_ = pprof.StartCPUProfile(f)
|
|
|
|
|
defer pprof.StopCPUProfile()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
|
if err := serve(":8080"); err != nil {
|
|
|
|
|
log.Error().Err(err).Msg("failed to serve requests")
|
|
|
|
@ -86,7 +99,7 @@ func main() {
|
|
|
|
|
log.Fatal().Err(err).Msg("failed to open database")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
store, err = themis.NewStore(db, *zerolog.DefaultContextLogger)
|
|
|
|
|
store, err = themis.NewStore(db, log.Logger)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Fatal().Err(err).Msg("failed to initialize database")
|
|
|
|
|
}
|
|
|
|
@ -328,6 +341,7 @@ func main() {
|
|
|
|
|
"claim": func(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) error {
|
|
|
|
|
if i.Type == discordgo.InteractionApplicationCommandAutocomplete {
|
|
|
|
|
log.Debug().Ctx(ctx).Msg("command type interaction autocomplete")
|
|
|
|
|
// TODO(wperron) fix this
|
|
|
|
|
handleClaimAutocomplete(ctx, store, s, i)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
@ -337,6 +351,7 @@ func main() {
|
|
|
|
|
err = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
|
|
|
Data: &discordgo.InteractionResponseData{
|
|
|
|
|
Flags: discordgo.MessageFlagsEphemeral,
|
|
|
|
|
Content: "`claim-type` and `name` are mandatory parameters",
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
@ -351,6 +366,7 @@ func main() {
|
|
|
|
|
err = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
|
|
|
Data: &discordgo.InteractionResponseData{
|
|
|
|
|
Flags: discordgo.MessageFlagsEphemeral,
|
|
|
|
|
Content: "You can only take claims of types `area`, `region` or `trade`",
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
@ -370,6 +386,7 @@ func main() {
|
|
|
|
|
|
|
|
|
|
_, err = store.Claim(ctx, userId, player, name, claimType)
|
|
|
|
|
if err != nil {
|
|
|
|
|
// TODO(wperron) fix this error cast
|
|
|
|
|
conflict, ok := err.(themis.ErrConflict)
|
|
|
|
|
if ok {
|
|
|
|
|
sb := strings.Builder{}
|
|
|
|
@ -382,6 +399,7 @@ func main() {
|
|
|
|
|
err = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
|
|
|
Data: &discordgo.InteractionResponseData{
|
|
|
|
|
Flags: discordgo.MessageFlagsEphemeral,
|
|
|
|
|
Content: sb.String(),
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
@ -394,6 +412,7 @@ func main() {
|
|
|
|
|
err = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
|
|
|
Data: &discordgo.InteractionResponseData{
|
|
|
|
|
Flags: discordgo.MessageFlagsEphemeral,
|
|
|
|
|
Content: "failed to acquire claim :(",
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
@ -433,7 +452,7 @@ func main() {
|
|
|
|
|
sb := strings.Builder{}
|
|
|
|
|
sb.WriteString(fmt.Sprintf("#%d %s %s (%s)\n", detail.ID, detail.Name, detail.Type, detail.Player))
|
|
|
|
|
for _, p := range detail.Provinces {
|
|
|
|
|
sb.WriteString(fmt.Sprintf(" - %s\n", p))
|
|
|
|
|
sb.WriteString(fmt.Sprintf("- %s\n", p))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
@ -452,7 +471,7 @@ func main() {
|
|
|
|
|
userId := i.Member.User.ID
|
|
|
|
|
err := store.DeleteClaim(ctx, int(id.IntValue()), userId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
msg := "Oops, something went wrong :( blame @wperron"
|
|
|
|
|
msg := "Oops, something went wrong :( blame <@wperron>"
|
|
|
|
|
if errors.Is(err, themis.ErrNoSuchClaim) {
|
|
|
|
|
msg = fmt.Sprintf("Claim #%d not found for %s", id.IntValue(), i.Member.Nick)
|
|
|
|
|
}
|
|
|
|
@ -472,6 +491,7 @@ func main() {
|
|
|
|
|
err = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
|
|
|
Data: &discordgo.InteractionResponseData{
|
|
|
|
|
Flags: discordgo.MessageFlagsEphemeral,
|
|
|
|
|
Content: "Got it chief.",
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
@ -610,6 +630,7 @@ func main() {
|
|
|
|
|
if err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
|
|
|
Data: &discordgo.InteractionResponseData{
|
|
|
|
|
Flags: discordgo.MessageFlagsEphemeral,
|
|
|
|
|
Content: "Done.",
|
|
|
|
|
},
|
|
|
|
|
}); err != nil {
|
|
|
|
@ -631,6 +652,7 @@ func main() {
|
|
|
|
|
if err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
|
|
|
Data: &discordgo.InteractionResponseData{
|
|
|
|
|
Flags: discordgo.MessageFlagsEphemeral,
|
|
|
|
|
Content: "failed to parse provided date, make sure to use the YYYY-MM-DD format.",
|
|
|
|
|
},
|
|
|
|
|
}); err != nil {
|
|
|
|
@ -643,6 +665,7 @@ func main() {
|
|
|
|
|
if err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
|
|
|
Data: &discordgo.InteractionResponseData{
|
|
|
|
|
Flags: discordgo.MessageFlagsEphemeral,
|
|
|
|
|
Content: "The date must be some time in the future.",
|
|
|
|
|
},
|
|
|
|
|
}); err != nil {
|
|
|
|
@ -655,6 +678,7 @@ func main() {
|
|
|
|
|
if err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
|
|
|
Data: &discordgo.InteractionResponseData{
|
|
|
|
|
Flags: discordgo.MessageFlagsEphemeral,
|
|
|
|
|
Content: "The date you provided is not a Monday.",
|
|
|
|
|
},
|
|
|
|
|
}); err != nil {
|
|
|
|
@ -680,6 +704,7 @@ func main() {
|
|
|
|
|
err = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
|
|
|
Data: &discordgo.InteractionResponseData{
|
|
|
|
|
Flags: discordgo.MessageFlagsEphemeral,
|
|
|
|
|
Content: "Okey dokey.",
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
@ -752,7 +777,7 @@ func main() {
|
|
|
|
|
|
|
|
|
|
<-ctx.Done()
|
|
|
|
|
log.Info().Msg("context cancelled, exiting")
|
|
|
|
|
os.Exit(0)
|
|
|
|
|
store.Close()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func touchDbFile(path string) error {
|
|
|
|
|