• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Return-To-The-Roots / s25client / 14201549551

01 Apr 2025 04:58PM UTC coverage: 50.307% (+0.02%) from 50.288%
14201549551

Pull #1750

github

web-flow
Merge 4a407ae29 into c8cf430f2
Pull Request #1750: Fix size of Settings window

8 of 26 new or added lines in 15 files covered. (30.77%)

2 existing lines in 1 file now uncovered.

22368 of 44463 relevant lines covered (50.31%)

34399.1 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.96
/libs/s25main/SavedFile.cpp
1
// Copyright (C) 2005 - 2024 Settlers Freaks (sf-team at siedler25.org)
2
//
3
// SPDX-License-Identifier: GPL-2.0-or-later
4

5
#include "SavedFile.h"
6
#include "BasePlayerInfo.h"
7
#include "RTTR_Version.h"
8
#include "enum_cast.hpp"
9
#include "libendian/ConvertEndianess.h"
10
#include "s25util/BinaryFile.h"
11
#include "s25util/Serializer.h"
12
#include <boost/format.hpp>
13
#include <algorithm>
14
#include <mygettext/mygettext.h>
15
#include <stdexcept>
16

17
SavedFile::SavedFile() : saveTime_(0)
18✔
18
{
19
    const std::string rev = rttr::version::GetRevision();
18✔
20
    std::copy(rev.begin(), rev.begin() + revision.size(), revision.begin());
18✔
21
}
18✔
22

23
SavedFile::~SavedFile() = default;
18✔
24

25
void SavedFile::WriteFileHeader(BinaryFile& file) const
7✔
26
{
27
    // Signature
28
    const std::string signature = GetSignature();
14✔
29
    file.WriteRawData(signature.c_str(), signature.length());
7✔
30
    // Format version
31
    file.WriteUnsignedShort(GetVersion());
7✔
32
}
7✔
33

34
void SavedFile::WriteExtHeader(BinaryFile& file, const std::string& mapName)
6✔
35
{
36
    // Store data in struct
37
    saveTime_ = s25util::Time::CurrentTime();
6✔
38
    mapName_ = mapName;
6✔
39

40
    // Program version
41
    file.WriteRawData(&revision[0], revision.size());
6✔
42
    s25util::time64_t tmpTime = libendian::ConvertEndianess<false>::fromNative(saveTime_);
6✔
43
    file.WriteRawData(&tmpTime, sizeof(tmpTime));
6✔
44
    file.WriteShortString(mapName);
6✔
45
    file.WriteUnsignedInt(playerNames_.size());
6✔
46
    for(const std::string& name : playerNames_)
24✔
47
        file.WriteShortString(name);
18✔
48
}
6✔
49

50
bool SavedFile::ReadFileHeader(BinaryFile& file)
12✔
51
{
52
    lastErrorMsg.clear();
12✔
53

54
    const std::string signature = GetSignature();
24✔
55
    std::array<char, 32> read_signature;
56
    if(signature.size() > read_signature.size())
12✔
57
        throw std::range_error("Program signature is to long!");
×
58
    try
59
    {
60
        file.ReadRawData(&read_signature[0], signature.size());
12✔
61

62
        // Signatur überprüfen
63
        if(!std::equal(signature.begin(), signature.end(), read_signature.begin()))
12✔
64
        {
65
            lastErrorMsg = _("File is not in a valid format!");
×
66
            return false;
×
67
        }
68

69
        // Version überprüfen
70
        uint16_t read_version = file.ReadUnsignedShort();
12✔
71
        if(read_version != GetVersion())
12✔
72
        {
73
            boost::format fmt = boost::format(
74
              (read_version < GetVersion()) ?
×
75
                _("File has an old version and cannot be used (version: %1%, expected: %2%)!") :
×
76
                _("File was created with more recent program and cannot be used (version: %1%, expected: %2%)!"));
×
77
            lastErrorMsg = (fmt % read_version % GetVersion()).str();
×
78
            return false;
×
79
        }
NEW
80
    } catch(const std::runtime_error& e)
×
81
    {
82
        lastErrorMsg = e.what();
×
83
        return false;
×
84
    }
85

86
    return true;
12✔
87
}
88

