Build crop finder
Status
vdata/users by the finder.
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();
?>
vdata/users by the finder.