Skip to content

Commit

Permalink
Merge branch 'release/47.1.6'
Browse files Browse the repository at this point in the history
  • Loading branch information
alaingilbert committed Aug 4, 2022
2 parents 3e96743 + e84dd9e commit 56e4797
Show file tree
Hide file tree
Showing 7 changed files with 2,366 additions and 1 deletion.
50 changes: 50 additions & 0 deletions extractor_v9.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package ogame

import (
"bytes"
"github.com/PuerkitoBio/goquery"
"time"
)

// ExtractorV9 ...
type ExtractorV9 struct {
ExtractorV874
}

// NewExtractorV9 ...
func NewExtractorV9() *ExtractorV9 {
return &ExtractorV9{}
}

// ExtractEspionageReport ...
func (e ExtractorV9) ExtractEspionageReport(pageHTML []byte, location *time.Location) (EspionageReport, error) {
doc, _ := goquery.NewDocumentFromReader(bytes.NewReader(pageHTML))
return e.ExtractEspionageReportFromDoc(doc, location)
}

// ExtractEspionageReportFromDoc ...
func (e ExtractorV9) ExtractEspionageReportFromDoc(doc *goquery.Document, location *time.Location) (EspionageReport, error) {
return extractEspionageReportFromDocV9(doc, location)
}

// ExtractResources ...
func (e ExtractorV9) ExtractResources(pageHTML []byte) Resources {
doc, _ := goquery.NewDocumentFromReader(bytes.NewReader(pageHTML))
return e.ExtractResourcesFromDoc(doc)
}

// ExtractResourcesFromDoc ...
func (e ExtractorV9) ExtractResourcesFromDoc(doc *goquery.Document) Resources {
return extractResourcesFromDocV9(doc)
}

// ExtractResourcesDetailsFromFullPage ...
func (e ExtractorV9) ExtractResourcesDetailsFromFullPage(pageHTML []byte) ResourcesDetails {
doc, _ := goquery.NewDocumentFromReader(bytes.NewReader(pageHTML))
return e.ExtractResourcesDetailsFromFullPageFromDoc(doc)
}

// ExtractResourcesDetailsFromFullPageFromDoc ...
func (e ExtractorV9) ExtractResourcesDetailsFromFullPageFromDoc(doc *goquery.Document) ResourcesDetails {
return extractResourcesDetailsFromFullPageFromDocV9(doc)
}
348 changes: 348 additions & 0 deletions extracts_v9.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,348 @@
package ogame

import (
"errors"
"github.com/PuerkitoBio/goquery"
"regexp"
"strconv"
"strings"
"time"
)

func extractResourcesFromDocV9(doc *goquery.Document) Resources {
res := Resources{}
metalDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(doc.Find("div#metal_box").AttrOr("title", "")))
crystalDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(doc.Find("div#crystal_box").AttrOr("title", "")))
deuteriumDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(doc.Find("div#deuterium_box").AttrOr("title", "")))
energyDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(doc.Find("div#energy_box").AttrOr("title", "")))
darkmatterDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(doc.Find("div#darkmatter_box").AttrOr("title", "")))
res.Metal = ParseInt(metalDoc.Find("table tr").Eq(0).Find("td").Eq(0).Text())
res.Crystal = ParseInt(crystalDoc.Find("table tr").Eq(0).Find("td").Eq(0).Text())
res.Deuterium = ParseInt(deuteriumDoc.Find("table tr").Eq(0).Find("td").Eq(0).Text())
res.Energy = ParseInt(energyDoc.Find("table tr").Eq(0).Find("td").Eq(0).Text())
res.Darkmatter = ParseInt(darkmatterDoc.Find("table tr").Eq(0).Find("td").Eq(0).Text())
return res
}

