Crossfire Client, Branch
R11627
|
00001 const char * const rcsid_common_init_c = 00002 "$Id: init.c 10973 2008-12-14 08:51:26Z ryo_saeba $"; 00003 /* 00004 Crossfire client, a client program for the crossfire program. 00005 00006 Copyright (C) 2001 Mark Wedel & Crossfire Development Team 00007 00008 This program is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 2 of the License, or 00011 (at your option) any later version. 00012 00013 This program is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with this program; if not, write to the Free Software 00020 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00021 00022 The author can be reached via e-mail to crossfire-devel@real-time.com 00023 */ 00024 00025 /* This handles the initialization of the client. This includes making 00026 * the I_IMAGE and I_ARCH commands. 00027 */ 00028 00029 #include <client.h> 00030 #include "p_cmd.h" /* init_commands() */ 00031 00032 /* XXX Does the x11 client *use* these? */ 00033 00034 /* Makes the load/save code trivial - basically, the 00035 * entries here match the same numbers as the CONFIG_ values defined 00036 * in common/client.h - this means the load and save just does 00037 * something like a fprintf(outifle, "%s: %d", config_names[i], 00038 * want_config[i]); 00039 */ 00040 const char *const config_names[CONFIG_NUMS] = { 00041 NULL, "download_all_images", "echo_bindings", 00042 "fasttcpsend", "command_window", "cacheimages", "fog_of_war", "iconscale", 00043 "mapscale", "popups", "displaymode", "showicon", "tooltips", "sound", "splitinfo", 00044 "split", "show_grid", "lighting", "trim_info_window", 00045 "map_width", "map_height", "foodbeep", "darkness", "port", 00046 "grad_color_bars", "resistances", "smoothing", "nosplash", 00047 "auto_apply_container", "mapscroll", "sign_popups", "message_timestamping" 00048 }; 00049 00050 sint16 want_config[CONFIG_NUMS], use_config[CONFIG_NUMS]; 00051 00052 #define FREE_AND_CLEAR(xyz) { free(xyz); xyz=NULL; } 00053 00054 void VersionCmd(char *data, int len) 00055 { 00056 char *cp; 00057 00058 csocket.cs_version = atoi(data); 00059 /* set sc_version in case it is an old server supplying only one version */ 00060 csocket.sc_version = csocket.cs_version; 00061 if (csocket.cs_version != VERSION_CS) { 00062 LOG(LOG_WARNING,"common::VersionCmd","Differing C->S version numbers (%d,%d)", 00063 VERSION_CS,csocket.cs_version); 00064 /* exit(1);*/ 00065 } 00066 cp = strchr(data,' '); 00067 if (!cp) return; 00068 csocket.sc_version = atoi(cp); 00069 if (csocket.sc_version != VERSION_SC) { 00070 LOG(LOG_WARNING,"common::VersionCmd","Differing S->C version numbers (%d,%d)", 00071 VERSION_SC,csocket.sc_version); 00072 } 00073 cp = strchr(cp+1, ' '); 00074 if (cp) 00075 LOG(LOG_INFO,"common::VersionCmd","Playing on server type %s", cp); 00076 } 00077 00078 void SendVersion(ClientSocket csock) 00079 { 00080 cs_print_string(csock.fd, 00081 "version %d %d %s", VERSION_CS, VERSION_SC, VERSION_INFO); 00082 } 00083 00084 00085 void SendAddMe(ClientSocket csock) 00086 { 00087 cs_print_string(csock.fd, "addme"); 00088 } 00089 00090 00091 void SendSetFaceMode(ClientSocket csock,int mode) 00092 { 00093 cs_print_string(csock.fd, "setfacemode %d", mode); 00094 } 00095 00096 00097 void init_client_vars(void) 00098 { 00099 int i; 00100 00101 /* I think environment variables should be more important than 00102 * compiled in defaults, so these probably should be reversed. 00103 */ 00104 client_libdir=getenv("CFCLIENT_LIBDIR"); 00105 #ifdef CLIENT_LIBDIR 00106 if (client_libdir==NULL) 00107 client_libdir=CLIENT_LIBDIR; 00108 #endif 00109 00110 if (exp_table) { 00111 free(exp_table); 00112 exp_table=NULL; 00113 } 00114 exp_table_max=0; 00115 00116 cpl.count_left = 0; 00117 cpl.container = NULL; 00118 memset(&cpl.stats,0, sizeof(Stats)); 00119 cpl.stats.maxsp=1; /* avoid div by 0 errors */ 00120 cpl.stats.maxhp=1; /* ditto */ 00121 cpl.stats.maxgrace=1; /* ditto */ 00122 /* ditto - displayed weapon speed is weapon speed/speed */ 00123 cpl.stats.speed=1; 00124 cpl.input_text[0]='\0'; 00125 cpl.title[0] = '\0'; 00126 cpl.range[0] = '\0'; 00127 cpl.last_command[0] = '\0'; 00128 00129 for (i=0; i<range_size; i++) 00130 cpl.ranges[i]=NULL; 00131 00132 for (i=0; i<MAX_SKILL; i++) { 00133 cpl.stats.skill_exp[i]=0; 00134 cpl.stats.skill_level[i] = 0; 00135 skill_names[i] = NULL; 00136 last_used_skills[i] = -1; 00137 } 00138 last_used_skills[MAX_SKILL] = -1; 00139 00140 cpl.ob = player_item(); 00141 cpl.below = map_item(); 00142 cpl.magicmap=NULL; 00143 cpl.showmagic=0; 00144 00145 00146 csocket.command_sent=0; 00147 csocket.command_received=0; 00148 csocket.command_time=0; 00149 00150 face_info.faceset = 0; 00151 face_info.num_images = 0; 00152 face_info.bmaps_checksum = 0; 00153 face_info.old_bmaps_checksum = 0; 00154 face_info.want_faceset = NULL; 00155 face_info.cache_hits=0; 00156 face_info.cache_misses=0; 00157 face_info.have_faceset_info=0; 00158 for (i=0; i<MAX_FACE_SETS; i++) { 00159 face_info.facesets[i].prefix = NULL; 00160 face_info.facesets[i].fullname = NULL; 00161 face_info.facesets[i].fallback = 0; 00162 face_info.facesets[i].size = NULL; 00163 face_info.facesets[i].extension = NULL; 00164 face_info.facesets[i].comment = NULL; 00165 } 00166 /* Makes just as much sense to initialize the arrays 00167 * where they are declared, but I did this so I could 00168 * keep track of everything as I was updating 00169 * the code. Plus, the performance difference is virtually 00170 * nothing. 00171 */ 00172 want_config[CONFIG_DOWNLOAD] = FALSE; 00173 want_config[CONFIG_ECHO] = FALSE; 00174 want_config[CONFIG_FASTTCP] = TRUE; 00175 want_config[CONFIG_CWINDOW] = COMMAND_WINDOW; 00176 want_config[CONFIG_CACHE] = FALSE; 00177 want_config[CONFIG_FOGWAR] = TRUE; 00178 want_config[CONFIG_ICONSCALE] = 100; 00179 want_config[CONFIG_MAPSCALE] = 100; 00180 want_config[CONFIG_POPUPS] = FALSE; 00181 want_config[CONFIG_DISPLAYMODE] = CFG_DM_PIXMAP; 00182 want_config[CONFIG_SHOWICON] = FALSE; 00183 want_config[CONFIG_TOOLTIPS] = TRUE; 00184 want_config[CONFIG_SOUND] = TRUE; 00185 want_config[CONFIG_SPLITINFO] = FALSE; 00186 want_config[CONFIG_SPLITWIN] = FALSE; 00187 want_config[CONFIG_SHOWGRID] = FALSE; 00188 want_config[CONFIG_LIGHTING] = CFG_LT_TILE; 00189 want_config[CONFIG_TRIMINFO] = FALSE; 00190 want_config[CONFIG_MAPWIDTH] = 11; 00191 want_config[CONFIG_MAPHEIGHT] = 11; 00192 want_config[CONFIG_FOODBEEP] = FALSE; 00193 want_config[CONFIG_DARKNESS] = TRUE; 00194 want_config[CONFIG_PORT] = EPORT; 00195 want_config[CONFIG_GRAD_COLOR] = FALSE; 00196 want_config[CONFIG_RESISTS] = 0; 00197 want_config[CONFIG_RESISTS] = 0; 00198 want_config[CONFIG_SMOOTH] = 0; 00199 want_config[CONFIG_SPLASH] = TRUE; 00200 want_config[CONFIG_APPLY_CONTAINER] = TRUE; /* Same behavior before this option was put in */ 00201 want_config[CONFIG_MAPSCROLL] = TRUE; 00202 want_config[CONFIG_SIGNPOPUP] = TRUE; 00203 want_config[CONFIG_TIMESTAMP] = FALSE; 00204 for (i=0; i<CONFIG_NUMS; i++) 00205 use_config[i] = want_config[i]; 00206 00207 #ifdef WIN32 00208 /* If HOME is not set, let's set it to . to avoid things like (null)/.crossfire paths */ 00209 if ( !getenv( "HOME" ) ) 00210 { 00211 if ( getenv( "APPDATA" ) ) 00212 { 00213 char env[ MAX_BUF ]; 00214 _snprintf( env, MAX_BUF, "HOME=%s", getenv( "APPDATA" ) ); 00215 LOG( LOG_INFO, "common::init.c", "init_client_vars: HOME set to %APPDATA%.\n" ); 00216 putenv( env ); 00217 } 00218 else 00219 { 00220 LOG( LOG_INFO, "common::init.c", "init_client_vars: HOME not set, setting it to .\n" ); 00221 putenv( "HOME=." ); 00222 } 00223 } 00224 #endif 00225 init_commands(); /* pcmd.c */ 00226 init_metaserver(); /* metaserver.c */ 00227 /* Any reasonable seed really works */ 00228 srandom(time(NULL)); 00229 } 00230 00231 /* This is basically called each time a new player logs 00232 * on - reset all the player data 00233 */ 00234 void reset_player_data(void) 00235 { 00236 int i; 00237 00238 for (i=0; i<MAX_SKILL; i++) { 00239 cpl.stats.skill_exp[i]=0; 00240 cpl.stats.skill_level[i] = 0; 00241 } 00242 } 00243 00244 /* This is used to clear values between connections to different 00245 * servers. This needs to be called after init_client_vars has 00246 * been called because it does not re-allocated some values. 00247 */ 00248 00249 void reset_client_vars(void) 00250 { 00251 int i; 00252 00253 cpl.count_left = 0; 00254 cpl.container = NULL; 00255 memset(&cpl.stats,0, sizeof(Stats)); 00256 cpl.stats.maxsp=1; /* avoid div by 0 errors */ 00257 cpl.stats.maxhp=1; /* ditto */ 00258 cpl.stats.maxgrace=1; /* ditto */ 00259 /* ditto - displayed weapon speed is weapon speed/speed */ 00260 cpl.stats.speed=1; 00261 cpl.input_text[0]='\0'; 00262 cpl.title[0] = '\0'; 00263 cpl.range[0] = '\0'; 00264 cpl.last_command[0] = '\0'; 00265 00266 for (i=0; i<range_size; i++) 00267 cpl.ranges[i]=NULL; 00268 00269 cpl.magicmap=NULL; 00270 cpl.showmagic=0; 00271 00272 csocket.command_sent=0; 00273 csocket.command_received=0; 00274 csocket.command_time=0; 00275 00276 face_info.faceset = 0; 00277 face_info.num_images = 0; 00278 /* Preserve the old one - this can be used to see if the next 00279 * server has the same name -> number mapping so that we don't 00280 * need to rebuild all the images. 00281 */ 00282 face_info.old_bmaps_checksum = face_info.bmaps_checksum; 00283 face_info.bmaps_checksum = 0; 00284 face_info.cache_hits=0; 00285 face_info.cache_misses=0; 00286 face_info.have_faceset_info=0; 00287 for (i=0; i<MAX_FACE_SETS; i++) { 00288 FREE_AND_CLEAR(face_info.facesets[i].prefix); 00289 FREE_AND_CLEAR(face_info.facesets[i].fullname); 00290 face_info.facesets[i].fallback = 0; 00291 FREE_AND_CLEAR(face_info.facesets[i].size); 00292 FREE_AND_CLEAR(face_info.facesets[i].extension); 00293 FREE_AND_CLEAR(face_info.facesets[i].comment); 00294 } 00295 reset_player_data(); 00296 for (i=0; i<MAX_SKILL; i++) 00297 FREE_AND_CLEAR(skill_names[i]); 00298 00299 }