Crossfire Server, Branches 1.12  R18729
image.c
Go to the documentation of this file.
1 /*
2  * static char *rcsid_init_c =
3  * "$Id: image.c 11578 2009-02-23 22:02:27Z lalo $";
4  */
5 
6 /*
7  CrossFire, A Multiplayer game for X-windows
8 
9  Copyright (C) 2006 Mark Wedel & Crossfire Development Team
10  Copyright (C) 1992 Frank Tore Johansen
11 
12  This program is free software; you can redistribute it and/or modify
13  it under the terms of the GNU General Public License as published by
14  the Free Software Foundation; either version 2 of the License, or
15  (at your option) any later version.
16 
17  This program is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  GNU General Public License for more details.
21 
22  You should have received a copy of the GNU General Public License
23  along with this program; if not, write to the Free Software
24  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 
26  The author can be reached via e-mail to crossfire-devel@real-time.com
27 */
28 
40 #include <global.h>
41 #include <sproto.h>
42 
43 #include <newclient.h>
44 #include <newserver.h>
45 #include <loader.h>
46 #include <image.h>
47 
53 void set_face_mode_cmd(char *buf, int len, socket_struct *ns) {
54  int mask = (atoi(buf)&CF_FACE_CACHE), mode = (atoi(buf)&~CF_FACE_CACHE);
55 
56  if (mode == CF_FACE_NONE) {
57  ns->facecache = 1;
58  } else if (mode != CF_FACE_PNG) {
59  SockList sl;
60 
61  SockList_Init(&sl);
62  SockList_AddPrintf(&sl, "drawinfo %d %s", NDI_RED, "Warning - send unsupported face mode. Will use Png");
63  Send_With_Handling(ns, &sl);
64  SockList_Term(&sl);
65 #ifdef ESRV_DEBUG
66  LOG(llevDebug, "set_face_mode_cmd: Invalid mode from client: %d\n", mode);
67 #endif
68  }
69  if (mask) {
70  ns->facecache = 1;
71  }
72 }
73 
80 void send_face_cmd(char *buff, int len, socket_struct *ns) {
81  long tmpnum = atoi(buff);
82  short facenum = tmpnum&0xffff;
83 
84  if (facenum != 0)
85  esrv_send_face(ns, facenum, 1);
86 }
87 
96 void esrv_send_face(socket_struct *ns, short face_num, int nocache) {
97  SockList sl;
98  int fallback;
99 
100  if (face_num <= 0 || face_num >= nrofpixmaps) {
101  LOG(llevError, "esrv_send_face (%d) out of bounds??\n", face_num);
102  return;
103  }
104 
105  SockList_Init(&sl);
106  fallback = get_face_fallback(ns->faceset, face_num);
107 
108  if (facesets[fallback].faces[face_num].data == NULL) {
109  LOG(llevError, "esrv_send_face: faces[%d].data == NULL\n", face_num);
110  return;
111  }
112 
113  if (ns->facecache && !nocache) {
114  SockList_AddString(&sl, "face2 ");
115  SockList_AddShort(&sl, face_num);
116  SockList_AddChar(&sl, fallback);
117  SockList_AddInt(&sl, facesets[fallback].faces[face_num].checksum);
118  SockList_AddString(&sl, new_faces[face_num].name);
119  Send_With_Handling(ns, &sl);
120  } else {
121  SockList_AddString(&sl, "image2 ");
122  SockList_AddInt(&sl, face_num);
123  SockList_AddChar(&sl, fallback);
124  SockList_AddInt(&sl, facesets[fallback].faces[face_num].datalen);
125  SockList_AddData(&sl, facesets[fallback].faces[face_num].data, facesets[fallback].faces[face_num].datalen);
126  Send_With_Handling(ns, &sl);
127  }
128  ns->faces_sent[face_num] |= NS_FACESENT_FACE;
129  SockList_Term(&sl);
130 }
131 
138 void send_image_info(socket_struct *ns, char *params) {
139  SockList sl;
140  int i;
141 
142  SockList_Init(&sl);
143  SockList_AddPrintf(&sl, "replyinfo image_info\n%d\n%d\n", nrofpixmaps-1, bmaps_checksum);
144  for (i = 0; i < MAX_FACE_SETS; i++) {
145  if (facesets[i].prefix) {
146  SockList_AddPrintf(&sl, "%d:%s:%s:%d:%s:%s:%s",
147  i, facesets[i].prefix, facesets[i].fullname,
148  facesets[i].fallback, facesets[i].size,
149  facesets[i].extension, facesets[i].comment);
150  }
151  }
152  Send_With_Handling(ns, &sl);
153  SockList_Term(&sl);
154 }
155 
165 void send_image_sums(socket_struct *ns, char *params) {
166  int start, stop;
167  short i;
168  char *cp;
169  SockList sl;
170 
171  SockList_Init(&sl);
172 
173  start = atoi(params);
174  for (cp = params; *cp != '\0'; cp++)
175  if (*cp == ' ')
176  break;
177 
178  stop = atoi(cp);
179  if (stop < start
180  || *cp == '\0'
181  || (stop-start) > 1000
182  || stop >= nrofpixmaps) {
183  SockList_AddPrintf(&sl, "replyinfo image_sums %d %d", start, stop);
184  Send_With_Handling(ns, &sl);
185  SockList_Term(&sl);
186  return;
187  }
188  SockList_AddPrintf(&sl, "replyinfo image_sums %d %d ", start, stop);
189 
190  for (i = start; i <= stop; i++) {
191  int faceset;
192 
193  if (SockList_Avail(&sl) < 2+4+1+1+strlen(new_faces[i].name)+1) {
194  LOG(llevError, "send_image_sums: buffer overflow, rejecting range %d..%d\n", start, stop);
195  SockList_Reset(&sl);
196  SockList_AddPrintf(&sl, "replyinfo image_sums %d %d", start, stop);
197  Send_With_Handling(ns, &sl);
198  SockList_Term(&sl);
199  return;
200  }
201 
202  SockList_AddShort(&sl, i);
203  ns->faces_sent[i] |= NS_FACESENT_FACE;
204 
205  faceset = get_face_fallback(ns->faceset, i);
206  SockList_AddInt(&sl, facesets[faceset].faces[i].checksum);
207  SockList_AddChar(&sl, faceset);
208  SockList_AddLen8Data(&sl, new_faces[i].name, strlen(new_faces[i].name)+1);
209  }
210  Send_With_Handling(ns, &sl);
211  SockList_Term(&sl);
212 }
#define CF_FACE_PNG
Definition: newclient.h:240
void SockList_AddPrintf(SockList *sl, const char *format,...)
Definition: lowlevel.c:187
void SockList_Reset(SockList *sl)
Definition: lowlevel.c:85
#define CF_FACE_NONE
Definition: newclient.h:237
#define NS_FACESENT_FACE
Definition: newserver.h:164
int nrofpixmaps
Definition: image.c:76
void SockList_Init(SockList *sl)
Definition: lowlevel.c:67
New_Face * new_faces
Definition: image.c:38
void set_face_mode_cmd(char *buf, int len, socket_struct *ns)
Definition: image.c:53
char * name
Definition: image.c:53
void SockList_AddShort(SockList *sl, uint16 data)
Definition: lowlevel.c:113
#define NDI_RED
Definition: newclient.h:198
uint8 * faces_sent
Definition: newserver.h:121
void SockList_AddData(SockList *sl, const void *data, size_t len)
Definition: lowlevel.c:164
void SockList_Term(SockList *sl)
Definition: lowlevel.c:77
void SockList_AddString(SockList *sl, const char *data)
Definition: lowlevel.c:154
uint32 facecache
Definition: newserver.h:128
size_t SockList_Avail(const SockList *sl)
Definition: lowlevel.c:231
void SockList_AddChar(SockList *sl, char c)
Definition: lowlevel.c:103
void send_image_info(socket_struct *ns, char *params)
Definition: image.c:138
void send_image_sums(socket_struct *ns, char *params)
Definition: image.c:165
#define MAX_FACE_SETS
Definition: image.h:49
face_sets facesets[MAX_FACE_SETS]
Definition: image.c:78
EXTERN int bmaps_checksum
Definition: global.h:242
void SockList_AddLen8Data(SockList *sl, const void *data, size_t len)
Definition: lowlevel.c:176
#define CF_FACE_CACHE
Definition: newclient.h:241
void esrv_send_face(socket_struct *ns, short face_num, int nocache)
Definition: image.c:96
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:63
int get_face_fallback(int faceset, int imageno)
Definition: image.c:614
void SockList_AddInt(SockList *sl, uint32 data)
Definition: lowlevel.c:124
void send_face_cmd(char *buff, int len, socket_struct *ns)
Definition: image.c:80
uint8 faceset
Definition: newserver.h:144
void Send_With_Handling(socket_struct *ns, SockList *sl)
Definition: lowlevel.c:541