ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/login.C
Revision: 1.42
Committed: Thu Jan 4 19:28:38 2007 UTC (17 years, 5 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: last_stable
Changes since 1.41: +4 -12 lines
Log Message:
fix quit to actually delete the directory, should all be moved to perl

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 /* Delete character with name. if new is set, also delete the new
35 * style directory, otherwise, just delete the old style playfile
36 * (needed for transition)
37 */
38 void
39 delete_character (const char *name)
40 {
41 char buf[MAX_BUF];
42
43 sprintf (buf, "%s/%s/%s", settings.localdir, settings.playerdir, name);
44 /* this effectively does an rm -rf on the directory */
45 remove_directory (buf);
46 }
47
48 int
49 create_savedir_if_needed (char *savedir)
50 {
51 struct stat *buf;
52
53 if ((buf = (struct stat *) malloc (sizeof (struct stat))) == NULL)
54 {
55 LOG (llevError, "Unable to save playerfile... out of memory.\n");
56 return 0;
57 }
58 else
59 {
60 stat (savedir, buf);
61 if (!S_ISDIR (buf->st_mode))
62 if (mkdir (savedir, SAVE_DIR_MODE))
63 {
64 LOG (llevError, "Unable to create player savedir %s: %s\n", savedir, strerror (errno));
65 return 0;
66 }
67 free (buf);
68 }
69
70 return 1;
71 }
72
73 /*
74 * If final is set, it a clean/final save, not a backup, ie dont remove objects from inventory
75 */
76 void
77 player::save (bool final)
78 {
79 object *tmp, *container = 0;
80
81 /* Sanity check - some stuff changes this when player is exiting */
82 if (ob->type != PLAYER || !enable_save || !ns)
83 return;
84
85 char filename[MAX_BUF];
86
87 sprintf (filename, "%s/%s/%s/%s.pl", settings.localdir, settings.playerdir, &ob->name, &ob->name);
88 make_path_to_file (filename);
89
90 INVOKE_PLAYER (SAVE, ob->contr, ARG_STRING (filename));
91
92 object_freezer freezer;
93
94 int wiz = ob->flag [FLAG_WIZ];
95
96 /* Eneq(@csd.uu.se): If we have an open container hide it. */
97 container = ob->container;
98 ob->container = 0;
99
100 #define PL_OUT(k) freezer.put (KW_ ## k, k)
101 #define PL_OUT2(k,v) freezer.put (KW_ ## k, v)
102
103 PL_OUT (password);
104 PL_OUT2 (title, own_title);
105 PL_OUT (explore);
106 PL_OUT (gen_hp);
107 PL_OUT (gen_sp);
108 PL_OUT (gen_grace);
109 PL_OUT (listening);
110 PL_OUT (shoottype);
111 PL_OUT (bowtype);
112 PL_OUT (petmode);
113 PL_OUT (peaceful);
114 PL_OUT (digestion);
115 PL_OUT2 (pickup, mode);
116 PL_OUT (outputs_sync);
117 PL_OUT (outputs_count);
118
119 freezer.put (KW_usekeys, usekeys == key_inventory ? "key_inventory" : (usekeys == keyrings ? "keyrings" : "containers"));
120 freezer.put (KW_unapply, unapply == unapply_nochoice ? "unapply_nochoice" : (unapply == unapply_never ? "unapply_never" : "unapply_always"));
121
122 if (ob->map) PL_OUT2 (map, ob->map->path);
123
124 PL_OUT (savebed_map);
125 PL_OUT (bed_x);
126 PL_OUT (bed_y);
127 PL_OUT (weapon_sp);
128 PL_OUT2 (Str, orig_stats.Str);
129 PL_OUT2 (Dex, orig_stats.Dex);
130 PL_OUT2 (Con, orig_stats.Con);
131 PL_OUT2 (Int, orig_stats.Int);
132 PL_OUT2 (Pow, orig_stats.Pow);
133 PL_OUT2 (Wis, orig_stats.Wis);
134 PL_OUT2 (Cha, orig_stats.Cha);
135
136 PL_OUT2 (lev_array, min (ob->level, 10));
137
138 for (int i = 1; i <= last_level && i <= 10; i++)
139 {
140 fprintf (freezer, "%d\n", levhp[i]);
141 fprintf (freezer, "%d\n", levsp[i]);
142 fprintf (freezer, "%d\n", levgrace[i]);
143 }
144
145 freezer.put (ob->contr);
146 freezer.put (KW_endplst);
147
148 SET_FLAG (ob, FLAG_NO_FIX_PLAYER);
149 CLEAR_FLAG (ob, FLAG_WIZ);
150 save_object (freezer, ob, 1); /* don't check and don't remove */
151
152 freezer.save (filename);
153
154 CLEAR_FLAG (ob, FLAG_NO_FIX_PLAYER);
155
156 /* Eneq(@csd.uu.se): Reveal the container if we have one. */
157 ob->container = container;
158
159 ob->flag [FLAG_WIZ] = wiz;
160
161 enable_save = !final;
162
163 INVOKE_PLAYER (SAVE_DONE, ob->contr, ARG_STRING (filename));
164 }
165
166 player *
167 player::load (const char *path)
168 {
169 object_thawer thawer (path);
170
171 /* If no file, must be a new player, so lets get confirmation of
172 * the password. Return control to the higher level dispatch,
173 * since the rest of this just deals with loading of the file.
174 */
175 if (!thawer)
176 return 0;
177
178 player *pl = new player;
179
180 char buf[MAX_BUF], bufall[MAX_BUF];
181
182 pl->set_object (object::create ());
183 pl->last_save_time = time (0);
184
185 pl->savebed_map = first_map_path;
186
187 /* Loop through the file, loading the rest of the values */
188 for (;;)
189 {
190 keyword kw = thawer.get_kv ();
191
192 switch (kw)
193 {
194 case KW_EOF:
195 LOG (llevError, "%s: error while reading player header\n", path);
196 return 0;
197
198 case KW_ERROR:
199 LOG (llevError, "%s: error while reading player header, skipping (%s,%s)\n", path, thawer.last_keyword, thawer.last_value);
200 break;
201
202 case KW_endplst:
203 goto done;
204
205 case KW_oid: thawer.get (pl, thawer.get_sint32 ()); break;
206 case KW_password: assign (pl->password , thawer.get_str ()); break;
207 case KW_title: assign (pl->own_title, thawer.get_str ()); break;
208 case KW_shoottype: pl->shoottype = (rangetype) thawer.get_sint32 (); break;
209 case KW_bowtype: pl->bowtype = (bowtype_t) thawer.get_sint32 (); break;
210 case KW_petmode: pl->petmode = (petmode_t) thawer.get_sint32 (); break;
211 case KW_explore: thawer.get (pl->explore); break;
212 case KW_listening: thawer.get (pl->listening); break;
213 case KW_peaceful: thawer.get (pl->peaceful); break;
214 case KW_digestion: thawer.get (pl->digestion); break;
215 case KW_pickup: thawer.get (pl->mode); break;
216 case KW_outputs_sync: thawer.get (pl->outputs_sync); break;
217 case KW_outputs_count: thawer.get (pl->outputs_count); break;
218 case KW_map: thawer.get (pl->maplevel); break;
219 case KW_savebed_map: thawer.get (pl->savebed_map); break;
220 case KW_bed_x: thawer.get (pl->bed_x); break;
221 case KW_bed_y: thawer.get (pl->bed_y); break;
222 case KW_weapon_sp: thawer.get (pl->weapon_sp); break;
223 case KW_Str: thawer.get (pl->orig_stats.Str); break;
224 case KW_Dex: thawer.get (pl->orig_stats.Dex); break;
225 case KW_Con: thawer.get (pl->orig_stats.Con); break;
226 case KW_Int: thawer.get (pl->orig_stats.Int); break;
227 case KW_Pow: thawer.get (pl->orig_stats.Pow); break;
228 case KW_Wis: thawer.get (pl->orig_stats.Wis); break;
229 case KW_Cha: thawer.get (pl->orig_stats.Cha); break;
230 case KW_gen_hp: thawer.get (pl->gen_hp); break;
231 case KW_gen_sp: thawer.get (pl->gen_sp); break;
232 case KW_gen_grace: thawer.get (pl->gen_grace); break;
233
234 case KW_usekeys:
235 if (!strcmp (thawer.get_str (), "key_inventory"))
236 pl->usekeys = key_inventory;
237 else if (!strcmp (thawer.get_str (), "keyrings"))
238 pl->usekeys = keyrings;
239 else if (!strcmp (thawer.get_str (), "containers"))
240 pl->usekeys = containers;
241 else
242 LOG (llevDebug, "load_player: got unknown usekeys type: %s\n", thawer.get_str ());
243 break;
244
245 case KW_unapply:
246 if (!strcmp (thawer.get_str (), "unapply_nochoice"))
247 pl->unapply = unapply_nochoice;
248 else if (!strcmp (thawer.get_str (), "unapply_never"))
249 pl->unapply = unapply_never;
250 else if (!strcmp (thawer.get_str (), "unapply_always"))
251 pl->unapply = unapply_always;
252 else
253 LOG (llevDebug, "load_player: got unknown unapply type: %s\n", thawer.get_str ());
254 break;
255
256 case KW_lev_array:
257 {
258 int count = thawer.get_sint32 ();
259
260 for (int i = 1; i <= count; i++)
261 {
262 char line[128];
263
264 fgets (line, 128, thawer); pl->levhp [i] = atoi (line);
265 fgets (line, 128, thawer); pl->levsp [i] = atoi (line);
266 fgets (line, 128, thawer); pl->levgrace[i] = atoi (line);
267 }
268 }
269 break;
270
271 default:
272 LOG (llevError, "%s: skipping unknown key in player header: %s\n", path, keyword_str [kw]);
273 break;
274 }
275 }
276
277 done:
278 /* this loads the standard objects values. */
279 load_object (thawer, pl->ob, 0);
280
281 pl->last_save_tick = pticks;
282
283 INVOKE_PLAYER (LOAD, pl, ARG_STRING (path));
284
285 return pl;
286 }
287