Mercurial > hg > batmud > maputils
changeset 1904:0625482ac9a5
Implement location search.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 06 Nov 2017 12:03:34 +0200 |
parents | 953c9a2c55f5 |
children | 9e659d0f995f |
files | mapsearch.c |
diffstat | 1 files changed, 126 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/mapsearch.c Mon Nov 06 11:35:46 2017 +0200 +++ b/mapsearch.c Mon Nov 06 12:03:34 2017 +0200 @@ -73,7 +73,8 @@ typedef struct { - char *map; + BOOL type; + char *map, *loc1, *loc2; int mx, my, wx, wy; int accuracy; BOOL centered; @@ -242,6 +243,8 @@ char *piece, *start, *fmt = th_strdup(str); BOOL ret = FALSE; + memset(info, 0, sizeof(MAPInfoCtx)); + // Check for map filename end if ((piece = strchr(fmt, ':')) == NULL) goto err; @@ -845,6 +848,51 @@ } +void mapCreateResultStr(char **buf, size_t *bufLen, const MAPMatch *matches, const int nmatches) +{ + size_t bufSize = 0; + *bufLen = 0; + *buf = NULL; + + th_strbuf_puts(buf, &bufSize, bufLen, "RESULT:["); + + for (int n = 0; n < nmatches; n++) + { + const MAPMatch *match = &matches[n]; + char *vstr; + + if (match->type) + { + vstr = th_strdup_printf( + "[%d,%d,\"%s\",%d,%d,%d,%d]%s", + match->accuracy, + match->centered, + match->map, + match->mx, match->my, + match->wx, match->wy, + (n < nmatches - 1) ? "," : ""); + } + else + { + vstr = th_strdup_printf( + "[%d,%d,\"%s\",%d,%d,%d,%d,\"%s\",\"%s\"]%s", + match->accuracy, + match->centered, + match->map, + match->mx, match->my, + match->wx, match->wy, + match->loc1, match->loc2, + (n < nmatches - 1) ? "," : ""); + } + + th_strbuf_puts(buf, &bufSize, bufLen, vstr); + th_free(vstr); + } + + th_strbuf_puts(buf, &bufSize, bufLen, "]"); +} + + void mapPerformSearch(struct lws *wsi, const unsigned char *data, const size_t len, char **verr) { static const char *cleanChars = " *@?%C"; @@ -1022,6 +1070,7 @@ // Okay, add the match to our list MAPMatch *match = &matches[nmatches++]; + match->type = TRUE; match->map = info->locFile.continent; match->mx = ox + centerX + 1; match->my = oy + centerY + 1; @@ -1045,32 +1094,79 @@ return; // We got some matches, output them as a JSON array - char *buf = NULL; - size_t bufLen = 0, bufSize = 0; + char *buf; + size_t bufLen; + + mapCreateResultStr(&buf, &bufLen, matches, nmatches); + + mapMSG(2, "%s\n", buf); + mapLWSWrite(wsi, (unsigned char *) buf, bufLen); + th_free(buf); +} + - th_strbuf_puts(&buf, &bufSize, &bufLen, "RESULT:["); +void mapLocationSearch(struct lws *wsi, const unsigned char *data, const size_t len, char **verr) +{ + MAPMatch matches[SET_MAX_MATCHES]; + int nmatches = 0; + char *pattern = NULL; - for (int n = 0; n < nmatches; n++) + // Check search pattern length + if (len < 3 || len > 25) + goto out; + + char *tmp = th_strndup((char *) data, len); + pattern = th_strdup_printf("*%s*", tmp); + th_free(tmp); + + // + // Search the maps .. enabled or if none specified, all of them + // + for (int nmap = 0; nmap < optNMaps; nmap++) { - MAPMatch *match = &matches[n]; - char *vstr = th_strdup_printf( - "[%d,%d,\"%s\",%d,%d,%d,%d]%s", - match->accuracy, - match->centered, - match->map, - match->mx, match->my, - match->wx, match->wy, - (n < nmatches - 1) ? "," : ""); + MAPInfoCtx *info = &optMaps[nmap]; + for (int nloc = 0; nloc < info->loc.n; nloc++) + { + LocMarker *marker = info->loc.locations[nloc]; + for (int nname = 0; nname < marker->nnames; nname++) + if (th_strcasematch(marker->names[nname].name, pattern)) + { + // Okay, add the match to our list + MAPMatch *match = &matches[nmatches++]; - th_strbuf_puts(&buf, &bufSize, &bufLen, vstr); - th_free(vstr); + match->type = FALSE; + match->loc1 = marker->names[0].name; + match->loc2 = marker->names[nname].name; + match->map = info->locFile.continent; + match->mx = marker->x + 1; + match->my = marker->y + 1; + match->wx = optWorldXC + info->locFile.x + marker->x; + match->wy = optWorldYC + info->locFile.y + marker->y; + match->accuracy = 100; + match->centered = TRUE; + + // Check for max matches + if (nmatches >= SET_MAX_MATCHES) + goto out; + } + } } - th_strbuf_puts(&buf, &bufSize, &bufLen, "]"); - mapMSG(2, "%s\n", buf); +out: + th_free(pattern); + + // If an error occured, bail out now + if (*verr != NULL) + return; + // We got some matches, output them as a JSON array + char *buf; + size_t bufLen; + + mapCreateResultStr(&buf, &bufLen, matches, nmatches); + + mapMSG(2, "%s\n", buf); mapLWSWrite(wsi, (unsigned char *) buf, bufLen); - th_free(buf); } @@ -1134,6 +1230,16 @@ th_free(buf); } else + if (len >= 10 && strncmp(data, "LOCSEARCH:", 10) == 0) + { + mapMSG(1, "[%p] Location search query.\n", wsi); + + if (len <= 10 + 1) + verr = "Invalid search query."; + else + mapLocationSearch(wsi, udata + 10, len - 10, &verr); + } + else { // Unknown or invalid query verr = "Invalid command/search query, not enough data."; @@ -1272,7 +1378,7 @@ return FALSE; } - if (!locParseLocStream(fh, &info->locFile, &(info->loc), info->locFile.x, info->locFile.y)) + if (!locParseLocStream(fh, &info->locFile, &(info->loc), 0, 0)) { fclose(fh); return FALSE;