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.1 by elmex, Sun Aug 13 17:16:05 2006 UTC vs.
Revision 1.15 by root, Sat Dec 16 22:14:42 2006 UTC

1/*
2 * static char *rcsid_init_c =
3 * "$Id: image.C,v 1.1 2006/08/13 17:16:05 elmex Exp $";
4 */
5
6/* 1/*
7 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
8 3
9 Copyright (C) 2001 Mark Wedel 4 Copyright (C) 2001 Mark Wedel
10 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
21 16
22 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 20
26 The author can be reached via e-mail to crossfire-devel@real-time.com 21 The author can be reached via e-mail to <crossfire@schmorp.de>
27*/ 22*/
28 23
29/** \file 24/** \file
30 * Image related communication 25 * Image related communication
31 * 26 *
38 */ 33 */
39 34
40#include <global.h> 35#include <global.h>
41#include <sproto.h> 36#include <sproto.h>
42 37
43#include <newclient.h>
44#include <newserver.h>
45#include <loader.h>
46
47#define MAX_FACE_SETS 20 /**< Maximum number of image sets the program will handle */ 38#define MAX_FACE_SETS 20 /**< Maximum number of image sets the program will handle */
48 39
49/** Information about one image */ 40/** Information about one image */
50typedef struct FaceInfo { 41typedef struct FaceInfo
42{
51 uint8 *data; /**< image data */ 43 uint8 *data; /**< image data */
52 uint16 datalen; /**< length of the xpm data */ 44 uint16 datalen; /**< length of the xpm data */
53 uint32 checksum; /**< Checksum of face data */ 45 uint32 checksum; /**< Checksum of face data */
54} FaceInfo; 46} FaceInfo;
55 47
56/** Information about one face set */ 48/** Information about one face set */
57typedef struct { 49typedef struct
50{
58 char *prefix; /**< */ 51 char *prefix; /**< */
59 char *fullname; 52 char *fullname;
53
60 uint8 fallback; /**< faceset to use when an image is not found in this faceset */ 54 uint8 fallback; /**< faceset to use when an image is not found in this faceset */
61 char *size; 55 char *size;
62 char *extension; 56 char *extension;
63 char *comment; 57 char *comment;
58
64 FaceInfo *faces; /**< images in this faceset */ 59 FaceInfo *faces; /**< images in this faceset */
65} FaceSets; 60} FaceSets;
66 61
67static FaceSets facesets[MAX_FACE_SETS]; /**< All facesets */ 62static FaceSets facesets[MAX_FACE_SETS]; /**< All facesets */
68 63
69/** 64/**
70 * Checks specified faceset is valid 65 * Checks specified faceset is valid
71 * \param fsn faceset number 66 * \param fsn faceset number
72 */ 67 */
68int
73int is_valid_faceset(int fsn) 69is_valid_faceset (int fsn)
74{ 70{
75 if (fsn >=0 && fsn < MAX_FACE_SETS && facesets[fsn].prefix) return TRUE; 71 if (fsn >= 0 && fsn < MAX_FACE_SETS && facesets[fsn].prefix)
72 return TRUE;
76 return FALSE; 73 return FALSE;
77} 74}
78 75
79/** 76/**
80 * Frees all faceset information 77 * Frees all faceset information
81 */ 78 */
79void
82void free_socket_images(void) 80free_socket_images (void)
83{ 81{
84 int num,q; 82 int num, q;
85 83
86 for(num=0;num<MAX_FACE_SETS; num++) { 84 for (num = 0; num < MAX_FACE_SETS; num++)
85 {
87 if (facesets[num].prefix) { 86 if (facesets[num].prefix)
87 {
88 for (q=0; q<nrofpixmaps; q++) 88 for (q = 0; q < nrofpixmaps; q++)
89 if (facesets[num].faces[q].data) free(facesets[num].faces[q].data); 89 if (facesets[num].faces[q].data)
90 free (facesets[num].faces[q].data);
91
90 free(facesets[num].prefix); 92 free (facesets[num].prefix);
91 free(facesets[num].fullname); 93 free (facesets[num].fullname);
92 free(facesets[num].size); 94 free (facesets[num].size);
93 free(facesets[num].extension); 95 free (facesets[num].extension);
94 free(facesets[num].comment); 96 free (facesets[num].comment);
95 free(facesets[num].faces); 97 free (facesets[num].faces);
96 } 98 }
97 } 99 }
98} 100}
99 101
100/** 102/**
101 * This returns the set we will actually use when sending 103 * This returns the set we will actually use when sending
107 * 109 *
108 * \param faceset faceset to check 110 * \param faceset faceset to check
109 * \param imageno image number 111 * \param imageno image number
110 * 112 *
111 */ 113 */
114static int
112static int get_face_fallback(int faceset, int imageno) 115get_face_fallback (int faceset, int imageno)
113{ 116{
114 /* faceset 0 is supposed to have every image, so just return. Doing 117 /* faceset 0 is supposed to have every image, so just return. Doing
115 * so also prevents infinite loops in the case if it not having 118 * so also prevents infinite loops in the case if it not having
116 * the face, but in that case, we are likely to crash when we try 119 * the face, but in that case, we are likely to crash when we try
117 * to access the data, but that is probably preferable to an infinite 120 * to access the data, but that is probably preferable to an infinite
118 * loop. 121 * loop.
119 */ 122 */
120 if (faceset==0) return 0; 123 if (faceset == 0)
124 return 0;
121 125
122 if (!facesets[faceset].prefix) { 126 if (!facesets[faceset].prefix)
127 {
123 LOG(llevError,"get_face_fallback called with unused set (%d)?\n", faceset); 128 LOG (llevError, "get_face_fallback called with unused set (%d)?\n", faceset);
124 return 0; /* use default set */ 129 return 0; /* use default set */
125 } 130 }
131
126 if (facesets[faceset].faces[imageno].data) return faceset; 132 if (facesets[faceset].faces[imageno].data)
133 return faceset;
134
127 return get_face_fallback(facesets[faceset].fallback, imageno); 135 return get_face_fallback (facesets[faceset].fallback, imageno);
128} 136}
129 137
130/** 138/**
131 * Checks fallback are correctly defined. 139 * Checks fallback are correctly defined.
132 * This is a simple recursive function that makes sure the fallbacks 140 * This is a simple recursive function that makes sure the fallbacks
133 * are all proper (eg, the fall back to defined sets, and also 141 * are all proper (eg, the fall back to defined sets, and also
134 * eventually fall back to 0). At the top level, togo is set to MAX_FACE_SETS, 142 * eventually fall back to 0). At the top level, togo is set to MAX_FACE_SETS,
135 * if togo gets to zero, it means we have a loop. 143 * if togo gets to zero, it means we have a loop.
136 * This is only run when we first load the facesets. 144 * This is only run when we first load the facesets.
137 */ 145 */
146static void
138static void check_faceset_fallback(int faceset, int togo) 147check_faceset_fallback (int faceset, int togo)
139{ 148{
140 int fallback = facesets[faceset].fallback; 149 int fallback = facesets[faceset].fallback;
141 150
142 /* proper case - falls back to base set */ 151 /* proper case - falls back to base set */
143 if (fallback == 0) return; 152 if (fallback == 0)
153 return;
144 154
145 if (!facesets[fallback].prefix) { 155 if (!facesets[fallback].prefix)
156 {
146 LOG(llevError,"Face set %d falls to non set faceset %d\n", faceset, fallback); 157 LOG (llevError, "Face set %d falls to non set faceset %d\n", faceset, fallback);
147 abort(); 158 abort ();
148 } 159 }
160
149 togo--; 161 togo--;
150 if (togo == 0) { 162 if (togo == 0)
163 {
151 LOG(llevError,"Infinite loop found in facesets. aborting.\n"); 164 LOG (llevError, "Infinite loop found in facesets. aborting.\n");
152 abort(); 165 abort ();
153 } 166 }
167
154 check_faceset_fallback(fallback, togo); 168 check_faceset_fallback (fallback, togo);
155} 169}
156 170
157#define MAX_IMAGE_SIZE 10000 171#define MAX_IMAGE_SIZE 10000
158 172
159/** 173/**
170 * Function largely rewritten May 2000 to be more general purpose. 184 * Function largely rewritten May 2000 to be more general purpose.
171 * The server itself does not care what the image data is - to the server, 185 * The server itself does not care what the image data is - to the server,
172 * it is just data it needs to allocate. As such, the code is written 186 * it is just data it needs to allocate. As such, the code is written
173 * to do such. 187 * to do such.
174 */ 188 */
175 189void
176void read_client_images(void) 190read_client_images (void)
177{ 191{
178 char filename[400]; 192 char filename[400];
179 char buf[HUGE_BUF]; 193 char buf[HUGE_BUF];
180 char *cp, *cps[7]; 194 char *cp, *cps[7];
181 FILE *infile; 195 FILE *infile;
182 int num,len,compressed, fileno,i, badline; 196 int num, len, compressed, fileno, i, badline;
183 197
184 memset(facesets, 0, sizeof(facesets)); 198 memset (facesets, 0, sizeof (facesets));
185 sprintf(filename,"%s/image_info",settings.datadir); 199 sprintf (filename, "%s/image_info", settings.datadir);
186 if ((infile=open_and_uncompress(filename, 0, &compressed))==NULL) { 200 if ((infile = open_and_uncompress (filename, 0, &compressed)) == NULL)
201 {
187 LOG(llevError,"Unable to open %s\n", filename); 202 LOG (llevError, "Unable to open %s\n", filename);
188 abort(); 203 abort ();
189 } 204 }
205
190 while (fgets(buf, HUGE_BUF-1, infile)!=NULL) { 206 while (fgets (buf, HUGE_BUF - 1, infile) != NULL)
191 badline=0; 207 {
208 badline = 0;
192 209
193 if (buf[0] == '#') continue; 210 if (buf[0] == '#')
211 continue;
212
194 if (!(cps[0] = strtok(buf, ":"))) badline=1; 213 if (!(cps[0] = strtok (buf, ":")))
195 for (i=1; i<7; i++) { 214 badline = 1;
215
216 for (i = 1; i < 7; i++)
196 if (!(cps[i] = strtok(NULL, ":"))) badline=1; 217 if (!(cps[i] = strtok (NULL, ":")))
197 } 218 badline = 1;
198 if (badline) { 219
220 if (badline)
199 LOG(llevError,"Bad line in image_info file, ignoring line:\n %s", buf); 221 LOG (llevError, "Bad line in image_info file, ignoring line:\n %s", buf);
200 } else { 222 else
223 {
201 len = atoi(cps[0]); 224 len = atoi (cps[0]);
202 if (len >=MAX_FACE_SETS) { 225 if (len >= MAX_FACE_SETS)
226 {
203 LOG(llevError,"To high a setnum in image_info file: %d > %d\n", 227 LOG (llevError, "To high a setnum in image_info file: %d > %d\n", len, MAX_FACE_SETS);
204 len, MAX_FACE_SETS); 228 abort ();
205 abort(); 229 }
206 }
207 facesets[len].prefix = strdup_local(cps[1]); 230 facesets[len].prefix = strdup (cps[1]);
208 facesets[len].fullname = strdup_local(cps[2]); 231 facesets[len].fullname = strdup (cps[2]);
209 facesets[len].fallback = atoi(cps[3]); 232 facesets[len].fallback = atoi (cps[3]);
210 facesets[len].size = strdup_local(cps[4]); 233 facesets[len].size = strdup (cps[4]);
211 facesets[len].extension = strdup_local(cps[5]); 234 facesets[len].extension = strdup (cps[5]);
212 facesets[len].comment = strdup_local(cps[6]); 235 facesets[len].comment = strdup (cps[6]);
213 } 236 }
214 } 237 }
238
215 close_and_delete(infile,compressed); 239 close_and_delete (infile, compressed);
240
216 for (i=0; i<MAX_FACE_SETS; i++) { 241 for (i = 0; i < MAX_FACE_SETS; i++)
217 if (facesets[i].prefix) check_faceset_fallback(i, MAX_FACE_SETS);
218 } 242 {
243 if (facesets[i].prefix)
244 check_faceset_fallback (i, MAX_FACE_SETS);
245 }
246
219 /* Loaded the faceset information - now need to load up the 247 /* Loaded the faceset information - now need to load up the
220 * actual faces. 248 * actual faces.
221 */ 249 */
222 250
223 for (fileno=0; fileno<MAX_FACE_SETS; fileno++) { 251 for (fileno = 0; fileno < MAX_FACE_SETS; fileno++)
252 {
224 /* if prefix is not set, this is not used */ 253 /* if prefix is not set, this is not used */
225 if (!facesets[fileno].prefix) continue; 254 if (!facesets[fileno].prefix)
255 continue;
256
226 facesets[fileno].faces = (FaceInfo *) calloc(nrofpixmaps, sizeof(FaceInfo)); 257 facesets[fileno].faces = (FaceInfo *) calloc (nrofpixmaps, sizeof (FaceInfo));
227 258
228 sprintf(filename,"%s/crossfire.%d",settings.datadir, fileno); 259 sprintf (filename, "%s/crossfire.%d", settings.datadir, fileno);
229 LOG(llevDebug,"Loading image file %s\n", filename); 260 LOG (llevDebug, "Loading image file %s\n", filename);
230 261
231 if ((infile = open_and_uncompress(filename,0,&compressed))==NULL) { 262 if ((infile = open_and_uncompress (filename, 0, &compressed)) == NULL)
263 {
232 LOG(llevError,"Unable to open %s\n", filename); 264 LOG (llevError, "Unable to open %s\n", filename);
233 abort(); 265 abort ();
234 } 266 }
267
235 while(fgets(buf, HUGE_BUF-1, infile)!=NULL) { 268 while (fgets (buf, HUGE_BUF - 1, infile) != NULL)
269 {
236 if(strncmp(buf,"IMAGE ",6)!=0) { 270 if (strncmp (buf, "IMAGE ", 6) != 0)
271 {
237 LOG(llevError,"read_client_images:Bad image line - not IMAGE, instead\n%s",buf); 272 LOG (llevError, "read_client_images:Bad image line - not IMAGE, instead\n%s", buf);
238 abort(); 273 abort ();
239 } 274 }
275
240 num = atoi(buf+6); 276 num = atoi (buf + 6);
241 if (num<0 || num>=nrofpixmaps) { 277 if (num < 0 || num >= nrofpixmaps)
278 {
242 LOG(llevError,"read_client_images: Image num %d not in 0..%d\n%s", 279 LOG (llevError, "read_client_images: Image num %d not in 0..%d\n%s", num, nrofpixmaps, buf);
243 num,nrofpixmaps,buf); 280 abort ();
244 abort(); 281 }
245 } 282
246 /* Skip accross the number data */ 283 /* Skip accross the number data */
247 for (cp=buf+6; *cp!=' '; cp++) ; 284 for (cp = buf + 6; *cp != ' '; cp++);
248 len = atoi(cp); 285 len = atoi (cp);
249 if (len==0 || len>MAX_IMAGE_SIZE) { 286 if (len == 0 || len > MAX_IMAGE_SIZE)
250 LOG(llevError,"read_client_images: length not valid: %d > %d \n%s", 287 {
251 len,MAX_IMAGE_SIZE,buf); 288 LOG (llevError, "read_client_images: length not valid: %d > %d \n%s", len, MAX_IMAGE_SIZE, buf);
252 abort(); 289 abort ();
253 } 290 }
291
254 /* We don't actualy care about the name if the image that 292 /* We don't actualy care about the name of the image that
255 * is embedded in the image file, so just ignore it. 293 * is embedded in the image file, so just ignore it.
256 */ 294 */
257 facesets[fileno].faces[num].datalen = len; 295 facesets[fileno].faces[num].datalen = len;
258 facesets[fileno].faces[num].data = (uint8*) malloc(len); 296 facesets[fileno].faces[num].data = (uint8 *) malloc (len);
259 if ((i=fread(facesets[fileno].faces[num].data, len, 1, infile))!=1) { 297 if ((i = fread (facesets[fileno].faces[num].data, len, 1, infile)) != 1)
298 {
260 LOG(llevError,"read_client_images: Did not read desired amount of data, wanted %d, got %d\n%s", 299 LOG (llevError, "read_client_images: Did not read desired amount of data, wanted %d, got %d\n%s", len, i, buf);
261 len, i, buf); 300 abort ();
262 abort(); 301 }
263 } 302
264 facesets[fileno].faces[num].checksum=0; 303 facesets[fileno].faces[num].checksum = 0;
265 for (i=0; i<len; i++) { 304 for (i = 0; i < len; i++)
305 {
266 ROTATE_RIGHT(facesets[fileno].faces[num].checksum); 306 ROTATE_RIGHT (facesets[fileno].faces[num].checksum);
267 facesets[fileno].faces[num].checksum += facesets[fileno].faces[num].data[i]; 307 facesets[fileno].faces[num].checksum += facesets[fileno].faces[num].data[i];
268 facesets[fileno].faces[num].checksum &= 0xffffffff; 308 facesets[fileno].faces[num].checksum &= 0xffffffff;
269 } 309 }
270 } 310 }
311
271 close_and_delete(infile,compressed); 312 close_and_delete (infile, compressed);
272 } /* For fileno < MAX_FACE_SETS */ 313 } /* For fileno < MAX_FACE_SETS */
273} 314}
274 315
275/** 316/**
276 * Client tells us what type of faces it wants. Also sets 317 * Client tells us what type of faces it wants. Also sets
277 * the caching attribute. 318 * the caching attribute.
278 * 319 *
279 */ 320 */
280 321void
281void SetFaceMode(char *buf, int len, NewSocket *ns) 322SetFaceMode (char *buf, int len, client *ns)
282{ 323{
283 char tmp[256];
284
285 int mask =(atoi(buf) & CF_FACE_CACHE), mode=(atoi(buf) & ~CF_FACE_CACHE); 324 int mask = (atoi (buf) & CF_FACE_CACHE), mode = (atoi (buf) & ~CF_FACE_CACHE);
286 325
287 if (mode==CF_FACE_NONE) { 326 if (mode == CF_FACE_NONE)
288 ns->facecache=1; 327 ns->facecache = 1;
289 } else if (mode!=CF_FACE_PNG) { 328 else if (mode != CF_FACE_PNG)
290 sprintf(tmp,"drawinfo %d %s", NDI_RED,"Warning - send unsupported face mode. Will use Png"); 329 ns->send_packet_printf ("drawinfo %d %s", NDI_RED, "Warning - send unsupported face mode. Will use Png");
291 Write_String_To_Socket(ns, tmp, strlen(tmp)); 330
292#ifdef ESRV_DEBUG
293 LOG(llevDebug,"SetFaceMode: Invalid mode from client: %d\n", mode);
294#endif
295 }
296 if (mask) { 331 if (mask)
297 ns->facecache=1; 332 ns->facecache = 1;
298 }
299} 333}
300 334
301/** 335/**
302 * Client has requested pixmap that it somehow missed getting. 336 * Client has requested pixmap that it somehow missed getting.
303 * This will be called often if the client is 337 * This will be called often if the client is
304 * caching images. 338 * caching images.
305 */ 339 */
306 340void
307void SendFaceCmd(char *buff, int len, NewSocket *ns) 341SendFaceCmd (char *buf, int len, client *ns)
308{ 342{
309 long tmpnum = atoi(buff); 343 uint16 facenum = atoi (buf);
310 short facenum=tmpnum & 0xffff;
311 344
312 if(facenum!=0) 345 if (facenum != 0)
313 esrv_send_face(ns, facenum,1); 346 esrv_send_face (ns, facenum, 1);
314} 347}
315 348
316/** 349/**
317 * Sends a face to a client if they are in pixmap mode 350 * Sends a face to a client if they are in pixmap mode
318 * nothing gets sent in bitmap mode. 351 * nothing gets sent in bitmap mode.
319 * If nocache is true (nonzero), ignore the cache setting from the client - 352 * If nocache is true (nonzero), ignore the cache setting from the client -
320 * this is needed for the askface, in which we really do want to send the 353 * this is needed for the askface, in which we really do want to send the
321 * face (and askface is the only place that should be setting it). Otherwise, 354 * face (and askface is the only place that should be setting it). Otherwise,
322 * we look at the facecache, and if set, send the image name. 355 * we look at the facecache, and if set, send the image name.
323 */ 356 */
324 357void
325void esrv_send_face(NewSocket *ns,short face_num, int nocache) 358esrv_send_face (client *ns, short face_num, int nocache)
326{ 359{
327 SockList sl;
328 char fallback; 360 char fallback;
329 361
330 if (face_num <= 0 || face_num >= nrofpixmaps) { 362 if (face_num <= 0 || face_num >= nrofpixmaps)
363 {
331 LOG(llevError,"esrv_send_face (%d) out of bounds??\n",face_num); 364 LOG (llevError, "esrv_send_face (%d) out of bounds??\n", face_num);
332 return; 365 return;
333 } 366 }
334 367
335 sl.buf = (unsigned char*) malloc(MAXSOCKBUF); 368 packet sl;
336 fallback = get_face_fallback(ns->faceset, face_num); 369 fallback = get_face_fallback (ns->faceset, face_num);
337 370
338 if (facesets[fallback].faces[face_num].data == NULL) { 371 if (facesets[fallback].faces[face_num].data == NULL)
372 {
339 LOG(llevError,"esrv_send_face: faces[%d].data == NULL\n",face_num); 373 LOG (llevError, "esrv_send_face: faces[%d].data == NULL\n", face_num);
340 return; 374 return;
341 } 375 }
342 376
343 if (ns->facecache && !nocache) { 377 if (ns->facecache && !nocache)
378 {
379 sl << (ns->image2 ? "face2 " : "face1 ")
380 << uint16 (face_num);
381
344 if (ns->image2) 382 if (ns->image2)
345 strcpy((char*)sl.buf, "face2 "); 383 sl << uint8 (fallback);
346 else if (ns->sc_version >= 1026)
347 strcpy((char*)sl.buf, "face1 ");
348 else
349 strcpy((char*)sl.buf, "face ");
350 384
351 sl.len=strlen((const char*)sl.buf); 385 sl << uint32 (facesets[fallback].faces[face_num].checksum)
352 SockList_AddShort(&sl, face_num); 386 << new_faces[face_num].name;
387
388 ns->send_packet (sl);
389 }
390 else
391 {
392 sl << (ns->image2 ? "image2 " : "image ")
393 << uint32 (face_num);
394
353 if (ns->image2) 395 if (ns->image2)
354 SockList_AddChar(&sl, fallback); 396 sl << uint8 (fallback);
355 if (ns->sc_version >= 1026) 397
356 SockList_AddInt(&sl, facesets[fallback].faces[face_num].checksum);
357 strcpy((char*)sl.buf + sl.len, new_faces[face_num].name);
358 sl.len += strlen(new_faces[face_num].name);
359 Send_With_Handling(ns, &sl);
360 }
361 else {
362 if (ns->image2)
363 strcpy((char*)sl.buf, "image2 ");
364 else
365 strcpy((char*)sl.buf, "image ");
366 sl.len=strlen((char*)sl.buf);
367 SockList_AddInt(&sl, face_num);
368 if (ns->image2)
369 SockList_AddChar(&sl, fallback);
370 SockList_AddInt(&sl, facesets[fallback].faces[face_num].datalen);
371 memcpy(sl.buf+sl.len, facesets[fallback].faces[face_num].data,
372 facesets[fallback].faces[face_num].datalen);
373 sl.len += facesets[fallback].faces[face_num].datalen; 398 sl << uint32 (facesets[fallback].faces[face_num].datalen)
374 Send_With_Handling(ns, &sl); 399 << data (facesets[fallback].faces[face_num].data, facesets[fallback].faces[face_num].datalen);
400
401 ns->send_packet (sl);
375 } 402 }
403
376 ns->faces_sent[face_num] |= NS_FACESENT_FACE; 404 ns->faces_sent[face_num] |= NS_FACESENT_FACE;
377 free(sl.buf);
378} 405}
379 406
380/** 407/**
381 * Sends the number of images, checksum of the face file, 408 * Sends the number of images, checksum of the face file,
382 * and the image_info file information. See the doc/Developers/protocol 409 * and the image_info file information. See the doc/Developers/protocol
383 * if you want further detail. 410 * if you want further detail.
384 */ 411 */
385 412
413void
386void send_image_info(NewSocket *ns, char *params) 414send_image_info (client *ns, char *params)
387{ 415{
388 SockList sl; 416 packet sl;
389 int i;
390 417
391 sl.buf = (unsigned char *) malloc(MAXSOCKBUF);
392
393 sprintf((char*)sl.buf,"replyinfo image_info\n%d\n%d\n", nrofpixmaps-1, bmaps_checksum); 418 sl.printf ("replyinfo image_info\n%d\n%d\n", nrofpixmaps - 1, bmaps_checksum);
419
394 for (i=0; i<MAX_FACE_SETS; i++) { 420 for (int i = 0; i < MAX_FACE_SETS; i++)
395 if (facesets[i].prefix) { 421 if (facesets[i].prefix)
396 sprintf((char*)sl.buf + strlen((const char*)sl.buf), "%d:%s:%s:%d:%s:%s:%s", 422 sl.printf ("%d:%s:%s:%d:%s:%s:%s", i,
397 i, facesets[i].prefix, facesets[i].fullname, facesets[i].fallback, 423 facesets[i].prefix, facesets[i].fullname , facesets[i].fallback,
398 facesets[i].size, facesets[i].extension, facesets[i].comment); 424 facesets[i].size , facesets[i].extension, facesets[i].comment);
399 } 425
400 } 426 ns->send_packet (sl);
401 sl.len = strlen((const char*)sl.buf);
402 Send_With_Handling(ns, &sl);
403 free(sl.buf);
404} 427}
405 428
406/** 429/**
407 * Sends requested face information. 430 * Sends requested face information.
408 * \param ns socket to send to 431 * \param ns socket to send to
410 * 433 *
411 * For each image in [start..stop] sends 434 * For each image in [start..stop] sends
412 * - checksum 435 * - checksum
413 * - name 436 * - name
414 */ 437 */
438void
415void send_image_sums(NewSocket *ns, char *params) 439send_image_sums (client *ns, char *params)
416{ 440{
417 int start, stop; 441 int start, stop;
418 short i;
419 char qq;
420 char *cp, buf[MAX_BUF]; 442 char *cp, buf[MAX_BUF];
421 SockList sl;
422 443
423 sl.buf = (unsigned char *) malloc(MAXSOCKBUF); 444 packet sl;
424 445
425 start = atoi(params); 446 start = atoi (params);
426 for (cp = params; *cp != '\0'; cp++) 447 for (cp = params; *cp != '\0'; cp++)
427 if (*cp == ' ') break; 448 if (*cp == ' ')
449 break;
428 450
429 stop = atoi(cp); 451 stop = atoi (cp);
430 if (stop < start || *cp == '\0' || (stop-start)>1000 || stop >= nrofpixmaps) { 452 if (stop < start || *cp == '\0' || (stop - start) > 1000 || stop >= nrofpixmaps)
453 {
454 sl.printf ("replyinfo image_sums %d %d", start, stop);
455 ns->send_packet (sl);
456 sl.reset ();
457 return;
458 }
459
431 sprintf(buf,"replyinfo image_sums %d %d", start, stop); 460 sl.printf ("replyinfo image_sums %d %d ", start, stop);
432 cs_write_string(ns, buf, strlen(buf));
433 return;
434 }
435 sprintf((char*)sl.buf,"replyinfo image_sums %d %d ", start, stop);
436 461
437 sl.len = strlen((const char*)sl.buf);
438
439 for (i=start; i<=stop; i++) { 462 for (int i = start; i <= stop; i++)
440 SockList_AddShort(&sl, i); 463 {
441 ns->faces_sent[i] |= NS_FACESENT_FACE; 464 ns->faces_sent[i] |= NS_FACESENT_FACE;
442 465
443 qq = get_face_fallback(ns->faceset, i); 466 int qq = get_face_fallback (ns->faceset, i);
444 SockList_AddInt(&sl, facesets[qq].faces[i].checksum);
445 SockList_AddChar(&sl, qq);
446 467
447 qq = strlen(new_faces[i].name); 468 sl << uint16 (i)
448 SockList_AddChar(&sl, ( char )( qq + 1 )); 469 << uint32 (facesets[qq].faces[i].checksum)
449 strcpy((char*)sl.buf + sl.len, new_faces[i].name); 470 << uint8 (qq)
450 sl.len += qq; 471 << data8 (&new_faces[i].name, new_faces[i].name.length () + 1);
451 SockList_AddChar(&sl, 0);
452 } 472 }
473
453 /* It would make more sense to catch this pre-emptively in the code above. 474 /* It would make more sense to catch this pre-emptively in the code above.
454 * however, if this really happens, we probably just want to cut down the 475 * however, if this really happens, we probably just want to cut down the
455 * size to less than 1000, since that is what we claim the protocol would 476 * size to less than 1000, since that is what we claim the protocol would
456 * support. 477 * support.
457 */ 478 */
458 if (sl.len >= MAXSOCKBUF) { 479 if (sl.length () >= MAXSOCKBUF)
480 {
459 LOG(llevError,"send_image_send: buffer overrun, %d > %d\n", sl.len, MAXSOCKBUF); 481 LOG (llevError, "send_image_send: buffer overrun, %d > %d\n", sl.length (), MAXSOCKBUF);
460 abort(); 482 abort ();
461 } 483 }
462 Send_With_Handling(ns, &sl); 484
463 free(sl.buf); 485 ns->send_packet (sl);
464} 486}
487

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines