switched to steam-api for player profile information

This commit is contained in:
2021-10-16 01:33:57 +02:00
parent 3787c59b9e
commit af2523a78a
12 changed files with 388 additions and 116 deletions

View File

@@ -42,6 +42,7 @@ var (
{Name: "steam_updated", Type: field.TypeTime},
{Name: "sharecode_updated", Type: field.TypeTime, Nullable: true},
{Name: "auth_code", Type: field.TypeString, Nullable: true},
{Name: "profile_created", Type: field.TypeTime, Nullable: true},
}
// PlayersTable holds the schema information for the "players" table.
PlayersTable = &schema.Table{

View File

@@ -1320,6 +1320,7 @@ type PlayerMutation struct {
steam_updated *time.Time
sharecode_updated *time.Time
auth_code *string
profile_created *time.Time
clearedFields map[string]struct{}
stats map[int]struct{}
removedstats map[int]struct{}
@@ -1902,6 +1903,55 @@ func (m *PlayerMutation) ResetAuthCode() {
delete(m.clearedFields, player.FieldAuthCode)
}
// SetProfileCreated sets the "profile_created" field.
func (m *PlayerMutation) SetProfileCreated(t time.Time) {
m.profile_created = &t
}
// ProfileCreated returns the value of the "profile_created" field in the mutation.
func (m *PlayerMutation) ProfileCreated() (r time.Time, exists bool) {
v := m.profile_created
if v == nil {
return
}
return *v, true
}
// OldProfileCreated returns the old "profile_created" field's value of the Player entity.
// If the Player object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *PlayerMutation) OldProfileCreated(ctx context.Context) (v time.Time, err error) {
if !m.op.Is(OpUpdateOne) {
return v, fmt.Errorf("OldProfileCreated is only allowed on UpdateOne operations")
}
if m.id == nil || m.oldValue == nil {
return v, fmt.Errorf("OldProfileCreated requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
return v, fmt.Errorf("querying old value for OldProfileCreated: %w", err)
}
return oldValue.ProfileCreated, nil
}
// ClearProfileCreated clears the value of the "profile_created" field.
func (m *PlayerMutation) ClearProfileCreated() {
m.profile_created = nil
m.clearedFields[player.FieldProfileCreated] = struct{}{}
}
// ProfileCreatedCleared returns if the "profile_created" field was cleared in this mutation.
func (m *PlayerMutation) ProfileCreatedCleared() bool {
_, ok := m.clearedFields[player.FieldProfileCreated]
return ok
}
// ResetProfileCreated resets all changes to the "profile_created" field.
func (m *PlayerMutation) ResetProfileCreated() {
m.profile_created = nil
delete(m.clearedFields, player.FieldProfileCreated)
}
// AddStatIDs adds the "stats" edge to the Stats entity by ids.
func (m *PlayerMutation) AddStatIDs(ids ...int) {
if m.stats == nil {
@@ -2029,7 +2079,7 @@ func (m *PlayerMutation) Type() string {
// order to get all numeric fields that were incremented/decremented, call
// AddedFields().
func (m *PlayerMutation) Fields() []string {
fields := make([]string, 0, 10)
fields := make([]string, 0, 11)
if m.name != nil {
fields = append(fields, player.FieldName)
}
@@ -2060,6 +2110,9 @@ func (m *PlayerMutation) Fields() []string {
if m.auth_code != nil {
fields = append(fields, player.FieldAuthCode)
}
if m.profile_created != nil {
fields = append(fields, player.FieldProfileCreated)
}
return fields
}
@@ -2088,6 +2141,8 @@ func (m *PlayerMutation) Field(name string) (ent.Value, bool) {
return m.SharecodeUpdated()
case player.FieldAuthCode:
return m.AuthCode()
case player.FieldProfileCreated:
return m.ProfileCreated()
}
return nil, false
}
@@ -2117,6 +2172,8 @@ func (m *PlayerMutation) OldField(ctx context.Context, name string) (ent.Value,
return m.OldSharecodeUpdated(ctx)
case player.FieldAuthCode:
return m.OldAuthCode(ctx)
case player.FieldProfileCreated:
return m.OldProfileCreated(ctx)
}
return nil, fmt.Errorf("unknown Player field %s", name)
}
@@ -2196,6 +2253,13 @@ func (m *PlayerMutation) SetField(name string, value ent.Value) error {
}
m.SetAuthCode(v)
return nil
case player.FieldProfileCreated:
v, ok := value.(time.Time)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.SetProfileCreated(v)
return nil
}
return fmt.Errorf("unknown Player field %s", name)
}
@@ -2265,6 +2329,9 @@ func (m *PlayerMutation) ClearedFields() []string {
if m.FieldCleared(player.FieldAuthCode) {
fields = append(fields, player.FieldAuthCode)
}
if m.FieldCleared(player.FieldProfileCreated) {
fields = append(fields, player.FieldProfileCreated)
}
return fields
}
@@ -2303,6 +2370,9 @@ func (m *PlayerMutation) ClearField(name string) error {
case player.FieldAuthCode:
m.ClearAuthCode()
return nil
case player.FieldProfileCreated:
m.ClearProfileCreated()
return nil
}
return fmt.Errorf("unknown Player nullable field %s", name)
}
@@ -2341,6 +2411,9 @@ func (m *PlayerMutation) ResetField(name string) error {
case player.FieldAuthCode:
m.ResetAuthCode()
return nil
case player.FieldProfileCreated:
m.ResetProfileCreated()
return nil
}
return fmt.Errorf("unknown Player field %s", name)
}