func extractResourcesDetailsFromFullPageFromDocV9(doc *goquery.Document) ResourcesDetails {
out := ResourcesDetails{}
out.Metal.Available = ParseInt(strings.Split(doc.Find("span#resources_metal").AttrOr("data-raw", "0"), ".")[0])
out.Crystal.Available = ParseInt(strings.Split(doc.Find("span#resources_crystal").AttrOr("data-raw", "0"), ".")[0])
out.Deuterium.Available = ParseInt(strings.Split(doc.Find("span#resources_deuterium").AttrOr("data-raw", "0"), ".")[0])
out.Energy.Available = ParseInt(doc.Find("span#resources_energy").Text())
out.Darkmatter.Available = ParseInt(doc.Find("span#resources_darkmatter").Text())
metalDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(doc.Find("div#metal_box").AttrOr("title", "")))
crystalDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(doc.Find("div#crystal_box").AttrOr("title", "")))
deuteriumDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(doc.Find("div#deuterium_box").AttrOr("title", "")))
energyDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(doc.Find("div#energy_box").AttrOr("title", "")))
darkmatterDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(doc.Find("div#darkmatter_box").AttrOr("title", "")))
out.Metal.StorageCapacity = ParseInt(metalDoc.Find("table tr").Eq(1).Find("td").Eq(0).Text())
out.Metal.CurrentProduction = ParseInt(metalDoc.Find("table tr").Eq(2).Find("td").Eq(0).Text())
out.Crystal.StorageCapacity = ParseInt(crystalDoc.Find("table tr").Eq(1).Find("td").Eq(0).Text())
out.Crystal.CurrentProduction = ParseInt(crystalDoc.Find("table tr").Eq(2).Find("td").Eq(0).Text())
out.Deuterium.StorageCapacity = ParseInt(deuteriumDoc.Find("table tr").Eq(1).Find("td").Eq(0).Text())
out.Deuterium.CurrentProduction = ParseInt(deuteriumDoc.Find("table tr").Eq(2).Find("td").Eq(0).Text())
out.Energy.CurrentProduction = ParseInt(energyDoc.Find("table tr").Eq(1).Find("td").Eq(0).Text())
out.Energy.Consumption = ParseInt(energyDoc.Find("table tr").Eq(2).Find("td").Eq(0).Text())
out.Darkmatter.Purchased = ParseInt(darkmatterDoc.Find("table tr").Eq(1).Find("td").Eq(0).Text())
out.Darkmatter.Found = ParseInt(darkmatterDoc.Find("table tr").Eq(2).Find("td").Eq(0).Text())
return out
}

func extractEspionageReportFromDocV9(doc *goquery.Document, location *time.Location) (EspionageReport, error) {
report := EspionageReport{}
report.ID, _ = strconv.ParseInt(doc.Find("div.detail_msg").AttrOr("data-msg-id", "0"), 10, 64)
spanLink := doc.Find("span.msg_title a").First()
txt := spanLink.Text()
figure := spanLink.Find("figure").First()
r := regexp.MustCompile(`([^\[]+) \[(\d+):(\d+):(\d+)]`)
m := r.FindStringSubmatch(txt)
if len(m) == 5 {
report.Coordinate.Galaxy, _ = strconv.ParseInt(m[2], 10, 64)
report.Coordinate.System, _ = strconv.ParseInt(m[3], 10, 64)
report.Coordinate.Position, _ = strconv.ParseInt(m[4], 10, 64)
} else {
return report, errors.New("failed to extract coordinate")
}
if figure.HasClass("planet") {
report.Coordinate.Type = PlanetType
} else if figure.HasClass("moon") {
report.Coordinate.Type = MoonType
}
messageType := Report
if doc.Find("span.espionageDefText").Size() > 0 {
messageType = Action
}
report.Type = messageType
msgDateRaw := doc.Find("span.msg_date").Text()
msgDate, _ := time.ParseInLocation("02.01.2006 15:04:05", msgDateRaw, location)
report.Date = msgDate.In(time.Local)

username := doc.Find("div.detail_txt").First().Find("span span").First().Text()
username = strings.TrimSpace(username)
split := strings.Split(username, "(i")
if len(split) > 0 {
report.Username = strings.TrimSpace(split[0])
}
characterClassStr := doc.Find("div.detail_txt").Eq(1).Find("span span").First().Text()
characterClassStr = strings.TrimSpace(characterClassStr)
report.CharacterClass = getCharacterClass(characterClassStr)

report.AllianceClass = NoAllianceClass
allianceClassSpan := doc.Find("div.detail_txt").Eq(2).Find("span.alliance_class")
if allianceClassSpan.HasClass("trader") {
report.AllianceClass = Trader
} else if allianceClassSpan.HasClass("warrior") {
report.AllianceClass = Warrior
} else if allianceClassSpan.HasClass("researcher") {
report.AllianceClass = Researcher
}

// Bandit, Starlord
banditstarlord := doc.Find("div.detail_txt").First().Find("span")
if banditstarlord.HasClass("honorRank") {
report.IsBandit = banditstarlord.HasClass("rank_bandit1") || banditstarlord.HasClass("rank_bandit2") || banditstarlord.HasClass("rank_bandit3")
report.IsStarlord = banditstarlord.HasClass("rank_starlord1") || banditstarlord.HasClass("rank_starlord2") || banditstarlord.HasClass("rank_starlord3")
}

honorableFound := doc.Find("div.detail_txt").First().Find("span.status_abbr_honorableTarget")
report.HonorableTarget = honorableFound.Length() > 0

// IsInactive, IsLongInactive
inactive := doc.Find("div.detail_txt").First().Find("span")
if inactive.HasClass("status_abbr_longinactive") {
report.IsInactive = true
report.IsLongInactive = true
} else if inactive.HasClass("status_abbr_inactive") {
report.IsInactive = true
}

// APIKey
apikey, _ := doc.Find("span.icon_apikey").Attr("title")
apiDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(apikey))
report.APIKey = apiDoc.Find("input").First().AttrOr("value", "")

