pageLoadTimeStart(); include_once("GameEngine/Session.php"); include_once("GameEngine/config.php"); include_once("GameEngine/Database.php"); include_once("GameEngine/Village.php"); AccessLogger::logRequest(); // ---------- Admin gate ---------- if (!isset($session) || !isset($session->access) || (int)$session->access < 8) { header('Location: dorf1.php'); exit; } // ---------- Setup ---------- @session_start(); $TBP = defined('TB_PREFIX') ? TB_PREFIX : 's1_'; $CROP_TABLE = $TBP . 'croppers'; $WDATA = $TBP . 'wdata'; // Build an absolute-safe asset prefix for CSS/JS $assetBase = $session->gpack ?: GP_LOCATE; $assetBase = '/'.ltrim($assetBase, '/'); // CSRF if (empty($_SESSION['csrf_cb'])) { $_SESSION['csrf_cb'] = bin2hex(random_bytes(16)); } $csrf = $_SESSION['csrf_cb']; function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); } function indexExists($db, $tableName, $indexName) { $sql = "SELECT 1 FROM information_schema.statistics WHERE table_schema = DATABASE() AND table_name = '".mysqli_real_escape_string($db, $tableName)."' AND index_name = '".mysqli_real_escape_string($db, $indexName)."' LIMIT 1"; $result = mysqli_query($db, $sql); if (!$result) { return false; } return mysqli_num_rows($result) > 0; } function createIndexIfMissing($db, $tableName, $indexName, $columnsSql) { if (!indexExists($db, $tableName, $indexName)) { mysqli_query($db, "CREATE INDEX `{$indexName}` ON `{$tableName}` ({$columnsSql})"); } } function dropIndexIfExists($db, $tableName, $indexName) { if (indexExists($db, $tableName, $indexName)) { mysqli_query($db, "DROP INDEX `{$indexName}` ON `{$tableName}`"); } } // Ensure table exists (minimal schema, unsigned tinyints) mysqli_query($database->dblink, "CREATE TABLE IF NOT EXISTS `$CROP_TABLE` ( `wref` INT UNSIGNED NOT NULL PRIMARY KEY, `x` INT NOT NULL, `y` INT NOT NULL, `fieldtype` TINYINT UNSIGNED NOT NULL, `best_oasis_bonus` TINYINT UNSIGNED NOT NULL, `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, CHECK (`best_oasis_bonus` IN (0,25,50,75,100,125,150)) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"); // Helpful indexes (idempotent, avoids PHP8 mysqli duplicate-index exceptions) createIndexIfMissing($database->dblink, $CROP_TABLE, 'idx_ft_bonus_xy', '`fieldtype`, `best_oasis_bonus`, `x`, `y`'); createIndexIfMissing($database->dblink, $CROP_TABLE, 'idx_xy', '`x`, `y`'); createIndexIfMissing($database->dblink, $CROP_TABLE, 'idx_bonus', '`best_oasis_bonus`'); // ---------- Helpers ---------- function worldSizeLabel(): string { if (defined('WORLD_MIN') && defined('WORLD_MAX')) { $min = (int)WORLD_MIN; $max = (int)WORLD_MAX; return ($max - $min + 1) . "×" . ($max - $min + 1) . " (" . $min . " .. " . $max . ")"; } if (defined('WORLD_MAX')) { $max = (int)WORLD_MAX; $min = -$max; return ($max - $min + 1) . "×" . ($max - $min + 1) . " (" . $min . " .. " . $max . ")"; } return "unknown"; } function getCounts($db, $WDATA, $CROP_TABLE) { $c1 = mysqli_fetch_assoc(mysqli_query($db, "SELECT COUNT(*) c FROM `$WDATA` WHERE fieldtype IN (1,6)")); $c2 = mysqli_fetch_assoc(mysqli_query($db, "SELECT COUNT(*) c FROM `$CROP_TABLE`")); $lu = mysqli_fetch_assoc(mysqli_query($db, "SELECT MAX(updated_at) lu FROM `$CROP_TABLE`")); return [ 'croppers_world' => (int)($c1['c'] ?? 0), 'croppers_table' => (int)($c2['c'] ?? 0), 'last_updated' => $lu['lu'] ?? null, ]; } // stream log function startStreaming() { @ini_set('output_buffering','off'); @ini_set('zlib.output_compression', 0); while (ob_get_level()) { @ob_end_flush(); } ob_implicit_flush(true); echo "
";
    echo htmlspecialchars("[".date('H:i:s')."] Croppers builder started")."\n";
    flush();
}
function logLine($msg) { echo htmlspecialchars("[".date('H:i:s')."] ".$msg)."\n"; flush(); }
function endStreaming() { echo "
"; flush(); } // ---------- Actions ---------- $action = $_POST['action'] ?? null; $okCsrf = isset($_POST['csrf']) && hash_equals($_SESSION['csrf_cb'], $_POST['csrf']); $notice = null; if ($action && !$okCsrf) { $notice = "Invalid CSRF token. Please reload the page."; $action = null; } if ($action === 'truncate') { mysqli_query($database->dblink, "TRUNCATE TABLE `$CROP_TABLE`"); $notice = "Croppers table truncated."; } if ($action === 'reindex') { dropIndexIfExists($database->dblink, $CROP_TABLE, 'idx_ft_bonus_xy'); dropIndexIfExists($database->dblink, $CROP_TABLE, 'idx_xy'); dropIndexIfExists($database->dblink, $CROP_TABLE, 'idx_bonus'); createIndexIfMissing($database->dblink, $CROP_TABLE, 'idx_ft_bonus_xy', '`fieldtype`, `best_oasis_bonus`, `x`, `y`'); createIndexIfMissing($database->dblink, $CROP_TABLE, 'idx_xy', '`x`, `y`'); createIndexIfMissing($database->dblink, $CROP_TABLE, 'idx_bonus', '`best_oasis_bonus`'); $notice = "Indexes rebuilt."; } if ($action === 'estimate') { $notice = "Estimated counts refreshed."; } $stats = getCounts($database->dblink, $WDATA, $CROP_TABLE); $worldLabel = worldSizeLabel(); ?> <?php echo SERVER_NAME ?> - Mass Message gpack == null || GP_ENABLE == false) { echo " "; } else { echo " "; } ?> gpack == null || GP_ENABLE == false) { echo " "; } else { echo " "; } ?>

Build crop finder

Status

World:
9c/15c in map:
Rows in table:
Last updated:
The croppers table stores only wref,x,y,fieldtype,best_oasis_bonus. Ownership and occupied status are pulled live from vdata/users by the finder.

Actions

Building streams progress below. You can leave this page; the process stops when the request ends.
dblink, "SELECT COUNT(*) AS c FROM `$WDATA` WHERE `fieldtype` IN (1,6)")); $target = (int)($cnt['c'] ?? 0); logLine("Detected $target croppers."); $offset = 0; $total = 0; while (true) { $sql = "SELECT id AS wref, x, y, fieldtype FROM `$WDATA` WHERE `fieldtype` IN (1,6) LIMIT $offset, $batch"; $res = mysqli_query($database->dblink, $sql); if (!$res) { logLine('Query failed: '.mysqli_error($database->dblink)); break; } $rows = []; while ($r = mysqli_fetch_assoc($res)) { $rows[] = $r; } if (!$rows) break; $values = []; foreach ($rows as $r) { $x = (int)$r['x']; $y = (int)$r['y']; $bonus = (int)$database->getBestOasisCropBonus($x, $y); if (!in_array($bonus, [0,25,50,75,100,125,150], true)) { $bonus = max(0, min(150, $bonus)); } $values[] = sprintf("(%d,%d,%d,%d,%d)", (int)$r['wref'], $x, $y, (int)$r['fieldtype'], $bonus); } if ($values) { $sql = "REPLACE INTO `$CROP_TABLE` (`wref`,`x`,`y`,`fieldtype`,`best_oasis_bonus`) VALUES ".implode(',', $values); if (!mysqli_query($database->dblink, $sql)) { logLine('Upsert failed: '.mysqli_error($database->dblink)); break; } } $countThis = count($rows); $total += $countThis; $offset += $batch; logLine("Processed $total / $target"); } @mysqli_query($database->dblink, "ANALYZE TABLE `$CROP_TABLE`"); logLine("Analyze complete."); logLine("Done."); endStreaming(); // Refresh stats after build $stats = getCounts($database->dblink, $WDATA, $CROP_TABLE); } ?>







"; include("Templates/links.tpl"); } ?>
pageLoadTimeEnd()-$start_timer)*1000); ?> ms