View File

@@ -36,6 +36,8 @@ type Player struct {
SharecodeUpdated time.Time `json:"-"`
// AuthCode holds the value of the "auth_code" field.
AuthCode string `json:"-"`
// ProfileCreated holds the value of the "profile_created" field.
ProfileCreated time.Time `json:"profile_created,omitempty"`
// Edges holds the relations/edges for other nodes in the graph.
// The values are being populated by the PlayerQuery when eager-loading is set.
Edges PlayerEdges `json:"edges"`
@@ -81,7 +83,7 @@ func (*Player) scanValues(columns []string) ([]interface{}, error) {
values[i] = new(sql.NullInt64)
case player.FieldName, player.FieldAvatarURL, player.FieldVanityURL, player.FieldVanityURLReal, player.FieldAuthCode:
values[i] = new(sql.NullString)
case player.FieldVacDate, player.FieldSteamUpdated, player.FieldSharecodeUpdated:
case player.FieldVacDate, player.FieldSteamUpdated, player.FieldSharecodeUpdated, player.FieldProfileCreated:
values[i] = new(sql.NullTime)
default:
return nil, fmt.Errorf("unexpected column %q for type Player", columns[i])
@@ -164,6 +166,12 @@ func (pl *Player) assignValues(columns []string, values []interface{}) error {
} else if value.Valid {
pl.AuthCode = value.String
}
case player.FieldProfileCreated:
if value, ok := values[i].(*sql.NullTime); !ok {
return fmt.Errorf("unexpected type %T for field profile_created", values[i])
} else if value.Valid {
pl.ProfileCreated = value.Time
}
}
}
return nil
@@ -221,6 +229,8 @@ func (pl *Player) String() string {
builder.WriteString(", sharecode_updated=")
builder.WriteString(pl.SharecodeUpdated.Format(time.ANSIC))
builder.WriteString(", auth_code=<sensitive>")
builder.WriteString(", profile_created=")
builder.WriteString(pl.ProfileCreated.Format(time.ANSIC))
builder.WriteByte(')')
return builder.String()
}

View File

@@ -31,6 +31,8 @@ const (
FieldSharecodeUpdated = "sharecode_updated"
// FieldAuthCode holds the string denoting the auth_code field in the database.
FieldAuthCode = "auth_code"
// FieldProfileCreated holds the string denoting the profile_created field in the database.
FieldProfileCreated = "profile_created"
// EdgeStats holds the string denoting the stats edge name in mutations.
EdgeStats = "stats"
// EdgeMatches holds the string denoting the matches edge name in mutations.
@@ -64,6 +66,7 @@ var Columns = []string{
FieldSteamUpdated,
FieldSharecodeUpdated,
FieldAuthCode,
FieldProfileCreated,
}
var (

View File

@@ -163,6 +163,13 @@ func AuthCode(v string) predicate.Player {
})
}
// ProfileCreated applies equality check predicate on the "profile_created" field. It's identical to ProfileCreatedEQ.
func ProfileCreated(v time.Time) predicate.Player {
return predicate.Player(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldProfileCreated), v))
})
}
// NameEQ applies the EQ predicate on the "name" field.
func NameEQ(v string) predicate.Player {
return predicate.Player(func(s *sql.Selector) {
@@ -1148,6 +1155,96 @@ func AuthCodeContainsFold(v string) predicate.Player {
})
}
// ProfileCreatedEQ applies the EQ predicate on the "profile_created" field.
func ProfileCreatedEQ(v time.Time) predicate.Player {
return predicate.Player(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldProfileCreated), v))
})
}
// ProfileCreatedNEQ applies the NEQ predicate on the "profile_created" field.
func ProfileCreatedNEQ(v time.Time) predicate.Player {
return predicate.Player(func(s *sql.Selector) {
s.Where(sql.NEQ(s.C(FieldProfileCreated), v))
})
}
// ProfileCreatedIn applies the In predicate on the "profile_created" field.
func ProfileCreatedIn(vs ...time.Time) predicate.Player {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Player(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.In(s.C(FieldProfileCreated), v...))
})
}
// ProfileCreatedNotIn applies the NotIn predicate on the "profile_created" field.
func ProfileCreatedNotIn(vs ...time.Time) predicate.Player {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Player(func(s *sql.Selector) {
// if not arguments were provided, append the FALSE constants,
// since we can't apply "IN ()". This will make this predicate falsy.
if len(v) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.NotIn(s.C(FieldProfileCreated), v...))
})
}
// ProfileCreatedGT applies the GT predicate on the "profile_created" field.
func ProfileCreatedGT(v time.Time) predicate.Player {
return predicate.Player(func(s *sql.Selector) {
s.Where(sql.GT(s.C(FieldProfileCreated), v))
})
}
// ProfileCreatedGTE applies the GTE predicate on the "profile_created" field.
func ProfileCreatedGTE(v time.Time) predicate.Player {
return predicate.Player(func(s *sql.Selector) {
s.Where(sql.GTE(s.C(FieldProfileCreated), v))
})
}
// ProfileCreatedLT applies the LT predicate on the "profile_created" field.
func ProfileCreatedLT(v time.Time) predicate.Player {
return predicate.Player(func(s *sql.Selector) {
s.Where(sql.LT(s.C(FieldProfileCreated), v))
})
}
// ProfileCreatedLTE applies the LTE predicate on the "profile_created" field.
func ProfileCreatedLTE(v time.Time) predicate.Player {
return predicate.Player(func(s *sql.Selector) {
s.Where(sql.LTE(s.C(FieldProfileCreated), v))
})
}
// ProfileCreatedIsNil applies the IsNil predicate on the "profile_created" field.
func ProfileCreatedIsNil() predicate.Player {
return predicate.Player(func(s *sql.Selector) {
s.Where(sql.IsNull(s.C(FieldProfileCreated)))
})
}
// ProfileCreatedNotNil applies the NotNil predicate on the "profile_created" field.
func ProfileCreatedNotNil() predicate.Player {
return predicate.Player(func(s *sql.Selector) {
s.Where(sql.NotNull(s.C(FieldProfileCreated)))
})
}
// HasStats applies the HasEdge predicate on the "stats" edge.
func HasStats() predicate.Player {
return predicate.Player(func(s *sql.Selector) {

View File

@@ -162,6 +162,20 @@ func (pc *PlayerCreate) SetNillableAuthCode(s *string) *PlayerCreate {
return pc
}
// SetProfileCreated sets the "profile_created" field.
func (pc *PlayerCreate) SetProfileCreated(t time.Time) *PlayerCreate {
pc.mutation.SetProfileCreated(t)
return pc
}
// SetNillableProfileCreated sets the "profile_created" field if the given value is not nil.
func (pc *PlayerCreate) SetNillableProfileCreated(t *time.Time) *PlayerCreate {
if t != nil {
pc.SetProfileCreated(*t)
}
return pc
}
// SetID sets the "id" field.
func (pc *PlayerCreate) SetID(u uint64) *PlayerCreate {
pc.mutation.SetID(u)
@@ -400,6 +414,14 @@ func (pc *PlayerCreate) createSpec() (*Player, *sqlgraph.CreateSpec) {
})
_node.AuthCode = value
}
if value, ok := pc.mutation.ProfileCreated(); ok {
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: player.FieldProfileCreated,
})
_node.ProfileCreated = value
}
if nodes := pc.mutation.StatsIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,

