]> git.localhorst.tv Git - blank.git/blob - src/world/WorldSave.cpp
save and load world seed
[blank.git] / src / world / WorldSave.cpp
1 #include "WorldSave.hpp"
2
3 #include "../app/io.hpp"
4
5 #include <cctype>
6 #include <fstream>
7 #include <iostream>
8 #include <stdexcept>
9
10 using namespace std;
11
12
13 namespace blank {
14
15 WorldSave::WorldSave(const string &path)
16 : root_path(path)
17 , conf_path(path + "world.conf") {
18
19 }
20
21
22 bool WorldSave::Exists() const noexcept {
23         return is_dir(root_path) && is_file(conf_path);
24 }
25
26
27 void WorldSave::Create(const World::Config &conf) const {
28         cout << "creating world save" << endl;
29
30         if (!make_dirs(root_path)) {
31                 throw runtime_error("failed to create world save directory");
32         }
33
34         ofstream out(conf_path);
35         out << "seed = " << conf.gen.seed << endl;
36         out.close();
37
38         if (!out) {
39                 throw runtime_error("failed to write world config");
40         }
41 }
42
43 void WorldSave::Read(World::Config &conf) const {
44         cout << "reading world save" << endl;
45
46         ifstream in(conf_path);
47         if (!in) {
48                 throw runtime_error("failed to open world config");
49         }
50
51         constexpr char spaces[] = "\n\r\t ";
52
53         string line;
54         while (getline(in, line)) {
55                 if (line.empty() || line[0] == '#') continue;
56                 auto equals_pos = line.find_first_of('=');
57
58                 auto name_begin = line.find_first_not_of(spaces, 0, sizeof(spaces));
59                 auto name_end = equals_pos - 1;
60                 while (name_end > name_begin && isspace(line[name_end])) {
61                         --name_end;
62                 }
63
64                 auto value_begin = line.find_first_not_of(spaces, equals_pos + 1, sizeof(spaces));
65                 auto value_end = line.length() - 1;
66                 while (value_end > value_begin && isspace(line[value_end])) {
67                         --value_end;
68                 }
69
70                 string name(line, name_begin, name_end - name_begin + 1);
71                 string value(line, value_begin, value_end - value_begin + 1);
72
73                 if (name == "seed") {
74                         conf.gen.seed = stoul(value);
75                 } else {
76                         throw runtime_error("unknown world option: " + name);
77                 }
78         }
79         if (in.bad()) {
80                 throw runtime_error("IO error reading world config");
81         }
82 }
83
84 }