ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/login.C
(Generate patch)

Comparing deliantra/server/server/login.C (file contents):
Revision 1.31 by root, Sat Dec 23 03:38:43 2006 UTC vs.
Revision 1.43 by pippijn, Sat Jan 6 14:42:30 2007 UTC

1/* 1/*
2 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
3 3
4 Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 5 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
5 Copyright (C) 1992 Frank Tore Johansen 6 Copyright (C) 1992 Frank Tore Johansen
6 7
7 This program is free software; you can redistribute it and/or modify 8 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 9 it under the terms of the GNU General Public License as published by
29 30
30extern void sub_weight (object *, signed long); 31extern void sub_weight (object *, signed long);
31extern void add_weight (object *, signed long); 32extern void add_weight (object *, signed long);
32extern long pticks; 33extern long pticks;
33 34
34/* If flag is non zero, it means that we want to try and save everyone, but
35 * keep the game running. Thus, we don't want to free any information.
36 */
37void
38emergency_save (int flag)
39{
40 player *pl;
41
42 trying_emergency_save = 1;
43
44 LOG (llevError, "Emergency save: ");
45 for (pl = first_player; pl; pl = pl->next)
46 {
47 if (!pl->ob)
48 {
49 LOG (llevError, "No name, ignoring this.\n");
50 continue;
51 }
52
53 LOG (llevError, "%s ", &pl->ob->name);
54 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Emergency save...");
55
56 /* If we are not exiting the game (ie, this is sort of a backup save), then
57 * don't change the location back to the village. Note that there are other
58 * options to have backup saves be done at the starting village
59 */
60 if (!flag)
61 {
62 strcpy (pl->maplevel, first_map_path);
63
64 pl->ob->map = 0;
65 pl->ob->x = -1;
66 pl->ob->y = -1;
67 }
68
69 pl->save (1);
70 }
71
72 LOG (llevError, "\n");
73}
74
75/* Delete character with name. if new is set, also delete the new 35/* Delete character with name. if new is set, also delete the new
76 * style directory, otherwise, just delete the old style playfile 36 * style directory, otherwise, just delete the old style playfile
77 * (needed for transition) 37 * (needed for transition)
78 */ 38 */
79void 39void
80delete_character (const char *name, int newchar) 40delete_character (const char *name)
81{ 41{
82 char buf[MAX_BUF]; 42 char buf[MAX_BUF];
83 43
84 sprintf (buf, "%s/%s/%s.pl", settings.localdir, settings.playerdir, name); 44 sprintf (buf, "%s/%s/%s", settings.localdir, settings.playerdir, name);
85
86 if (unlink (buf) == -1)
87 LOG (llevDebug, "Cannot delete character file %s: %s\n", buf, strerror (errno));
88
89 if (newchar)
90 {
91 sprintf (buf, "%s/%s/%s", settings.localdir, settings.playerdir, name);
92 /* this effectively does an rm -rf on the directory */ 45 /* this effectively does an rm -rf on the directory */
93 remove_directory (buf); 46 remove_directory (buf);
94 }
95} 47}
96 48
97int 49int
98create_savedir_if_needed (char *savedir) 50create_savedir_if_needed (char *savedir)
99{ 51{
129 81
130 /* Sanity check - some stuff changes this when player is exiting */ 82 /* Sanity check - some stuff changes this when player is exiting */
131 if (ob->type != PLAYER || !enable_save || !ns) 83 if (ob->type != PLAYER || !enable_save || !ns)
132 return; 84 return;
133 85
134 INVOKE_PLAYER (SAVE, ob->contr); 86 char filename[MAX_BUF];
87
88 sprintf (filename, "%s/%s/%s/%s.pl", settings.localdir, settings.playerdir, &ob->name, &ob->name);
89 make_path_to_file (filename);
90
91 INVOKE_PLAYER (SAVE, ob->contr, ARG_STRING (filename));
135 92
136 object_freezer freezer; 93 object_freezer freezer;
137 94
138 int wiz = ob->flags [FLAG_WIZ]; 95 int wiz = ob->flag [FLAG_WIZ];
139 96
140 /* Eneq(@csd.uu.se): If we have an open container hide it. */ 97 /* Eneq(@csd.uu.se): If we have an open container hide it. */
141 container = ob->container; 98 container = ob->container;
142 ob->container = 0; 99 ob->container = 0;
143 100
144 fprintf (freezer, "password %s\n", password); 101#define PL_OUT(k) freezer.put (KW_ ## k, k)
102#define PL_OUT2(k,v) freezer.put (KW_ ## k, v)
145 103
146 if (own_title[0] != '\0') 104 PL_OUT (password);
147 fprintf (freezer, "title %s\n", own_title); 105 PL_OUT2 (title, own_title);
106 PL_OUT (explore);
107 PL_OUT (gen_hp);
108 PL_OUT (gen_sp);
109 PL_OUT (gen_grace);
110 PL_OUT (listening);
111 PL_OUT (shoottype);
112 PL_OUT (bowtype);
113 PL_OUT (petmode);
114 PL_OUT (peaceful);
115 PL_OUT (digestion);
116 PL_OUT2 (pickup, mode);
117 PL_OUT (outputs_sync);
118 PL_OUT (outputs_count);
148 119
149 fprintf (freezer, "explore %d\n", explore);
150 fprintf (freezer, "gen_hp %d\n", gen_hp);
151 fprintf (freezer, "gen_sp %d\n", gen_sp);
152 fprintf (freezer, "gen_grace %d\n", gen_grace);
153 fprintf (freezer, "listening %d\n", listening);
154 fprintf (freezer, "shoottype %d\n", shoottype);
155 fprintf (freezer, "bowtype %d\n", bowtype);
156 fprintf (freezer, "petmode %d\n", petmode);
157 fprintf (freezer, "peaceful %d\n", peaceful);
158 fprintf (freezer, "digestion %d\n", digestion);
159 fprintf (freezer, "pickup %d\n", mode);
160 fprintf (freezer, "outputs_sync %d\n", outputs_sync);
161 fprintf (freezer, "outputs_count %d\n", outputs_count);
162 /* Match the enumerations but in string form */
163 fprintf (freezer, "usekeys %s\n", usekeys == key_inventory ? "key_inventory" : (usekeys == keyrings ? "keyrings" : "containers")); 120 freezer.put (KW_usekeys, usekeys == key_inventory ? "key_inventory" : (usekeys == keyrings ? "keyrings" : "containers"));
164 /* Match the enumerations but in string form */ 121 freezer.put (KW_unapply, unapply == unapply_nochoice ? "unapply_nochoice" : (unapply == unapply_never ? "unapply_never" : "unapply_always"));
165 fprintf (freezer, "unapply %s\n", unapply == unapply_nochoice ? "unapply_nochoice" :
166 (unapply == unapply_never ? "unapply_never" : "unapply_always"));
167 122
168 if (ob->map) 123 if (ob->map) PL_OUT2 (map, ob->map->path);
169 fprintf (freezer, "map %s\n", ob->map->path);
170 else
171 fprintf (freezer, "map %s\n", settings.emergency_mapname);
172 124
173 fprintf (freezer, "savebed_map %s\n", savebed_map); 125 PL_OUT (savebed_map);
174 fprintf (freezer, "bed_x %d\nbed_y %d\n", bed_x, bed_y); 126 PL_OUT (bed_x);
175 fprintf (freezer, "weapon_sp %f\n", weapon_sp); 127 PL_OUT (bed_y);
176 fprintf (freezer, "Str %d\n", orig_stats.Str); 128 PL_OUT (weapon_sp);
177 fprintf (freezer, "Dex %d\n", orig_stats.Dex); 129 PL_OUT2 (Str, orig_stats.Str);
178 fprintf (freezer, "Con %d\n", orig_stats.Con); 130 PL_OUT2 (Dex, orig_stats.Dex);
179 fprintf (freezer, "Int %d\n", orig_stats.Int); 131 PL_OUT2 (Con, orig_stats.Con);
180 fprintf (freezer, "Pow %d\n", orig_stats.Pow); 132 PL_OUT2 (Int, orig_stats.Int);
181 fprintf (freezer, "Wis %d\n", orig_stats.Wis); 133 PL_OUT2 (Pow, orig_stats.Pow);
182 fprintf (freezer, "Cha %d\n", orig_stats.Cha); 134 PL_OUT2 (Wis, orig_stats.Wis);
135 PL_OUT2 (Cha, orig_stats.Cha);
183 136
184 fprintf (freezer, "lev_array %d\n", ob->level > 10 ? 10 : ob->level); 137 PL_OUT2 (lev_array, min (ob->level, 10));
185 138
186 for (int i = 1; i <= last_level && i <= 10; i++) 139 for (int i = 1; i <= last_level && i <= 10; i++)
187 { 140 {
188 fprintf (freezer, "%d\n", levhp[i]); 141 fprintf (freezer, "%d\n", levhp[i]);
189 fprintf (freezer, "%d\n", levsp[i]); 142 fprintf (freezer, "%d\n", levsp[i]);
190 fprintf (freezer, "%d\n", levgrace[i]); 143 fprintf (freezer, "%d\n", levgrace[i]);
191 } 144 }
192 145
193 freezer.put (ob->contr); 146 freezer.put (ob->contr);
194 147 freezer.put (KW_endplst);
195 fprintf (freezer, "endplst\n");
196 148
197 SET_FLAG (ob, FLAG_NO_FIX_PLAYER); 149 SET_FLAG (ob, FLAG_NO_FIX_PLAYER);
198 CLEAR_FLAG (ob, FLAG_WIZ); 150 CLEAR_FLAG (ob, FLAG_WIZ);
199 save_object (freezer, ob, 3); /* don't check and don't remove */ 151 save_object (freezer, ob, 1); /* don't check and don't remove */
200 152
201 char filename[MAX_BUF];
202
203 sprintf (filename, "%s/%s/%s/%s.pl", settings.localdir, settings.playerdir, &ob->name, &ob->name);
204 make_path_to_file (filename);
205 freezer.save (filename); 153 freezer.save (filename);
206 154
207 CLEAR_FLAG (ob, FLAG_NO_FIX_PLAYER); 155 CLEAR_FLAG (ob, FLAG_NO_FIX_PLAYER);
208 156
209 /* Eneq(@csd.uu.se): Reveal the container if we have one. */ 157 /* Eneq(@csd.uu.se): Reveal the container if we have one. */
210 ob->container = container; 158 ob->container = container;
211 159
212 ob->flags [FLAG_WIZ] = wiz; 160 ob->flag [FLAG_WIZ] = wiz;
213 161
214 enable_save = !final; 162 enable_save = !final;
163
164 INVOKE_PLAYER (SAVE_DONE, ob->contr, ARG_STRING (filename));
215} 165}
216 166
217player * 167player *
218player::load (const char *path) 168player::load (const char *path)
219{ 169{
230 180
231 char buf[MAX_BUF], bufall[MAX_BUF]; 181 char buf[MAX_BUF], bufall[MAX_BUF];
232 182
233 pl->set_object (object::create ()); 183 pl->set_object (object::create ());
234 pl->last_save_time = time (0); 184 pl->last_save_time = time (0);
235 pl->name_changed = 1;
236 185
237 assign (pl->savebed_map, first_map_path); 186 pl->savebed_map = first_map_path;
238 187
239 /* Loop through the file, loading the rest of the values */ 188 /* Loop through the file, loading the rest of the values */
240 while (fgets (bufall, MAX_BUF, thawer)) 189 for (;;)
241 { 190 {
242 int value; 191 keyword kw = thawer.get_kv ();
243 sscanf (bufall, "%s %d\n", buf, &value);
244 192
245 if (!strcmp (buf, "endplst")) 193 switch (kw)
246 break;
247 else if (!strcmp (buf, "oid"))
248 thawer.get (pl, value);
249 else if (!strcmp (buf, "password"))
250 sscanf (bufall, "password %[^\n]", pl->password);
251 else if (!strcmp (buf, "title"))
252 sscanf (bufall, "title %[^\n]", pl->own_title);
253 else if (!strcmp (buf, "explore"))
254 pl->explore = value;
255 else if (!strcmp (buf, "gen_hp"))
256 pl->gen_hp = value;
257 else if (!strcmp (buf, "shoottype"))
258 pl->shoottype = (rangetype) value;
259 else if (!strcmp (buf, "bowtype"))
260 pl->bowtype = (bowtype_t) value;
261 else if (!strcmp (buf, "petmode"))
262 pl->petmode = (petmode_t) value;
263 else if (!strcmp (buf, "gen_sp"))
264 pl->gen_sp = value;
265 else if (!strcmp (buf, "gen_grace"))
266 pl->gen_grace = value;
267 else if (!strcmp (buf, "listening"))
268 pl->listening = value;
269 else if (!strcmp (buf, "peaceful"))
270 pl->peaceful = value;
271 else if (!strcmp (buf, "digestion"))
272 pl->digestion = value;
273 else if (!strcmp (buf, "pickup"))
274 pl->mode = value;
275 else if (!strcmp (buf, "outputs_sync"))
276 pl->outputs_sync = value;
277 else if (!strcmp (buf, "outputs_count"))
278 pl->outputs_count = value;
279 else if (!strcmp (buf, "map"))
280 sscanf (bufall, "map %s", pl->maplevel);
281 else if (!strcmp (buf, "savebed_map"))
282 sscanf (bufall, "savebed_map %s", pl->savebed_map);
283 else if (!strcmp (buf, "bed_x"))
284 pl->bed_x = value;
285 else if (!strcmp (buf, "bed_y"))
286 pl->bed_y = value;
287 else if (!strcmp (buf, "weapon_sp"))
288 sscanf (buf, "weapon_sp %f", &pl->weapon_sp);
289 else if (!strcmp (buf, "Str"))
290 pl->orig_stats.Str = value;
291 else if (!strcmp (buf, "Dex"))
292 pl->orig_stats.Dex = value;
293 else if (!strcmp (buf, "Con"))
294 pl->orig_stats.Con = value;
295 else if (!strcmp (buf, "Int"))
296 pl->orig_stats.Int = value;
297 else if (!strcmp (buf, "Pow"))
298 pl->orig_stats.Pow = value;
299 else if (!strcmp (buf, "Wis"))
300 pl->orig_stats.Wis = value;
301 else if (!strcmp (buf, "Cha"))
302 pl->orig_stats.Cha = value;
303 else if (!strcmp (buf, "usekeys"))
304 { 194 {
305 if (!strcmp (bufall + 8, "key_inventory\n")) 195 case KW_EOF:
196 LOG (llevError, "%s: error while reading player header\n", path);
197 return 0;
198
199 case KW_ERROR:
200 LOG (llevError, "%s: error while reading player header, skipping (%s,%s)\n", path, thawer.last_keyword, thawer.last_value);
201 break;
202
203 case KW_endplst:
204 goto done;
205
206 case KW_oid: thawer.get (pl, thawer.get_sint32 ()); break;
207 case KW_password: assign (pl->password , thawer.get_str ()); break;
208 case KW_title: assign (pl->own_title, thawer.get_str ()); break;
209 case KW_shoottype: pl->shoottype = (rangetype) thawer.get_sint32 (); break;
210 case KW_bowtype: pl->bowtype = (bowtype_t) thawer.get_sint32 (); break;
211 case KW_petmode: pl->petmode = (petmode_t) thawer.get_sint32 (); break;
212 case KW_explore: thawer.get (pl->explore); break;
213 case KW_listening: thawer.get (pl->listening); break;
214 case KW_peaceful: thawer.get (pl->peaceful); break;
215 case KW_digestion: thawer.get (pl->digestion); break;
216 case KW_pickup: thawer.get (pl->mode); break;
217 case KW_outputs_sync: thawer.get (pl->outputs_sync); break;
218 case KW_outputs_count: thawer.get (pl->outputs_count); break;
219 case KW_map: thawer.get (pl->maplevel); break;
220 case KW_savebed_map: thawer.get (pl->savebed_map); break;
221 case KW_bed_x: thawer.get (pl->bed_x); break;
222 case KW_bed_y: thawer.get (pl->bed_y); break;
223 case KW_weapon_sp: thawer.get (pl->weapon_sp); break;
224 case KW_Str: thawer.get (pl->orig_stats.Str); break;
225 case KW_Dex: thawer.get (pl->orig_stats.Dex); break;
226 case KW_Con: thawer.get (pl->orig_stats.Con); break;
227 case KW_Int: thawer.get (pl->orig_stats.Int); break;
228 case KW_Pow: thawer.get (pl->orig_stats.Pow); break;
229 case KW_Wis: thawer.get (pl->orig_stats.Wis); break;
230 case KW_Cha: thawer.get (pl->orig_stats.Cha); break;
231 case KW_gen_hp: thawer.get (pl->gen_hp); break;
232 case KW_gen_sp: thawer.get (pl->gen_sp); break;
233 case KW_gen_grace: thawer.get (pl->gen_grace); break;
234
235 case KW_usekeys:
236 if (!strcmp (thawer.get_str (), "key_inventory"))
306 pl->usekeys = key_inventory; 237 pl->usekeys = key_inventory;
307 else if (!strcmp (bufall + 8, "keyrings\n")) 238 else if (!strcmp (thawer.get_str (), "keyrings"))
308 pl->usekeys = keyrings; 239 pl->usekeys = keyrings;
309 else if (!strcmp (bufall + 8, "containers\n")) 240 else if (!strcmp (thawer.get_str (), "containers"))
310 pl->usekeys = containers; 241 pl->usekeys = containers;
311 else 242 else
312 LOG (llevDebug, "load_player: got unknown usekeys type: %s\n", bufall + 8); 243 LOG (llevDebug, "load_player: got unknown usekeys type: %s\n", thawer.get_str ());
244 break;
245
246 case KW_unapply:
247 if (!strcmp (thawer.get_str (), "unapply_nochoice"))
248 pl->unapply = unapply_nochoice;
249 else if (!strcmp (thawer.get_str (), "unapply_never"))
250 pl->unapply = unapply_never;
251 else if (!strcmp (thawer.get_str (), "unapply_always"))
252 pl->unapply = unapply_always;
253 else
254 LOG (llevDebug, "load_player: got unknown unapply type: %s\n", thawer.get_str ());
255 break;
256
257 case KW_lev_array:
258 {
259 int count = thawer.get_sint32 ();
260
261 for (int i = 1; i <= count; i++)
262 {
263 char line[128];
264
265 fgets (line, 128, thawer); pl->levhp [i] = atoi (line);
266 fgets (line, 128, thawer); pl->levsp [i] = atoi (line);
267 fgets (line, 128, thawer); pl->levgrace[i] = atoi (line);
268 }
269 }
270 break;
271
272 default:
273 LOG (llevError, "%s: skipping unknown key in player header: %s\n", path, keyword_str [kw]);
274 break;
313 } 275 }
314 else if (!strcmp (buf, "unapply"))
315 {
316 if (!strcmp (bufall + 8, "unapply_nochoice\n"))
317 pl->unapply = unapply_nochoice;
318 else if (!strcmp (bufall + 8, "unapply_never\n"))
319 pl->unapply = unapply_never;
320 else if (!strcmp (bufall + 8, "unapply_always\n"))
321 pl->unapply = unapply_always;
322 else
323 LOG (llevDebug, "load_player: got unknown unapply type: %s\n", bufall + 8);
324 }
325 else if (!strcmp (buf, "lev_array"))
326 {
327 for (int i = 1; i <= value; i++)
328 {
329 char line[128];
330
331 fgets (line, 128, thawer);
332 pl->levhp[i] = atoi (line);
333 fgets (line, 128, thawer);
334 pl->levsp[i] = atoi (line);
335 fgets (line, 128, thawer);
336 pl->levgrace[i] = atoi (line);
337 }
338 /* spell_array code removed - don't know when that was last used.
339 * Even the load code below will someday be replaced by spells being
340 * objects.
341 */
342 }
343 else
344 LOG (llevDebug, "unparseable line in player file %s: %s\n", path, bufall);
345 } 276 }
346 277
278done:
347 /* this loads the standard objects values. */ 279 /* this loads the standard objects values. */
348 load_object (thawer, pl->ob, 0); 280 load_object (thawer, pl->ob, 0);
349 281
350 /* If the map where the person was last saved does not exist,
351 * restart them on their home-savebed. This is good for when
352 * maps change between versions
353 * First, we check for partial path, then check to see if the full
354 * path (for unique player maps)
355 */
356 if (!has_been_loaded (pl->maplevel)
357 && check_path (pl->maplevel, 1) == -1
358 && check_path (pl->maplevel, 0) == -1)
359 {
360 strcpy (pl->maplevel, pl->savebed_map);
361 pl->ob->x = pl->bed_x, pl->ob->y = pl->bed_y;
362 }
363
364 /* make sure he's a player -- needed because of class change. */
365 pl->name_changed = 1;
366 pl->last_save_tick = pticks; 282 pl->last_save_tick = pticks;
367 283
368 INVOKE_PLAYER (LOAD, pl, ARG_STRING (path)); 284 INVOKE_PLAYER (LOAD, pl, ARG_STRING (path));
369 285
370 return pl; 286 return pl;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines