Crossfire Server, Trunk  1.75.0
image.cpp
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 #include "AssetsManager.h"
36 
45 void send_face_cmd(char *buff, int len, socket_struct *ns) {
46  long tmpnum;
47  uint16_t faceid;
48 
49  if (len <= 0 || !buff) {
50  LOG(llevDebug, "IP '%s' sent bogus send_face_cmd information\n", ns->host);
51  return;
52  }
53 
54  tmpnum = atoi(buff);
55  faceid = tmpnum&0xffff;
56 
57  if (faceid != 0)
58  esrv_send_face(ns, get_face_by_id(faceid), 1);
59 }
60 
72 void esrv_send_face(socket_struct *ns, const Face *face, int nocache) {
73  SockList sl;
74 
75  if (face == NULL) {
76  LOG(llevError, "esrv_send_face NULL??\n");
77  return;
78  }
79 
80  SockList_Init(&sl);
82 
83  if (!fs || fs->faces[face->number].data == NULL) {
84  LOG(llevError, "esrv_send_face: faces[%d].data == NULL\n", face->number);
85  return;
86  }
87 
88  if (ns->facecache && !nocache) {
89  SockList_AddString(&sl, "face2 ");
90  SockList_AddShort(&sl, face->number);
91  SockList_AddChar(&sl, fs->id);
92  SockList_AddInt(&sl, fs->faces[face->number].checksum);
94  Send_With_Handling(ns, &sl);
95  } else {
96  SockList_AddString(&sl, "image2 ");
97  SockList_AddInt(&sl, face->number);
98  SockList_AddChar(&sl, fs->id);
99  SockList_AddInt(&sl, fs->faces[face->number].datalen);
100  SockList_AddData(&sl, fs->faces[face->number].data, fs->faces[face->number].datalen);
101  Send_With_Handling(ns, &sl);
102  }
103  ns->faces_sent[face->number] |= NS_FACESENT_FACE;
104  SockList_Term(&sl);
105 }
106 
114  SockList sl;
115 
116  SockList_Init(&sl);
117 
118  SockList_AddPrintf(&sl, "replyinfo image_info\n%d\n%d\n", get_faces_count()-1, getManager()->faces()->checksum());
119  getManager()->facesets()->each([&sl] (const face_sets *fs) {
120  SockList_AddPrintf(&sl, "%d:%s:%s:%d:%s:%s:%s\n",
121  fs->id, fs->prefix, fs->fullname,
122  fs->fallback ? fs->fallback->id : 0, fs->size,
123  fs->extension, fs->comment);
124  });
125  Send_With_Handling(ns, &sl);
126  SockList_Term(&sl);
127 }
128 
138 void send_image_sums(socket_struct *ns, char *params) {
139  unsigned int start, stop;
140  unsigned short i;
141  char *cp;
142  SockList sl;
143 
144  // Sanity check:
145  // If no params, bail out with an error.
146  // Otherwise, a rogue client could produce a segfault by supplying "requestinfo image_sums" without parameters.
147  if (params == NULL) {
148  LOG(llevError, "send_image_sums: bogus \"requestinfo image_sums\": no range provided.\n");
149  return;
150  }
151 
152  SockList_Init(&sl);
153 
154  start = atoi(params);
155  for (cp = params; *cp != '\0'; cp++)
156  if (*cp == ' ')
157  break;
158 
159  stop = atoi(cp);
160  if (stop < start
161  || *cp == '\0'
162  || (stop-start) > 1000
163  || stop >= get_faces_count()) {
164  SockList_AddPrintf(&sl, "replyinfo image_sums %d %d", start, stop);
165  Send_With_Handling(ns, &sl);
166  SockList_Term(&sl);
167  return;
168  }
169  SockList_AddPrintf(&sl, "replyinfo image_sums %d %d ", start, stop);
170 
171  for (i = start; i <= stop; i++) {
172  const Face *face = get_face_by_id(i);
173 
174  if (SockList_Avail(&sl) < 2+4+1+1+strlen(face->name)+1) {
175  LOG(llevError, "send_image_sums: buffer overflow, rejecting range %d..%d\n", start, stop);
176  SockList_Reset(&sl);
177  SockList_AddPrintf(&sl, "replyinfo image_sums %d %d", start, stop);
178  Send_With_Handling(ns, &sl);
179  SockList_Term(&sl);
180  return;
181  }
182 
183  SockList_AddShort(&sl, i);
184  ns->faces_sent[face->number] |= NS_FACESENT_FACE;
185 
187  SockList_AddInt(&sl, fs->faces[i].checksum);
188  SockList_AddChar(&sl, fs->id);
189  SockList_AddLen8Data(&sl, face->name, strlen(face->name)+1);
190  }
191  Send_With_Handling(ns, &sl);
192  SockList_Term(&sl);
193 }
Face
New face structure - this enforces the notion that data is face by face only - you can not change the...
Definition: face.h:14
SockList_AddInt
void SockList_AddInt(SockList *sl, uint32_t data)
Adds a 32 bit value.
Definition: lowlevel.cpp:127
global.h
NS_FACESENT_FACE
#define NS_FACESENT_FACE
Bitmask for the faces_sent[] array - what portion of the face have we sent?
Definition: newserver.h:141
llevError
@ llevError
Error, serious thing.
Definition: logger.h:11
LOG
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.cpp:58
AssetsManager.h
socket_struct
Socket structure, represents a client-server connection.
Definition: newserver.h:93
get_face_fallback
int get_face_fallback(int faceset, uint16_t imageno)
This returns the set we will actually use when sending a face.
Definition: image.cpp:133
SockList_AddString
void SockList_AddString(SockList *sl, const char *data)
Adds a string without length.
Definition: lowlevel.cpp:157
esrv_send_face
void esrv_send_face(socket_struct *ns, const Face *face, int nocache)
Sends a face to a client if they are in pixmap mode, nothing gets sent in bitmap mode.
Definition: image.cpp:72
find_faceset
face_sets * find_faceset(int id)
Definition: assets.cpp:328
checksum
static unsigned checksum(const mtar_raw_header_t *rh)
Definition: microtar.cpp:49
face_sets::id
int id
Definition: image.h:18
SockList_Reset
void SockList_Reset(SockList *sl)
Resets the length of the stored data for writing.
Definition: lowlevel.cpp:74
getManager
AssetsManager * getManager()
Definition: assets.cpp:305
face_sets::prefix
char * prefix
Faceset short name, used in pictures names (base, clsc).
Definition: image.h:19
send_face_cmd
void send_face_cmd(char *buff, int len, socket_struct *ns)
Client has requested pixmap that it somehow missed getting.
Definition: image.cpp:45
face_sets::extension
char * extension
Supplementary description.
Definition: image.h:23
SockList_Avail
size_t SockList_Avail(const SockList *sl)
Returns the available bytes in a SockList instance.
Definition: lowlevel.cpp:246
socket_struct::facecache
uint32_t facecache
If true, client is caching images.
Definition: newserver.h:106
treasurelist::name
sstring name
Usually monster-name/combination.
Definition: treasure.h:86
SockList_AddShort
void SockList_AddShort(SockList *sl, uint16_t data)
Adds a 16 bit value.
Definition: lowlevel.cpp:116
SockList_AddChar
void SockList_AddChar(SockList *sl, unsigned char c)
Adds an 8 bit value.
Definition: lowlevel.cpp:106
face_sets::comment
char * comment
Human-readable comment for this set.
Definition: image.h:24
socket_struct::host
char * host
Which host it is connected from (ip address).
Definition: newserver.h:104
face_info::data
uint8_t * data
Image data.
Definition: image.h:11
socket_struct::faceset
uint8_t faceset
Set the client is using, default 0.
Definition: newserver.h:121
face_sets::size
char * size
Human-readable set size.
Definition: image.h:22
sproto.h
AssetsCollection::each
void each(std::function< void(T *)> op)
Apply a function to each asset.
Definition: AssetsCollection.h:158
get_face_by_id
const Face * get_face_by_id(uint16_t id)
Get a face from its unique identifier.
Definition: assets.cpp:315
AssetsManager::facesets
Facesets * facesets()
Get facesets.
Definition: AssetsManager.h:65
SockList_Init
void SockList_Init(SockList *sl)
Initializes the SockList instance.
Definition: lowlevel.cpp:55
image.h
face_sets::fallback
struct face_sets * fallback
Faceset to use when an image is not found in this faceset.
Definition: image.h:21
send_image_info
void send_image_info(socket_struct *ns)
Sends the number of images, checksum of the face file, and the image_info file information.
Definition: image.cpp:113
SockList_Term
void SockList_Term(SockList *sl)
Frees all resources allocated by a SockList instance.
Definition: lowlevel.cpp:65
send_image_sums
void send_image_sums(socket_struct *ns, char *params)
Sends requested face information.
Definition: image.cpp:138
SockList_AddData
void SockList_AddData(SockList *sl, const void *data, size_t len)
Adds a data block.
Definition: lowlevel.cpp:167
newserver.h
SockList_AddLen8Data
void SockList_AddLen8Data(SockList *sl, const void *data, size_t len)
Adds a data block prepended with an 8 bit length field.
Definition: lowlevel.cpp:179
assets.h
face_info::datalen
uint16_t datalen
Length of data.
Definition: image.h:12
face_info::checksum
uint32_t checksum
Checksum of face data.
Definition: image.h:13
socket_struct::faces_sent
uint8_t * faces_sent
This is a bitmap on sent face status.
Definition: newserver.h:100
newclient.h
face_sets::fullname
char * fullname
Full faceset name.
Definition: image.h:20
get_faces_count
size_t get_faces_count()
Definition: assets.cpp:293
face_sets
Information about one face set.
Definition: image.h:17
Send_With_Handling
void Send_With_Handling(socket_struct *ns, SockList *sl)
Calls Write_To_Socket to send data to the client.
Definition: lowlevel.cpp:447
face_sets::faces
face_info * faces
images in this faceset
Definition: image.h:26
SockList
Contains the base information we use to make up a packet we want to send.
Definition: newclient.h:685
llevDebug
@ llevDebug
Only for debugging purposes.
Definition: logger.h:13
SockList_AddPrintf
void SockList_AddPrintf(SockList *sl, const char *format,...)
Adds a printf like formatted string.
Definition: lowlevel.cpp:202
face
in that case they will be relative to whatever the PWD of the crossfire server process is You probably shouldn though Notes on Specific and settings file datadir Usually usr share crossfire Contains data that the server does not need to modify while such as the etc A default install will pack the and treasurelist definitions into a single or trs file and the graphics into a face(metadata) and .tar(bitmaps) file