1 | /* |
1 | /* |
2 | * static char *rcsid_login_c = |
2 | * static char *rcsid_login_c = |
3 | * "$Id: login.C,v 1.1 2006/08/13 17:16:04 elmex Exp $"; |
3 | * "$Id: login.C,v 1.11 2006/09/03 22:45:57 root Exp $"; |
4 | */ |
4 | */ |
5 | |
5 | |
6 | /* |
6 | /* |
7 | CrossFire, A Multiplayer game for X-windows |
7 | CrossFire, A Multiplayer game for X-windows |
8 | |
8 | |
… | |
… | |
59 | /* If we are not exiting the game (ie, this is sort of a backup save), then |
59 | /* If we are not exiting the game (ie, this is sort of a backup save), then |
60 | * don't change the location back to the village. Note that there are other |
60 | * don't change the location back to the village. Note that there are other |
61 | * options to have backup saves be done at the starting village |
61 | * options to have backup saves be done at the starting village |
62 | */ |
62 | */ |
63 | if (!flag) { |
63 | if (!flag) { |
64 | strcpy(pl->maplevel, first_map_path); |
64 | strcpy(pl->maplevel, first_map_path); |
65 | if(pl->ob->map!=NULL) |
65 | if(pl->ob->map!=NULL) |
66 | pl->ob->map = NULL; |
66 | pl->ob->map = NULL; |
67 | pl->ob->x = -1; |
67 | pl->ob->x = -1; |
68 | pl->ob->y = -1; |
68 | pl->ob->y = -1; |
69 | } |
69 | } |
70 | if(!save_player(pl->ob,flag)) { |
70 | if(!save_player(pl->ob,flag)) { |
71 | LOG(llevError, "(failed) "); |
71 | LOG(llevError, "(failed) "); |
72 | new_draw_info(NDI_UNIQUE, 0,pl->ob,"Emergency save failed, checking score..."); |
72 | new_draw_info(NDI_UNIQUE, 0,pl->ob,"Emergency save failed, checking score..."); |
73 | } |
73 | } |
… | |
… | |
93 | void delete_character(const char *name, int newchar) { |
93 | void delete_character(const char *name, int newchar) { |
94 | char buf[MAX_BUF]; |
94 | char buf[MAX_BUF]; |
95 | |
95 | |
96 | sprintf(buf,"%s/%s/%s.pl",settings.localdir,settings.playerdir,name); |
96 | sprintf(buf,"%s/%s/%s.pl",settings.localdir,settings.playerdir,name); |
97 | if(unlink(buf)== -1) |
97 | if(unlink(buf)== -1) |
98 | LOG(llevDebug, "Cannot delete character file %s: %s\n", buf, strerror_local(errno)); |
98 | LOG(llevDebug, "Cannot delete character file %s: %s\n", buf, strerror(errno)); |
99 | if (newchar) { |
99 | if (newchar) { |
100 | sprintf(buf,"%s/%s/%s",settings.localdir,settings.playerdir,name); |
100 | sprintf(buf,"%s/%s/%s",settings.localdir,settings.playerdir,name); |
101 | /* this effectively does an rm -rf on the directory */ |
101 | /* this effectively does an rm -rf on the directory */ |
102 | remove_directory(buf); |
102 | remove_directory(buf); |
103 | } |
103 | } |
104 | } |
104 | } |
105 | |
105 | |
106 | /* This verify that a character of name exits, and that it matches |
106 | /* This verify that a character of name exits, and that it matches |
107 | * password. It return 0 if there is match, 1 if no such player, |
107 | * password. It return 0 if there is match, 1 if no such player, |
… | |
… | |
113 | char buf[MAX_BUF]; |
113 | char buf[MAX_BUF]; |
114 | int comp; |
114 | int comp; |
115 | FILE *fp; |
115 | FILE *fp; |
116 | |
116 | |
117 | if (strpbrk(name, "/.\\") != NULL) { |
117 | if (strpbrk(name, "/.\\") != NULL) { |
118 | LOG(llevError, "Username contains illegal characters: %s\n", name); |
118 | LOG(llevError, "Username contains illegal characters: %s\n", name); |
119 | return 1; |
119 | return 1; |
120 | } |
120 | } |
121 | |
121 | |
122 | snprintf(buf, sizeof(buf), "%s/%s/%s/%s.pl", settings.localdir, settings.playerdir, name, name); |
122 | snprintf(buf, sizeof(buf), "%s/%s/%s/%s.pl", settings.localdir, settings.playerdir, name, name); |
123 | if (strlen(buf) >= sizeof(buf)-1) { |
123 | if (strlen(buf) >= sizeof(buf)-1) { |
124 | LOG(llevError, "Username too long: %s\n", name); |
124 | LOG(llevError, "Username too long: %s\n", name); |
125 | return 1; |
125 | return 1; |
126 | } |
126 | } |
127 | |
127 | |
128 | if ((fp=open_and_uncompress(buf,0,&comp))==NULL) return 1; |
128 | if ((fp=open_and_uncompress(buf,0,&comp))==NULL) return 1; |
129 | |
129 | |
130 | /* Read in the file until we find the password line. Our logic could |
130 | /* Read in the file until we find the password line. Our logic could |
131 | * be a bit better on cleaning up the password from the file, but since |
131 | * be a bit better on cleaning up the password from the file, but since |
132 | * it is written by the program, I think it is fair to assume that the |
132 | * it is written by the program, I think it is fair to assume that the |
133 | * syntax should be pretty standard. |
133 | * syntax should be pretty standard. |
134 | */ |
134 | */ |
135 | while (fgets(buf, MAX_BUF-1, fp) != NULL) { |
135 | while (fgets(buf, MAX_BUF-1, fp) != NULL) { |
136 | if (!strncmp(buf,"password ",9)) { |
136 | if (!strncmp(buf,"password ",9)) { |
137 | buf[strlen(buf)-1]=0; /* remove newline */ |
137 | buf[strlen(buf)-1]=0; /* remove newline */ |
138 | if (check_password(password, buf+9)) { |
138 | if (check_password(password, buf+9)) { |
139 | close_and_delete(fp, comp); |
139 | close_and_delete(fp, comp); |
140 | return 0; |
140 | return 0; |
141 | } |
141 | } |
142 | else { |
142 | else { |
143 | close_and_delete(fp, comp); |
143 | close_and_delete(fp, comp); |
144 | return 2; |
144 | return 2; |
145 | } |
145 | } |
146 | } |
146 | } |
147 | } |
147 | } |
148 | LOG(llevDebug,"Could not find a password line in player %s\n", name); |
148 | LOG(llevDebug,"Could not find a password line in player %s\n", name); |
149 | close_and_delete(fp, comp); |
149 | close_and_delete(fp, comp); |
150 | return 1; |
150 | return 1; |
151 | } |
151 | } |
… | |
… | |
162 | |
162 | |
163 | int check_name(player *me,const char *name) { |
163 | int check_name(player *me,const char *name) { |
164 | player *pl; |
164 | player *pl; |
165 | |
165 | |
166 | for(pl=first_player;pl!=NULL;pl=pl->next) |
166 | for(pl=first_player;pl!=NULL;pl=pl->next) |
167 | if(pl!=me&&pl->ob->name!=NULL&&!strcmp(pl->ob->name,name)) { |
167 | if(pl!=me&&pl->ob->name!=NULL&&!strcmp(pl->ob->name,name)) { |
168 | new_draw_info(NDI_UNIQUE, 0,me->ob,"That name is already in use."); |
168 | new_draw_info(NDI_UNIQUE, 0,me->ob,"That name is already in use."); |
169 | return 0; |
169 | return 0; |
170 | } |
170 | } |
171 | |
171 | |
172 | if (*name=='\0') { |
172 | if (*name=='\0') { |
173 | new_draw_info(NDI_UNIQUE, 0,me->ob,"Null names are not allowed."); |
173 | new_draw_info(NDI_UNIQUE, 0,me->ob,"Null names are not allowed."); |
174 | return 0; |
174 | return 0; |
175 | } |
175 | } |
176 | |
176 | |
177 | if(!playername_ok(name)) { |
177 | if(!playername_ok(name)) { |
178 | new_draw_info(NDI_UNIQUE, 0,me->ob,"That name contains illegal characters."); |
178 | new_draw_info(NDI_UNIQUE, 0,me->ob,"That name contains illegal characters."); |
179 | return 0; |
179 | return 0; |
180 | } |
180 | } |
181 | if (strlen(name) >= MAX_NAME) { |
181 | if (strlen(name) >= MAX_NAME) { |
182 | new_draw_info(NDI_UNIQUE, 0,me->ob,"That name is too long."); |
182 | new_draw_info(NDI_UNIQUE, 0,me->ob,"That name is too long."); |
183 | return 0; |
183 | return 0; |
184 | } |
184 | } |
185 | |
185 | |
186 | return 1; |
186 | return 1; |
187 | } |
187 | } |
188 | |
188 | |
… | |
… | |
195 | return 0; |
195 | return 0; |
196 | } else { |
196 | } else { |
197 | stat(savedir, buf); |
197 | stat(savedir, buf); |
198 | if (!S_ISDIR(buf->st_mode)) |
198 | if (!S_ISDIR(buf->st_mode)) |
199 | if (mkdir(savedir, SAVE_DIR_MODE)) |
199 | if (mkdir(savedir, SAVE_DIR_MODE)) |
200 | { |
200 | { |
201 | LOG(llevError, "Unable to create player savedir %s: %s\n", savedir, strerror_local(errno)); |
201 | LOG(llevError, "Unable to create player savedir %s: %s\n", savedir, strerror(errno)); |
202 | return 0; |
202 | return 0; |
203 | } |
203 | } |
204 | free(buf); |
204 | free(buf); |
205 | } |
205 | } |
206 | return 1; |
206 | return 1; |
207 | } |
207 | } |
208 | |
208 | |
209 | void destroy_object (object *op) |
209 | void destroy_object (object *op) |
210 | { |
210 | { |
211 | object *tmp; |
211 | object *tmp; |
212 | while ((tmp = op->inv)) |
212 | while ((tmp = op->inv)) |
213 | destroy_object (tmp); |
213 | destroy_object (tmp); |
214 | |
214 | |
215 | if (!QUERY_FLAG(op, FLAG_REMOVED)) |
215 | if (!QUERY_FLAG(op, FLAG_REMOVED)) |
216 | remove_ob(op); |
216 | remove_ob(op); |
217 | free_object(op); |
217 | free_object(op); |
218 | } |
218 | } |
219 | |
219 | |
220 | /* |
220 | /* |
221 | * If flag is set, it's only backup, ie dont remove objects from inventory |
221 | * If flag is set, it's only backup, ie dont remove objects from inventory |
… | |
… | |
223 | * will be saved at the emergency save location. |
223 | * will be saved at the emergency save location. |
224 | * Returns non zero if successful. |
224 | * Returns non zero if successful. |
225 | */ |
225 | */ |
226 | |
226 | |
227 | int save_player(object *op, int flag) { |
227 | int save_player(object *op, int flag) { |
228 | FILE *fp; |
|
|
229 | char filename[MAX_BUF], *tmpfilename,backupfile[MAX_BUF]; |
|
|
230 | object *tmp, *container=NULL; |
228 | object *tmp, *container=NULL; |
231 | player *pl = op->contr; |
229 | player *pl = op->contr; |
232 | int i,wiz=QUERY_FLAG(op,FLAG_WIZ); |
230 | int i,wiz=QUERY_FLAG(op,FLAG_WIZ); |
233 | long checksum; |
231 | long checksum; |
234 | #ifdef BACKUP_SAVE_AT_HOME |
232 | #ifdef BACKUP_SAVE_AT_HOME |
… | |
… | |
252 | |
250 | |
253 | /* Prevent accidental saves if connection is reset after player has |
251 | /* Prevent accidental saves if connection is reset after player has |
254 | * mostly exited. |
252 | * mostly exited. |
255 | */ |
253 | */ |
256 | if (pl->state != ST_PLAYING && pl->state != ST_GET_PARTY_PASSWORD) |
254 | if (pl->state != ST_PLAYING && pl->state != ST_GET_PARTY_PASSWORD) |
257 | return 0; |
255 | return 0; |
|
|
256 | |
|
|
257 | INVOKE_PLAYER (SAVE, op->contr); |
258 | |
258 | |
259 | if (flag == 0) |
259 | if (flag == 0) |
260 | terminate_all_pets(op); |
260 | terminate_all_pets(op); |
261 | |
261 | |
262 | /* Delete old style file */ |
262 | object_freezer freezer; |
263 | sprintf(filename,"%s/%s/%s.pl",settings.localdir,settings.playerdir,op->name); |
|
|
264 | unlink(filename); |
|
|
265 | |
263 | |
266 | sprintf(filename,"%s/%s/%s/%s.pl",settings.localdir,settings.playerdir,op->name,op->name); |
|
|
267 | make_path_to_file(filename); |
|
|
268 | tmpfilename = tempnam_local(settings.tmpdir,NULL); |
|
|
269 | fp=fopen(tmpfilename, "w"); |
|
|
270 | if(!fp) { |
|
|
271 | new_draw_info(NDI_UNIQUE, 0,op, "Can't open file for save."); |
|
|
272 | LOG(llevDebug,"Can't open file for save (%s).\n",tmpfilename); |
|
|
273 | free(tmpfilename); |
|
|
274 | return 0; |
|
|
275 | } |
|
|
276 | |
|
|
277 | /* Eneq(@csd.uu.se): If we have an open container hide it. */ |
264 | /* Eneq(@csd.uu.se): If we have an open container hide it. */ |
278 | if (op->container) { |
265 | if (op->container) |
|
|
266 | { |
279 | container=op->container; |
267 | container = op->container; |
280 | op->container=NULL; |
268 | op->container = NULL; |
281 | } |
269 | } |
282 | |
270 | |
283 | execute_global_event (EVENT_PLAYER_SAVE, op, filename); |
|
|
284 | |
|
|
285 | fprintf(fp,"password %s\n",pl->password); |
271 | fprintf(freezer,"password %s\n",pl->password); |
|
|
272 | |
286 | if (settings.set_title == TRUE) |
273 | if (settings.set_title == TRUE) |
287 | if(pl->own_title[0]!='\0') |
274 | if(pl->own_title[0]!='\0') |
288 | fprintf(fp,"title %s\n",pl->own_title); |
275 | fprintf(freezer,"title %s\n",pl->own_title); |
289 | |
276 | |
290 | fprintf(fp,"explore %d\n",pl->explore); |
277 | fprintf(freezer,"explore %d\n",pl->explore); |
291 | fprintf(fp,"gen_hp %d\n",pl->gen_hp); |
278 | fprintf(freezer,"gen_hp %d\n",pl->gen_hp); |
292 | fprintf(fp,"gen_sp %d\n",pl->gen_sp); |
279 | fprintf(freezer,"gen_sp %d\n",pl->gen_sp); |
293 | fprintf(fp,"gen_grace %d\n",pl->gen_grace); |
280 | fprintf(freezer,"gen_grace %d\n",pl->gen_grace); |
294 | fprintf(fp,"listening %d\n",pl->listening); |
281 | fprintf(freezer,"listening %d\n",pl->listening); |
295 | fprintf(fp,"shoottype %d\n",pl->shoottype); |
282 | fprintf(freezer,"shoottype %d\n",pl->shoottype); |
296 | fprintf(fp,"bowtype %d\n",pl->bowtype); |
283 | fprintf(freezer,"bowtype %d\n",pl->bowtype); |
297 | fprintf(fp,"petmode %d\n",pl->petmode); |
284 | fprintf(freezer,"petmode %d\n",pl->petmode); |
298 | fprintf(fp,"peaceful %d\n",pl->peaceful); |
285 | fprintf(freezer,"peaceful %d\n",pl->peaceful); |
299 | fprintf(fp,"no_shout %d\n",pl->no_shout); |
286 | fprintf(freezer,"no_shout %d\n",pl->no_shout); |
300 | fprintf(fp,"digestion %d\n",pl->digestion); |
287 | fprintf(freezer,"digestion %d\n",pl->digestion); |
301 | fprintf(fp,"pickup %d\n", pl->mode); |
288 | fprintf(freezer,"pickup %d\n", pl->mode); |
302 | fprintf(fp,"outputs_sync %d\n", pl->outputs_sync); |
289 | fprintf(freezer,"outputs_sync %d\n", pl->outputs_sync); |
303 | fprintf(fp,"outputs_count %d\n", pl->outputs_count); |
290 | fprintf(freezer,"outputs_count %d\n", pl->outputs_count); |
304 | /* Match the enumerations but in string form */ |
291 | /* Match the enumerations but in string form */ |
305 | fprintf(fp,"usekeys %s\n", pl->usekeys==key_inventory?"key_inventory": |
292 | fprintf(freezer,"usekeys %s\n", pl->usekeys==key_inventory?"key_inventory": |
306 | (pl->usekeys==keyrings?"keyrings":"containers")); |
293 | (pl->usekeys==keyrings?"keyrings":"containers")); |
307 | /* Match the enumerations but in string form */ |
294 | /* Match the enumerations but in string form */ |
308 | fprintf(fp,"unapply %s\n", pl->unapply==unapply_nochoice?"unapply_nochoice": |
295 | fprintf(freezer,"unapply %s\n", pl->unapply==unapply_nochoice?"unapply_nochoice": |
309 | (pl->unapply==unapply_never?"unapply_never":"unapply_always")); |
296 | (pl->unapply==unapply_never?"unapply_never":"unapply_always")); |
310 | |
|
|
311 | |
|
|
312 | |
297 | |
313 | #ifdef BACKUP_SAVE_AT_HOME |
298 | #ifdef BACKUP_SAVE_AT_HOME |
314 | if (op->map!=NULL && flag==0) |
299 | if (op->map!=NULL && flag==0) |
315 | #else |
300 | #else |
316 | if (op->map!=NULL) |
301 | if (op->map!=NULL) |
317 | #endif |
302 | #endif |
318 | fprintf(fp,"map %s\n",op->map->path); |
303 | fprintf(freezer,"map %s\n",op->map->path); |
319 | else |
304 | else |
320 | fprintf(fp,"map %s\n",settings.emergency_mapname); |
305 | fprintf(freezer,"map %s\n",settings.emergency_mapname); |
321 | |
306 | |
322 | fprintf(fp,"savebed_map %s\n", pl->savebed_map); |
307 | fprintf(freezer,"savebed_map %s\n", pl->savebed_map); |
323 | fprintf(fp,"bed_x %d\nbed_y %d\n", pl->bed_x, pl->bed_y); |
308 | fprintf(freezer,"bed_x %d\nbed_y %d\n", pl->bed_x, pl->bed_y); |
324 | fprintf(fp,"weapon_sp %f\n",pl->weapon_sp); |
309 | fprintf(freezer,"weapon_sp %f\n",pl->weapon_sp); |
325 | fprintf(fp,"Str %d\n",pl->orig_stats.Str); |
310 | fprintf(freezer,"Str %d\n",pl->orig_stats.Str); |
326 | fprintf(fp,"Dex %d\n",pl->orig_stats.Dex); |
311 | fprintf(freezer,"Dex %d\n",pl->orig_stats.Dex); |
327 | fprintf(fp,"Con %d\n",pl->orig_stats.Con); |
312 | fprintf(freezer,"Con %d\n",pl->orig_stats.Con); |
328 | fprintf(fp,"Int %d\n",pl->orig_stats.Int); |
313 | fprintf(freezer,"Int %d\n",pl->orig_stats.Int); |
329 | fprintf(fp,"Pow %d\n",pl->orig_stats.Pow); |
314 | fprintf(freezer,"Pow %d\n",pl->orig_stats.Pow); |
330 | fprintf(fp,"Wis %d\n",pl->orig_stats.Wis); |
315 | fprintf(freezer,"Wis %d\n",pl->orig_stats.Wis); |
331 | fprintf(fp,"Cha %d\n",pl->orig_stats.Cha); |
316 | fprintf(freezer,"Cha %d\n",pl->orig_stats.Cha); |
332 | |
317 | |
333 | fprintf(fp,"lev_array %d\n",op->level>10?10:op->level); |
318 | fprintf(freezer,"lev_array %d\n",op->level>10?10:op->level); |
334 | for(i=1;i<=pl->last_level&&i<=10;i++) { |
319 | for(i=1;i<=pl->last_level&&i<=10;i++) { |
335 | fprintf(fp,"%d\n",pl->levhp[i]); |
320 | fprintf(freezer,"%d\n",pl->levhp[i]); |
336 | fprintf(fp,"%d\n",pl->levsp[i]); |
321 | fprintf(freezer,"%d\n",pl->levsp[i]); |
337 | fprintf(fp,"%d\n",pl->levgrace[i]); |
322 | fprintf(freezer,"%d\n",pl->levgrace[i]); |
338 | } |
323 | } |
|
|
324 | |
|
|
325 | freezer.put (op->contr); |
|
|
326 | |
339 | fprintf(fp,"endplst\n"); |
327 | fprintf(freezer,"endplst\n"); |
340 | |
328 | |
341 | SET_FLAG(op, FLAG_NO_FIX_PLAYER); |
329 | SET_FLAG(op, FLAG_NO_FIX_PLAYER); |
342 | CLEAR_FLAG(op, FLAG_WIZ); |
330 | CLEAR_FLAG(op, FLAG_WIZ); |
343 | #ifdef BACKUP_SAVE_AT_HOME |
331 | #ifdef BACKUP_SAVE_AT_HOME |
344 | if (flag) { |
332 | if (flag) { |
… | |
… | |
348 | op->y = -1; |
336 | op->y = -1; |
349 | } |
337 | } |
350 | /* Save objects, but not unpaid objects. Don't remove objects from |
338 | /* Save objects, but not unpaid objects. Don't remove objects from |
351 | * inventory. |
339 | * inventory. |
352 | */ |
340 | */ |
353 | save_object(fp, op, 2); |
341 | save_object(freezer, op, 2); |
354 | if (flag) { |
342 | if (flag) { |
355 | op->x = backup_x; |
343 | op->x = backup_x; |
356 | op->y = backup_y; |
344 | op->y = backup_y; |
357 | } |
345 | } |
358 | #else |
346 | #else |
359 | save_object(fp, op, 3); /* don't check and don't remove */ |
347 | save_object(freezer, op, 3); /* don't check and don't remove */ |
360 | #endif |
348 | #endif |
|
|
349 | |
|
|
350 | char filename[MAX_BUF]; |
|
|
351 | sprintf(filename,"%s/%s/%s/%s.pl",settings.localdir,settings.playerdir,&op->name,&op->name); |
|
|
352 | make_path_to_file(filename); |
|
|
353 | freezer.save (filename); |
361 | |
354 | |
362 | CLEAR_FLAG(op, FLAG_NO_FIX_PLAYER); |
355 | CLEAR_FLAG(op, FLAG_NO_FIX_PLAYER); |
363 | |
356 | |
364 | if(!flag) |
357 | if(!flag) |
365 | while ((tmp = op->inv)) |
358 | while ((tmp = op->inv)) |
366 | destroy_object (tmp); |
359 | destroy_object (tmp); |
367 | |
|
|
368 | if (fclose(fp) == EOF) { /* make sure the write succeeded */ |
|
|
369 | new_draw_info(NDI_UNIQUE, 0,op, "Can't save character."); |
|
|
370 | unlink(tmpfilename); |
|
|
371 | free(tmpfilename); |
|
|
372 | return 0; |
|
|
373 | } |
|
|
374 | |
|
|
375 | checksum = 0; |
|
|
376 | sprintf(backupfile, "%s.tmp", filename); |
|
|
377 | rename(filename, backupfile); |
|
|
378 | fp = fopen(filename,"w"); |
|
|
379 | if(!fp) { |
|
|
380 | new_draw_info(NDI_UNIQUE, 0,op, "Can't open file for save."); |
|
|
381 | unlink(tmpfilename); |
|
|
382 | free(tmpfilename); |
|
|
383 | return 0; |
|
|
384 | } |
|
|
385 | fprintf(fp,"checksum %lx\n",checksum); |
|
|
386 | copy_file(tmpfilename, fp); |
|
|
387 | unlink(tmpfilename); |
|
|
388 | free(tmpfilename); |
|
|
389 | if (fclose(fp) == EOF) { /* got write error */ |
|
|
390 | new_draw_info(NDI_UNIQUE, 0,op, "Can't close file for save."); |
|
|
391 | rename(backupfile, filename); /* Restore the original */ |
|
|
392 | return 0; |
|
|
393 | } |
|
|
394 | else |
|
|
395 | unlink(backupfile); |
|
|
396 | |
360 | |
397 | /* Eneq(@csd.uu.se): Reveal the container if we have one. */ |
361 | /* Eneq(@csd.uu.se): Reveal the container if we have one. */ |
398 | if (flag&&container!=NULL) |
362 | if (flag && container!=NULL) |
399 | op->container = container; |
363 | op->container = container; |
400 | |
364 | |
401 | if (wiz) SET_FLAG(op,FLAG_WIZ); |
365 | if (wiz) SET_FLAG (op, FLAG_WIZ); |
|
|
366 | |
402 | if(!flag) |
367 | if(!flag) |
403 | esrv_send_inventory(op, op); |
368 | esrv_send_inventory(op, op); |
404 | |
|
|
405 | chmod(filename,SAVE_MODE); |
|
|
406 | |
369 | |
407 | return 1; |
370 | return 1; |
408 | } |
371 | } |
409 | |
372 | |
410 | void copy_file(const char *filename, FILE *fpout) { |
|
|
411 | FILE *fp; |
|
|
412 | char buf[MAX_BUF]; |
|
|
413 | if((fp = fopen(filename,"r")) == NULL) |
|
|
414 | return; |
|
|
415 | while(fgets(buf,MAX_BUF,fp)!=NULL) |
|
|
416 | fputs(buf,fpout); |
|
|
417 | fclose(fp); |
|
|
418 | } |
|
|
419 | |
|
|
420 | |
|
|
421 | void check_login(object *op) { |
373 | void check_login(object *op) { |
422 | FILE *fp; |
|
|
423 | char filename[MAX_BUF]; |
374 | char filename[MAX_BUF]; |
424 | char buf[MAX_BUF],bufall[MAX_BUF]; |
375 | char buf[MAX_BUF],bufall[MAX_BUF]; |
425 | int i,value,comp; |
376 | int i,value,comp; |
426 | long checksum = 0; |
377 | long checksum = 0; |
427 | player *pl = op->contr; |
378 | player *pl = op->contr; |
428 | int correct = 0; |
379 | int correct = 0; |
429 | time_t elapsed_save_time=0; |
|
|
430 | struct stat statbuf; |
|
|
431 | |
380 | |
432 | strcpy (pl->maplevel,first_map_path); |
381 | strcpy (pl->maplevel,first_map_path); |
433 | |
|
|
434 | /* First, lets check for newest form of save */ |
|
|
435 | sprintf(filename,"%s/%s/%s/%s.pl",settings.localdir,settings.playerdir,op->name,op->name); |
382 | sprintf(filename,"%s/%s/%s/%s.pl",settings.localdir,settings.playerdir,&op->name,&op->name); |
436 | if (access(filename, F_OK)==-1) { |
|
|
437 | /* not there, Try the old style */ |
|
|
438 | |
383 | |
439 | sprintf(filename,"%s/%s/%s.pl",settings.localdir,settings.playerdir,op->name); |
384 | object_thawer thawer (filename); |
440 | /* Ok - old style exists. Lets make the new style directory */ |
|
|
441 | if (access(filename, F_OK)==0) { |
|
|
442 | sprintf(buf,"%s/%s/%s",settings.localdir,settings.playerdir,op->name); |
|
|
443 | make_path_to_file(buf); |
|
|
444 | } |
|
|
445 | } |
|
|
446 | |
|
|
447 | /* If no file, must be a new player, so lets get confirmation of |
385 | /* If no file, must be a new player, so lets get confirmation of |
448 | * the password. Return control to the higher level dispatch, |
386 | * the password. Return control to the higher level dispatch, |
449 | * since the rest of this just deals with loading of the file. |
387 | * since the rest of this just deals with loading of the file. |
450 | */ |
388 | */ |
451 | if ((fp=open_and_uncompress(filename,1,&comp)) == NULL) { |
389 | if (!thawer) { |
452 | confirm_password(op); |
390 | confirm_password(op); |
453 | return; |
391 | return; |
454 | } |
392 | } |
455 | if (fstat(fileno(fp), &statbuf)) { |
|
|
456 | LOG(llevError,"Unable to stat %s?\n", filename); |
|
|
457 | elapsed_save_time=0; |
|
|
458 | } else { |
|
|
459 | elapsed_save_time = time(NULL) - statbuf.st_mtime; |
|
|
460 | if (elapsed_save_time<0) { |
|
|
461 | LOG(llevError,"Player file %s was saved in the future? (%d time)\n", filename, elapsed_save_time); |
|
|
462 | elapsed_save_time=0; |
|
|
463 | } |
|
|
464 | } |
|
|
465 | |
393 | |
466 | if(fgets(bufall,MAX_BUF,fp) != NULL) { |
394 | if(fgets(bufall,MAX_BUF,thawer) != NULL) { |
467 | if(!strncmp(bufall,"checksum ",9)) { |
395 | if(!strncmp(bufall,"checksum ",9)) { |
468 | checksum = strtol(bufall+9,(char **) NULL, 16); |
396 | checksum = strtol(bufall+9,(char **) NULL, 16); |
469 | (void) fgets(bufall,MAX_BUF,fp); |
397 | (void) fgets(bufall,MAX_BUF,thawer); |
470 | } |
398 | } |
471 | if(sscanf(bufall,"password %s\n",buf)) { |
399 | if(sscanf(bufall,"password %s\n",buf)) { |
472 | /* New password scheme: */ |
400 | /* New password scheme: */ |
473 | correct=check_password(pl->write_buf+1,buf); |
401 | correct=check_password(pl->write_buf+1,buf); |
474 | } |
402 | } |
475 | /* Old password mode removed - I have no idea what it |
403 | /* Old password mode removed - I have no idea what it |
476 | * was, and the current password mechanism has been used |
404 | * was, and the current password mechanism has been used |
477 | * for at least several years. |
405 | * for at least several years. |
478 | */ |
406 | */ |
479 | } |
407 | } |
480 | if (!correct) { |
408 | if (!correct) { |
481 | new_draw_info(NDI_UNIQUE, 0,op," "); |
409 | new_draw_info(NDI_UNIQUE, 0,op," "); |
482 | new_draw_info(NDI_UNIQUE, 0,op,"Wrong Password!"); |
410 | new_draw_info(NDI_UNIQUE, 0,op,"Wrong Password!"); |
483 | new_draw_info(NDI_UNIQUE, 0,op," "); |
411 | new_draw_info(NDI_UNIQUE, 0,op," "); |
484 | FREE_AND_COPY(op->name, "noname"); |
412 | op->name = |
485 | FREE_AND_COPY(op->name_pl, "noname"); |
413 | op->name_pl = "noname"; |
486 | op->contr->socket.password_fails++; |
414 | op->contr->socket.password_fails++; |
487 | if (op->contr->socket.password_fails >= MAX_PASSWORD_FAILURES) { |
415 | if (op->contr->socket.password_fails >= MAX_PASSWORD_FAILURES) { |
488 | new_draw_info(NDI_UNIQUE, 0,op, |
416 | new_draw_info(NDI_UNIQUE, 0,op, |
489 | "You gave an incorrect password too many times, you will now be dropped from the server."); |
417 | "You gave an incorrect password too many times, you will now be dropped from the server."); |
490 | LOG(llevInfo, "A player connecting from %s has been dropped for password failure\n", |
418 | LOG(llevInfo, "A player connecting from %s has been dropped for password failure\n", |
491 | op->contr->socket.host); |
419 | op->contr->socket.host); |
492 | op->contr->socket.status = Ns_Dead; /* the socket loop should handle the rest for us */ |
420 | op->contr->socket.status = Ns_Dead; /* the socket loop should handle the rest for us */ |
493 | } |
421 | } |
494 | else get_name(op); |
422 | else get_name(op); |
495 | return; /* Once again, rest of code just loads the char */ |
423 | return; /* Once again, rest of code just loads the char */ |
496 | } |
424 | } |
497 | |
425 | |
498 | #ifdef SAVE_INTERVAL |
426 | #ifdef SAVE_INTERVAL |
499 | pl->last_save_time=time(NULL); |
427 | pl->last_save_time=time(NULL); |
500 | #endif /* SAVE_INTERVAL */ |
428 | #endif /* SAVE_INTERVAL */ |
501 | pl->party = NULL; |
429 | pl->party = NULL; |
502 | if (settings.search_items == TRUE) |
430 | if (settings.search_items == TRUE) |
503 | pl->search_str[0]='\0'; |
431 | pl->search_str[0]='\0'; |
504 | pl->name_changed=1; |
432 | pl->name_changed=1; |
505 | pl->orig_stats.Str=0; |
433 | pl->orig_stats.Str=0; |
506 | pl->orig_stats.Dex=0; |
434 | pl->orig_stats.Dex=0; |
507 | pl->orig_stats.Con=0; |
435 | pl->orig_stats.Con=0; |
508 | pl->orig_stats.Int=0; |
436 | pl->orig_stats.Int=0; |
… | |
… | |
512 | strcpy(pl->savebed_map, first_map_path); |
440 | strcpy(pl->savebed_map, first_map_path); |
513 | pl->bed_x=0, pl->bed_y=0; |
441 | pl->bed_x=0, pl->bed_y=0; |
514 | pl->spellparam[0] = '\0'; |
442 | pl->spellparam[0] = '\0'; |
515 | |
443 | |
516 | /* Loop through the file, loading the rest of the values */ |
444 | /* Loop through the file, loading the rest of the values */ |
517 | while (fgets(bufall,MAX_BUF,fp)!=NULL) { |
445 | while (fgets(bufall,MAX_BUF,thawer)!=NULL) { |
518 | sscanf(bufall,"%s %d\n",buf,&value); |
446 | sscanf(bufall,"%s %d\n",buf,&value); |
519 | if (!strcmp(buf,"endplst")) |
447 | if (!strcmp(buf,"endplst")) |
520 | break; |
448 | break; |
|
|
449 | else if (!strcmp(buf,"oid")) |
|
|
450 | thawer.get (pl, value); |
521 | else if (!strcmp(buf,"title") && settings.set_title == TRUE) |
451 | else if (!strcmp(buf,"title") && settings.set_title == TRUE) |
522 | sscanf(bufall,"title %[^\n]",pl->own_title); |
452 | sscanf(bufall,"title %[^\n]",pl->own_title); |
523 | else if (!strcmp(buf,"explore")) |
453 | else if (!strcmp(buf,"explore")) |
524 | pl->explore = value; |
454 | pl->explore = value; |
525 | else if (!strcmp(buf,"gen_hp")) |
455 | else if (!strcmp(buf,"gen_hp")) |
526 | pl->gen_hp=value; |
456 | pl->gen_hp=value; |
527 | else if (!strcmp(buf,"shoottype")) |
457 | else if (!strcmp(buf,"shoottype")) |
528 | pl->shoottype=(rangetype)value; |
458 | pl->shoottype=(rangetype)value; |
529 | else if (!strcmp(buf,"bowtype")) |
459 | else if (!strcmp(buf,"bowtype")) |
530 | pl->bowtype=(bowtype_t)value; |
460 | pl->bowtype=(bowtype_t)value; |
531 | else if (!strcmp(buf,"petmode")) |
461 | else if (!strcmp(buf,"petmode")) |
532 | pl->petmode=(petmode_t)value; |
462 | pl->petmode=(petmode_t)value; |
533 | else if (!strcmp(buf,"gen_sp")) |
463 | else if (!strcmp(buf,"gen_sp")) |
534 | pl->gen_sp=value; |
464 | pl->gen_sp=value; |
535 | else if (!strcmp(buf,"gen_grace")) |
465 | else if (!strcmp(buf,"gen_grace")) |
536 | pl->gen_grace=value; |
466 | pl->gen_grace=value; |
537 | else if (!strcmp(buf,"listening")) |
467 | else if (!strcmp(buf,"listening")) |
538 | pl->listening=value; |
468 | pl->listening=value; |
539 | else if (!strcmp(buf,"peaceful")) |
469 | else if (!strcmp(buf,"peaceful")) |
540 | pl->peaceful=value; |
470 | pl->peaceful=value; |
541 | else if (!strcmp(buf,"no_shout")) |
471 | else if (!strcmp(buf,"no_shout")) |
542 | pl->no_shout=value; |
472 | pl->no_shout=value; |
543 | else if (!strcmp(buf,"digestion")) |
473 | else if (!strcmp(buf,"digestion")) |
544 | pl->digestion=value; |
474 | pl->digestion=value; |
545 | else if (!strcmp(buf,"pickup")) |
475 | else if (!strcmp(buf,"pickup")) |
546 | pl->mode=value; |
476 | pl->mode=value; |
547 | else if (!strcmp(buf,"outputs_sync")) |
477 | else if (!strcmp(buf,"outputs_sync")) |
548 | pl->outputs_sync = value; |
478 | pl->outputs_sync = value; |
549 | else if (!strcmp(buf,"outputs_count")) |
479 | else if (!strcmp(buf,"outputs_count")) |
550 | pl->outputs_count = value; |
480 | pl->outputs_count = value; |
551 | else if (!strcmp(buf,"map")) |
481 | else if (!strcmp(buf,"map")) |
552 | sscanf(bufall,"map %s", pl->maplevel); |
482 | sscanf(bufall,"map %s", pl->maplevel); |
553 | else if (!strcmp(buf,"savebed_map")) |
483 | else if (!strcmp(buf,"savebed_map")) |
554 | sscanf(bufall,"savebed_map %s", pl->savebed_map); |
484 | sscanf(bufall,"savebed_map %s", pl->savebed_map); |
555 | else if (!strcmp(buf,"bed_x")) |
485 | else if (!strcmp(buf,"bed_x")) |
556 | pl->bed_x=value; |
486 | pl->bed_x=value; |
557 | else if (!strcmp(buf,"bed_y")) |
487 | else if (!strcmp(buf,"bed_y")) |
558 | pl->bed_y=value; |
488 | pl->bed_y=value; |
559 | else if (!strcmp(buf,"weapon_sp")) |
489 | else if (!strcmp(buf,"weapon_sp")) |
560 | sscanf(buf,"weapon_sp %f",&pl->weapon_sp); |
490 | sscanf(buf,"weapon_sp %f",&pl->weapon_sp); |
561 | else if (!strcmp(buf,"Str")) |
491 | else if (!strcmp(buf,"Str")) |
562 | pl->orig_stats.Str=value; |
492 | pl->orig_stats.Str=value; |
563 | else if (!strcmp(buf,"Dex")) |
493 | else if (!strcmp(buf,"Dex")) |
564 | pl->orig_stats.Dex=value; |
494 | pl->orig_stats.Dex=value; |
565 | else if (!strcmp(buf,"Con")) |
495 | else if (!strcmp(buf,"Con")) |
566 | pl->orig_stats.Con=value; |
496 | pl->orig_stats.Con=value; |
567 | else if (!strcmp(buf,"Int")) |
497 | else if (!strcmp(buf,"Int")) |
568 | pl->orig_stats.Int=value; |
498 | pl->orig_stats.Int=value; |
569 | else if (!strcmp(buf,"Pow")) |
499 | else if (!strcmp(buf,"Pow")) |
570 | pl->orig_stats.Pow=value; |
500 | pl->orig_stats.Pow=value; |
571 | else if (!strcmp(buf,"Wis")) |
501 | else if (!strcmp(buf,"Wis")) |
572 | pl->orig_stats.Wis=value; |
502 | pl->orig_stats.Wis=value; |
573 | else if (!strcmp(buf,"Cha")) |
503 | else if (!strcmp(buf,"Cha")) |
574 | pl->orig_stats.Cha=value; |
504 | pl->orig_stats.Cha=value; |
575 | else if (!strcmp(buf,"usekeys")) { |
505 | else if (!strcmp(buf,"usekeys")) { |
576 | if (!strcmp(bufall+8,"key_inventory\n")) |
506 | if (!strcmp(bufall+8,"key_inventory\n")) |
577 | pl->usekeys=key_inventory; |
507 | pl->usekeys=key_inventory; |
578 | else if (!strcmp(bufall+8,"keyrings\n")) |
508 | else if (!strcmp(bufall+8,"keyrings\n")) |
579 | pl->usekeys=keyrings; |
509 | pl->usekeys=keyrings; |
580 | else if (!strcmp(bufall+8,"containers\n")) |
510 | else if (!strcmp(bufall+8,"containers\n")) |
581 | pl->usekeys=containers; |
511 | pl->usekeys=containers; |
582 | else LOG(llevDebug,"load_player: got unknown usekeys type: %s\n", bufall+8); |
512 | else LOG(llevDebug,"load_player: got unknown usekeys type: %s\n", bufall+8); |
583 | } |
513 | } |
584 | else if (!strcmp(buf,"unapply")) { |
514 | else if (!strcmp(buf,"unapply")) { |
585 | if (!strcmp(bufall+8,"unapply_nochoice\n")) |
515 | if (!strcmp(bufall+8,"unapply_nochoice\n")) |
586 | pl->unapply=unapply_nochoice; |
516 | pl->unapply=unapply_nochoice; |
587 | else if (!strcmp(bufall+8,"unapply_never\n")) |
517 | else if (!strcmp(bufall+8,"unapply_never\n")) |
588 | pl->unapply=unapply_never; |
518 | pl->unapply=unapply_never; |
589 | else if (!strcmp(bufall+8,"unapply_always\n")) |
519 | else if (!strcmp(bufall+8,"unapply_always\n")) |
590 | pl->unapply=unapply_always; |
520 | pl->unapply=unapply_always; |
591 | else LOG(llevDebug,"load_player: got unknown unapply type: %s\n", bufall+8); |
521 | else LOG(llevDebug,"load_player: got unknown unapply type: %s\n", bufall+8); |
592 | } |
522 | } |
593 | else if (!strcmp(buf,"lev_array")){ |
523 | else if (!strcmp(buf,"lev_array")){ |
594 | for(i=1;i<=value;i++) { |
524 | for(i=1;i<=value;i++) |
595 | int j; |
525 | { |
596 | fscanf(fp,"%d\n",&j); |
526 | char line[128]; |
597 | pl->levhp[i]=j; |
527 | fgets (line, 128, thawer); pl->levhp[i] = atoi (line); |
598 | fscanf(fp,"%d\n",&j); |
528 | fgets (line, 128, thawer); pl->levsp[i] = atoi (line); |
599 | pl->levsp[i]=j; |
529 | fgets (line, 128, thawer); pl->levgrace[i] = atoi (line); |
600 | fscanf(fp,"%d\n",&j); |
530 | } |
601 | pl->levgrace[i]=j; |
|
|
602 | } |
|
|
603 | /* spell_array code removed - don't know when that was last used. |
531 | /* spell_array code removed - don't know when that was last used. |
604 | * Even the load code below will someday be replaced by spells being |
532 | * Even the load code below will someday be replaced by spells being |
605 | * objects. |
533 | * objects. |
606 | */ |
534 | */ |
607 | } else if (!strcmp(buf,"known_spell")) { |
535 | } else if (!strcmp(buf,"known_spell")) { |
608 | #if 0 |
536 | #if 0 |
609 | /* Logic is left here in case someone wants to try |
537 | /* Logic is left here in case someone wants to try |
610 | * and write code to update to spell objects. |
538 | * and write code to update to spell objects. |
611 | */ |
539 | */ |
612 | char *cp=strchr(bufall,'\n'); |
540 | char *cp=strchr(bufall,'\n'); |
613 | *cp='\0'; |
541 | *cp='\0'; |
614 | cp=strchr(bufall,' '); |
542 | cp=strchr(bufall,' '); |
615 | cp++; |
543 | cp++; |
616 | for(i=0;i<NROFREALSPELLS;i++) |
544 | for(i=0;i<NROFREALSPELLS;i++) |
617 | if(!strcmp(spells[i].name,cp)) { |
545 | if(!strcmp(spells[i].name,cp)) { |
618 | pl->known_spells[pl->nrofknownspells++]=i; |
546 | pl->known_spells[pl->nrofknownspells++]=i; |
619 | break; |
547 | break; |
620 | } |
548 | } |
621 | if(i==NROFREALSPELLS) |
549 | if(i==NROFREALSPELLS) |
622 | LOG(llevDebug, "Error: unknown spell (%s)\n",cp); |
550 | LOG(llevDebug, "Error: unknown spell (%s)\n",cp); |
623 | #endif |
551 | #endif |
624 | } |
552 | } |
625 | } /* End of loop loading the character file */ |
553 | } /* End of loop loading the character file */ |
626 | leave_map(op); |
554 | leave_map(op); |
627 | op->speed=0; |
555 | op->speed=0; |
628 | update_ob_speed(op); |
556 | update_ob_speed(op); |
629 | reset_object(op); |
557 | reset_object(op); |
630 | op->contr = pl; |
558 | op->contr = pl; |
631 | pl->ob = op; |
559 | pl->ob = op; |
|
|
560 | |
632 | /* this loads the standard objects values. */ |
561 | /* this loads the standard objects values. */ |
633 | load_object(fp, op, LO_NEWFILE,0); |
562 | load_object (thawer, op, 0); |
634 | close_and_delete(fp, comp); |
|
|
635 | |
563 | |
636 | CLEAR_FLAG(op, FLAG_NO_FIX_PLAYER); |
564 | CLEAR_FLAG(op, FLAG_NO_FIX_PLAYER); |
637 | |
565 | |
638 | strncpy(pl->title, op->arch->clone.name, sizeof(pl->title)-1); |
566 | strncpy(pl->title, op->arch->clone.name, sizeof(pl->title)-1); |
639 | pl->title[sizeof(pl->title)-1] = '\0'; |
567 | pl->title[sizeof(pl->title)-1] = '\0'; |
… | |
… | |
644 | * First, we check for partial path, then check to see if the full |
572 | * First, we check for partial path, then check to see if the full |
645 | * path (for unique player maps) |
573 | * path (for unique player maps) |
646 | */ |
574 | */ |
647 | if (check_path(pl->maplevel,1)==-1) { |
575 | if (check_path(pl->maplevel,1)==-1) { |
648 | if (check_path(pl->maplevel,0)==-1) { |
576 | if (check_path(pl->maplevel,0)==-1) { |
649 | strcpy(pl->maplevel, pl->savebed_map); |
577 | strcpy(pl->maplevel, pl->savebed_map); |
650 | op->x = pl->bed_x, op->y = pl->bed_y; |
578 | op->x = pl->bed_x, op->y = pl->bed_y; |
651 | } |
579 | } |
652 | } |
|
|
653 | |
|
|
654 | /* If player saved beyond some time ago, and the feature is |
|
|
655 | * enabled, put the player back on his savebed map. |
|
|
656 | */ |
|
|
657 | if ((settings.reset_loc_time >0) && (elapsed_save_time > settings.reset_loc_time)) { |
|
|
658 | strcpy(pl->maplevel, pl->savebed_map); |
|
|
659 | op->x = pl->bed_x, op->y = pl->bed_y; |
|
|
660 | } |
580 | } |
661 | |
581 | |
662 | /* make sure he's a player--needed because of class change. */ |
582 | /* make sure he's a player--needed because of class change. */ |
663 | op->type = PLAYER; |
583 | op->type = PLAYER; |
664 | |
584 | |
… | |
… | |
685 | |
605 | |
686 | /* if it's a dragon player, set the correct title here */ |
606 | /* if it's a dragon player, set the correct title here */ |
687 | if (is_dragon_pl(op) && op->inv != NULL) { |
607 | if (is_dragon_pl(op) && op->inv != NULL) { |
688 | object *tmp, *abil=NULL, *skin=NULL; |
608 | object *tmp, *abil=NULL, *skin=NULL; |
689 | for (tmp=op->inv; tmp!=NULL; tmp=tmp->below) { |
609 | for (tmp=op->inv; tmp!=NULL; tmp=tmp->below) { |
690 | if (tmp->type == FORCE) { |
610 | if (tmp->type == FORCE) { |
691 | if (strcmp(tmp->arch->name, "dragon_ability_force")==0) |
611 | if (strcmp(tmp->arch->name, "dragon_ability_force")==0) |
692 | abil = tmp; |
612 | abil = tmp; |
693 | else if (strcmp(tmp->arch->name, "dragon_skin_force")==0) |
613 | else if (strcmp(tmp->arch->name, "dragon_skin_force")==0) |
694 | skin = tmp; |
614 | skin = tmp; |
695 | } |
615 | } |
696 | } |
616 | } |
697 | set_dragon_name(op, abil, skin); |
617 | set_dragon_name(op, abil, skin); |
698 | } |
618 | } |
699 | |
619 | |
700 | new_draw_info(NDI_UNIQUE, 0,op,"Welcome Back!"); |
620 | new_draw_info(NDI_UNIQUE, 0,op,"Welcome Back!"); |
701 | new_draw_info_format(NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, NULL, |
621 | new_draw_info_format(NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, NULL, |
702 | "%s has entered the game.",pl->ob->name); |
622 | "%s has entered the game.", &pl->ob->name); |
703 | |
623 | |
704 | execute_global_event (EVENT_PLAYER_LOAD, op, filename); |
624 | INVOKE_PLAYER (LOAD, pl, ARG_STRING (filename)); |
|
|
625 | INVOKE_PLAYER (LOGIN, pl); |
705 | |
626 | |
706 | /* Lauwenmark : Here we handle the LOGIN global event */ |
|
|
707 | execute_global_event(EVENT_LOGIN, pl, pl->socket.host); |
|
|
708 | op->contr->socket.update_look=1; |
627 | op->contr->socket.update_look=1; |
709 | /* If the player should be dead, call kill_player for them |
628 | /* If the player should be dead, call kill_player for them |
710 | * Only check for hp - if player lacks food, let the normal |
629 | * Only check for hp - if player lacks food, let the normal |
711 | * logic for that to take place. If player is permanently |
630 | * logic for that to take place. If player is permanently |
712 | * dead, and not using permadeath mode, the kill_player will |
631 | * dead, and not using permadeath mode, the kill_player will |
713 | * set the play_again flag, so return. |
632 | * set the play_again flag, so return. |
714 | */ |
633 | */ |
715 | if (op->stats.hp<0) { |
634 | if (op->stats.hp<0) { |
716 | new_draw_info(NDI_UNIQUE, 0,op,"Your character was dead last your played."); |
635 | new_draw_info(NDI_UNIQUE, 0,op,"Your character was dead last your played."); |
717 | kill_player(op); |
636 | kill_player(op); |
718 | if (pl->state != ST_PLAYING) return; |
637 | if (pl->state != ST_PLAYING) return; |
719 | } |
638 | } |
720 | LOG(llevInfo,"LOGIN: Player named %s from ip %s\n", op->name, |
639 | LOG(llevInfo,"LOGIN: Player named %s from ip %s\n", &op->name, op->contr->socket.host); |
721 | op->contr->socket.host); |
|
|
722 | |
640 | |
723 | /* Do this after checking for death - no reason sucking up bandwidth if |
641 | /* Do this after checking for death - no reason sucking up bandwidth if |
724 | * the data isn't needed. |
642 | * the data isn't needed. |
725 | */ |
643 | */ |
726 | esrv_new_player(op->contr,op->weight+op->carrying); |
644 | esrv_new_player(op->contr,op->weight+op->carrying); |