89
bool SavedFile::ReadExtHeader(BinaryFile& file)
10✔
90
{
91
    file.ReadRawData(&revision[0], revision.size());
10✔
92
    file.ReadRawData(&saveTime_, sizeof(saveTime_));
10✔
93
    saveTime_ = libendian::ConvertEndianess<false>::toNative(saveTime_);
10✔
94
    mapName_ = file.ReadShortString();
10✔
95
    playerNames_.resize(file.ReadUnsignedInt());
10✔
96
    for(std::string& name : playerNames_)
40✔
97
        name = file.ReadShortString();
30✔
98
    return true;
10✔
99
}
100

101
void SavedFile::WriteAllHeaderData(BinaryFile& file, const std::string& mapName)
6✔
102
{
103
    // Versionszeug schreiben
104
    WriteFileHeader(file);
6✔
105
    WriteExtHeader(file, mapName);
6✔
106
}
6✔
107

108
bool SavedFile::ReadAllHeaderData(BinaryFile& file)
10✔
109
{
110
    if(!ReadFileHeader(file))
10✔
111
        return false;
×
112
    if(!ReadExtHeader(file))
10✔
113
        return false;
×
114
    return true;
10✔
115
}
116

117
void SavedFile::WritePlayerData(BinaryFile& file)
6✔
118
{
119
    Serializer ser;
12✔
120
    ser.PushUnsignedChar(players.size());
6✔
121
    for(const auto& player : players)
29✔
122
        player.Serialize(ser, true);
23✔
123

124
    ser.WriteToFile(file);
6✔
125
}
6✔
126

127
void SavedFile::ReadPlayerData(BinaryFile& file)
7✔
128
{
129
    ClearPlayers();
7✔
130
    Serializer ser;
14✔
131
    ser.ReadFromFile(file);
7✔
132
    const unsigned playerCt = ser.PopUnsignedChar();
7✔
133
    players.reserve(playerCt);
7✔
134
    for(unsigned i = 0; i < playerCt; i++)
34✔
135
    {
136
        BasePlayerInfo player(ser, true);
54✔
137
        // Temporary workaround: The random team was stored in the file but should not anymore, see PR #1331
138
        if(player.team > Team::Team4)
27✔
139
            player.team = Team(rttr::enum_cast(player.team) - 3); // Was random team 2-4
×
140
        else if(player.team == Team::Random)
27✔
141
            player.team = Team::Team1; // Was random team 1
×
142
        AddPlayer(player);
27✔
143
    }
144
}
7✔
145

146
/**
147
 *  schreibt die GlobalGameSettings in die Datei.
148
 */
149
void SavedFile::WriteGGS(BinaryFile& file) const
6✔
150
{
151
    Serializer ser;
12✔
152
    ggs.Serialize(ser);
6✔
153
    ser.WriteToFile(file);
6✔
154
}
6✔
155

156
/**
157
 *  liest die GlobalGameSettings aus der Datei.
158
 */
159
void SavedFile::ReadGGS(BinaryFile& file)
7✔
160
{
161
    Serializer ser;
14✔
162
    ser.ReadFromFile(file);
7✔
163
    ggs.Deserialize(ser);
7✔
164
}
7✔
165

166
const BasePlayerInfo& SavedFile::GetPlayer(unsigned idx) const
27✔
167
{
168
    return players[idx];
27✔
169
}
170

171
unsigned SavedFile::GetNumPlayers()
9✔
172
{
173
    return players.size();
9✔
174
}
175

176
void SavedFile::AddPlayer(const BasePlayerInfo& player)
50✔
177
{
178
    players.push_back(player);
50✔
179
    if(player.isUsed())
50✔
180
        playerNames_.push_back(player.name);
39✔
181
}
50✔
182

183
void SavedFile::ClearPlayers()
17✔
184
{
185
    players.clear();
17✔
186
    playerNames_.clear();
17✔
187
}
17✔
188

189
std::string SavedFile::GetRevision() const
×
190
{
191
    return std::string(revision.begin(), revision.end());
×
192
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc