ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/socket/image.C
(Generate patch)

Comparing deliantra/server/socket/image.C (file contents):
Revision 1.57 by root, Fri Dec 26 10:44:17 2008 UTC vs.
Revision 1.58 by root, Sat Dec 27 01:25:00 2008 UTC

38#include "crc.h" 38#include "crc.h"
39 39
40#define MAX_IMAGE_SIZE 10000 40#define MAX_IMAGE_SIZE 10000
41 41
42/** 42/**
43 * Client tells us what type of faces it wants. Also sets
44 * the caching attribute.
45 *
46 */
47void
48SetFaceMode (char *buf, int len, client *ns)
49{
50 int mask = (atoi (buf) & CF_FACE_CACHE), mode = (atoi (buf) & ~CF_FACE_CACHE);
51
52 if (mode == CF_FACE_NONE)
53 ns->facecache = 1;
54 else if (mode != CF_FACE_PNG)
55 ns->send_packet_printf ("drawinfo %d %s", NDI_RED, "Warning - send unsupported face mode. Will use Png");
56
57 if (mask)
58 ns->facecache = 1;
59}
60
61/**
62 * client requested an image. send it rate-limited 43 * client requested an image. send it rate-limited
63 * before flushing. 44 * before flushing.
64 */ 45 */
65void 46void
66AskFaceCmd (char *buf, int len, client *ns) 47AskFaceCmd (char *buf, int len, client *ns)
82 ix.idx = idx; 63 ix.idx = idx;
83 ix.ofs = d->data.size (); 64 ix.ofs = d->data.size ();
84 65
85 auto (pos, ns->ixface.end ()); 66 auto (pos, ns->ixface.end ());
86 67
87 if (ns->fxix < 2)
88 {
89 // gcfclient does not support prioritising, older cfplus versions
90 // do not support interleaved transfers.
91 if (!ns->ixface.empty ())
92 pos = ns->ixface.end () - 1;
93 }
94 else
95 {
96 // the by far most common case will be to insert 68 // the by far most common case will be to insert
97 // near the end, so little looping. 69 // near the end, so little looping.
98 while (pos != ns->ixface.begin ()) 70 while (pos != ns->ixface.begin ())
71 {
72 --pos;
73
74 // sort within 2k bins, to slightly prefer smaller images
75 if (pri > pos->pri || (pri == pos->pri && (ix.ofs >> 11) <= (pos->ofs >> 11)))
99 { 76 {
100 --pos;
101
102 // sort within 2k bins, to slightly prefer smaller images
103 if (pri > pos->pri || (pri == pos->pri && (ix.ofs >> 11) <= (pos->ofs >> 11)))
104 {
105 ++pos; 77 ++pos;
106 break; 78 break;
107 }
108 } 79 }
109 } 80 }
110 81
111 ns->ixface.insert (pos, ix); 82 ns->ixface.insert (pos, ix);
112 83
113#if 0 84#if 0
114 for (auto (i, ns->ixface.begin ()); i != ns->ixface.end (); ++i) 85 for (auto (i, ns->ixface.begin ()); i != ns->ixface.end (); ++i)
115 fprintf (stderr, "<%d,%d> ", i->pri, i->ofs); 86 fprintf (stderr, "<%d,%d> ", i->pri, i->ofs);
116 fprintf (stderr, "\n"); 87 fprintf (stderr, "\n");
117#endif 88#endif
118}
119
120/**
121 * Tells client the picture it has to use
122 * to smooth a picture number given as argument.
123 */
124void
125AskSmooth (char *buf, int len, client *ns)
126{
127 ns->send_face (atoi (buf), -100);
128 ns->flush_fx ();
129}
130
131// how lame
132static void print_facename (packet &sl, const facedata &d)
133{
134 for (int i = 0; i < CHKSUM_SIZE; ++i)
135 sl.printf ("%02x", d.chksum [i]);
136}
137
138// gcfclient uses the server-provided checksum for comparison, but always
139// writes a broken checksum to its cache file, so we have to provide
140// gcfclient with the same broken (and useless) checksum just to have it
141// cache the image despite its bugs.
142static uint32 gcfclient_checksum (const facedata *d)
143{
144 uint32 csum = 0;
145
146 for (std::string::const_iterator i = d->data.begin ();
147 i != d->data.end ();
148 ++i)
149 {
150 csum = rotate_right (csum);
151 csum += *(uint8 *)&*i;
152 }
153
154 return csum;
155} 89}
156 90
157/** 91/**
158 * Sends a face to a client if they are in pixmap mode 92 * Sends a face to a client if they are in pixmap mode
159 * nothing gets sent in bitmap mode. 93 * nothing gets sent in bitmap mode.
184 if (faces_sent [facenum]) 118 if (faces_sent [facenum])
185 return; 119 return;
186 120
187 faces_sent[facenum] = true; 121 faces_sent[facenum] = true;
188 122
189 // if for some reason we let a client without face caching connect,
190 // we better support that decision here and implement it.
191 if (!facecache)
192 return send_image (facenum);
193
194 if (fxix)
195 {
196 fxface.push_back (facenum); 123 fxface.push_back (facenum);
197 return;
198 }
199
200 const facedata *d = f->data (faceset);
201
202 packet sl;
203
204 if (force_face0)
205 sl << "face " << uint16 (facenum);
206 else if (image2)
207 sl << "face2 " << uint16 (facenum) << uint8 (0) << uint32 (force_bad_checksum ? gcfclient_checksum (d) : 0);
208 else
209 sl << "face1 " << uint16 (facenum) << uint32 (force_bad_checksum ? gcfclient_checksum (d) : 0);
210
211 // how lame
212 print_facename (sl, *d);
213 send_packet (sl);
214} 124}
215 125
216void client::flush_fx () 126void client::flush_fx ()
217{ 127{
218 while (!fxface.empty ()) 128 while (!fxface.empty ())
262 send_packet (fx); 172 send_packet (fx);
263 if (sx.length () > 3) send_packet (sx); 173 if (sx.length () > 3) send_packet (sx);
264 } 174 }
265} 175}
266 176
267void
268client::send_image (faceidx facenum)
269{
270 // never send face 0. ever. it does not exist.
271 if (!facenum)
272 return;
273
274 const facedata *d = face_data (facenum, faceset);
275
276 faces_sent[facenum] = true;
277
278 if (!d)
279 {
280 LOG (llevError, "client::send_image (%d) out of bounds??\n", facenum);
281 return;
282 }
283
284 if (force_image_newmap)
285 force_newmap = true;
286
287 packet sl;
288
289 sl << (image2 ? "image2 " : "image ")
290 << uint32 (facenum);
291
292 if (image2)
293 sl << uint8 (0);
294
295 sl << uint32 (d->data.size ())
296 << data (d->data.data (), d->data.size ());
297
298 send_packet (sl);
299}
300
301// send all faces of this object to the client 177// send all faces of this object to the client
302// this uses more bandwidth initially, but makes 178// this uses more bandwidth initially, but makes
303// animations look much smoother, and every client 179// animations look much smoother, and every client
304// is supposed to do client-side caching anyways. 180// is supposed to do client-side caching anyways.
305void 181void
419 295
420 sl << uint16 (i) 296 sl << uint16 (i)
421 << uint32 (0) // checksum 297 << uint32 (0) // checksum
422 << uint8 (ns->faceset); 298 << uint8 (ns->faceset);
423 299
424 print_facename (sl, *d); sl << uint8 (0); 300 for (int i = 0; i < CHKSUM_SIZE; ++i)
301 sl.printf ("%02x", d->chksum [i]);
302
303 sl << uint8 (0);
425 } 304 }
426 305
427 /* It would make more sense to catch this pre-emptively in the code above. 306 /* It would make more sense to catch this pre-emptively in the code above.
428 * however, if this really happens, we probably just want to cut down the 307 * however, if this really happens, we probably just want to cut down the
429 * size to less than 1000, since that is what we claim the protocol would 308 * size to less than 1000, since that is what we claim the protocol would

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines