From cf649f18dc3097a332445ceefef9820f11fad0ad Mon Sep 17 00:00:00 2001 From: Aki Date: Wed, 19 May 2021 22:37:17 +0200 Subject: Extended content of Battle model --- derelict.go | 10 +++++-- esi.go | 56 ++++++++++++++++++++++++++++++++++ models.go | 62 +++++++++++++++++++++++++++++++++----- storage.go | 99 ++++++++++++++++++++++++++++++++++++++++++------------------- 4 files changed, 186 insertions(+), 41 deletions(-) diff --git a/derelict.go b/derelict.go index 2581d2f..569de51 100644 --- a/derelict.go +++ b/derelict.go @@ -57,9 +57,15 @@ func handleBattlesPost(w http.ResponseWriter, r *http.Request) { return } decoder := json.NewDecoder(r.Body) + var stub BattleStub + if err := decoder.Decode(&stub); err != nil { + http.Error(w, "Error reading stub", http.StatusBadRequest) + return + } var battle Battle - if err := decoder.Decode(&battle); err != nil { - http.Error(w, "Error reading battle", http.StatusBadRequest) + err = battle.From(&stub) + if err != nil { + http.Error(w, "Error getting battle details", http.StatusInternalServerError) return } err = storage.AddBattle(&battle) diff --git a/esi.go b/esi.go index 4eaa682..bd3b0fe 100644 --- a/esi.go +++ b/esi.go @@ -20,6 +20,34 @@ func GetKillmail(id int32, hash string) (EsiKillmail, error) { return details, nil } +func GetType(id int32) (EsiType, error) { + r, err := http.Get(fmt.Sprintf("https://esi.evetech.net/latest/universe/types/%d/", id)) + if err != nil { + return EsiType{}, err + } + decoder := json.NewDecoder(r.Body) + var details EsiType + if err := decoder.Decode(&details); err != nil { + return EsiType{}, err + } + + return details, nil +} + +func GetGroup(id int32) (EsiGroup, error) { + r, err := http.Get(fmt.Sprintf("https://esi.evetech.net/latest/universe/groups/%d/", id)) + if err != nil { + return EsiGroup{}, err + } + decoder := json.NewDecoder(r.Body) + var details EsiGroup + if err := decoder.Decode(&details); err != nil { + return EsiGroup{}, err + } + + return details, nil +} + func GetSolarSystem(id int32) (EsiUniverseSystem, error) { r, err := http.Get(fmt.Sprintf("https://esi.evetech.net/latest/universe/systems/%d/", id)) if err != nil { @@ -33,3 +61,31 @@ func GetSolarSystem(id int32) (EsiUniverseSystem, error) { return details, nil } + +func GetConstellation(id int32) (EsiUniverseConstellation, error) { + r, err := http.Get(fmt.Sprintf("https://esi.evetech.net/latest/universe/constellations/%d/", id)) + if err != nil { + return EsiUniverseConstellation{}, err + } + decoder := json.NewDecoder(r.Body) + var details EsiUniverseConstellation + if err := decoder.Decode(&details); err != nil { + return EsiUniverseConstellation{}, err + } + + return details, nil +} + +func GetRegion(id int32) (EsiUniverseRegion, error) { + r, err := http.Get(fmt.Sprintf("https://esi.evetech.net/latest/universe/regions/%d/", id)) + if err != nil { + return EsiUniverseRegion{}, err + } + decoder := json.NewDecoder(r.Body) + var details EsiUniverseRegion + if err := decoder.Decode(&details); err != nil { + return EsiUniverseRegion{}, err + } + + return details, nil +} diff --git a/models.go b/models.go index 7119fa9..3b369ca 100644 --- a/models.go +++ b/models.go @@ -15,29 +15,75 @@ type Killmail struct { Hash string `json:"hash"` } +type Ship struct { + Name string `json:"name"` + Group string `json:"group"` +} + +type Location struct { + Name string `json:"name"` + Security float32 `json:"security"` + Position Vector3 `json:"position"` + Constellation string `json:"constellation"` + Region string `json:"region"` +} + type Team []int32 +type BattleStub struct { + Teams []Team `json:"teams"` + Killmails []Killmail `json:"killmails"` +} + type Battle struct { - Id string `json:"-"` - LastModified time.Time `json:"-"` - StartTime time.Time `json:"started_at"` - EndTime time.Time `json:"ended_at"` - Teams [2]Team `json:"teams"` - Killmails []Killmail `json:"killmails"` - Name string `json:"name"` + Id string `json:"-"` + Name string `json:"name"` + LastModified time.Time `json:"-"` + StartTime time.Time `json:"started_at"` + EndTime time.Time `json:"ended_at"` + Killmails []EsiKillmail `json:"killmails"` // How about no? + Teams []Team `json:"teams"` + Ships map[int32]Ship `json:"ships"` + Locations map[int32]Location `json:"locations"` + Names map[int32]string `json:"names'` } type EsiKillmail struct { - SolarSystemId int32 `json:"solar_system_id"` + Id int32 `json:"killmail_id"` + Hash string `json:"hash"` + SolarSystemId int32 `json:"solar_system_id"` Victim struct { Position Vector3 `json:"position"` ShipTypeId int32 `json:"ship_type_id"` + CharacterId int32 `json:"character_id"` CorporationId int32 `json:"corporation_id"` AllianceId int32 `json:"alliance_id"` + FactionId int32 `json:"faction_id"` } `json:"victim"` Time time.Time `json:"killmail_time"` } type EsiUniverseSystem struct { + Name string `json:"name"` + ConstellationId int32 `json:"constellation_id"` + Position Vector3 `json:"position"` + Security float32 `json:"security_status"` +} + +type EsiUniverseConstellation struct { + Name string `json:"name"` + RegionId int32 `json:"region_id"` +} + +type EsiUniverseRegion struct { + Name string `json:"name"` +} + +type EsiType struct { + Name string `json:"name"` + GroupId int32 `json:"group_id"` +} + +type EsiGroup struct { Name string `json:"name"` } diff --git a/storage.go b/storage.go index ee3489a..e57e0f2 100644 --- a/storage.go +++ b/storage.go @@ -36,7 +36,7 @@ func (s *Storage) CanPost(token string) (bool, error) { return err == nil, nil } -func (b *Battle) CalculateHash() { +func (b *BattleStub) CalculateHash() string { hash := sha1.New() killmails := b.Killmails sort.Slice(killmails, func(lhs, rhs int) bool { @@ -46,7 +46,73 @@ func (b *Battle) CalculateHash() { fmt.Fprint(hash, km.Id) } sum := hash.Sum(nil) - b.Id = hex.EncodeToString(sum[:]) + return hex.EncodeToString(sum[:]) +} + +func (b *Battle) From(stub *BattleStub) error { + if len(stub.Killmails) < 1 { + return errors.New("missing killmails") + } + b.Id = stub.CalculateHash() + b.Ships = make(map[int32]Ship) + b.Locations = make(map[int32]Location) + b.Names = make(map[int32]string) + for _, km := range stub.Killmails { + details, err := GetKillmail(km.Id, km.Hash) + if err != nil { + return errors.New("could not retrieve killmail details") + } + details.Hash = km.Hash + b.Locations[details.SolarSystemId] = Location{} + b.Ships[details.Victim.ShipTypeId] = Ship{} + b.Names[details.Victim.CharacterId] = "" + b.Names[details.Victim.CorporationId] = "" + b.Names[details.Victim.AllianceId] = "" + b.Names[details.Victim.FactionId] = "" + if b.StartTime.IsZero() || b.StartTime.After(details.Time) { + b.StartTime = details.Time + } + if b.EndTime.IsZero() || b.EndTime.Before(details.Time) { + b.EndTime = details.Time + } + b.Killmails = append(b.Killmails, details) + } + b.Teams = stub.Teams + for key := range b.Ships { + t, err := GetType(key) + if err != nil { + return errors.New("could not retrieve type details") + } + g, err := GetGroup(t.GroupId) + if err != nil { + return errors.New("could not retrieve group details") + } + b.Ships[key] = Ship{Name: t.Name, Group: g.Name} + } + b.Name = "Untitled Fight" + for key := range b.Locations { + s, err := GetSolarSystem(key) + if err != nil { + return errors.New("could not retrieve solar system details") + } + c, err := GetConstellation(s.ConstellationId) + if err != nil { + return errors.New("could not retrieve constellation details") + } + r, err := GetRegion(c.RegionId) + if err != nil { + return errors.New("could not retrieve region details") + } + b.Locations[key] = Location{ + Name: s.Name, + Security: s.Security, + Position: s.Position, + Constellation: c.Name, + Region: r.Name, + } + } + // TODO: Resolve Names + return nil } func (s *Storage) LoadBattle(battle *Battle) error { @@ -63,35 +129,6 @@ func (s *Storage) LoadBattle(battle *Battle) error { } func (s *Storage) AddBattle(battle *Battle) error { - if len(battle.Killmails) < 1 { - return errors.New("missing killmails") - } - battle.CalculateHash() - killmail := battle.Killmails[0] - details, err := GetKillmail(killmail.Id, killmail.Hash) - if err != nil { - return err - } - system, err := GetSolarSystem(details.SolarSystemId) - if err != nil { - return err - } - battle.Name = fmt.Sprintf("Fight in %s", system.Name) - battle.StartTime = details.Time - battle.EndTime = details.Time - for _, km := range battle.Killmails[1:] { - details, err := GetKillmail(km.Id, km.Hash) - if err != nil { - return err - } - if battle.StartTime.After(details.Time) { - battle.StartTime = details.Time - } - if battle.EndTime.Before(details.Time) { - battle.EndTime = details.Time - } - } - data, err := json.Marshal(battle) if err != nil { return err -- cgit v1.1