Atrinik Server 2.5
socket/image.c
Go to the documentation of this file.
00001 /************************************************************************
00002 *            Atrinik, a Multiplayer Online Role Playing Game            *
00003 *                                                                       *
00004 *    Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team    *
00005 *                                                                       *
00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game)     *
00007 * and Crossfire (Multiplayer game for X-windows).                       *
00008 *                                                                       *
00009 * This program is free software; you can redistribute it and/or modify  *
00010 * it under the terms of the GNU General Public License as published by  *
00011 * the Free Software Foundation; either version 2 of the License, or     *
00012 * (at your option) any later version.                                   *
00013 *                                                                       *
00014 * This program is distributed in the hope that it will be useful,       *
00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00017 * GNU General Public License for more details.                          *
00018 *                                                                       *
00019 * You should have received a copy of the GNU General Public License     *
00020 * along with this program; if not, write to the Free Software           *
00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.             *
00022 *                                                                       *
00023 * The author can be reached at admin@atrinik.org                        *
00024 ************************************************************************/
00025 
00030 #include <global.h>
00031 #include <loader.h>
00032 #include "zlib.h"
00033 
00035 #define MAX_FACE_SETS   1
00036 
00038 typedef struct FaceInfo
00039 {
00041     uint8 *data;
00042 
00044     uint16 datalen;
00045 
00047     uint32 checksum;
00048 } FaceInfo;
00049 
00051 typedef struct
00052 {
00054     char *prefix;
00055 
00057     char *fullname;
00058 
00060     char *size;
00061 
00063     char *extension;
00064 
00066     char *comment;
00067 
00069     FaceInfo *faces;
00070 } FaceSets;
00071 
00073 static FaceSets facesets[MAX_FACE_SETS];
00074 
00079 int is_valid_faceset(int fsn)
00080 {
00081     if (fsn >= 0 && fsn < MAX_FACE_SETS && facesets[fsn].prefix)
00082     {
00083         return 1;
00084     }
00085 
00086     return 0;
00087 }
00088 
00091 void free_socket_images()
00092 {
00093     int num, q;
00094 
00095     for (num = 0; num < MAX_FACE_SETS; num++)
00096     {
00097         if (facesets[num].prefix)
00098         {
00099             for (q = 0; q < nrofpixmaps; q++)
00100             {
00101                 if (facesets[num].faces[q].data)
00102                 {
00103                     free(facesets[num].faces[q].data);
00104                 }
00105             }
00106 
00107             free(facesets[num].prefix);
00108             free(facesets[num].fullname);
00109             free(facesets[num].size);
00110             free(facesets[num].extension);
00111             free(facesets[num].comment);
00112             free(facesets[num].faces);
00113         }
00114     }
00115 }
00116 
00118 #define MAX_IMAGE_SIZE 50000
00119 
00129 void read_client_images()
00130 {
00131     char filename[400], buf[HUGE_BUF], *cp, *cps[7 + 1];
00132     FILE *infile, *fbmap;
00133     int num, len, compressed, file_num, i;
00134 
00135     memset(facesets, 0, sizeof(facesets));
00136 
00137     snprintf(filename, sizeof(filename), "%s/image_info", settings.datadir);
00138 
00139     if ((infile = open_and_uncompress(filename, 0, &compressed)) == NULL)
00140     {
00141         LOG(llevError, "read_client_images(): Unable to open %s\n", filename);
00142     }
00143 
00144     while (fgets(buf, HUGE_BUF - 1, infile) != NULL)
00145     {
00146         if (buf[0] == '#')
00147         {
00148             continue;
00149         }
00150 
00151         if (split_string(buf, cps, sizeof(cps) / sizeof(*cps), ':') != 7)
00152         {
00153             LOG(llevBug, "read_client_images(): Bad line in image_info file, ignoring line:\n  %s", buf);
00154         }
00155         else
00156         {
00157             len = atoi(cps[0]);
00158 
00159             if (len >= MAX_FACE_SETS)
00160             {
00161                 LOG(llevError, "read_client_images(): Too high a setnum in image_info file: %d > %d\n", len, MAX_FACE_SETS);
00162             }
00163 
00164             facesets[len].prefix = strdup_local(cps[1]);
00165             facesets[len].fullname = strdup_local(cps[2]);
00166             facesets[len].size = strdup_local(cps[4]);
00167             facesets[len].extension = strdup_local(cps[5]);
00168             facesets[len].comment = strdup_local(cps[6]);
00169         }
00170     }
00171 
00172     close_and_delete(infile, compressed);
00173 
00174     /* Loaded the faceset information - now need to load up the
00175      * actual faces. */
00176     for (file_num = 0; file_num < MAX_FACE_SETS; file_num++)
00177     {
00178         /* If prefix is not set, this is not used */
00179         if (!facesets[file_num].prefix)
00180         {
00181             continue;
00182         }
00183 
00184         facesets[file_num].faces = calloc(nrofpixmaps, sizeof(FaceInfo));
00185 
00186         snprintf(filename, sizeof(filename), "%s/atrinik.%d", settings.datadir, file_num);
00187         LOG(llevDebug, "Loading image file %s\n", filename);
00188 
00189         /* We don't use more than one face set here! */
00190         LOG(llevDebug, "Creating client_bmap....\n");
00191         snprintf(buf, sizeof(buf), "%s/client_bmaps", settings.localdir);
00192 
00193         if ((fbmap = fopen(buf, "wb")) == NULL)
00194         {
00195             LOG(llevError, "read_client_images(): Unable to open %s\n", buf);
00196         }
00197 
00198         if ((infile = open_and_uncompress(filename, 0, &compressed)) == NULL)
00199         {
00200             LOG(llevError, "read_client_images(): Unable to open %s\n", filename);
00201         }
00202 
00203         while (fgets(buf, HUGE_BUF - 1, infile) != NULL)
00204         {
00205             if (strncmp(buf, "IMAGE ", 6) != 0)
00206             {
00207                 LOG(llevError, "read_client_images(): Bad image line - not IMAGE, instead\n%s", buf);
00208             }
00209 
00210             num = atoi(buf + 6);
00211 
00212             if (num < 0 || num >= nrofpixmaps)
00213             {
00214                 LOG(llevError, "read_client_images(): Image num %d not in 0..%d\n%s", num, nrofpixmaps, buf);
00215             }
00216 
00217             /* Skip across the number data */
00218             for (cp = buf + 6; *cp != ' '; cp++)
00219             {
00220             }
00221 
00222             len = atoi(cp);
00223 
00224             if (len == 0 || len > MAX_IMAGE_SIZE)
00225             {
00226                 LOG(llevError, "read_client_images(): Length not valid: %d > %d \n%s", len, MAX_IMAGE_SIZE, buf);
00227             }
00228 
00229             /* We don't actually care about the name if the image that
00230              * is embedded in the image file, so just ignore it. */
00231             facesets[file_num].faces[num].datalen = len;
00232             facesets[file_num].faces[num].data = malloc(len);
00233 
00234             if ((i = fread(facesets[file_num].faces[num].data, len, 1, infile)) != 1)
00235             {
00236                 LOG(llevError, "read_client_images(): Did not read desired amount of data, wanted %d, got %d\n%s", len, i, buf);
00237             }
00238 
00239             facesets[file_num].faces[num].checksum = (uint32) crc32(1L, facesets[file_num].faces[num].data, len);
00240             snprintf(buf, sizeof(buf), "%x %x %s\n", len, facesets[file_num].faces[num].checksum, new_faces[num].name);
00241             fputs(buf, fbmap);
00242         }
00243 
00244         close_and_delete(infile, compressed);
00245         fclose(fbmap);
00246     }
00247 }
00248 
00254 void SendFaceCmd(char *buf, int len, socket_struct *ns)
00255 {
00256     long tmpnum;
00257     short facenum;
00258 
00259     if (!buf || !len)
00260     {
00261         return;
00262     }
00263 
00264     tmpnum = atoi(buf);
00265     facenum = tmpnum & 0xffff;
00266 
00267     if (facenum != 0)
00268     {
00269         esrv_send_face(ns, facenum);
00270     }
00271 }
00272 
00278 int esrv_send_face(socket_struct *ns, short face_num)
00279 {
00280     SockList sl;
00281 
00282     if (face_num < 0 || face_num >= nrofpixmaps)
00283     {
00284         LOG(llevBug, "esrv_send_face(): Face %d out of bounds!\n", face_num);
00285         return SEND_FACE_OUT_OF_BOUNDS;
00286     }
00287 
00288     if (facesets[0].faces[face_num].data == NULL)
00289     {
00290         LOG(llevBug, "esrv_send_face(): faces[%d].data == NULL\n", face_num);
00291         return SEND_FACE_NO_DATA;
00292     }
00293 
00294     /* 1 byte for the command ID, 4 bytes for the face ID, 4 bytes for
00295      * length of the face data. */
00296     sl.buf = malloc(1 + 4 + 4 + facesets[0].faces[face_num].datalen);
00297 
00298     SOCKET_SET_BINARY_CMD(&sl, BINARY_CMD_IMAGE);
00299     SockList_AddInt(&sl, face_num);
00300     SockList_AddInt(&sl, facesets[0].faces[face_num].datalen);
00301     memcpy(sl.buf + sl.len, facesets[0].faces[face_num].data, facesets[0].faces[face_num].datalen);
00302     sl.len += facesets[0].faces[face_num].datalen;
00303     Send_With_Handling(ns, &sl);
00304     free(sl.buf);
00305 
00306     return SEND_FACE_OK;
00307 }
00308 
00315 void face_get_data(int face, uint8 **ptr, uint16 *len)
00316 {
00317     if (ptr)
00318     {
00319         *ptr = facesets[0].faces[face].data;
00320     }
00321 
00322     if (len)
00323     {
00324         *len = facesets[0].faces[face].datalen;
00325     }
00326 }