ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/login.C
Revision: 1.34
Committed: Sat Dec 23 13:56:25 2006 UTC (17 years, 5 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.33: +1 -3 lines
Log Message:
an experiment

File Contents

# Content
1 /*
2 CrossFire, A Multiplayer game for X-windows
3
4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
5 Copyright (C) 1992 Frank Tore Johansen
6
7 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 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 The authors can be reached via e-mail at <crossfire@schmorp.de>
22 */
23
24 #include <global.h>
25 #include <sproto.h>
26 #include <spells.h>
27 #include <loader.h>
28 #include <define.h>
29
30 extern void sub_weight (object *, signed long);
31 extern void add_weight (object *, signed long);
32 extern long pticks;
33
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 */
37 void
38 emergency_save (int flag)
39 {
40 trying_emergency_save = 1;
41
42 LOG (llevError, "Emergency save: ");
43 for_all_players (pl)
44 {
45 if (!pl->ob)
46 {
47 LOG (llevError, "No name, ignoring this.\n");
48 continue;
49 }
50
51 LOG (llevError, "%s ", &pl->ob->name);
52 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Emergency save...");
53
54 /* If we are not exiting the game (ie, this is sort of a backup save), then
55 * don't change the location back to the village. Note that there are other
56 * options to have backup saves be done at the starting village
57 */
58 if (!flag)
59 {
60 strcpy (pl->maplevel, first_map_path);
61
62 pl->ob->map = 0;
63 pl->ob->x = -1;
64 pl->ob->y = -1;
65 }
66
67 pl->save (1);
68 }
69
70 LOG (llevError, "\n");
71 }
72
73 /* Delete character with name. if new is set, also delete the new
74 * style directory, otherwise, just delete the old style playfile
75 * (needed for transition)
76 */
77 void
78 delete_character (const char *name, int newchar)
79 {
80 char buf[MAX_BUF];
81
82 sprintf (buf, "%s/%s/%s.pl", settings.localdir, settings.playerdir, name);
83
84 if (unlink (buf) == -1)
85 LOG (llevDebug, "Cannot delete character file %s: %s\n", buf, strerror (errno));
86
87 if (newchar)
88 {
89 sprintf (buf, "%s/%s/%s", settings.localdir, settings.playerdir, name);
90 /* this effectively does an rm -rf on the directory */
91 remove_directory (buf);
92 }
93 }
94
95 int
96 create_savedir_if_needed (char *savedir)
97 {
98 struct stat *buf;
99
100 if ((buf = (struct stat *) malloc (sizeof (struct stat))) == NULL)
101 {
102 LOG (llevError, "Unable to save playerfile... out of memory.\n");
103 return 0;
104 }
105 else
106 {
107 stat (savedir, buf);
108 if (!S_ISDIR (buf->st_mode))
109 if (mkdir (savedir, SAVE_DIR_MODE))
110 {
111 LOG (llevError, "Unable to create player savedir %s: %s\n", savedir, strerror (errno));
112 return 0;
113 }
114 free (buf);
115 }
116
117 return 1;
118 }
119
120 /*
121 * If final is set, it a clean/final save, not a backup, ie dont remove objects from inventory
122 */
123 void
124 player::save (bool final)
125 {
126 object *tmp, *container = 0;
127
128 /* Sanity check - some stuff changes this when player is exiting */
129 if (ob->type != PLAYER || !enable_save || !ns)
130 return;
131
132 INVOKE_PLAYER (SAVE, ob->contr);
133
134 object_freezer freezer;
135
136 int wiz = ob->flag [FLAG_WIZ];
137
138 /* Eneq(@csd.uu.se): If we have an open container hide it. */
139 container = ob->container;
140 ob->container = 0;
141
142 fprintf (freezer, "password %s\n", password);
143
144 if (own_title[0] != '\0')
145 fprintf (freezer, "title %s\n", own_title);
146
147 fprintf (freezer, "explore %d\n", explore);
148 fprintf (freezer, "gen_hp %d\n", gen_hp);
149 fprintf (freezer, "gen_sp %d\n", gen_sp);
150 fprintf (freezer, "gen_grace %d\n", gen_grace);
151 fprintf (freezer, "listening %d\n", listening);
152 fprintf (freezer, "shoottype %d\n", shoottype);
153 fprintf (freezer, "bowtype %d\n", bowtype);
154 fprintf (freezer, "petmode %d\n", petmode);
155 fprintf (freezer, "peaceful %d\n", peaceful);
156 fprintf (freezer, "digestion %d\n", digestion);
157 fprintf (freezer, "pickup %d\n", mode);
158 fprintf (freezer, "outputs_sync %d\n", outputs_sync);
159 fprintf (freezer, "outputs_count %d\n", outputs_count);
160 /* Match the enumerations but in string form */
161 fprintf (freezer, "usekeys %s\n", usekeys == key_inventory ? "key_inventory" : (usekeys == keyrings ? "keyrings" : "containers"));
162 /* Match the enumerations but in string form */
163 fprintf (freezer, "unapply %s\n", unapply == unapply_nochoice ? "unapply_nochoice" :
164 (unapply == unapply_never ? "unapply_never" : "unapply_always"));
165
166 if (ob->map)
167 fprintf (freezer, "map %s\n", ob->map->path);
168 else
169 fprintf (freezer, "map %s\n", settings.emergency_mapname);
170
171 fprintf (freezer, "savebed_map %s\n", savebed_map);
172 fprintf (freezer, "bed_x %d\nbed_y %d\n", bed_x, bed_y);
173 fprintf (freezer, "weapon_sp %f\n", weapon_sp);
174 fprintf (freezer, "Str %d\n", orig_stats.Str);
175 fprintf (freezer, "Dex %d\n", orig_stats.Dex);
176 fprintf (freezer, "Con %d\n", orig_stats.Con);
177 fprintf (freezer, "Int %d\n", orig_stats.Int);
178 fprintf (freezer, "Pow %d\n", orig_stats.Pow);
179 fprintf (freezer, "Wis %d\n", orig_stats.Wis);
180 fprintf (freezer, "Cha %d\n", orig_stats.Cha);
181
182 fprintf (freezer, "lev_array %d\n", ob->level > 10 ? 10 : ob->level);
183
184 for (int i = 1; i <= last_level && i <= 10; i++)
185 {
186 fprintf (freezer, "%d\n", levhp[i]);
187 fprintf (freezer, "%d\n", levsp[i]);
188 fprintf (freezer, "%d\n", levgrace[i]);
189 }
190
191 freezer.put (ob->contr);
192
193 fprintf (freezer, "endplst\n");
194
195 SET_FLAG (ob, FLAG_NO_FIX_PLAYER);
196 CLEAR_FLAG (ob, FLAG_WIZ);
197 save_object (freezer, ob, 3); /* don't check and don't remove */
198
199 char filename[MAX_BUF];
200
201 sprintf (filename, "%s/%s/%s/%s.pl", settings.localdir, settings.playerdir, &ob->name, &ob->name);
202 make_path_to_file (filename);
203 freezer.save (filename);
204
205 CLEAR_FLAG (ob, FLAG_NO_FIX_PLAYER);
206
207 /* Eneq(@csd.uu.se): Reveal the container if we have one. */
208 ob->container = container;
209
210 ob->flag [FLAG_WIZ] = wiz;
211
212 enable_save = !final;
213 }
214
215 player *
216 player::load (const char *path)
217 {
218 object_thawer thawer (path);
219
220 /* If no file, must be a new player, so lets get confirmation of
221 * the password. Return control to the higher level dispatch,
222 * since the rest of this just deals with loading of the file.
223 */
224 if (!thawer)
225 return 0;
226
227 player *pl = new player;
228
229 char buf[MAX_BUF], bufall[MAX_BUF];
230
231 pl->set_object (object::create ());
232 pl->last_save_time = time (0);
233
234 assign (pl->savebed_map, first_map_path);
235
236 /* Loop through the file, loading the rest of the values */
237 while (fgets (bufall, MAX_BUF, thawer))
238 {
239 int value;
240 sscanf (bufall, "%s %d\n", buf, &value);
241
242 if (!strcmp (buf, "endplst"))
243 break;
244 else if (!strcmp (buf, "oid"))
245 thawer.get (pl, value);
246 else if (!strcmp (buf, "password"))
247 sscanf (bufall, "password %[^\n]", pl->password);
248 else if (!strcmp (buf, "title"))
249 sscanf (bufall, "title %[^\n]", pl->own_title);
250 else if (!strcmp (buf, "explore"))
251 pl->explore = value;
252 else if (!strcmp (buf, "gen_hp"))
253 pl->gen_hp = value;
254 else if (!strcmp (buf, "shoottype"))
255 pl->shoottype = (rangetype) value;
256 else if (!strcmp (buf, "bowtype"))
257 pl->bowtype = (bowtype_t) value;
258 else if (!strcmp (buf, "petmode"))
259 pl->petmode = (petmode_t) value;
260 else if (!strcmp (buf, "gen_sp"))
261 pl->gen_sp = value;
262 else if (!strcmp (buf, "gen_grace"))
263 pl->gen_grace = value;
264 else if (!strcmp (buf, "listening"))
265 pl->listening = value;
266 else if (!strcmp (buf, "peaceful"))
267 pl->peaceful = value;
268 else if (!strcmp (buf, "digestion"))
269 pl->digestion = value;
270 else if (!strcmp (buf, "pickup"))
271 pl->mode = value;
272 else if (!strcmp (buf, "outputs_sync"))
273 pl->outputs_sync = value;
274 else if (!strcmp (buf, "outputs_count"))
275 pl->outputs_count = value;
276 else if (!strcmp (buf, "map"))
277 sscanf (bufall, "map %s", pl->maplevel);
278 else if (!strcmp (buf, "savebed_map"))
279 sscanf (bufall, "savebed_map %s", pl->savebed_map);
280 else if (!strcmp (buf, "bed_x"))
281 pl->bed_x = value;
282 else if (!strcmp (buf, "bed_y"))
283 pl->bed_y = value;
284 else if (!strcmp (buf, "weapon_sp"))
285 sscanf (buf, "weapon_sp %f", &pl->weapon_sp);
286 else if (!strcmp (buf, "Str"))
287 pl->orig_stats.Str = value;
288 else if (!strcmp (buf, "Dex"))
289 pl->orig_stats.Dex = value;
290 else if (!strcmp (buf, "Con"))
291 pl->orig_stats.Con = value;
292 else if (!strcmp (buf, "Int"))
293 pl->orig_stats.Int = value;
294 else if (!strcmp (buf, "Pow"))
295 pl->orig_stats.Pow = value;
296 else if (!strcmp (buf, "Wis"))
297 pl->orig_stats.Wis = value;
298 else if (!strcmp (buf, "Cha"))
299 pl->orig_stats.Cha = value;
300 else if (!strcmp (buf, "usekeys"))
301 {
302 if (!strcmp (bufall + 8, "key_inventory\n"))
303 pl->usekeys = key_inventory;
304 else if (!strcmp (bufall + 8, "keyrings\n"))
305 pl->usekeys = keyrings;
306 else if (!strcmp (bufall + 8, "containers\n"))
307 pl->usekeys = containers;
308 else
309 LOG (llevDebug, "load_player: got unknown usekeys type: %s\n", bufall + 8);
310 }
311 else if (!strcmp (buf, "unapply"))
312 {
313 if (!strcmp (bufall + 8, "unapply_nochoice\n"))
314 pl->unapply = unapply_nochoice;
315 else if (!strcmp (bufall + 8, "unapply_never\n"))
316 pl->unapply = unapply_never;
317 else if (!strcmp (bufall + 8, "unapply_always\n"))
318 pl->unapply = unapply_always;
319 else
320 LOG (llevDebug, "load_player: got unknown unapply type: %s\n", bufall + 8);
321 }
322 else if (!strcmp (buf, "lev_array"))
323 {
324 for (int i = 1; i <= value; i++)
325 {
326 char line[128];
327
328 fgets (line, 128, thawer);
329 pl->levhp[i] = atoi (line);
330 fgets (line, 128, thawer);
331 pl->levsp[i] = atoi (line);
332 fgets (line, 128, thawer);
333 pl->levgrace[i] = atoi (line);
334 }
335 /* spell_array code removed - don't know when that was last used.
336 * Even the load code below will someday be replaced by spells being
337 * objects.
338 */
339 }
340 else
341 LOG (llevDebug, "unparseable line in player file %s: %s\n", path, bufall);
342 }
343
344 /* this loads the standard objects values. */
345 load_object (thawer, pl->ob, 0);
346
347 /* If the map where the person was last saved does not exist,
348 * restart them on their home-savebed. This is good for when
349 * maps change between versions
350 * First, we check for partial path, then check to see if the full
351 * path (for unique player maps)
352 */
353 if (!has_been_loaded (pl->maplevel)
354 && check_path (pl->maplevel, 1) == -1
355 && check_path (pl->maplevel, 0) == -1)
356 {
357 strcpy (pl->maplevel, pl->savebed_map);
358 pl->ob->x = pl->bed_x, pl->ob->y = pl->bed_y;
359 }
360
361 pl->last_save_tick = pticks;
362
363 INVOKE_PLAYER (LOAD, pl, ARG_STRING (path));
364
365 return pl;
366 }
367