|
Atrinik Client 2.5
|
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 00033 static const char *const server_file_names[SERVER_FILES_MAX] = 00034 { 00035 NULL, NULL, NULL, NULL, "bmaps", 00036 "hfiles", "updates", "spells", "settings", 00037 "anims", "effects", "skills" 00038 }; 00039 00041 static const char *const server_file_setup_names[SERVER_FILES_MAX] = 00042 { 00043 NULL, NULL, NULL, NULL, "bpf", 00044 "hpf", "upf", "spfv2", "ssf", 00045 "amfv2", "eff", "skfv2" 00046 }; 00047 00049 static void (*server_file_funcs[SERVER_FILES_MAX])() = 00050 { 00051 NULL, NULL, NULL, NULL, read_bmaps, 00052 read_help_files, file_updates_parse, spells_init, server_settings_init, 00053 read_anims, effects_init, skills_init 00054 }; 00055 00057 static void (*server_file_funcs_reload[SERVER_FILES_MAX])() = 00058 { 00059 NULL, NULL, NULL, NULL, NULL, 00060 NULL, NULL, spells_reload, NULL, 00061 anims_reset, effects_reinit, skills_reload 00062 }; 00063 00065 static server_files_struct server_files[SERVER_FILES_MAX]; 00066 00069 void server_files_init() 00070 { 00071 memset(&server_files, 0, sizeof(server_files)); 00072 } 00073 00078 void server_files_load(int post_load) 00079 { 00080 size_t i; 00081 FILE *fp; 00082 struct stat sb; 00083 size_t st_size, numread; 00084 char *contents; 00085 00086 for (i = 0; i < SERVER_FILES_MAX; i++) 00087 { 00088 /* Invalid server file. */ 00089 if (!server_file_names[i]) 00090 { 00091 continue; 00092 } 00093 00094 /* Server file was loaded previously. */ 00095 if (post_load && server_files[i].loaded) 00096 { 00097 if (server_file_funcs_reload[i]) 00098 { 00099 server_file_funcs_reload[i](); 00100 } 00101 00102 continue; 00103 } 00104 00105 /* Open the file. */ 00106 fp = server_file_open(i); 00107 00108 if (!fp) 00109 { 00110 return; 00111 } 00112 00113 /* Get and store the size. */ 00114 fstat(fileno(fp), &sb); 00115 st_size = sb.st_size; 00116 server_files[i].size = st_size; 00117 00118 /* Allocate temporary buffer and read into it the file. */ 00119 contents = malloc(st_size); 00120 numread = fread(contents, 1, st_size, fp); 00121 00122 /* Calculate and store the checksum, free the temporary buffer 00123 * and close the file pointer. */ 00124 server_files[i].crc32 = crc32(1L, (const unsigned char FAR *) contents, numread); 00125 free(contents); 00126 fclose(fp); 00127 00128 if (post_load) 00129 { 00130 /* Mark that we have loaded this file. */ 00131 server_files[i].loaded = 1; 00132 00133 if (server_file_funcs[i]) 00134 { 00135 server_file_funcs[i](); 00136 } 00137 } 00138 } 00139 } 00140 00147 static char *server_file_path(size_t id, char *buf, size_t buf_size) 00148 { 00149 snprintf(buf, buf_size, "srv_files/%s", server_file_names[id]); 00150 return buf; 00151 } 00152 00157 FILE *server_file_open(size_t id) 00158 { 00159 char buf[MAX_BUF]; 00160 00161 /* Doesn't exist. */ 00162 if (!server_file_names[id]) 00163 { 00164 return NULL; 00165 } 00166 00167 server_file_path(id, buf, sizeof(buf)); 00168 return fopen_wrapper(buf, "rb"); 00169 } 00170 00176 void server_file_save(size_t id, unsigned char *data, size_t len) 00177 { 00178 char path[MAX_BUF]; 00179 FILE *fp; 00180 00181 /* Finished updating. */ 00182 server_files[id].update = 0; 00183 00184 server_file_path(id, path, sizeof(path)); 00185 fp = fopen_wrapper(path, "wb"); 00186 00187 if (!fp) 00188 { 00189 LOG(llevBug, "server_file_save(): Can't open %s for writing.\n", path); 00190 return; 00191 } 00192 00193 if (fwrite(data, 1, len, fp) != len) 00194 { 00195 LOG(llevBug, "server_file_save(): Failed to write to %s.\n", path); 00196 } 00197 else 00198 { 00199 /* Mark the server file for reload. */ 00200 server_files[id].loaded = 0; 00201 } 00202 00203 fclose(fp); 00204 } 00205 00209 int server_files_updating() 00210 { 00211 size_t i; 00212 00213 /* Check all files. */ 00214 for (i = 0; i < SERVER_FILES_MAX; i++) 00215 { 00216 /* The server file was marked for update previously, so start 00217 * updating. */ 00218 if (server_files[i].update == 1) 00219 { 00220 char buf[MAX_BUF]; 00221 00222 snprintf(buf, sizeof(buf), "rf %"FMT64U, (uint64) i); 00223 cs_write_string(buf, strlen(buf)); 00224 /* Mark the file as 'being updated'. */ 00225 server_files[i].update = -1; 00226 return 1; 00227 } 00228 /* The file is being updated. */ 00229 else if (server_files[i].update == -1) 00230 { 00231 return 1; 00232 } 00233 } 00234 00235 return 0; 00236 } 00237 00243 void server_files_setup_add(char *buf, size_t buf_size) 00244 { 00245 size_t i; 00246 char tmp[MAX_BUF]; 00247 00248 /* Load up the files. */ 00249 server_files_load(0); 00250 00251 for (i = 0; i < SERVER_FILES_MAX; i++) 00252 { 00253 /* Invalid file. */ 00254 if (!server_file_setup_names[i]) 00255 { 00256 continue; 00257 } 00258 00259 /* Add the server file identifier, its size and the checksum. */ 00260 snprintf(tmp, sizeof(tmp), " %s %"FMT64U"|%lx", server_file_setup_names[i], (uint64) server_files[i].size, server_files[i].crc32); 00261 strncat(buf, tmp, buf_size - strlen(buf) - 1); 00262 } 00263 } 00264 00270 int server_files_parse_setup(const char *cmd, const char *param) 00271 { 00272 size_t i; 00273 00274 for (i = 0; i < SERVER_FILES_MAX; i++) 00275 { 00276 /* Invalid file. */ 00277 if (!server_file_setup_names[i]) 00278 { 00279 continue; 00280 } 00281 00282 /* Check if the command matches one of the names. */ 00283 if (!strcmp(server_file_setup_names[i], cmd)) 00284 { 00285 /* If the response is not 'OK', it's different, so mark for 00286 * update. */ 00287 if (strcmp(param, "OK")) 00288 { 00289 server_files[i].update = 1; 00290 } 00291 00292 return 1; 00293 } 00294 } 00295 00296 return 0; 00297 } 00298 00301 void server_files_clear_update() 00302 { 00303 size_t i; 00304 00305 for (i = 0; i < SERVER_FILES_MAX; i++) 00306 { 00307 /* Invalid file. */ 00308 if (!server_file_setup_names[i]) 00309 { 00310 continue; 00311 } 00312 00313 server_files[i].update = 0; 00314 } 00315 }
1.7.4