--- deliantra/server/socket/request.C 2010/04/21 05:48:22 1.175 +++ deliantra/server/socket/request.C 2018/11/18 00:37:11 1.196 @@ -1,24 +1,25 @@ /* * This file is part of Deliantra, the Roguelike Realtime MMORPG. - * - * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team + * + * Copyright (©) 2017,2018 Marc Alexander Lehmann / the Deliantra team + * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team * Copyright (©) 2001 Mark Wedel * Copyright (©) 1992 Frank Tore Johansen - * + * * Deliantra is free software: you can redistribute it and/or modify it under * the terms of the Affero GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the Affero GNU General Public License * and the GNU General Public License along with this program. If not, see * . - * + * * The authors can be reached via e-mail to */ @@ -30,9 +31,9 @@ * * \date 2003-12-02 * - * This file implements all of the goo on the server side for handling - * clients. It's got a bunch of global variables for keeping track of - * each of the clients. + * This file implements all of the goo on the server side for handling + * clients. It's got a bunch of global variables for keeping track of + * each of the clients. * * Note: All functions that are used to process data from the client * have the prototype of (char *data, int datalen, int client_num). This @@ -148,10 +149,7 @@ memset (&pl->ns->lastmap, 0, sizeof (pl->ns->lastmap)); pl->ns->force_newmap = false; - - if (pl->ns->newmapcmd == 1) - pl->ns->send_packet ("newmap"); - + pl->ns->send_packet ("newmap"); pl->ns->floorbox_reset (); } @@ -163,14 +161,18 @@ if (socket.mapinfocmd) { - if (ob->map && ob->map->path[0]) + if (ob->map && ob->map->path) { int flags = 0; - if (ob->map->tile_path[0]) flags |= 1; - if (ob->map->tile_path[1]) flags |= 2; - if (ob->map->tile_path[2]) flags |= 4; - if (ob->map->tile_path[3]) flags |= 8; + // due to historical glitches, the bit ordering and map index ordering differs + if (ob->map->tile_path [TILE_NORTH]) flags |= 0x01; + if (ob->map->tile_path [TILE_EAST ]) flags |= 0x02; + if (ob->map->tile_path [TILE_SOUTH]) flags |= 0x04; + if (ob->map->tile_path [TILE_WEST ]) flags |= 0x08; + // these two are debatable + if (ob->map->tile_path [TILE_UP ]) flags |= 0x10; + if (ob->map->tile_path [TILE_DOWN ]) flags |= 0x20; socket.send_packet_printf ("mapinfo - spatial %d %d %d %d %d %s", flags, socket.mapx / 2 - ob->x, socket.mapy / 2 - ob->y, @@ -195,7 +197,7 @@ socket.current_region = reg; } - // first try to aovid a full newmap on tiled map scrolls + // first try to avoid a full newmap on tiled map scrolls if (socket.current_map != ob->map && !socket.force_newmap) { rv_vector rv; @@ -248,10 +250,7 @@ sl.printf ("%d:%s\n", CS_STAT_SKILLINFO + i, &skillvec [i]->name); if (sl.length () > MAXSOCKBUF) - { - LOG (llevError, "Buffer overflow in send_skill_info!\n"); - fatal (0); - } + cleanup ("buffer overflow in send_skill_info!"); ns->send_packet (sl); } @@ -271,10 +270,7 @@ sl.printf ("%d:%s\n", 1 << i, spellpathnames[i]); if (sl.length () > MAXSOCKBUF) - { - LOG (llevError, "Buffer overflow in send_spell_paths!\n"); - fatal (0); - } + cleanup ("buffer overflow in send_spell_paths!"); ns->send_packet (sl); } @@ -283,6 +279,8 @@ * RequestInfo is sort of a meta command. There is some specific * request of information, but we call other functions to provide * that information. + * requestinfo is completely deprecated, use resource exti request + * and the fxix or http protocols. */ void RequestInfo (char *buf, int len, client *ns) @@ -330,8 +328,8 @@ void client::mapinfo_queue_clear () { - for (auto (i, mapinfo_queue.begin ()); i != mapinfo_queue.end (); ++i) - free (*i); + for (auto &&i : mapinfo_queue) + free (i); mapinfo_queue.clear (); } @@ -352,8 +350,14 @@ { int dir = *buf++ - '1'; - if (dir >= 0 && dir <= 3) + // due to historical glitches, the mapinfo index and tile index differs + static unsigned char dirmap [] = { TILE_NORTH, TILE_EAST, TILE_SOUTH, TILE_WEST, TILE_UP, TILE_DOWN }; + + // maybe we should only allow the four flat directions + if (IN_RANGE_EXC (dir, 0, array_length (dirmap))) { + dir = dirmap [dir]; + if (!map->tile_path [dir]) map = 0; else if (map->tile_available (dir, false)) @@ -386,10 +390,14 @@ { int flags = 0; - if (map->tile_path[0]) flags |= 1; - if (map->tile_path[1]) flags |= 2; - if (map->tile_path[2]) flags |= 4; - if (map->tile_path[3]) flags |= 8; + // due to historical glitches, the bit ordering and map index ordering differs + if (map->tile_path [TILE_NORTH]) flags |= 0x01; + if (map->tile_path [TILE_EAST ]) flags |= 0x02; + if (map->tile_path [TILE_SOUTH]) flags |= 0x04; + if (map->tile_path [TILE_WEST ]) flags |= 0x08; + // these two are debatable + if (map->tile_path [TILE_UP ]) flags |= 0x10; + if (map->tile_path [TILE_DOWN ]) flags |= 0x20; send_packet_printf ("mapinfo %s spatial %d %d %d %d %d %s", token, flags, mapx, mapy, map->width, map->height, &map->path); } @@ -493,50 +501,6 @@ pl->count = 0; } -/** - * This handles the general commands from the client (ie, north, fire, cast, - * etc.). It is a lot like PlayerCmd above, but is called with the - * 'ncom' method which gives more information back to the client so it - * can throttle. - */ -void -NewPlayerCmd (char *buf, int len, player *pl) -{ - if (len <= 6) - { - LOG (llevDebug, "%s: corrupt ncom command <%s>: not long enough (%d) - discarding\n", pl->ns->host, buf, len); - return; - } - - uint16 cmdid = net_uint16 ((uint8 *)buf); - sint32 repeat = net_sint32 ((uint8 *)buf + 2); - - /* -1 is special - no repeat, but don't update */ - if (repeat != -1) - pl->count = repeat; - - buf += 6; //len -= 6; - - execute_newserver_command (pl->ob, buf); - - /* Perhaps something better should be done with a left over count. - * Cleaning up the input should probably be done first - all actions - * for the command that issued the count should be done before any other - * commands. - */ - pl->count = 0; - - //TODO: schmorp thinks whatever this calculates, it makes no sense at all - int time = pl->ob->has_active_speed () - ? (int) (MAX_TIME / pl->ob->speed) - : MAX_TIME * 100; - - /* Send confirmation of command execution now */ - packet sl ("comc"); - sl << uint16 (cmdid) << uint32 (time); - pl->ns->send_packet (sl); -} - /** This is a reply to a previous query. */ void ReplyCmd (char *buf, int len, client *ns) @@ -884,25 +848,6 @@ return 0; } -//-GPL - -// prefetch maps in an area of PREFETCH x PREFETCH around the player -#define PREFETCH 40 - -// prefetch a generous area around the player -static void -prefetch_surrounding_maps (object *op) -{ - for (maprect *rect = op->map->split_to_tiles (mapwalk_buf, - op->x - PREFETCH , op->y - PREFETCH , - op->x + PREFETCH + 1, op->y + PREFETCH + 1); - rect->m; - ++rect) - rect->m->touch (); -} - -//+GPL - /** * Draws client map. */ @@ -917,13 +862,13 @@ * can get swapped out. If so, don't try to send them a map. All will * be OK once they really log in. */ - if (!ob->map || ob->map->in_memory != MAP_ACTIVE) + if (!ob->map || ob->map->state != MAP_ACTIVE) return; int startlen, oldlen; check_map_change (pl); - prefetch_surrounding_maps (pl->ob); + pl->ob->prefetch_surrounding_maps (); /* do LOS after calls to update_position */ /* unfortunately, we need to udpate los when observing, currently */ @@ -958,7 +903,7 @@ client &socket = *pl->ns; - packet sl (socket.mapmode == Map1Cmd ? "map1" : "map1a"); + packet sl ("map1a"); startlen = sl.length (); @@ -998,11 +943,11 @@ * reason. Still may need to send the head for this space. */ if (lastcell.count != -1 - || lastcell.faces[0] - || lastcell.faces[1] + || lastcell.faces[0] + || lastcell.faces[1] || lastcell.faces[2] - || lastcell.stat_hp - || lastcell.flags + || lastcell.stat_hp + || lastcell.flags || lastcell.player) sl << uint16 (mask); @@ -1251,7 +1196,7 @@ static void append_spell (player *pl, packet &sl, object *spell) { - int i, skill = 0; + int skill = 0; if (!(spell->name)) { @@ -1288,12 +1233,14 @@ << uint8 (skill) << uint32 (spell->path_attuned) << uint32 (spell->face) - << data8 (spell->name) - << data16 (spell->msg); + << data8 (spell->name); + + if (pl->ns->monitor_spells < 2) + sl << data16 (spell->msg); } /** - * This tells the client to add the spell *ob, if *ob is NULL, then add + * This tells the client to add the spell *ob, if *ob is NULL, then add * all spells in the player's inventory. */ void @@ -1314,13 +1261,13 @@ { for (spell = pl->ob->inv; spell; spell = spell->below) { - /* were we to simply keep appending data here, we could exceed + /* were we to simply keep appending data here, we could exceed * MAXSOCKBUF if the player has enough spells to add, we know that * append_spells will always append 19 data bytes, plus 4 length * bytes and 3 strings (because that is the spec) so we need to - * check that the length of those 3 strings, plus the 23 bytes, + * check that the length of those 3 strings, plus the 23 bytes, * won't take us over the length limit for the socket, if it does, - * we need to send what we already have, and restart packet formation + * we need to send what we already have, and restart packet formation */ if (spell->type != SPELL) continue; @@ -1351,10 +1298,7 @@ append_spell (pl, sl, spell); if (sl.length () > MAXSOCKBUF) - { - LOG (llevError, "Buffer overflow in esrv_add_spells!\n"); - fatal (0); - } + cleanup ("buffer overflow in esrv_add_spells!"); /* finally, we can send the packet */ pl->ns->flush_fx ();