Atrinik Server  4.0
image.c
Go to the documentation of this file.
1 /*************************************************************************
2  * Atrinik, a Multiplayer Online Role Playing Game *
3  * *
4  * Copyright (C) 2009-2014 Alex Tokar and Atrinik Development Team *
5  * *
6  * Fork from Crossfire (Multiplayer game for X-windows). *
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, write to the Free Software *
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
21  * *
22  * The author can be reached at admin@atrinik.org *
23  ************************************************************************/
24 
30 #include <global.h>
31 #include <loader.h>
32 #include <toolkit/packet.h>
33 #include <toolkit/string.h>
34 #include "zlib.h"
35 
37 #define MAX_FACE_SETS 1
38 
40 typedef struct FaceInfo {
42  uint8_t *data;
43 
45  uint16_t datalen;
46 
48  uint32_t checksum;
49 } FaceInfo;
50 
52 typedef struct {
54  char *prefix;
55 
57  char *fullname;
58 
60  char *size;
61 
63  char *extension;
64 
66  char *comment;
67 
70 } FaceSets;
71 
74 
82 int is_valid_faceset(int fsn)
83 {
84  if (fsn >= 0 && fsn < MAX_FACE_SETS && facesets[fsn].prefix) {
85  return 1;
86  }
87 
88  return 0;
89 }
90 
95 {
96  int num, q;
97 
98  for (num = 0; num < MAX_FACE_SETS; num++) {
99  if (facesets[num].prefix) {
100  for (q = 0; q < nrofpixmaps; q++) {
101  if (facesets[num].faces[q].data) {
102  efree(facesets[num].faces[q].data);
103  }
104  }
105 
106  efree(facesets[num].prefix);
107  efree(facesets[num].fullname);
108  efree(facesets[num].size);
109  efree(facesets[num].extension);
110  efree(facesets[num].comment);
111  efree(facesets[num].faces);
112  }
113  }
114 }
115 
117 #define MAX_IMAGE_SIZE 50000
118 
130 {
131  char filename[400], buf[HUGE_BUF], *cp, *cps[7 + 1];
132  FILE *infile, *fbmap;
133  int num, len, file_num, i;
134 
135  memset(facesets, 0, sizeof(facesets));
136 
137  snprintf(filename, sizeof(filename), "%s/image_info", settings.libpath);
138  infile = fopen(filename, "rb");
139 
140  if (!infile) {
141  LOG(ERROR, "Unable to open %s", filename);
142  exit(1);
143  }
144 
145  while (fgets(buf, HUGE_BUF - 1, infile) != NULL) {
146  if (buf[0] == '#') {
147  continue;
148  }
149 
150  if (string_split(buf, cps, sizeof(cps) / sizeof(*cps), ':') != 7) {
151  LOG(ERROR, "Bad line in image_info file: %s", buf);
152  exit(1);
153  } else {
154  len = atoi(cps[0]);
155 
156  if (len >= MAX_FACE_SETS) {
157  LOG(ERROR, "Too high a setnum in image_info file: %d > %d", len, MAX_FACE_SETS);
158  exit(1);
159  }
160 
161  facesets[len].prefix = estrdup(cps[1]);
162  facesets[len].fullname = estrdup(cps[2]);
163  facesets[len].size = estrdup(cps[4]);
164  facesets[len].extension = estrdup(cps[5]);
165  facesets[len].comment = estrdup(cps[6]);
166  }
167  }
168 
169  fclose(infile);
170 
171  /* Loaded the faceset information - now need to load up the
172  * actual faces. */
173  for (file_num = 0; file_num < MAX_FACE_SETS; file_num++) {
174  /* If prefix is not set, this is not used */
175  if (!facesets[file_num].prefix) {
176  continue;
177  }
178 
179  facesets[file_num].faces = ecalloc(nrofpixmaps, sizeof(FaceInfo));
180 
181  snprintf(filename, sizeof(filename), "%s/atrinik.%d", settings.libpath, file_num);
182  snprintf(buf, sizeof(buf), "%s/bmaps", settings.datapath);
183 
184  if ((fbmap = fopen(buf, "wb")) == NULL) {
185  LOG(ERROR, "Unable to open %s", buf);
186  exit(1);
187  }
188 
189  infile = fopen(filename, "rb");
190 
191  if (!infile) {
192  LOG(ERROR, "Unable to open %s", filename);
193  exit(1);
194  }
195 
196  while (fgets(buf, HUGE_BUF - 1, infile) != NULL) {
197  if (strncmp(buf, "IMAGE ", 6) != 0) {
198  LOG(ERROR, "Bad image line - not IMAGE, instead: %s", buf);
199  exit(1);
200  }
201 
202  num = atoi(buf + 6);
203 
204  if (num < 0 || num >= nrofpixmaps) {
205  LOG(ERROR, "Image num %d not in 0..%d: %s", num, nrofpixmaps, buf);
206  exit(1);
207  }
208 
209  /* Skip across the number data */
210  for (cp = buf + 6; *cp != ' '; cp++) {
211  }
212 
213  len = atoi(cp);
214 
215  if (len == 0 || len > MAX_IMAGE_SIZE) {
216  LOG(ERROR, "Length not valid: %d > %d: %s", len, MAX_IMAGE_SIZE, buf);
217  exit(1);
218  }
219 
220  /* We don't actually care about the name if the image that
221  * is embedded in the image file, so just ignore it. */
222  facesets[file_num].faces[num].datalen = len;
223  facesets[file_num].faces[num].data = emalloc(len);
224 
225  if ((i = fread(facesets[file_num].faces[num].data, len, 1, infile)) != 1) {
226  LOG(ERROR, "Did not read desired amount of data, wanted %d, got %d: %s", len, i, buf);
227  exit(1);
228  }
229 
230  facesets[file_num].faces[num].checksum = (uint32_t) crc32(1L, facesets[file_num].faces[num].data, len);
231  snprintf(buf, sizeof(buf), "%x %x %s\n", len, facesets[file_num].faces[num].checksum, new_faces[num].name);
232  fputs(buf, fbmap);
233  }
234 
235  fclose(infile);
236  fclose(fbmap);
237  }
238 }
239 
240 void socket_command_ask_face(socket_struct *ns, player *pl, uint8_t *data,
241  size_t len, size_t pos)
242 {
243  uint16_t facenum;
244  packet_struct *packet;
245 
246  facenum = packet_to_uint16(data, len, &pos);
247 
248  if (facenum == 0 || facenum >= nrofpixmaps ||
249  facesets[0].faces[facenum].data == NULL) {
250  return;
251  }
252 
253  packet = packet_new(CLIENT_CMD_IMAGE, 16, 0);
254  packet_debug_data(packet, 0, "Face ID");
255  packet_append_uint32(packet, facenum);
256  packet_debug_data(packet, 0, "Face size");
257  packet_append_uint32(packet, facesets[0].faces[facenum].datalen);
258  packet_debug_data(packet, 0, "Face data");
259  packet_append_data_len(packet, facesets[0].faces[facenum].data,
260  facesets[0].faces[facenum].datalen);
261  socket_send_packet(ns, packet);
262 }
263 
272 void face_get_data(int face, uint8_t **ptr, uint16_t *len)
273 {
274  if (ptr) {
275  *ptr = facesets[0].faces[face].data;
276  }
277 
278  if (len) {
279  *len = facesets[0].faces[face].datalen;
280  }
281 }
void read_client_images(void)
Definition: image.c:129
char datapath[MAX_BUF]
Definition: global.h:343
uint32_t checksum
Definition: image.c:48
uint8_t * data
Definition: image.c:42
char * prefix
Definition: image.c:54
char libpath[MAX_BUF]
Definition: global.h:338
void free_socket_images(void)
Definition: image.c:94
char * size
Definition: image.c:60
char * fullname
Definition: image.c:57
uint16_t datalen
Definition: image.c:45
union @21 data
Data about the rule.
Definition: image.c:40
uint64_t num
Number of successful updates.
Definition: metaserver.c:43
#define MAX_IMAGE_SIZE
Definition: image.c:117
char * comment
Definition: image.c:66
struct settings_struct settings
Definition: init.c:55
FaceInfo * faces
Definition: image.c:69
#define MAX_FACE_SETS
Definition: image.c:37
void face_get_data(int face, uint8_t **ptr, uint16_t *len)
Definition: image.c:272
Definition: image.c:52
char * extension
Definition: image.c:63
static FaceSets facesets[MAX_FACE_SETS]
Definition: image.c:73
int nrofpixmaps
Definition: image.c:67
struct FaceInfo FaceInfo
int is_valid_faceset(int fsn)
Definition: image.c:82