View File

@@ -224,6 +224,26 @@ func (pu *PlayerUpdate) ClearAuthCode() *PlayerUpdate {
return pu
}
// SetProfileCreated sets the "profile_created" field.
func (pu *PlayerUpdate) SetProfileCreated(t time.Time) *PlayerUpdate {
pu.mutation.SetProfileCreated(t)
return pu
}
// SetNillableProfileCreated sets the "profile_created" field if the given value is not nil.
func (pu *PlayerUpdate) SetNillableProfileCreated(t *time.Time) *PlayerUpdate {
if t != nil {
pu.SetProfileCreated(*t)
}
return pu
}
// ClearProfileCreated clears the value of the "profile_created" field.
func (pu *PlayerUpdate) ClearProfileCreated() *PlayerUpdate {
pu.mutation.ClearProfileCreated()
return pu
}
// AddStatIDs adds the "stats" edge to the Stats entity by IDs.
func (pu *PlayerUpdate) AddStatIDs(ids ...int) *PlayerUpdate {
pu.mutation.AddStatIDs(ids...)
@@ -498,6 +518,19 @@ func (pu *PlayerUpdate) sqlSave(ctx context.Context) (n int, err error) {
Column: player.FieldAuthCode,
})
}
if value, ok := pu.mutation.ProfileCreated(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: player.FieldProfileCreated,
})
}
if pu.mutation.ProfileCreatedCleared() {
_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Column: player.FieldProfileCreated,
})
}
if pu.mutation.StatsCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
@@ -820,6 +853,26 @@ func (puo *PlayerUpdateOne) ClearAuthCode() *PlayerUpdateOne {
return puo
}
// SetProfileCreated sets the "profile_created" field.
func (puo *PlayerUpdateOne) SetProfileCreated(t time.Time) *PlayerUpdateOne {
puo.mutation.SetProfileCreated(t)
return puo
}
// SetNillableProfileCreated sets the "profile_created" field if the given value is not nil.
func (puo *PlayerUpdateOne) SetNillableProfileCreated(t *time.Time) *PlayerUpdateOne {
if t != nil {
puo.SetProfileCreated(*t)
}
return puo
}
// ClearProfileCreated clears the value of the "profile_created" field.
func (puo *PlayerUpdateOne) ClearProfileCreated() *PlayerUpdateOne {
puo.mutation.ClearProfileCreated()
return puo
}
// AddStatIDs adds the "stats" edge to the Stats entity by IDs.
func (puo *PlayerUpdateOne) AddStatIDs(ids ...int) *PlayerUpdateOne {
puo.mutation.AddStatIDs(ids...)
@@ -1118,6 +1171,19 @@ func (puo *PlayerUpdateOne) sqlSave(ctx context.Context) (_node *Player, err err
Column: player.FieldAuthCode,
})
}
if value, ok := puo.mutation.ProfileCreated(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: value,
Column: player.FieldProfileCreated,
})
}
if puo.mutation.ProfileCreatedCleared() {
_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Column: player.FieldProfileCreated,
})
}
if puo.mutation.StatsCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,

