diff --git a/cmd/c/main.go b/cmd/c/main.go index 2d53ae16..74ca0096 100644 --- a/cmd/c/main.go +++ b/cmd/c/main.go @@ -332,9 +332,9 @@ func BuildShips(planetID, shipID, nbr C.int) (errorMsg *C.char) { // TODO: GetProduction(PlanetID) ([]Quantifiable, error) //export ConstructionsBeingBuilt -func ConstructionsBeingBuilt(planetID C.int) (buildingID, buildingCountdown, researchID, researchCountdown C.int) { - a, b, c, d := bot.ConstructionsBeingBuilt(ogame2.CelestialID(planetID)) - return C.int(a), C.int(b), C.int(c), C.int(d) +func ConstructionsBeingBuilt(planetID C.int) (buildingID, buildingCountdown, researchID, researchCountdown, lfBuildingID, lfBuildingCountdown C.int) { + a, b, c, d, e, f := bot.ConstructionsBeingBuilt(ogame2.CelestialID(planetID)) + return C.int(a), C.int(b), C.int(c), C.int(d), C.int(e), C.int(f) } //export CancelBuilding diff --git a/cmd/ogamed/main.go b/cmd/ogamed/main.go index 37506c8c..d5ded0e4 100644 --- a/cmd/ogamed/main.go +++ b/cmd/ogamed/main.go @@ -287,6 +287,7 @@ func start(c *cli.Context) error { e.GET("/bot/get-research", wrapper.GetResearchHandler) e.GET("/bot/buy-offer-of-the-day", wrapper.BuyOfferOfTheDayHandler) e.GET("/bot/price/:ogameID/:nbr", wrapper.GetPriceHandler) + e.GET("/bot/requirements/:ogameID", wrapper.GetRequirementsHandler) e.GET("/bot/moons", wrapper.GetMoonsHandler) e.GET("/bot/moons/:moonID", wrapper.GetMoonHandler) e.GET("/bot/moons/:galaxy/:system/:position", wrapper.GetMoonByCoordHandler) @@ -300,6 +301,7 @@ func start(c *cli.Context) error { e.GET("/bot/planets/:planetID/resource-settings", wrapper.GetResourceSettingsHandler) e.POST("/bot/planets/:planetID/resource-settings", wrapper.SetResourceSettingsHandler) e.GET("/bot/planets/:planetID/resources-buildings", wrapper.GetResourcesBuildingsHandler) + e.GET("/bot/planets/:planetID/lifeform-buildings", wrapper.GetLfBuildingsHandler) e.GET("/bot/planets/:planetID/defence", wrapper.GetDefenseHandler) e.GET("/bot/planets/:planetID/ships", wrapper.GetShipsHandler) e.GET("/bot/planets/:planetID/facilities", wrapper.GetFacilitiesHandler) diff --git a/pkg/extractor/extractor.go b/pkg/extractor/extractor.go index 62bb66e8..fa268a3e 100644 --- a/pkg/extractor/extractor.go +++ b/pkg/extractor/extractor.go @@ -1,13 +1,14 @@ package extractor import ( + "net/url" + "time" + "github.com/PuerkitoBio/goquery" v6 "github.com/alaingilbert/ogame/pkg/extractor/v6" v7 "github.com/alaingilbert/ogame/pkg/extractor/v7" v9 "github.com/alaingilbert/ogame/pkg/extractor/v9" "github.com/alaingilbert/ogame/pkg/ogame" - "net/url" - "time" ) type FullPageExtractorBytes interface { @@ -74,7 +75,7 @@ type OverviewExtractorBytes interface { ExtractCancelLfBuildingInfos(pageHTML []byte) (token string, id, listID int64, err error) ExtractCancelResearchInfos(pageHTML []byte) (token string, techID, listID int64, err error) ExtractCharacterClass(pageHTML []byte) (ogame.CharacterClass, error) - ExtractConstructions(pageHTML []byte) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64) + ExtractConstructions(pageHTML []byte) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64, lfBuildingID ogame.ID, lfBuildingCountdown int64) ExtractDMCosts(pageHTML []byte) (ogame.DMCosts, error) ExtractFleetDeutSaveFactor(pageHTML []byte) float64 ExtractOverviewProduction(pageHTML []byte) ([]ogame.Quantifiable, int64, error) @@ -355,7 +356,7 @@ type TraderImportExportExtractorDoc interface { // FetchTechsExtractorBytes ajax page fetchTechs type FetchTechsExtractorBytes interface { - ExtractTechs(pageHTML []byte) (ogame.ResourcesBuildings, ogame.Facilities, ogame.ShipsInfos, ogame.DefensesInfos, ogame.Researches, error) + ExtractTechs(pageHTML []byte) (ogame.ResourcesBuildings, ogame.Facilities, ogame.ShipsInfos, ogame.DefensesInfos, ogame.Researches, ogame.LfBuildings, error) } type ResourcesSettingsExtractorBytes interface { @@ -410,10 +411,16 @@ type MessagesMarketplaceExtractorBytes interface { type LfBuildingsExtractorBytes interface { ExtractUpgradeToken(pageHTML []byte) (string, error) + ExtractLfBuildings(pageHTML []byte) (ogame.LfBuildings, error) +} + +type LfBuildingsExtractorDoc interface { + ExtractLfBuildingsFromDoc(doc *goquery.Document) (ogame.LfBuildings, error) } type LfBuildingsExtractorBytesDoc interface { LfBuildingsExtractorBytes + LfBuildingsExtractorDoc } // ResourcesBuildingsExtractorBytes supplies page diff --git a/pkg/extractor/v6/extractor.go b/pkg/extractor/v6/extractor.go index 72f731e8..2a25c968 100644 --- a/pkg/extractor/v6/extractor.go +++ b/pkg/extractor/v6/extractor.go @@ -3,10 +3,11 @@ package v6 import ( "bytes" "errors" - "github.com/alaingilbert/ogame/pkg/ogame" "net/url" "time" + "github.com/alaingilbert/ogame/pkg/ogame" + "github.com/PuerkitoBio/goquery" "github.com/alaingilbert/clockwork" ) @@ -57,7 +58,7 @@ func (e *Extractor) ExtractPremiumToken(pageHTML []byte, days int64) (string, er } // ExtractTechs ... -func (e *Extractor) ExtractTechs(pageHTML []byte) (ogame.ResourcesBuildings, ogame.Facilities, ogame.ShipsInfos, ogame.DefensesInfos, ogame.Researches, error) { +func (e *Extractor) ExtractTechs(pageHTML []byte) (ogame.ResourcesBuildings, ogame.Facilities, ogame.ShipsInfos, ogame.DefensesInfos, ogame.Researches, ogame.LfBuildings, error) { panic("implement me") } @@ -546,7 +547,7 @@ func (e *Extractor) ExtractFleetsFromDoc(doc *goquery.Document) (res []ogame.Fle } func (e *Extractor) extractFleetsFromDoc(doc *goquery.Document, location *time.Location) (res []ogame.Fleet) { - return extractFleetsFromDoc(doc, location) + return extractFleetsFromDoc(doc, location, e.lifeformEnabled) } // ExtractSlotsFromDoc extract fleet slots from page "fleet1" @@ -808,7 +809,7 @@ func (e *Extractor) ExtractFederation(pageHTML []byte) url.Values { } // ExtractConstructions ... -func (e *Extractor) ExtractConstructions(pageHTML []byte) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64) { +func (e *Extractor) ExtractConstructions(pageHTML []byte) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64, lfBuildingID ogame.ID, lfBuildingCountdown int64) { return extractConstructions(pageHTML) } @@ -882,3 +883,13 @@ func (e *Extractor) ExtractIsMobile(pageHTML []byte) bool { func (e *Extractor) ExtractIsMobileFromDoc(doc *goquery.Document) bool { panic("not implemented") } + +// ExtractLfBuildings ... +func (e *Extractor) ExtractLfBuildings(pageHTML []byte) (ogame.LfBuildings, error) { + panic("not implemented") +} + +// ExtractLfBuildingsFromDoc ... +func (e *Extractor) ExtractLfBuildingsFromDoc(doc *goquery.Document) (ogame.LfBuildings, error) { + panic("not implemented") +} diff --git a/pkg/extractor/v6/extractor_test.go b/pkg/extractor/v6/extractor_test.go index fd160b10..7bd5caba 100644 --- a/pkg/extractor/v6/extractor_test.go +++ b/pkg/extractor/v6/extractor_test.go @@ -1884,7 +1884,7 @@ func TestCancelResearch(t *testing.T) { func TestGetConstructions(t *testing.T) { pageHTMLBytes, _ := ioutil.ReadFile("../../../samples/unversioned/overview_active.html") - buildingID, buildingCountdown, researchID, researchCountdown := NewExtractor().ExtractConstructions(pageHTMLBytes) + buildingID, buildingCountdown, researchID, researchCountdown, _, _ := NewExtractor().ExtractConstructions(pageHTMLBytes) assert.Equal(t, ogame.CrystalMineID, buildingID) assert.Equal(t, int64(731), buildingCountdown) assert.Equal(t, ogame.CombustionDriveID, researchID) diff --git a/pkg/extractor/v6/extracts.go b/pkg/extractor/v6/extracts.go index b02089c7..1332b5fb 100644 --- a/pkg/extractor/v6/extracts.go +++ b/pkg/extractor/v6/extracts.go @@ -1090,7 +1090,7 @@ func extractIPMFromDoc(doc *goquery.Document) (duration, max int64, token string return } -func extractFleetsFromDoc(doc *goquery.Document, location *time.Location) (res []ogame.Fleet) { +func extractFleetsFromDoc(doc *goquery.Document, location *time.Location, lifeformEnabled bool) (res []ogame.Fleet) { res = make([]ogame.Fleet, 0) script := doc.Find("body script").Text() doc.Find("div.fleetDetails").Each(func(i int, s *goquery.Selection) { @@ -1134,9 +1134,17 @@ func extractFleetsFromDoc(doc *goquery.Document, location *time.Location) (res [ trs := s.Find("table.fleetinfo tr") shipment := ogame.Resources{} - shipment.Metal = utils.ParseInt(trs.Eq(trs.Size() - 3).Find("td").Eq(1).Text()) - shipment.Crystal = utils.ParseInt(trs.Eq(trs.Size() - 2).Find("td").Eq(1).Text()) - shipment.Deuterium = utils.ParseInt(trs.Eq(trs.Size() - 1).Find("td").Eq(1).Text()) + metalTrOffset := 3 + crystalTrOffset := 2 + DeuteriumTrOffset := 1 + if lifeformEnabled { + metalTrOffset = 4 + crystalTrOffset = 3 + DeuteriumTrOffset = 2 + } + shipment.Metal = utils.ParseInt(trs.Eq(trs.Size() - metalTrOffset).Find("td").Eq(1).Text()) + shipment.Crystal = utils.ParseInt(trs.Eq(trs.Size() - crystalTrOffset).Find("td").Eq(1).Text()) + shipment.Deuterium = utils.ParseInt(trs.Eq(trs.Size() - DeuteriumTrOffset).Find("td").Eq(1).Text()) fedAttackHref := s.Find("span.fedAttack a").AttrOr("href", "") fedAttackURL, _ := url.Parse(fedAttackHref) @@ -1905,7 +1913,7 @@ func extractFederation(pageHTML []byte) url.Values { return payload } -func extractConstructions(pageHTML []byte) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64) { +func extractConstructions(pageHTML []byte) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64, lfBuildingID ogame.ID, lfBuildingCountdown int64) { buildingCountdownMatch := regexp.MustCompile(`getElementByIdWithCache\("Countdown"\),(\d+),`).FindSubmatch(pageHTML) if len(buildingCountdownMatch) > 0 { buildingCountdown = int64(utils.ToInt(buildingCountdownMatch[1])) diff --git a/pkg/extractor/v7/extractor.go b/pkg/extractor/v7/extractor.go index acb7190f..f215e683 100644 --- a/pkg/extractor/v7/extractor.go +++ b/pkg/extractor/v7/extractor.go @@ -96,7 +96,7 @@ func (e Extractor) ExtractResourcesDetails(pageHTML []byte) (out ogame.Resources } // ExtractConstructions ... -func (e Extractor) ExtractConstructions(pageHTML []byte) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64) { +func (e Extractor) ExtractConstructions(pageHTML []byte) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64, lfBuildingID ogame.ID, lfBuildingCountdown int64) { return ExtractConstructions(pageHTML, clockwork.NewRealClock()) } diff --git a/pkg/extractor/v7/extractor_test.go b/pkg/extractor/v7/extractor_test.go index 4f99aa91..b1d96539 100644 --- a/pkg/extractor/v7/extractor_test.go +++ b/pkg/extractor/v7/extractor_test.go @@ -313,7 +313,7 @@ func TestExtractFleetSlot_FleetDispatch(t *testing.T) { func TestGetConstructionsV7(t *testing.T) { pageHTMLBytes, _ := ioutil.ReadFile("../../../samples/v7/overview_supplies_in_construction.html") clock := clockwork.NewFakeClockAt(time.Date(2019, 11, 12, 9, 6, 43, 0, time.UTC)) - buildingID, buildingCountdown, researchID, researchCountdown := ExtractConstructions(pageHTMLBytes, clock) + buildingID, buildingCountdown, researchID, researchCountdown, _, _ := ExtractConstructions(pageHTMLBytes, clock) assert.Equal(t, ogame.MetalMineID, buildingID) assert.Equal(t, int64(62), buildingCountdown) assert.Equal(t, ogame.EnergyTechnologyID, researchID) diff --git a/pkg/extractor/v7/extracts.go b/pkg/extractor/v7/extracts.go index 6bfdc879..bdf3309b 100644 --- a/pkg/extractor/v7/extracts.go +++ b/pkg/extractor/v7/extracts.go @@ -37,24 +37,24 @@ func extractPremiumToken(pageHTML []byte, days int64) (token string, err error) func extractResourcesDetailsFromFullPageFromDoc(doc *goquery.Document) ogame.ResourcesDetails { out := ogame.ResourcesDetails{} - out.Metal.Available = utils.ParseInt(strings.Split(doc.Find("span#resources_metal").AttrOr("data-raw", "0"), ".")[0]) - out.Crystal.Available = utils.ParseInt(strings.Split(doc.Find("span#resources_crystal").AttrOr("data-raw", "0"), ".")[0]) - out.Deuterium.Available = utils.ParseInt(strings.Split(doc.Find("span#resources_deuterium").AttrOr("data-raw", "0"), ".")[0]) - out.Energy.Available = utils.ParseInt(doc.Find("span#resources_energy").Text()) - out.Darkmatter.Available = utils.ParseInt(doc.Find("span#resources_darkmatter").Text()) - metalDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(doc.Find("li#metal_box").AttrOr("title", ""))) - crystalDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(doc.Find("li#crystal_box").AttrOr("title", ""))) - deuteriumDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(doc.Find("li#deuterium_box").AttrOr("title", ""))) - energyDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(doc.Find("li#energy_box").AttrOr("title", ""))) - darkmatterDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(doc.Find("li#darkmatter_box").AttrOr("title", ""))) + 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.Available = utils.ParseInt(metalDoc.Find("table tr").Eq(0).Find("td").Eq(0).Text()) out.Metal.StorageCapacity = utils.ParseInt(metalDoc.Find("table tr").Eq(1).Find("td").Eq(0).Text()) out.Metal.CurrentProduction = utils.ParseInt(metalDoc.Find("table tr").Eq(2).Find("td").Eq(0).Text()) + out.Crystal.Available = utils.ParseInt(crystalDoc.Find("table tr").Eq(0).Find("td").Eq(0).Text()) out.Crystal.StorageCapacity = utils.ParseInt(crystalDoc.Find("table tr").Eq(1).Find("td").Eq(0).Text()) out.Crystal.CurrentProduction = utils.ParseInt(crystalDoc.Find("table tr").Eq(2).Find("td").Eq(0).Text()) + out.Deuterium.Available = utils.ParseInt(deuteriumDoc.Find("table tr").Eq(0).Find("td").Eq(0).Text()) out.Deuterium.StorageCapacity = utils.ParseInt(deuteriumDoc.Find("table tr").Eq(1).Find("td").Eq(0).Text()) out.Deuterium.CurrentProduction = utils.ParseInt(deuteriumDoc.Find("table tr").Eq(2).Find("td").Eq(0).Text()) + out.Energy.Available = utils.ParseInt(energyDoc.Find("table tr").Eq(0).Find("td").Eq(0).Text()) out.Energy.CurrentProduction = utils.ParseInt(energyDoc.Find("table tr").Eq(1).Find("td").Eq(0).Text()) out.Energy.Consumption = utils.ParseInt(energyDoc.Find("table tr").Eq(2).Find("td").Eq(0).Text()) + out.Darkmatter.Available = utils.ParseInt(darkmatterDoc.Find("table tr").Eq(0).Find("td").Eq(0).Text()) out.Darkmatter.Purchased = utils.ParseInt(darkmatterDoc.Find("table tr").Eq(1).Find("td").Eq(0).Text()) out.Darkmatter.Found = utils.ParseInt(darkmatterDoc.Find("table tr").Eq(2).Find("td").Eq(0).Text()) return out @@ -220,7 +220,7 @@ func extractResourcesDetails(pageHTML []byte) (out ogame.ResourcesDetails, err e return } -func ExtractConstructions(pageHTML []byte, clock clockwork.Clock) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64) { +func ExtractConstructions(pageHTML []byte, clock clockwork.Clock) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64, lfBuildingID ogame.ID, lfBuildingCountdown int64) { buildingCountdownMatch := regexp.MustCompile(`var restTimebuilding = (\d+) -`).FindSubmatch(pageHTML) if len(buildingCountdownMatch) > 0 { buildingCountdown = int64(utils.ToInt(buildingCountdownMatch[1])) - clock.Now().Unix() diff --git a/pkg/extractor/v71/extractor.go b/pkg/extractor/v71/extractor.go index 88df95cf..0697ba82 100644 --- a/pkg/extractor/v71/extractor.go +++ b/pkg/extractor/v71/extractor.go @@ -2,9 +2,10 @@ package v71 import ( "bytes" + "github.com/PuerkitoBio/goquery" "github.com/alaingilbert/clockwork" - "github.com/alaingilbert/ogame/pkg/extractor/v7" + v7 "github.com/alaingilbert/ogame/pkg/extractor/v7" "github.com/alaingilbert/ogame/pkg/ogame" ) @@ -46,7 +47,7 @@ func (e *Extractor) ExtractResourcesDetails(pageHTML []byte) (out ogame.Resource } // ExtractTechs ... -func (e *Extractor) ExtractTechs(pageHTML []byte) (ogame.ResourcesBuildings, ogame.Facilities, ogame.ShipsInfos, ogame.DefensesInfos, ogame.Researches, error) { +func (e *Extractor) ExtractTechs(pageHTML []byte) (ogame.ResourcesBuildings, ogame.Facilities, ogame.ShipsInfos, ogame.DefensesInfos, ogame.Researches, ogame.LfBuildings, error) { return extractTechs(pageHTML) } diff --git a/pkg/extractor/v71/extracts.go b/pkg/extractor/v71/extracts.go index d8839db6..c68e73d4 100644 --- a/pkg/extractor/v71/extracts.go +++ b/pkg/extractor/v71/extracts.go @@ -4,16 +4,17 @@ import ( "encoding/json" "errors" "fmt" - "github.com/alaingilbert/ogame/pkg/extractor/v6" - "github.com/alaingilbert/ogame/pkg/extractor/v7" - "github.com/alaingilbert/ogame/pkg/ogame" - "github.com/alaingilbert/ogame/pkg/utils" "math" "regexp" "strconv" "strings" "time" + v6 "github.com/alaingilbert/ogame/pkg/extractor/v6" + v7 "github.com/alaingilbert/ogame/pkg/extractor/v7" + "github.com/alaingilbert/ogame/pkg/ogame" + "github.com/alaingilbert/ogame/pkg/utils" + "github.com/PuerkitoBio/goquery" "github.com/alaingilbert/clockwork" "golang.org/x/net/html" @@ -44,6 +45,14 @@ type resourcesResp struct { Amount float64 `json:"amount"` Tooltip string `json:"tooltip"` } `json:"darkmatter"` + Population struct { + Amount float64 `json:"amount"` + Tooltip string `json:"tooltip"` + } `json:"population"` + Food struct { + Amount float64 `json:"amount"` + Tooltip string `json:"tooltip"` + } `json:"food"` } `json:"resources"` HonorScore int64 `json:"honorScore"` Techs struct { @@ -171,18 +180,38 @@ func extractResourcesDetails(pageHTML []byte) (out ogame.ResourcesDetails, err e out.Deuterium.StorageCapacity = int64(res.Resources.Deuterium.Storage) out.Energy.Available = int64(res.Resources.Energy.Amount) out.Darkmatter.Available = int64(res.Resources.Darkmatter.Amount) + out.Population.Available = int64(res.Resources.Population.Amount) + out.Food.Available = int64(res.Resources.Food.Amount) metalDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(res.Resources.Metal.Tooltip)) crystalDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(res.Resources.Crystal.Tooltip)) deuteriumDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(res.Resources.Deuterium.Tooltip)) darkmatterDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(res.Resources.Darkmatter.Tooltip)) energyDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(res.Resources.Energy.Tooltip)) + populationDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(res.Resources.Population.Tooltip)) + foodDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(res.Resources.Food.Tooltip)) + out.Metal.StorageCapacity = utils.ParseInt(metalDoc.Find("table tr").Eq(1).Find("td").Eq(0).Text()) out.Metal.CurrentProduction = utils.ParseInt(metalDoc.Find("table tr").Eq(2).Find("td").Eq(0).Text()) + out.Crystal.StorageCapacity = utils.ParseInt(crystalDoc.Find("table tr").Eq(1).Find("td").Eq(0).Text()) out.Crystal.CurrentProduction = utils.ParseInt(crystalDoc.Find("table tr").Eq(2).Find("td").Eq(0).Text()) + out.Deuterium.StorageCapacity = utils.ParseInt(deuteriumDoc.Find("table tr").Eq(1).Find("td").Eq(0).Text()) out.Deuterium.CurrentProduction = utils.ParseInt(deuteriumDoc.Find("table tr").Eq(2).Find("td").Eq(0).Text()) out.Energy.CurrentProduction = utils.ParseInt(energyDoc.Find("table tr").Eq(1).Find("td").Eq(0).Text()) out.Energy.Consumption = utils.ParseInt(energyDoc.Find("table tr").Eq(2).Find("td").Eq(0).Text()) out.Darkmatter.Purchased = utils.ParseInt(darkmatterDoc.Find("table tr").Eq(1).Find("td").Eq(0).Text()) out.Darkmatter.Found = utils.ParseInt(darkmatterDoc.Find("table tr").Eq(2).Find("td").Eq(0).Text()) + out.Food.Available = utils.ParseInt(foodDoc.Find("table tr").Eq(0).Find("td").Eq(0).Text()) + out.Food.StorageCapacity = utils.ParseInt(foodDoc.Find("table tr").Eq(1).Find("td").Eq(0).Text()) + out.Food.Overproduction = utils.ParseInt(foodDoc.Find("table tr").Eq(2).Find("td").Eq(0).Text()) + out.Food.ConsumedIn = utils.ParseInt(foodDoc.Find("table tr").Eq(3).Find("td").Eq(0).Text()) + out.Food.TimeTillFoodRunsOut = utils.ParseInt(foodDoc.Find("table tr").Eq(4).Find("td").Eq(0).Text()) + out.Population.Available = utils.ParseInt(populationDoc.Find("table tr").Eq(0).Find("td").Eq(0).Text()) + out.Population.T2Lifeforms = utils.ParseInt(populationDoc.Find("table tr").Eq(1).Find("td").Eq(0).Text()) + out.Population.T3Lifeforms = utils.ParseInt(populationDoc.Find("table tr").Eq(2).Find("td").Eq(0).Text()) + out.Population.LivingSpace = utils.ParseInt(populationDoc.Find("table tr").Eq(3).Find("td").Eq(0).Text()) + out.Population.Satisfied = utils.ParseInt(populationDoc.Find("table tr").Eq(4).Find("td").Eq(0).Text()) + out.Population.Hungry, _ = strconv.ParseFloat(populationDoc.Find("table tr").Eq(5).Find("td").Eq(0).Text(), 64) + out.Population.GrowthRate, _ = strconv.ParseFloat(strings.TrimPrefix(populationDoc.Find("table tr").Eq(6).Find("td").Eq(0).Text(), "±"), 64) + out.Population.BunkerSpace = utils.ParseInt(populationDoc.Find("table tr").Eq(7).Find("td").Eq(0).Text()) return } @@ -249,13 +278,63 @@ type planetTechsResp struct { Num408 int64 `json:"408"` Num502 int64 `json:"502"` Num503 int64 `json:"503"` + + // LFbuildings + Num11101 int64 `json:"11101"` + Num11102 int64 `json:"11102"` + Num11103 int64 `json:"11103"` + Num11104 int64 `json:"11104"` + Num11105 int64 `json:"11105"` + Num11106 int64 `json:"11106"` + Num11107 int64 `json:"11107"` + Num11108 int64 `json:"11108"` + Num11109 int64 `json:"11109"` + Num11110 int64 `json:"11110"` + Num11111 int64 `json:"11111"` + Num11112 int64 `json:"11112"` + Num12101 int64 `json:"12101"` + Num12102 int64 `json:"12102"` + Num12103 int64 `json:"12103"` + Num12104 int64 `json:"12104"` + Num12105 int64 `json:"12105"` + Num12106 int64 `json:"12106"` + Num12107 int64 `json:"12107"` + Num12108 int64 `json:"12108"` + Num12109 int64 `json:"12109"` + Num12110 int64 `json:"12110"` + Num12111 int64 `json:"12111"` + Num12112 int64 `json:"12112"` + Num13101 int64 `json:"13101"` + Num13102 int64 `json:"13102"` + Num13103 int64 `json:"13103"` + Num12304 int64 `json:"12304"` + Num13105 int64 `json:"13105"` + Num13106 int64 `json:"13106"` + Num13107 int64 `json:"13107"` + Num13108 int64 `json:"13108"` + Num13109 int64 `json:"13109"` + Num13110 int64 `json:"13110"` + Num13111 int64 `json:"13111"` + Num13112 int64 `json:"13112"` + Num14101 int64 `json:"14101"` + Num14102 int64 `json:"14102"` + Num14103 int64 `json:"14103"` + Num14104 int64 `json:"14104"` + Num14105 int64 `json:"14105"` + Num14106 int64 `json:"14106"` + Num14107 int64 `json:"14107"` + Num14108 int64 `json:"14108"` + Num14109 int64 `json:"14109"` + Num14110 int64 `json:"14110"` + Num14111 int64 `json:"14111"` + Num14112 int64 `json:"14112"` } -func extractTechs(pageHTML []byte) (supplies ogame.ResourcesBuildings, facilities ogame.Facilities, shipsInfos ogame.ShipsInfos, defenses ogame.DefensesInfos, researches ogame.Researches, err error) { +func extractTechs(pageHTML []byte) (supplies ogame.ResourcesBuildings, facilities ogame.Facilities, shipsInfos ogame.ShipsInfos, defenses ogame.DefensesInfos, researches ogame.Researches, lfBuildings ogame.LfBuildings, err error) { var res planetTechsResp if err = json.Unmarshal(pageHTML, &res); err != nil { if v6.IsLogged(pageHTML) { - return supplies, facilities, shipsInfos, defenses, researches, ogame.ErrInvalidPlanetID + return supplies, facilities, shipsInfos, defenses, researches, lfBuildings, ogame.ErrInvalidPlanetID } return } @@ -332,6 +411,56 @@ func extractTechs(pageHTML []byte) (supplies ogame.ResourcesBuildings, facilitie ShieldingTechnology: res.Num110, ArmourTechnology: res.Num111, } + lfBuildings = ogame.LfBuildings{ + ResidentialSector: res.Num11101, + BiosphereFarm: res.Num11102, + ResearchCentre: res.Num11103, + AcademyOfSciences: res.Num11104, + NeuroCalibrationCentre: res.Num11105, + HighEnergySmelting: res.Num11106, + FoodSilo: res.Num11107, + FusionPoweredProduction: res.Num11108, + Skyscraper: res.Num11109, + BiotechLab: res.Num11110, + Metropolis: res.Num11111, + PlanetaryShield: res.Num11112, + MeditationEnclave: res.Num12101, + CrystalFarm: res.Num12102, + RuneTechnologium: res.Num12103, + RuneForge: res.Num12104, + Oriktorium: res.Num12105, + MagmaForge: res.Num12106, + DisruptionChamber: res.Num12107, + Megalith: res.Num12108, + CrystalRefinery: res.Num12109, + DeuteriumSynthesiser: res.Num12110, + MineralResearchCentre: res.Num12111, + MetalRecyclingPlant: res.Num12112, + AssemblyLine: res.Num13101, + FusionCellFactory: res.Num13102, + RoboticsResearchCentre: res.Num13103, + UpdateNetwork: res.Num12304, + QuantumComputerCentre: res.Num13105, + AutomatisedAssemblyCentre: res.Num13106, + HighPerformanceTransformer: res.Num13107, + MicrochipAssemblyLine: res.Num13108, + ProductionAssemblyHall: res.Num13109, + HighPerformanceSynthesiser: res.Num13110, + ChipMassProduction: res.Num13111, + NanoRepairBots: res.Num13112, + Sanctuary: res.Num14101, + AntimatterCondenser: res.Num14102, + VortexChamber: res.Num14103, + HallsOfRealisation: res.Num14104, + ForumOfTranscendence: res.Num14105, + AntimatterConvector: res.Num14106, + CloningLaboratory: res.Num14107, + ChrysalisAccelerator: res.Num14108, + BioModifier: res.Num14109, + PsionicModulator: res.Num14110, + ShipManufacturingHall: res.Num14111, + SupraRefractor: res.Num14112, + } return } diff --git a/pkg/extractor/v9/extractor.go b/pkg/extractor/v9/extractor.go index f76499ef..6b0de589 100644 --- a/pkg/extractor/v9/extractor.go +++ b/pkg/extractor/v9/extractor.go @@ -81,15 +81,23 @@ func (e *Extractor) ExtractResourcesDetailsFromFullPageFromDoc(doc *goquery.Docu } // ExtractConstructions ... -func (e *Extractor) ExtractConstructions(pageHTML []byte) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64) { +func (e *Extractor) ExtractConstructions(pageHTML []byte) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64, lfBuildingID ogame.ID, lfBuildingCountdown int64) { return ExtractConstructions(pageHTML, clockwork.NewRealClock()) } +// ExtractResourceSettings ... func (e *Extractor) ExtractResourceSettings(pageHTML []byte) (ogame.ResourceSettings, string, error) { doc, _ := goquery.NewDocumentFromReader(bytes.NewReader(pageHTML)) return e.ExtractResourceSettingsFromDoc(doc) } -func (e *Extractor) ExtractResourceSettingsFromDoc(doc *goquery.Document) (ogame.ResourceSettings, string, error) { - return extractResourceSettingsFromDoc(doc) +// ExtractLfBuildings ... +func (e *Extractor) ExtractLfBuildings(pageHTML []byte) (ogame.LfBuildings, error) { + doc, _ := goquery.NewDocumentFromReader(bytes.NewReader(pageHTML)) + return e.ExtractLfBuildingsFromDoc(doc) +} + +// ExtractLfBuildingsFromDoc ... +func (e *Extractor) ExtractLfBuildingsFromDoc(doc *goquery.Document) (ogame.LfBuildings, error) { + return extractLfBuildingsFromDoc(doc) } diff --git a/pkg/extractor/v9/extractor_test.go b/pkg/extractor/v9/extractor_test.go index 03bbcd1e..9ad283b7 100644 --- a/pkg/extractor/v9/extractor_test.go +++ b/pkg/extractor/v9/extractor_test.go @@ -30,6 +30,14 @@ func TestExtractResourcesDetailsFromFullPage(t *testing.T) { assert.Equal(t, int64(8000), res.Darkmatter.Found) } +func TestExtractResourcesDetailsFromFullPagePopulation(t *testing.T) { + pageHTMLBytes, _ := ioutil.ReadFile("../../../samples/v9.0.4/en/lifeform/overview.html") + res := NewExtractor().ExtractResourcesDetailsFromFullPage(pageHTMLBytes) + assert.Equal(t, int64(1974118), res.Population.Available) + assert.Equal(t, 0.233, res.Population.Hungry) + assert.Equal(t, 61.983, res.Population.GrowthRate) +} + func TestExtractResources(t *testing.T) { pageHTMLBytes, _ := ioutil.ReadFile("../../../samples/v9.0.0/en/overview.html") res := NewExtractor().ExtractResources(pageHTMLBytes) @@ -102,7 +110,7 @@ func TestGetConstructions(t *testing.T) { // Without lifeform pageHTMLBytes, _ := ioutil.ReadFile("../../../samples/v9.0.2/en/overview_all_queues.html") clock := clockwork.NewFakeClockAt(time.Date(2022, 8, 20, 12, 43, 11, 0, time.UTC)) - buildingID, buildingCountdown, researchID, researchCountdown := ExtractConstructions(pageHTMLBytes, clock) + buildingID, buildingCountdown, researchID, researchCountdown, _, _ := ExtractConstructions(pageHTMLBytes, clock) assert.Equal(t, ogame.MetalMineID, buildingID) assert.Equal(t, int64(5413), buildingCountdown) assert.Equal(t, ogame.ComputerTechnologyID, researchID) @@ -111,19 +119,13 @@ func TestGetConstructions(t *testing.T) { // With lifeform pageHTMLBytes, _ = ioutil.ReadFile("../../../samples/v9.0.2/en/lifeform/overview_all_queues2.html") clock = clockwork.NewFakeClockAt(time.Date(2022, 8, 28, 17, 22, 26, 0, time.UTC)) - buildingID, buildingCountdown, researchID, researchCountdown = ExtractConstructions(pageHTMLBytes, clock) + buildingID, buildingCountdown, researchID, researchCountdown, _, _ = ExtractConstructions(pageHTMLBytes, clock) assert.Equal(t, ogame.MetalStorageID, buildingID) assert.Equal(t, int64(33483), buildingCountdown) assert.Equal(t, ogame.ComputerTechnologyID, researchID) assert.Equal(t, int64(18355), researchCountdown) } -func TestExtractResourceSettings(t *testing.T) { - pageHTMLBytes, _ := ioutil.ReadFile("../../../samples/v9.0.4/en/resource_settings.html") - settings, _, _ := NewExtractor().ExtractResourceSettings(pageHTMLBytes) - assert.Equal(t, ogame.ResourceSettings{MetalMine: 100, CrystalMine: 100, DeuteriumSynthesizer: 100, SolarPlant: 100, FusionReactor: 100, SolarSatellite: 100, Crawler: 100, PlasmaTechnology: 100}, settings) -} - func TestExtractUserInfos(t *testing.T) { pageHTMLBytes, _ := ioutil.ReadFile("../../../samples/v9.0.4/en/overview.html") info, err := NewExtractor().ExtractUserInfos(pageHTMLBytes) @@ -132,3 +134,50 @@ func TestExtractUserInfos(t *testing.T) { assert.Equal(t, int64(1102), info.Rank) assert.Equal(t, int64(2931), info.Total) } + +func TestExtractFleetResources(t *testing.T) { + pageHTMLBytes, _ := ioutil.ReadFile("../../../samples/v9.0.4/en/lifeform/movement.html") + e := NewExtractor() + e.SetLocation(time.FixedZone("OGT", 3600)) + e.SetLifeformEnabled(true) + fleets := e.ExtractFleets(pageHTMLBytes) + assert.Equal(t, int64(1), fleets[0].Resources.Metal) + assert.Equal(t, int64(2), fleets[0].Resources.Crystal) + assert.Equal(t, int64(3), fleets[0].Resources.Deuterium) +} + +func TestExtractLfBuildings(t *testing.T) { + pageHTMLBytes, _ := ioutil.ReadFile("../../../samples/v9.0.4/en/lfbuildings.html") + res, _ := NewExtractor().ExtractLfBuildings(pageHTMLBytes) + assert.Equal(t, int64(2), res.ResidentialSector) + assert.Equal(t, int64(1), res.BiosphereFarm) + assert.Equal(t, int64(0), res.ResearchCentre) + assert.Equal(t, int64(0), res.AcademyOfSciences) + assert.Equal(t, int64(0), res.NeuroCalibrationCentre) + assert.Equal(t, int64(0), res.HighEnergySmelting) + assert.Equal(t, int64(0), res.FoodSilo) + assert.Equal(t, int64(0), res.FusionPoweredProduction) + assert.Equal(t, int64(0), res.Skyscraper) + assert.Equal(t, int64(0), res.BiotechLab) + assert.Equal(t, int64(0), res.Metropolis) + assert.Equal(t, int64(0), res.PlanetaryShield) +} + +func TestExtractLfBuildingsRocktal(t *testing.T) { + pageHTMLBytes, _ := ioutil.ReadFile("../../../samples/v9.0.4/en/lifeform/lfbuildings_rocktal.html") + res, _ := NewExtractor().ExtractLfBuildings(pageHTMLBytes) + assert.Equal(t, int64(0), res.ResidentialSector) + assert.Equal(t, int64(0), res.BiosphereFarm) + assert.Equal(t, int64(0), res.ResearchCentre) + assert.Equal(t, int64(0), res.AcademyOfSciences) + assert.Equal(t, int64(0), res.NeuroCalibrationCentre) + assert.Equal(t, int64(0), res.HighEnergySmelting) + assert.Equal(t, int64(0), res.FoodSilo) + assert.Equal(t, int64(0), res.FusionPoweredProduction) + assert.Equal(t, int64(0), res.Skyscraper) + assert.Equal(t, int64(0), res.BiotechLab) + assert.Equal(t, int64(0), res.Metropolis) + assert.Equal(t, int64(0), res.PlanetaryShield) + assert.Equal(t, int64(2), res.MeditationEnclave) + assert.Equal(t, int64(1), res.CrystalFarm) +} diff --git a/pkg/extractor/v9/extracts.go b/pkg/extractor/v9/extracts.go index 5c9f727d..33754e9b 100644 --- a/pkg/extractor/v9/extracts.go +++ b/pkg/extractor/v9/extracts.go @@ -3,6 +3,7 @@ package v9 import ( "errors" "regexp" + "strconv" "strings" "time" @@ -15,7 +16,9 @@ import ( "github.com/alaingilbert/ogame/pkg/utils" ) -func ExtractConstructions(pageHTML []byte, clock clockwork.Clock) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64) { +func ExtractConstructions(pageHTML []byte, clock clockwork.Clock) (buildingID ogame.ID, buildingCountdown int64, + researchID ogame.ID, researchCountdown int64, + lfBuildingID ogame.ID, lfBuildingCountdown int64) { buildingCountdownMatch := regexp.MustCompile(`var restTimebuilding = (\d+) -`).FindSubmatch(pageHTML) if len(buildingCountdownMatch) > 0 { buildingCountdown = int64(utils.ToInt(buildingCountdownMatch[1])) - clock.Now().Unix() @@ -28,6 +31,12 @@ func ExtractConstructions(pageHTML []byte, clock clockwork.Clock) (buildingID og researchIDInt := utils.ToInt(regexp.MustCompile(`onclick="cancelresearch\((\d+),`).FindSubmatch(pageHTML)[1]) researchID = ogame.ID(researchIDInt) } + lfBuildingCountdownMatch := regexp.MustCompile(`var restTimelfbuilding = (\d+) -`).FindSubmatch(pageHTML) + if len(lfBuildingCountdownMatch) > 0 { + lfBuildingCountdown = int64(utils.ToInt(lfBuildingCountdownMatch[1])) - clock.Now().Unix() + lfBuildingIDInt := utils.ToInt(regexp.MustCompile(`onclick="cancellfbuilding\((\d+),`).FindSubmatch(pageHTML)[1]) + lfBuildingID = ogame.ID(lfBuildingIDInt) + } return } @@ -218,6 +227,8 @@ func extractResourcesDetailsFromFullPageFromDoc(doc *goquery.Document) ogame.Res 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", ""))) + populationDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(doc.Find("div#population_box").AttrOr("title", ""))) + foodDoc, _ := goquery.NewDocumentFromReader(strings.NewReader(doc.Find("div#food_box").AttrOr("title", ""))) out.Metal.Available = utils.ParseInt(metalDoc.Find("table tr").Eq(0).Find("td").Eq(0).Text()) out.Metal.StorageCapacity = utils.ParseInt(metalDoc.Find("table tr").Eq(1).Find("td").Eq(0).Text()) out.Metal.CurrentProduction = utils.ParseInt(metalDoc.Find("table tr").Eq(2).Find("td").Eq(0).Text()) @@ -233,6 +244,19 @@ func extractResourcesDetailsFromFullPageFromDoc(doc *goquery.Document) ogame.Res out.Darkmatter.Available = utils.ParseInt(darkmatterDoc.Find("table tr").Eq(0).Find("td").Eq(0).Text()) out.Darkmatter.Purchased = utils.ParseInt(darkmatterDoc.Find("table tr").Eq(1).Find("td").Eq(0).Text()) out.Darkmatter.Found = utils.ParseInt(darkmatterDoc.Find("table tr").Eq(2).Find("td").Eq(0).Text()) + out.Food.Available = utils.ParseInt(foodDoc.Find("table tr").Eq(0).Find("td").Eq(0).Text()) + out.Food.StorageCapacity = utils.ParseInt(foodDoc.Find("table tr").Eq(1).Find("td").Eq(0).Text()) + out.Food.Overproduction = utils.ParseInt(foodDoc.Find("table tr").Eq(2).Find("td").Eq(0).Text()) + out.Food.ConsumedIn = utils.ParseInt(foodDoc.Find("table tr").Eq(3).Find("td").Eq(0).Text()) + out.Food.TimeTillFoodRunsOut = utils.ParseInt(foodDoc.Find("table tr").Eq(4).Find("td").Eq(0).Text()) + out.Population.Available = utils.ParseInt(populationDoc.Find("table tr").Eq(0).Find("td").Eq(0).Text()) + out.Population.T2Lifeforms = utils.ParseInt(populationDoc.Find("table tr").Eq(1).Find("td").Eq(0).Text()) + out.Population.T3Lifeforms = utils.ParseInt(populationDoc.Find("table tr").Eq(2).Find("td").Eq(0).Text()) + out.Population.LivingSpace = utils.ParseInt(populationDoc.Find("table tr").Eq(3).Find("td").Eq(0).Text()) + out.Population.Satisfied = utils.ParseInt(populationDoc.Find("table tr").Eq(4).Find("td").Eq(0).Text()) + out.Population.Hungry, _ = strconv.ParseFloat(populationDoc.Find("table tr").Eq(5).Find("td").Eq(0).Text(), 64) + out.Population.GrowthRate, _ = strconv.ParseFloat(strings.TrimPrefix(populationDoc.Find("table tr").Eq(6).Find("td").Eq(0).Text(), "±"), 64) + out.Population.BunkerSpace = utils.ParseInt(populationDoc.Find("table tr").Eq(7).Find("td").Eq(0).Text()) return out } @@ -534,39 +558,60 @@ func extractEspionageReportFromDoc(doc *goquery.Document, location *time.Locatio return report, nil } -func extractResourceSettingsFromDoc(doc *goquery.Document) (ogame.ResourceSettings, string, error) { - bodyID := v6.ExtractBodyIDFromDoc(doc) - if bodyID == "overview" { - return ogame.ResourceSettings{}, "", ogame.ErrInvalidPlanetID - } - vals := make([]int64, 0) - doc.Find("option").Each(func(i int, s *goquery.Selection) { - _, selectedExists := s.Attr("selected") - if selectedExists { - a, _ := s.Attr("value") - val := utils.DoParseI64(a) - vals = append(vals, val) - } - }) - - if len(vals) != 8 { - return ogame.ResourceSettings{}, "", errors.New("failed to find all resource settings") - } - - res := ogame.ResourceSettings{} - res.MetalMine = vals[0] - res.CrystalMine = vals[1] - res.DeuteriumSynthesizer = vals[2] - res.SolarPlant = vals[3] - res.FusionReactor = vals[4] - res.SolarSatellite = vals[5] - res.Crawler = vals[6] - res.PlasmaTechnology = vals[7] - - token, exists := doc.Find("form input[name=token]").Attr("value") - if !exists { - return ogame.ResourceSettings{}, "", errors.New("unable to find token") - } +func GetNbr(doc *goquery.Document, name string) int64 { + val := utils.DoParseI64(doc.Find("span."+name+" span.level").First().AttrOr("data-value", "0")) + return val +} - return res, token, nil +func extractLfBuildingsFromDoc(doc *goquery.Document) (ogame.LfBuildings, error) { + res := ogame.LfBuildings{} + res.ResidentialSector = GetNbr(doc, "lifeformTech11101") + res.BiosphereFarm = GetNbr(doc, "lifeformTech11102") + res.ResearchCentre = GetNbr(doc, "lifeformTech11103") + res.AcademyOfSciences = GetNbr(doc, "lifeformTech11104") + res.NeuroCalibrationCentre = GetNbr(doc, "lifeformTech11105") + res.HighEnergySmelting = GetNbr(doc, "lifeformTech11106") + res.FoodSilo = GetNbr(doc, "lifeformTech11107") + res.FusionPoweredProduction = GetNbr(doc, "lifeformTech11108") + res.Skyscraper = GetNbr(doc, "lifeformTech11109") + res.BiotechLab = GetNbr(doc, "lifeformTech11110") + res.Metropolis = GetNbr(doc, "lifeformTech11111") + res.PlanetaryShield = GetNbr(doc, "lifeformTech11112") + res.MeditationEnclave = GetNbr(doc, "lifeformTech12101") + res.CrystalFarm = GetNbr(doc, "lifeformTech12102") + res.RuneTechnologium = GetNbr(doc, "lifeformTech12103") + res.RuneForge = GetNbr(doc, "lifeformTech12104") + res.Oriktorium = GetNbr(doc, "lifeformTech12105") + res.MagmaForge = GetNbr(doc, "lifeformTech12106") + res.DisruptionChamber = GetNbr(doc, "lifeformTech12107") + res.Megalith = GetNbr(doc, "lifeformTech12108") + res.CrystalRefinery = GetNbr(doc, "lifeformTech12109") + res.DeuteriumSynthesiser = GetNbr(doc, "lifeformTech12110") + res.MineralResearchCentre = GetNbr(doc, "lifeformTech12111") + res.MetalRecyclingPlant = GetNbr(doc, "lifeformTech12112") + res.AssemblyLine = GetNbr(doc, "lifeformTech13101") + res.FusionCellFactory = GetNbr(doc, "lifeformTech13102") + res.RoboticsResearchCentre = GetNbr(doc, "lifeformTech13103") + res.UpdateNetwork = GetNbr(doc, "lifeformTech12304") + res.QuantumComputerCentre = GetNbr(doc, "lifeformTech13105") + res.AutomatisedAssemblyCentre = GetNbr(doc, "lifeformTech13106") + res.HighPerformanceTransformer = GetNbr(doc, "lifeformTech13107") + res.MicrochipAssemblyLine = GetNbr(doc, "lifeformTech13108") + res.ProductionAssemblyHall = GetNbr(doc, "lifeformTech13109") + res.HighPerformanceSynthesiser = GetNbr(doc, "lifeformTech13110") + res.ChipMassProduction = GetNbr(doc, "lifeformTech13111") + res.NanoRepairBots = GetNbr(doc, "lifeformTech13112") + res.Sanctuary = GetNbr(doc, "lifeformTech14101") + res.AntimatterCondenser = GetNbr(doc, "lifeformTech14102") + res.VortexChamber = GetNbr(doc, "lifeformTech14103") + res.HallsOfRealisation = GetNbr(doc, "lifeformTech14104") + res.ForumOfTranscendence = GetNbr(doc, "lifeformTech14105") + res.AntimatterConvector = GetNbr(doc, "lifeformTech14106") + res.CloningLaboratory = GetNbr(doc, "lifeformTech14107") + res.ChrysalisAccelerator = GetNbr(doc, "lifeformTech14108") + res.BioModifier = GetNbr(doc, "lifeformTech14109") + res.PsionicModulator = GetNbr(doc, "lifeformTech14110") + res.ShipManufacturingHall = GetNbr(doc, "lifeformTech14111") + res.SupraRefractor = GetNbr(doc, "lifeformTech14112") + return res, nil } diff --git a/pkg/ogame/baseBuilding.go b/pkg/ogame/baseBuilding.go index 53f106b1..7bfde3ef 100644 --- a/pkg/ogame/baseBuilding.go +++ b/pkg/ogame/baseBuilding.go @@ -16,10 +16,11 @@ func (b BaseBuilding) DeconstructionPrice(level int64, techs IResearches) Resour return int64(math.Floor(float64(baseCost)*math.Pow(increaseFactor, float64(level-1))) * (1 - 0.04*float64(techs.GetIonTechnology()))) } return Resources{ - Metal: tmp(b.BaseCost.Metal, b.IncreaseFactor, level), - Crystal: tmp(b.BaseCost.Crystal, b.IncreaseFactor, level), - Deuterium: tmp(b.BaseCost.Deuterium, b.IncreaseFactor, level), - Energy: tmp(b.BaseCost.Energy, b.IncreaseFactor, level), + Metal: tmp(b.BaseCost.Metal, b.IncreaseFactor, level), + Crystal: tmp(b.BaseCost.Crystal, b.IncreaseFactor, level), + Deuterium: tmp(b.BaseCost.Deuterium, b.IncreaseFactor, level), + Energy: tmp(b.BaseCost.Energy, b.IncreaseFactor, level), + Population: tmp(b.BaseCost.Population, b.IncreaseFactor, level), } } diff --git a/pkg/ogame/id.go b/pkg/ogame/id.go index b0f441f4..b29bacd1 100644 --- a/pkg/ogame/id.go +++ b/pkg/ogame/id.go @@ -164,7 +164,7 @@ func (o ID) String() string { // IsValid returns either or not the id is valid func (o ID) IsValid() bool { - return o.IsDefense() || o.IsShip() || o.IsTech() || o.IsBuilding() + return o.IsDefense() || o.IsShip() || o.IsTech() || o.IsBuilding() || o.IsLfBuilding() } // IsFacility returns either or not the id is a facility diff --git a/pkg/ogame/lfBuildings.go b/pkg/ogame/lfBuildings.go index 0f2fb632..d5871839 100644 --- a/pkg/ogame/lfBuildings.go +++ b/pkg/ogame/lfBuildings.go @@ -9,18 +9,54 @@ type LazyLfBuildings func() LfBuildings // LfBuildings lifeform buildings type LfBuildings struct { - ResidentialSector int64 // 11101 - BiosphereFarm int64 // 11102 - ResearchCentre int64 // 11103 - AcademyOfSciences int64 // 11104 - NeuroCalibrationCentre int64 // 11105 - HighEnergySmelting int64 // 11106 - FoodSilo int64 // 11107 - FusionPoweredProduction int64 // 11108 - Skyscraper int64 // 11109 - BiotechLab int64 // 11110 - Metropolis int64 // 11111 - PlanetaryShield int64 // 11112 + ResidentialSector int64 // 11101 // Lifeform (humans) + BiosphereFarm int64 // 11102 + ResearchCentre int64 // 11103 + AcademyOfSciences int64 // 11104 + NeuroCalibrationCentre int64 // 11105 + HighEnergySmelting int64 // 11106 + FoodSilo int64 // 11107 + FusionPoweredProduction int64 // 11108 + Skyscraper int64 // 11109 + BiotechLab int64 // 11110 + Metropolis int64 // 11111 + PlanetaryShield int64 // 11112 + MeditationEnclave int64 // 12101 // Lifeform (rocktal) + CrystalFarm int64 // 12102 + RuneTechnologium int64 // 12103 + RuneForge int64 // 12104 + Oriktorium int64 // 12105 + MagmaForge int64 // 12106 + DisruptionChamber int64 // 12107 + Megalith int64 // 12108 + CrystalRefinery int64 // 12109 + DeuteriumSynthesiser int64 // 12110 + MineralResearchCentre int64 // 12111 + MetalRecyclingPlant int64 // 12112 + AssemblyLine int64 // 13101 // Lifeform (mechas) + FusionCellFactory int64 // 13102 + RoboticsResearchCentre int64 // 13103 + UpdateNetwork int64 // 12304 + QuantumComputerCentre int64 // 13105 + AutomatisedAssemblyCentre int64 // 13106 + HighPerformanceTransformer int64 // 13107 + MicrochipAssemblyLine int64 // 13108 + ProductionAssemblyHall int64 // 13109 + HighPerformanceSynthesiser int64 // 13110 + ChipMassProduction int64 // 13111 + NanoRepairBots int64 // 13112 + Sanctuary int64 // 14101 // Lifeform (kaelesh) + AntimatterCondenser int64 // 14102 + VortexChamber int64 // 14103 + HallsOfRealisation int64 // 14104 + ForumOfTranscendence int64 // 14105 + AntimatterConvector int64 // 14106 + CloningLaboratory int64 // 14107 + ChrysalisAccelerator int64 // 14108 + BioModifier int64 // 14109 + PsionicModulator int64 // 14110 + ShipManufacturingHall int64 // 14111 + SupraRefractor int64 // 14112 } // Lazy returns a function that return self @@ -55,6 +91,78 @@ func (b LfBuildings) ByID(id ID) int64 { return b.Metropolis case PlanetaryShieldID: return b.PlanetaryShield + case MeditationEnclaveID: + return b.MeditationEnclave + case CrystalFarmID: + return b.CrystalFarm + case RuneTechnologiumID: + return b.RuneTechnologium + case RuneForgeID: + return b.RuneForge + case OriktoriumID: + return b.Oriktorium + case MagmaForgeID: + return b.MagmaForge + case DisruptionChamberID: + return b.DisruptionChamber + case MegalithID: + return b.Megalith + case CrystalRefineryID: + return b.CrystalRefinery + case DeuteriumSynthesiserID: + return b.DeuteriumSynthesiser + case MineralResearchCentreID: + return b.MineralResearchCentre + case MetalRecyclingPlantID: + return b.MetalRecyclingPlant + case AssemblyLineID: + return b.AssemblyLine + case FusionCellFactoryID: + return b.FusionCellFactory + case RoboticsResearchCentreID: + return b.RoboticsResearchCentre + case UpdateNetworkID: + return b.UpdateNetwork + case QuantumComputerCentreID: + return b.QuantumComputerCentre + case AutomatisedAssemblyCentreID: + return b.AutomatisedAssemblyCentre + case HighPerformanceTransformerID: + return b.HighPerformanceTransformer + case MicrochipAssemblyLineID: + return b.MicrochipAssemblyLine + case ProductionAssemblyHallID: + return b.ProductionAssemblyHall + case HighPerformanceSynthesiserID: + return b.HighPerformanceSynthesiser + case ChipMassProductionID: + return b.ChipMassProduction + case NanoRepairBotsID: + return b.NanoRepairBots + case SanctuaryID: + return b.Sanctuary + case AntimatterCondenserID: + return b.AntimatterCondenser + case VortexChamberID: + return b.VortexChamber + case HallsOfRealisationID: + return b.HallsOfRealisation + case ForumOfTranscendenceID: + return b.ForumOfTranscendence + case AntimatterConvectorID: + return b.AntimatterConvector + case CloningLaboratoryID: + return b.CloningLaboratory + case ChrysalisAcceleratorID: + return b.ChrysalisAccelerator + case BioModifierID: + return b.BioModifier + case PsionicModulatorID: + return b.PsionicModulator + case ShipManufacturingHallID: + return b.ShipManufacturingHall + case SupraRefractorID: + return b.SupraRefractor } return 0 } @@ -62,7 +170,8 @@ func (b LfBuildings) ByID(id ID) int64 { // BaseLfBuilding base struct for Lifeform buildings type BaseLfBuilding struct { BaseBuilding - energyIncreaseFactor float64 + energyIncreaseFactor float64 + populationIncreaseFactor float64 } // GetPrice returns the price to build the given level @@ -70,14 +179,19 @@ func (b BaseLfBuilding) GetPrice(level int64) Resources { tmp := func(baseCost int64, increaseFactor float64, level int64) int64 { return int64(float64(baseCost) * math.Pow(increaseFactor, float64(level-1)) * float64(level)) } + tmp2 := func(baseCost int64, increaseFactor float64, level int64) int64 { + return int64(float64(baseCost) * math.Pow(increaseFactor, float64(level-1))) + } return Resources{ - Metal: tmp(b.BaseCost.Metal, b.IncreaseFactor, level), - Crystal: tmp(b.BaseCost.Crystal, b.IncreaseFactor, level), - Deuterium: tmp(b.BaseCost.Deuterium, b.IncreaseFactor, level), - Energy: tmp(b.BaseCost.Energy, b.energyIncreaseFactor, level), + Metal: tmp(b.BaseCost.Metal, b.IncreaseFactor, level), + Crystal: tmp(b.BaseCost.Crystal, b.IncreaseFactor, level), + Deuterium: tmp(b.BaseCost.Deuterium, b.IncreaseFactor, level), + Energy: tmp(b.BaseCost.Energy, b.energyIncreaseFactor, level), + Population: tmp2(b.BaseCost.Population, b.populationIncreaseFactor, level), } } +// Humans type residentialSector struct { BaseLfBuilding } @@ -86,7 +200,7 @@ func newResidentialSector() *residentialSector { b := new(residentialSector) b.Name = "residential sector" b.ID = ResidentialSectorID - b.IncreaseFactor = 1.2 + b.IncreaseFactor = 1.20 b.BaseCost = Resources{Metal: 7, Crystal: 2} b.Requirements = map[ID]int64{} return b @@ -129,8 +243,9 @@ func newAcademyOfSciences() *academyOfSciences { b := new(academyOfSciences) b.Name = "academy of sciences" b.ID = AcademyOfSciencesID - b.IncreaseFactor = 1 // TODO - b.BaseCost = Resources{Metal: 5000, Crystal: 3200, Deuterium: 1500, Lifeform: 20000000} + b.IncreaseFactor = 1.70 + b.populationIncreaseFactor = 1.10 + b.BaseCost = Resources{Metal: 5000, Crystal: 3200, Deuterium: 1500, Population: 20000000} b.Requirements = map[ID]int64{ResidentialSectorID: 40} return b } @@ -143,8 +258,9 @@ func newNeuroCalibrationCentre() *neuroCalibrationCentre { b := new(neuroCalibrationCentre) b.Name = "neuro calibration centre" b.ID = NeuroCalibrationCentreID - b.IncreaseFactor = 1 // TODO - b.BaseCost = Resources{Metal: 50000, Crystal: 40000, Deuterium: 50000, Lifeform: 100000000} + b.IncreaseFactor = 1.70 + b.populationIncreaseFactor = 1.10 + b.BaseCost = Resources{Metal: 50000, Crystal: 40000, Deuterium: 50000, Population: 100000000} b.Requirements = map[ID]int64{ResidentialSectorID: 40, AcademyOfSciencesID: 1, FusionPoweredProductionID: 1, SkyscraperID: 5} return b } @@ -157,7 +273,7 @@ func newHighEnergySmelting() *highEnergySmelting { b := new(highEnergySmelting) b.Name = "high energy smelting" b.ID = HighEnergySmeltingID - b.IncreaseFactor = 1 // TODO + b.IncreaseFactor = 1.50 b.BaseCost = Resources{Metal: 7500, Crystal: 5000, Deuterium: 3000} b.Requirements = map[ID]int64{ResidentialSectorID: 12, BiosphereFarmID: 13, ResearchCentreID: 5} return b @@ -171,7 +287,7 @@ func newFoodSilo() *foodSilo { b := new(foodSilo) b.Name = "food silo" b.ID = FoodSiloID - b.IncreaseFactor = 1 // TODO + b.IncreaseFactor = 1.09 b.BaseCost = Resources{Metal: 25000, Crystal: 13000, Deuterium: 7000} b.Requirements = map[ID]int64{ResidentialSectorID: 12, BiosphereFarmID: 13, ResearchCentreID: 5, HighEnergySmeltingID: 3} return b @@ -185,7 +301,7 @@ func newFusionPoweredProduction() *fusionPoweredProduction { b := new(fusionPoweredProduction) b.Name = "fusion powered production" b.ID = FusionPoweredProductionID - b.IncreaseFactor = 1 // TODO + b.IncreaseFactor = 1.50 b.BaseCost = Resources{Metal: 50000, Crystal: 25000, Deuterium: 25000} b.Requirements = map[ID]int64{ResidentialSectorID: 40, AcademyOfSciencesID: 1} return b @@ -199,7 +315,7 @@ func newSkyscraper() *skyscraper { b := new(skyscraper) b.Name = "skyscraper" b.ID = SkyscraperID - b.IncreaseFactor = 1 // TODO + b.IncreaseFactor = 1.09 b.BaseCost = Resources{Metal: 75000, Crystal: 20000, Deuterium: 25000} b.Requirements = map[ID]int64{ResidentialSectorID: 40, AcademyOfSciencesID: 1, FusionPoweredProductionID: 1} return b @@ -213,7 +329,7 @@ func newBiotechLab() *biotechLab { b := new(biotechLab) b.Name = "biotech lab" b.ID = BiotechLabID - b.IncreaseFactor = 1 // TODO + b.IncreaseFactor = 1.12 b.BaseCost = Resources{Metal: 150000, Crystal: 30000, Deuterium: 15000} b.Requirements = map[ID]int64{ResidentialSectorID: 40, AcademyOfSciencesID: 1, FusionPoweredProductionID: 2} return b @@ -227,7 +343,7 @@ func newMetropolis() *metropolis { b := new(metropolis) b.Name = "metropolis" b.ID = MetropolisID - b.IncreaseFactor = 1 // TODO + b.IncreaseFactor = 1.12 b.BaseCost = Resources{Metal: 80000, Crystal: 35000, Deuterium: 60000} b.Requirements = map[ID]int64{ResidentialSectorID: 40, AcademyOfSciencesID: 1, FusionPoweredProductionID: 1, SkyscraperID: 5, NeuroCalibrationCentreID: 1} return b @@ -241,7 +357,7 @@ func newPlanetaryShield() *planetaryShield { b := new(planetaryShield) b.Name = "planetary shield" b.ID = PlanetaryShieldID - b.IncreaseFactor = 1 // TODO + b.IncreaseFactor = 1.20 b.BaseCost = Resources{Metal: 250000, Crystal: 125000, Deuterium: 125000} b.Requirements = map[ID]int64{ ResidentialSectorID: 40, @@ -261,3 +377,519 @@ func newPlanetaryShield() *planetaryShield { type BaseLfTechnology struct { BaseLevelable } + +// Rocktal +type meditationEnclave struct { + BaseLfBuilding +} + +func newMeditationEnclave() *meditationEnclave { + b := new(meditationEnclave) + b.Name = "meditation enclave" + b.ID = MeditationEnclaveID + b.IncreaseFactor = 1.20 + b.BaseCost = Resources{Metal: 9, Crystal: 3} + b.Requirements = map[ID]int64{} + return b +} + +type crystalFarm struct { + BaseLfBuilding +} + +func newCrystalFarm() *crystalFarm { + b := new(crystalFarm) + b.Name = "crystal farm" + b.ID = CrystalFarmID + b.IncreaseFactor = 1.20 + b.energyIncreaseFactor = 1.03 + b.BaseCost = Resources{Metal: 7, Crystal: 2, Energy: 10} + b.Requirements = map[ID]int64{} + return b +} + +type runeTechnologium struct { + BaseLfBuilding +} + +func newRuneTechnologium() *runeTechnologium { + b := new(runeTechnologium) + b.Name = "rune technologium" + b.ID = RuneTechnologiumID + b.IncreaseFactor = 1.30 + b.BaseCost = Resources{Metal: 40000, Crystal: 10000, Deuterium: 15000} + b.Requirements = map[ID]int64{MeditationEnclaveID: 21, CrystalFarmID: 22} + return b +} + +type runeForge struct { + BaseLfBuilding +} + +func newRuneForge() *runeForge { + b := new(runeForge) + b.Name = "rune forge" + b.ID = RuneForgeID + b.IncreaseFactor = 1.70 + b.populationIncreaseFactor = 1.14 + b.BaseCost = Resources{Metal: 5000, Crystal: 3800, Deuterium: 1000, Population: 16000000} + b.Requirements = map[ID]int64{MeditationEnclaveID: 41} + return b +} + +type oriktorium struct { + BaseLfBuilding +} + +func newOriktorium() *oriktorium { + b := new(oriktorium) + b.Name = "oriktorium" + b.ID = OriktoriumID + b.IncreaseFactor = 1.70 + b.populationIncreaseFactor = 1.65 + b.BaseCost = Resources{Metal: 50000, Crystal: 40000, Deuterium: 50000, Population: 90000000} + b.Requirements = map[ID]int64{MeditationEnclaveID: 41, RuneForgeID: 1, MegalithID: 1, CrystalRefineryID: 5} + return b +} + +type magmaForge struct { + BaseLfBuilding +} + +func newMagmaForge() *magmaForge { + b := new(magmaForge) + b.Name = "magma forge" + b.ID = MagmaForgeID + b.IncreaseFactor = 1.40 + b.BaseCost = Resources{Metal: 10000, Crystal: 8000, Deuterium: 1000} + b.Requirements = map[ID]int64{MeditationEnclaveID: 21, CrystalFarmID: 22, RuneTechnologiumID: 5} + return b +} + +type disruptionChamber struct { + BaseLfBuilding +} + +func newDisruptionChamber() *disruptionChamber { + b := new(disruptionChamber) + b.Name = "disruption chamber" + b.ID = DisruptionChamberID + b.IncreaseFactor = 1.20 + b.BaseCost = Resources{Metal: 20000, Crystal: 15000, Deuterium: 10000} + b.Requirements = map[ID]int64{MeditationEnclaveID: 21, CrystalFarmID: 22, RuneTechnologiumID: 5, MagmaForgeID: 3} + return b +} + +type megalith struct { + BaseLfBuilding +} + +func newMegalith() *megalith { + b := new(megalith) + b.Name = "megalith" + b.ID = MegalithID + b.IncreaseFactor = 1.50 + b.BaseCost = Resources{Metal: 50000, Crystal: 35000, Deuterium: 15000} + b.Requirements = map[ID]int64{MeditationEnclaveID: 41, RuneForgeID: 1} + return b +} + +type crystalRefinery struct { + BaseLfBuilding +} + +func newCrystalRefinery() *crystalRefinery { + b := new(crystalRefinery) + b.Name = "crystal refinery" + b.ID = CrystalRefineryID + b.IncreaseFactor = 1.40 + b.BaseCost = Resources{Metal: 85000, Crystal: 44000, Deuterium: 25000} + b.Requirements = map[ID]int64{MeditationEnclaveID: 41, RuneForgeID: 1, MegalithID: 1} + return b +} + +type deuteriumSynthesiser struct { + BaseLfBuilding +} + +func newDeuteriumSynthesiser() *deuteriumSynthesiser { + b := new(deuteriumSynthesiser) + b.Name = "deuterium synthesiser" + b.ID = DeuteriumSynthesiserID + b.IncreaseFactor = 1.40 + b.BaseCost = Resources{Metal: 120000, Crystal: 50000, Deuterium: 20000} + b.Requirements = map[ID]int64{MeditationEnclaveID: 41, RuneForgeID: 1, MegalithID: 2} + return b +} + +type mineralResearchCentre struct { + BaseLfBuilding +} + +func newMineralResearchCentre() *mineralResearchCentre { + b := new(mineralResearchCentre) + b.Name = "mineral research centre" + b.ID = MineralResearchCentreID + b.IncreaseFactor = 1.80 + b.BaseCost = Resources{Metal: 250000, Crystal: 150000, Deuterium: 100000} + b.Requirements = map[ID]int64{MeditationEnclaveID: 41, RuneForgeID: 1, MegalithID: 1, CrystalRefineryID: 6, OriktoriumID: 1} + return b +} + +type metalRecyclingPlant struct { + BaseLfBuilding +} + +func newMetalRecyclingPlant() *metalRecyclingPlant { + b := new(metalRecyclingPlant) + b.Name = "metal recycling plant" + b.ID = MetalRecyclingPlantID + b.IncreaseFactor = 1.50 + b.BaseCost = Resources{Metal: 250000, Crystal: 125000, Deuterium: 125000} + b.Requirements = map[ID]int64{MeditationEnclaveID: 41, CrystalFarmID: 22, RuneForgeID: 1, MegalithID: 5, CrystalRefineryID: 6, OriktoriumID: 5, RuneTechnologiumID: 5, MagmaForgeID: 3, DisruptionChamberID: 4, MineralResearchCentreID: 5} + return b +} + +// Mechas +type assemblyLine struct { + BaseLfBuilding +} + +func newAssemblyLine() *assemblyLine { + b := new(assemblyLine) + b.Name = "assembly line" + b.ID = AssemblyLineID + b.IncreaseFactor = 1.21 + b.BaseCost = Resources{Metal: 6, Crystal: 2} + b.Requirements = map[ID]int64{} + return b +} + +type fusionCellFactory struct { + BaseLfBuilding +} + +func newFusionCellFactory() *fusionCellFactory { + b := new(fusionCellFactory) + b.Name = "fusion cell factory" + b.ID = FusionCellFactoryID + b.IncreaseFactor = 1.18 + b.energyIncreaseFactor = 1.02 + b.BaseCost = Resources{Metal: 5, Crystal: 2, Energy: 8} + b.Requirements = map[ID]int64{} + return b +} + +type roboticsResearchCentre struct { + BaseLfBuilding +} + +func newRoboticsResearchCentre() *roboticsResearchCentre { + b := new(roboticsResearchCentre) + b.Name = "robotics research centre" + b.ID = RoboticsResearchCentreID + b.IncreaseFactor = 1.30 + b.BaseCost = Resources{Metal: 30000, Crystal: 20000, Deuterium: 10000} + b.Requirements = map[ID]int64{AssemblyLineID: 20, FusionCellFactoryID: 17} + return b +} + +type updateNetwork struct { + BaseLfBuilding +} + +func newUpdateNetwork() *updateNetwork { + b := new(updateNetwork) + b.Name = "update network" + b.ID = UpdateNetworkID + b.IncreaseFactor = 1.80 + b.populationIncreaseFactor = 1.10 + b.BaseCost = Resources{Metal: 5000, Crystal: 3800, Deuterium: 1000, Population: 40000000} + b.Requirements = map[ID]int64{AssemblyLineID: 41} + return b +} + +type quantumComputerCentre struct { + BaseLfBuilding +} + +func newQuantumComputerCentre() *quantumComputerCentre { + b := new(quantumComputerCentre) + b.Name = "quantum computer centre" + b.ID = QuantumComputerCentreID + b.IncreaseFactor = 1.80 + b.populationIncreaseFactor = 1.10 + b.BaseCost = Resources{Metal: 50000, Crystal: 40000, Deuterium: 50000, Population: 130000000} + b.Requirements = map[ID]int64{AssemblyLineID: 41, UpdateNetworkID: 1, MicrochipAssemblyLineID: 1, ProductionAssemblyHallID: 5} + return b +} + +type automatisedAssemblyCentre struct { + BaseLfBuilding +} + +func newAutomatisedAssemblyCentre() *automatisedAssemblyCentre { + b := new(automatisedAssemblyCentre) + b.Name = "automatised assembly centre" + b.ID = AutomatisedAssemblyCentreID + b.IncreaseFactor = 1.30 + b.BaseCost = Resources{Metal: 7500, Crystal: 7000, Deuterium: 1000} + b.Requirements = map[ID]int64{AssemblyLineID: 17, FusionCellFactoryID: 20, RoboticsResearchCentreID: 5} + return b +} + +type highPerformanceTransformer struct { + BaseLfBuilding +} + +func newHighPerformanceTransformer() *highPerformanceTransformer { + b := new(highPerformanceTransformer) + b.Name = "high performance transformer" + b.ID = HighPerformanceTransformerID + b.IncreaseFactor = 1.50 + b.BaseCost = Resources{Metal: 35000, Crystal: 15000, Deuterium: 10000} + b.Requirements = map[ID]int64{AssemblyLineID: 17, FusionCellFactoryID: 20, RoboticsResearchCentreID: 5, AutomatisedAssemblyCentreID: 3} + return b +} + +type microchipAssemblyLine struct { + BaseLfBuilding +} + +func newMicrochipAssemblyLine() *microchipAssemblyLine { + b := new(microchipAssemblyLine) + b.Name = "microchip assembly line" + b.ID = MicrochipAssemblyLineID + b.IncreaseFactor = 1.07 + b.BaseCost = Resources{Metal: 50000, Crystal: 20000, Deuterium: 30000} + b.Requirements = map[ID]int64{AssemblyLineID: 41, UpdateNetworkID: 1} + return b +} + +type productionAssemblyHall struct { + BaseLfBuilding +} + +func newProductionAssemblyHall() *productionAssemblyHall { + b := new(productionAssemblyHall) + b.Name = "production assembly hall" + b.ID = ProductionAssemblyHallID + b.IncreaseFactor = 1.14 + b.BaseCost = Resources{Metal: 100000, Crystal: 10000, Deuterium: 3000} + b.Requirements = map[ID]int64{AssemblyLineID: 41, UpdateNetworkID: 1, MicrochipAssemblyLineID: 1} + return b +} + +type highPerformanceSynthesiser struct { + BaseLfBuilding +} + +func newHighPerformanceSynthesiser() *highPerformanceSynthesiser { + b := new(highPerformanceSynthesiser) + b.Name = "high performance synthesiser" + b.ID = HighPerformanceSynthesiserID + b.IncreaseFactor = 1.50 + b.BaseCost = Resources{Metal: 100000, Crystal: 40000, Deuterium: 20000} + b.Requirements = map[ID]int64{AssemblyLineID: 41, UpdateNetworkID: 1, MicrochipAssemblyLineID: 2} + return b +} + +type chipMassProduction struct { + BaseLfBuilding +} + +func newChipMassProduction() *chipMassProduction { + b := new(chipMassProduction) + b.Name = "chip mass production" + b.ID = ChipMassProductionID + b.IncreaseFactor = 1.50 + b.BaseCost = Resources{Metal: 55000, Crystal: 50000, Deuterium: 30000} + b.Requirements = map[ID]int64{AssemblyLineID: 41, UpdateNetworkID: 1, MicrochipAssemblyLineID: 1, ProductionAssemblyHallID: 6, QuantumComputerCentreID: 1} + return b +} + +type nanoRepairBots struct { + BaseLfBuilding +} + +func newNanoRepairBots() *nanoRepairBots { + b := new(nanoRepairBots) + b.Name = "nano repair bots" + b.ID = NanoRepairBotsID + b.IncreaseFactor = 1.40 + b.BaseCost = Resources{Metal: 250000, Crystal: 125000, Deuterium: 125000} + b.Requirements = map[ID]int64{AssemblyLineID: 41, FusionCellFactoryID: 20, MicrochipAssemblyLineID: 5, RoboticsResearchCentreID: 5, HighPerformanceTransformerID: 4, ProductionAssemblyHallID: 6, QuantumComputerCentreID: 5, ChipMassProductionID: 11} + return b +} + +// Kaelesh +type sanctuary struct { + BaseLfBuilding +} + +func newSanctuary() *sanctuary { + b := new(sanctuary) + b.Name = "sanctuary" + b.ID = SanctuaryID + b.IncreaseFactor = 1.21 + b.BaseCost = Resources{Metal: 4, Crystal: 3} + b.Requirements = map[ID]int64{} + return b +} + +type antimatterCondenser struct { + BaseLfBuilding +} + +func newAntimatterCondenser() *antimatterCondenser { + b := new(antimatterCondenser) + b.Name = "antimatter condenser" + b.ID = AntimatterCondenserID + b.IncreaseFactor = 1.21 + b.energyIncreaseFactor = 1.02 + b.BaseCost = Resources{Metal: 6, Crystal: 3, Energy: 9} + b.Requirements = map[ID]int64{} + return b +} + +type vortexChamber struct { + BaseLfBuilding +} + +func newVortexChamber() *vortexChamber { + b := new(vortexChamber) + b.Name = "vortex chamber" + b.ID = VortexChamberID + b.IncreaseFactor = 1.30 + b.BaseCost = Resources{Metal: 20000, Crystal: 20000, Deuterium: 30000} + b.Requirements = map[ID]int64{SanctuaryID: 20, AntimatterCondenserID: 21} + return b +} + +type hallsOfRealisation struct { + BaseLfBuilding +} + +func newHallsOfRealisation() *hallsOfRealisation { + b := new(hallsOfRealisation) + b.Name = "halls of realisation" + b.ID = HallsOfRealisationID + b.IncreaseFactor = 1.80 + b.populationIncreaseFactor = 1.10 + b.BaseCost = Resources{Metal: 7500, Crystal: 5000, Deuterium: 800, Population: 30000000} + b.Requirements = map[ID]int64{SanctuaryID: 42} + return b +} + +type forumOfTranscendence struct { + BaseLfBuilding +} + +func newForumOfTranscendence() *forumOfTranscendence { + b := new(forumOfTranscendence) + b.Name = "forum of transcendence" + b.ID = ForumOfTranscendenceID + b.IncreaseFactor = 1.80 + b.populationIncreaseFactor = 1.10 + b.BaseCost = Resources{Metal: 60000, Crystal: 30000, Deuterium: 50000, Population: 100000000} + b.Requirements = map[ID]int64{SanctuaryID: 42, HallsOfRealisationID: 1, ChrysalisAcceleratorID: 1, BioModifierID: 5} + return b +} + +type antimatterConvector struct { + BaseLfBuilding +} + +func newAntimatterConvector() *antimatterConvector { + b := new(antimatterConvector) + b.Name = "antimatter convector" + b.ID = AntimatterConvectorID + b.IncreaseFactor = 1.25 + b.BaseCost = Resources{Metal: 8500, Crystal: 5000, Deuterium: 3000} + b.Requirements = map[ID]int64{SanctuaryID: 20, AntimatterCondenserID: 21, VortexChamberID: 5} + return b +} + +type cloningLaboratory struct { + BaseLfBuilding +} + +func newCloningLaboratory() *cloningLaboratory { + b := new(cloningLaboratory) + b.Name = "cloning laboratory" + b.ID = CloningLaboratoryID + b.IncreaseFactor = 1.20 + b.BaseCost = Resources{Metal: 15000, Crystal: 15000, Deuterium: 20000} + b.Requirements = map[ID]int64{SanctuaryID: 20, AntimatterCondenserID: 21, VortexChamberID: 5, AntimatterConvectorID: 3} + return b +} + +type chrysalisAccelerator struct { + BaseLfBuilding +} + +func newChrysalisAccelerator() *chrysalisAccelerator { + b := new(chrysalisAccelerator) + b.Name = "chrysalis accelerator" + b.ID = ChrysalisAcceleratorID + b.IncreaseFactor = 1.05 + b.BaseCost = Resources{Metal: 75000, Crystal: 25000, Deuterium: 30000} + b.Requirements = map[ID]int64{SanctuaryID: 42, HallsOfRealisationID: 1} + return b +} + +type bioModifier struct { + BaseLfBuilding +} + +func newBioModifier() *bioModifier { + b := new(bioModifier) + b.Name = "bio modifier" + b.ID = BioModifierID + b.IncreaseFactor = 1.20 + b.BaseCost = Resources{Metal: 87500, Crystal: 25000, Deuterium: 30000} + b.Requirements = map[ID]int64{SanctuaryID: 42, HallsOfRealisationID: 1, ChrysalisAcceleratorID: 1} + return b +} + +type psionicModulator struct { + BaseLfBuilding +} + +func newPsionicModulator() *psionicModulator { + b := new(psionicModulator) + b.Name = "psionic modulator" + b.ID = PsionicModulatorID + b.IncreaseFactor = 1.50 + b.BaseCost = Resources{Metal: 150000, Crystal: 30000, Deuterium: 30000} + b.Requirements = map[ID]int64{SanctuaryID: 42, HallsOfRealisationID: 1, ChrysalisAcceleratorID: 2} + return b +} + +type shipManufacturingHall struct { + BaseLfBuilding +} + +func newShipManufacturingHall() *shipManufacturingHall { + b := new(shipManufacturingHall) + b.Name = "ship manufacturing hall" + b.ID = ShipManufacturingHallID + b.IncreaseFactor = 1.20 + b.BaseCost = Resources{Metal: 75000, Crystal: 50000, Deuterium: 55000} + b.Requirements = map[ID]int64{SanctuaryID: 42, HallsOfRealisationID: 1, ChrysalisAcceleratorID: 1, BioModifierID: 6, ForumOfTranscendenceID: 1} + return b +} + +type supraRefractor struct { + BaseLfBuilding +} + +func newSupraRefractor() *supraRefractor { + b := new(supraRefractor) + b.Name = "suprarefractor" + b.ID = SupraRefractorID + b.IncreaseFactor = 1.40 + b.BaseCost = Resources{Metal: 500000, Crystal: 250000, Deuterium: 250000} + b.Requirements = map[ID]int64{SanctuaryID: 42, AntimatterCondenserID: 21, VortexChamberID: 5, AntimatterConvectorID: 3, CloningLaboratoryID: 4, HallsOfRealisationID: 1, ChrysalisAcceleratorID: 5, BioModifierID: 6, ForumOfTranscendenceID: 5, ShipManufacturingHallID: 5} + return b +} diff --git a/pkg/ogame/objs.go b/pkg/ogame/objs.go index 206a7329..38a2d21d 100644 --- a/pkg/ogame/objs.go +++ b/pkg/ogame/objs.go @@ -67,7 +67,7 @@ var ( PlasmaTechnology = register[*plasmaTechnology](newPlasmaTechnology) ShieldingTechnology = register[*shieldingTechnology](newShieldingTechnology) WeaponsTechnology = register[*weaponsTechnology](newWeaponsTechnology) - ResidentialSector = register[*residentialSector](newResidentialSector) // Lifeform + ResidentialSector = register[*residentialSector](newResidentialSector) // Humans BiosphereFarm = register[*biosphereFarm](newBiosphereFarm) ResearchCentre = register[*researchCentre](newResearchCentre) AcademyOfSciences = register[*academyOfSciences](newAcademyOfSciences) @@ -79,6 +79,42 @@ var ( BiotechLab = register[*biotechLab](newBiotechLab) Metropolis = register[*metropolis](newMetropolis) PlanetaryShield = register[*planetaryShield](newPlanetaryShield) + MeditationEnclave = register[*meditationEnclave](newMeditationEnclave) //Rocktal + CrystalFarm = register[*crystalFarm](newCrystalFarm) + RuneTechnologium = register[*runeTechnologium](newRuneTechnologium) + RuneForge = register[*runeForge](newRuneForge) + Oriktorium = register[*oriktorium](newOriktorium) + MagmaForge = register[*magmaForge](newMagmaForge) + DisruptionChamber = register[*disruptionChamber](newDisruptionChamber) + Megalith = register[*megalith](newMegalith) + CrystalRefinery = register[*crystalRefinery](newCrystalRefinery) + DeuteriumSynthesiser = register[*deuteriumSynthesiser](newDeuteriumSynthesiser) + MineralResearchCentre = register[*mineralResearchCentre](newMineralResearchCentre) + MetalRecyclingPlant = register[*metalRecyclingPlant](newMetalRecyclingPlant) + AssemblyLine = register[*assemblyLine](newAssemblyLine) //Mechas + FusionCellFactory = register[*fusionCellFactory](newFusionCellFactory) + RoboticsResearchCentre = register[*roboticsResearchCentre](newRoboticsResearchCentre) + UpdateNetwork = register[*updateNetwork](newUpdateNetwork) + QuantumComputerCentre = register[*quantumComputerCentre](newQuantumComputerCentre) + AutomatisedAssemblyCentre = register[*automatisedAssemblyCentre](newAutomatisedAssemblyCentre) + HighPerformanceTransformer = register[*highPerformanceTransformer](newHighPerformanceTransformer) + MicrochipAssemblyLine = register[*microchipAssemblyLine](newMicrochipAssemblyLine) + ProductionAssemblyHall = register[*productionAssemblyHall](newProductionAssemblyHall) + HighPerformanceSynthesiser = register[*highPerformanceSynthesiser](newHighPerformanceSynthesiser) + ChipMassProduction = register[*chipMassProduction](newChipMassProduction) + NanoRepairBots = register[*nanoRepairBots](newNanoRepairBots) + Sanctuary = register[*sanctuary](newSanctuary) //Kaelesh + AntimatterCondenser = register[*antimatterCondenser](newAntimatterCondenser) + VortexChamber = register[*vortexChamber](newVortexChamber) + HallsOfRealisation = register[*hallsOfRealisation](newHallsOfRealisation) + ForumOfTranscendence = register[*forumOfTranscendence](newForumOfTranscendence) + AntimatterConvector = register[*antimatterConvector](newAntimatterConvector) + CloningLaboratory = register[*cloningLaboratory](newCloningLaboratory) + ChrysalisAccelerator = register[*chrysalisAccelerator](newChrysalisAccelerator) + BioModifier = register[*bioModifier](newBioModifier) + PsionicModulator = register[*psionicModulator](newPsionicModulator) + ShipManufacturingHall = register[*shipManufacturingHall](newShipManufacturingHall) + SupraRefractor = register[*supraRefractor](newSupraRefractor) ) type ObjsStruct struct{ m map[ID]BaseOgameObj } diff --git a/pkg/ogame/resourceSettings.go b/pkg/ogame/resourceSettings.go index 37e7941d..b5be0868 100644 --- a/pkg/ogame/resourceSettings.go +++ b/pkg/ogame/resourceSettings.go @@ -11,7 +11,6 @@ type ResourceSettings struct { FusionReactor int64 SolarSatellite int64 Crawler int64 - PlasmaTechnology int64 } func (r ResourceSettings) String() string { @@ -22,6 +21,5 @@ func (r ResourceSettings) String() string { " Solar Plant: " + utils.FI64(r.SolarPlant) + "\n" + " Fusion Reactor: " + utils.FI64(r.FusionReactor) + "\n" + " Solar Satellite: " + utils.FI64(r.SolarSatellite) + "\n" + - " Crawler: " + utils.FI64(r.Crawler) + "\n" + - " Plasma Technology: " + utils.FI64(r.PlasmaTechnology) + " Crawler: " + utils.FI64(r.Crawler) } diff --git a/pkg/ogame/resourceSettings_test.go b/pkg/ogame/resourceSettings_test.go index 3beae2ad..1bbe24d8 100644 --- a/pkg/ogame/resourceSettings_test.go +++ b/pkg/ogame/resourceSettings_test.go @@ -15,7 +15,6 @@ func TestResourceSettings_String(t *testing.T) { FusionReactor: 5, SolarSatellite: 6, Crawler: 7, - PlasmaTechnology: 8, } expected := "\n" + " Metal Mine: 1\n" + @@ -24,7 +23,6 @@ func TestResourceSettings_String(t *testing.T) { " Solar Plant: 4\n" + " Fusion Reactor: 5\n" + " Solar Satellite: 6\n" + - " Crawler: 7\n" + - " Plasma Technology: 8" + " Crawler: 7" assert.Equal(t, expected, r.String()) } diff --git a/pkg/ogame/resources.go b/pkg/ogame/resources.go index 35fc6098..f6b0779d 100644 --- a/pkg/ogame/resources.go +++ b/pkg/ogame/resources.go @@ -28,6 +28,23 @@ type ResourcesDetails struct { CurrentProduction int64 // DenCapacity int } + Food struct { + Available int64 + StorageCapacity int64 + Overproduction int64 + ConsumedIn int64 + TimeTillFoodRunsOut int64 + } + Population struct { + Available int64 + T2Lifeforms int64 + T3Lifeforms int64 + LivingSpace int64 + Satisfied int64 + Hungry float64 + GrowthRate float64 + BunkerSpace int64 + } Energy struct { Available int64 CurrentProduction int64 @@ -46,6 +63,8 @@ func (r ResourcesDetails) Available() Resources { Metal: r.Metal.Available, Crystal: r.Crystal.Available, Deuterium: r.Deuterium.Available, + Food: r.Food.Available, + Population: r.Population.Available, Energy: r.Energy.Available, Darkmatter: r.Darkmatter.Available, } @@ -58,7 +77,7 @@ type Resources struct { Deuterium int64 Energy int64 Darkmatter int64 - Lifeform int64 + Population int64 Food int64 } diff --git a/pkg/parser/fetchTechsAjaxPage.go b/pkg/parser/fetchTechsAjaxPage.go index 99c0c847..d59ad23e 100644 --- a/pkg/parser/fetchTechsAjaxPage.go +++ b/pkg/parser/fetchTechsAjaxPage.go @@ -2,6 +2,6 @@ package parser import "github.com/alaingilbert/ogame/pkg/ogame" -func (p FetchTechsAjaxPage) ExtractTechs() (ogame.ResourcesBuildings, ogame.Facilities, ogame.ShipsInfos, ogame.DefensesInfos, ogame.Researches, error) { +func (p FetchTechsAjaxPage) ExtractTechs() (ogame.ResourcesBuildings, ogame.Facilities, ogame.ShipsInfos, ogame.DefensesInfos, ogame.Researches, ogame.LfBuildings, error) { return p.e.ExtractTechs(p.content) } diff --git a/pkg/parser/fullPage.go b/pkg/parser/fullPage.go index df2efd17..38185ac5 100644 --- a/pkg/parser/fullPage.go +++ b/pkg/parser/fullPage.go @@ -1,8 +1,9 @@ package parser import ( - "github.com/alaingilbert/ogame/pkg/ogame" "time" + + "github.com/alaingilbert/ogame/pkg/ogame" ) func (p FullPage) ExtractOGameSession() string { @@ -45,6 +46,10 @@ func (p FullPage) ExtractLifeformEnabled() bool { return p.e.ExtractLifeformEnabled(p.GetContent()) } +func (p FullPage) ExtractLfBuildings() (ogame.LfBuildings, error) { + return p.e.ExtractLfBuildings(p.GetContent()) +} + func (p FullPage) ExtractServerTime() (time.Time, error) { return p.e.ExtractServerTimeFromDoc(p.GetDoc()) } diff --git a/pkg/parser/lfbuildingsPage.go b/pkg/parser/lfbuildingsPage.go new file mode 100644 index 00000000..0738f829 --- /dev/null +++ b/pkg/parser/lfbuildingsPage.go @@ -0,0 +1,7 @@ +package parser + +import "github.com/alaingilbert/ogame/pkg/ogame" + +func (p SuppliesPage) ExtractLfBuildings() (ogame.LfBuildings, error) { + return p.e.ExtractLfBuildingsFromDoc(p.GetDoc()) +} diff --git a/pkg/parser/overviewPage.go b/pkg/parser/overviewPage.go index 8fd5d372..23774849 100644 --- a/pkg/parser/overviewPage.go +++ b/pkg/parser/overviewPage.go @@ -12,7 +12,7 @@ func (p OverviewPage) ExtractDMCosts() (ogame.DMCosts, error) { return p.e.ExtractDMCosts(p.content) } -func (p OverviewPage) ExtractConstructions() (ogame.ID, int64, ogame.ID, int64) { +func (p OverviewPage) ExtractConstructions() (ogame.ID, int64, ogame.ID, int64, ogame.ID, int64) { return p.e.ExtractConstructions(p.content) } diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index 0112e041..98f44855 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -3,11 +3,12 @@ package parser import ( "bytes" "errors" + "time" + "github.com/PuerkitoBio/goquery" "github.com/alaingilbert/ogame/pkg/extractor" v6 "github.com/alaingilbert/ogame/pkg/extractor/v6" "github.com/alaingilbert/ogame/pkg/ogame" - "time" ) var ErrParsePageType = errors.New("failed to parse requested page type") @@ -44,6 +45,7 @@ type FacilitiesPage struct{ FullPage } type ShipyardPage struct{ FullPage } type DefensesPage struct{ FullPage } type MovementPage struct{ FullPage } +type LfBuildingsPage struct{ FullPage } type FullPagePages interface { OverviewPage | @@ -51,6 +53,7 @@ type FullPagePages interface { SuppliesPage | ResourcesSettingsPage | FacilitiesPage | + LfBuildingsPage | //TraderOverviewPageContent | //TraderResourcesPageContent | ResearchPage | @@ -127,6 +130,8 @@ func ParsePage[T FullPagePages](e extractor.Extractor, pageHTML []byte) (T, erro return T(ResearchPage{fullPage}), nil case FacilitiesPage: return T(FacilitiesPage{fullPage}), nil + case LfBuildingsPage: + return T(LfBuildingsPage{fullPage}), nil case SuppliesPage: return T(SuppliesPage{fullPage}), nil case ResourcesSettingsPage: diff --git a/pkg/wrapper/fetcher.go b/pkg/wrapper/fetcher.go index bb19c89d..24d809eb 100644 --- a/pkg/wrapper/fetcher.go +++ b/pkg/wrapper/fetcher.go @@ -1,8 +1,9 @@ package wrapper import ( - "github.com/alaingilbert/ogame/pkg/parser" "net/url" + + "github.com/alaingilbert/ogame/pkg/parser" ) // Page names @@ -82,6 +83,8 @@ func getPage[T parser.FullPagePages](b *OGame, opts ...Option) (T, error) { pageName = DefensesPageName case parser.ResearchPage: pageName = ResearchPageName + case parser.LfBuildingsPage: + pageName = LfbuildingsPageName case parser.ShipyardPage: pageName = ShipyardPageName case parser.ResourcesSettingsPage: diff --git a/pkg/wrapper/fleetBuilder.go b/pkg/wrapper/fleetBuilder.go index 1b04a244..89adbc0b 100644 --- a/pkg/wrapper/fleetBuilder.go +++ b/pkg/wrapper/fleetBuilder.go @@ -202,6 +202,9 @@ func (f *FleetBuilder) FlightTime() (secs, fuel int64) { ships, _ = f.b.GetShips(f.origin.GetID()) } } + if f.tx != nil { + return f.tx.FlightTime(f.origin.GetCoordinate(), f.destination, f.speed, ships, f.mission) + } return f.b.FlightTime(f.origin.GetCoordinate(), f.destination, f.speed, ships, f.mission) } diff --git a/pkg/wrapper/handlers.go b/pkg/wrapper/handlers.go index cd4f1c0c..4914d9b0 100644 --- a/pkg/wrapper/handlers.go +++ b/pkg/wrapper/handlers.go @@ -5,12 +5,13 @@ import ( "encoding/base64" "errors" "fmt" - "github.com/alaingilbert/ogame/pkg/ogame" - "github.com/alaingilbert/ogame/pkg/utils" - echo "github.com/labstack/echo/v4" "net/http" "net/url" "strings" + + "github.com/alaingilbert/ogame/pkg/ogame" + "github.com/alaingilbert/ogame/pkg/utils" + echo "github.com/labstack/echo/v4" ) // APIResp ... @@ -537,6 +538,20 @@ func SetResourceSettingsHandler(c echo.Context) error { return c.JSON(http.StatusOK, SuccessResp(nil)) } +// GetLfBuildingsHandler ... +func GetLfBuildingsHandler(c echo.Context) error { + bot := c.Get("bot").(*OGame) + planetID, err := utils.ParseI64(c.Param("planetID")) + if err != nil { + return c.JSON(http.StatusBadRequest, ErrorResp(400, "invalid planet id")) + } + res, err := bot.GetLfBuildings(ogame.CelestialID(planetID)) + if err != nil { + return c.JSON(http.StatusInternalServerError, ErrorResp(500, err.Error())) + } + return c.JSON(http.StatusOK, SuccessResp(res)) +} + // GetResourcesBuildingsHandler ... func GetResourcesBuildingsHandler(c echo.Context) error { bot := c.Get("bot").(*OGame) @@ -749,18 +764,22 @@ func ConstructionsBeingBuiltHandler(c echo.Context) error { if err != nil { return c.JSON(http.StatusBadRequest, ErrorResp(400, "invalid planet id")) } - buildingID, buildingCountdown, researchID, researchCountdown := bot.ConstructionsBeingBuilt(ogame.CelestialID(planetID)) + buildingID, buildingCountdown, researchID, researchCountdown, lfBuildingID, lfBuildingCountdown := bot.ConstructionsBeingBuilt(ogame.CelestialID(planetID)) return c.JSON(http.StatusOK, SuccessResp( struct { - BuildingID int64 - BuildingCountdown int64 - ResearchID int64 - ResearchCountdown int64 + BuildingID int64 + BuildingCountdown int64 + ResearchID int64 + ResearchCountdown int64 + LfBuildingID int64 + LfBuildingCountdown int64 }{ - BuildingID: int64(buildingID), - BuildingCountdown: buildingCountdown, - ResearchID: int64(researchID), - ResearchCountdown: researchCountdown, + BuildingID: int64(buildingID), + BuildingCountdown: buildingCountdown, + ResearchID: int64(researchID), + ResearchCountdown: researchCountdown, + LfBuildingID: int64(lfBuildingID), + LfBuildingCountdown: lfBuildingCountdown, }, )) } @@ -805,6 +824,20 @@ func GetResourcesHandler(c echo.Context) error { return c.JSON(http.StatusOK, SuccessResp(res)) } +// GetRequirementsHandler ... +func GetRequirementsHandler(c echo.Context) error { + ogameID, err := utils.ParseI64(c.Param("ogameID")) + if err != nil { + return c.JSON(http.StatusBadRequest, ErrorResp(400, "invalid ogameID")) + } + ogameObj := ogame.Objs.ByID(ogame.ID(ogameID)) + if ogameObj != nil { + requirements := ogameObj.GetRequirements() + return c.JSON(http.StatusOK, SuccessResp(requirements)) + } + return c.JSON(http.StatusBadRequest, ErrorResp(400, "invalid ogameID")) +} + // GetPriceHandler ... func GetPriceHandler(c echo.Context) error { ogameID, err := utils.ParseI64(c.Param("ogameID")) @@ -1294,16 +1327,17 @@ func TechsHandler(c echo.Context) error { if err != nil { return c.JSON(http.StatusBadRequest, ErrorResp(400, "invalid celestial id")) } - supplies, facilities, ships, defenses, researches, err := bot.GetTechs(ogame.CelestialID(celestialID)) + supplies, facilities, ships, defenses, researches, lfbuildings, err := bot.GetTechs(ogame.CelestialID(celestialID)) if err != nil { return c.JSON(http.StatusBadRequest, ErrorResp(400, err.Error())) } return c.JSON(http.StatusOK, SuccessResp(map[string]any{ - "supplies": supplies, - "facilities": facilities, - "ships": ships, - "defenses": defenses, - "researches": researches, + "supplies": supplies, + "facilities": facilities, + "ships": ships, + "defenses": defenses, + "researches": researches, + "lfbuildings": lfbuildings, })) } diff --git a/pkg/wrapper/interfaces.go b/pkg/wrapper/interfaces.go index c4109290..e82197b3 100644 --- a/pkg/wrapper/interfaces.go +++ b/pkg/wrapper/interfaces.go @@ -2,13 +2,14 @@ package wrapper import ( "crypto/tls" + "net/http" + "net/url" + "time" + "github.com/alaingilbert/ogame/pkg/extractor" "github.com/alaingilbert/ogame/pkg/httpclient" "github.com/alaingilbert/ogame/pkg/ogame" "github.com/alaingilbert/ogame/pkg/taskRunner" - "net/http" - "net/url" - "time" ) // Celestial superset of ogame.Celestial. @@ -23,16 +24,18 @@ type Celestial interface { CancelBuilding() error CancelLfBuilding() error CancelResearch() error - ConstructionsBeingBuilt() (ogame.ID, int64, ogame.ID, int64) + ConstructionsBeingBuilt() (ogame.ID, int64, ogame.ID, int64, ogame.ID, int64) EnsureFleet([]ogame.Quantifiable, ogame.Speed, ogame.Coordinate, ogame.MissionID, ogame.Resources, int64, int64) (ogame.Fleet, error) GetDefense(...Option) (ogame.DefensesInfos, error) GetFacilities(...Option) (ogame.Facilities, error) GetItems() ([]ogame.Item, error) + GetLfBuildings(...Option) (ogame.LfBuildings, error) GetProduction() ([]ogame.Quantifiable, int64, error) GetResources() (ogame.Resources, error) GetResourcesBuildings(...Option) (ogame.ResourcesBuildings, error) GetResourcesDetails() (ogame.ResourcesDetails, error) GetShips(...Option) (ogame.ShipsInfos, error) + GetTechs() (ogame.ResourcesBuildings, ogame.Facilities, ogame.ShipsInfos, ogame.DefensesInfos, ogame.Researches, ogame.LfBuildings, error) SendFleet([]ogame.Quantifiable, ogame.Speed, ogame.Coordinate, ogame.MissionID, ogame.Resources, int64, int64) (ogame.Fleet, error) TearDown(buildingID ogame.ID) error } @@ -113,16 +116,17 @@ type Prioritizable interface { CancelBuilding(ogame.CelestialID) error CancelLfBuilding(ogame.CelestialID) error CancelResearch(ogame.CelestialID) error - ConstructionsBeingBuilt(ogame.CelestialID) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64) + ConstructionsBeingBuilt(ogame.CelestialID) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64, lfBuildingID ogame.ID, lfBuildingCountdown int64) EnsureFleet(celestialID ogame.CelestialID, ships []ogame.Quantifiable, speed ogame.Speed, where ogame.Coordinate, mission ogame.MissionID, resources ogame.Resources, holdingTime, unionID int64) (ogame.Fleet, error) GetDefense(ogame.CelestialID, ...Option) (ogame.DefensesInfos, error) GetFacilities(ogame.CelestialID, ...Option) (ogame.Facilities, error) + GetLfBuildings(ogame.CelestialID, ...Option) (ogame.LfBuildings, error) GetProduction(ogame.CelestialID) ([]ogame.Quantifiable, int64, error) GetResources(ogame.CelestialID) (ogame.Resources, error) GetResourcesBuildings(ogame.CelestialID, ...Option) (ogame.ResourcesBuildings, error) GetResourcesDetails(ogame.CelestialID) (ogame.ResourcesDetails, error) GetShips(ogame.CelestialID, ...Option) (ogame.ShipsInfos, error) - GetTechs(celestialID ogame.CelestialID) (ogame.ResourcesBuildings, ogame.Facilities, ogame.ShipsInfos, ogame.DefensesInfos, ogame.Researches, error) + GetTechs(celestialID ogame.CelestialID) (ogame.ResourcesBuildings, ogame.Facilities, ogame.ShipsInfos, ogame.DefensesInfos, ogame.Researches, ogame.LfBuildings, error) SendFleet(celestialID ogame.CelestialID, ships []ogame.Quantifiable, speed ogame.Speed, where ogame.Coordinate, mission ogame.MissionID, resources ogame.Resources, holdingTime, unionID int64) (ogame.Fleet, error) TearDown(celestialID ogame.CelestialID, id ogame.ID) error diff --git a/pkg/wrapper/moon.go b/pkg/wrapper/moon.go index 91a97634..d6e10a24 100644 --- a/pkg/wrapper/moon.go +++ b/pkg/wrapper/moon.go @@ -18,7 +18,7 @@ func (m Moon) GetProduction() ([]ogame.Quantifiable, int64, error) { } // ConstructionsBeingBuilt returns the building & research being built, and the time remaining (secs) -func (m Moon) ConstructionsBeingBuilt() (ogame.ID, int64, ogame.ID, int64) { +func (m Moon) ConstructionsBeingBuilt() (ogame.ID, int64, ogame.ID, int64, ogame.ID, int64) { return m.ogame.ConstructionsBeingBuilt(ogame.CelestialID(m.ID)) } @@ -137,3 +137,13 @@ func (m Moon) Phalanx(coord ogame.Coordinate) ([]ogame.Fleet, error) { //func (m *Moon) UseJumpGate() error { // return nil //} + +// GetLfBuildings gets the lifeform buildings levels +func (m Moon) GetLfBuildings(options ...Option) (ogame.LfBuildings, error) { + return m.ogame.GetLfBuildings(m.ID.Celestial(), options...) +} + +// GetTechs gets (ogame.ResourcesBuildings, ogame.Facilities, ogame.ShipsInfos, ogame.DefensesInfos, ogame.Researches) +func (m Moon) GetTechs() (ogame.ResourcesBuildings, ogame.Facilities, ogame.ShipsInfos, ogame.DefensesInfos, ogame.Researches, ogame.LfBuildings, error) { + return m.ogame.GetTechs(m.ID.Celestial()) +} diff --git a/pkg/wrapper/ogame.go b/pkg/wrapper/ogame.go index 2ee66c8e..204c61ae 100644 --- a/pkg/wrapper/ogame.go +++ b/pkg/wrapper/ogame.go @@ -8,20 +8,6 @@ import ( "encoding/json" err2 "errors" "fmt" - "github.com/alaingilbert/clockwork" - "github.com/alaingilbert/ogame/pkg/exponentialBackoff" - "github.com/alaingilbert/ogame/pkg/extractor" - "github.com/alaingilbert/ogame/pkg/extractor/v6" - "github.com/alaingilbert/ogame/pkg/extractor/v7" - "github.com/alaingilbert/ogame/pkg/extractor/v71" - "github.com/alaingilbert/ogame/pkg/extractor/v8" - "github.com/alaingilbert/ogame/pkg/extractor/v874" - "github.com/alaingilbert/ogame/pkg/extractor/v9" - "github.com/alaingilbert/ogame/pkg/httpclient" - "github.com/alaingilbert/ogame/pkg/ogame" - "github.com/alaingilbert/ogame/pkg/parser" - "github.com/alaingilbert/ogame/pkg/taskRunner" - "github.com/alaingilbert/ogame/pkg/utils" "image" "image/color" "image/png" @@ -42,6 +28,21 @@ import ( "sync/atomic" "time" + "github.com/alaingilbert/clockwork" + "github.com/alaingilbert/ogame/pkg/exponentialBackoff" + "github.com/alaingilbert/ogame/pkg/extractor" + v6 "github.com/alaingilbert/ogame/pkg/extractor/v6" + v7 "github.com/alaingilbert/ogame/pkg/extractor/v7" + v71 "github.com/alaingilbert/ogame/pkg/extractor/v71" + v8 "github.com/alaingilbert/ogame/pkg/extractor/v8" + v874 "github.com/alaingilbert/ogame/pkg/extractor/v874" + v9 "github.com/alaingilbert/ogame/pkg/extractor/v9" + "github.com/alaingilbert/ogame/pkg/httpclient" + "github.com/alaingilbert/ogame/pkg/ogame" + "github.com/alaingilbert/ogame/pkg/parser" + "github.com/alaingilbert/ogame/pkg/taskRunner" + "github.com/alaingilbert/ogame/pkg/utils" + "github.com/PuerkitoBio/goquery" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api" version "github.com/hashicorp/go-version" @@ -2878,6 +2879,15 @@ func (b *OGame) getResourcesBuildings(celestialID ogame.CelestialID, options ... return page.ExtractResourcesBuildings() } +func (b *OGame) getLfBuildings(celestialID ogame.CelestialID, options ...Option) (ogame.LfBuildings, error) { + options = append(options, ChangePlanet(celestialID)) + page, err := getPage[parser.LfBuildingsPage](b, options...) + if err != nil { + return ogame.LfBuildings{}, err + } + return page.ExtractLfBuildings() +} + func (b *OGame) getDefense(celestialID ogame.CelestialID, options ...Option) (ogame.DefensesInfos, error) { options = append(options, ChangePlanet(celestialID)) page, err := getPage[parser.DefensesPage](b, options...) @@ -2905,11 +2915,11 @@ func (b *OGame) getFacilities(celestialID ogame.CelestialID, options ...Option) return page.ExtractFacilities() } -func (b *OGame) getTechs(celestialID ogame.CelestialID) (ogame.ResourcesBuildings, ogame.Facilities, ogame.ShipsInfos, ogame.DefensesInfos, ogame.Researches, error) { +func (b *OGame) getTechs(celestialID ogame.CelestialID) (ogame.ResourcesBuildings, ogame.Facilities, ogame.ShipsInfos, ogame.DefensesInfos, ogame.Researches, ogame.LfBuildings, error) { vals := url.Values{"page": {FetchTechsName}} page, err := getAjaxPage[parser.FetchTechsAjaxPage](b, vals, ChangePlanet(celestialID)) if err != nil { - return ogame.ResourcesBuildings{}, ogame.Facilities{}, ogame.ShipsInfos{}, ogame.DefensesInfos{}, ogame.Researches{}, err + return ogame.ResourcesBuildings{}, ogame.Facilities{}, ogame.ShipsInfos{}, ogame.DefensesInfos{}, ogame.Researches{}, ogame.LfBuildings{}, err } return page.ExtractTechs() } @@ -3038,7 +3048,7 @@ func (b *OGame) build(celestialID ogame.CelestialID, id ogame.ID, nbr int64) err } func (b *OGame) buildCancelable(celestialID ogame.CelestialID, id ogame.ID) error { - if !id.IsBuilding() && !id.IsTech() { + if !id.IsBuilding() && !id.IsTech() && !id.IsLfBuilding() { return errors.New("invalid id " + id.String()) } return b.build(celestialID, id, 0) @@ -3079,10 +3089,10 @@ func (b *OGame) buildShips(celestialID ogame.CelestialID, shipID ogame.ID, nbr i return b.buildProduction(celestialID, shipID, nbr) } -func (b *OGame) constructionsBeingBuilt(celestialID ogame.CelestialID) (ogame.ID, int64, ogame.ID, int64) { +func (b *OGame) constructionsBeingBuilt(celestialID ogame.CelestialID) (ogame.ID, int64, ogame.ID, int64, ogame.ID, int64) { page, err := getPage[parser.OverviewPage](b, ChangePlanet(celestialID)) if err != nil { - return ogame.ID(0), 0, ogame.ID(0), 0 + return ogame.ID(0), 0, ogame.ID(0), 0, ogame.ID(0), 0 } return page.ExtractConstructions() } @@ -3139,6 +3149,8 @@ func (b *OGame) getResources(celestialID ogame.CelestialID) (ogame.Resources, er Deuterium: res.Deuterium.Available, Energy: res.Energy.Available, Darkmatter: res.Darkmatter.Available, + Population: res.Population.Available, + Food: res.Food.Available, }, nil } @@ -4499,7 +4511,7 @@ func (b *OGame) BuildShips(celestialID ogame.CelestialID, shipID ogame.ID, nbr i } // ConstructionsBeingBuilt returns the building & research being built, and the time remaining (secs) -func (b *OGame) ConstructionsBeingBuilt(celestialID ogame.CelestialID) (ogame.ID, int64, ogame.ID, int64) { +func (b *OGame) ConstructionsBeingBuilt(celestialID ogame.CelestialID) (ogame.ID, int64, ogame.ID, int64, ogame.ID, int64) { return b.WithPriority(taskRunner.Normal).ConstructionsBeingBuilt(celestialID) } @@ -4534,7 +4546,7 @@ func (b *OGame) GetResourcesDetails(celestialID ogame.CelestialID) (ogame.Resour } // GetTechs gets a celestial supplies/facilities/ships/researches -func (b *OGame) GetTechs(celestialID ogame.CelestialID) (ogame.ResourcesBuildings, ogame.Facilities, ogame.ShipsInfos, ogame.DefensesInfos, ogame.Researches, error) { +func (b *OGame) GetTechs(celestialID ogame.CelestialID) (ogame.ResourcesBuildings, ogame.Facilities, ogame.ShipsInfos, ogame.DefensesInfos, ogame.Researches, ogame.LfBuildings, error) { return b.WithPriority(taskRunner.Normal).GetTechs(celestialID) } @@ -4663,7 +4675,8 @@ func (b *OGame) RegisterHTMLInterceptor(fn func(method, url string, params, payl // Phalanx scan a coordinate from a moon to get fleets information // IMPORTANT: My account was instantly banned when I scanned an invalid coordinate. // IMPORTANT: This function DOES validate that the coordinate is a valid planet in range of phalanx -// and that you have enough deuterium. +// +// and that you have enough deuterium. func (b *OGame) Phalanx(moonID ogame.MoonID, coord ogame.Coordinate) ([]ogame.Fleet, error) { return b.WithPriority(taskRunner.Normal).Phalanx(moonID, coord) } @@ -4777,3 +4790,8 @@ func (b *OGame) OfferSellMarketplace(itemID any, quantity, priceType, price, pri func (b *OGame) OfferBuyMarketplace(itemID any, quantity, priceType, price, priceRange int64, celestialID ogame.CelestialID) error { return b.WithPriority(taskRunner.Normal).OfferBuyMarketplace(itemID, quantity, priceType, price, priceRange, celestialID) } + +// GetLfBuildings ... +func (b *OGame) GetLfBuildings(celestialID ogame.CelestialID, opts ...Option) (ogame.LfBuildings, error) { + return b.WithPriority(taskRunner.Normal).GetLfBuildings(celestialID, opts...) +} diff --git a/pkg/wrapper/planet.go b/pkg/wrapper/planet.go index f0867307..e6a66437 100644 --- a/pkg/wrapper/planet.go +++ b/pkg/wrapper/planet.go @@ -2,6 +2,7 @@ package wrapper import ( "fmt" + "github.com/alaingilbert/ogame/pkg/ogame" ) @@ -108,7 +109,7 @@ func (p Planet) EnsureFleet(ships []ogame.Quantifiable, speed ogame.Speed, where } // ConstructionsBeingBuilt returns the building & research being built, and the time remaining (secs) -func (p Planet) ConstructionsBeingBuilt() (ogame.ID, int64, ogame.ID, int64) { +func (p Planet) ConstructionsBeingBuilt() (ogame.ID, int64, ogame.ID, int64, ogame.ID, int64) { return p.ogame.ConstructionsBeingBuilt(ogame.CelestialID(p.ID)) } @@ -151,3 +152,13 @@ func (p Planet) FlightTime(destination ogame.Coordinate, speed ogame.Speed, ship func (p Planet) SendIPM(planetID ogame.PlanetID, coord ogame.Coordinate, nbr int64, priority ogame.ID) (int64, error) { return p.ogame.SendIPM(planetID, coord, nbr, priority) } + +// GetLfBuildings gets the lifeform buildings levels +func (p Planet) GetLfBuildings(options ...Option) (ogame.LfBuildings, error) { + return p.ogame.getLfBuildings(p.ID.Celestial(), options...) +} + +// GetTechs gets (ogame.ResourcesBuildings, ogame.Facilities, ogame.ShipsInfos, ogame.DefensesInfos, ogame.Researches) +func (p Planet) GetTechs() (ogame.ResourcesBuildings, ogame.Facilities, ogame.ShipsInfos, ogame.DefensesInfos, ogame.Researches, ogame.LfBuildings, error) { + return p.ogame.GetTechs(p.ID.Celestial()) +} diff --git a/pkg/wrapper/prioritize.go b/pkg/wrapper/prioritize.go index afea5366..5dc9926a 100644 --- a/pkg/wrapper/prioritize.go +++ b/pkg/wrapper/prioritize.go @@ -1,11 +1,12 @@ package wrapper import ( - "github.com/alaingilbert/ogame/pkg/ogame" "net/http" "net/url" "sync/atomic" "time" + + "github.com/alaingilbert/ogame/pkg/ogame" ) // Prioritize ... @@ -376,7 +377,7 @@ func (b *Prioritize) BuildShips(celestialID ogame.CelestialID, shipID ogame.ID, } // ConstructionsBeingBuilt returns the building & research being built, and the time remaining (secs) -func (b *Prioritize) ConstructionsBeingBuilt(celestialID ogame.CelestialID) (ogame.ID, int64, ogame.ID, int64) { +func (b *Prioritize) ConstructionsBeingBuilt(celestialID ogame.CelestialID) (ogame.ID, int64, ogame.ID, int64, ogame.ID, int64) { b.begin("ConstructionsBeingBuilt") defer b.done() return b.bot.constructionsBeingBuilt(celestialID) @@ -425,7 +426,7 @@ func (b *Prioritize) GetResourcesDetails(celestialID ogame.CelestialID) (ogame.R } // GetTechs gets a celestial supplies/facilities/ships/researches -func (b *Prioritize) GetTechs(celestialID ogame.CelestialID) (ogame.ResourcesBuildings, ogame.Facilities, ogame.ShipsInfos, ogame.DefensesInfos, ogame.Researches, error) { +func (b *Prioritize) GetTechs(celestialID ogame.CelestialID) (ogame.ResourcesBuildings, ogame.Facilities, ogame.ShipsInfos, ogame.DefensesInfos, ogame.Researches, ogame.LfBuildings, error) { b.begin("GetTechs") defer b.done() return b.bot.getTechs(celestialID) @@ -706,3 +707,10 @@ func (b *Prioritize) OfferBuyMarketplace(itemID any, quantity, priceType, price, defer b.done() return b.bot.offerMarketplace(3, itemID, quantity, priceType, price, priceRange, celestialID) } + +// GetLfBuildings ... +func (b *Prioritize) GetLfBuildings(celestialID ogame.CelestialID, options ...Option) (ogame.LfBuildings, error) { + b.begin("GetLfBuildings") + defer b.done() + return b.bot.getLfBuildings(celestialID, options...) +} diff --git a/samples/v9.0.4/en/lfbuildings.html b/samples/v9.0.4/en/lfbuildings.html new file mode 100644 index 00000000..2734be40 --- /dev/null +++ b/samples/v9.0.4/en/lfbuildings.html @@ -0,0 +1,1563 @@ + + + + Bermuda OGame + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + + + + +
+ +
+ + + + + +
+
+
+
+
+ +
+
+
+ +
+ +
+
+
+ + 6,624 + +
+
+
+
+
+ + 7,270 + +
+
+
+
+
+ + 964 + +
+
+
+
+
+ + 8 + +
+
+
+
+
+ + 210.127 + +
+
+
+
+
+ + 10.032 + +
+
+
+
+ + +
+
+ + 10,000,000 + +
+
+
+ +
+ +
+
+ + + + + 0 + + +
+ +
+ ajax spinner + load... +
+ +
+
+ +
+
+
+ +
+
+
+
+ ? +
+
+
+
+
+
+ +
+ + + + + + + + + +
+
+ +
+
+
+
+
+
+
+ + +

Events

+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
+

Lifeform Buildings - Homeworld

+ +
+
+
+
+
+

+ Lifeform Buildings +

+
    +
  • 2
  • 1
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
+
+
+
+
+
+
+

Lifeform Buildings

+
+ + +
+ +
+
+
+
+ +
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+ + + + + +
+
+ +
+ +
+ + + + diff --git a/samples/v9.0.4/en/lifeform/lfbuildings_rocktal.html b/samples/v9.0.4/en/lifeform/lfbuildings_rocktal.html new file mode 100644 index 00000000..195ebea7 --- /dev/null +++ b/samples/v9.0.4/en/lifeform/lfbuildings_rocktal.html @@ -0,0 +1,1624 @@ + + + + + Halley OGame + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + +
+ + +
+ +
+ + + + + + + + +
+
+ + + + + + +
+ +
+ + + + + +
+
+
+
+
+ +
+
+
+ +
+ +
+
+
+ + 476,154 + +
+
+
+
+
+ + 237,423 + +
+
+
+
+
+ + 144,730 + +
+
+
+
+
+ + -1,238 + +
+
+
+
+
+ + 210.312 + +
+
+
+
+
+ + 1.122 + +
+
+
+
+ + +
+
+ + 8,000 + +
+
+
+ +
+ +
+
+ + + 25 + + + + + 0 + + +
+ +
+ ajax spinner + load... +
+ +
+
+ +
+
+
+ +
+
+
+
+ ? +
+
+
+
+
+
+ +
+ + + + + + +
+
+ +
+
+
+
+
+
+
+ + +

Events

+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
+

Lifeform Buildings - Colony

+ +
+
+
+
+
+

+ Lifeform Buildings +

+
    +
  • 2
  • 1
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
+
+
+
+
+
+
+

Lifeform Buildings

+
+ + +
+ +
+
+
+
+ +
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+ + + + + +
+
+ +
+ +
+ + + +
+
+ + + + diff --git a/samples/v9.0.4/en/lifeform/movement.html b/samples/v9.0.4/en/lifeform/movement.html new file mode 100644 index 00000000..d2175939 --- /dev/null +++ b/samples/v9.0.4/en/lifeform/movement.html @@ -0,0 +1,1765 @@ + + + + + Halley OGame + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + +
+ + +
+ +
+ + + + + + + + +
+
+ + + + + + +
+ +
+ + + + + +
+
+
+
+
+ +
+
+
+ +
+ +
+
+
+ + 471,747 + +
+
+
+
+
+ + 222,828 + +
+
+
+
+
+ + 175,011 + +
+
+
+
+
+ + -2,267 + +
+
+
+
+
+ + 1,974,118.233 + +
+
+
+
+
+ + 0 + +
+
+
+
+ + +
+
+ + 8,000 + +
+
+
+ +
+ +
+
+ + + 24 + + + + + 0 + + +
+ +
+ ajax spinner + load... +
+ +
+
+ +
+
+
+ +
+
+
+
+ ? +
+
+
+
+
+
+ +
+ + + + + + +
+
+ +
+
+
+
+
+
+
+ + +

Events

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + load... + + 10:07:48 Clock + + +
Homeworld +
+ + [2:138:12] + + + 1 + + +   + + +
Colony +
+ + [2:138:5] + + + +
+ + load... + + 15:50:31 Clock + + +
Homeworld +
+ + [2:138:12] + + + 1 + + +   + + +
Colony +
+ + [2:138:5] + + + +
+
+
+
+ + + +
+
+
+
+
+

Fleet movement - Homeworld

+ + + +
+
+
+
+ + + + Reload + + + + Fleets: 1 / 12 + + + Expeditions: 0 / 2 + + + + + + +
+
+ load... + 10:07:48 Clock + Transport + + + [2:138:12] + +
Homeworld +
+
+ + + + + + + + + + + + +
+
+ +
+ +
+ + + + + +
+ +
+ +
+
+
+ + + +
Colony +
+
+ + [2:138:5] +
+ load... + 15:50:31 Clock + Return + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + +
+
+ +
+ +
+ + + +
+
+ + + + diff --git a/samples/v9.0.4/en/lifeform/overview.html b/samples/v9.0.4/en/lifeform/overview.html new file mode 100644 index 00000000..c940efb0 --- /dev/null +++ b/samples/v9.0.4/en/lifeform/overview.html @@ -0,0 +1,1913 @@ + + + + + Halley OGame + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + +
+ + +
+ +
+ + + + + + + + +
+
+ + + + + + +
+ +
+ + + + + +
+
+
+
+
+ +
+
+
+ +
+ +
+
+
+ + 310,443 + +
+
+
+
+
+ + 87,170 + +
+
+
+
+
+ + 137,717 + +
+
+
+
+
+ + -2,248 + +
+
+
+
+
+ + 1,974,118.233 + +
+
+
+
+
+ + 0 + +
+
+
+
+ + +
+
+ + 8,000 + +
+
+
+ +
+ +
+
+ + + 25 + + + + + 0 + + +
+ +
+ ajax spinner + load... +
+ +
+
+ +
+
+
+ +
+
+
+
+ ? +
+
+
+
+
+
+ +
+ + + + + + +
+
+ +
+
+
+
+
+
+
+ + +

Events

+
+ + + +
+
+
+
+ + + +
+
+ +
+
+
+ + +
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + +
+ + +
+
+ + +
+
+ +
+
+ +
+ +
+ + +
+
+
+
+
+
+
+

Buildings

+
+ + +
+ +
+
+
+

Lifeform Buildings

+
+
+ + + + + + + + + + + + + + + + + + + +
Residential Sector
+ + Improve to + Level 34 +
Duration:
+ load... +
+ +
+ + Halve time + + + Costs: + 9,000 DM + + Purchase Dark Matter +
+
+
+ +
+ +
+
+
+
+ +
+
+ +
+
+
+ +
+
+

Shipyard

+
+ + +
+ +
+
+
+ + + +
+
+ +
+
+
+ + + + + +
+
+ +
+ +
+ + + +
+
+ + + +