--- deliantra/server/socket/image.C 2007/07/24 04:55:34 1.50 +++ deliantra/server/socket/image.C 2008/12/27 01:25:00 1.58 @@ -1,11 +1,11 @@ /* - * This file is part of Crossfire TRT, the Roguelike Realtime MORPG. + * This file is part of Deliantra, the Roguelike Realtime MMORPG. * - * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team + * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team * Copyright (©) 2001,2007 Mark Wedel * Copyright (©) 1992,2007 Frank Tore Johansen * - * Crossfire TRT is free software: you can redistribute it and/or modify + * Deliantra is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. @@ -18,7 +18,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . * - * The authors can be reached via e-mail to + * The authors can be reached via e-mail to */ /** \file @@ -40,25 +40,6 @@ #define MAX_IMAGE_SIZE 10000 /** - * Client tells us what type of faces it wants. Also sets - * the caching attribute. - * - */ -void -SetFaceMode (char *buf, int len, client *ns) -{ - int mask = (atoi (buf) & CF_FACE_CACHE), mode = (atoi (buf) & ~CF_FACE_CACHE); - - if (mode == CF_FACE_NONE) - ns->facecache = 1; - else if (mode != CF_FACE_PNG) - ns->send_packet_printf ("drawinfo %d %s", NDI_RED, "Warning - send unsupported face mode. Will use Png"); - - if (mask) - ns->facecache = 1; -} - -/** * client requested an image. send it rate-limited * before flushing. */ @@ -69,6 +50,8 @@ sscanf (buf, "%d %d", &idx, &pri); + //TODO: somehow fetch default priority from send_fx here + const facedata *d = face_data (idx, ns->faceset); if (!d) @@ -82,27 +65,17 @@ auto (pos, ns->ixface.end ()); - if (ns->fxix < 2) + // the by far most common case will be to insert + // near the end, so little looping. + while (pos != ns->ixface.begin ()) { - // gcfclient does not support prioritising, older cfplus versions - // do not support interleaved transfers. - if (!ns->ixface.empty ()) - pos = ns->ixface.end () - 1; - } - else - { - // the by far most common case will be to insert - // near the end, so little looping. - while (pos != ns->ixface.begin ()) - { - --pos; + --pos; - // sort within 2k bins, to slightly prefer smaller images - if (pri > pos->pri || (pri == pos->pri && (ix.ofs >> 11) <= (pos->ofs >> 11))) - { - ++pos; - break; - } + // sort within 2k bins, to slightly prefer smaller images + if (pri > pos->pri || (pri == pos->pri && (ix.ofs >> 11) <= (pos->ofs >> 11))) + { + ++pos; + break; } } @@ -116,43 +89,6 @@ } /** - * Tells client the picture it has to use - * to smooth a picture number given as argument. - */ -void -AskSmooth (char *buf, int len, client *ns) -{ - ns->send_face (atoi (buf), -100); - ns->flush_fx (); -} - -// how lame -static void print_facename (packet &sl, const facedata &d) -{ - for (int i = 0; i < CHKSUM_SIZE; ++i) - sl.printf ("%02x", d.chksum [i]); -} - -// gcfclient uses the server-provided checksum for comparison, but always -// writes a broken checksum to its cache file, so we have to provide -// gcfclient with the same broken (and useless) checksum just to have it -// cache the image despite its bugs. -static uint32 gcfclient_checksum (const facedata *d) -{ - uint32 csum = 0; - - for (std::string::const_iterator i = d->data.begin (); - i != d->data.end (); - ++i) - { - csum = rotate_right (csum); - csum += *(uint8 *)&*i; - } - - return csum; -} - -/** * Sends a face to a client if they are in pixmap mode * nothing gets sent in bitmap mode. * If nocache is true (nonzero), ignore the cache setting from the client - @@ -171,7 +107,7 @@ if (!f) { - LOG (llevError, "client::send_face (%d) out of bounds??\n", facenum); + LOG (llevError | logBacktrace, "client::send_face (%d) out of bounds??\n", facenum); return; } @@ -184,46 +120,7 @@ faces_sent[facenum] = true; - // if for some reason we let a client without face caching connect, - // we better support that decision here and implement it. - if (!facecache) - return send_image (facenum); - - if (fxix) - { - fxface.push_back (facenum); - return; - } - - const facedata *d = f->data (faceset); - - packet sl; - - if (force_face0) - sl << "face " << uint16 (facenum); - else if (image2) - sl << "face2 " << uint16 (facenum) << uint8 (0) << uint32 (force_bad_checksum ? gcfclient_checksum (d) : 0); - else - sl << "face1 " << uint16 (facenum) << uint32 (force_bad_checksum ? gcfclient_checksum (d) : 0); - - // how lame - print_facename (sl, *d); - send_packet (sl); - - if (EMI_smooth) - { - if (f->smooth) - { - send_face (f->smooth); - - packet sl ("smooth"); - - sl << uint16 (facenum) - << uint16 (f->smooth); - - send_packet (sl); - } - } + fxface.push_back (facenum); } void client::flush_fx () @@ -277,42 +174,6 @@ } } -void -client::send_image (faceidx facenum) -{ - // never send face 0. ever. it does not exist. - if (!facenum) - return; - - const facedata *d = face_data (facenum, faceset); - - faces_sent[facenum] = true; - - if (!d) - { - LOG (llevError, "client::send_image (%d) out of bounds??\n", facenum); - return; - } - - //TODO: check type here? - - if (force_image_newmap) - force_newmap = true; - - packet sl; - - sl << (image2 ? "image2 " : "image ") - << uint32 (facenum); - - if (image2) - sl << uint8 (0); - - sl << uint32 (d->data.size ()) - << data (d->data.data (), d->data.size ()); - - send_packet (sl); -} - // send all faces of this object to the client // this uses more bandwidth initially, but makes // animations look much smoother, and every client @@ -422,20 +283,25 @@ sl.printf ("replyinfo image_sums %d %d ", start, stop); for (int i = start; i <= stop && i < faces.size (); i++) - { - ns->faces_sent[i] = true; + if (const faceinfo *f = face_info (i)) + if (ns->fx_want [f->type]) + { + ns->faces_sent[i] = true; - const facedata *d = face_data (i, ns->faceset); + const facedata *d = f->data (ns->faceset); - if (sl.room () < 2 + 4 + 1 + d->data.size () + 1) - break; + if (sl.room () < 2 + 4 + 1 + d->data.size () + 1) + break; - sl << uint16 (i) - << uint32 (0) // checksum - << uint8 (ns->faceset); + sl << uint16 (i) + << uint32 (0) // checksum + << uint8 (ns->faceset); - print_facename (sl, *d); sl << uint8 (0); - } + for (int i = 0; i < CHKSUM_SIZE; ++i) + sl.printf ("%02x", d->chksum [i]); + + sl << uint8 (0); + } /* It would make more sense to catch this pre-emptively in the code above. * however, if this really happens, we probably just want to cut down the @@ -443,7 +309,7 @@ * support. */ //TODO: taken care of above, should simply abort or make sure the above code is correct - if (sl.length () >= MAXSOCKBUF) + if (sl.length () > MAXSOCKBUF) { LOG (llevError, "send_image_send: buffer overrun, %d > %d\n", sl.length (), MAXSOCKBUF); abort ();