diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c778b00..40707814 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - (impressum) Fix broken de-obfuscation with some browsers +- many balancing tweaks, thanks u/schokoboy! + - Increase production for each plantage level: + - (plantage) increase `production_amount_per_level` `10 -> 30` + - (plantage) increase `production_amount_per_item_id` `30 -> 100` + - Reduce research duration per building level: + - (research_lab) increase `bonus_factor` `0.055 -> 0.10` + - Increase production per research level: + - (research_lab) increase `production_amount_per_level` `12 -> 30` + - (research_lab) increase `production_cost_per_level` `7 -> 25` + - (research_lab) increase `cost_item_id_factor` `100 -> 1000` + - Decrease building time for each building yard level: + - (building_yard) increase `bonus_factor` `0.061 -> 0.08` + - Decrease deposit amount of bank per building level: + - (bank) decrease `bonus_factor_upgrade` `1.75 -> 1.50` + - Level 0: `100.000` + - Level 1: `200.000 -> 150.000` + - Level 2: `350.000 -> 250.000` + - Level 3: `550.000 -> 350.000` + - Level 4: `950.000 -> 550.000` + - Level 5: `1.650.000 -> 800.000` + - Level 6: `2.900.000 -> 1.150.000` + - Level 7: `5.050.000 -> 1.750.000` + - (bank) increase `credit_limit` `-15000 -> -30000` + - Increase credit limit depending on bank building level + - Each level of the bank building will now increase the credit amount by a factor of `3` + - Level 0: `30.000` + - Level 1: `90.000` + - Level 2: `270.000` + - Level 3: `810.000` + - Level 4: `2.430.000` + - Level 5: `7.290.000` + - Level 6: `21.870.000` ### Security diff --git a/actions/bank.php b/actions/bank.php index 3afb63a2..01ddb830 100644 --- a/actions/bank.php +++ b/actions/bank.php @@ -24,6 +24,7 @@ redirectTo('/?p=bank', 112, __LINE__); } $depositLimit = calculateDepositLimit($data['Gebaeude' . building_bank]); +$creditLimit = calculateCreditLimit($data['Gebaeude' . building_bank]); switch ($art) { // deposit money @@ -59,7 +60,7 @@ // withdraw money case 2: - if ($data['Bank'] - $betrag < Config::getInt(Config::SECTION_BANK, 'credit_limit')) { + if ($data['Bank'] - $betrag < $creditLimit) { redirectTo(sprintf('/?p=bank&art=%d&betrag=%f', $art, $betrag), 109, __LINE__); } @@ -68,7 +69,7 @@ 'Geld' => +$betrag, 'Bank' => -$betrag ), array( - 'Bank + ' . abs(Config::getInt(Config::SECTION_BANK, 'credit_limit')) . ' >= :whr0' => $betrag + 'Bank - ' . $betrag . ' >= :whr0' => $creditLimit )) == 0) { Database::getInstance()->rollBack(); redirectTo(sprintf('/?p=bank&art=%d&betrag=%f', $art, $betrag), 142, __LINE__); diff --git a/config/config-defaults.ini b/config/config-defaults.ini index 6e9dcb77..836cd5e4 100644 --- a/config/config-defaults.ini +++ b/config/config-defaults.ini @@ -156,9 +156,9 @@ production_base_amount = 350 ; base production cost for all items production_base_cost = 200 ; bonus to production amount for each plantage level -production_amount_per_level = 10 +production_amount_per_level = 30 ; bonus to production amount for later items -production_amount_per_item_id = 30 +production_amount_per_item_id = 100 ; maximum duration of a single production (in hours) production_hours_max = 12 ; base income per item and level each cronjob interval (x kg per research level and cronjob run) @@ -172,11 +172,11 @@ base_duration = 1900 factor_cost = 1.37 factor_duration = 1.23 ; each level of research lab reduces research duration (1 = 100%, 0.5 = 50%, 0 = 0%) -bonus_factor = 0.055 +bonus_factor = 0.10 ; bonus to production amount for each research level -production_amount_per_level = 12 +production_amount_per_level = 30 ; malus to production cost for each research level -production_cost_per_level = 7 +production_cost_per_level = 25 ; base data for researches research_base_cost = 230 research_base_duration = 2400 @@ -185,7 +185,7 @@ research_factor_duration = 1.19 ; minimum duration of all researches (in seconds) research_min_duration = 7200 ; extra cost for later items -cost_item_id_factor = 100 +cost_item_id_factor = 1000 [shop] ; building data for shop @@ -226,7 +226,7 @@ base_duration = 2250 factor_cost = 1.40 factor_duration = 1.24 ; each level of building yard reduces building duration (1 = 100%, 0.5 = 50%, 0 = 0%) -bonus_factor = 0.061 +bonus_factor = 0.08 [school] ; building data for school @@ -261,8 +261,8 @@ base_cost = 200000 base_duration = 86400 factor_cost = 1.85 factor_duration = 1.75 -; each level of this building increases the deposit amount by that value -bonus_factor_upgrade = 1.75 +; each level of this building increases the deposit amount by that factor +bonus_factor_upgrade = 1.5 ; minimum interest rate (1 = 100%, 0.5 = 50%, 0 = 0%) interest_debit_rate_min = 0.011 ; maximum interest rate (1 = 100%, 0.5 = 50%, 0 = 0%) @@ -275,7 +275,9 @@ interest_credit_rate_max = 0.023 ; each level of the building doubles this amount deposit_limit = 100000 ; maximum amount a user may overdraw a bank account -credit_limit = -15000 +credit_limit = -30000 +; each level of this building increases the credit amount by that factor +credit_limit_factor = 3 [market] ; when retracting an offer from the market, return that amount of the item (1 = 100%, 0.5 = 50%, 0 = 0%) diff --git a/cronjobs/cron.php b/cronjobs/cron.php index 34b8346c..8bc31358 100644 --- a/cronjobs/cron.php +++ b/cronjobs/cron.php @@ -76,7 +76,10 @@ function handleInterestRatesAndBaseIncome(Database $database): void function handleResetDueToDispo(Database $database): void { - $entries = $database->getAllPlayerIdAndNameBankSmallerEquals(calculateResetCreditLimit()); + $entries = $database->getAllPlayerIdAndNameForDispoReset( + Config::getInt(Config::SECTION_BANK, 'credit_limit'), + Config::getFloat(Config::SECTION_BANK, 'credit_limit_factor') + ); foreach ($entries as $entry) { error_log(sprintf('Resetting player %s/%s', $entry['ID'], $entry['Name'])); $database->begin(); @@ -90,7 +93,7 @@ function handleResetDueToDispo(Database $database): void 'Von' => 0, 'An' => $entry['ID'], 'Betreff' => 'Account zurückgesetzt', - 'Nachricht' => "Nachdem Ihr Kontostand unter " . formatCurrency(calculateResetCreditLimit()) . " gefallen ist wurden Sie gezwungen, Insolvenz anzumelden. Sie haben sich an der Grenze zu Absurdistan einen neuen Pass geholt und versuchen Ihr Glück mit einer neuen Identität nochmal neu" + 'Nachricht' => "Nachdem Ihr Kontostand unter " . formatCurrency(calculateResetCreditLimit($entry['Gebaeude' . building_bank])) . " gefallen ist wurden Sie gezwungen, Insolvenz anzumelden. Sie haben sich an der Grenze zu Absurdistan einen neuen Pass geholt und versuchen Ihr Glück mit einer neuen Identität nochmal neu" )) != 1) { $database->rollBack(); error_log(sprintf('Could create message after resetting player %d', $entry['ID'])); diff --git a/include/database.class.php b/include/database.class.php index 8e53ad5c..e7bb46b1 100644 --- a/include/database.class.php +++ b/include/database.class.php @@ -1310,7 +1310,7 @@ public function getMessageByIdAndAnOrVonEquals(int $id, int $blm_user): ?array public function getAllPlayerIdAndBankAndBioladenAndDoenerstandAndBank(): ?array { - return $this->executeAndExtractRows($this->prepare("SELECT ID, Bank, Gebaeude3, Gebaeude4, Gebaeude9 FROM " . self::TABLE_USERS . " WHERE ID > 0 AND EmailAct IS NULL")); + return $this->executeAndExtractRows($this->prepare("SELECT ID, Bank, Gebaeude" . building_shop . ", Gebaeude" . building_kebab_stand . ", Gebaeude" . building_bank . " FROM " . self::TABLE_USERS . " WHERE ID > 0 AND EmailAct IS NULL")); } public function getAllPlayerIdAndResearchLevels(): ?array @@ -1318,10 +1318,11 @@ public function getAllPlayerIdAndResearchLevels(): ?array return $this->executeAndExtractRows($this->prepare("SELECT ID, " . getAllResearchFields() . " FROM " . self::TABLE_USERS . " WHERE ID > 0 AND EmailAct IS NULL")); } - public function getAllPlayerIdAndNameBankSmallerEquals(float $amount): ?array + public function getAllPlayerIdAndNameForDispoReset(int $creditLimit, float $creditLimitFactor): ?array { - $stmt = $this->prepare("SELECT ID, Name FROM " . self::TABLE_USERS . " WHERE Bank <= :amount AND ID > 0"); - $stmt->bindParam('amount', $amount); + $stmt = $this->prepare("SELECT ID, Name, Gebaeude" . building_bank . " FROM " . self::TABLE_USERS . " WHERE Bank <= :amount * pow(:limitFactor, Gebaeude" . building_bank . ") AND ID > 0"); + $stmt->bindParam('amount', $creditLimit); + $stmt->bindParam('limitFactor', $creditLimitFactor); return $this->executeAndExtractRows($stmt); } diff --git a/include/functions.inc.php b/include/functions.inc.php index 773367cb..ca1ce2d2 100644 --- a/include/functions.inc.php +++ b/include/functions.inc.php @@ -1313,10 +1313,10 @@ function calculateInterestRates(): array return $result; } -function calculateResetCreditLimit(): int +function calculateResetCreditLimit(int $bankLevel): int { $resetMedianRates = (Config::getFloat(Config::SECTION_BANK, 'interest_credit_rate_min') + Config::getFloat(Config::SECTION_BANK, 'interest_credit_rate_max')) / 2; - $resetCreditLimit = (int)(Config::getInt(Config::SECTION_BANK, 'credit_limit') * pow(1 + $resetMedianRates, 96)); + $resetCreditLimit = (int)(calculateCreditLimit($bankLevel) * pow(1 + $resetMedianRates, 96)); $resetCreditLimit -= 10000 + ($resetCreditLimit % 10000); return $resetCreditLimit; } @@ -1644,6 +1644,11 @@ function calculateDepositLimit(int $bankLevel): float return ceil($limit / 50000) * 50000; } +function calculateCreditLimit(int $bankLevel): float +{ + return pow(Config::getFloat(Config::SECTION_BANK, 'credit_limit_factor'), $bankLevel) * Config::getInt(Config::SECTION_BANK, 'credit_limit'); +} + function trimAndRemoveControlChars(string $string): string { // remove all control characters and trim spaces diff --git a/pages/bank.inc.php b/pages/bank.inc.php index a732f65f..09cf7547 100644 --- a/pages/bank.inc.php +++ b/pages/bank.inc.php @@ -15,7 +15,7 @@ $depositLimit = calculateDepositLimit($data['Gebaeude' . building_bank]); $resetMedianRates = (Config::getFloat(Config::SECTION_BANK, 'interest_credit_rate_min') + Config::getFloat(Config::SECTION_BANK, 'interest_credit_rate_max')) / 2; -$resetCreditLimit = calculateResetCreditLimit(); +$resetCreditLimit = calculateResetCreditLimit($data['Gebaeude' . building_bank]); ?>
Wichtig! Falls der Kontostand unter = formatCurrency($resetCreditLimit); ?> fällt, wird Ihr Account automatisch resettet! diff --git a/pages/hilfe.inc.php b/pages/hilfe.inc.php index 91b54138..ec01d362 100644 --- a/pages/hilfe.inc.php +++ b/pages/hilfe.inc.php @@ -121,13 +121,13 @@ Sie haben von Anfang an ein Bankkonto mit ' . formatCurrency(Config::getSection(Config::SECTION_STARTING_VALUES)['Bank']) . ' Startguthaben. Die maximale Summe, welche Sie zu Beginn einzahlen können liegt bei ' . formatCurrency(Config::getInt(Config::SECTION_BANK, 'deposit_limit')) . ' -(Bitte beachten: Bei diesem Betrag bekommen Sie auch keine Zinsen mehr!), die maximale Kreditsumme beträgt ' . formatCurrency(Config::getInt(Config::SECTION_BANK, 'credit_limit')) . '. +(Bitte beachten: Bei diesem Betrag bekommen Sie auch keine Zinsen mehr!), die maximale Kreditsumme beträgt ' . formatCurrency(Config::getInt(Config::SECTION_BANK, 'credit_limit')) . ', steigt jedoch mit jeder Stufe des Bankschliessfaches. Die Zinsen werden alle ' . Config::getInt(Config::SECTION_BASE, 'cron_interval') . ' Minuten abgerechnet. Das Geld auf der Bank kann nicht (im Gegensatz zum Bargeld) von anderen Spielern geklaut werden. -Die Kapazität der Bank kann mit Hilfe des Bankschliessfaches je Stufe verdoppelt werden. +Die Kapazität der Bank kann mit Hilfe des Bankschliessfaches je Stufe um den Faktor ' . formatCurrency(Config::getFloat(Config::SECTION_BANK, 'bonus_factor_upgrade'), false) . ' erhöht werden. -[color=red]Wichtig: Falls Ihr Kontostand unter ' . formatCurrency(calculateResetCreditLimit()) . ' fällt, wird Ihr Account automatisch resettet![/color]' +[color=red]Wichtig: Falls Ihr Kontostand unter das Dispo-Limit fällt, wird Ihr Account automatisch resettet![/color]' ), 110 => array( 'Verträge', diff --git a/tests/src/test/java/eu/fraho/blm2/st/BankTests.java b/tests/src/test/java/eu/fraho/blm2/st/BankTests.java index 0f8d8ca3..6fa6b70d 100644 --- a/tests/src/test/java/eu/fraho/blm2/st/BankTests.java +++ b/tests/src/test/java/eu/fraho/blm2/st/BankTests.java @@ -141,13 +141,13 @@ void testWithdrawCreditLimit() { driver.findElement(By.id("link_bank")).click(); driver.findElement(By.id("auszahlen")).click(); - setValue(By.id("betrag"), "65000.01"); + setValue(By.id("betrag"), "80000.01"); driver.findElement(By.id("do_transaction")).click(); assertElementPresent(By.id("meldung_109")); // check new balance assertText(By.id("cur_bank_account"), "Ihr Kontostand: 50,000.00 €"); - assertValue(By.id("betrag"), new BigDecimal("65000.01")); + assertValue(By.id("betrag"), new BigDecimal("80000.01")); assertText(By.id("stat_money"), "100,000.00 €"); assertText(By.id("stat_bank"), "50,000.00 €"); } @@ -217,15 +217,15 @@ void testDepositWithBankSafe() { driver.findElement(By.id("link_bank")).click(); driver.findElement(By.id("einzahlen")).click(); - assertValue(By.id("betrag"), new BigDecimal("130000.00")); + assertValue(By.id("betrag"), new BigDecimal("80000.00")); driver.findElement(By.id("do_transaction")).click(); assertElementPresent(By.id("meldung_207")); - assertText(By.id("cur_bank_account"), "Ihr Kontostand: 200,000.00 €"); + assertText(By.id("cur_bank_account"), "Ihr Kontostand: 150,000.00 €"); assertValue(By.id("betrag"), new BigDecimal("0.00")); - assertText(By.id("stat_money"), "70,000.00 €"); - assertText(By.id("stat_bank"), "200,000.00 €"); + assertText(By.id("stat_money"), "120,000.00 €"); + assertText(By.id("stat_bank"), "150,000.00 €"); } @Test diff --git a/tests/src/test/java/eu/fraho/blm2/st/PlantageTests.java b/tests/src/test/java/eu/fraho/blm2/st/PlantageTests.java index 95075770..041a6010 100644 --- a/tests/src/test/java/eu/fraho/blm2/st/PlantageTests.java +++ b/tests/src/test/java/eu/fraho/blm2/st/PlantageTests.java @@ -29,15 +29,15 @@ void testPlantAll2Hours() { driver.findElement(By.id("link_plantage")).click(); setValue(By.id("stunden"), "2"); - assertText(By.id("pr_ko_all"), "Kosten: 1,592.00 €"); + assertText(By.id("pr_ko_all"), "Kosten: 2,600.00 €"); driver.findElement(By.id("plant_all")).submit(); assertElementPresent(By.id("meldung_207")); assertElementPresent(By.id("abort_1")); assertElementPresent(By.id("abort_2")); - assertText(By.id("stat_money"), "13,408.00 €"); + assertText(By.id("stat_money"), "12,400.00 €"); driver.findElement(By.id("link_buero")).click(); - assertText(By.id("b_s_3"), "1,592.00 €"); + assertText(By.id("b_s_3"), "2,600.00 €"); } @Test @@ -46,7 +46,7 @@ void testPlantAll13Hours() { driver.findElement(By.id("link_plantage")).click(); setValue(By.id("stunden"), "13"); - assertText(By.id("pr_ko_all"), "Kosten: 10,348.00 €"); + assertText(By.id("pr_ko_all"), "Kosten: 16,900.00 €"); driver.findElement(By.id("plant_all")).submit(); assertElementPresent(By.id("meldung_133")); } @@ -56,12 +56,12 @@ void testPlant12HoursManualAmount() { WebDriver driver = getDriver(); driver.findElement(By.id("link_plantage")).click(); - setValue(By.id("amount_1"), "8448"); + setValue(By.id("amount_1"), "16920"); driver.findElement(By.id("plant_1")).submit(); assertElementPresent(By.id("meldung_207")); assertElementPresent(By.id("abort_1")); assertElementPresent(By.id("plant_2")); - assertText(By.id("stat_money"), "12,432.00 €"); + assertText(By.id("stat_money"), "12,000.00 €"); } @Test @@ -69,7 +69,7 @@ void testPlantAmountOver12Hours() { WebDriver driver = getDriver(); driver.findElement(By.id("link_plantage")).click(); - setValue(By.id("amount_1"), "8449"); + setValue(By.id("amount_1"), "16921"); driver.findElement(By.id("plant_1")).submit(); assertElementPresent(By.id("meldung_125")); assertElementPresent(By.id("plant_1")); @@ -85,15 +85,15 @@ void testPlantAndCancelAfter1Kg() throws InterruptedException { setValue(By.id("amount_15"), "3"); driver.findElement(By.id("plant_15")).submit(); assertElementPresent(By.id("meldung_207")); - assertText(By.id("stat_money"), "14,999.20 €"); + assertText(By.id("stat_money"), "14,999.29 €"); assertElementPresent(By.id("plant_1")); assertElementPresent(By.id("abort_15")); - Thread.sleep(TimeUnit.SECONDS.toMillis(3)); + Thread.sleep(TimeUnit.SECONDS.toMillis(1)); driver.findElement(By.id("abort_15")).click(); driver.switchTo().alert().accept(); assertElementPresent(By.id("meldung_222")); assertElementPresent(By.id("plant_15")); - assertText(By.id("stat_money"), "14,999.20 €"); + assertText(By.id("stat_money"), "14,999.29 €"); driver.findElement(By.id("link_bioladen")).click(); assertText(By.id("cur_amount_15"), "1 kg"); diff --git a/tests/src/test/java/eu/fraho/blm2/st/ResearchTests.java b/tests/src/test/java/eu/fraho/blm2/st/ResearchTests.java index 48131fc8..e29beba5 100644 --- a/tests/src/test/java/eu/fraho/blm2/st/ResearchTests.java +++ b/tests/src/test/java/eu/fraho/blm2/st/ResearchTests.java @@ -41,15 +41,15 @@ void testResearchAndCancel() { assertElementPresent(By.id("meldung_207")); assertElementPresent(By.id("abort_1")); - assertText(By.id("stat_money"), "4,517.26 €"); + assertText(By.id("stat_money"), "3,617.26 €"); driver.findElement(By.id("abort_1")).click(); driver.switchTo().alert().accept(); assertElementPresent(By.id("meldung_222")); assertElementPresent(By.id("research_1")); - assertText(By.id("stat_money"), "4,879.32 €"); + assertText(By.id("stat_money"), "4,654.32 €"); driver.findElement(By.id("link_buero")).click(); - assertText(By.id("b_s_2"), "120.68 €"); + assertText(By.id("b_s_2"), "345.68 €"); } } diff --git a/tests/src/test/resources/test-reset-player.php b/tests/src/test/resources/test-reset-player.php index a9251f0a..0027b686 100644 --- a/tests/src/test/resources/test-reset-player.php +++ b/tests/src/test/resources/test-reset-player.php @@ -53,14 +53,14 @@ Database::getInstance()->updateTableEntry(Database::TABLE_USERS, $id, array('Bank' => 99900, 'Gebaeude9' => 1)); } if ($testMethod === 'testResetAfterDispoLimit') { - Database::getInstance()->updateTableEntry(Database::TABLE_USERS, $id, array('Bank' => -109000)); + Database::getInstance()->updateTableEntry(Database::TABLE_USERS, $id, array('Bank' => -210000)); } break; case 'BuildingTests': Database::getInstance()->updateTableEntry(Database::TABLE_USERS, $id, array( 'Gebaeude' . building_plantage => 8, - 'Gebaeude' . building_building_yard => 120, + 'Gebaeude' . building_building_yard => 80, )); break;