diff --git a/pkg/extractor/extractor.go b/pkg/extractor/extractor.go
index 99b72437..fe7fcad2 100644
--- a/pkg/extractor/extractor.go
+++ b/pkg/extractor/extractor.go
@@ -16,7 +16,10 @@ type Extractor interface {
SetLanguage(lang string)
GetLocation() *time.Location
SetLocation(loc *time.Location)
+ GetLifeformEnabled() bool
+ SetLifeformEnabled(lifeformEnabled bool)
ExtractActiveItems(pageHTML []byte) ([]ogame.ActiveItem, error)
+ ExtractLifeformEnabled(pageHTML []byte) bool
ExtractAdmiral(pageHTML []byte) bool
ExtractAjaxChatToken(pageHTML []byte) (string, error)
ExtractAllResources(pageHTML []byte) (map[ogame.CelestialID]ogame.Resources, error)
@@ -24,6 +27,7 @@ type Extractor interface {
ExtractAuction(pageHTML []byte) (ogame.Auction, error)
ExtractBuffActivation(pageHTML []byte) (string, []ogame.Item, error)
ExtractCancelBuildingInfos(pageHTML []byte) (token string, techID, listID int64, err error)
+ ExtractCancelLfBuildingInfos(pageHTML []byte) (token string, id, listID int64, err error)
ExtractCancelFleetToken(pageHTML []byte, fleetID ogame.FleetID) (string, error)
ExtractCancelResearchInfos(pageHTML []byte) (token string, techID, listID int64, err error)
ExtractCelestial(pageHTML []byte, v any) (ogame.Celestial, error)
diff --git a/pkg/extractor/v6/extractor.go b/pkg/extractor/v6/extractor.go
index 2efd59a9..e456e940 100644
--- a/pkg/extractor/v6/extractor.go
+++ b/pkg/extractor/v6/extractor.go
@@ -5,6 +5,7 @@ import (
"errors"
"github.com/alaingilbert/ogame/pkg/ogame"
"net/url"
+ "regexp"
"time"
"github.com/PuerkitoBio/goquery"
@@ -13,8 +14,9 @@ import (
// Extractor ...
type Extractor struct {
- loc *time.Location
- lang string
+ loc *time.Location
+ lang string
+ lifeformEnabled bool
}
// NewExtractor ...
@@ -24,8 +26,10 @@ func NewExtractor() *Extractor {
return &Extractor{}
}
-func (e *Extractor) SetLocation(loc *time.Location) { e.loc = loc }
-func (e *Extractor) SetLanguage(lang string) { e.lang = lang }
+func (e *Extractor) SetLocation(loc *time.Location) { e.loc = loc }
+func (e *Extractor) SetLanguage(lang string) { e.lang = lang }
+func (e *Extractor) SetLifeformEnabled(lifeformEnabled bool) { e.lifeformEnabled = lifeformEnabled }
+func (e *Extractor) GetLifeformEnabled() bool { return e.lifeformEnabled }
func (e *Extractor) GetLocation() *time.Location {
if e.loc == nil {
return time.UTC
@@ -39,6 +43,10 @@ func (e *Extractor) GetLanguage() string {
return e.lang
}
+func (e *Extractor) ExtractCancelLfBuildingInfos(pageHTML []byte) (token string, id, listID int64, err error) {
+ panic("implement me")
+}
+
// ExtractActiveItems ...
func (e *Extractor) ExtractActiveItems(pageHTML []byte) ([]ogame.ActiveItem, error) {
panic("implement me")
@@ -79,6 +87,18 @@ func (e *Extractor) ExtractExpeditionMessagesFromDoc(doc *goquery.Document) ([]o
panic("implement me")
}
+// ExtractLifeformEnabled ...
+func (e *Extractor) ExtractLifeformEnabled(pageHTML []byte) bool {
+ lifeformEnabledMatch := regexp.MustCompile(`"lifeformEnabled":(\btrue\b|\bfalse\b)`).FindSubmatch(pageHTML)
+ if len(lifeformEnabledMatch) < 2 {
+ return false
+ }
+ if bytes.Equal(lifeformEnabledMatch[1], []byte("true")) {
+ return true
+ }
+ return false
+}
+
// ExtractIsInVacation ...
func (e *Extractor) ExtractIsInVacation(pageHTML []byte) bool {
doc, _ := goquery.NewDocumentFromReader(bytes.NewReader(pageHTML))
diff --git a/pkg/extractor/v6/extractor_test.go b/pkg/extractor/v6/extractor_test.go
index 43e55280..ac4ea459 100644
--- a/pkg/extractor/v6/extractor_test.go
+++ b/pkg/extractor/v6/extractor_test.go
@@ -174,3 +174,14 @@ func TestExtractAttacks1(t *testing.T) {
assert.Equal(t, int64(1), attacks[0].Missiles)
assert.Nil(t, attacks[0].Ships)
}
+
+func TestExtractLifeformEnabled(t *testing.T) {
+ pageHTML, _ := ioutil.ReadFile("../../../samples/unversioned/overview_active.html")
+ assert.False(t, NewExtractor().ExtractLifeformEnabled(pageHTML))
+
+ pageHTML, _ = ioutil.ReadFile("../../../samples/v9.0.2/en/overview_all_queues.html")
+ assert.False(t, NewExtractor().ExtractLifeformEnabled(pageHTML))
+
+ pageHTML, _ = ioutil.ReadFile("../../../samples/v9.0.2/en/lifeform/overview_all_queues.html")
+ assert.True(t, NewExtractor().ExtractLifeformEnabled(pageHTML))
+}
diff --git a/pkg/extractor/v7/extracts.go b/pkg/extractor/v7/extracts.go
index c9229110..6019efac 100644
--- a/pkg/extractor/v7/extracts.go
+++ b/pkg/extractor/v7/extracts.go
@@ -600,44 +600,32 @@ func extractEspionageReportFromDocV7(doc *goquery.Document, location *time.Locat
return report, nil
}
-func extractCancelBuildingInfosV7(pageHTML []byte) (token string, techID, listID int64, err error) {
- r1 := regexp.MustCompile(`cancelLinkbuilding[^?]+\?page=ingame&component=overview&modus=2&token=(\w+)&action=cancel`)
+func ExtractCancelInfos(pageHTML []byte, linkVarName, fnName string, tableIdx int) (token string, id, listID int64, err error) {
+ r1 := regexp.MustCompile(linkVarName + `[^?]+\?page=ingame&component=overview&modus=2&token=(\w+)&action=cancel`)
m1 := r1.FindSubmatch(pageHTML)
if len(m1) < 2 {
return "", 0, 0, errors.New("unable to find token")
}
token = string(m1[1])
doc, _ := goquery.NewDocumentFromReader(bytes.NewReader(pageHTML))
- t := doc.Find("table.construction").Eq(0)
+ t := doc.Find("table.construction").Eq(tableIdx)
a, _ := t.Find("a.abortNow").Attr("onclick")
- r := regexp.MustCompile(`cancelbuilding\((\d+),\s?(\d+),`)
+ r := regexp.MustCompile(fnName + `\((\d+),\s?(\d+),`)
m := r.FindStringSubmatch(a)
if len(m) < 3 {
- return "", 0, 0, errors.New("unable to find techid/listid")
+ return "", 0, 0, errors.New("unable to find id/listid")
}
- techID = utils.DoParseI64(m[1])
+ id = utils.DoParseI64(m[1])
listID = utils.DoParseI64(m[2])
return
}
+func extractCancelBuildingInfosV7(pageHTML []byte) (token string, techID, listID int64, err error) {
+ return ExtractCancelInfos(pageHTML, "cancelLinkbuilding", "cancelbuilding", 0)
+}
+
func extractCancelResearchInfosV7(pageHTML []byte) (token string, techID, listID int64, err error) {
- r1 := regexp.MustCompile(`cancelLinkresearch[^?]+\?page=ingame&component=overview&modus=2&token=(\w+)&action=cancel`)
- m1 := r1.FindSubmatch(pageHTML)
- if len(m1) < 2 {
- return "", 0, 0, errors.New("unable to find token")
- }
- token = string(m1[1])
- doc, _ := goquery.NewDocumentFromReader(bytes.NewReader(pageHTML))
- t := doc.Find("table.construction").Eq(1)
- a, _ := t.Find("a.abortNow").Attr("onclick")
- r := regexp.MustCompile(`cancelresearch\((\d+),\s?(\d+),`)
- m := r.FindStringSubmatch(a)
- if len(m) < 3 {
- return "", 0, 0, errors.New("unable to find techid/listid")
- }
- techID = utils.DoParseI64(m[1])
- listID = utils.DoParseI64(m[2])
- return
+ return ExtractCancelInfos(pageHTML, "cancelLinkresearch", "cancelresearch", 1)
}
func extractResourceSettingsFromDocV7(doc *goquery.Document) (ogame.ResourceSettings, error) {
diff --git a/pkg/extractor/v9/extractor.go b/pkg/extractor/v9/extractor.go
index d9bc23dc..9bc7c341 100644
--- a/pkg/extractor/v9/extractor.go
+++ b/pkg/extractor/v9/extractor.go
@@ -17,6 +17,16 @@ func NewExtractor() *Extractor {
return &Extractor{}
}
+// ExtractCancelLfBuildingInfos ...
+func (e *Extractor) ExtractCancelLfBuildingInfos(pageHTML []byte) (token string, id, listID int64, err error) {
+ return extractCancelLfBuildingInfos(pageHTML)
+}
+
+// ExtractCancelResearchInfos ...
+func (e *Extractor) ExtractCancelResearchInfos(pageHTML []byte) (token string, id, listID int64, err error) {
+ return extractCancelResearchInfos(pageHTML, e.GetLifeformEnabled())
+}
+
// ExtractEmpire ...
func (e *Extractor) ExtractEmpire(pageHTML []byte) ([]ogame.EmpireCelestial, error) {
return extractEmpireV9(pageHTML)
diff --git a/pkg/extractor/v9/extracts.go b/pkg/extractor/v9/extracts.go
index 3f5d16b6..80185481 100644
--- a/pkg/extractor/v9/extracts.go
+++ b/pkg/extractor/v9/extracts.go
@@ -4,6 +4,7 @@ import (
"errors"
"github.com/PuerkitoBio/goquery"
"github.com/alaingilbert/ogame/pkg/extractor/v6"
+ v7 "github.com/alaingilbert/ogame/pkg/extractor/v7"
"github.com/alaingilbert/ogame/pkg/extractor/v71"
"github.com/alaingilbert/ogame/pkg/ogame"
"github.com/alaingilbert/ogame/pkg/utils"
@@ -12,6 +13,18 @@ import (
"time"
)
+func extractCancelLfBuildingInfos(pageHTML []byte) (token string, id, listID int64, err error) {
+ return v7.ExtractCancelInfos(pageHTML, "cancelLinklfbuilding", "cancellfbuilding", 1)
+}
+
+func extractCancelResearchInfos(pageHTML []byte, lifeformEnabled bool) (token string, techID, listID int64, err error) {
+ tableIdx := 1
+ if lifeformEnabled {
+ tableIdx = 2
+ }
+ return v7.ExtractCancelInfos(pageHTML, "cancelLinkresearch", "cancelresearch", tableIdx)
+}
+
func extractEmpireV9(pageHTML []byte) ([]ogame.EmpireCelestial, error) {
var out []ogame.EmpireCelestial
raw, err := v6.ExtractEmpireJSON(pageHTML)
diff --git a/pkg/ogame/constants.go b/pkg/ogame/constants.go
index 78bf3544..332aa98b 100644
--- a/pkg/ogame/constants.go
+++ b/pkg/ogame/constants.go
@@ -113,71 +113,101 @@ const (
MoonType CelestialType = 3
//Buildings
- MetalMineID ID = 1
- CrystalMineID ID = 2
- DeuteriumSynthesizerID ID = 3
- SolarPlantID ID = 4
- FusionReactorID ID = 12
- MetalStorageID ID = 22
- CrystalStorageID ID = 23
- DeuteriumTankID ID = 24
- ShieldedMetalDenID ID = 25
- UndergroundCrystalDenID ID = 26
- SeabedDeuteriumDenID ID = 27
- AllianceDepotID ID = 34 // Facilities
- RoboticsFactoryID ID = 14
- ShipyardID ID = 21
- ResearchLabID ID = 31
- MissileSiloID ID = 44
- NaniteFactoryID ID = 15
- TerraformerID ID = 33
- SpaceDockID ID = 36
- LunarBaseID ID = 41 // Moon facilities
- SensorPhalanxID ID = 42
- JumpGateID ID = 43
- RocketLauncherID ID = 401 // Defense
- LightLaserID ID = 402
- HeavyLaserID ID = 403
- GaussCannonID ID = 404
- IonCannonID ID = 405
- PlasmaTurretID ID = 406
- SmallShieldDomeID ID = 407
- LargeShieldDomeID ID = 408
- AntiBallisticMissilesID ID = 502
- InterplanetaryMissilesID ID = 503
- SmallCargoID ID = 202 // Ships
- LargeCargoID ID = 203
- LightFighterID ID = 204
- HeavyFighterID ID = 205
- CruiserID ID = 206
- BattleshipID ID = 207
- ColonyShipID ID = 208
- RecyclerID ID = 209
- EspionageProbeID ID = 210
- BomberID ID = 211
- SolarSatelliteID ID = 212
- DestroyerID ID = 213
- DeathstarID ID = 214
- BattlecruiserID ID = 215
- CrawlerID ID = 217
- ReaperID ID = 218
- PathfinderID ID = 219
- EspionageTechnologyID ID = 106 // Research
- ComputerTechnologyID ID = 108
- WeaponsTechnologyID ID = 109
- ShieldingTechnologyID ID = 110
- ArmourTechnologyID ID = 111
- EnergyTechnologyID ID = 113
- HyperspaceTechnologyID ID = 114
- CombustionDriveID ID = 115
- ImpulseDriveID ID = 117
- HyperspaceDriveID ID = 118
- LaserTechnologyID ID = 120
- IonTechnologyID ID = 121
- PlasmaTechnologyID ID = 122
- IntergalacticResearchNetworkID ID = 123
- AstrophysicsID ID = 124
- GravitonTechnologyID ID = 199
+ MetalMineID ID = 1
+ CrystalMineID ID = 2
+ DeuteriumSynthesizerID ID = 3
+ SolarPlantID ID = 4
+ FusionReactorID ID = 12
+ MetalStorageID ID = 22
+ CrystalStorageID ID = 23
+ DeuteriumTankID ID = 24
+ ShieldedMetalDenID ID = 25
+ UndergroundCrystalDenID ID = 26
+ SeabedDeuteriumDenID ID = 27
+ AllianceDepotID ID = 34 // Facilities
+ RoboticsFactoryID ID = 14
+ ShipyardID ID = 21
+ ResearchLabID ID = 31
+ MissileSiloID ID = 44
+ NaniteFactoryID ID = 15
+ TerraformerID ID = 33
+ SpaceDockID ID = 36
+ LunarBaseID ID = 41 // Moon facilities
+ SensorPhalanxID ID = 42
+ JumpGateID ID = 43
+ RocketLauncherID ID = 401 // Defense
+ LightLaserID ID = 402
+ HeavyLaserID ID = 403
+ GaussCannonID ID = 404
+ IonCannonID ID = 405
+ PlasmaTurretID ID = 406
+ SmallShieldDomeID ID = 407
+ LargeShieldDomeID ID = 408
+ AntiBallisticMissilesID ID = 502
+ InterplanetaryMissilesID ID = 503
+ SmallCargoID ID = 202 // Ships
+ LargeCargoID ID = 203
+ LightFighterID ID = 204
+ HeavyFighterID ID = 205
+ CruiserID ID = 206
+ BattleshipID ID = 207
+ ColonyShipID ID = 208
+ RecyclerID ID = 209
+ EspionageProbeID ID = 210
+ BomberID ID = 211
+ SolarSatelliteID ID = 212
+ DestroyerID ID = 213
+ DeathstarID ID = 214
+ BattlecruiserID ID = 215
+ CrawlerID ID = 217
+ ReaperID ID = 218
+ PathfinderID ID = 219
+ EspionageTechnologyID ID = 106 // Research
+ ComputerTechnologyID ID = 108
+ WeaponsTechnologyID ID = 109
+ ShieldingTechnologyID ID = 110
+ ArmourTechnologyID ID = 111
+ EnergyTechnologyID ID = 113
+ HyperspaceTechnologyID ID = 114
+ CombustionDriveID ID = 115
+ ImpulseDriveID ID = 117
+ HyperspaceDriveID ID = 118
+ LaserTechnologyID ID = 120
+ IonTechnologyID ID = 121
+ PlasmaTechnologyID ID = 122
+ IntergalacticResearchNetworkID ID = 123
+ AstrophysicsID ID = 124
+ GravitonTechnologyID ID = 199
+ ResidentialSectorID ID = 11101 // Lifeform
+ BiosphereFarmID ID = 11102
+ ResearchCentreID ID = 11103
+ AcademyOfSciencesID ID = 11104
+ NeuroCalibrationCentreID ID = 11105
+ HighEnergySmeltingID ID = 11106
+ FoodSiloID ID = 11107
+ FusionPoweredProductionID ID = 11108
+ SkyscraperID ID = 11109
+ BiotechLabID ID = 11110
+ MetropolisID ID = 11111
+ PlanetaryShieldID ID = 11112
+ IntergalacticEnvoysID ID = 11201 // Lifeform tech
+ HighPerformanceExtractorsID ID = 11202
+ FusionDrivesID ID = 11203
+ StealthFieldGeneratorID ID = 11204
+ OrbitalDenID ID = 11205
+ ResearchAIID ID = 11206
+ HighPerformanceTerraformerID ID = 11207
+ EnhancedProductionTechnologiesID ID = 11208
+ LightFighterMkIIID ID = 11209
+ CruiserMkIIID ID = 11210
+ ImprovedLabTechnologyID ID = 11211
+ PlasmaTerraformerID ID = 11212
+ LowTemperatureDrivesID ID = 11213
+ BomberMkIIID ID = 11214
+ DestroyerMkIIID ID = 11215
+ BattlecruiserMkIIID ID = 11216
+ RobotAssistantsID ID = 11217
+ SupercomputerID ID = 11218
// Missions
Attack MissionID = 1
diff --git a/pkg/ogame/id.go b/pkg/ogame/id.go
index febeb8aa..d7493616 100644
--- a/pkg/ogame/id.go
+++ b/pkg/ogame/id.go
@@ -197,9 +197,24 @@ func (o ID) IsResourceBuilding() bool {
o == SeabedDeuteriumDenID
}
+func (o ID) IsLfBuilding() bool {
+ return o == ResidentialSectorID ||
+ o == BiosphereFarmID ||
+ o == ResearchCentreID ||
+ o == AcademyOfSciencesID ||
+ o == NeuroCalibrationCentreID ||
+ o == HighEnergySmeltingID ||
+ o == FoodSiloID ||
+ o == FusionPoweredProductionID ||
+ o == SkyscraperID ||
+ o == BiotechLabID ||
+ o == MetropolisID ||
+ o == PlanetaryShieldID
+}
+
// IsBuilding returns either or not the id is a building (facility, resource building)
func (o ID) IsBuilding() bool {
- return o.IsResourceBuilding() || o.IsFacility()
+ return o.IsResourceBuilding() || o.IsLfBuilding() || o.IsFacility()
}
// IsTech returns either or not the id is a technology
diff --git a/pkg/ogame/lfBuildings.go b/pkg/ogame/lfBuildings.go
new file mode 100644
index 00000000..0f2fb632
--- /dev/null
+++ b/pkg/ogame/lfBuildings.go
@@ -0,0 +1,263 @@
+package ogame
+
+import (
+ "math"
+)
+
+// LazyLfBuildings ...
+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
+}
+
+// Lazy returns a function that return self
+func (b LfBuildings) Lazy() LazyLfBuildings {
+ return func() LfBuildings { return b }
+}
+
+// ByID gets the lfBuilding level by lfBuilding id
+func (b LfBuildings) ByID(id ID) int64 {
+ switch id {
+ case ResidentialSectorID:
+ return b.ResidentialSector
+ case BiosphereFarmID:
+ return b.BiosphereFarm
+ case ResearchCentreID:
+ return b.ResearchCentre
+ case AcademyOfSciencesID:
+ return b.AcademyOfSciences
+ case NeuroCalibrationCentreID:
+ return b.NeuroCalibrationCentre
+ case HighEnergySmeltingID:
+ return b.HighEnergySmelting
+ case FoodSiloID:
+ return b.FoodSilo
+ case FusionPoweredProductionID:
+ return b.FusionPoweredProduction
+ case SkyscraperID:
+ return b.Skyscraper
+ case BiotechLabID:
+ return b.BiotechLab
+ case MetropolisID:
+ return b.Metropolis
+ case PlanetaryShieldID:
+ return b.PlanetaryShield
+ }
+ return 0
+}
+
+// BaseLfBuilding base struct for Lifeform buildings
+type BaseLfBuilding struct {
+ BaseBuilding
+ energyIncreaseFactor float64
+}
+
+// GetPrice returns the price to build the given level
+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))
+ }
+ 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),
+ }
+}
+
+type residentialSector struct {
+ BaseLfBuilding
+}
+
+func newResidentialSector() *residentialSector {
+ b := new(residentialSector)
+ b.Name = "residential sector"
+ b.ID = ResidentialSectorID
+ b.IncreaseFactor = 1.2
+ b.BaseCost = Resources{Metal: 7, Crystal: 2}
+ b.Requirements = map[ID]int64{}
+ return b
+}
+
+type biosphereFarm struct {
+ BaseLfBuilding
+}
+
+func newBiosphereFarm() *biosphereFarm {
+ b := new(biosphereFarm)
+ b.Name = "biosphere farm"
+ b.ID = BiosphereFarmID
+ b.IncreaseFactor = 1.23
+ b.energyIncreaseFactor = 1.021
+ b.BaseCost = Resources{Metal: 5, Crystal: 2, Energy: 8}
+ b.Requirements = map[ID]int64{}
+ return b
+}
+
+type researchCentre struct {
+ BaseLfBuilding
+}
+
+func newResearchCentre() *researchCentre {
+ b := new(researchCentre)
+ b.Name = "research centre"
+ b.ID = ResearchCentreID
+ b.IncreaseFactor = 1.3
+ b.BaseCost = Resources{Metal: 20000, Crystal: 25000, Deuterium: 10000}
+ b.Requirements = map[ID]int64{ResidentialSectorID: 12, BiosphereFarmID: 13}
+ return b
+}
+
+type academyOfSciences struct {
+ BaseLfBuilding
+}
+
+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.Requirements = map[ID]int64{ResidentialSectorID: 40}
+ return b
+}
+
+type neuroCalibrationCentre struct {
+ BaseLfBuilding
+}
+
+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.Requirements = map[ID]int64{ResidentialSectorID: 40, AcademyOfSciencesID: 1, FusionPoweredProductionID: 1, SkyscraperID: 5}
+ return b
+}
+
+type highEnergySmelting struct {
+ BaseLfBuilding
+}
+
+func newHighEnergySmelting() *highEnergySmelting {
+ b := new(highEnergySmelting)
+ b.Name = "high energy smelting"
+ b.ID = HighEnergySmeltingID
+ b.IncreaseFactor = 1 // TODO
+ b.BaseCost = Resources{Metal: 7500, Crystal: 5000, Deuterium: 3000}
+ b.Requirements = map[ID]int64{ResidentialSectorID: 12, BiosphereFarmID: 13, ResearchCentreID: 5}
+ return b
+}
+
+type foodSilo struct {
+ BaseLfBuilding
+}
+
+func newFoodSilo() *foodSilo {
+ b := new(foodSilo)
+ b.Name = "food silo"
+ b.ID = FoodSiloID
+ b.IncreaseFactor = 1 // TODO
+ b.BaseCost = Resources{Metal: 25000, Crystal: 13000, Deuterium: 7000}
+ b.Requirements = map[ID]int64{ResidentialSectorID: 12, BiosphereFarmID: 13, ResearchCentreID: 5, HighEnergySmeltingID: 3}
+ return b
+}
+
+type fusionPoweredProduction struct {
+ BaseLfBuilding
+}
+
+func newFusionPoweredProduction() *fusionPoweredProduction {
+ b := new(fusionPoweredProduction)
+ b.Name = "fusion powered production"
+ b.ID = FusionPoweredProductionID
+ b.IncreaseFactor = 1 // TODO
+ b.BaseCost = Resources{Metal: 50000, Crystal: 25000, Deuterium: 25000}
+ b.Requirements = map[ID]int64{ResidentialSectorID: 40, AcademyOfSciencesID: 1}
+ return b
+}
+
+type skyscraper struct {
+ BaseLfBuilding
+}
+
+func newSkyscraper() *skyscraper {
+ b := new(skyscraper)
+ b.Name = "skyscraper"
+ b.ID = SkyscraperID
+ b.IncreaseFactor = 1 // TODO
+ b.BaseCost = Resources{Metal: 75000, Crystal: 20000, Deuterium: 25000}
+ b.Requirements = map[ID]int64{ResidentialSectorID: 40, AcademyOfSciencesID: 1, FusionPoweredProductionID: 1}
+ return b
+}
+
+type biotechLab struct {
+ BaseLfBuilding
+}
+
+func newBiotechLab() *biotechLab {
+ b := new(biotechLab)
+ b.Name = "biotech lab"
+ b.ID = BiotechLabID
+ b.IncreaseFactor = 1 // TODO
+ b.BaseCost = Resources{Metal: 150000, Crystal: 30000, Deuterium: 15000}
+ b.Requirements = map[ID]int64{ResidentialSectorID: 40, AcademyOfSciencesID: 1, FusionPoweredProductionID: 2}
+ return b
+}
+
+type metropolis struct {
+ BaseLfBuilding
+}
+
+func newMetropolis() *metropolis {
+ b := new(metropolis)
+ b.Name = "metropolis"
+ b.ID = MetropolisID
+ b.IncreaseFactor = 1 // TODO
+ 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
+}
+
+type planetaryShield struct {
+ BaseLfBuilding
+}
+
+func newPlanetaryShield() *planetaryShield {
+ b := new(planetaryShield)
+ b.Name = "planetary shield"
+ b.ID = PlanetaryShieldID
+ b.IncreaseFactor = 1 // TODO
+ b.BaseCost = Resources{Metal: 250000, Crystal: 125000, Deuterium: 125000}
+ b.Requirements = map[ID]int64{
+ ResidentialSectorID: 40,
+ BiosphereFarmID: 13,
+ ResearchCentreID: 5,
+ AcademyOfSciencesID: 1,
+ FusionPoweredProductionID: 5,
+ SkyscraperID: 5,
+ HighEnergySmeltingID: 3,
+ MetropolisID: 5,
+ FoodSiloID: 4,
+ NeuroCalibrationCentreID: 5}
+ return b
+}
+
+// BaseLfTechnology base struct for lifeform technologies
+type BaseLfTechnology struct {
+ BaseLevelable
+}
diff --git a/pkg/ogame/lfBuildings_test.go b/pkg/ogame/lfBuildings_test.go
new file mode 100644
index 00000000..ed4896b4
--- /dev/null
+++ b/pkg/ogame/lfBuildings_test.go
@@ -0,0 +1,25 @@
+package ogame
+
+import (
+ "github.com/stretchr/testify/assert"
+ "testing"
+)
+
+func TestResidentialSectorCost(t *testing.T) {
+ a := newResidentialSector()
+ 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))
+}
+
+func TestBiosphereFarmCost(t *testing.T) {
+ a := newBiosphereFarm()
+ assert.Equal(t, Resources{Metal: 5, Crystal: 2, Energy: 8}, a.GetPrice(1))
+ assert.Equal(t, Resources{Metal: 8499, Crystal: 3399, Energy: 272}, a.GetPrice(22))
+}
+
+func TestResearchCenterCost(t *testing.T) {
+ a := newResearchCentre()
+ 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))
+}
diff --git a/pkg/ogame/objs.go b/pkg/ogame/objs.go
index 3a8c3db5..206a7329 100644
--- a/pkg/ogame/objs.go
+++ b/pkg/ogame/objs.go
@@ -67,6 +67,18 @@ var (
PlasmaTechnology = register[*plasmaTechnology](newPlasmaTechnology)
ShieldingTechnology = register[*shieldingTechnology](newShieldingTechnology)
WeaponsTechnology = register[*weaponsTechnology](newWeaponsTechnology)
+ ResidentialSector = register[*residentialSector](newResidentialSector) // Lifeform
+ BiosphereFarm = register[*biosphereFarm](newBiosphereFarm)
+ ResearchCentre = register[*researchCentre](newResearchCentre)
+ AcademyOfSciences = register[*academyOfSciences](newAcademyOfSciences)
+ NeuroCalibrationCentre = register[*neuroCalibrationCentre](newNeuroCalibrationCentre)
+ HighEnergySmelting = register[*highEnergySmelting](newHighEnergySmelting)
+ FoodSilo = register[*foodSilo](newFoodSilo)
+ FusionPoweredProduction = register[*fusionPoweredProduction](newFusionPoweredProduction)
+ Skyscraper = register[*skyscraper](newSkyscraper)
+ BiotechLab = register[*biotechLab](newBiotechLab)
+ Metropolis = register[*metropolis](newMetropolis)
+ PlanetaryShield = register[*planetaryShield](newPlanetaryShield)
)
type ObjsStruct struct{ m map[ID]BaseOgameObj }
diff --git a/pkg/ogame/resources.go b/pkg/ogame/resources.go
index fec9a486..35fc6098 100644
--- a/pkg/ogame/resources.go
+++ b/pkg/ogame/resources.go
@@ -58,6 +58,8 @@ type Resources struct {
Deuterium int64
Energy int64
Darkmatter int64
+ Lifeform int64
+ Food int64
}
func (r Resources) String() string {
diff --git a/pkg/ogame/resources_test.go b/pkg/ogame/resources_test.go
index cc64595a..3f1383f9 100644
--- a/pkg/ogame/resources_test.go
+++ b/pkg/ogame/resources_test.go
@@ -88,7 +88,7 @@ func TestResourcesDetails_Available(t *testing.T) {
d.Deuterium.Available = 3
d.Energy.Available = 4
d.Darkmatter.Available = 5
- assert.Equal(t, Resources{1, 2, 3, 4, 5}, d.Available())
+ assert.Equal(t, Resources{1, 2, 3, 4, 5, 0, 0}, d.Available())
}
func TestResources_FitsIn(t *testing.T) {
diff --git a/pkg/ogame/utils.go b/pkg/ogame/utils.go
index 3b1be8b5..307a6d87 100644
--- a/pkg/ogame/utils.go
+++ b/pkg/ogame/utils.go
@@ -7,6 +7,7 @@ import (
"golang.org/x/text/transform"
"golang.org/x/text/unicode/norm"
"regexp"
+ "sort"
"strings"
"unicode"
)
@@ -63,6 +64,20 @@ func ParseCoord(str string) (coord Coordinate, err error) {
var namesChars = "ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяёァイウオガキケコサザシスズソタダチッテデトドニノバパビフプヘマミムャヤラルレロンー偵列加反収器回型塔大太子察射導小履巡帶弾彈惡戦戰抗探撃收星機死残殖毀民洋滅漿炮爆發砲磁罩者能船艦衛諜護路車軌軽輕輸農送運道重間闘防陽際離雷電飛骸鬥魔"
var namesRgx = regexp.MustCompile("[^a-zA-Zα-ωΑ-Ω" + namesChars + "]+")
+func unique(s string) string {
+ //s = strings.ToLower(s)
+ m := make(map[rune]struct{})
+ for _, c := range s {
+ m[c] = struct{}{}
+ }
+ arr := make([]string, 0)
+ for k := range m {
+ arr = append(arr, string(k))
+ }
+ sort.Slice(arr, func(i, j int) bool { return arr[i] < arr[j] })
+ return strings.Join(arr, "")
+}
+
// DefenceName2ID ...
func DefenceName2ID(name string) ID {
t := transform.Chain(norm.NFD, runes.Remove(runes.In(unicode.Mn)), norm.NFC)
diff --git a/pkg/parser/fullPage.go b/pkg/parser/fullPage.go
index 1f3b37d4..df2efd17 100644
--- a/pkg/parser/fullPage.go
+++ b/pkg/parser/fullPage.go
@@ -41,6 +41,10 @@ func (p FullPage) ExtractTechnocrat() bool {
return p.e.ExtractTechnocratFromDoc(p.GetDoc())
}
+func (p FullPage) ExtractLifeformEnabled() bool {
+ return p.e.ExtractLifeformEnabled(p.GetContent())
+}
+
func (p FullPage) ExtractServerTime() (time.Time, error) {
return p.e.ExtractServerTimeFromDoc(p.GetDoc())
}
diff --git a/pkg/parser/fullPage_test.go b/pkg/parser/fullPage_test.go
index 975a122a..36bf3b14 100644
--- a/pkg/parser/fullPage_test.go
+++ b/pkg/parser/fullPage_test.go
@@ -11,7 +11,7 @@ import (
)
func TestExtractCelestial(t *testing.T) {
- pageHTML, _ := ioutil.ReadFile("../../samples/v9.0.2/en/overview_all_queues.html")
+ pageHTML, _ := ioutil.ReadFile("../../samples/v9.0.2/en/lifeform/overview_all_queues.html")
p := FullPage{Page: Page{e: v9.NewExtractor(), content: pageHTML}}
celestial, err := p.ExtractCelestial(33640820)
assert.NoError(t, err)
diff --git a/pkg/parser/overviewPage.go b/pkg/parser/overviewPage.go
index 6cb65288..8fd5d372 100644
--- a/pkg/parser/overviewPage.go
+++ b/pkg/parser/overviewPage.go
@@ -27,3 +27,7 @@ func (p OverviewPage) ExtractCancelResearchInfos() (token string, techID, listID
func (p OverviewPage) ExtractCancelBuildingInfos() (token string, techID, listID int64, err error) {
return p.e.ExtractCancelBuildingInfos(p.content)
}
+
+func (p OverviewPage) ExtractCancelLfBuildingInfos() (token string, id, listID int64, err error) {
+ return p.e.ExtractCancelLfBuildingInfos(p.content)
+}
diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go
index 063e66b0..6b7b7bf2 100644
--- a/pkg/utils/utils.go
+++ b/pkg/utils/utils.go
@@ -8,7 +8,6 @@ import (
"io/ioutil"
"net/http"
"regexp"
- "sort"
"strconv"
"strings"
)
@@ -114,20 +113,6 @@ func GetNbrShips(doc *goquery.Document, name string) int64 {
return ParseInt(m[1])
}
-func unique(s string) string {
- //s = strings.ToLower(s)
- m := make(map[rune]struct{})
- for _, c := range s {
- m[c] = struct{}{}
- }
- arr := make([]string, 0)
- for k := range m {
- arr = append(arr, string(k))
- }
- sort.Slice(arr, func(i, j int) bool { return arr[i] < arr[j] })
- return strings.Join(arr, "")
-}
-
func ReadBody(resp *http.Response) (respContent []byte, err error) {
var reader io.ReadCloser
switch resp.Header.Get("Content-Encoding") {
diff --git a/pkg/wrapper/fetcher.go b/pkg/wrapper/fetcher.go
index 22def64d..bb19c89d 100644
--- a/pkg/wrapper/fetcher.go
+++ b/pkg/wrapper/fetcher.go
@@ -11,6 +11,7 @@ const (
PreferencesPageName = "preferences"
ResourceSettingsPageName = "resourceSettings"
DefensesPageName = "defenses"
+ LfbuildingsPageName = "lfbuildings"
SuppliesPageName = "supplies"
FacilitiesPageName = "facilities"
FleetdispatchPageName = "fleetdispatch"
diff --git a/pkg/wrapper/interfaces.go b/pkg/wrapper/interfaces.go
index 73ca6d11..4266ced1 100644
--- a/pkg/wrapper/interfaces.go
+++ b/pkg/wrapper/interfaces.go
@@ -20,6 +20,7 @@ type Celestial interface {
BuildDefense(defenseID ogame.ID, nbr int64) error
BuildTechnology(technologyID ogame.ID) error
CancelBuilding() error
+ CancelLfBuilding() error
CancelResearch() error
ConstructionsBeingBuilt() (ogame.ID, int64, ogame.ID, int64)
EnsureFleet([]ogame.Quantifiable, ogame.Speed, ogame.Coordinate, ogame.MissionID, ogame.Resources, int64, int64) (ogame.Fleet, error)
@@ -109,6 +110,7 @@ type Prioritizable interface {
BuildShips(celestialID ogame.CelestialID, shipID ogame.ID, nbr int64) error
BuildTechnology(celestialID ogame.CelestialID, technologyID ogame.ID) error
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)
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)
diff --git a/pkg/wrapper/moon.go b/pkg/wrapper/moon.go
index fd488d30..91a97634 100644
--- a/pkg/wrapper/moon.go
+++ b/pkg/wrapper/moon.go
@@ -67,6 +67,11 @@ func (m Moon) CancelBuilding() error {
return m.ogame.CancelBuilding(ogame.CelestialID(m.ID))
}
+// CancelLfBuilding cancel the construction of a lifeform building
+func (p Moon) CancelLfBuilding() error {
+ return p.ogame.CancelLfBuilding(ogame.CelestialID(p.ID))
+}
+
// CancelResearch cancel the research
func (m Moon) CancelResearch() error {
return m.ogame.CancelResearch(m.ID.Celestial())
diff --git a/pkg/wrapper/ogame.go b/pkg/wrapper/ogame.go
index f75bc3f9..f5aa318d 100644
--- a/pkg/wrapper/ogame.go
+++ b/pkg/wrapper/ogame.go
@@ -513,6 +513,7 @@ func postSessions(b *OGame, lobby, username, password, otpSecret string) (out *G
}
cookies = append(cookies, cookie)
b.client.Jar.SetCookies(u, cookies)
+ fmt.Println("bearer", out.Token)
b.bearerToken = out.Token
return out, nil
}
@@ -631,7 +632,7 @@ func (b *OGame) loginPart3(userAccount Account, page parser.OverviewPage) error
b.extractor = v7.NewExtractor()
}
b.extractor.SetLanguage(b.language)
- b.extractor.SetLocation(b.location)
+ b.extractor.SetLifeformEnabled(page.ExtractLifeformEnabled())
} else {
b.error("failed to parse ogame version: " + err.Error())
}
@@ -648,6 +649,7 @@ func (b *OGame) loginPart3(userAccount Account, page parser.OverviewPage) error
serverTime, _ := page.ExtractServerTime()
b.location = serverTime.Location()
+ b.extractor.SetLocation(b.location)
b.cacheFullPageInfo(page)
@@ -2949,6 +2951,8 @@ func (b *OGame) build(celestialID ogame.CelestialID, id ogame.ID, nbr int64) err
page = DefensesPageName
} else if id.IsShip() {
page = ShipyardPageName
+ } else if id.IsLfBuilding() {
+ page = LfbuildingsPageName
} else if id.IsBuilding() {
page = SuppliesPageName
} else if id.IsTech() {
@@ -3057,6 +3061,15 @@ func (b *OGame) cancelBuilding(celestialID ogame.CelestialID) error {
return b.cancel(token, techID, listID)
}
+func (b *OGame) cancelLfBuilding(celestialID ogame.CelestialID) error {
+ page, err := getPage[parser.OverviewPage](b, ChangePlanet(celestialID))
+ if err != nil {
+ return err
+ }
+ token, id, listID, _ := page.ExtractCancelLfBuildingInfos()
+ return b.cancel(token, id, listID)
+}
+
func (b *OGame) cancelResearch(celestialID ogame.CelestialID) error {
page, err := getPage[parser.OverviewPage](b, ChangePlanet(celestialID))
if err != nil {
@@ -4457,6 +4470,11 @@ func (b *OGame) CancelBuilding(celestialID ogame.CelestialID) error {
return b.WithPriority(taskRunner.Normal).CancelBuilding(celestialID)
}
+// CancelLfBuilding cancel the construction of a lifeform building on a specified planet
+func (b *OGame) CancelLfBuilding(celestialID ogame.CelestialID) error {
+ return b.WithPriority(taskRunner.Normal).CancelLfBuilding(celestialID)
+}
+
// CancelResearch cancel the research
func (b *OGame) CancelResearch(celestialID ogame.CelestialID) error {
return b.WithPriority(taskRunner.Normal).CancelResearch(celestialID)
diff --git a/pkg/wrapper/ogame_test.go b/pkg/wrapper/ogame_test.go
index 28952709..d57c64ca 100644
--- a/pkg/wrapper/ogame_test.go
+++ b/pkg/wrapper/ogame_test.go
@@ -2166,6 +2166,40 @@ func TestCancelV7(t *testing.T) {
assert.Equal(t, int64(1336041), listID)
}
+func TestCancelBuildingV902(t *testing.T) {
+ pageHTMLBytes, _ := ioutil.ReadFile("../../samples/v9.0.2/en/overview_all_queues.html")
+ token, id, listID, _ := v9.NewExtractor().ExtractCancelBuildingInfos(pageHTMLBytes)
+ assert.Equal(t, "66f639922a3c76fe6074d12ae36e573e", token)
+ assert.Equal(t, int64(1), id)
+ assert.Equal(t, int64(3469488), listID)
+}
+
+func TestCancelLfBuildingLFV902(t *testing.T) {
+ pageHTMLBytes, _ := ioutil.ReadFile("../../samples/v9.0.2/en/lifeform/overview_all_queues.html")
+ token, id, listID, _ := v9.NewExtractor().ExtractCancelLfBuildingInfos(pageHTMLBytes)
+ assert.Equal(t, "07287218c9661bcc67b05ec1b6171fe8", token)
+ assert.Equal(t, int64(11101), id)
+ assert.Equal(t, int64(3998104), listID)
+}
+
+func TestCancelResearchV902(t *testing.T) {
+ pageHTMLBytes, _ := ioutil.ReadFile("../../samples/v9.0.2/en/overview_all_queues.html")
+ token, id, listID, _ := v9.NewExtractor().ExtractCancelResearchInfos(pageHTMLBytes)
+ assert.Equal(t, "66f639922a3c76fe6074d12ae36e573e", token)
+ assert.Equal(t, int64(108), id)
+ assert.Equal(t, int64(3469490), listID)
+}
+
+func TestCancelResearchLFV902(t *testing.T) {
+ pageHTMLBytes, _ := ioutil.ReadFile("../../samples/v9.0.2/en/lifeform/overview_all_queues.html")
+ e := v9.NewExtractor()
+ e.SetLifeformEnabled(true)
+ token, id, listID, _ := e.ExtractCancelResearchInfos(pageHTMLBytes)
+ assert.Equal(t, "07287218c9661bcc67b05ec1b6171fe8", token)
+ assert.Equal(t, int64(113), id)
+ assert.Equal(t, int64(3998106), listID)
+}
+
func TestCancelResearch(t *testing.T) {
pageHTMLBytes, _ := ioutil.ReadFile("../../samples/unversioned/overview_active_queue2.html")
token, techID, listID, _ := v6.NewExtractor().ExtractCancelResearchInfos(pageHTMLBytes)
@@ -2468,7 +2502,7 @@ func TestV71ExtractOverviewProduction(t *testing.T) {
}
func TestV902ExtractOverviewProduction(t *testing.T) {
- pageHTMLBytes, _ := ioutil.ReadFile("../../samples/v9.0.2/en/overview_all_queues.html")
+ pageHTMLBytes, _ := ioutil.ReadFile("../../samples/v9.0.2/en/lifeform/overview_all_queues.html")
prods, countdown, _ := v9.NewExtractor().ExtractOverviewProduction(pageHTMLBytes)
assert.Equal(t, 4, len(prods))
assert.Equal(t, int64(1660), countdown)
diff --git a/pkg/wrapper/planet.go b/pkg/wrapper/planet.go
index 267620fd..f0867307 100644
--- a/pkg/wrapper/planet.go
+++ b/pkg/wrapper/planet.go
@@ -117,6 +117,11 @@ func (p Planet) CancelBuilding() error {
return p.ogame.CancelBuilding(ogame.CelestialID(p.ID))
}
+// CancelLfBuilding cancel the construction of a lifeform building
+func (p Planet) CancelLfBuilding() error {
+ return p.ogame.CancelLfBuilding(ogame.CelestialID(p.ID))
+}
+
// CancelResearch cancel the research
func (p Planet) CancelResearch() error {
return p.ogame.CancelResearch(p.ID.Celestial())
diff --git a/pkg/wrapper/prioritize.go b/pkg/wrapper/prioritize.go
index b69ceaa7..afea5366 100644
--- a/pkg/wrapper/prioritize.go
+++ b/pkg/wrapper/prioritize.go
@@ -389,6 +389,13 @@ func (b *Prioritize) CancelBuilding(celestialID ogame.CelestialID) error {
return b.bot.cancelBuilding(celestialID)
}
+// CancelLfBuilding cancel the construction of a lifeform building on a specified planet
+func (b *Prioritize) CancelLfBuilding(celestialID ogame.CelestialID) error {
+ b.begin("CancelLfBuilding")
+ defer b.done()
+ return b.bot.cancelLfBuilding(celestialID)
+}
+
// CancelResearch cancel the research
func (b *Prioritize) CancelResearch(celestialID ogame.CelestialID) error {
b.begin("CancelResearch")
diff --git a/samples/v9.0.2/en/defence.html b/samples/v9.0.2/en/lifeform/defence.html
similarity index 100%
rename from samples/v9.0.2/en/defence.html
rename to samples/v9.0.2/en/lifeform/defence.html
diff --git a/samples/v9.0.2/en/lifeform/overview_all_queues.html b/samples/v9.0.2/en/lifeform/overview_all_queues.html
new file mode 100644
index 00000000..2842a540
--- /dev/null
+++ b/samples/v9.0.2/en/lifeform/overview_all_queues.html
@@ -0,0 +1,1871 @@
+
+
+ Halley OGame
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ load...
+
+
+ No fleet movement
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Metal: (+9.682) 208.335 / 2.920.00021.08 11:38:56 Crystal: (+5.578) 95.023 / 2.920.00030.08 22:01:33 Deuterium: (+3.384) 394.521 / 1.590.00024.08 12:51:00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+
+
+
+
+ 3
+
+
+
+
+ 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0 Contact(s) online
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/v9.0.2/en/overview_ships_queue.html b/samples/v9.0.2/en/lifeform/overview_ships_queue.html
similarity index 100%
rename from samples/v9.0.2/en/overview_ships_queue.html
rename to samples/v9.0.2/en/lifeform/overview_ships_queue.html
diff --git a/samples/v9.0.2/en/overview_all_queues.html b/samples/v9.0.2/en/overview_all_queues.html
index 2842a540..ae7b16bc 100644
--- a/samples/v9.0.2/en/overview_all_queues.html
+++ b/samples/v9.0.2/en/overview_all_queues.html
@@ -1,445 +1,535 @@
-
- Halley OGame
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ Ferdinand OGame
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+ );
+
+
+
-
+ body {margin:0; padding:0;} #mmonetbar { background:transparent url(//gf3.geo.gfsrv.net/cdn52/ab65c4951f415dff50d74738c953b5.bg) repeat-x; font:normal 11px Tahoma, Arial, Helvetica, sans-serif; height:32px; left:0; padding:0; position:absolute; text-align:center; top:0; width:100%; z-index:3000; } #mmonetbar #mmoContent { height:32px; margin:0 auto; width:1024px; position: relative; } #mmonetbar #mmoLogo { background:transparent url(//gf3.geo.gfsrv.net/cdn29/0f334111ba97c654b6e353f7168012.sprites) no-repeat top left; float:left; display:block; height:32px; width:108px; text-indent: -9999px; } #mmonetbar #mmoNews, #mmonetbar #mmoGame, #mmonetbar #mmoFocus, #pagefoldtarget { display:none !important; }
+
-
+