Fix autocomplete

Fix autocomplete
This commit is contained in:
novgorodschi catalin
2026-08-05 14:14:10 +03:00
parent dcb9311f4c
commit 077708ef84
4 changed files with 86 additions and 13 deletions
+53 -4
View File
@@ -1988,6 +1988,39 @@ trait DatabaseVillageQueries {
mysqli_query($this->dblink, $q);
}
/**
* Rezolva ce a scris jucatorul in casuta de destinatie.
*
* Accepta atat "Numele satului", cat si formatul dat de autocomplete pentru
* numele ambigue: "Numele satului (x|y)". Cand vin coordonate, ele decid -
* sunt neambigue prin definitie.
*
* @param string $input textul din formular
* @param int $uid jucatorul, pentru preferinta pe satele proprii
* @return int wref, sau 0 daca nu s-a gasit
*/
function resolveVillageInput($input, $uid = 0) {
$input = trim((string) $input);
if ($input === '') {
return 0;
}
// "Nume (x|y)" -> coordonatele au ultimul cuvant
if (preg_match('/^(.*)\\s*\\((-?\\d+)\\|(-?\\d+)\\)$/', $input, $m)) {
$wref = (int) $this->getVilWref((int) $m[2], (int) $m[3]);
if ($wref > 0) {
return $wref;
}
// coordonate invalide: incercam macar numele
$input = trim($m[1]);
}
return (int) $this->getVillageByName($input, true, $uid);
}
function getVillageByName($name, $use_cache = true, $uid = 0) {
/**
@@ -2067,7 +2100,10 @@ trait DatabaseVillageQueries {
$radius = (int) $radius;
$limit = (int) $limit;
$joins = "JOIN " . TB_PREFIX . "users u ON u.id = v.owner ";
// wdata se alatura MEREU: avem nevoie de coordonate la fiecare sugestie,
// nu doar cand se filtreaza dupa raza.
$joins = "JOIN " . TB_PREFIX . "users u ON u.id = v.owner "
. "JOIN " . TB_PREFIX . "wdata w ON w.id = v.wref ";
$conds = [];
if ($v1) {
@@ -2077,7 +2113,6 @@ trait DatabaseVillageQueries {
$conds[] = "u.alliance = $alliance";
}
if ($v2) {
$joins .= "JOIN " . TB_PREFIX . "wdata w ON w.id = v.wref ";
$conds[] = "(ABS(w.x - $x) <= $radius AND ABS(w.y - $y) <= $radius)";
}
@@ -2085,7 +2120,17 @@ trait DatabaseVillageQueries {
return [];
}
$q = "SELECT DISTINCT v.name FROM " . TB_PREFIX . "vdata v " .
/**
* Aducem si coordonatele, nu doar numele.
*
* Numele de sate NU sunt unice: cele 13 sate de Minune ale Natarilor se
* cheama toate "WW village". Cand jucatorul alegea o sugestie, in formular
* ajungea doar numele, iar cautarea putea nimeri alt sat.
*
* Cu coordonatele la indemana, sablonul poate adauga "(x|y)" DOAR la
* numele care apar de mai multe ori - restul raman curate.
*/
$q = "SELECT v.name, w.x, w.y FROM " . TB_PREFIX . "vdata v " .
$joins .
"WHERE u.id > 5 AND (" . implode(' OR ', $conds) . ") " .
"ORDER BY v.name LIMIT $limit";
@@ -2094,7 +2139,11 @@ trait DatabaseVillageQueries {
$names = [];
if ($result) {
while ($row = mysqli_fetch_assoc($result)) {
$names[] = $row['name'];
$names[] = array(
'name' => $row['name'],
'x' => (int) $row['x'],
'y' => (int) $row['y'],
);
}
}
return $names;
+4 -4
View File
@@ -95,8 +95,8 @@ class Units {
if(!empty($post['dname']) && $post['x'] != "" && $post['y'] != "") return "Insert name or coordinates";
if(isset($post['dname']) && !empty($post['dname'])) {
$id = $database->getVillageByName(stripslashes($post['dname']), true,
(int) ($session->uid ?? 0)); // preferam satele jucatorului
$id = $database->resolveVillageInput(stripslashes($post['dname']),
(int) ($session->uid ?? 0)); // accepta si "Nume (x|y)"
if (!isset($id)) return "Village doesn't exist";
else $coor = $database->getCoor($id);
@@ -165,8 +165,8 @@ class Units {
$vid = $database->getVilWref($post['x'], $post['y']);
unset($post['dname']);
}
else if(isset($post['dname']) && !empty($post['dname'])) $vid = $database->getVillageByName(stripslashes($post['dname']), true,
(int) ($session->uid ?? 0)); // preferam satele jucatorului
else if(isset($post['dname']) && !empty($post['dname'])) $vid = $database->resolveVillageInput(stripslashes($post['dname']),
(int) ($session->uid ?? 0)); // accepta si "Nume (x|y)"
if (!empty($vid)) {
if($isOasis = $database->isVillageOases($vid)){
+2 -2
View File
@@ -46,8 +46,8 @@ if ($x!== '' && $y!== '' && is_numeric($x) && is_numeric($y)) {
$getwref = (int)$database->getVilWref((int)$x, (int)$y);
$checkexist = $database->checkVilExist($getwref);
} elseif ($dname!== '') {
// Preferam satele jucatorului: numele NU sunt unice (vezi getVillageByName).
$getwref = (int) $database->getVillageByName($dname, true, (int) ($session->uid ?? 0));
// Accepta si formatul dat de autocomplete pentru nume ambigue: "Nume (x|y)".
$getwref = (int) $database->resolveVillageInput($dname, (int) ($session->uid ?? 0));
$checkexist = $database->checkVilExist($getwref);
}
+27 -3
View File
@@ -23,10 +23,34 @@ if ($acV1 || $acV2 || $acV3) {
$acV3
);
echo '<datalist id="dnameSuggest">';
foreach ($acNames as $acName) {
echo '<option value="' . htmlspecialchars($acName, ENT_QUOTES) . '">';
/**
* Numele de sate NU sunt unice - cele 13 sate de Minune ale Natarilor se
* cheama toate "WW village". Daca sugestia trimite doar numele, cautarea
* poate nimeri alt sat, iar resursele pleaca aiurea.
*
* Asa ca adaugam coordonatele DOAR la numele care apar de mai multe ori.
* Numele unice raman curate, deci pentru majoritatea jucatorilor nu se
* schimba nimic.
*/
$acCount = array();
foreach ($acNames as $acRow) {
$acKey = $acRow['name'];
$acCount[$acKey] = isset($acCount[$acKey]) ? $acCount[$acKey] + 1 : 1;
}
echo '<datalist id="dnameSuggest">';
foreach ($acNames as $acRow) {
$acValue = $acRow['name'];
if ($acCount[$acRow['name']] > 1) {
$acValue .= ' (' . (int) $acRow['x'] . '|' . (int) $acRow['y'] . ')';
}
echo '<option value="' . htmlspecialchars($acValue, ENT_QUOTES) . '">';
}
echo '</datalist>';
}
?>