diff --git a/dataBase.go b/dataBase.go index 4fb05cb..268897b 100644 --- a/dataBase.go +++ b/dataBase.go @@ -62,7 +62,8 @@ func (db *dbLayer) execInTransaction(ctx context.Context, query string, args ... type Player struct { id string name string - lastOnline time.Time + lastLogin time.Time + lastLogout time.Time onlineDuration time.Duration deaths int level int @@ -75,18 +76,26 @@ type scannable interface { func fetchPlayer(r scannable, p *Player) error { var ( err error - lastOnline string + lastLogin string + lastLogout *string onlineDuration int ) - err = r.Scan(&p.id, &p.name, &lastOnline, &onlineDuration, &p.deaths, &p.level) + err = r.Scan(&p.id, &p.name, &lastLogin, &onlineDuration, &p.deaths, &p.level, &lastLogout) if err != nil { return errors.Wrap(err, "Failed to fetch data base") } - p.lastOnline, err = time.Parse(time.RFC3339, lastOnline) + p.lastLogin, err = time.Parse(time.RFC3339, lastLogin) if err != nil { - return errors.Wrapf(err, "Failed to parse date [%s]", lastOnline) + return errors.Wrapf(err, "Failed to parse date [%s]", lastLogin) + } + + if lastLogout != nil { + p.lastLogout, err = time.Parse(time.RFC3339, lastLogin) + if err != nil { + return errors.Wrapf(err, "Failed to parse date [%s]", lastLogout) + } } p.onlineDuration = time.Second * time.Duration(onlineDuration) @@ -97,7 +106,7 @@ func fetchPlayer(r scannable, p *Player) error { func (db *dbLayer) getPlayers(ctx context.Context) ([]Player, error) { var players []Player - query := "SELECT id, name, last_login, online_duration, deaths, level FROM players" + query := "SELECT id, name, last_login, online_duration, deaths, level, last_logout FROM players" rows, err := db.db.QueryContext(ctx, query) if err != nil { @@ -121,7 +130,7 @@ func (db *dbLayer) getPlayers(ctx context.Context) ([]Player, error) { } func (db *dbLayer) getPlayerByID(ctx context.Context, id string) (*Player, error) { - query := "SELECT id, name, last_login, online_duration, deaths, level FROM players WHERE id = $1" + query := "SELECT id, name, last_login, online_duration, deaths, level, last_logout FROM players WHERE id = $1" row := db.db.QueryRowContext(ctx, query, id) if err := row.Err(); err != nil { @@ -140,7 +149,7 @@ func (db *dbLayer) getPlayerByID(ctx context.Context, id string) (*Player, error } func (db *dbLayer) getPlayerByName(ctx context.Context, name string) (*Player, error) { - query := "SELECT id, name, last_login, online_duration, deaths, level FROM players WHERE name = $1 LIMIT 1" + query := "SELECT id, name, last_login, online_duration, deaths, level, last_logout FROM players WHERE name = $1 LIMIT 1" row := db.db.QueryRowContext(ctx, query, name) if err := row.Err(); err != nil { @@ -175,19 +184,19 @@ func (db *dbLayer) getKillsByPlayerID(ctx context.Context, playerID string) (int return killsNum, nil } -func (db *dbLayer) createPlayer(ctx context.Context, name string, lastOnline time.Time) (*Player, error) { +func (db *dbLayer) createPlayer(ctx context.Context, name string, lastLogin time.Time) (*Player, error) { id := uuid() - err := db.execInTransaction(ctx, "INSERT INTO players (id, name, last_login) VALUES ($1, $2, $3)", id, name, lastOnline.Format(time.RFC3339)) + err := db.execInTransaction(ctx, "INSERT INTO players (id, name, last_login) VALUES ($1, $2, $3)", id, name, lastLogin.Format(time.RFC3339)) if err != nil { return nil, err } return &Player{ - id: id, - name: name, - lastOnline: lastOnline, + id: id, + name: name, + lastLogin: lastLogin, }, nil } diff --git a/handlers.go b/handlers.go index 2257daa..e650db3 100644 --- a/handlers.go +++ b/handlers.go @@ -117,7 +117,7 @@ func (c *quitCommand) run(ctx context.Context) { return } - err = db.increasePlayerOnlineDuration(ctx, p.id, time.Now().Sub(p.lastOnline)) + err = db.increasePlayerOnlineDuration(ctx, p.id, time.Now().Sub(p.lastLogin)) if err != nil { log.Error(err) return diff --git a/playersBoard.go b/playersBoard.go index 2e9640a..162c09f 100644 --- a/playersBoard.go +++ b/playersBoard.go @@ -70,6 +70,7 @@ const ( emojiDeaths = "\xF0\x9F\x92\x80" emojiTime = "\xF0\x9F\x95\x90" emojiGun = "\xF0\x9F\x94\xAB" + emojiCheck = "\xE2\x9C\x85" ) func (p *playerInfo) updatePlayerInfo(ctx context.Context) error { @@ -89,9 +90,9 @@ func (p *playerInfo) updatePlayerInfo(ctx context.Context) error { return err } - access := "\xE2\x9D\x8C offLine" + access := "\x1F\x53\x04 offLine" if p.isOnline { - access = "\xE2\x9C\x85 onLine" + access = "\x1F\x7E\x02 onLine" } level := "-" @@ -111,6 +112,11 @@ func (p *playerInfo) updatePlayerInfo(ctx context.Context) error { lines = append(lines, fmt.Sprintf("%s Смертей: *%d*", emojiDeaths, player.deaths)) lines = append(lines, fmt.Sprintf("%s Фрагов: *%d*", emojiGun, kills)) lines = append(lines, fmt.Sprintf("%s Время в игре: *%s*", emojiTime, d.Format(units))) + + if !player.lastLogout.IsZero() && !p.isOnline { + lines = append(lines, fmt.Sprintf("%s Был в сети: *%s*", emojiCheck, player.lastLogout.Format("02 Jan 15:04"))) + } + lines = append(lines, "-----") emojiAch := make([]string, 0, len(p.achievements))