Crossfire Server, Trunk
image.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
25 #include "global.h"
26 
27 #include <stdlib.h>
28 #include <string.h>
29 
30 #include "image.h"
31 #include "newserver.h"
32 #include "shared/newclient.h"
33 #include "sproto.h"
34 #include "assets.h"
35 
44 void send_face_cmd(char *buff, int len, socket_struct *ns) {
45  long tmpnum;
46  uint16_t faceid;
47 
48  if (len <= 0 || !buff) {
49  LOG(llevDebug, "IP '%s' sent bogus send_face_cmd information\n", ns->host);
50  return;
51  }
52 
53  tmpnum = atoi(buff);
54  faceid = tmpnum&0xffff;
55 
56  if (faceid != 0)
57  esrv_send_face(ns, get_face_by_id(faceid), 1);
58 }
59 
71 void esrv_send_face(socket_struct *ns, const Face *face, int nocache) {
72  SockList sl;
73 
74  if (face == NULL) {
75  LOG(llevError, "esrv_send_face NULL??\n");
76  return;
77  }
78 
79  SockList_Init(&sl);
81 
82  if (!fs || fs->faces[face->number].data == NULL) {
83  LOG(llevError, "esrv_send_face: faces[%d].data == NULL\n", face->number);
84  return;
85  }
86 
87  if (ns->facecache && !nocache) {
88  SockList_AddString(&sl, "face2 ");
89  SockList_AddShort(&sl, face->number);
90  SockList_AddChar(&sl, fs->id);
91  SockList_AddInt(&sl, fs->faces[face->number].checksum);
92  SockList_AddString(&sl, face->name);
93  Send_With_Handling(ns, &sl);
94  } else {
95  SockList_AddString(&sl, "image2 ");
96  SockList_AddInt(&sl, face->number);
97  SockList_AddChar(&sl, fs->id);
98  SockList_AddInt(&sl, fs->faces[face->number].datalen);
99  SockList_AddData(&sl, fs->faces[face->number].data, fs->faces[face->number].datalen);
100  Send_With_Handling(ns, &sl);
101  }
102  ns->faces_sent[face->number] |= NS_FACESENT_FACE;
103  SockList_Term(&sl);
104 }
105 
107 static SockList *ugly;
108 static void do_faceset(const face_sets *fs) {
109  SockList_AddPrintf(ugly, "%d:%s:%s:%d:%s:%s:%s\n",
110  fs->id, fs->prefix, fs->fullname,
111  fs->fallback ? fs->fallback->id : 0, fs->size,
112  fs->extension, fs->comment);
113 }
114 
122  SockList sl;
123 
124  SockList_Init(&sl);
125 
126  ugly = &sl;
127  SockList_AddPrintf(&sl, "replyinfo image_info\n%d\n%d\n", get_faces_count()-1, get_bitmap_checksum());
129  Send_With_Handling(ns, &sl);
130  SockList_Term(&sl);
131 }
132 
143  unsigned int start, stop;
144  unsigned short i;
145  char *cp;
146  SockList sl;
147 
148  // Sanity check:
149  // If no params, bail out with an error.
150  // Otherwise, a rogue client could produce a segfault by supplying "requestinfo image_sums" without parameters.
151  if (params == NULL) {
152  LOG(llevError, "send_image_sums: bogus \"requestinfo image_sums\": no range provided.\n");
153  return;
154  }
155 
156  SockList_Init(&sl);
157 
158  start = atoi(params);
159  for (cp = params; *cp != '\0'; cp++)
160  if (*cp == ' ')
161  break;
162 
163  stop = atoi(cp);
164  if (stop < start
165  || *cp == '\0'
166  || (stop-start) > 1000
167  || stop >= get_faces_count()) {
168  SockList_AddPrintf(&sl, "replyinfo image_sums %d %d", start, stop);
169  Send_With_Handling(ns, &sl);
170  SockList_Term(&sl);
171  return;
172  }
173  SockList_AddPrintf(&sl, "replyinfo image_sums %d %d ", start, stop);
174 
175  for (i = start; i <= stop; i++) {
176  const Face *face = get_face_by_id(i);
177 
178  if (SockList_Avail(&sl) < 2+4+1+1+strlen(face->name)+1) {
179  LOG(llevError, "send_image_sums: buffer overflow, rejecting range %d..%d\n", start, stop);
180  SockList_Reset(&sl);
181  SockList_AddPrintf(&sl, "replyinfo image_sums %d %d", start, stop);
182  Send_With_Handling(ns, &sl);
183  SockList_Term(&sl);
184  return;
185  }
186 
187  SockList_AddShort(&sl, i);
188  ns->faces_sent[face->number] |= NS_FACESENT_FACE;
189 
191  SockList_AddInt(&sl, fs->faces[i].checksum);
192  SockList_AddChar(&sl, fs->id);
193  SockList_AddLen8Data(&sl, face->name, strlen(face->name)+1);
194  }
195  Send_With_Handling(ns, &sl);
196  SockList_Term(&sl);
197 }
Face::name
sstring name
Definition: face.h:19
facesets_for_each
void facesets_for_each(faceset_op op)
Definition: assets.cpp:327
Face
Definition: face.h:14
SockList_AddInt
void SockList_AddInt(SockList *sl, uint32_t data)
Definition: lowlevel.c:124
global.h
NS_FACESENT_FACE
#define NS_FACESENT_FACE
Definition: newserver.h:137
ugly
static SockList * ugly
Definition: image.c:107
llevError
@ llevError
Definition: logger.h:11
socket_struct
Definition: newserver.h:89
SockList_AddString
void SockList_AddString(SockList *sl, const char *data)
Definition: lowlevel.c:154
find_faceset
face_sets * find_faceset(int id)
Definition: assets.cpp:366
face_sets::id
int id
Definition: image.h:18
SockList_Reset
void SockList_Reset(SockList *sl)
Definition: lowlevel.c:71
face_sets::prefix
char * prefix
Definition: image.h:19
face_sets::extension
char * extension
Definition: image.h:23
SockList_Avail
size_t SockList_Avail(const SockList *sl)
Definition: lowlevel.c:243
get_bitmap_checksum
int get_bitmap_checksum()
Definition: assets.cpp:362
socket_struct::facecache
uint32_t facecache
Definition: newserver.h:102
Face::number
uint16_t number
Definition: face.h:15
SockList_AddShort
void SockList_AddShort(SockList *sl, uint16_t data)
Definition: lowlevel.c:113
do_faceset
static void do_faceset(const face_sets *fs)
Definition: image.c:108
SockList_AddChar
void SockList_AddChar(SockList *sl, unsigned char c)
Definition: lowlevel.c:103
face_sets::comment
char * comment
Definition: image.h:24
socket_struct::host
char * host
Definition: newserver.h:100
send_image_info
void send_image_info(socket_struct *ns)
Definition: image.c:121
face_info::data
uint8_t * data
Definition: image.h:11
socket_struct::faceset
uint8_t faceset
Definition: newserver.h:117
face_sets::size
char * size
Definition: image.h:22
sproto.h
get_face_by_id
const Face * get_face_by_id(uint16_t id)
Definition: assets.cpp:345
SockList_Init
void SockList_Init(SockList *sl)
Definition: lowlevel.c:52
image.h
face_sets::fallback
struct face_sets * fallback
Definition: image.h:21
esrv_send_face
void esrv_send_face(socket_struct *ns, const Face *face, int nocache)
Definition: image.c:71
SockList_Term
void SockList_Term(SockList *sl)
Definition: lowlevel.c:62
send_image_sums
void send_image_sums(socket_struct *ns, char *params)
Definition: image.c:142
SockList_AddData
void SockList_AddData(SockList *sl, const void *data, size_t len)
Definition: lowlevel.c:164
roll-o-matic.stop
def stop()
Definition: roll-o-matic.py:78
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
newserver.h
get_face_fallback
int get_face_fallback(int faceset, uint16_t imageno)
Definition: image.c:132
SockList_AddLen8Data
void SockList_AddLen8Data(SockList *sl, const void *data, size_t len)
Definition: lowlevel.c:176
roll-o-matic.params
params
Definition: roll-o-matic.py:193
assets.h
face_info::datalen
uint16_t datalen
Definition: image.h:12
face_info::checksum
uint32_t checksum
Definition: image.h:13
socket_struct::faces_sent
uint8_t * faces_sent
Definition: newserver.h:96
newclient.h
send_face_cmd
void send_face_cmd(char *buff, int len, socket_struct *ns)
Definition: image.c:44
face_sets::fullname
char * fullname
Definition: image.h:20
get_faces_count
size_t get_faces_count()
Definition: assets.cpp:319
face_sets
Definition: image.h:17
Send_With_Handling
void Send_With_Handling(socket_struct *ns, SockList *sl)
Definition: lowlevel.c:440
face_sets::faces
face_info * faces
Definition: image.h:26
SockList
Definition: newclient.h:681
llevDebug
@ llevDebug
Definition: logger.h:13
SockList_AddPrintf
void SockList_AddPrintf(SockList *sl, const char *format,...)
Definition: lowlevel.c:199