diff --git a/empireCelestial.go b/empireCelestial.go new file mode 100644 index 00000000..6b046a14 --- /dev/null +++ b/empireCelestial.go @@ -0,0 +1,17 @@ +package ogame + +// EmpireCelestial celestial information extracted from empire page (commander only) +type EmpireCelestial struct { + Name string + ID CelestialID + Type CelestialType + Fields Fields + Temperature Temperature + Coordinate Coordinate + Resources Resources + Supplies ResourcesBuildings + Facilities Facilities + Defenses DefensesInfos + Researches Researches + Ships ShipsInfos +} diff --git a/extractor_v6.go b/extractor_v6.go index 32c1bae6..70071c70 100644 --- a/extractor_v6.go +++ b/extractor_v6.go @@ -797,6 +797,11 @@ func (e ExtractorV6) ExtractCancelResearchInfos(pageHTML []byte) (token string, return extractCancelResearchInfosV6(pageHTML) } +// ExtractEmpire ... +func (e ExtractorV6) ExtractEmpire(pageHTML []byte) ([]EmpireCelestial, error) { + return extractEmpire(pageHTML) +} + // ExtractEmpireJSON ... func (e ExtractorV6) ExtractEmpireJSON(pageHTML []byte) (interface{}, error) { return extractEmpireJSON(pageHTML) diff --git a/extracts_v6.go b/extracts_v6.go index 0afa4e0a..1942f9cc 100644 --- a/extracts_v6.go +++ b/extracts_v6.go @@ -1990,7 +1990,9 @@ func extractUniverseSpeedV6(pageHTML []byte) int64 { return universeSpeed } -var planetInfosRgx = regexp.MustCompile(`([^\[]+) \[(\d+):(\d+):(\d+)]([\d.,]+)(?i)(?:km|км|公里|χμ) \((\d+)/(\d+)\)(?:de|da|od|mellem|от)?\s*([-\d]+).+C\s*(?:bis|-tól|para|to|à|至|a|~|do|ile|tot|og|до|až|til|la|έως|:sta)\s*([-\d]+).+C`) +var temperatureRgxStr = `([-\d]+).+C\s*(?:bis|-tól|para|to|à|至|a|~|do|ile|tot|og|до|až|til|la|έως|:sta)\s*([-\d]+).+C` +var temperatureRgx = regexp.MustCompile(temperatureRgxStr) +var planetInfosRgx = regexp.MustCompile(`([^\[]+) \[(\d+):(\d+):(\d+)]([\d.,]+)(?i)(?:km|км|公里|χμ) \((\d+)/(\d+)\)(?:de|da|od|mellem|от)?\s*` + temperatureRgxStr) var moonInfosRgx = regexp.MustCompile(`([^\[]+) \[(\d+):(\d+):(\d+)]([\d.,]+)(?i)(?:km|км|χμ|公里) \((\d+)/(\d+)\)`) var cpRgx = regexp.MustCompile(`&cp=(\d+)`) @@ -2074,6 +2076,139 @@ func extractMoonFromSelectionV6(moonLink *goquery.Selection, b *OGame) (Moon, er return moon, nil } +func extractEmpire(pageHTML []byte) ([]EmpireCelestial, error) { + var out []EmpireCelestial + raw, err := extractEmpireJSON(pageHTML) + if err != nil { + return nil, err + } + j, ok := raw.(map[string]interface{}) + if !ok { + return nil, errors.New("failed to parse json") + } + planetsRaw, ok := j["planets"].([]interface{}) + if !ok { + return nil, errors.New("failed to parse json") + } + for _, planetRaw := range planetsRaw { + planet, ok := planetRaw.(map[string]interface{}) + if !ok { + return nil, errors.New("failed to parse json") + } + + var tempMin, tempMax int64 + temperatureStr := doCastStr(planet["temperature"]) + m := temperatureRgx.FindStringSubmatch(temperatureStr) + if len(m) == 3 { + tempMin, _ = strconv.ParseInt(m[1], 10, 64) + tempMax, _ = strconv.ParseInt(m[2], 10, 64) + } + energyStr := doCastStr(planet["energy"]) + energyDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(energyStr)) + energy := ParseInt(energyDoc.Find("div span").Text()) + celestialType := CelestialType(doCastF64(planet["type"])) + out = append(out, EmpireCelestial{ + Name: doCastStr(planet["name"]), + ID: CelestialID(doCastF64(planet["id"])), + Type: celestialType, + Fields: Fields{ + Built: int64(doCastF64(planet["fieldUsed"])), + Total: int64(doCastF64(planet["fieldMax"])), + }, + Temperature: Temperature{ + Min: tempMin, + Max: tempMax, + }, + Coordinate: Coordinate{ + Galaxy: int64(doCastF64(planet["galaxy"])), + System: int64(doCastF64(planet["system"])), + Position: int64(doCastF64(planet["position"])), + Type: celestialType, + }, + Resources: Resources{ + Metal: int64(doCastF64(planet["metal"])), + Crystal: int64(doCastF64(planet["crystal"])), + Deuterium: int64(doCastF64(planet["deuterium"])), + Energy: energy, + }, + Supplies: ResourcesBuildings{ + MetalMine: int64(doCastF64(planet["1"])), + CrystalMine: int64(doCastF64(planet["2"])), + DeuteriumSynthesizer: int64(doCastF64(planet["3"])), + SolarPlant: int64(doCastF64(planet["4"])), + FusionReactor: int64(doCastF64(planet["12"])), + SolarSatellite: int64(doCastF64(planet["212"])), + MetalStorage: int64(doCastF64(planet["22"])), + CrystalStorage: int64(doCastF64(planet["23"])), + DeuteriumTank: int64(doCastF64(planet["24"])), + }, + Facilities: Facilities{ + RoboticsFactory: int64(doCastF64(planet["14"])), + Shipyard: int64(doCastF64(planet["21"])), + ResearchLab: int64(doCastF64(planet["31"])), + AllianceDepot: int64(doCastF64(planet["34"])), + MissileSilo: int64(doCastF64(planet["44"])), + NaniteFactory: int64(doCastF64(planet["15"])), + Terraformer: int64(doCastF64(planet["33"])), + SpaceDock: int64(doCastF64(planet["36"])), + LunarBase: int64(doCastF64(planet["41"])), + SensorPhalanx: int64(doCastF64(planet["42"])), + JumpGate: int64(doCastF64(planet["43"])), + }, + Defenses: DefensesInfos{ + RocketLauncher: int64(doCastF64(planet["401"])), + LightLaser: int64(doCastF64(planet["402"])), + HeavyLaser: int64(doCastF64(planet["403"])), + GaussCannon: int64(doCastF64(planet["404"])), + IonCannon: int64(doCastF64(planet["405"])), + PlasmaTurret: int64(doCastF64(planet["406"])), + SmallShieldDome: int64(doCastF64(planet["407"])), + LargeShieldDome: int64(doCastF64(planet["408"])), + AntiBallisticMissiles: int64(doCastF64(planet["502"])), + InterplanetaryMissiles: int64(doCastF64(planet["503"])), + }, + Researches: Researches{ + EnergyTechnology: int64(doCastF64(planet["113"])), + LaserTechnology: int64(doCastF64(planet["120"])), + IonTechnology: int64(doCastF64(planet["121"])), + HyperspaceTechnology: int64(doCastF64(planet["114"])), + PlasmaTechnology: int64(doCastF64(planet["122"])), + CombustionDrive: int64(doCastF64(planet["115"])), + ImpulseDrive: int64(doCastF64(planet["117"])), + HyperspaceDrive: int64(doCastF64(planet["118"])), + EspionageTechnology: int64(doCastF64(planet["106"])), + ComputerTechnology: int64(doCastF64(planet["108"])), + Astrophysics: int64(doCastF64(planet["124"])), + IntergalacticResearchNetwork: int64(doCastF64(planet["123"])), + GravitonTechnology: int64(doCastF64(planet["199"])), + WeaponsTechnology: int64(doCastF64(planet["109"])), + ShieldingTechnology: int64(doCastF64(planet["110"])), + ArmourTechnology: int64(doCastF64(planet["111"])), + }, + Ships: ShipsInfos{ + LightFighter: int64(doCastF64(planet["204"])), + HeavyFighter: int64(doCastF64(planet["205"])), + Cruiser: int64(doCastF64(planet["206"])), + Battleship: int64(doCastF64(planet["207"])), + Battlecruiser: int64(doCastF64(planet["215"])), + Bomber: int64(doCastF64(planet["211"])), + Destroyer: int64(doCastF64(planet["213"])), + Deathstar: int64(doCastF64(planet["214"])), + SmallCargo: int64(doCastF64(planet["202"])), + LargeCargo: int64(doCastF64(planet["203"])), + ColonyShip: int64(doCastF64(planet["208"])), + Recycler: int64(doCastF64(planet["209"])), + EspionageProbe: int64(doCastF64(planet["210"])), + SolarSatellite: int64(doCastF64(planet["212"])), + Crawler: int64(doCastF64(planet["217"])), + Reaper: int64(doCastF64(planet["218"])), + Pathfinder: int64(doCastF64(planet["219"])), + }, + }) + } + return out, nil +} + func extractEmpireJSON(pageHTML []byte) (interface{}, error) { m := regexp.MustCompile(`createImperiumHtml\("#mainWrapper",\s"#loading",\s(.*),\s\d+\s\);`).FindSubmatch(pageHTML) if len(m) != 2 { diff --git a/interfaces.go b/interfaces.go index ff943a21..19fbdb4d 100644 --- a/interfaces.go +++ b/interfaces.go @@ -38,6 +38,7 @@ type Prioritizable interface { GetCelestials() ([]Celestial, error) GetCombatReportSummaryFor(Coordinate) (CombatReportSummary, error) GetDMCosts(CelestialID) (DMCosts, error) + GetEmpire(CelestialType) ([]EmpireCelestial, error) GetEmpireJSON(nbr int64) (interface{}, error) GetEspionageReport(msgID int64) (EspionageReport, error) GetEspionageReportFor(Coordinate) (EspionageReport, error) @@ -383,6 +384,7 @@ type Extractor interface { ExtractFleetDeutSaveFactor(pageHTML []byte) float64 ExtractCancelBuildingInfos(pageHTML []byte) (token string, techID, listID int64, err error) ExtractCancelResearchInfos(pageHTML []byte) (token string, techID, listID int64, err error) + ExtractEmpire(pageHTML []byte) ([]EmpireCelestial, error) ExtractEmpireJSON(pageHTML []byte) (interface{}, error) ExtractCharacterClass(pageHTML []byte) (CharacterClass, error) ExtractCharacterClassFromDoc(doc *goquery.Document) (CharacterClass, error) diff --git a/ogame.go b/ogame.go index 3e7b527e..0f483ac1 100644 --- a/ogame.go +++ b/ogame.go @@ -3053,6 +3053,23 @@ func (b *OGame) executeJumpGate(originMoonID, destMoonID MoonID, ships ShipsInfo return true, 0, nil } +func (b *OGame) getEmpire(celestialType CelestialType) (out []EmpireCelestial, err error) { + var planetType int + if celestialType == PlanetType { + planetType = 0 + } else if celestialType == MoonType { + planetType = 1 + } else { + return out, errors.New("invalid celestial type") + } + vals := url.Values{"page": {"standalone"}, "component": {"empire"}, "planetType": {strconv.Itoa(planetType)}} + pageHTMLBytes, err := b.getPageContent(vals) + if err != nil { + return out, err + } + return b.extractor.ExtractEmpire(pageHTMLBytes) +} + func (b *OGame) getEmpireJSON(nbr int64) (interface{}, error) { // Valid URLs: // /game/index.php?page=standalone&component=empire&planetType=0 @@ -5687,6 +5704,11 @@ func (b *OGame) HeadersForPage(url string) (http.Header, error) { return b.WithPriority(Normal).HeadersForPage(url) } +// GetEmpire gets all planets/moons information resources/supplies/facilities/ships/researches +func (b *OGame) GetEmpire(celestialType CelestialType) ([]EmpireCelestial, error) { + return b.WithPriority(Normal).GetEmpire(celestialType) +} + // GetEmpireJSON retrieves JSON from Empire page (Commander only). func (b *OGame) GetEmpireJSON(nbr int64) (interface{}, error) { return b.WithPriority(Normal).GetEmpireJSON(nbr) diff --git a/ogame_test.go b/ogame_test.go index 043b7df7..3635f5c6 100644 --- a/ogame_test.go +++ b/ogame_test.go @@ -3043,6 +3043,24 @@ func TestFixAttackEvents(t *testing.T) { assert.Equal(t, PlanetType, attacks[0].Destination.Type) // Did not change } +func TestExtractEmpirePlanets(t *testing.T) { + pageHTMLBytes, _ := ioutil.ReadFile("samples/v8.1/en/empire_planets.html") + res, _ := NewExtractorV6().ExtractEmpire(pageHTMLBytes) + assert.Equal(t, 8, len(res)) + assert.Equal(t, Coordinate{Galaxy: 4, System: 208, Position: 8, Type: PlanetType}, res[0].Coordinate) + assert.Equal(t, int64(-3199), res[0].Resources.Energy) +} + +func TestExtractEmpireMoons(t *testing.T) { + pageHTMLBytes, _ := ioutil.ReadFile("samples/v8.1/en/empire_moons.html") + res, _ := NewExtractorV6().ExtractEmpire(pageHTMLBytes) + assert.Equal(t, 3, len(res)) + assert.Equal(t, Coordinate{Galaxy: 4, System: 116, Position: 9, Type: MoonType}, res[0].Coordinate) + assert.Equal(t, int64(0), res[0].Resources.Energy) + assert.Equal(t, int64(-19), res[0].Temperature.Min) + assert.Equal(t, int64(21), res[0].Temperature.Max) +} + func TestExtractAuction_playerBid(t *testing.T) { pageHTMLBytes, _ := ioutil.ReadFile("samples/v7.5.0/en/auction_player_bid.html") res, _ := NewExtractorV6().ExtractAuction(pageHTMLBytes) diff --git a/prioritize.go b/prioritize.go index cbd1193e..8b07e796 100644 --- a/prioritize.go +++ b/prioritize.go @@ -605,6 +605,13 @@ func (b *Prioritize) HeadersForPage(url string) (http.Header, error) { return b.bot.headersForPage(url) } +// GetEmpire (Commander only) +func (b *Prioritize) GetEmpire(celestialType CelestialType) ([]EmpireCelestial, error) { + b.begin("GetEmpire") + defer b.done() + return b.bot.getEmpire(celestialType) +} + // GetEmpireJSON retrieves JSON from Empire page (Commander only). func (b *Prioritize) GetEmpireJSON(nbr int64) (interface{}, error) { b.begin("GetEmpireJSON") diff --git a/samples/v8.1/en/empire_moons.html b/samples/v8.1/en/empire_moons.html new file mode 100644 index 00000000..3e55dcff --- /dev/null +++ b/samples/v8.1/en/empire_moons.html @@ -0,0 +1,284 @@ + + + + + Zibal OGame + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ +
+
+
+
+ +
load...
+ +
+
+
+
+ + + + + +
+
+
+ +
+ + + diff --git a/samples/v8.1/en/empire_planets.html b/samples/v8.1/en/empire_planets.html new file mode 100644 index 00000000..1d34fbc4 --- /dev/null +++ b/samples/v8.1/en/empire_planets.html @@ -0,0 +1,284 @@ + + + + + Zibal OGame + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ +
+
+
+
+ +
load...
+ +
+
+
+
+ + + + + +
+
+
+ +
+ + +