View File

@@ -28,6 +28,7 @@ func (Player) Fields() []ent.Field {
}).StructTag(`json:"-"`),
field.Time("sharecode_updated").Optional().StructTag(`json:"-"`),
field.String("auth_code").Optional().Sensitive(),
field.Time("profile_created").Optional(),
}
}

1
go.mod
View File

@@ -10,6 +10,7 @@ require (
github.com/go-redis/redis/v8 v8.11.4
github.com/gorilla/handlers v1.5.1
github.com/gorilla/mux v1.8.0
github.com/lib/pq v1.10.2
github.com/markus-wa/demoinfocs-golang/v2 v2.10.1
github.com/mattn/go-sqlite3 v1.14.8
github.com/sirupsen/logrus v1.8.1

6
go.sum
View File

@@ -66,7 +66,6 @@ github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU=
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
@@ -94,7 +93,6 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o=
github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
@@ -246,6 +244,7 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
@@ -460,7 +459,6 @@ golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxT
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20210916165020-5cb4fee858ee h1:qlrAyYdKz4o7rWVUjiKqQJMa4PEpd55fqBU8jpsl4Iw=
golang.org/x/exp v0.0.0-20210916165020-5cb4fee858ee/go.mod h1:a3o/VtDNHN+dCVLEpzjjUHOzR+Ln3DHX056ZPzoZGGA=
golang.org/x/exp v0.0.0-20211012155715-ffe10e552389 h1:qFfBYVpJAdBCk6Nmd7ZbcyhGmKmv8fps+OyoOfpjvu8=
golang.org/x/exp v0.0.0-20211012155715-ffe10e552389/go.mod h1:a3o/VtDNHN+dCVLEpzjjUHOzR+Ln3DHX056ZPzoZGGA=
@@ -553,7 +551,6 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c h1:taxlMj0D/1sOAuv/CbSD+MMDof2vbyPTqz5FNYKpXt8=
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -672,7 +669,6 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

62
main.go
View File

@@ -16,6 +16,7 @@ import (
"github.com/go-redis/redis/v8"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
_ "github.com/lib/pq"
_ "github.com/mattn/go-sqlite3"
log "github.com/sirupsen/logrus"
"github.com/wercker/journalhook"
@@ -45,43 +46,6 @@ var (
journalLogFlag = flag.Bool("journal", false, "Log to systemd journal instead of stdout")
)
type PlayerResponse struct {
SteamID64 uint64 `json:"steamid64,string"`
Name string `json:"name"`
Avatar string `json:"avatar"`
VAC bool `json:"vac"`
VACDate time.Time `json:"vac_date,omitempty"`
Tracked bool `json:"tracked"`
VanityURL string `json:"vanity_url,omitempty"`
MatchStats utils.MatchStats `json:"match_stats,omitempty"`
Matches []*MatchResponse `json:"matches,omitempty"`
}
type EqResponse struct {
Victim uint64 `json:"victim"`
Type int `json:"type"`
HitGroup int `json:"hit_group"`
Dmg uint `json:"dmg"`
}
type WeaponResponse struct {
Player *PlayerResponse `json:"player"`
Eq []*EqResponse `json:"eq,omitempty"`
}
type MatchResponse struct {
MatchId uint64 `json:"match_id,string"`
ShareCode string `json:"share_code,omitempty"`
Map string `json:"map"`
Date time.Time `json:"date"`
Score [2]int `json:"score"`
Duration int `json:"duration"`
MatchResult int `json:"match_result"`
MaxRounds int `json:"max_rounds,omitempty"`
Parsed bool `json:"parsed"`
Stats interface{} `json:"stats,omitempty"`
}
func housekeeping() {
for {
if !firstHK {
@@ -100,9 +64,7 @@ func housekeeping() {
continue
}
for _, tPlayer := range tPlayerNeedSteamUpdate {
_, err = utils.UpdatePlayerFromSteam(tPlayer, conf.Steam.APIKey, db.Lock, rL)
}
_, err = utils.UpdatePlayerFromSteam(tPlayerNeedSteamUpdate, db.Client, conf.Steam.APIKey, db.Lock, rL)
// getting new sharecodes
if !demoLoader.GCReady {
@@ -171,14 +133,14 @@ func getPlayer(w http.ResponseWriter, r *http.Request) {
return
}
response := PlayerResponse{
response := utils.PlayerResponse{
SteamID64: tPlayer.ID,
Name: tPlayer.Name,
Avatar: tPlayer.AvatarURL,
VAC: tPlayer.Vac,
VanityURL: tPlayer.VanityURLReal,
Tracked: tPlayer.AuthCode != "",
Matches: []*MatchResponse{},
Matches: []*utils.MatchResponse{},
}
if !tPlayer.VacDate.IsZero() {
@@ -232,7 +194,7 @@ func getPlayer(w http.ResponseWriter, r *http.Request) {
}
for _, iMatch := range tMatches {
mResponse := &MatchResponse{
mResponse := &utils.MatchResponse{
MatchId: iMatch.ID,
Map: iMatch.Map,
Date: iMatch.Date,
@@ -386,7 +348,7 @@ func getMatchWeapons(w http.ResponseWriter, r *http.Request) {
return
}
mResponse := make([]*WeaponResponse, 0)
mResponse := make([]*utils.WeaponResponse, 0)
db.Lock.RLock()
tStats, err := db.Client.Stats.Query().Where(stats.HasMatchesWith(match.ID(matchId))).All(context.Background())
@@ -406,12 +368,12 @@ func getMatchWeapons(w http.ResponseWriter, r *http.Request) {
continue
}
mWr := &WeaponResponse{
Player: &PlayerResponse{SteamID64: stat.PlayerStats},
mWr := &utils.WeaponResponse{
Player: &utils.PlayerResponse{SteamID64: stat.PlayerStats},
}
for _, wr := range mWs {
mWr.Eq = append(mWr.Eq, &EqResponse{
mWr.Eq = append(mWr.Eq, &utils.EqResponse{
Victim: wr.Victim,
Type: wr.EqType,
HitGroup: wr.HitGroup,
@@ -453,7 +415,7 @@ func getMatch(w http.ResponseWriter, r *http.Request) {
return
}
mResponse := &MatchResponse{
mResponse := &utils.MatchResponse{
MatchId: tMatch.ID,
ShareCode: tMatch.ShareCode,
Map: tMatch.Map,
@@ -479,7 +441,7 @@ func getMatch(w http.ResponseWriter, r *http.Request) {
for _, iStats := range tStats {
sResponse := &utils.StatsResponse{
Player: PlayerResponse{
Player: utils.PlayerResponse{
SteamID64: iStats.Edges.Players.ID,
Name: iStats.Edges.Players.Name,
Avatar: iStats.Edges.Players.AvatarURL,
@@ -545,7 +507,7 @@ func getMatch(w http.ResponseWriter, r *http.Request) {
if !iStats.Edges.Players.VacDate.IsZero() {
switch s := sResponse.Player.(type) {
case PlayerResponse:
case utils.PlayerResponse:
s.VACDate = iStats.Edges.Players.VacDate
}
}

View File

@@ -7,7 +7,6 @@ import (
"csgowtfd/ent/player"
"csgowtfd/ent/stats"
"encoding/json"
"encoding/xml"
"entgo.io/ent/dialect/sql"
"fmt"
"github.com/Philipp15b/go-steamapi"
@@ -16,6 +15,7 @@ import (
"io"
"io/ioutil"
"net/http"
"path"
"regexp"
"strconv"
"strings"
@@ -150,6 +150,43 @@ type StatsResponse struct {
KAST int `json:"kast,omitempty"`
}
type PlayerResponse struct {
SteamID64 uint64 `json:"steamid64,string"`
Name string `json:"name"`
Avatar string `json:"avatar"`
VAC bool `json:"vac"`
VACDate time.Time `json:"vac_date,omitempty"`
Tracked bool `json:"tracked"`
VanityURL string `json:"vanity_url,omitempty"`
MatchStats MatchStats `json:"match_stats,omitempty"`
Matches []*MatchResponse `json:"matches,omitempty"`
}
type EqResponse struct {
Victim uint64 `json:"victim"`
Type int `json:"type"`
HitGroup int `json:"hit_group"`
Dmg uint `json:"dmg"`
}
type WeaponResponse struct {
Player *PlayerResponse `json:"player"`
Eq []*EqResponse `json:"eq,omitempty"`
}
type MatchResponse struct {
MatchId uint64 `json:"match_id,string"`
ShareCode string `json:"share_code,omitempty"`
Map string `json:"map"`
Date time.Time `json:"date"`
Score [2]int `json:"score"`
Duration int `json:"duration"`
MatchResult int `json:"match_result"`
MaxRounds int `json:"max_rounds,omitempty"`
Parsed bool `json:"parsed"`
Stats interface{} `json:"stats,omitempty"`
}
const (
steamID64Entry = "https://steamcommunity.com/profiles/%d?xml=1"
steamVanityURLEntry = "https://steamcommunity.com/id/%s?xml=1"
@@ -329,13 +366,13 @@ func GetPlayer(db *DBWithLock, id interface{}, apiKey string, rl ratelimit.Limit
return GetPlayerFromSteamID64(db, steamID64, apiKey, rl)
}
return GetPlayerFromVanityURL(db, e)
return GetPlayerFromVanityURL(db, e, apiKey, rl)
default:
return nil, fmt.Errorf("invalid arguments")
}
}
func GetPlayerFromVanityURL(db *DBWithLock, id string) (*ent.Player, error) {
func GetPlayerFromVanityURL(db *DBWithLock, id string, apiKey string, rl ratelimit.Limiter) (*ent.Player, error) {
if id == "" {
return nil, fmt.Errorf("invalid arguments")
}
@@ -346,28 +383,28 @@ func GetPlayerFromVanityURL(db *DBWithLock, id string) (*ent.Player, error) {
if err == nil {
return tPlayer, nil
} else {
profile, err := SteamProfile2XML(id, 0)
rl.Take()
resp, err := steamapi.ResolveVanityURL(id, apiKey)
if err != nil {
return nil, err
}
if profile.Error != "" {
return nil, fmt.Errorf("profile not found")
if resp.Success != 1 {
return nil, fmt.Errorf("vanity url not found")
}
db.Lock.Lock()
nPlayer, err := db.Client.Player.Create().SetID(profile.SteamID64).SetVanityURL(strings.ToLower(profile.VanityURL)).SetVac(profile.VacBanned).SetAvatarURL(profile.AvatarURL).SetName(profile.ProfileName).Save(context.Background())
db.Lock.Unlock()
nPlayer, err := GetPlayerFromSteamID64(db, resp.SteamID, apiKey, rl)
if err != nil {
return nil, err
}
return nPlayer, nil
}
}
func GetPlayerFromSteamID64(db *DBWithLock, steamID uint64, apiKey string, rl ratelimit.Limiter) (*ent.Player, error) {
db.Lock.RLock()
tPlayer, err := db.Client.Player.Query().Where(player.ID(steamID)).Only(context.Background())
tPlayer, err := db.Client.Player.Get(context.Background(), steamID)
db.Lock.RUnlock()
if err == nil {
return tPlayer, nil
@@ -379,75 +416,78 @@ func GetPlayerFromSteamID64(db *DBWithLock, steamID uint64, apiKey string, rl ra
return nil, err
}
nPlayer, err = UpdatePlayerFromSteam(nPlayer, apiKey, db.Lock, rl)
uPlayer, err := UpdatePlayerFromSteam([]*ent.Player{nPlayer}, db.Client, apiKey, db.Lock, rl)
if err != nil {
return nil, err
}
return nPlayer, nil
if len(uPlayer) > 0 {
return uPlayer[0], nil
} else {
return nil, nil
}
}
}
func SteamProfile2XML(id string, steamID64 uint64) (*CommunityXML, error) {
var r *http.Response
var err error
if steamID64 != 0 {
r, err = http.Get(fmt.Sprintf(steamID64Entry, steamID64))
} else {
r, err = http.Get(fmt.Sprintf(steamVanityURLEntry, id))
}
if err != nil {
return nil, err
}
defer func(Body io.ReadCloser) {
_ = Body.Close()
}(r.Body)
func UpdatePlayerFromSteam(players []*ent.Player, db *ent.Client, apiKey string, lock *sync.RWMutex, rl ratelimit.Limiter) ([]*ent.Player, error) {
var idsToUpdate []uint64
body, err := ioutil.ReadAll(r.Body)
if err != nil {
return nil, err
}
cXML := &CommunityXML{}
err = xml.Unmarshal(body, cXML)
if err != nil {
return nil, err
}
return cXML, nil
}
func UpdatePlayerFromSteam(player *ent.Player, apiKey string, lock *sync.RWMutex, rl ratelimit.Limiter) (*ent.Player, error) {
profile, err := SteamProfile2XML("", player.ID)
if err != nil {
return nil, err
}
if profile.Error != "" {
return nil, fmt.Errorf("profile not found")
}
lock.Lock()
tPlayer, err := player.Update().SetName(profile.ProfileName).SetVac(profile.VacBanned).SetAvatarURL(profile.AvatarURL).SetSteamUpdated(time.Now().UTC()).SetVanityURL(strings.ToLower(profile.VanityURL)).SetVanityURLReal(profile.VanityURL).SetSteamUpdated(time.Now().UTC()).Save(context.Background())
lock.Unlock()
if err != nil {
return nil, err
for _, updatePlayer := range players {
idsToUpdate = append(idsToUpdate, updatePlayer.ID)
}
rl.Take()
bans, err := steamapi.GetPlayerBans([]uint64{profile.SteamID64}, apiKey)
playerSum, err := steamapi.GetPlayerSummaries(idsToUpdate, apiKey)
if err != nil {
return nil, err
}
if len(bans) > 0 && bans[0].NumberOfVACBans > 0 {
banDate := time.Now().UTC().AddDate(0, 0, -1*int(bans[0].DaysSinceLastBan))
var nPlayers []*ent.Player
for _, pS := range playerSum {
// TODO: what happens if a player deleted their profile?
// check for vanityURL
if SteamId64RegEx.MatchString(path.Base(pS.ProfileURL)) {
pS.ProfileURL = ""
} else {
pS.ProfileURL = path.Base(pS.ProfileURL)
}
lock.Lock()
err := tPlayer.Update().SetVacCount(int(bans[0].NumberOfVACBans)).SetVacDate(banDate).Exec(context.Background())
tPlayer, err := db.Player.UpdateOneID(pS.SteamID).
SetName(pS.PersonaName).
SetAvatarURL(pS.LargeAvatarURL).
SetSteamUpdated(time.Now().UTC()).
SetVanityURL(strings.ToLower(pS.ProfileURL)).
SetVanityURLReal(pS.ProfileURL).
SetSteamUpdated(time.Now().UTC()).
SetProfileCreated(time.Unix(pS.TimeCreated, 0).UTC()).
Save(context.Background())
lock.Unlock()
if err != nil {
return nil, err
}
nPlayers = append(nPlayers, tPlayer)
}
return tPlayer, nil
rl.Take()
bans, err := steamapi.GetPlayerBans(idsToUpdate, apiKey)
if err != nil {
return nil, err
}
for _, ban := range bans {
if ban.NumberOfVACBans > 0 {
banDate := time.Now().UTC().AddDate(0, 0, -1*int(bans[0].DaysSinceLastBan))
lock.Lock()
err := db.Player.UpdateOneID(ban.SteamID).SetVacCount(int(ban.NumberOfVACBans)).SetVacDate(banDate).Exec(context.Background())
lock.Unlock()
if err != nil {
return nil, err
}
}
}
return nPlayers, nil
}