diff --git a/cmd/c/main.go b/cmd/c/main.go index 6550e845..0b584d8a 100644 --- a/cmd/c/main.go +++ b/cmd/c/main.go @@ -332,7 +332,7 @@ 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, lfBuildingID, lfBuildingCountdown, lfTechID, lfTechCountdown C.int) { +func ConstructionsBeingBuilt(planetID C.int) (buildingID, buildingCountdown, researchID, researchCountdown, lfBuildingID, lfBuildingCountdown, lfResearchID, lfResearchCountdown C.int) { a, b, c, d, e, f, g, h := bot.ConstructionsBeingBuilt(ogame2.CelestialID(planetID)) return C.int(a), C.int(b), C.int(c), C.int(d), C.int(e), C.int(f), C.int(g), C.int(h) } diff --git a/cmd/ogamed/main.go b/cmd/ogamed/main.go index 5c0a0d72..eec40f4f 100644 --- a/cmd/ogamed/main.go +++ b/cmd/ogamed/main.go @@ -245,7 +245,9 @@ func start(c *cli.Context) error { // CAPTCHA Handler e.GET("/bot/captcha", wrapper.GetCaptchaHandler) e.POST("/bot/captcha/solve", wrapper.GetCaptchaSolverHandler) + e.GET("/bot/captcha/challenge", wrapper.GetCaptchaChallengeHandler) + e.GET("/bot/ip", wrapper.GetPublicIPHandler) e.GET("/bot/server", wrapper.GetServerHandler) e.GET("/bot/server-data", wrapper.GetServerDataHandler) e.POST("/bot/set-user-agent", wrapper.SetUserAgentHandler) @@ -302,7 +304,7 @@ func start(c *cli.Context) error { 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/lifeform-techs", wrapper.GetLfTechsHandler) + e.GET("/bot/planets/:planetID/lifeform-techs", wrapper.GetLfResearchHandler) 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/go.mod b/go.mod index 64a9ec33..76a1de13 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible github.com/google/gxui v0.0.0-20151028112939-f85e0a97b3a4 github.com/hashicorp/go-version v1.2.0 - github.com/labstack/echo/v4 v4.8.0 + github.com/labstack/echo/v4 v4.9.0 github.com/magiconair/properties v1.8.1 github.com/olekukonko/tablewriter v0.0.4 github.com/orirawlings/persistent-cookiejar v0.3.0 diff --git a/go.sum b/go.sum index 14c050ab..e92d171f 100644 --- a/go.sum +++ b/go.sum @@ -108,8 +108,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/labstack/echo/v4 v4.8.0 h1:wdc6yKVaHxkNOEdz4cRZs1pQkwSXPiRjq69yWP4QQS8= -github.com/labstack/echo/v4 v4.8.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks= +github.com/labstack/echo/v4 v4.9.0 h1:wPOF1CE6gvt/kmbMR4dGzWvHMPT+sAEUJOwOTtvITVY= +github.com/labstack/echo/v4 v4.9.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks= github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o= github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= diff --git a/pkg/extractor/extractor.go b/pkg/extractor/extractor.go index 96418fb8..62fc666a 100644 --- a/pkg/extractor/extractor.go +++ b/pkg/extractor/extractor.go @@ -75,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, lfBuildingID ogame.ID, lfBuildingCountdown int64, lfTechID ogame.ID, lfTechCountdown int64) + ExtractConstructions(pageHTML []byte) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64, lfBuildingID ogame.ID, lfBuildingCountdown int64, lfResearchID ogame.ID, lfResearchCountdown int64) ExtractDMCosts(pageHTML []byte) (ogame.DMCosts, error) ExtractFleetDeutSaveFactor(pageHTML []byte) float64 ExtractOverviewProduction(pageHTML []byte) ([]ogame.Quantifiable, int64, error) @@ -423,18 +423,18 @@ type LfBuildingsExtractorBytesDoc interface { LfBuildingsExtractorDoc } -type LfTechsExtractorBytes interface { +type LfResearchExtractorBytes interface { ExtractUpgradeToken(pageHTML []byte) (string, error) - ExtractLfTechs(pageHTML []byte) (ogame.LfTechs, error) + ExtractLfResearch(pageHTML []byte) (ogame.LfResearches, error) } -type LfTechsExtractorDoc interface { - ExtractLfTechsFromDoc(doc *goquery.Document) (ogame.LfTechs, error) +type LfResearchExtractorDoc interface { + ExtractLfResearchFromDoc(doc *goquery.Document) (ogame.LfResearches, error) } -type LfTechsExtractorBytesDoc interface { - LfTechsExtractorBytes - LfTechsExtractorDoc +type LfResearchExtractorBytesDoc interface { + LfResearchExtractorBytes + LfResearchExtractorDoc } // ResourcesBuildingsExtractorBytes supplies page @@ -463,11 +463,13 @@ type PlanetLayerExtractorDoc interface { } type TechnologyDetailsExtractorBytes interface { + ExtractTechnologyDetails(pageHTML []byte) (ogame.TechnologyDetails, error) ExtractTearDownButtonEnabled(pageHTML []byte) bool } type TechnologyDetailsExtractorDoc interface { ExtractTearDownButtonEnabledFromDoc(doc *goquery.Document) bool + ExtractTechnologyDetailsFromDoc(doc *goquery.Document) (ogame.TechnologyDetails, error) } type TechnologyDetailsExtractorBytesDoc interface { @@ -492,7 +494,7 @@ type Extractor interface { FullPageExtractorBytesDoc HighscoreExtractorBytesDoc LfBuildingsExtractorBytesDoc - LfTechsExtractorBytesDoc + LfResearchExtractorBytesDoc MessagesCombatReportExtractorBytesDoc MessagesEspionageReportExtractorBytesDoc MessagesExpeditionExtractorBytesDoc diff --git a/pkg/extractor/v6/extractor.go b/pkg/extractor/v6/extractor.go index 6edecf7c..c770ae1f 100644 --- a/pkg/extractor/v6/extractor.go +++ b/pkg/extractor/v6/extractor.go @@ -43,6 +43,16 @@ func (e *Extractor) GetLanguage() string { return e.lang } +// ExtractTechnologyDetails ... +func (e *Extractor) ExtractTechnologyDetails(pageHTML []byte) (out ogame.TechnologyDetails, err error) { + panic("implement me") +} + +// ExtractTechnologyDetailsFromDoc ... +func (e *Extractor) ExtractTechnologyDetailsFromDoc(doc *goquery.Document) (ogame.TechnologyDetails, error) { + panic("implement me") +} + func (e *Extractor) ExtractCancelLfBuildingInfos(pageHTML []byte) (token string, id, listID int64, err error) { panic("implement me") } @@ -809,7 +819,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, lfBuildingID ogame.ID, lfBuildingCountdown int64, lfTechID ogame.ID, lfTechCountdown int64) { +func (e *Extractor) ExtractConstructions(pageHTML []byte) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64, lfBuildingID ogame.ID, lfBuildingCountdown int64, lfResearchID ogame.ID, lfResearchCountdown int64) { return extractConstructions(pageHTML) } @@ -894,12 +904,12 @@ func (e *Extractor) ExtractLfBuildingsFromDoc(doc *goquery.Document) (ogame.LfBu panic("not implemented") } -// ExtractLfTechs ... -func (e *Extractor) ExtractLfTechs(pageHTML []byte) (ogame.LfTechs, error) { +// ExtractLfResearch ... +func (e *Extractor) ExtractLfResearch(pageHTML []byte) (ogame.LfResearches, error) { panic("not implemented") } -// ExtractLfTechsFromDoc ... -func (e *Extractor) ExtractLfTechsFromDoc(doc *goquery.Document) (ogame.LfTechs, error) { +// ExtractLfResearchFromDoc ... +func (e *Extractor) ExtractLfResearchFromDoc(doc *goquery.Document) (ogame.LfResearches, error) { panic("not implemented") } diff --git a/pkg/extractor/v6/extracts.go b/pkg/extractor/v6/extracts.go index 50ae61db..f1f95862 100644 --- a/pkg/extractor/v6/extracts.go +++ b/pkg/extractor/v6/extracts.go @@ -1913,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, lfBuildingID ogame.ID, lfBuildingCountdown int64, lfTechID ogame.ID, lfTechCountdown int64) { +func extractConstructions(pageHTML []byte) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64, lfBuildingID ogame.ID, lfBuildingCountdown int64, lfResearchID ogame.ID, lfResearchCountdown 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 91f91b05..05c8139a 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, lfBuildingID ogame.ID, lfBuildingCountdown int64, lfTechID ogame.ID, lfTechCountdown int64) { +func (e Extractor) ExtractConstructions(pageHTML []byte) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64, lfBuildingID ogame.ID, lfBuildingCountdown int64, lfResearchID ogame.ID, lfResearchCountdown int64) { return ExtractConstructions(pageHTML, clockwork.NewRealClock()) } diff --git a/pkg/extractor/v7/extracts.go b/pkg/extractor/v7/extracts.go index 0590485e..110629ab 100644 --- a/pkg/extractor/v7/extracts.go +++ b/pkg/extractor/v7/extracts.go @@ -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, lfBuildingID ogame.ID, lfBuildingCountdown int64, lfTechID ogame.ID, lfTechCountdown int64) { +func ExtractConstructions(pageHTML []byte, clock clockwork.Clock) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64, lfBuildingID ogame.ID, lfBuildingCountdown int64, lfResearchID ogame.ID, lfResearchCountdown 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/v9/extractor.go b/pkg/extractor/v9/extractor.go index 56d49026..8ba61259 100644 --- a/pkg/extractor/v9/extractor.go +++ b/pkg/extractor/v9/extractor.go @@ -2,6 +2,8 @@ package v9 import ( "bytes" + "encoding/json" + "strings" "github.com/PuerkitoBio/goquery" "github.com/alaingilbert/clockwork" @@ -19,6 +21,38 @@ func NewExtractor() *Extractor { return &Extractor{} } +// ExtractTechnologyDetailsFromDoc ... +func (e *Extractor) ExtractTechnologyDetailsFromDoc(doc *goquery.Document) (ogame.TechnologyDetails, error) { + return extractTechnologyDetailsFromDoc(doc) +} + +type technologyDetailsStruct struct { + Target string `json:"target"` + Content struct { + Technologydetails string `json:"technologydetails"` + } `json:"content"` + Files struct { + Js []string `json:"js"` + CSS []string `json:"css"` + } `json:"files"` + Page struct { + StateObj string `json:"stateObj"` + Title string `json:"title"` + URL string `json:"url"` + } `json:"page"` + ServerTime int `json:"serverTime"` +} + +// ExtractTechnologyDetails ... +func (e *Extractor) ExtractTechnologyDetails(pageHTML []byte) (out ogame.TechnologyDetails, err error) { + var technologyDetails technologyDetailsStruct + if err := json.Unmarshal(pageHTML, &technologyDetails); err != nil { + return out, err + } + doc, _ := goquery.NewDocumentFromReader(strings.NewReader(technologyDetails.Content.Technologydetails)) + return e.ExtractTechnologyDetailsFromDoc(doc) +} + // ExtractCancelLfBuildingInfos ... func (e *Extractor) ExtractCancelLfBuildingInfos(pageHTML []byte) (token string, id, listID int64, err error) { return extractCancelLfBuildingInfos(pageHTML) @@ -81,7 +115,7 @@ func (e *Extractor) ExtractResourcesDetailsFromFullPageFromDoc(doc *goquery.Docu } // ExtractConstructions ... -func (e *Extractor) ExtractConstructions(pageHTML []byte) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64, lfBuildingID ogame.ID, lfBuildingCountdown int64, lfTechID ogame.ID, lfTechCountdown int64) { +func (e *Extractor) ExtractConstructions(pageHTML []byte) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64, lfBuildingID ogame.ID, lfBuildingCountdown int64, lfResearchID ogame.ID, lfResearchCountdown int64) { return ExtractConstructions(pageHTML, clockwork.NewRealClock()) } @@ -102,13 +136,24 @@ func (e *Extractor) ExtractLfBuildingsFromDoc(doc *goquery.Document) (ogame.LfBu return extractLfBuildingsFromDoc(doc) } -// ExtractLfTechs ... -func (e *Extractor) ExtractLfTechs(pageHTML []byte) (ogame.LfTechs, error) { +// ExtractLfResearch ... +func (e *Extractor) ExtractLfResearch(pageHTML []byte) (ogame.LfResearches, error) { + doc, _ := goquery.NewDocumentFromReader(bytes.NewReader(pageHTML)) + return e.ExtractLfResearchFromDoc(doc) +} + +// ExtractLfResearchFromDoc ... +func (e *Extractor) ExtractLfResearchFromDoc(doc *goquery.Document) (ogame.LfResearches, error) { + return extractLfResearchFromDoc(doc) +} + +// ExtractTearDownButtonEnabled ... +func (e *Extractor) ExtractTearDownButtonEnabled(pageHTML []byte) bool { doc, _ := goquery.NewDocumentFromReader(bytes.NewReader(pageHTML)) - return e.ExtractLfTechsFromDoc(doc) + return e.ExtractTearDownButtonEnabledFromDoc(doc) } -// ExtractLfTechsFromDoc ... -func (e *Extractor) ExtractLfTechsFromDoc(doc *goquery.Document) (ogame.LfTechs, error) { - return extractLfTechsFromDoc(doc) +// ExtractTearDownButtonEnabledFromDoc ... +func (e *Extractor) ExtractTearDownButtonEnabledFromDoc(doc *goquery.Document) bool { + return extractTearDownButtonEnabledFromDoc(doc) } diff --git a/pkg/extractor/v9/extractor_test.go b/pkg/extractor/v9/extractor_test.go index 31e33c9a..c67b7d73 100644 --- a/pkg/extractor/v9/extractor_test.go +++ b/pkg/extractor/v9/extractor_test.go @@ -181,3 +181,37 @@ func TestExtractLfBuildingsRocktal(t *testing.T) { assert.Equal(t, int64(2), res.MeditationEnclave) assert.Equal(t, int64(1), res.CrystalFarm) } + +func TestExtractTechnologyDetails(t *testing.T) { + pageHTMLBytes, _ := ioutil.ReadFile("../../../samples/v9.0.4/en/lifeform/technologyDetails_1.html") + details, err := NewExtractor().ExtractTechnologyDetails(pageHTMLBytes) + assert.NoError(t, err) + assert.Equal(t, ogame.ID(11105), details.TechnologyID) + assert.Equal(t, 41*time.Minute+12*time.Second, details.ProductionDuration) + assert.Equal(t, int64(0), details.Level) + assert.Equal(t, int64(50000), details.Price.Metal) + assert.Equal(t, int64(40000), details.Price.Crystal) + assert.Equal(t, int64(50000), details.Price.Deuterium) + assert.Equal(t, int64(100000000), details.Price.Population) + assert.False(t, details.TearDownEnabled) + + pageHTMLBytes, _ = ioutil.ReadFile("../../../samples/v9.0.4/en/lifeform/technologyDetails_lfbuilding_teardown_enabled.html") + details, err = NewExtractor().ExtractTechnologyDetails(pageHTMLBytes) + assert.NoError(t, err) + assert.Equal(t, ogame.ID(11101), details.TechnologyID) + assert.Equal(t, 6*time.Hour+58*time.Minute+48*time.Second, details.ProductionDuration) + assert.Equal(t, int64(34), details.Level) + assert.Equal(t, int64(120594), details.Price.Metal) + assert.Equal(t, int64(34455), details.Price.Crystal) + assert.Equal(t, int64(0), details.Price.Deuterium) + assert.Equal(t, int64(0), details.Price.Population) + assert.True(t, details.TearDownEnabled) + + pageHTMLBytes, _ = ioutil.ReadFile("../../../samples/v9.0.4/en/lifeform/technologyDetails_lfbuilding_teardown_disabled.html") + details, _ = NewExtractor().ExtractTechnologyDetails(pageHTMLBytes) + assert.False(t, details.TearDownEnabled) + + pageHTMLBytes, _ = ioutil.ReadFile("../../../samples/v9.0.4/en/lifeform/technologyDetails_supplies.html") + details, _ = NewExtractor().ExtractTechnologyDetails(pageHTMLBytes) + assert.True(t, details.TearDownEnabled) +} diff --git a/pkg/extractor/v9/extracts.go b/pkg/extractor/v9/extracts.go index 256901da..6bc4ba61 100644 --- a/pkg/extractor/v9/extracts.go +++ b/pkg/extractor/v9/extracts.go @@ -2,6 +2,7 @@ package v9 import ( "errors" + "fmt" "regexp" "strconv" "strings" @@ -19,7 +20,7 @@ import ( func ExtractConstructions(pageHTML []byte, clock clockwork.Clock) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64, lfBuildingID ogame.ID, lfBuildingCountdown int64, - lfTechID ogame.ID, lfTechCountdown int64) { + lfResearchID ogame.ID, lfResearchCountdown int64) { buildingCountdownMatch := regexp.MustCompile(`var restTimebuilding = (\d+) -`).FindSubmatch(pageHTML) if len(buildingCountdownMatch) > 0 { buildingCountdown = int64(utils.ToInt(buildingCountdownMatch[1])) - clock.Now().Unix() @@ -38,11 +39,11 @@ func ExtractConstructions(pageHTML []byte, clock clockwork.Clock) (buildingID og lfBuildingIDInt := utils.ToInt(regexp.MustCompile(`onclick="cancellfbuilding\((\d+),`).FindSubmatch(pageHTML)[1]) lfBuildingID = ogame.ID(lfBuildingIDInt) } - lfTechCountdownMatch := regexp.MustCompile(`var restTimelfresearch = (\d+) -`).FindSubmatch(pageHTML) - if len(lfTechCountdownMatch) > 0 { - lfTechCountdown = int64(utils.ToInt(lfTechCountdownMatch[1])) - clock.Now().Unix() - lfTechIDInt := utils.ToInt(regexp.MustCompile(`onclick="cancellfresearch\((\d+),`).FindSubmatch(pageHTML)[1]) - lfTechID = ogame.ID(lfTechIDInt) + lfResearchCountdownMatch := regexp.MustCompile(`var restTimelfresearch = (\d+) -`).FindSubmatch(pageHTML) + if len(lfResearchCountdownMatch) > 0 { + lfResearchCountdown = int64(utils.ToInt(lfResearchCountdownMatch[1])) - clock.Now().Unix() + lfResearchIDInt := utils.ToInt(regexp.MustCompile(`onclick="cancellfresearch\((\d+),`).FindSubmatch(pageHTML)[1]) + lfResearchID = ogame.ID(lfResearchIDInt) } return } @@ -638,8 +639,8 @@ func extractLfBuildingsFromDoc(doc *goquery.Document) (ogame.LfBuildings, error) return res, nil } -func extractLfTechsFromDoc(doc *goquery.Document) (ogame.LfTechs, error) { - res := ogame.LfTechs{} +func extractLfResearchFromDoc(doc *goquery.Document) (ogame.LfResearches, error) { + res := ogame.LfResearches{} // Can have any lifeform techs whatever current planet lifeform is, so take everything res.IntergalacticEnvoys = GetNbr(doc, "lifeformTech11201") res.HighPerformanceExtractors = GetNbr(doc, "lifeformTech11202") @@ -716,3 +717,38 @@ func extractLfTechsFromDoc(doc *goquery.Document) (ogame.LfTechs, error) { return res, nil } + +func extractTechnologyDetailsFromDoc(doc *goquery.Document) (out ogame.TechnologyDetails, err error) { + out.TechnologyID = ogame.ID(utils.DoParseI64(doc.Find("div#technologydetails").AttrOr("data-technology-id", ""))) + + durationStr := doc.Find("li.build_duration time").AttrOr("datetime", "") + rgx := regexp.MustCompile(`PT(?:(\d+)H)?(?:(\d+)M)?(\d+)S`) + m := rgx.FindStringSubmatch(durationStr) + if len(m) != 4 { + return out, fmt.Errorf("failed to extract duration: %s", durationStr) + } + hour := time.Duration(utils.DoParseI64(m[1])) * time.Hour + min := time.Duration(utils.DoParseI64(m[2])) * time.Minute + sec := time.Duration(utils.DoParseI64(m[3])) * time.Second + out.ProductionDuration = hour + min + sec + + out.Level = utils.DoParseI64(doc.Find("span.level").AttrOr("data-value", "")) - 1 + + out.Price.Metal = utils.DoParseI64(doc.Find("div.costs li.metal").AttrOr("data-value", "")) + out.Price.Crystal = utils.DoParseI64(doc.Find("div.costs li.crystal").AttrOr("data-value", "")) + out.Price.Deuterium = utils.DoParseI64(doc.Find("div.costs li.deuterium").AttrOr("data-value", "")) + out.Price.Population = utils.DoParseI64(doc.Find("div.costs li.population").AttrOr("data-value", "")) + + out.TearDownEnabled = extractTearDownButtonEnabledFromDoc(doc) + + return out, err +} + +func extractTearDownButtonEnabledFromDoc(doc *goquery.Document) (out bool) { + if doc.Find("button.downgrade").Length() == 1 { + if _, exists := doc.Find("button.downgrade").Attr("disabled"); !exists { + out = true + } + } + return +} diff --git a/pkg/ogame/constants.go b/pkg/ogame/constants.go index 4f23dfb3..c6c89e36 100644 --- a/pkg/ogame/constants.go +++ b/pkg/ogame/constants.go @@ -205,7 +205,7 @@ const ( AssemblyLineID ID = 13101 // Lifeform (mechas) FusionCellFactoryID ID = 13102 RoboticsResearchCentreID ID = 13103 - UpdateNetworkID ID = 12304 + UpdateNetworkID ID = 13104 QuantumComputerCentreID ID = 13105 AutomatisedAssemblyCentreID ID = 13106 HighPerformanceTransformerID ID = 13107 diff --git a/pkg/ogame/id.go b/pkg/ogame/id.go index f6cfe9ad..b526b9c6 100644 --- a/pkg/ogame/id.go +++ b/pkg/ogame/id.go @@ -156,6 +156,246 @@ func (o ID) String() string { res += "Astrophysics" case GravitonTechnologyID: res += "GravitonTechnology" + case ResidentialSectorID: + res += "ResidentialSector" + case BiosphereFarmID: + res += "BiosphereFarm" + case ResearchCentreID: + res += "ResearchCentre" + case AcademyOfSciencesID: + res += "AcademyOfSciences" + case NeuroCalibrationCentreID: + res += "NeuroCalibrationCentre" + case HighEnergySmeltingID: + res += "HighEnergySmelting" + case FoodSiloID: + res += "FoodSilo" + case FusionPoweredProductionID: + res += "FusionPoweredProduction" + case SkyscraperID: + res += "Skyscraper" + case BiotechLabID: + res += "BiotechLab" + case MetropolisID: + res += "Metropolis" + case PlanetaryShieldID: + res += "PlanetaryShield" + case MeditationEnclaveID: + res += "MeditationEnclave" + case CrystalFarmID: + res += "CrystalFarm" + case RuneTechnologiumID: + res += "RuneTechnologium" + case RuneForgeID: + res += "RuneForge" + case OriktoriumID: + res += "Oriktorium" + case MagmaForgeID: + res += "MagmaForge" + case DisruptionChamberID: + res += "DisruptionChamber" + case MegalithID: + res += "Megalith" + case CrystalRefineryID: + res += "CrystalRefinery" + case DeuteriumSynthesiserID: + res += "DeuteriumSynthesiser" + case MineralResearchCentreID: + res += "MineralResearchCentre" + case MetalRecyclingPlantID: + res += "MetalRecyclingPlant" + case AssemblyLineID: + res += "AssemblyLine" + case FusionCellFactoryID: + res += "FusionCellFactory" + case RoboticsResearchCentreID: + res += "RoboticsResearchCentre" + case UpdateNetworkID: + res += "UpdateNetwork" + case QuantumComputerCentreID: + res += "QuantumComputerCentre" + case AutomatisedAssemblyCentreID: + res += "AutomatisedAssemblyCentre" + case HighPerformanceTransformerID: + res += "HighPerformanceTransformer" + case MicrochipAssemblyLineID: + res += "MicrochipAssemblyLine" + case ProductionAssemblyHallID: + res += "ProductionAssemblyHall" + case HighPerformanceSynthesiserID: + res += "HighPerformanceSynthesiser" + case ChipMassProductionID: + res += "ChipMassProduction" + case NanoRepairBotsID: + res += "NanoRepairBots" + case SanctuaryID: + res += "Sanctuary" + case AntimatterCondenserID: + res += "AntimatterCondenser" + case VortexChamberID: + res += "VortexChamber" + case HallsOfRealisationID: + res += "HallsOfRealisation" + case ForumOfTranscendenceID: + res += "ForumOfTranscendence" + case AntimatterConvectorID: + res += "AntimatterConvector" + case CloningLaboratoryID: + res += "CloningLaboratory" + case ChrysalisAcceleratorID: + res += "ChrysalisAccelerator" + case BioModifierID: + res += "BioModifier" + case PsionicModulatorID: + res += "PsionicModulator" + case ShipManufacturingHallID: + res += "ShipManufacturingHall" + case SupraRefractorID: + res += "SupraRefractor" + case IntergalacticEnvoysID: + res += "IntergalacticEnvoys" + case HighPerformanceExtractorsID: + res += "HighPerformanceExtractors" + case FusionDrivesID: + res += "FusionDrives" + case StealthFieldGeneratorID: + res += "StealthFieldGenerator" + case OrbitalDenID: + res += "OrbitalDen" + case ResearchAIID: + res += "ResearchAI" + case HighPerformanceTerraformerID: + res += "HighPerformanceTerraformer" + case EnhancedProductionTechnologiesID: + res += "EnhancedProductionTechnologies" + case LightFighterMkIIID: + res += "LightFighterMkII" + case CruiserMkIIID: + res += "CruiserMkII" + case ImprovedLabTechnologyID: + res += "ImprovedLabTechnology" + case PlasmaTerraformerID: + res += "PlasmaTerraformer" + case LowTemperatureDrivesID: + res += "LowTemperatureDrives" + case BomberMkIIID: + res += "BomberMkII" + case DestroyerMkIIID: + res += "DestroyerMkII" + case BattlecruiserMkIIID: + res += "BattlecruiserMkII" + case RobotAssistantsID: + res += "RobotAssistants" + case SupercomputerID: + res += "Supercomputer" + case VolcanicBatteriesID: + res += "VolcanicBatteries" + case AcousticScanningID: + res += "AcousticScanning" + case HighEnergyPumpSystemsID: + res += "HighEnergyPumpSystems" + case CargoHoldExpansionCivilianShipsID: + res += "CargoHoldExpansionCivilianShips" + case MagmaPoweredProductionID: + res += "MagmaPoweredProduction" + case GeothermalPowerPlantsID: + res += "GeothermalPowerPlants" + case DepthSoundingID: + res += "DepthSounding" + case IonCrystalEnhancementHeavyFighterID: + res += "IonCrystalEnhancementHeavyFighter" + case ImprovedStellaratorID: + res += "ImprovedStellarator" + case HardenedDiamondDrillHeadsID: + res += "HardenedDiamondDrillHeads" + case SeismicMiningTechnologyID: + res += "SeismicMiningTechnology" + case MagmaPoweredPumpSystemsID: + res += "MagmaPoweredPumpSystems" + case IonCrystalModulesID: + res += "IonCrystalModules" + case OptimisedSiloConstructionMethodID: + res += "OptimisedSiloConstructionMethod" + case DiamondEnergyTransmitterID: + res += "DiamondEnergyTransmitter" + case ObsidianShieldReinforcementID: + res += "ObsidianShieldReinforcement" + case RuneShieldsID: + res += "RuneShields" + case RocktalCollectorEnhancementID: + res += "RocktalCollectorEnhancement" + case CatalyserTechnologyID: + res += "CatalyserTechnology" + case PlasmaDriveID: + res += "PlasmaDrive" + case EfficiencyModuleID: + res += "EfficiencyModule" + case DepotAIID: + res += "DepotAI" + case GeneralOverhaulLightFighterID: + res += "GeneralOverhaulLightFighter" + case AutomatedTransportLinesID: + res += "AutomatedTransportLines" + case ImprovedDroneAIID: + res += "ImprovedDroneAI" + case ExperimentalRecyclingTechnologyID: + res += "ExperimentalRecyclingTechnology" + case GeneralOverhaulCruiserID: + res += "GeneralOverhaulCruiser" + case SlingshotAutopilotID: + res += "SlingshotAutopilot" + case HighTemperatureSuperconductorsID: + res += "HighTemperatureSuperconductors" + case GeneralOverhaulBattleshipID: + res += "GeneralOverhaulBattleship" + case ArtificialSwarmIntelligenceID: + res += "ArtificialSwarmIntelligence" + case GeneralOverhaulBattlecruiserID: + res += "GeneralOverhaulBattlecruiser" + case GeneralOverhaulBomberID: + res += "GeneralOverhaulBomber" + case GeneralOverhaulDestroyerID: + res += "GeneralOverhaulDestroyer" + case ExperimentalWeaponsTechnologyID: + res += "ExperimentalWeaponsTechnology" + case MechanGeneralEnhancementID: + res += "MechanGeneralEnhancement" + case HeatRecoveryID: + res += "HeatRecovery" + case SulphideProcessID: + res += "SulphideProcess" + case PsionicNetworkID: + res += "PsionicNetwork" + case TelekineticTractorBeamID: + res += "TelekineticTractorBeam" + case EnhancedSensorTechnologyID: + res += "EnhancedSensorTechnology" + case NeuromodalCompressorID: + res += "NeuromodalCompressor" + case NeuroInterfaceID: + res += "NeuroInterface" + case InterplanetaryAnalysisNetworkID: + res += "InterplanetaryAnalysisNetwork" + case OverclockingHeavyFighterID: + res += "OverclockingHeavyFighter" + case TelekineticDriveID: + res += "TelekineticDrive" + case SixthSenseID: + res += "SixthSense" + case PsychoharmoniserID: + res += "Psychoharmoniser" + case EfficientSwarmIntelligenceID: + res += "EfficientSwarmIntelligence" + case OverclockingLargeCargoID: + res += "OverclockingLargeCargo" + case GravitationSensorsID: + res += "GravitationSensors" + case OverclockingBattleshipID: + res += "OverclockingBattleship" + case PsionicShieldMatrixID: + res += "PsionicShieldMatrix" + case KaeleshDiscovererEnhancementID: + res += "KaeleshDiscovererEnhancement" default: res += "Invalid(" + strconv.FormatInt(int64(o), 10) + ")" } @@ -273,7 +513,7 @@ func (o ID) IsTech() bool { o == GravitonTechnologyID } -// IsLsTech returns either or not the id is a lifeform technology +// IsLfTech returns either or not the id is a lifeform technology func (o ID) IsLfTech() bool { return o == IntergalacticEnvoysID || //Humans o == HighPerformanceExtractorsID || diff --git a/pkg/ogame/lfBuildings.go b/pkg/ogame/lfBuildings.go index 9fae3670..ae400677 100644 --- a/pkg/ogame/lfBuildings.go +++ b/pkg/ogame/lfBuildings.go @@ -399,11 +399,6 @@ func newPlanetaryShield() *planetaryShield { return b } -// BaseLfTechnology base struct for lifeform technologies -type BaseLfTechnology struct { - BaseLevelable -} - // Rocktal type meditationEnclave struct { BaseLfBuilding diff --git a/pkg/ogame/lfBuildings_test.go b/pkg/ogame/lfBuildings_test.go index ed4896b4..2c40e56e 100644 --- a/pkg/ogame/lfBuildings_test.go +++ b/pkg/ogame/lfBuildings_test.go @@ -10,6 +10,7 @@ func TestResidentialSectorCost(t *testing.T) { assert.Equal(t, Resources{Metal: 7, Crystal: 2}, a.GetPrice(1)) assert.Equal(t, Resources{Metal: 16, Crystal: 4}, a.GetPrice(2)) assert.Equal(t, Resources{Metal: 30, Crystal: 8}, a.GetPrice(3)) + assert.Equal(t, Resources{Metal: 120594, Crystal: 34455}, a.GetPrice(35)) } func TestBiosphereFarmCost(t *testing.T) { @@ -23,3 +24,8 @@ func TestResearchCenterCost(t *testing.T) { assert.Equal(t, Resources{Metal: 20000, Crystal: 25000, Deuterium: 10000}, a.GetPrice(1)) assert.Equal(t, Resources{Metal: 52000, Crystal: 65000, Deuterium: 26000}, a.GetPrice(2)) } + +//func TestResidentialSectorConstructionTime(t *testing.T) { +// rs := newResidentialSector() +// assert.Equal(t, (6*60*60+58*60+48)*time.Second, rs.ConstructionTime(35, 4, Facilities{}, false, false)) +//} diff --git a/pkg/ogame/lfTechs.go b/pkg/ogame/lfResearches.go similarity index 95% rename from pkg/ogame/lfTechs.go rename to pkg/ogame/lfResearches.go index c6dff005..8e881751 100644 --- a/pkg/ogame/lfTechs.go +++ b/pkg/ogame/lfResearches.go @@ -4,15 +4,10 @@ import ( "math" ) -// LazyLfTechs ... -type LazyLfTechs func() LfTechs - -type LfTechs struct { - None bool - Humans bool - Rocktal bool - Mechas bool - Kaelesh bool +// LazyLfResearches ... +type LazyLfResearches func() LfResearches + +type LfResearches struct { IntergalacticEnvoys int64 // Humans techs HighPerformanceExtractors int64 FusionDrives int64 @@ -87,12 +82,12 @@ type LfTechs struct { KaeleshDiscovererEnhancement int64 } -func (b LfTechs) Lazy() LazyLfTechs { - return func() LfTechs { return b } +func (b LfResearches) Lazy() LazyLfResearches { + return func() LfResearches { return b } } -// ByID gets the lfTechs level by lfTechs id -func (b LfTechs) ByID(id ID) int64 { +// ByID gets the research level by lfResearch id +func (b LfResearches) ByID(id ID) int64 { switch id { case IntergalacticEnvoysID: return b.IntergalacticEnvoys @@ -242,13 +237,13 @@ func (b LfTechs) ByID(id ID) int64 { return 0 } -// BaseLfTechs base struct for Lifeform techs -type BaseLfTechs struct { +// BaseLfResearch base struct for Lifeform techs +type BaseLfResearch struct { BaseTechnology } // GetPrice returns the price to build the given level -func (b BaseLfTechs) GetPrice(level int64) Resources { +func (b BaseLfResearch) 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)) } @@ -261,7 +256,7 @@ func (b BaseLfTechs) GetPrice(level int64) Resources { // Humans type intergalacticEnvoys struct { - BaseLfTechs + BaseLfResearch } func newIntergalacticEnvoys() *intergalacticEnvoys { @@ -275,7 +270,7 @@ func newIntergalacticEnvoys() *intergalacticEnvoys { } type highPerformanceExtractors struct { - BaseLfTechs + BaseLfResearch } func newHighPerformanceExtractors() *highPerformanceExtractors { @@ -289,7 +284,7 @@ func newHighPerformanceExtractors() *highPerformanceExtractors { } type fusionDrives struct { - BaseLfTechs + BaseLfResearch } func newFusionDrives() *fusionDrives { @@ -303,7 +298,7 @@ func newFusionDrives() *fusionDrives { } type stealthFieldGenerator struct { - BaseLfTechs + BaseLfResearch } func newStealthFieldGenerator() *stealthFieldGenerator { @@ -317,7 +312,7 @@ func newStealthFieldGenerator() *stealthFieldGenerator { } type orbitalDen struct { - BaseLfTechs + BaseLfResearch } func newOrbitalDen() *orbitalDen { @@ -331,7 +326,7 @@ func newOrbitalDen() *orbitalDen { } type researchAI struct { - BaseLfTechs + BaseLfResearch } func newResearchAI() *researchAI { @@ -345,7 +340,7 @@ func newResearchAI() *researchAI { } type highPerformanceTerraformer struct { - BaseLfTechs + BaseLfResearch } func newHighPerformanceTerraformer() *highPerformanceTerraformer { @@ -359,7 +354,7 @@ func newHighPerformanceTerraformer() *highPerformanceTerraformer { } type enhancedProductionTechnologies struct { - BaseLfTechs + BaseLfResearch } func newEnhancedProductionTechnologies() *enhancedProductionTechnologies { @@ -373,7 +368,7 @@ func newEnhancedProductionTechnologies() *enhancedProductionTechnologies { } type lightFighterMkII struct { - BaseLfTechs + BaseLfResearch } func newLightFighterMkII() *lightFighterMkII { @@ -387,7 +382,7 @@ func newLightFighterMkII() *lightFighterMkII { } type cruiserMkII struct { - BaseLfTechs + BaseLfResearch } func newCruiserMkII() *cruiserMkII { @@ -401,7 +396,7 @@ func newCruiserMkII() *cruiserMkII { } type improvedLabTechnology struct { - BaseLfTechs + BaseLfResearch } func newImprovedLabTechnology() *improvedLabTechnology { @@ -415,7 +410,7 @@ func newImprovedLabTechnology() *improvedLabTechnology { } type plasmaTerraformer struct { - BaseLfTechs + BaseLfResearch } func newPlasmaTerraformer() *plasmaTerraformer { @@ -429,7 +424,7 @@ func newPlasmaTerraformer() *plasmaTerraformer { } type lowTemperatureDrives struct { - BaseLfTechs + BaseLfResearch } func newLowTemperatureDrives() *lowTemperatureDrives { @@ -443,7 +438,7 @@ func newLowTemperatureDrives() *lowTemperatureDrives { } type bomberMkII struct { - BaseLfTechs + BaseLfResearch } func newBomberMkII() *bomberMkII { @@ -457,7 +452,7 @@ func newBomberMkII() *bomberMkII { } type destroyerMkII struct { - BaseLfTechs + BaseLfResearch } func newDestroyerMkII() *destroyerMkII { @@ -471,7 +466,7 @@ func newDestroyerMkII() *destroyerMkII { } type battlecruiserMkII struct { - BaseLfTechs + BaseLfResearch } func newBattlecruiserMkII() *battlecruiserMkII { @@ -485,7 +480,7 @@ func newBattlecruiserMkII() *battlecruiserMkII { } type robotAssistants struct { - BaseLfTechs + BaseLfResearch } func newRobotAssistants() *robotAssistants { @@ -499,7 +494,7 @@ func newRobotAssistants() *robotAssistants { } type supercomputer struct { - BaseLfTechs + BaseLfResearch } func newSupercomputer() *supercomputer { @@ -514,7 +509,7 @@ func newSupercomputer() *supercomputer { //Rocktal type volcanicBatteries struct { - BaseLfTechs + BaseLfResearch } func newVolcanicBatteries() *volcanicBatteries { @@ -528,7 +523,7 @@ func newVolcanicBatteries() *volcanicBatteries { } type acousticScanning struct { - BaseLfTechs + BaseLfResearch } func newAcousticScanning() *acousticScanning { @@ -542,7 +537,7 @@ func newAcousticScanning() *acousticScanning { } type highEnergyPumpSystems struct { - BaseLfTechs + BaseLfResearch } func newHighEnergyPumpSystems() *highEnergyPumpSystems { @@ -556,7 +551,7 @@ func newHighEnergyPumpSystems() *highEnergyPumpSystems { } type cargoHoldExpansionCivilianShips struct { - BaseLfTechs + BaseLfResearch } func newCargoHoldExpansionCivilianShips() *cargoHoldExpansionCivilianShips { @@ -570,7 +565,7 @@ func newCargoHoldExpansionCivilianShips() *cargoHoldExpansionCivilianShips { } type magmaPoweredProduction struct { - BaseLfTechs + BaseLfResearch } func newMagmaPoweredProduction() *magmaPoweredProduction { @@ -584,7 +579,7 @@ func newMagmaPoweredProduction() *magmaPoweredProduction { } type geothermalPowerPlants struct { - BaseLfTechs + BaseLfResearch } func newGeothermalPowerPlants() *geothermalPowerPlants { @@ -598,7 +593,7 @@ func newGeothermalPowerPlants() *geothermalPowerPlants { } type depthSounding struct { - BaseLfTechs + BaseLfResearch } func newDepthSounding() *depthSounding { @@ -612,7 +607,7 @@ func newDepthSounding() *depthSounding { } type ionCrystalEnhancementHeavyFighter struct { - BaseLfTechs + BaseLfResearch } func newIonCrystalEnhancementHeavyFighter() *ionCrystalEnhancementHeavyFighter { @@ -626,7 +621,7 @@ func newIonCrystalEnhancementHeavyFighter() *ionCrystalEnhancementHeavyFighter { } type improvedStellarator struct { - BaseLfTechs + BaseLfResearch } func newImprovedStellarator() *improvedStellarator { @@ -640,7 +635,7 @@ func newImprovedStellarator() *improvedStellarator { } type hardenedDiamondDrillHeads struct { - BaseLfTechs + BaseLfResearch } func newHardenedDiamondDrillHeads() *hardenedDiamondDrillHeads { @@ -654,7 +649,7 @@ func newHardenedDiamondDrillHeads() *hardenedDiamondDrillHeads { } type seismicMiningTechnology struct { - BaseLfTechs + BaseLfResearch } func newSeismicMiningTechnology() *seismicMiningTechnology { @@ -668,7 +663,7 @@ func newSeismicMiningTechnology() *seismicMiningTechnology { } type magmaPoweredPumpSystems struct { - BaseLfTechs + BaseLfResearch } func newMagmaPoweredPumpSystems() *magmaPoweredPumpSystems { @@ -682,7 +677,7 @@ func newMagmaPoweredPumpSystems() *magmaPoweredPumpSystems { } type ionCrystalModules struct { - BaseLfTechs + BaseLfResearch } func newIonCrystalModules() *ionCrystalModules { @@ -696,7 +691,7 @@ func newIonCrystalModules() *ionCrystalModules { } type optimisedSiloConstructionMethod struct { - BaseLfTechs + BaseLfResearch } func newOptimisedSiloConstructionMethod() *optimisedSiloConstructionMethod { @@ -710,7 +705,7 @@ func newOptimisedSiloConstructionMethod() *optimisedSiloConstructionMethod { } type diamondEnergyTransmitter struct { - BaseLfTechs + BaseLfResearch } func newDiamondEnergyTransmitter() *diamondEnergyTransmitter { @@ -724,7 +719,7 @@ func newDiamondEnergyTransmitter() *diamondEnergyTransmitter { } type obsidianShieldReinforcement struct { - BaseLfTechs + BaseLfResearch } func newObsidianShieldReinforcement() *obsidianShieldReinforcement { @@ -738,7 +733,7 @@ func newObsidianShieldReinforcement() *obsidianShieldReinforcement { } type runeShields struct { - BaseLfTechs + BaseLfResearch } func newRuneShields() *runeShields { @@ -752,7 +747,7 @@ func newRuneShields() *runeShields { } type rocktalCollectorEnhancement struct { - BaseLfTechs + BaseLfResearch } func newRocktalCollectorEnhancement() *rocktalCollectorEnhancement { @@ -768,7 +763,7 @@ func newRocktalCollectorEnhancement() *rocktalCollectorEnhancement { //Mechas type catalyserTechnology struct { - BaseLfTechs + BaseLfResearch } func newCatalyserTechnology() *catalyserTechnology { @@ -782,7 +777,7 @@ func newCatalyserTechnology() *catalyserTechnology { } type plasmaDrive struct { - BaseLfTechs + BaseLfResearch } func newPlasmaDrive() *plasmaDrive { @@ -796,7 +791,7 @@ func newPlasmaDrive() *plasmaDrive { } type efficiencyModule struct { - BaseLfTechs + BaseLfResearch } func newEfficiencyModule() *efficiencyModule { @@ -810,7 +805,7 @@ func newEfficiencyModule() *efficiencyModule { } type depotAI struct { - BaseLfTechs + BaseLfResearch } func newDepotAI() *depotAI { @@ -824,7 +819,7 @@ func newDepotAI() *depotAI { } type generalOverhaulLightFighter struct { - BaseLfTechs + BaseLfResearch } func newGeneralOverhaulLightFighter() *generalOverhaulLightFighter { @@ -838,7 +833,7 @@ func newGeneralOverhaulLightFighter() *generalOverhaulLightFighter { } type automatedTransportLines struct { - BaseLfTechs + BaseLfResearch } func newAutomatedTransportLines() *automatedTransportLines { @@ -852,7 +847,7 @@ func newAutomatedTransportLines() *automatedTransportLines { } type improvedDroneAI struct { - BaseLfTechs + BaseLfResearch } func newImprovedDroneAI() *improvedDroneAI { @@ -866,7 +861,7 @@ func newImprovedDroneAI() *improvedDroneAI { } type experimentalRecyclingTechnology struct { - BaseLfTechs + BaseLfResearch } func newExperimentalRecyclingTechnology() *experimentalRecyclingTechnology { @@ -880,7 +875,7 @@ func newExperimentalRecyclingTechnology() *experimentalRecyclingTechnology { } type generalOverhaulCruiser struct { - BaseLfTechs + BaseLfResearch } func newGeneralOverhaulCruiser() *generalOverhaulCruiser { @@ -894,7 +889,7 @@ func newGeneralOverhaulCruiser() *generalOverhaulCruiser { } type slingshotAutopilot struct { - BaseLfTechs + BaseLfResearch } func newSlingshotAutopilot() *slingshotAutopilot { @@ -908,7 +903,7 @@ func newSlingshotAutopilot() *slingshotAutopilot { } type highTemperatureSuperconductors struct { - BaseLfTechs + BaseLfResearch } func newHighTemperatureSuperconductors() *highTemperatureSuperconductors { @@ -922,7 +917,7 @@ func newHighTemperatureSuperconductors() *highTemperatureSuperconductors { } type generalOverhaulBattleship struct { - BaseLfTechs + BaseLfResearch } func newGeneralOverhaulBattleship() *generalOverhaulBattleship { @@ -936,7 +931,7 @@ func newGeneralOverhaulBattleship() *generalOverhaulBattleship { } type artificialSwarmIntelligence struct { - BaseLfTechs + BaseLfResearch } func newArtificialSwarmIntelligence() *artificialSwarmIntelligence { @@ -950,7 +945,7 @@ func newArtificialSwarmIntelligence() *artificialSwarmIntelligence { } type generalOverhaulBattlecruiser struct { - BaseLfTechs + BaseLfResearch } func newGeneralOverhaulBattlecruiser() *generalOverhaulBattlecruiser { @@ -964,7 +959,7 @@ func newGeneralOverhaulBattlecruiser() *generalOverhaulBattlecruiser { } type generalOverhaulBomber struct { - BaseLfTechs + BaseLfResearch } func newGeneralOverhaulBomber() *generalOverhaulBomber { @@ -978,7 +973,7 @@ func newGeneralOverhaulBomber() *generalOverhaulBomber { } type generalOverhaulDestroyer struct { - BaseLfTechs + BaseLfResearch } func newGeneralOverhaulDestroyer() *generalOverhaulDestroyer { @@ -992,7 +987,7 @@ func newGeneralOverhaulDestroyer() *generalOverhaulDestroyer { } type experimentalWeaponsTechnology struct { - BaseLfTechs + BaseLfResearch } func newExperimentalWeaponsTechnology() *experimentalWeaponsTechnology { @@ -1006,7 +1001,7 @@ func newExperimentalWeaponsTechnology() *experimentalWeaponsTechnology { } type mechanGeneralEnhancement struct { - BaseLfTechs + BaseLfResearch } func newMechanGeneralEnhancement() *mechanGeneralEnhancement { @@ -1021,7 +1016,7 @@ func newMechanGeneralEnhancement() *mechanGeneralEnhancement { //Kaelesh type heatRecovery struct { - BaseLfTechs + BaseLfResearch } func newHeatRecovery() *heatRecovery { @@ -1035,7 +1030,7 @@ func newHeatRecovery() *heatRecovery { } type sulphideProcess struct { - BaseLfTechs + BaseLfResearch } func newSulphideProcess() *sulphideProcess { @@ -1049,7 +1044,7 @@ func newSulphideProcess() *sulphideProcess { } type psionicNetwork struct { - BaseLfTechs + BaseLfResearch } func newPsionicNetwork() *psionicNetwork { @@ -1063,7 +1058,7 @@ func newPsionicNetwork() *psionicNetwork { } type telekineticTractorBeam struct { - BaseLfTechs + BaseLfResearch } func newTelekineticTractorBeam() *telekineticTractorBeam { @@ -1077,7 +1072,7 @@ func newTelekineticTractorBeam() *telekineticTractorBeam { } type enhancedSensorTechnology struct { - BaseLfTechs + BaseLfResearch } func newEnhancedSensorTechnology() *enhancedSensorTechnology { @@ -1091,7 +1086,7 @@ func newEnhancedSensorTechnology() *enhancedSensorTechnology { } type neuromodalCompressor struct { - BaseLfTechs + BaseLfResearch } func newNeuromodalCompressor() *neuromodalCompressor { @@ -1105,7 +1100,7 @@ func newNeuromodalCompressor() *neuromodalCompressor { } type neuroInterface struct { - BaseLfTechs + BaseLfResearch } func newNeuroInterface() *neuroInterface { @@ -1119,7 +1114,7 @@ func newNeuroInterface() *neuroInterface { } type interplanetaryAnalysisNetwork struct { - BaseLfTechs + BaseLfResearch } func newInterplanetaryAnalysisNetwork() *interplanetaryAnalysisNetwork { @@ -1133,7 +1128,7 @@ func newInterplanetaryAnalysisNetwork() *interplanetaryAnalysisNetwork { } type overclockingHeavyFighter struct { - BaseLfTechs + BaseLfResearch } func newOverclockingHeavyFighter() *overclockingHeavyFighter { @@ -1147,7 +1142,7 @@ func newOverclockingHeavyFighter() *overclockingHeavyFighter { } type telekineticDrive struct { - BaseLfTechs + BaseLfResearch } func newTelekineticDrive() *telekineticDrive { @@ -1161,7 +1156,7 @@ func newTelekineticDrive() *telekineticDrive { } type sixthSense struct { - BaseLfTechs + BaseLfResearch } func newSixthSense() *sixthSense { @@ -1175,7 +1170,7 @@ func newSixthSense() *sixthSense { } type psychoharmoniser struct { - BaseLfTechs + BaseLfResearch } func newPsychoharmoniser() *psychoharmoniser { @@ -1189,7 +1184,7 @@ func newPsychoharmoniser() *psychoharmoniser { } type efficientSwarmIntelligence struct { - BaseLfTechs + BaseLfResearch } func newEfficientSwarmIntelligence() *efficientSwarmIntelligence { @@ -1203,7 +1198,7 @@ func newEfficientSwarmIntelligence() *efficientSwarmIntelligence { } type overclockingLargeCargo struct { - BaseLfTechs + BaseLfResearch } func newOverclockingLargeCargo() *overclockingLargeCargo { @@ -1217,7 +1212,7 @@ func newOverclockingLargeCargo() *overclockingLargeCargo { } type gravitationSensors struct { - BaseLfTechs + BaseLfResearch } func newGravitationSensors() *gravitationSensors { @@ -1231,7 +1226,7 @@ func newGravitationSensors() *gravitationSensors { } type overclockingBattleship struct { - BaseLfTechs + BaseLfResearch } func newOverclockingBattleship() *overclockingBattleship { @@ -1245,7 +1240,7 @@ func newOverclockingBattleship() *overclockingBattleship { } type psionicShieldMatrix struct { - BaseLfTechs + BaseLfResearch } func newPsionicShieldMatrix() *psionicShieldMatrix { @@ -1259,7 +1254,7 @@ func newPsionicShieldMatrix() *psionicShieldMatrix { } type kaeleshDiscovererEnhancement struct { - BaseLfTechs + BaseLfResearch } func newKaeleshDiscovererEnhancement() *kaeleshDiscovererEnhancement { diff --git a/pkg/ogame/technologyDetails.go b/pkg/ogame/technologyDetails.go new file mode 100644 index 00000000..a8f5be0a --- /dev/null +++ b/pkg/ogame/technologyDetails.go @@ -0,0 +1,11 @@ +package ogame + +import "time" + +type TechnologyDetails struct { + TechnologyID ID + ProductionDuration time.Duration + Price Resources + Level int64 + TearDownEnabled bool +} diff --git a/pkg/parser/fullPage.go b/pkg/parser/fullPage.go index 38185ac5..0776899f 100644 --- a/pkg/parser/fullPage.go +++ b/pkg/parser/fullPage.go @@ -46,10 +46,6 @@ 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 index 0738f829..9dd40667 100644 --- a/pkg/parser/lfbuildingsPage.go +++ b/pkg/parser/lfbuildingsPage.go @@ -2,6 +2,6 @@ package parser import "github.com/alaingilbert/ogame/pkg/ogame" -func (p SuppliesPage) ExtractLfBuildings() (ogame.LfBuildings, error) { +func (p LfBuildingsPage) ExtractLfBuildings() (ogame.LfBuildings, error) { return p.e.ExtractLfBuildingsFromDoc(p.GetDoc()) } diff --git a/pkg/parser/lftechsPage.go b/pkg/parser/lftechsPage.go index 3e2b0b8f..fe8dccb0 100644 --- a/pkg/parser/lftechsPage.go +++ b/pkg/parser/lftechsPage.go @@ -2,6 +2,6 @@ package parser import "github.com/alaingilbert/ogame/pkg/ogame" -func (p LfTechsPage) ExtractLfTechs() (ogame.LfTechs, error) { - return p.e.ExtractLfTechsFromDoc(p.GetDoc()) +func (p LfResearchPage) ExtractLfResearch() (ogame.LfResearches, error) { + return p.e.ExtractLfResearchFromDoc(p.GetDoc()) } diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index c068cf05..9a0595cb 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -46,7 +46,7 @@ type ShipyardPage struct{ FullPage } type DefensesPage struct{ FullPage } type MovementPage struct{ FullPage } type LfBuildingsPage struct{ FullPage } -type LfTechsPage struct{ FullPage } +type LfResearchPage struct{ FullPage } type FullPagePages interface { OverviewPage | @@ -55,7 +55,7 @@ type FullPagePages interface { ResourcesSettingsPage | FacilitiesPage | LfBuildingsPage | - LfTechsPage | + LfResearchPage | //TraderOverviewPageContent | //TraderResourcesPageContent | ResearchPage | @@ -134,8 +134,8 @@ func ParsePage[T FullPagePages](e extractor.Extractor, pageHTML []byte) (T, erro return T(FacilitiesPage{fullPage}), nil case LfBuildingsPage: return T(LfBuildingsPage{fullPage}), nil - case LfTechsPage: - return T(LfTechsPage{fullPage}), nil + case LfResearchPage: + return T(LfResearchPage{fullPage}), nil case SuppliesPage: return T(SuppliesPage{fullPage}), nil case ResourcesSettingsPage: diff --git a/pkg/wrapper/fetcher.go b/pkg/wrapper/fetcher.go index 2e5076bf..7bfecdbb 100644 --- a/pkg/wrapper/fetcher.go +++ b/pkg/wrapper/fetcher.go @@ -12,8 +12,8 @@ const ( PreferencesPageName = "preferences" ResourceSettingsPageName = "resourceSettings" DefensesPageName = "defenses" - LfbuildingsPageName = "lfbuildings" - LftechsPageName = "lfresearch" + LfBuildingsPageName = "lfbuildings" + LfResearchPageName = "lfresearch" SuppliesPageName = "supplies" FacilitiesPageName = "facilities" FleetdispatchPageName = "fleetdispatch" @@ -85,9 +85,9 @@ func getPage[T parser.FullPagePages](b *OGame, opts ...Option) (T, error) { case parser.ResearchPage: pageName = ResearchPageName case parser.LfBuildingsPage: - pageName = LfbuildingsPageName - case parser.LfTechsPage: - pageName = LftechsPageName + pageName = LfBuildingsPageName + case parser.LfResearchPage: + pageName = LfResearchPageName case parser.ShipyardPage: pageName = ShipyardPageName case parser.ResourcesSettingsPage: diff --git a/pkg/wrapper/gameforge.go b/pkg/wrapper/gameforge.go index 710a17ab..70e7d0bd 100644 --- a/pkg/wrapper/gameforge.go +++ b/pkg/wrapper/gameforge.go @@ -527,13 +527,12 @@ type ServerData struct { Domain string `xml:"domain"` // s157-ru.ogame.gameforge.com Version string `xml:"version"` // 6.8.8-pl2 Speed int64 `xml:"speed"` // 6 - SpeedFleet int64 `xml:"speedFleet"` // 6 // Deprecated in 8.1.0 SpeedFleetPeaceful int64 `xml:"speedFleetPeaceful"` // 1 SpeedFleetWar int64 `xml:"speedFleetWar"` // 1 SpeedFleetHolding int64 `xml:"speedFleetHolding"` // 1 Galaxies int64 `xml:"galaxies"` // 4 Systems int64 `xml:"systems"` // 499 - ACS bool `xml:"aCS"` // 1 + ACS bool `xml:"acs"` // 1 RapidFire bool `xml:"rapidFire"` // 1 DefToTF bool `xml:"defToTF"` // 0 DebrisFactor float64 `xml:"debrisFactor"` // 0.5 @@ -541,6 +540,7 @@ type ServerData struct { RepairFactor float64 `xml:"repairFactor"` // 0.7 NewbieProtectionLimit int64 `xml:"newbieProtectionLimit"` // 500000 NewbieProtectionHigh int64 `xml:"newbieProtectionHigh"` // 50000 + TopScore float64 `xml:"topScore"` // 60259362 / 1.0363090034999E+17 BonusFields int64 `xml:"bonusFields"` // 30 DonutGalaxy bool `xml:"donutGalaxy"` // 1 DonutSystem bool `xml:"donutSystem"` // 1 @@ -554,7 +554,7 @@ type ServerData struct { ResearchDurationDivisor int64 `xml:"researchDurationDivisor"` // 2 DarkMatterNewAcount int64 `xml:"darkMatterNewAcount"` // 8000 CargoHyperspaceTechMultiplier int64 `xml:"cargoHyperspaceTechMultiplier"` // 5 - //TopScore int64 `xml:"topScore"` // 60259362 / 1.0363090034999E+17 + SpeedFleet int64 `xml:"speedFleet"` // 6 // Deprecated in 8.1.0 } // GetServerData gets the server data from xml api diff --git a/pkg/wrapper/handlers.go b/pkg/wrapper/handlers.go index 1b9499c4..4260c154 100644 --- a/pkg/wrapper/handlers.go +++ b/pkg/wrapper/handlers.go @@ -552,14 +552,14 @@ func GetLfBuildingsHandler(c echo.Context) error { return c.JSON(http.StatusOK, SuccessResp(res)) } -// GetLfTechsHandler ... -func GetLfTechsHandler(c echo.Context) error { +// GetLfResearchHandler ... +func GetLfResearchHandler(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.GetLfTechs(ogame.CelestialID(planetID)) + res, err := bot.GetLfResearch(ogame.CelestialID(planetID)) if err != nil { return c.JSON(http.StatusInternalServerError, ErrorResp(500, err.Error())) } @@ -778,7 +778,7 @@ func ConstructionsBeingBuiltHandler(c echo.Context) error { if err != nil { return c.JSON(http.StatusBadRequest, ErrorResp(400, "invalid planet id")) } - buildingID, buildingCountdown, researchID, researchCountdown, lfBuildingID, lfBuildingCountdown, LFTechID, lfTechCountdown := bot.ConstructionsBeingBuilt(ogame.CelestialID(planetID)) + buildingID, buildingCountdown, researchID, researchCountdown, lfBuildingID, lfBuildingCountdown, lfResearchID, lfResearchCountdown := bot.ConstructionsBeingBuilt(ogame.CelestialID(planetID)) return c.JSON(http.StatusOK, SuccessResp( struct { BuildingID int64 @@ -787,8 +787,8 @@ func ConstructionsBeingBuiltHandler(c echo.Context) error { ResearchCountdown int64 LfBuildingID int64 LfBuildingCountdown int64 - LfTechID int64 - LfTechCountdown int64 + LfResearchID int64 + LfResearchCountdown int64 }{ BuildingID: int64(buildingID), BuildingCountdown: buildingCountdown, @@ -796,8 +796,8 @@ func ConstructionsBeingBuiltHandler(c echo.Context) error { ResearchCountdown: researchCountdown, LfBuildingID: int64(lfBuildingID), LfBuildingCountdown: lfBuildingCountdown, - LfTechID: int64(LFTechID), - LfTechCountdown: lfTechCountdown, + LfResearchID: int64(lfResearchID), + LfResearchCountdown: lfResearchCountdown, }, )) } @@ -1405,3 +1405,43 @@ func GetCaptchaSolverHandler(c echo.Context) error { } return c.Redirect(http.StatusTemporaryRedirect, "/") } + +// CaptchaChallenge ... +type CaptchaChallenge struct { + ID string + Question string + Icons string +} + +// GetCaptchaChallengeHandler ... +func GetCaptchaChallengeHandler(c echo.Context) error { + bot := c.Get("bot").(*OGame) + _, err := GFLogin(bot.client, bot.ctx, bot.lobby, bot.Username, bot.password, bot.otpSecret, "") + var captchaErr *CaptchaRequiredError + if errors.As(err, &captchaErr) { + questionRaw, iconsRaw, err := StartCaptchaChallenge(bot.GetClient(), bot.ctx, captchaErr.ChallengeID) + if err != nil { + return c.JSON(http.StatusInternalServerError, ErrorResp(500, err.Error())) + } + questionB64 := base64.StdEncoding.EncodeToString(questionRaw) + iconsB64 := base64.StdEncoding.EncodeToString(iconsRaw) + return c.JSON(http.StatusOK, SuccessResp(CaptchaChallenge{ + ID: captchaErr.ChallengeID, + Question: questionB64, + Icons: iconsB64, + })) + } else if err != nil { + return c.JSON(http.StatusInternalServerError, ErrorResp(500, err.Error())) + } + return c.JSON(http.StatusOK, SuccessResp(CaptchaChallenge{})) +} + +// GetPublicIPHandler ... +func GetPublicIPHandler(c echo.Context) error { + bot := c.Get("bot").(*OGame) + ip, err := bot.GetPublicIP() + if err != nil { + return c.JSON(http.StatusInternalServerError, ErrorResp(500, err.Error())) + } + return c.JSON(http.StatusOK, SuccessResp(ip)) +} diff --git a/pkg/wrapper/interfaces.go b/pkg/wrapper/interfaces.go index ae3e15aa..5528e68f 100644 --- a/pkg/wrapper/interfaces.go +++ b/pkg/wrapper/interfaces.go @@ -30,7 +30,7 @@ type Celestial interface { GetFacilities(...Option) (ogame.Facilities, error) GetItems() ([]ogame.Item, error) GetLfBuildings(...Option) (ogame.LfBuildings, error) - GetLfTechs(...Option) (ogame.LfTechs, error) + GetLfResearch(...Option) (ogame.LfResearches, error) GetProduction() ([]ogame.Quantifiable, int64, error) GetResources() (ogame.Resources, error) GetResourcesBuildings(...Option) (ogame.ResourcesBuildings, error) @@ -117,12 +117,12 @@ 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, lfBuildingID ogame.ID, lfBuildingCountdown int64, lfTechID ogame.ID, lfTechCountdown int64) + ConstructionsBeingBuilt(ogame.CelestialID) (buildingID ogame.ID, buildingCountdown int64, researchID ogame.ID, researchCountdown int64, lfBuildingID ogame.ID, lfBuildingCountdown int64, lfResearchID ogame.ID, lfResearchCountdown 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) - GetLfTechs(ogame.CelestialID, ...Option) (ogame.LfTechs, error) + GetLfResearch(ogame.CelestialID, ...Option) (ogame.LfResearches, error) GetProduction(ogame.CelestialID) ([]ogame.Quantifiable, int64, error) GetResources(ogame.CelestialID) (ogame.Resources, error) GetResourcesBuildings(ogame.CelestialID, ...Option) (ogame.ResourcesBuildings, error) @@ -131,6 +131,7 @@ type Prioritizable interface { 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 + TechnologyDetails(celestialID ogame.CelestialID, id ogame.ID) (ogame.TechnologyDetails, error) // Planet specific functions DestroyRockets(ogame.PlanetID, int64, int64) error diff --git a/pkg/wrapper/moon.go b/pkg/wrapper/moon.go index 93084084..25377c7b 100644 --- a/pkg/wrapper/moon.go +++ b/pkg/wrapper/moon.go @@ -143,9 +143,9 @@ func (m Moon) GetLfBuildings(options ...Option) (ogame.LfBuildings, error) { return m.ogame.GetLfBuildings(m.ID.Celestial(), options...) } -// GetLfTechs gets the lifeform techs levels -func (m Moon) GetLfTechs(options ...Option) (ogame.LfTechs, error) { - return m.ogame.GetLfTechs(m.ID.Celestial(), options...) +// GetLfResearch gets the lifeform techs levels +func (m Moon) GetLfResearch(options ...Option) (ogame.LfResearches, error) { + return m.ogame.GetLfResearch(m.ID.Celestial(), options...) } // GetTechs gets (ogame.ResourcesBuildings, ogame.Facilities, ogame.ShipsInfos, ogame.DefensesInfos, ogame.Researches) diff --git a/pkg/wrapper/ogame.go b/pkg/wrapper/ogame.go index 4cf699e6..93fe2822 100644 --- a/pkg/wrapper/ogame.go +++ b/pkg/wrapper/ogame.go @@ -2888,13 +2888,13 @@ func (b *OGame) getLfBuildings(celestialID ogame.CelestialID, options ...Option) return page.ExtractLfBuildings() } -func (b *OGame) getLfTechs(celestialID ogame.CelestialID, options ...Option) (ogame.LfTechs, error) { +func (b *OGame) getLfResearch(celestialID ogame.CelestialID, options ...Option) (ogame.LfResearches, error) { options = append(options, ChangePlanet(celestialID)) - page, err := getPage[parser.LfTechsPage](b, options...) + page, err := getPage[parser.LfResearchPage](b, options...) if err != nil { - return ogame.LfTechs{}, err + return ogame.LfResearches{}, err } - return page.ExtractLfTechs() + return page.ExtractLfResearch() } func (b *OGame) getDefense(celestialID ogame.CelestialID, options ...Option) (ogame.DefensesInfos, error) { @@ -2956,6 +2956,18 @@ func (b *OGame) IsV9() bool { return len(b.ServerVersion()) > 0 && b.ServerVersion()[0] == '9' } +func (b *OGame) technologyDetails(celestialID ogame.CelestialID, id ogame.ID) (ogame.TechnologyDetails, error) { + pageHTML, _ := b.getPageContent(url.Values{ + "page": {"ingame"}, + "component": {"technologydetails"}, + "ajax": {"1"}, + "action": {"getDetails"}, + "technology": {utils.FI64(id)}, + "cp": {utils.FI64(celestialID)}, + }) + return b.extractor.ExtractTechnologyDetails(pageHTML) +} + func getToken(b *OGame, page string, celestialID ogame.CelestialID) (string, error) { pageHTML, _ := b.getPage(page, ChangePlanet(celestialID)) return b.extractor.ExtractUpgradeToken(pageHTML) @@ -3009,9 +3021,9 @@ func (b *OGame) build(celestialID ogame.CelestialID, id ogame.ID, nbr int64) err } else if id.IsShip() { page = ShipyardPageName } else if id.IsLfBuilding() { - page = LfbuildingsPageName + page = LfBuildingsPageName } else if id.IsLfTech() { - page = LftechsPageName + page = LfResearchPageName } else if id.IsBuilding() { page = SuppliesPageName } else if id.IsTech() { @@ -3080,7 +3092,7 @@ func (b *OGame) buildBuilding(celestialID ogame.CelestialID, buildingID ogame.ID } func (b *OGame) buildTechnology(celestialID ogame.CelestialID, technologyID ogame.ID) error { - if !technologyID.IsTech() { + if !technologyID.IsTech() && !technologyID.IsLfTech() { return errors.New("invalid technology id " + technologyID.String()) } return b.buildCancelable(celestialID, technologyID) @@ -4491,6 +4503,11 @@ func (b *OGame) Build(celestialID ogame.CelestialID, id ogame.ID, nbr int64) err return b.WithPriority(taskRunner.Normal).Build(celestialID, id, nbr) } +// TechnologyDetails extract details from ajax window when clicking supplies/facilities/techs/lf... +func (b *OGame) TechnologyDetails(celestialID ogame.CelestialID, id ogame.ID) (ogame.TechnologyDetails, error) { + return b.WithPriority(taskRunner.Normal).TechnologyDetails(celestialID, id) +} + // TearDown tears down any ogame building func (b *OGame) TearDown(celestialID ogame.CelestialID, id ogame.ID) error { return b.WithPriority(taskRunner.Normal).TearDown(celestialID, id) @@ -4807,7 +4824,7 @@ func (b *OGame) GetLfBuildings(celestialID ogame.CelestialID, opts ...Option) (o return b.WithPriority(taskRunner.Normal).GetLfBuildings(celestialID, opts...) } -// GetLfTechs ... -func (b *OGame) GetLfTechs(celestialID ogame.CelestialID, opts ...Option) (ogame.LfTechs, error) { - return b.WithPriority(taskRunner.Normal).GetLfTechs(celestialID, opts...) +// GetLfResearch ... +func (b *OGame) GetLfResearch(celestialID ogame.CelestialID, opts ...Option) (ogame.LfResearches, error) { + return b.WithPriority(taskRunner.Normal).GetLfResearch(celestialID, opts...) } diff --git a/pkg/wrapper/planet.go b/pkg/wrapper/planet.go index 741d9622..f2242642 100644 --- a/pkg/wrapper/planet.go +++ b/pkg/wrapper/planet.go @@ -158,9 +158,9 @@ func (p Planet) GetLfBuildings(options ...Option) (ogame.LfBuildings, error) { return p.ogame.getLfBuildings(p.ID.Celestial(), options...) } -// GetLfTechs gets the lifeform techs levels -func (p Planet) GetLfTechs(options ...Option) (ogame.LfTechs, error) { - return p.ogame.getLfTechs(p.ID.Celestial(), options...) +// GetLfResearch gets the lifeform techs levels +func (p Planet) GetLfResearch(options ...Option) (ogame.LfResearches, error) { + return p.ogame.getLfResearch(p.ID.Celestial(), options...) } // GetTechs gets (ogame.ResourcesBuildings, ogame.Facilities, ogame.ShipsInfos, ogame.DefensesInfos, ogame.Researches) diff --git a/pkg/wrapper/prioritize.go b/pkg/wrapper/prioritize.go index 468633e7..d6eedd12 100644 --- a/pkg/wrapper/prioritize.go +++ b/pkg/wrapper/prioritize.go @@ -334,6 +334,13 @@ func (b *Prioritize) Build(celestialID ogame.CelestialID, id ogame.ID, nbr int64 return b.bot.build(celestialID, id, nbr) } +// TechnologyDetails extract details from ajax window when clicking supplies/facilities/techs/lf... +func (b *Prioritize) TechnologyDetails(celestialID ogame.CelestialID, id ogame.ID) (ogame.TechnologyDetails, error) { + b.begin("TechnologyDetails") + defer b.done() + return b.bot.technologyDetails(celestialID, id) +} + // TearDown tears down any ogame building func (b *Prioritize) TearDown(celestialID ogame.CelestialID, id ogame.ID) error { b.begin("TearDown") @@ -715,9 +722,9 @@ func (b *Prioritize) GetLfBuildings(celestialID ogame.CelestialID, options ...Op return b.bot.getLfBuildings(celestialID, options...) } -// GetLfTechs ... -func (b *Prioritize) GetLfTechs(celestialID ogame.CelestialID, options ...Option) (ogame.LfTechs, error) { - b.begin("GetLfTechs") +// GetLfResearch ... +func (b *Prioritize) GetLfResearch(celestialID ogame.CelestialID, options ...Option) (ogame.LfResearches, error) { + b.begin("GetLfResearch") defer b.done() - return b.bot.getLfTechs(celestialID, options...) + return b.bot.getLfResearch(celestialID, options...) } diff --git a/samples/v9.0.4/en/lifeform/technologyDetails_1.html b/samples/v9.0.4/en/lifeform/technologyDetails_1.html new file mode 100644 index 00000000..0dc41b98 --- /dev/null +++ b/samples/v9.0.4/en/lifeform/technologyDetails_1.html @@ -0,0 +1 @@ +{"target":"technologydetails","content":{"technologydetails":"
\n
\n