// Inactivity timer
activity := doc.Find("div.detail_txt").Eq(3).Find("font")
if len(activity.Text()) == 2 {
report.LastActivity = ParseInt(activity.Text())
}

// CounterEspionage
ceTxt := doc.Find("div.detail_txt").Eq(2).Text()
m1 := regexp.MustCompile(`(\d+)%`).FindStringSubmatch(ceTxt)
if len(m1) == 2 {
report.CounterEspionage, _ = strconv.ParseInt(m1[1], 10, 64)
}

hasError := false
resourcesFound := false
buildingsFound := false
doc.Find("ul.detail_list").Each(func(i int, s *goquery.Selection) {
dataType := s.AttrOr("data-type", "")
if dataType == "resources" && !resourcesFound {
resourcesFound = true
report.Metal = ParseInt(s.Find("li").Eq(0).AttrOr("title", "0"))
report.Crystal = ParseInt(s.Find("li").Eq(1).AttrOr("title", "0"))
report.Deuterium = ParseInt(s.Find("li").Eq(2).AttrOr("title", "0"))
report.Energy = ParseInt(s.Find("li").Eq(3).AttrOr("title", "0"))
} else if dataType == "buildings" && !buildingsFound {
buildingsFound = true
report.HasBuildingsInformation = s.Find("li.detail_list_fail").Size() == 0
s.Find("li.detail_list_el").EachWithBreak(func(i int, s2 *goquery.Selection) bool {
img := s2.Find("img")
if img.Size() == 0 {
hasError = true
return false
}
imgClass := img.AttrOr("class", "")
r := regexp.MustCompile(`building(\d+)`)
buildingID, _ := strconv.ParseInt(r.FindStringSubmatch(imgClass)[1], 10, 64)
l := ParseInt(s2.Find("span.fright").Text())
level := &l
switch ID(buildingID) {
case MetalMine.ID:
report.MetalMine = level
case CrystalMine.ID:
report.CrystalMine = level
case DeuteriumSynthesizer.ID:
report.DeuteriumSynthesizer = level
case SolarPlant.ID:
report.SolarPlant = level
case FusionReactor.ID:
report.FusionReactor = level
case MetalStorage.ID:
report.MetalStorage = level
case CrystalStorage.ID:
report.CrystalStorage = level
case DeuteriumTank.ID:
report.DeuteriumTank = level
case AllianceDepot.ID:
report.AllianceDepot = level
case RoboticsFactory.ID:
report.RoboticsFactory = level
case Shipyard.ID:
report.Shipyard = level
case ResearchLab.ID:
report.ResearchLab = level
case MissileSilo.ID:
report.MissileSilo = level
case NaniteFactory.ID:
report.NaniteFactory = level
case Terraformer.ID:
report.Terraformer = level
case SpaceDock.ID:
report.SpaceDock = level
case LunarBase.ID:
report.LunarBase = level
case SensorPhalanx.ID:
report.SensorPhalanx = level
case JumpGate.ID:
report.JumpGate = level
}
return true
})
} else if dataType == "research" {
report.HasResearchesInformation = s.Find("li.detail_list_fail").Size() == 0
s.Find("li.detail_list_el").EachWithBreak(func(i int, s2 *goquery.Selection) bool {
img := s2.Find("img")
if img.Size() == 0 {
hasError = true
return false
}
imgClass := img.AttrOr("class", "")
r := regexp.MustCompile(`research(\d+)`)
researchID, _ := strconv.ParseInt(r.FindStringSubmatch(imgClass)[1], 10, 64)
l := ParseInt(s2.Find("span.fright").Text())
level := &l
switch ID(researchID) {
case EspionageTechnology.ID:
report.EspionageTechnology = level
case ComputerTechnology.ID:
report.ComputerTechnology = level
case WeaponsTechnology.ID:
report.WeaponsTechnology = level
case ShieldingTechnology.ID:
report.ShieldingTechnology = level
case ArmourTechnology.ID:
report.ArmourTechnology = level
case EnergyTechnology.ID:
report.EnergyTechnology = level
case HyperspaceTechnology.ID:
report.HyperspaceTechnology = level
case CombustionDrive.ID:
report.CombustionDrive = level
case ImpulseDrive.ID:
report.ImpulseDrive = level
case HyperspaceDrive.ID:
report.HyperspaceDrive = level
case LaserTechnology.ID:
report.LaserTechnology = level
case IonTechnology.ID:
report.IonTechnology = level
case PlasmaTechnology.ID:
report.PlasmaTechnology = level
case IntergalacticResearchNetwork.ID:
report.IntergalacticResearchNetwork = level
case Astrophysics.ID:
report.Astrophysics = level
case GravitonTechnology.ID:
report.GravitonTechnology = level
}
return true
})
} else if dataType == "ships" {
report.HasFleetInformation = s.Find("li.detail_list_fail").Size() == 0
s.Find("li.detail_list_el").EachWithBreak(func(i int, s2 *goquery.Selection) bool {
img := s2.Find("img")
if img.Size() == 0 {
hasError = true
return false
}
imgClass := img.AttrOr("class", "")
r := regexp.MustCompile(`tech(\d+)`)
shipID, _ := strconv.ParseInt(r.FindStringSubmatch(imgClass)[1], 10, 64)
l := ParseInt(s2.Find("span.fright").Text())
level := &l
switch ID(shipID) {
case SmallCargo.ID:
report.SmallCargo = level
case LargeCargo.ID:
report.LargeCargo = level
case LightFighter.ID:
report.LightFighter = level
case HeavyFighter.ID:
report.HeavyFighter = level
case Cruiser.ID:
report.Cruiser = level
case Battleship.ID:
report.Battleship = level
case ColonyShip.ID:
report.ColonyShip = level
case Recycler.ID:
report.Recycler = level
case EspionageProbe.ID:
report.EspionageProbe = level
case Bomber.ID:
report.Bomber = level
case SolarSatellite.ID:
report.SolarSatellite = level
case Destroyer.ID:
report.Destroyer = level
case Deathstar.ID:
report.Deathstar = level
case Battlecruiser.ID:
report.Battlecruiser = level
case Crawler.ID:
report.Crawler = level
case Reaper.ID:
report.Reaper = level
case Pathfinder.ID:
report.Pathfinder = level
}
return true
})
} else if dataType == "defense" {
report.HasDefensesInformation = s.Find("li.detail_list_fail").Size() == 0
s.Find("li.detail_list_el").EachWithBreak(func(i int, s2 *goquery.Selection) bool {
img := s2.Find("img")
if img.Size() == 0 {
hasError = true
return false
}
imgClass := img.AttrOr("class", "")
r := regexp.MustCompile(`defense(\d+)`)
defenceID, _ := strconv.ParseInt(r.FindStringSubmatch(imgClass)[1], 10, 64)
l := ParseInt(s2.Find("span.fright").Text())
level := &l
switch ID(defenceID) {
case RocketLauncher.ID:
report.RocketLauncher = level
case LightLaser.ID:
report.LightLaser = level
case HeavyLaser.ID:
report.HeavyLaser = level
case GaussCannon.ID:
report.GaussCannon = level
case IonCannon.ID:
report.IonCannon = level
case PlasmaTurret.ID:
report.PlasmaTurret = level
case SmallShieldDome.ID:
report.SmallShieldDome = level
case LargeShieldDome.ID:
report.LargeShieldDome = level
case AntiBallisticMissiles.ID:
report.AntiBallisticMissiles = level
case InterplanetaryMissiles.ID:
report.InterplanetaryMissiles = level
}
return true
})
}
})
if hasError {
return report, ErrDeactivateHidePictures
}
return report, nil
}
Loading

0 comments on commit 56e4797

Please sign in to comment.