Merge branch 'master' into jgrpp-beta

# Conflicts:
#	src/cargopacket.h
#	src/lang/korean.txt
#	src/linkgraph/linkgraph.h
#	src/linkgraph/linkgraphjob.h
#	src/linkgraph/linkgraphschedule.h
#	src/network/network_admin.h
#	src/network/network_func.h
#	src/network/network_server.cpp
#	src/network/network_server.h
#	src/order_base.h
#	src/rail_cmd.cpp
#	src/saveload/company_sl.cpp
#	src/saveload/depot_sl.cpp
#	src/saveload/economy_sl.cpp
#	src/saveload/linkgraph_sl.cpp
#	src/saveload/map_sl.cpp
#	src/saveload/newgrf_sl.cpp
#	src/saveload/order_sl.cpp
#	src/saveload/saveload.cpp
#	src/saveload/saveload.h
#	src/saveload/signs_sl.cpp
#	src/saveload/station_sl.cpp
#	src/saveload/subsidy_sl.cpp
#	src/saveload/town_sl.cpp
#	src/saveload/vehicle_sl.cpp
#	src/script/api/script_object.cpp
#	src/settings.cpp
#	src/string.cpp
#	src/string_func.h
#	src/table/CMakeLists.txt
#	src/table/settings/settings.ini
#	src/viewport_sprite_sorter_sse4.cpp
This commit is contained in:
Jonathan G Rennison
2021-10-18 18:01:27 +01:00
113 changed files with 721 additions and 755 deletions

View File

@@ -444,7 +444,7 @@ if(WIN32)
endif() endif()
if(CMAKE_SIZEOF_VOID_P EQUAL 8) if(CMAKE_SIZEOF_VOID_P EQUAL 8)
add_definitions(-D_SQ64) add_definitions(-DPOINTER_IS_64BIT)
endif() endif()
include(CreateRegression) include(CreateRegression)

View File

@@ -544,7 +544,7 @@ public:
DoCommandP(0, this->sel_group | (GroupFlags::GF_REPLACE_WAGON_REMOVAL << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL) ? 0 : 1) | (_ctrl_pressed << 1), CMD_SET_GROUP_FLAG); DoCommandP(0, this->sel_group | (GroupFlags::GF_REPLACE_WAGON_REMOVAL << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL) ? 0 : 1) | (_ctrl_pressed << 1), CMD_SET_GROUP_FLAG);
} else { } else {
// toggle renew_keep_length // toggle renew_keep_length
DoCommandP(0, GetCompanySettingIndex("company.renew_keep_length"), Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, CMD_CHANGE_COMPANY_SETTING); DoCommandP(0, 0, Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, CMD_CHANGE_COMPANY_SETTING, nullptr, "company.renew_keep_length");
} }
break; break;
} }

View File

@@ -198,7 +198,7 @@ bmno_full_transparency:
m_colour = r == 0 ? m_colour : cmap; \ m_colour = r == 0 ? m_colour : cmap; \
m_colour = m != 0 ? m_colour : srcm; \ m_colour = m != 0 ? m_colour : srcm; \
} }
#ifdef _SQ64 #ifdef POINTER_IS_64BIT
uint64 srcs = _mm_cvtsi128_si64(srcABCD); uint64 srcs = _mm_cvtsi128_si64(srcABCD);
uint64 dsts; uint64 dsts;
if (animated) dsts = _mm_cvtsi128_si64(dstABCD); if (animated) dsts = _mm_cvtsi128_si64(dstABCD);
@@ -449,7 +449,7 @@ bm_normal:
else Draw<BM_NORMAL, RM_WITH_SKIP, BT_ODD, true, true>(bp, zoom); else Draw<BM_NORMAL, RM_WITH_SKIP, BT_ODD, true, true>(bp, zoom);
} }
} else { } else {
#ifdef _SQ64 #ifdef POINTER_IS_64BIT
if (sprite_flags & SF_TRANSLUCENT) { if (sprite_flags & SF_TRANSLUCENT) {
if (sprite_flags & SF_NO_ANIM) Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, true, false>(bp, zoom); if (sprite_flags & SF_NO_ANIM) Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, true, false>(bp, zoom);
else Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, true, true>(bp, zoom); else Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, true, true>(bp, zoom);

View File

@@ -34,7 +34,7 @@ static inline void InsertSecondUint32(const uint32 value, __m128i &into)
static inline void LoadUint64(const uint64 value, __m128i &into) static inline void LoadUint64(const uint64 value, __m128i &into)
{ {
#ifdef _SQ64 #ifdef POINTER_IS_64BIT
into = _mm_cvtsi64_si128(value); into = _mm_cvtsi64_si128(value);
#else #else
#if (SSE_VERSION >= 4) #if (SSE_VERSION >= 4)
@@ -303,7 +303,7 @@ inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel
m_colour = r == 0 ? m_colour : cmap; \ m_colour = r == 0 ? m_colour : cmap; \
m_colour = m != 0 ? m_colour : srcm; \ m_colour = m != 0 ? m_colour : srcm; \
} }
#ifdef _SQ64 #ifdef POINTER_IS_64BIT
uint64 srcs = _mm_cvtsi128_si64(srcABCD); uint64 srcs = _mm_cvtsi128_si64(srcABCD);
uint64 remapped_src = 0; uint64 remapped_src = 0;
CMOV_REMAP(c0, 0, srcs, mvX2); CMOV_REMAP(c0, 0, srcs, mvX2);

View File

@@ -18,6 +18,7 @@
#include "vehicle_type.h" #include "vehicle_type.h"
#include "company_type.h" #include "company_type.h"
#include "core/multimap.hpp" #include "core/multimap.hpp"
#include "saveload/saveload.h"
#include <deque> #include <deque>
/** Unique identifier for a single cargo packet. */ /** Unique identifier for a single cargo packet. */
@@ -33,7 +34,7 @@ struct GoodsEntry; // forward-declare for Stage() and RerouteStalePackets()
template <class Tinst, class Tcont> class CargoList; template <class Tinst, class Tcont> class CargoList;
class StationCargoList; // forward-declare, so we can use it in VehicleCargoList. class StationCargoList; // forward-declare, so we can use it in VehicleCargoList.
extern const struct SaveLoad *GetCargoPacketDesc(); extern SaveLoadTable GetCargoPacketDesc();
typedef uint32 TileOrStationID; typedef uint32 TileOrStationID;
@@ -68,7 +69,7 @@ private:
friend class VehicleCargoList; friend class VehicleCargoList;
friend class StationCargoList; friend class StationCargoList;
/** We want this to be saved, right? */ /** We want this to be saved, right? */
friend const struct SaveLoad *GetCargoPacketDesc(); friend SaveLoadTable GetCargoPacketDesc();
friend void Load_CPDP(); friend void Load_CPDP();
public: public:
/** Maximum number of items in a single cargo packet. */ /** Maximum number of items in a single cargo packet. */
@@ -342,7 +343,7 @@ public:
/** The super class ought to know what it's doing. */ /** The super class ought to know what it's doing. */
friend class CargoList<VehicleCargoList, CargoPacketList>; friend class CargoList<VehicleCargoList, CargoPacketList>;
/** The vehicles have a cargo list (and we want that saved). */ /** The vehicles have a cargo list (and we want that saved). */
friend const struct SaveLoad *GetVehicleDescription(VehicleType vt); friend SaveLoadTable GetVehicleDescription(VehicleType vt);
friend class CargoShift; friend class CargoShift;
friend class CargoTransfer; friend class CargoTransfer;
@@ -493,7 +494,7 @@ public:
/** The super class ought to know what it's doing. */ /** The super class ought to know what it's doing. */
friend class CargoList<StationCargoList, StationCargoPacketMap>; friend class CargoList<StationCargoList, StationCargoPacketMap>;
/** The stations, via GoodsEntry, have a CargoList. */ /** The stations, via GoodsEntry, have a CargoList. */
friend const struct SaveLoad *GetGoodsDesc(); friend SaveLoadTable GetGoodsDesc();
friend class CargoLoad; friend class CargoLoad;
friend class CargoTransfer; friend class CargoTransfer;

View File

@@ -536,6 +536,7 @@ enum CommandLogEntryFlag : uint16 {
DECLARE_ENUM_AS_BIT_SET(CommandLogEntryFlag) DECLARE_ENUM_AS_BIT_SET(CommandLogEntryFlag)
struct CommandLogEntry { struct CommandLogEntry {
std::string text;
TileIndex tile; TileIndex tile;
uint32 p1; uint32 p1;
uint32 p2; uint32 p2;
@@ -550,8 +551,8 @@ struct CommandLogEntry {
CommandLogEntry() { } CommandLogEntry() { }
CommandLogEntry(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandLogEntryFlag log_flags) CommandLogEntry(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandLogEntryFlag log_flags, std::string text)
: tile(tile), p1(p1), p2(p2), cmd(cmd), p3(p3), date(_date), date_fract(_date_fract), tick_skip_counter(_tick_skip_counter), : text(text), tile(tile), p1(p1), p2(p2), cmd(cmd), p3(p3), date(_date), date_fract(_date_fract), tick_skip_counter(_tick_skip_counter),
current_company(_current_company), local_company(_local_company), log_flags(log_flags) { } current_company(_current_company), local_company(_local_company), log_flags(log_flags) { }
}; };
@@ -607,11 +608,8 @@ static void DumpSubCommandLog(char *&buffer, const char *last, const CommandLog
switch (entry.cmd & CMD_ID_MASK) { switch (entry.cmd & CMD_ID_MASK) {
case CMD_CHANGE_SETTING: case CMD_CHANGE_SETTING:
buffer += seprintf(buffer, last, " [%s]", GetSettingNameByIndex(entry.p1));
break;
case CMD_CHANGE_COMPANY_SETTING: case CMD_CHANGE_COMPANY_SETTING:
buffer += seprintf(buffer, last, " [%s]", GetCompanySettingNameByIndex(entry.p1)); buffer += seprintf(buffer, last, " [%s]", entry.text.c_str());
break; break;
} }
@@ -806,7 +804,7 @@ Money GetAvailableMoneyForCommand()
return Company::Get(company)->money; return Company::Get(company)->money;
} }
static void AppendCommandLogEntry(const CommandCost &res, TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandLogEntryFlag log_flags) static void AppendCommandLogEntry(const CommandCost &res, TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandLogEntryFlag log_flags, const char *text)
{ {
if (res.Failed()) log_flags |= CLEF_CMD_FAILED; if (res.Failed()) log_flags |= CLEF_CMD_FAILED;
if (_generating_world) log_flags |= CLEF_GENERATING_WORLD; if (_generating_world) log_flags |= CLEF_GENERATING_WORLD;
@@ -824,7 +822,16 @@ static void AppendCommandLogEntry(const CommandCost &res, TileIndex tile, uint32
return; return;
} }
} }
cmd_log.log[cmd_log.next] = CommandLogEntry(tile, p1, p2, p3, cmd, log_flags);
std::string str;
switch (cmd & CMD_ID_MASK) {
case CMD_CHANGE_SETTING:
case CMD_CHANGE_COMPANY_SETTING:
if (text != nullptr) str.assign(text);
break;
}
cmd_log.log[cmd_log.next] = CommandLogEntry(tile, p1, p2, p3, cmd, log_flags, std::move(str));
cmd_log.next = (cmd_log.next + 1) % cmd_log.log.size(); cmd_log.next = (cmd_log.next + 1) % cmd_log.log.size();
cmd_log.count++; cmd_log.count++;
} }
@@ -889,7 +896,7 @@ bool DoCommandPEx(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, C
if (my_cmd) log_flags |= CLEF_MY_CMD; if (my_cmd) log_flags |= CLEF_MY_CMD;
if (binary_length > 0) log_flags |= CLEF_BINARY; if (binary_length > 0) log_flags |= CLEF_BINARY;
if (!random_state.Check()) log_flags |= CLEF_RANDOM; if (!random_state.Check()) log_flags |= CLEF_RANDOM;
AppendCommandLogEntry(res, tile, p1, p2, p3, cmd, log_flags); AppendCommandLogEntry(res, tile, p1, p2, p3, cmd, log_flags, text);
if (unlikely(HasChickenBit(DCBF_DESYNC_CHECK_POST_COMMAND)) && !(GetCommandFlags(cmd) & CMD_LOG_AUX)) { if (unlikely(HasChickenBit(DCBF_DESYNC_CHECK_POST_COMMAND)) && !(GetCommandFlags(cmd) & CMD_LOG_AUX)) {
CheckCachesFlags flags = CHECK_CACHE_ALL | CHECK_CACHE_EMIT_LOG; CheckCachesFlags flags = CHECK_CACHE_ALL | CHECK_CACHE_EMIT_LOG;
@@ -935,7 +942,7 @@ CommandCost DoCommandPScript(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, ui
if (my_cmd) log_flags |= CLEF_MY_CMD; if (my_cmd) log_flags |= CLEF_MY_CMD;
if (binary_length > 0) log_flags |= CLEF_BINARY; if (binary_length > 0) log_flags |= CLEF_BINARY;
if (!random_state.Check()) log_flags |= CLEF_RANDOM; if (!random_state.Check()) log_flags |= CLEF_RANDOM;
AppendCommandLogEntry(res, tile, p1, p2, p3, cmd, log_flags); AppendCommandLogEntry(res, tile, p1, p2, p3, cmd, log_flags, text);
if (unlikely(HasChickenBit(DCBF_DESYNC_CHECK_POST_COMMAND)) && !(GetCommandFlags(cmd) & CMD_LOG_AUX)) { if (unlikely(HasChickenBit(DCBF_DESYNC_CHECK_POST_COMMAND)) && !(GetCommandFlags(cmd) & CMD_LOG_AUX)) {
CheckCachesFlags flags = CHECK_CACHE_ALL | CHECK_CACHE_EMIT_LOG; CheckCachesFlags flags = CHECK_CACHE_ALL | CHECK_CACHE_EMIT_LOG;

View File

@@ -111,7 +111,7 @@ void IConsolePrint(TextColour colour_code, const char *string)
* characters and (when applicable) assign it to the console buffer */ * characters and (when applicable) assign it to the console buffer */
str = stredup(string); str = stredup(string);
str_strip_colours(str); str_strip_colours(str);
str_validate(str, str + strlen(str)); StrMakeValidInPlace(str);
if (_network_dedicated) { if (_network_dedicated) {
NetworkAdminConsole("console", str); NetworkAdminConsole("console", str);

View File

@@ -550,7 +550,7 @@ DEF_CONSOLE_CMD(ConClearBuffer)
* Network Core Console Commands * Network Core Console Commands
**********************************/ **********************************/
static bool ConKickOrBan(const char *argv, bool ban, const char *reason) static bool ConKickOrBan(const char *argv, bool ban, const std::string &reason)
{ {
uint n; uint n;
@@ -604,7 +604,7 @@ DEF_CONSOLE_CMD(ConKick)
if (argc != 2 && argc != 3) return false; if (argc != 2 && argc != 3) return false;
/* No reason supplied for kicking */ /* No reason supplied for kicking */
if (argc == 2) return ConKickOrBan(argv[1], false, nullptr); if (argc == 2) return ConKickOrBan(argv[1], false, {});
/* Reason for kicking supplied */ /* Reason for kicking supplied */
size_t kick_message_length = strlen(argv[2]); size_t kick_message_length = strlen(argv[2]);
@@ -628,7 +628,7 @@ DEF_CONSOLE_CMD(ConBan)
if (argc != 2 && argc != 3) return false; if (argc != 2 && argc != 3) return false;
/* No reason supplied for kicking */ /* No reason supplied for kicking */
if (argc == 2) return ConKickOrBan(argv[1], true, nullptr); if (argc == 2) return ConKickOrBan(argv[1], true, {});
/* Reason for kicking supplied */ /* Reason for kicking supplied */
size_t kick_message_length = strlen(argv[2]); size_t kick_message_length = strlen(argv[2]);
@@ -827,7 +827,7 @@ DEF_CONSOLE_CMD(ConClientNickChange)
return true; return true;
} }
if (!NetworkServerChangeClientName(client_id, client_name.c_str())) { if (!NetworkServerChangeClientName(client_id, client_name)) {
IConsoleError("Cannot give a client a duplicate name"); IConsoleError("Cannot give a client a duplicate name");
} }

98
src/core/span_type.hpp Normal file
View File

@@ -0,0 +1,98 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file span_type.hpp Minimized implementation of C++20 std::span. */
#ifndef CORE_SPAN_TYPE_HPP
#define CORE_SPAN_TYPE_HPP
/* This is a partial copy/paste from https://github.com/gsl-lite/gsl-lite/blob/master/include/gsl/gsl-lite.hpp */
/* Template to check if a template variable defines size() and data(). */
template <class, class = void>
struct has_size_and_data : std::false_type{};
template <class C>
struct has_size_and_data
<
C, std::void_t<
decltype(std::size(std::declval<C>())),
decltype(std::data(std::declval<C>()))>
> : std::true_type{};
/* Template to check if two elements are compatible. */
template <class, class, class = void>
struct is_compatible_element : std::false_type {};
template <class C, class E>
struct is_compatible_element
<
C, E, std::void_t<
decltype(std::data(std::declval<C>())),
typename std::remove_pointer<decltype(std::data( std::declval<C&>()))>::type(*)[]>
> : std::is_convertible<typename std::remove_pointer<decltype(std::data(std::declval<C&>()))>::type(*)[], E(*)[]>{};
/* Template to check if a container is compatible. gsl-lite also includes is_array and is_std_array, but as we don't use them, they are omitted. */
template <class C, class E>
struct is_compatible_container : std::bool_constant
<
has_size_and_data<C>::value
&& is_compatible_element<C,E>::value
>{};
/**
* A trimmed down version of what std::span will be in C++20.
*
* It is fully forwards compatible, so if this codebase switches to C++20,
* all "span" instances can be replaced by "std::span" without loss of
* functionality.
*
* Currently it only supports basic functionality:
* - size() and friends
* - begin() and friends
*
* It is meant to simplify function parameters, where we only want to walk
* a continuous list.
*/
template<class T>
class span {
public:
typedef T element_type;
typedef typename std::remove_cv< T >::type value_type;
typedef T &reference;
typedef T *pointer;
typedef const T &const_reference;
typedef const T *const_pointer;
typedef pointer iterator;
typedef const_pointer const_iterator;
typedef size_t size_type;
typedef std::ptrdiff_t difference_type;
constexpr span(pointer data_in, size_t size_in) : first(data_in), last(data_in + size_in) {}
template<class Container, typename std::enable_if<(is_compatible_container<Container, element_type>::value), int>::type = 0>
constexpr span(Container &list) noexcept : first(std::data(list)), last(std::data(list) + std::size(list)) {}
template<class Container, typename std::enable_if<(std::is_const<element_type>::value && is_compatible_container<Container, element_type>::value), int>::type = 0>
constexpr span(const Container &list) noexcept : first(std::data(list)), last(std::data(list) + std::size(list)) {}
constexpr size_t size() const noexcept { return static_cast<size_t>( last - first ); }
constexpr std::ptrdiff_t ssize() const noexcept { return static_cast<std::ptrdiff_t>( last - first ); }
constexpr bool empty() const noexcept { return size() == 0; }
constexpr iterator begin() const noexcept { return iterator(first); }
constexpr iterator end() const noexcept { return iterator(last); }
constexpr const_iterator cbegin() const noexcept { return const_iterator(first); }
constexpr const_iterator cend() const noexcept { return const_iterator(last); }
private:
pointer first;
pointer last;
};
#endif /* CORE_SPAN_TYPE_HPP */

View File

@@ -153,7 +153,7 @@ char *CrashLog::LogOpenTTDVersion(char *buffer, const char *last) const
_openttd_revision_modified, _openttd_revision_modified,
_openttd_release_version, _openttd_release_version,
_openttd_newgrf_version, _openttd_newgrf_version,
#ifdef _SQ64 #ifdef POINTER_IS_64BIT
64, 64,
#else #else
32, 32,

View File

@@ -342,7 +342,7 @@ bool FiosFileScanner::AddFile(const std::string &filename, size_t basepath_lengt
t = filename.c_str() + (ps == std::string::npos ? 0 : ps + 1); t = filename.c_str() + (ps == std::string::npos ? 0 : ps + 1);
} }
strecpy(fios->title, t, lastof(fios->title)); strecpy(fios->title, t, lastof(fios->title));
str_validate(fios->title, lastof(fios->title)); StrMakeValidInPlace(fios->title, lastof(fios->title));
return true; return true;
} }
@@ -394,7 +394,7 @@ static void FiosGetFileList(SaveLoadOperation fop, fios_getlist_callback_proc *c
std::string dirname = std::string(d_name) + PATHSEP; std::string dirname = std::string(d_name) + PATHSEP;
SetDParamStr(0, dirname); SetDParamStr(0, dirname);
GetString(fios->title, STR_SAVELOAD_DIRECTORY, lastof(fios->title)); GetString(fios->title, STR_SAVELOAD_DIRECTORY, lastof(fios->title));
str_validate(fios->title, lastof(fios->title)); StrMakeValidInPlace(fios->title, lastof(fios->title));
} }
} }
closedir(dir); closedir(dir);
@@ -446,7 +446,7 @@ static void GetFileTitle(const std::string &file, char *title, const char *last,
size_t read = fread(title, 1, last - title, f); size_t read = fread(title, 1, last - title, f);
assert(title + read <= last); assert(title + read <= last);
title[read] = '\0'; title[read] = '\0';
str_validate(title, last); StrMakeValidInPlace(title, last);
FioFCloseFile(f); FioFCloseFile(f);
} }

View File

@@ -170,7 +170,7 @@ void LoadFromHighScore()
i = SP_SAVED_HIGHSCORE_END; i = SP_SAVED_HIGHSCORE_END;
break; break;
} }
str_validate(hs->company, lastof(hs->company), SVS_NONE); StrMakeValidInPlace(hs->company, lastof(hs->company), SVS_NONE);
hs->title = EndGameGetPerformanceTitleFromValue(hs->score); hs->title = EndGameGetPerformanceTitleFromValue(hs->score);
} }
} }

View File

@@ -22,7 +22,7 @@
*/ */
IniItem::IniItem(IniGroup *parent, const std::string &name) : next(nullptr) IniItem::IniItem(IniGroup *parent, const std::string &name) : next(nullptr)
{ {
this->name = str_validate(name); this->name = StrMakeValid(name);
*parent->last_item = this; *parent->last_item = this;
parent->last_item = &this->next; parent->last_item = &this->next;
@@ -50,7 +50,7 @@ void IniItem::SetValue(const std::string_view value)
*/ */
IniGroup::IniGroup(IniLoadFile *parent, const std::string &name) : next(nullptr), type(IGT_VARIABLES), item(nullptr) IniGroup::IniGroup(IniLoadFile *parent, const std::string &name) : next(nullptr), type(IGT_VARIABLES), item(nullptr)
{ {
this->name = str_validate(name); this->name = StrMakeValid(name);
this->last_item = &this->item; this->last_item = &this->item;
*parent->last_group = this; *parent->last_group = this;
@@ -294,7 +294,7 @@ void IniLoadFile::LoadFromDisk(const std::string &filename, Subdirectory subdir,
if (!quoted && e == t) { if (!quoted && e == t) {
item->value.reset(); item->value.reset();
} else { } else {
item->value = str_validate(std::string(t)); item->value = StrMakeValid(std::string(t));
} }
} else { } else {
/* it's an orphan item */ /* it's an orphan item */

View File

@@ -2639,7 +2639,7 @@ STR_NETWORK_ERROR_SERVER_START :{WHITE}서버
STR_NETWORK_ERROR_CLIENT_START :{WHITE}접속할 수 없습니다 STR_NETWORK_ERROR_CLIENT_START :{WHITE}접속할 수 없습니다
STR_NETWORK_ERROR_TIMEOUT :{WHITE}접속자 #{NUM}의 입력 시간이 초과되었습니다 STR_NETWORK_ERROR_TIMEOUT :{WHITE}접속자 #{NUM}의 입력 시간이 초과되었습니다
STR_NETWORK_ERROR_SERVER_ERROR :{WHITE}프로토콜 오류가 발생되어 연결이 끊어졌습니다 STR_NETWORK_ERROR_SERVER_ERROR :{WHITE}프로토콜 오류가 발생되어 연결이 끊어졌습니다
STR_NETWORK_ERROR_BAD_PLAYER_NAME :{WHITE}접속자 이름을 정하지 않았습니다. 접속자 이름은 멀티플레이 창 맨 위에서 설정할 수 있습니다. STR_NETWORK_ERROR_BAD_PLAYER_NAME :{WHITE}접속자 이름을 정하지 않았습니다. 이름은 멀티플레이 창의 상단에서 설정할 수 있습니다.
STR_NETWORK_ERROR_BAD_SERVER_NAME :{WHITE}서버 이름을 지정하지 않았습니다. 서버 이름은 멀티플레이 창 맨 위에서 설정할 수 있습니다. STR_NETWORK_ERROR_BAD_SERVER_NAME :{WHITE}서버 이름을 지정하지 않았습니다. 서버 이름은 멀티플레이 창 맨 위에서 설정할 수 있습니다.
STR_NETWORK_ERROR_WRONG_REVISION :{WHITE}이 접속자의 게임 버전이 서버의 버전과 일치하지 않습니다 STR_NETWORK_ERROR_WRONG_REVISION :{WHITE}이 접속자의 게임 버전이 서버의 버전과 일치하지 않습니다
STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}잘못된 비밀번호입니다 STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}잘못된 비밀번호입니다

View File

@@ -17,10 +17,10 @@
#include "../station_base.h" #include "../station_base.h"
#include "../cargotype.h" #include "../cargotype.h"
#include "../date_func.h" #include "../date_func.h"
#include "../saveload/saveload.h"
#include "linkgraph_type.h" #include "linkgraph_type.h"
#include <utility> #include <utility>
struct SaveLoad;
class LinkGraph; class LinkGraph;
/** /**
@@ -531,8 +531,8 @@ public:
protected: protected:
friend class LinkGraph::ConstNode; friend class LinkGraph::ConstNode;
friend class LinkGraph::Node; friend class LinkGraph::Node;
friend const SaveLoad *GetLinkGraphDesc(); friend SaveLoadTable GetLinkGraphDesc();
friend const SaveLoad *GetLinkGraphJobDesc(); friend SaveLoadTable GetLinkGraphJobDesc();
friend void Save_LinkGraph(LinkGraph &lg); friend void Save_LinkGraph(LinkGraph &lg);
friend void Load_LinkGraph(LinkGraph &lg); friend void Load_LinkGraph(LinkGraph &lg);

View File

@@ -56,7 +56,7 @@ private:
typedef std::vector<NodeAnnotation> NodeAnnotationVector; typedef std::vector<NodeAnnotation> NodeAnnotationVector;
typedef SmallMatrix<EdgeAnnotation> EdgeAnnotationMatrix; typedef SmallMatrix<EdgeAnnotation> EdgeAnnotationMatrix;
friend const SaveLoad *GetLinkGraphJobDesc(); friend SaveLoadTable GetLinkGraphJobDesc();
friend void GetLinkGraphJobDayLengthScaleAfterLoad(LinkGraphJob *lgj); friend void GetLinkGraphJobDayLengthScaleAfterLoad(LinkGraphJob *lgj);
friend class LinkGraphSchedule; friend class LinkGraphSchedule;
friend class LinkGraphJobGroup; friend class LinkGraphJobGroup;

View File

@@ -41,7 +41,7 @@ private:
~LinkGraphSchedule(); ~LinkGraphSchedule();
typedef std::list<LinkGraph *> GraphList; typedef std::list<LinkGraph *> GraphList;
typedef std::list<std::unique_ptr<LinkGraphJob>> JobList; typedef std::list<std::unique_ptr<LinkGraphJob>> JobList;
friend const SaveLoad *GetLinkGraphScheduleDesc(); friend SaveLoadTable GetLinkGraphScheduleDesc();
protected: protected:
std::unique_ptr<ComponentHandler> handlers[6]; ///< Handlers to be run for each job. std::unique_ptr<ComponentHandler> handlers[6]; ///< Handlers to be run for each job.

View File

@@ -1075,7 +1075,7 @@ struct QueryStringWindow : public Window
char *last_of = &this->editbox.text.buf[this->editbox.text.max_bytes - 1]; char *last_of = &this->editbox.text.buf[this->editbox.text.max_bytes - 1];
GetString(this->editbox.text.buf, str, last_of); GetString(this->editbox.text.buf, str, last_of);
str_validate(this->editbox.text.buf, last_of, SVS_NONE); StrMakeValidInPlace(this->editbox.text.buf, last_of, SVS_NONE);
/* Make sure the name isn't too long for the text buffer in the number of /* Make sure the name isn't too long for the text buffer in the number of
* characters (not bytes). max_chars also counts the '\0' characters. */ * characters (not bytes). max_chars also counts the '\0' characters. */

View File

@@ -401,7 +401,7 @@ void Packet::Recv_string(char *buffer, size_t size, StringValidationSettings set
assert(pos <= std::numeric_limits<PacketSize>::max()); assert(pos <= std::numeric_limits<PacketSize>::max());
this->pos = static_cast<PacketSize>(pos); this->pos = static_cast<PacketSize>(pos);
str_validate(bufp, last, settings); StrMakeValidInPlace(bufp, last, settings);
} }
/** /**
@@ -430,7 +430,7 @@ std::string Packet::Recv_string(size_t length, StringValidationSettings settings
while (this->Recv_uint8() != '\0') {} while (this->Recv_uint8() != '\0') {}
} }
return str_validate(str, settings); return StrMakeValid(str, settings);
} }
/** /**
@@ -455,7 +455,7 @@ void Packet::Recv_string(std::string &buffer, StringValidationSettings settings)
size_t length = ttd_strnlen((const char *)(this->buffer.data() + this->pos), this->Size() - this->pos - 1); size_t length = ttd_strnlen((const char *)(this->buffer.data() + this->pos), this->Size() - this->pos - 1);
buffer.assign((const char *)(this->buffer.data() + this->pos), length); buffer.assign((const char *)(this->buffer.data() + this->pos), length);
this->pos += (uint)length + 1; this->pos += (uint)length + 1;
str_validate_inplace(buffer, settings); StrMakeValidInPlace(buffer, settings);
} }
/** /**

View File

@@ -30,8 +30,6 @@ static_assert((int)CRR_END == (int)ADMIN_CRR_END);
NetworkAdminSocketHandler::NetworkAdminSocketHandler(SOCKET s) : status(ADMIN_STATUS_INACTIVE) NetworkAdminSocketHandler::NetworkAdminSocketHandler(SOCKET s) : status(ADMIN_STATUS_INACTIVE)
{ {
this->sock = s; this->sock = s;
this->admin_name[0] = '\0';
this->admin_version[0] = '\0';
} }
NetworkRecvStatus NetworkAdminSocketHandler::CloseConnection(bool error) NetworkRecvStatus NetworkAdminSocketHandler::CloseConnection(bool error)
@@ -89,9 +87,9 @@ NetworkRecvStatus NetworkAdminSocketHandler::HandlePacket(Packet *p)
default: default:
if (this->HasClientQuit()) { if (this->HasClientQuit()) {
DEBUG(net, 0, "[tcp/admin] Received invalid packet type %d from '%s' (%s)", type, this->admin_name, this->admin_version); DEBUG(net, 0, "[tcp/admin] Received invalid packet type %d from '%s' (%s)", type, this->admin_name.c_str(), this->admin_version.c_str());
} else { } else {
DEBUG(net, 0, "[tcp/admin] Received illegal packet from '%s' (%s)", this->admin_name, this->admin_version); DEBUG(net, 0, "[tcp/admin] Received illegal packet from '%s' (%s)", this->admin_name.c_str(), this->admin_version.c_str());
} }
this->CloseConnection(); this->CloseConnection();
@@ -124,7 +122,7 @@ NetworkRecvStatus NetworkAdminSocketHandler::ReceivePackets()
*/ */
NetworkRecvStatus NetworkAdminSocketHandler::ReceiveInvalidPacket(PacketAdminType type) NetworkRecvStatus NetworkAdminSocketHandler::ReceiveInvalidPacket(PacketAdminType type)
{ {
DEBUG(net, 0, "[tcp/admin] Received illegal packet type %d from admin %s (%s)", type, this->admin_name, this->admin_version); DEBUG(net, 0, "[tcp/admin] Received illegal packet type %d from admin %s (%s)", type, this->admin_name.c_str(), this->admin_version.c_str());
return NETWORK_RECV_STATUS_MALFORMED_PACKET; return NETWORK_RECV_STATUS_MALFORMED_PACKET;
} }

View File

@@ -109,8 +109,8 @@ enum AdminCompanyRemoveReason {
/** Main socket handler for admin related connections. */ /** Main socket handler for admin related connections. */
class NetworkAdminSocketHandler : public NetworkTCPSocketHandler { class NetworkAdminSocketHandler : public NetworkTCPSocketHandler {
protected: protected:
char admin_name[NETWORK_CLIENT_NAME_LENGTH]; ///< Name of the admin. std::string admin_name; ///< Name of the admin.
char admin_version[NETWORK_REVISION_LENGTH]; ///< Version string of the admin. std::string admin_version; ///< Version string of the admin.
AdminStatus status; ///< Status of this admin. AdminStatus status; ///< Status of this admin.
NetworkRecvStatus ReceiveInvalidPacket(PacketAdminType type); NetworkRecvStatus ReceiveInvalidPacket(PacketAdminType type);

View File

@@ -74,7 +74,7 @@ ServerNetworkAdminSocketHandler::ServerNetworkAdminSocketHandler(SOCKET s) : Net
ServerNetworkAdminSocketHandler::~ServerNetworkAdminSocketHandler() ServerNetworkAdminSocketHandler::~ServerNetworkAdminSocketHandler()
{ {
_network_admins_connected--; _network_admins_connected--;
DEBUG(net, 3, "[admin] '%s' (%s) has disconnected", this->admin_name, this->admin_version); DEBUG(net, 3, "[admin] '%s' (%s) has disconnected", this->admin_name.c_str(), this->admin_version.c_str());
if (_redirect_console_to_admin == this->index) _redirect_console_to_admin = INVALID_ADMIN_ID; if (_redirect_console_to_admin == this->index) _redirect_console_to_admin = INVALID_ADMIN_ID;
if (this->update_frequency[ADMIN_UPDATE_CONSOLE] & ADMIN_FREQUENCY_AUTOMATIC) { if (this->update_frequency[ADMIN_UPDATE_CONSOLE] & ADMIN_FREQUENCY_AUTOMATIC) {
@@ -140,7 +140,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendError(NetworkErrorCode er
std::string error_message = GetString(GetNetworkErrorMsg(error)); std::string error_message = GetString(GetNetworkErrorMsg(error));
DEBUG(net, 1, "[admin] The admin '%s' (%s) made an error and has been disconnected: '%s'", this->admin_name, this->admin_version, error_message.c_str()); DEBUG(net, 1, "[admin] The admin '%s' (%s) made an error and has been disconnected: '%s'", this->admin_name.c_str(), this->admin_version.c_str(), error_message.c_str());
return this->CloseConnection(true); return this->CloseConnection(true);
} }
@@ -473,7 +473,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendChat(NetworkAction action
* Send a notification indicating the rcon command has completed. * Send a notification indicating the rcon command has completed.
* @param command The original command sent. * @param command The original command sent.
*/ */
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRconEnd(const char *command) NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRconEnd(const std::string_view command)
{ {
Packet *p = new Packet(ADMIN_PACKET_SERVER_RCON_END); Packet *p = new Packet(ADMIN_PACKET_SERVER_RCON_END);
@@ -488,7 +488,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRconEnd(const char *comma
* @param colour The colour of the text. * @param colour The colour of the text.
* @param result The result of the command. * @param result The result of the command.
*/ */
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRcon(uint16 colour, const char *result) NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRcon(uint16 colour, const std::string_view result)
{ {
Packet *p = new Packet(ADMIN_PACKET_SERVER_RCON); Packet *p = new Packet(ADMIN_PACKET_SERVER_RCON);
@@ -503,14 +503,12 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_RCON(Packet *p)
{ {
if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED); if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
char command[NETWORK_RCONCOMMAND_LENGTH]; std::string command = p->Recv_string(NETWORK_RCONCOMMAND_LENGTH);
p->Recv_string(command, sizeof(command)); DEBUG(net, 3, "[admin] Rcon command from '%s' (%s): %s", this->admin_name.c_str(), this->admin_version.c_str(), command.c_str());
DEBUG(net, 3, "[admin] Rcon command from '%s' (%s): %s", this->admin_name, this->admin_version, command);
_redirect_console_to_admin = this->index; _redirect_console_to_admin = this->index;
IConsoleCmdExec(command); IConsoleCmdExec(command.c_str());
_redirect_console_to_admin = INVALID_ADMIN_ID; _redirect_console_to_admin = INVALID_ADMIN_ID;
return this->SendRconEnd(command); return this->SendRconEnd(command);
} }
@@ -519,11 +517,9 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_GAMESCRIPT(Pack
{ {
if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED); if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
char json[NETWORK_GAMESCRIPT_JSON_LENGTH]; std::string json = p->Recv_string(NETWORK_GAMESCRIPT_JSON_LENGTH);
p->Recv_string(json, sizeof(json)); DEBUG(net, 6, "[admin] GameScript JSON from '%s' (%s): %s", this->admin_name.c_str(), this->admin_version.c_str(), json.c_str());
DEBUG(net, 6, "[admin] GameScript JSON from '%s' (%s): %s", this->admin_name, this->admin_version, json);
Game::NewEvent(new ScriptEventAdminPort(json)); Game::NewEvent(new ScriptEventAdminPort(json));
return NETWORK_RECV_STATUS_OKAY; return NETWORK_RECV_STATUS_OKAY;
@@ -535,7 +531,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_PING(Packet *p)
uint32 d1 = p->Recv_uint32(); uint32 d1 = p->Recv_uint32();
DEBUG(net, 6, "[admin] Ping from '%s' (%s): %d", this->admin_name, this->admin_version, d1); DEBUG(net, 6, "[admin] Ping from '%s' (%s): %d", this->admin_name.c_str(), this->admin_version.c_str(), d1);
return this->SendPong(d1); return this->SendPong(d1);
} }
@@ -545,13 +541,13 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_PING(Packet *p)
* @param origin The origin of the string. * @param origin The origin of the string.
* @param string The string that's put on the console. * @param string The string that's put on the console.
*/ */
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendConsole(const char *origin, const char *string) NetworkRecvStatus ServerNetworkAdminSocketHandler::SendConsole(const std::string_view origin, const std::string_view string)
{ {
/* If the length of both strings, plus the 2 '\0' terminations and 3 bytes of the packet /* If the length of both strings, plus the 2 '\0' terminations and 3 bytes of the packet
* are bigger than the MTU, just ignore the message. Better safe than sorry. It should * are bigger than the MTU, just ignore the message. Better safe than sorry. It should
* never occur though as the longest strings are chat messages, which are still 30% * never occur though as the longest strings are chat messages, which are still 30%
* smaller than COMPAT_MTU. */ * smaller than COMPAT_MTU. */
if (strlen(origin) + strlen(string) + 2 + 3 >= COMPAT_MTU) return NETWORK_RECV_STATUS_OKAY; if (origin.size() + string.size() + 2 + 3 >= COMPAT_MTU) return NETWORK_RECV_STATUS_OKAY;
Packet *p = new Packet(ADMIN_PACKET_SERVER_CONSOLE); Packet *p = new Packet(ADMIN_PACKET_SERVER_CONSOLE);
@@ -566,12 +562,12 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendConsole(const char *origi
* Send GameScript JSON output. * Send GameScript JSON output.
* @param json The JSON string. * @param json The JSON string.
*/ */
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendGameScript(const char *json) NetworkRecvStatus ServerNetworkAdminSocketHandler::SendGameScript(const std::string_view json)
{ {
/* At the moment we cannot transmit anything larger than MTU. So we limit /* At the moment we cannot transmit anything larger than MTU. So we limit
* the maximum amount of json data that can be sent. Account also for * the maximum amount of json data that can be sent. Account also for
* the trailing \0 of the string */ * the trailing \0 of the string */
if (strlen(json) + 1 >= NETWORK_GAMESCRIPT_JSON_LENGTH) return NETWORK_RECV_STATUS_OKAY; if (json.size() + 1 >= NETWORK_GAMESCRIPT_JSON_LENGTH) return NETWORK_RECV_STATUS_OKAY;
Packet *p = new Packet(ADMIN_PACKET_SERVER_GAMESCRIPT); Packet *p = new Packet(ADMIN_PACKET_SERVER_GAMESCRIPT);
@@ -661,17 +657,17 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_JOIN(Packet *p)
return this->SendError(NETWORK_ERROR_WRONG_PASSWORD); return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
} }
p->Recv_string(this->admin_name, sizeof(this->admin_name)); this->admin_name = p->Recv_string(NETWORK_CLIENT_NAME_LENGTH);
p->Recv_string(this->admin_version, sizeof(this->admin_version)); this->admin_version = p->Recv_string(NETWORK_REVISION_LENGTH);
if (StrEmpty(this->admin_name) || StrEmpty(this->admin_version)) { if (this->admin_name.empty() || this->admin_version.empty()) {
/* no name or version supplied */ /* no name or version supplied */
return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET); return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
} }
this->status = ADMIN_STATUS_ACTIVE; this->status = ADMIN_STATUS_ACTIVE;
DEBUG(net, 3, "[admin] '%s' (%s) has connected", this->admin_name, this->admin_version); DEBUG(net, 3, "[admin] '%s' (%s) has connected", this->admin_name.c_str(), this->admin_version.c_str());
return this->SendProtocol(); return this->SendProtocol();
} }
@@ -691,7 +687,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_UPDATE_FREQUENC
if (type >= ADMIN_UPDATE_END || (_admin_update_type_frequencies[type] & freq) != freq) { if (type >= ADMIN_UPDATE_END || (_admin_update_type_frequencies[type] & freq) != freq) {
/* The server does not know of this UpdateType. */ /* The server does not know of this UpdateType. */
DEBUG(net, 1, "[admin] Not supported update frequency %d (%d) from '%s' (%s)", type, freq, this->admin_name, this->admin_version); DEBUG(net, 1, "[admin] Not supported update frequency %d (%d) from '%s' (%s)", type, freq, this->admin_name.c_str(), this->admin_version.c_str());
return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET); return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
} }
@@ -761,7 +757,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_POLL(Packet *p)
default: default:
/* An unsupported "poll" update type. */ /* An unsupported "poll" update type. */
DEBUG(net, 1, "[admin] Not supported poll %d (%d) from '%s' (%s).", type, d1, this->admin_name, this->admin_version); DEBUG(net, 1, "[admin] Not supported poll %d (%d) from '%s' (%s).", type, d1, this->admin_name.c_str(), this->admin_version.c_str());
return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET); return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
} }
@@ -787,7 +783,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_CHAT(Packet *p)
break; break;
default: default:
DEBUG(net, 1, "[admin] Invalid chat action %d from admin '%s' (%s).", action, this->admin_name, this->admin_version); DEBUG(net, 1, "[admin] Invalid chat action %d from admin '%s' (%s).", action, this->admin_name.c_str(), this->admin_version.c_str());
return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET); return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
} }
@@ -925,7 +921,7 @@ void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_i
* @param colour_code The colour of the string. * @param colour_code The colour of the string.
* @param string The string to show. * @param string The string to show.
*/ */
void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code, const char *string) void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code, const std::string_view string)
{ {
ServerNetworkAdminSocketHandler::Get(admin_index)->SendRcon(colour_code, string); ServerNetworkAdminSocketHandler::Get(admin_index)->SendRcon(colour_code, string);
} }
@@ -935,7 +931,7 @@ void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code,
* @param origin the origin of the message. * @param origin the origin of the message.
* @param string the message as printed on the console. * @param string the message as printed on the console.
*/ */
void NetworkAdminConsole(const char *origin, const char *string) void NetworkAdminConsole(const std::string_view origin, const std::string_view string)
{ {
for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) { for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) {
if (as->update_frequency[ADMIN_UPDATE_CONSOLE] & ADMIN_FREQUENCY_AUTOMATIC) { if (as->update_frequency[ADMIN_UPDATE_CONSOLE] & ADMIN_FREQUENCY_AUTOMATIC) {
@@ -948,7 +944,7 @@ void NetworkAdminConsole(const char *origin, const char *string)
* Send GameScript JSON to the admin network (if they did opt in for the respective update). * Send GameScript JSON to the admin network (if they did opt in for the respective update).
* @param json The JSON data as received from the GameScript. * @param json The JSON data as received from the GameScript.
*/ */
void NetworkAdminGameScript(const char *json) void NetworkAdminGameScript(const std::string_view json)
{ {
for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) { for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) {
if (as->update_frequency[ADMIN_UPDATE_GAMESCRIPT] & ADMIN_FREQUENCY_AUTOMATIC) { if (as->update_frequency[ADMIN_UPDATE_GAMESCRIPT] & ADMIN_FREQUENCY_AUTOMATIC) {

View File

@@ -62,12 +62,12 @@ public:
NetworkRecvStatus SendCompanyStats(); NetworkRecvStatus SendCompanyStats();
NetworkRecvStatus SendChat(NetworkAction action, DestType desttype, ClientID client_id, const std::string &msg, NetworkTextMessageData data); NetworkRecvStatus SendChat(NetworkAction action, DestType desttype, ClientID client_id, const std::string &msg, NetworkTextMessageData data);
NetworkRecvStatus SendRcon(uint16 colour, const char *command); NetworkRecvStatus SendRcon(uint16 colour, const std::string_view command);
NetworkRecvStatus SendConsole(const char *origin, const char *command); NetworkRecvStatus SendConsole(const std::string_view origin, const std::string_view command);
NetworkRecvStatus SendGameScript(const char *json); NetworkRecvStatus SendGameScript(const std::string_view json);
NetworkRecvStatus SendCmdNames(); NetworkRecvStatus SendCmdNames();
NetworkRecvStatus SendCmdLogging(ClientID client_id, const CommandPacket *cp); NetworkRecvStatus SendCmdLogging(ClientID client_id, const CommandPacket *cp);
NetworkRecvStatus SendRconEnd(const char *command); NetworkRecvStatus SendRconEnd(const std::string_view command);
static void Send(); static void Send();
static void AcceptConnection(SOCKET s, const NetworkAddress &address); static void AcceptConnection(SOCKET s, const NetworkAddress &address);
@@ -108,9 +108,9 @@ void NetworkAdminCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason bc
void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_id, const std::string &msg, NetworkTextMessageData data = NetworkTextMessageData(), bool from_admin = false); void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_id, const std::string &msg, NetworkTextMessageData data = NetworkTextMessageData(), bool from_admin = false);
void NetworkAdminUpdate(AdminUpdateFrequency freq); void NetworkAdminUpdate(AdminUpdateFrequency freq);
void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code, const char *string); void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code, const std::string_view string);
void NetworkAdminConsole(const char *origin, const char *string); void NetworkAdminConsole(const std::string_view origin, const std::string_view string);
void NetworkAdminGameScript(const char *json); void NetworkAdminGameScript(const std::string_view json);
void NetworkAdminCmdLogging(const NetworkClientSocket *owner, const CommandPacket *cp); void NetworkAdminCmdLogging(const NetworkClientSocket *owner, const CommandPacket *cp);
#endif /* NETWORK_ADMIN_H */ #endif /* NETWORK_ADMIN_H */

View File

@@ -612,7 +612,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetPassword(const std::str
* Tell the server that we like to change the name of the client. * Tell the server that we like to change the name of the client.
* @param name The new name. * @param name The new name.
*/ */
NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetName(const char *name) NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetName(const std::string &name)
{ {
Packet *p = new Packet(PACKET_CLIENT_SET_NAME, SHRT_MAX); Packet *p = new Packet(PACKET_CLIENT_SET_NAME, SHRT_MAX);
@@ -637,7 +637,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendQuit()
* @param pass The password for the remote command. * @param pass The password for the remote command.
* @param command The actual command. * @param command The actual command.
*/ */
NetworkRecvStatus ClientNetworkGameSocketHandler::SendRCon(const std::string &pass, const char *command) NetworkRecvStatus ClientNetworkGameSocketHandler::SendRCon(const std::string &pass, const std::string &command)
{ {
Packet *p = new Packet(PACKET_CLIENT_RCON, SHRT_MAX); Packet *p = new Packet(PACKET_CLIENT_RCON, SHRT_MAX);
p->Send_string(GenerateCompanyPasswordHash(pass, _password_server_id, _rcon_password_game_seed)); p->Send_string(GenerateCompanyPasswordHash(pass, _password_server_id, _rcon_password_game_seed));
@@ -1467,7 +1467,7 @@ void NetworkClient_Connected()
* @param password The password. * @param password The password.
* @param command The command to execute. * @param command The command to execute.
*/ */
void NetworkClientSendRcon(const std::string &password, const char *command) void NetworkClientSendRcon(const std::string &password, const std::string &command)
{ {
MyClient::SendRCon(password, command); MyClient::SendRCon(password, command);
} }
@@ -1574,12 +1574,11 @@ void NetworkUpdateClientName(const std::string &client_name)
/* Don't change the name if it is the same as the old name */ /* Don't change the name if it is the same as the old name */
if (client_name.compare(ci->client_name) != 0) { if (client_name.compare(ci->client_name) != 0) {
if (!_network_server) { if (!_network_server) {
MyClient::SendSetName(client_name.c_str()); MyClient::SendSetName(client_name);
} else { } else {
/* Copy to a temporary buffer so no #n gets added after our name in the settings when there are duplicate names. */ /* Copy to a temporary buffer so no #n gets added after our name in the settings when there are duplicate names. */
char temporary_name[NETWORK_CLIENT_NAME_LENGTH]; std::string temporary_name = client_name;
strecpy(temporary_name, client_name.c_str(), lastof(temporary_name)); if (NetworkMakeClientNameUnique(temporary_name)) {
if (NetworkFindName(temporary_name, lastof(temporary_name))) {
NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, temporary_name); NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, temporary_name);
ci->client_name = temporary_name; ci->client_name = temporary_name;
NetworkUpdateClientInfo(CLIENT_ID_SERVER); NetworkUpdateClientInfo(CLIENT_ID_SERVER);

View File

@@ -110,8 +110,8 @@ public:
static NetworkRecvStatus SendChat(NetworkAction action, DestType type, int dest, const std::string &msg, NetworkTextMessageData data); static NetworkRecvStatus SendChat(NetworkAction action, DestType type, int dest, const std::string &msg, NetworkTextMessageData data);
static NetworkRecvStatus SendSetPassword(const std::string &password); static NetworkRecvStatus SendSetPassword(const std::string &password);
static NetworkRecvStatus SendSetName(const char *name); static NetworkRecvStatus SendSetName(const std::string &name);
static NetworkRecvStatus SendRCon(const std::string &password, const char *command); static NetworkRecvStatus SendRCon(const std::string &password, const std::string &command);
static NetworkRecvStatus SendMove(CompanyID company, const std::string &password); static NetworkRecvStatus SendMove(CompanyID company, const std::string &password);
static bool IsConnected(); static bool IsConnected();

View File

@@ -55,7 +55,7 @@ void NetworkClientsToSpectators(CompanyID cid);
bool NetworkClientConnectGame(const std::string &connection_string, CompanyID default_company, const std::string &join_server_password = "", const std::string &join_company_password = ""); bool NetworkClientConnectGame(const std::string &connection_string, CompanyID default_company, const std::string &join_server_password = "", const std::string &join_company_password = "");
void NetworkClientJoinGame(); void NetworkClientJoinGame();
void NetworkClientRequestMove(CompanyID company, const std::string &pass = ""); void NetworkClientRequestMove(CompanyID company, const std::string &pass = "");
void NetworkClientSendRcon(const std::string &password, const char *command); void NetworkClientSendRcon(const std::string &password, const std::string &command);
void NetworkClientSendSettingsPassword(const std::string &password); void NetworkClientSendSettingsPassword(const std::string &password);
void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const std::string &msg, NetworkTextMessageData data = NetworkTextMessageData()); void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const std::string &msg, NetworkTextMessageData data = NetworkTextMessageData());
void NetworkClientSendDesyncMsg(const char *msg); void NetworkClientSendDesyncMsg(const char *msg);
@@ -75,16 +75,16 @@ void NetworkServerUpdateGameInfo();
void NetworkServerShowStatusToConsole(); void NetworkServerShowStatusToConsole();
bool NetworkServerStart(); bool NetworkServerStart();
void NetworkServerNewCompany(const Company *company, NetworkClientInfo *ci); void NetworkServerNewCompany(const Company *company, NetworkClientInfo *ci);
bool NetworkServerChangeClientName(ClientID client_id, const char *new_name); bool NetworkServerChangeClientName(ClientID client_id, const std::string &new_name);
void NetworkServerDoMove(ClientID client_id, CompanyID company_id); void NetworkServerDoMove(ClientID client_id, CompanyID company_id);
void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const char *string); void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const std::string &string);
void NetworkServerSendChat(NetworkAction action, DestType type, int dest, const std::string &msg, ClientID from_id, NetworkTextMessageData data = NetworkTextMessageData(), bool from_admin = false); void NetworkServerSendChat(NetworkAction action, DestType type, int dest, const std::string &msg, ClientID from_id, NetworkTextMessageData data = NetworkTextMessageData(), bool from_admin = false);
void NetworkServerKickClient(ClientID client_id, const char *reason); void NetworkServerKickClient(ClientID client_id, const std::string &reason);
uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const char *reason); uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const std::string &reason);
uint NetworkServerKickOrBanIP(const char *ip, bool ban, const char *reason); uint NetworkServerKickOrBanIP(const std::string &ip, bool ban, const std::string &reason);
void NetworkInitChatMessage(); void NetworkInitChatMessage();
void CDECL NetworkAddChatMessage(TextColour colour, uint duration, const std::string &message); void CDECL NetworkAddChatMessage(TextColour colour, uint duration, const std::string &message);

View File

@@ -1676,7 +1676,7 @@ enum DropDownAdmin {
*/ */
static void AdminClientKickCallback(Window *w, bool confirmed) static void AdminClientKickCallback(Window *w, bool confirmed)
{ {
if (confirmed) NetworkServerKickClient(_admin_client_id, nullptr); if (confirmed) NetworkServerKickClient(_admin_client_id, {});
} }
/** /**
@@ -1686,7 +1686,7 @@ static void AdminClientKickCallback(Window *w, bool confirmed)
*/ */
static void AdminClientBanCallback(Window *w, bool confirmed) static void AdminClientBanCallback(Window *w, bool confirmed)
{ {
if (confirmed) NetworkServerKickOrBanIP(_admin_client_id, true, nullptr); if (confirmed) NetworkServerKickOrBanIP(_admin_client_id, true, {});
} }
/** /**

View File

@@ -124,7 +124,7 @@ void ShowNetworkError(StringID error_string);
void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send, const std::string &name, const std::string &str = "", NetworkTextMessageData data = NetworkTextMessageData()); void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send, const std::string &name, const std::string &str = "", NetworkTextMessageData data = NetworkTextMessageData());
uint NetworkCalculateLag(const NetworkClientSocket *cs); uint NetworkCalculateLag(const NetworkClientSocket *cs);
StringID GetNetworkErrorMsg(NetworkErrorCode err); StringID GetNetworkErrorMsg(NetworkErrorCode err);
bool NetworkFindName(char *new_name, const char *last); bool NetworkMakeClientNameUnique(std::string &new_name);
std::string GenerateCompanyPasswordHash(const std::string &password, const std::string &password_server_id, uint32 password_game_seed); std::string GenerateCompanyPasswordHash(const std::string &password, const std::string &password_server_id, uint32 password_game_seed);
NetworkAddress ParseConnectionString(const std::string &connection_string, uint16 default_port); NetworkAddress ParseConnectionString(const std::string &connection_string, uint16 default_port);

View File

@@ -443,12 +443,12 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyInfo()
* @param error The error to disconnect for. * @param error The error to disconnect for.
* @param reason In case of kicking a client, specifies the reason for kicking the client. * @param reason In case of kicking a client, specifies the reason for kicking the client.
*/ */
NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode error, const char *reason) NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode error, const std::string &reason)
{ {
Packet *p = new Packet(PACKET_SERVER_ERROR, SHRT_MAX); Packet *p = new Packet(PACKET_SERVER_ERROR, SHRT_MAX);
p->Send_uint8(error); p->Send_uint8(error);
if (reason != nullptr) p->Send_string(reason); if (!reason.empty()) p->Send_string(reason);
this->SendPacket(p); this->SendPacket(p);
StringID strid = GetNetworkErrorMsg(error); StringID strid = GetNetworkErrorMsg(error);
@@ -461,7 +461,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode err
DEBUG(net, 1, "'%s' made an error and has been disconnected: %s", client_name, GetString(strid).c_str()); DEBUG(net, 1, "'%s' made an error and has been disconnected: %s", client_name, GetString(strid).c_str());
if (error == NETWORK_ERROR_KICKED && reason != nullptr) { if (error == NETWORK_ERROR_KICKED && !reason.empty()) {
NetworkTextMessage(NETWORK_ACTION_KICKED, CC_DEFAULT, false, client_name, reason, strid); NetworkTextMessage(NETWORK_ACTION_KICKED, CC_DEFAULT, false, client_name, reason, strid);
} else { } else {
NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, "", strid); NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, "", strid);
@@ -823,7 +823,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGame()
* @param colour The colour of the result. * @param colour The colour of the result.
* @param command The command that was executed. * @param command The command that was executed.
*/ */
NetworkRecvStatus ServerNetworkGameSocketHandler::SendRConResult(uint16 colour, const char *command) NetworkRecvStatus ServerNetworkGameSocketHandler::SendRConResult(uint16 colour, const std::string &command)
{ {
Packet *p = new Packet(PACKET_SERVER_RCON, SHRT_MAX); Packet *p = new Packet(PACKET_SERVER_RCON, SHRT_MAX);
@@ -928,8 +928,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p)
return this->SendError(NETWORK_ERROR_NOT_EXPECTED); return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
} }
char name[NETWORK_CLIENT_NAME_LENGTH];
CompanyID playas;
char client_revision[NETWORK_REVISION_LENGTH]; char client_revision[NETWORK_REVISION_LENGTH];
p->Recv_string(client_revision, sizeof(client_revision)); p->Recv_string(client_revision, sizeof(client_revision));
@@ -941,8 +939,8 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p)
return this->SendError(NETWORK_ERROR_WRONG_REVISION); return this->SendError(NETWORK_ERROR_WRONG_REVISION);
} }
p->Recv_string(name, sizeof(name)); std::string client_name = p->Recv_string(NETWORK_CLIENT_NAME_LENGTH);
playas = (Owner)p->Recv_uint8(); CompanyID playas = (Owner)p->Recv_uint8();
if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CLIENT_QUIT; if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CLIENT_QUIT;
@@ -965,14 +963,14 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p)
break; break;
} }
if (!NetworkIsValidClientName(name)) { if (!NetworkIsValidClientName(client_name)) {
/* An invalid client name was given. However, the client ensures the name /* An invalid client name was given. However, the client ensures the name
* is valid before it is sent over the network, so something went horribly * is valid before it is sent over the network, so something went horribly
* wrong. This is probably someone trying to troll us. */ * wrong. This is probably someone trying to troll us. */
return this->SendError(NETWORK_ERROR_INVALID_CLIENT_NAME); return this->SendError(NETWORK_ERROR_INVALID_CLIENT_NAME);
} }
if (!NetworkFindName(name, lastof(name))) { // Change name if duplicate if (!NetworkMakeClientNameUnique(client_name)) { // Change name if duplicate
/* We could not create a name for this client */ /* We could not create a name for this client */
return this->SendError(NETWORK_ERROR_NAME_IN_USE); return this->SendError(NETWORK_ERROR_NAME_IN_USE);
} }
@@ -981,7 +979,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p)
NetworkClientInfo *ci = new NetworkClientInfo(this->client_id); NetworkClientInfo *ci = new NetworkClientInfo(this->client_id);
this->SetInfo(ci); this->SetInfo(ci);
ci->join_date = _date; ci->join_date = _date;
ci->client_name = name; ci->client_name = client_name;
ci->client_playas = playas; ci->client_playas = playas;
DEBUG(desync, 1, "client: date{%08x; %02x; %02x}; client: %02x; company: %02x", _date, _date_fract, _tick_skip_counter, (int)ci->index, (int)ci->client_playas); DEBUG(desync, 1, "client: date{%08x; %02x; %02x}; client: %02x; company: %02x", _date, _date_fract, _tick_skip_counter, (int)ci->index, (int)ci->client_playas);
@@ -1528,10 +1526,9 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SET_NAME(Packet
return this->SendError(NETWORK_ERROR_NOT_EXPECTED); return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
} }
char client_name[NETWORK_CLIENT_NAME_LENGTH];
NetworkClientInfo *ci; NetworkClientInfo *ci;
p->Recv_string(client_name, sizeof(client_name)); std::string client_name = p->Recv_string(NETWORK_CLIENT_NAME_LENGTH);
ci = this->GetInfo(); ci = this->GetInfo();
if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CLIENT_QUIT; if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CLIENT_QUIT;
@@ -1545,7 +1542,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SET_NAME(Packet
} }
/* Display change */ /* Display change */
if (NetworkFindName(client_name, lastof(client_name))) { if (NetworkMakeClientNameUnique(client_name)) {
NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, client_name); NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, client_name);
ci->client_name = client_name; ci->client_name = client_name;
NetworkUpdateClientInfo(ci->client_id); NetworkUpdateClientInfo(ci->client_id);
@@ -1558,15 +1555,13 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_RCON(Packet *p)
{ {
if (this->status != STATUS_ACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED); if (this->status != STATUS_ACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
char command[NETWORK_RCONCOMMAND_LENGTH];
if (_settings_client.network.rcon_password.empty()) { if (_settings_client.network.rcon_password.empty()) {
NetworkServerSendRcon(this->client_id, CC_ERROR, "Access Denied"); NetworkServerSendRcon(this->client_id, CC_ERROR, "Access Denied");
return NETWORK_RECV_STATUS_OKAY; return NETWORK_RECV_STATUS_OKAY;
} }
std::string password = p->Recv_string(NETWORK_PASSWORD_LENGTH); std::string password = p->Recv_string(NETWORK_PASSWORD_LENGTH);
p->Recv_string(command, sizeof(command)); std::string command = p->Recv_string(NETWORK_RCONCOMMAND_LENGTH);
if (password != GenerateCompanyPasswordHash(_settings_client.network.rcon_password.c_str(), _settings_client.network.network_id.c_str(), _settings_game.game_creation.generation_seed ^ this->rcon_hash_bits)) { if (password != GenerateCompanyPasswordHash(_settings_client.network.rcon_password.c_str(), _settings_client.network.network_id.c_str(), _settings_game.game_creation.generation_seed ^ this->rcon_hash_bits)) {
DEBUG(net, 0, "[rcon] wrong password from client-id %d", this->client_id); DEBUG(net, 0, "[rcon] wrong password from client-id %d", this->client_id);
@@ -1574,10 +1569,10 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_RCON(Packet *p)
return NETWORK_RECV_STATUS_OKAY; return NETWORK_RECV_STATUS_OKAY;
} }
DEBUG(net, 3, "[rcon] Client-id %d executed: %s", this->client_id, command); DEBUG(net, 3, "[rcon] Client-id %d executed: %s", this->client_id, command.c_str());
_redirect_console_to_client = this->client_id; _redirect_console_to_client = this->client_id;
IConsoleCmdExec(command); IConsoleCmdExec(command.c_str());
_redirect_console_to_client = INVALID_CLIENT_ID; _redirect_console_to_client = INVALID_CLIENT_ID;
return NETWORK_RECV_STATUS_OKAY; return NETWORK_RECV_STATUS_OKAY;
} }
@@ -1837,42 +1832,40 @@ static void NetworkAutoCleanCompanies()
/** /**
* Check whether a name is unique, and otherwise try to make it unique. * Check whether a name is unique, and otherwise try to make it unique.
* @param new_name The name to check/modify. * @param new_name The name to check/modify.
* @param last The last writeable element of the buffer.
* @return True if an unique name was achieved. * @return True if an unique name was achieved.
*/ */
bool NetworkFindName(char *new_name, const char *last) bool NetworkMakeClientNameUnique(std::string &name)
{ {
bool found_name = false; bool is_name_unique = false;
uint number = 0; uint number = 0;
char original_name[NETWORK_CLIENT_NAME_LENGTH]; std::string original_name = name;
strecpy(original_name, new_name, lastof(original_name)); while (!is_name_unique) {
is_name_unique = true;
while (!found_name) {
found_name = true;
for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) {
if (ci->client_name.compare(new_name) == 0) { if (ci->client_name.compare(name) == 0) {
/* Name already in use */ /* Name already in use */
found_name = false; is_name_unique = false;
break; break;
} }
} }
/* Check if it is the same as the server-name */ /* Check if it is the same as the server-name */
const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER); const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER);
if (ci != nullptr) { if (ci != nullptr) {
if (ci->client_name.compare(new_name) == 0) found_name = false; // name already in use if (ci->client_name.compare(name) == 0) is_name_unique = false; // name already in use
} }
if (!found_name) { if (!is_name_unique) {
/* Try a new name (<name> #1, <name> #2, and so on) */ /* Try a new name (<name> #1, <name> #2, and so on) */
name = original_name + " #" + std::to_string(number);
/* Something's really wrong when there're more names than clients */ /* The constructed client name is larger than the limit,
if (number++ > MAX_CLIENTS) break; * so... bail out as no valid name can be created. */
seprintf(new_name, last, "%s #%d", original_name, number); if (name.size() >= NETWORK_CLIENT_NAME_LENGTH) return false;
} }
} }
return found_name; return is_name_unique;
} }
/** /**
@@ -1881,7 +1874,7 @@ bool NetworkFindName(char *new_name, const char *last)
* @param new_name the new name for the client * @param new_name the new name for the client
* @return true iff the name was changed * @return true iff the name was changed
*/ */
bool NetworkServerChangeClientName(ClientID client_id, const char *new_name) bool NetworkServerChangeClientName(ClientID client_id, const std::string &new_name)
{ {
/* Check if the name's already in use */ /* Check if the name's already in use */
for (NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { for (NetworkClientInfo *ci : NetworkClientInfo::Iterate()) {
@@ -2213,7 +2206,7 @@ void NetworkServerDoMove(ClientID client_id, CompanyID company_id)
* @param colour_code The colour of the text. * @param colour_code The colour of the text.
* @param string The actual reply. * @param string The actual reply.
*/ */
void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const char *string) void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const std::string &string)
{ {
NetworkClientSocket::GetByClientID(client_id)->SendRConResult(colour_code, string); NetworkClientSocket::GetByClientID(client_id)->SendRConResult(colour_code, string);
} }
@@ -2223,7 +2216,7 @@ void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const cha
* @param client_id The client to kick. * @param client_id The client to kick.
* @param reason In case of kicking a client, specifies the reason for kicking the client. * @param reason In case of kicking a client, specifies the reason for kicking the client.
*/ */
void NetworkServerKickClient(ClientID client_id, const char *reason) void NetworkServerKickClient(ClientID client_id, const std::string &reason)
{ {
if (client_id == CLIENT_ID_SERVER) return; if (client_id == CLIENT_ID_SERVER) return;
NetworkClientSocket::GetByClientID(client_id)->SendError(NETWORK_ERROR_KICKED, reason); NetworkClientSocket::GetByClientID(client_id)->SendError(NETWORK_ERROR_KICKED, reason);
@@ -2235,7 +2228,7 @@ void NetworkServerKickClient(ClientID client_id, const char *reason)
* @param ban Whether to ban or kick. * @param ban Whether to ban or kick.
* @param reason In case of kicking a client, specifies the reason for kicking the client. * @param reason In case of kicking a client, specifies the reason for kicking the client.
*/ */
uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const char *reason) uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const std::string &reason)
{ {
return NetworkServerKickOrBanIP(NetworkClientSocket::GetByClientID(client_id)->GetClientIP(), ban, reason); return NetworkServerKickOrBanIP(NetworkClientSocket::GetByClientID(client_id)->GetClientIP(), ban, reason);
} }
@@ -2246,7 +2239,7 @@ uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const char *reason)
* @param ban Whether to ban or just kick. * @param ban Whether to ban or just kick.
* @param reason In case of kicking a client, specifies the reason for kicking the client. * @param reason In case of kicking a client, specifies the reason for kicking the client.
*/ */
uint NetworkServerKickOrBanIP(const char *ip, bool ban, const char *reason) uint NetworkServerKickOrBanIP(const std::string &ip, bool ban, const std::string &reason)
{ {
/* Add address to ban-list */ /* Add address to ban-list */
if (ban) { if (ban) {
@@ -2270,7 +2263,7 @@ uint NetworkServerKickOrBanIP(const char *ip, bool ban, const char *reason)
for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
if (cs->client_id == CLIENT_ID_SERVER) continue; if (cs->client_id == CLIENT_ID_SERVER) continue;
if (cs->client_id == _redirect_console_to_client) continue; if (cs->client_id == _redirect_console_to_client) continue;
if (cs->client_address.IsInNetmask(ip)) { if (cs->client_address.IsInNetmask(ip.c_str())) {
NetworkServerKickClient(cs->client_id, reason); NetworkServerKickClient(cs->client_id, reason);
n++; n++;
} }

View File

@@ -103,11 +103,11 @@ public:
NetworkRecvStatus SendQuit(ClientID client_id); NetworkRecvStatus SendQuit(ClientID client_id);
NetworkRecvStatus SendShutdown(); NetworkRecvStatus SendShutdown();
NetworkRecvStatus SendNewGame(); NetworkRecvStatus SendNewGame();
NetworkRecvStatus SendRConResult(uint16 colour, const char *command); NetworkRecvStatus SendRConResult(uint16 colour, const std::string &command);
NetworkRecvStatus SendMove(ClientID client_id, CompanyID company_id); NetworkRecvStatus SendMove(ClientID client_id, CompanyID company_id);
NetworkRecvStatus SendClientInfo(NetworkClientInfo *ci); NetworkRecvStatus SendClientInfo(NetworkClientInfo *ci);
NetworkRecvStatus SendError(NetworkErrorCode error, const char *reason = nullptr); NetworkRecvStatus SendError(NetworkErrorCode error, const std::string &reason = {});
NetworkRecvStatus SendDesyncLog(const std::string &log); NetworkRecvStatus SendDesyncLog(const std::string &log);
NetworkRecvStatus SendChat(NetworkAction action, ClientID client_id, bool self_send, const std::string &msg, NetworkTextMessageData data); NetworkRecvStatus SendChat(NetworkAction action, ClientID client_id, bool self_send, const std::string &msg, NetworkTextMessageData data);
NetworkRecvStatus SendJoin(ClientID client_id); NetworkRecvStatus SendJoin(ClientID client_id);

View File

@@ -2678,7 +2678,7 @@ static std::string ReadDWordAsString(ByteReader *reader)
char output[5]; char output[5];
for (int i = 0; i < 4; i++) output[i] = reader->ReadByte(); for (int i = 0; i < 4; i++) output[i] = reader->ReadByte();
output[4] = '\0'; output[4] = '\0';
str_validate(output, lastof(output)); StrMakeValidInPlace(output, lastof(output));
return std::string(output); return std::string(output);
} }

View File

@@ -254,9 +254,8 @@ static_assert(lengthof(_news_type_data) == NT_END);
NewsDisplay NewsTypeData::GetDisplay() const NewsDisplay NewsTypeData::GetDisplay() const
{ {
const SettingDesc *sd = GetSettingFromName(this->name); const SettingDesc *sd = GetSettingFromName(this->name);
assert(sd != nullptr); assert(sd != nullptr && sd->IsIntSetting());
void *ptr = GetVariableAddress(nullptr, &sd->save); return (NewsDisplay)sd->AsIntSetting()->Read(nullptr);
return (NewsDisplay)ReadValue(ptr, sd->save.conv);
} }
/** Window class displaying a news item. */ /** Window class displaying a news item. */

View File

@@ -15,6 +15,7 @@
#include "tile_type.h" #include "tile_type.h"
#include "vehicle_type.h" #include "vehicle_type.h"
#include "base_consist.h" #include "base_consist.h"
#include "saveload/saveload.h"
/** Unique identifier for an order backup. */ /** Unique identifier for an order backup. */
typedef uint8 OrderBackupID; typedef uint8 OrderBackupID;
@@ -34,7 +35,7 @@ static const uint32 MAKE_ORDER_BACKUP_FLAG = 1U << 31;
*/ */
struct OrderBackup : OrderBackupPool::PoolItem<&_order_backup_pool>, BaseConsist { struct OrderBackup : OrderBackupPool::PoolItem<&_order_backup_pool>, BaseConsist {
private: private:
friend const struct SaveLoad *GetOrderBackupDescription(); ///< Saving and loading of order backups. friend SaveLoadTable GetOrderBackupDescription(); ///< Saving and loading of order backups.
friend void Load_BKOR(); ///< Creating empty orders upon savegame loading. friend void Load_BKOR(); ///< Creating empty orders upon savegame loading.
uint32 user; ///< The user that requested the backup. uint32 user; ///< The user that requested the backup.
TileIndex tile; ///< Tile of the depot where the order was changed. TileIndex tile; ///< Tile of the depot where the order was changed.

View File

@@ -19,6 +19,7 @@
#include "vehicle_type.h" #include "vehicle_type.h"
#include "date_type.h" #include "date_type.h"
#include "schdispatch.h" #include "schdispatch.h"
#include "saveload/saveload.h"
#include <memory> #include <memory>
#include <vector> #include <vector>
@@ -62,9 +63,9 @@ struct OrderExtraInfo {
*/ */
struct Order : OrderPool::PoolItem<&_order_pool> { struct Order : OrderPool::PoolItem<&_order_pool> {
private: private:
friend const struct SaveLoad *GetVehicleDescription(VehicleType vt); ///< Saving and loading the current order of vehicles. friend SaveLoadTable GetVehicleDescription(VehicleType vt); ///< Saving and loading the current order of vehicles.
friend void Load_VEHS(); ///< Loading of ancient vehicles. friend void Load_VEHS(); ///< Loading of ancient vehicles.
friend const struct SaveLoad *GetOrderDescription(); ///< Saving and loading of orders. friend SaveLoadTable GetOrderDescription(); ///< Saving and loading of orders.
friend void Load_ORDX(); ///< Saving and loading of orders. friend void Load_ORDX(); ///< Saving and loading of orders.
friend void Save_ORDX(); ///< Saving and loading of orders. friend void Save_ORDX(); ///< Saving and loading of orders.
friend void Load_VEOX(); ///< Saving and loading of orders. friend void Load_VEOX(); ///< Saving and loading of orders.
@@ -586,7 +587,7 @@ template <typename T, typename F> T CargoMaskValueFilter(CargoTypes &cargo_mask,
struct OrderList : OrderListPool::PoolItem<&_orderlist_pool> { struct OrderList : OrderListPool::PoolItem<&_orderlist_pool> {
private: private:
friend void AfterLoadVehicles(bool part_of_load); ///< For instantiating the shared vehicle chain friend void AfterLoadVehicles(bool part_of_load); ///< For instantiating the shared vehicle chain
friend const struct SaveLoad *GetOrderListDescription(); ///< Saving and loading of order lists. friend SaveLoadTable GetOrderListDescription(); ///< Saving and loading of order lists.
friend void Ptrs_ORDL(); ///< Saving and loading of order lists. friend void Ptrs_ORDL(); ///< Saving and loading of order lists.
StationID GetBestLoadableNext(const Vehicle *v, const Order *o1, const Order *o2) const; StationID GetBestLoadableNext(const Vehicle *v, const Order *o1, const Order *o2) const;

View File

@@ -74,8 +74,8 @@
#endif #endif
/* Check for mismatching 'architectures' */ /* Check for mismatching 'architectures' */
#if !defined(STRGEN) && !defined(SETTINGSGEN) && ((defined(__LP64__) && !defined(_SQ64)) || (!defined(__LP64__) && defined(_SQ64))) #if !defined(STRGEN) && !defined(SETTINGSGEN) && ((defined(__LP64__) && !defined(POINTER_IS_64BIT)) || (!defined(__LP64__) && defined(POINTER_IS_64BIT)))
# error "Compiling 64 bits without _SQ64 set! (or vice versa)" # error "Compiling 64 bits without POINTER_IS_64BIT set! (or vice versa)"
#endif #endif
/* Name conflict */ /* Name conflict */

View File

@@ -174,7 +174,7 @@ int CDECL main(int argc, char *argv[])
SetRandomSeed(time(nullptr)); SetRandomSeed(time(nullptr));
/* Make sure our arguments contain only valid UTF-8 characters. */ /* Make sure our arguments contain only valid UTF-8 characters. */
for (int i = 0; i < argc; i++) ValidateString(argv[i]); for (int i = 0; i < argc; i++) StrMakeValidInPlace(argv[i]);
return openttd_main(argc, argv); return openttd_main(argc, argv);
} }

View File

@@ -243,7 +243,7 @@ void CocoaReleaseAutoreleasePool();
int CDECL main(int argc, char *argv[]) int CDECL main(int argc, char *argv[])
{ {
/* Make sure our arguments contain only valid UTF-8 characters. */ /* Make sure our arguments contain only valid UTF-8 characters. */
for (int i = 0; i < argc; i++) ValidateString(argv[i]); for (int i = 0; i < argc; i++) StrMakeValidInPlace(argv[i]);
#ifdef WITH_COCOA #ifdef WITH_COCOA
CocoaSetupAutoreleasePool(); CocoaSetupAutoreleasePool();

View File

@@ -436,7 +436,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
argc = ParseCommandLine(cmdline, argv, lengthof(argv)); argc = ParseCommandLine(cmdline, argv, lengthof(argv));
/* Make sure our arguments contain only valid UTF-8 characters. */ /* Make sure our arguments contain only valid UTF-8 characters. */
for (int i = 0; i < argc; i++) ValidateString(argv[i]); for (int i = 0; i < argc; i++) StrMakeValidInPlace(argv[i]);
openttd_main(argc, argv); openttd_main(argc, argv);

View File

@@ -1970,15 +1970,15 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, DoCommandFlag flags, uin
last_suitable_trackdir = trackdir; last_suitable_trackdir = trackdir;
} else if (!test_only && last_suitable_tile != INVALID_TILE && ret.GetErrorMessage() != STR_ERROR_CANNOT_MODIFY_TRACK_TRAIN_APPROACHING) { } else if (!test_only && last_suitable_tile != INVALID_TILE && ret.GetErrorMessage() != STR_ERROR_CANNOT_MODIFY_TRACK_TRAIN_APPROACHING) {
/* If a signal can't be placed, place it at the last possible position. */ /* If a signal can't be placed, place it at the last possible position. */
SB(p1, 0, 3, TrackdirToTrack(last_suitable_trackdir)); SB(param1, 0, 3, TrackdirToTrack(last_suitable_trackdir));
ClrBit(p1, 17); ClrBit(param1, 17);
/* Pick the correct orientation for the track direction. */ /* Pick the correct orientation for the track direction. */
signals = 0; signals = 0;
if (HasBit(signal_dir, 0)) signals |= SignalAlongTrackdir(last_suitable_trackdir); if (HasBit(signal_dir, 0)) signals |= SignalAlongTrackdir(last_suitable_trackdir);
if (HasBit(signal_dir, 1)) signals |= SignalAgainstTrackdir(last_suitable_trackdir); if (HasBit(signal_dir, 1)) signals |= SignalAgainstTrackdir(last_suitable_trackdir);
ret = DoCommand(last_suitable_tile, p1, signals, flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS); ret = DoCommand(last_suitable_tile, param1, signals, flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS);
if (ret.Succeeded() && IsTileType(last_suitable_tile, MP_TUNNELBRIDGE) && GetTunnelBridgeDirection(last_suitable_tile) == TrackdirToExitdir(last_suitable_trackdir)) { if (ret.Succeeded() && IsTileType(last_suitable_tile, MP_TUNNELBRIDGE) && GetTunnelBridgeDirection(last_suitable_tile) == TrackdirToExitdir(last_suitable_trackdir)) {
/* Blacklist far end of tunnel if we just actioned the near end */ /* Blacklist far end of tunnel if we just actioned the near end */
tunnel_bridge_blacklist.push_back(GetOtherTunnelBridgeEnd(last_suitable_tile)); tunnel_bridge_blacklist.push_back(GetOtherTunnelBridgeEnd(last_suitable_tile));

View File

@@ -30,7 +30,6 @@ static const SaveLoad _ai_company[] = {
SLEG_SSTR(_ai_saveload_settings, SLE_STR), SLEG_SSTR(_ai_saveload_settings, SLE_STR),
SLEG_CONDVAR(_ai_saveload_version, SLE_UINT32, SLV_108, SL_MAX_VERSION), SLEG_CONDVAR(_ai_saveload_version, SLE_UINT32, SLV_108, SL_MAX_VERSION),
SLEG_CONDVAR(_ai_saveload_is_random, SLE_BOOL, SLV_136, SL_MAX_VERSION), SLEG_CONDVAR(_ai_saveload_is_random, SLE_BOOL, SLV_136, SL_MAX_VERSION),
SLE_END()
}; };
static void SaveReal_AIPL(int *index_ptr) static void SaveReal_AIPL(int *index_ptr)

View File

@@ -21,7 +21,6 @@ static const SaveLoad _engine_renew_desc[] = {
SLE_REF(EngineRenew, next, REF_ENGINE_RENEWS), SLE_REF(EngineRenew, next, REF_ENGINE_RENEWS),
SLE_CONDVAR(EngineRenew, group_id, SLE_UINT16, SLV_60, SL_MAX_VERSION), SLE_CONDVAR(EngineRenew, group_id, SLE_UINT16, SLV_60, SL_MAX_VERSION),
SLE_CONDVAR(EngineRenew, replace_when_old, SLE_BOOL, SLV_175, SL_MAX_VERSION), SLE_CONDVAR(EngineRenew, replace_when_old, SLE_BOOL, SLV_175, SL_MAX_VERSION),
SLE_END()
}; };
static void Save_ERNW() static void Save_ERNW()

View File

@@ -19,7 +19,6 @@ struct LongBridgeSignalStorageStub {
static const SaveLoad _long_bridge_signal_storage_stub_desc[] = { static const SaveLoad _long_bridge_signal_storage_stub_desc[] = {
SLE_VAR(LongBridgeSignalStorageStub, length, SLE_UINT32), SLE_VAR(LongBridgeSignalStorageStub, length, SLE_UINT32),
SLE_END()
}; };
static void Load_XBSS() static void Load_XBSS()

View File

@@ -24,7 +24,6 @@ struct TempStorage {
static const SaveLoad _cargomonitor_pair_desc[] = { static const SaveLoad _cargomonitor_pair_desc[] = {
SLE_VAR(TempStorage, number, SLE_UINT32), SLE_VAR(TempStorage, number, SLE_UINT32),
SLE_VAR(TempStorage, amount, SLE_UINT32), SLE_VAR(TempStorage, amount, SLE_UINT32),
SLE_END()
}; };
static CargoMonitorID FixupCargoMonitor(CargoMonitorID number) static CargoMonitorID FixupCargoMonitor(CargoMonitorID number)

View File

@@ -108,7 +108,7 @@ extern btree::btree_map<uint64, Money> _cargo_packet_deferred_payments;
* some of the variables itself are private. * some of the variables itself are private.
* @return the saveload description for CargoPackets. * @return the saveload description for CargoPackets.
*/ */
const SaveLoad *GetCargoPacketDesc() SaveLoadTable GetCargoPacketDesc()
{ {
static const SaveLoad _cargopacket_desc[] = { static const SaveLoad _cargopacket_desc[] = {
SLE_VAR(CargoPacket, source, SLE_UINT16), SLE_VAR(CargoPacket, source, SLE_UINT16),
@@ -122,8 +122,6 @@ const SaveLoad *GetCargoPacketDesc()
/* Used to be paid_for, but that got changed. */ /* Used to be paid_for, but that got changed. */
SLE_CONDNULL(1, SL_MIN_VERSION, SLV_121), SLE_CONDNULL(1, SL_MIN_VERSION, SLV_121),
SLE_END()
}; };
return _cargopacket_desc; return _cargopacket_desc;
} }
@@ -136,7 +134,7 @@ static void Save_CAPA()
std::vector<SaveLoad> filtered_packet_desc = SlFilterObject(GetCargoPacketDesc()); std::vector<SaveLoad> filtered_packet_desc = SlFilterObject(GetCargoPacketDesc());
for (CargoPacket *cp : CargoPacket::Iterate()) { for (CargoPacket *cp : CargoPacket::Iterate()) {
SlSetArrayIndex(cp->index); SlSetArrayIndex(cp->index);
SlObjectSaveFiltered(cp, filtered_packet_desc.data()); SlObjectSaveFiltered(cp, filtered_packet_desc);
} }
} }
@@ -149,7 +147,7 @@ static void Load_CAPA()
int index; int index;
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
CargoPacket *cp = new (index) CargoPacket(); CargoPacket *cp = new (index) CargoPacket();
SlObjectLoadFiltered(cp, filtered_packet_desc.data()); SlObjectLoadFiltered(cp, filtered_packet_desc);
} }
} }

View File

@@ -79,7 +79,6 @@ static void Load_CHTX()
SLE_STR(CheatsExtLoad, name, SLE_STRB, 256), SLE_STR(CheatsExtLoad, name, SLE_STRB, 256),
SLE_VAR(CheatsExtLoad, cht.been_used, SLE_BOOL), SLE_VAR(CheatsExtLoad, cht.been_used, SLE_BOOL),
SLE_VAR(CheatsExtLoad, cht.value, SLE_BOOL), SLE_VAR(CheatsExtLoad, cht.value, SLE_BOOL),
SLE_END()
}; };
CheatsExtLoad current_cheat; CheatsExtLoad current_cheat;
@@ -122,7 +121,6 @@ static void Save_CHTX()
SLE_STR(CheatsExtSave, name, SLE_STR, 0), SLE_STR(CheatsExtSave, name, SLE_STR, 0),
SLE_VAR(CheatsExtSave, cht.been_used, SLE_BOOL), SLE_VAR(CheatsExtSave, cht.been_used, SLE_BOOL),
SLE_VAR(CheatsExtSave, cht.value, SLE_BOOL), SLE_VAR(CheatsExtSave, cht.value, SLE_BOOL),
SLE_END()
}; };
SlAutolength([](void *) { SlAutolength([](void *) {
@@ -153,7 +151,6 @@ static const SaveLoad _settings_ext_save_desc[] = {
SLE_VAR(SettingsExtSave, flags, SLE_UINT32), SLE_VAR(SettingsExtSave, flags, SLE_UINT32),
SLE_STR(SettingsExtSave, name, SLE_STR, 0), SLE_STR(SettingsExtSave, name, SLE_STR, 0),
SLE_VAR(SettingsExtSave, setting_length, SLE_UINT32), SLE_VAR(SettingsExtSave, setting_length, SLE_UINT32),
SLE_END()
}; };

View File

@@ -294,8 +294,6 @@ static const SaveLoad _company_desc[] = {
SLE_CONDVAR(CompanyProperties, tree_limit, SLE_UINT32, SLV_175, SL_MAX_VERSION), SLE_CONDVAR(CompanyProperties, tree_limit, SLE_UINT32, SLV_175, SL_MAX_VERSION),
SLE_CONDVAR_X(CompanyProperties, purchase_land_limit, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_BUY_LAND_RATE_LIMIT)), SLE_CONDVAR_X(CompanyProperties, purchase_land_limit, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_BUY_LAND_RATE_LIMIT)),
SLE_CONDVAR_X(CompanyProperties, build_object_limit, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_BUILD_OBJECT_RATE_LIMIT)), SLE_CONDVAR_X(CompanyProperties, build_object_limit, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_BUILD_OBJECT_RATE_LIMIT)),
SLE_END()
}; };
static const SaveLoad _company_settings_desc[] = { static const SaveLoad _company_settings_desc[] = {
@@ -316,8 +314,6 @@ static const SaveLoad _company_settings_desc[] = {
SLE_CONDVAR_X(Company, settings.vehicle.auto_timetable_by_default, SLE_BOOL, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_AUTO_TIMETABLE, 2, 2)), SLE_CONDVAR_X(Company, settings.vehicle.auto_timetable_by_default, SLE_BOOL, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_AUTO_TIMETABLE, 2, 2)),
SLE_CONDNULL(63, SLV_2, SLV_144), // old reserved space SLE_CONDNULL(63, SLV_2, SLV_144), // old reserved space
SLE_END()
}; };
static const SaveLoad _company_settings_skip_desc[] = { static const SaveLoad _company_settings_skip_desc[] = {
@@ -339,8 +335,6 @@ static const SaveLoad _company_settings_skip_desc[] = {
SLE_CONDNULL_X(1, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_AUTO_TIMETABLE, 2, 2)), // settings.vehicle.auto_timetable_by_default SLE_CONDNULL_X(1, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_AUTO_TIMETABLE, 2, 2)), // settings.vehicle.auto_timetable_by_default
SLE_CONDNULL(63, SLV_2, SLV_144), // old reserved space SLE_CONDNULL(63, SLV_2, SLV_144), // old reserved space
SLE_END()
}; };
static const SaveLoad _company_economy_desc[] = { static const SaveLoad _company_economy_desc[] = {
@@ -356,8 +350,6 @@ static const SaveLoad _company_economy_desc[] = {
SLE_CONDARR(CompanyEconomyEntry, delivered_cargo, SLE_UINT32, 32, SLV_170, SLV_EXTEND_CARGOTYPES), SLE_CONDARR(CompanyEconomyEntry, delivered_cargo, SLE_UINT32, 32, SLV_170, SLV_EXTEND_CARGOTYPES),
SLE_CONDARR(CompanyEconomyEntry, delivered_cargo, SLE_UINT32, NUM_CARGO, SLV_EXTEND_CARGOTYPES, SL_MAX_VERSION), SLE_CONDARR(CompanyEconomyEntry, delivered_cargo, SLE_UINT32, NUM_CARGO, SLV_EXTEND_CARGOTYPES, SL_MAX_VERSION),
SLE_VAR(CompanyEconomyEntry, performance_history, SLE_INT32), SLE_VAR(CompanyEconomyEntry, performance_history, SLE_INT32),
SLE_END()
}; };
/* We do need to read this single value, as the bigger it gets, the more data is stored */ /* We do need to read this single value, as the bigger it gets, the more data is stored */
@@ -393,7 +385,6 @@ static const SaveLoad _company_ai_desc[] = {
SLE_CONDNULL(32, SL_MIN_VERSION, SLV_107), SLE_CONDNULL(32, SL_MIN_VERSION, SLV_107),
SLE_CONDNULL(64, SLV_2, SLV_107), SLE_CONDNULL(64, SLV_2, SLV_107),
SLE_END()
}; };
static const SaveLoad _company_ai_build_rec_desc[] = { static const SaveLoad _company_ai_build_rec_desc[] = {
@@ -402,14 +393,12 @@ static const SaveLoad _company_ai_build_rec_desc[] = {
SLE_CONDNULL(2, SL_MIN_VERSION, SLV_6), SLE_CONDNULL(2, SL_MIN_VERSION, SLV_6),
SLE_CONDNULL(4, SLV_6, SLV_107), SLE_CONDNULL(4, SLV_6, SLV_107),
SLE_CONDNULL(8, SL_MIN_VERSION, SLV_107), SLE_CONDNULL(8, SL_MIN_VERSION, SLV_107),
SLE_END()
}; };
static const SaveLoad _company_livery_desc[] = { static const SaveLoad _company_livery_desc[] = {
SLE_CONDVAR(Livery, in_use, SLE_UINT8, SLV_34, SL_MAX_VERSION), SLE_CONDVAR(Livery, in_use, SLE_UINT8, SLV_34, SL_MAX_VERSION),
SLE_CONDVAR(Livery, colour1, SLE_UINT8, SLV_34, SL_MAX_VERSION), SLE_CONDVAR(Livery, colour1, SLE_UINT8, SLV_34, SL_MAX_VERSION),
SLE_CONDVAR(Livery, colour2, SLE_UINT8, SLV_34, SL_MAX_VERSION), SLE_CONDVAR(Livery, colour2, SLE_UINT8, SLV_34, SL_MAX_VERSION),
SLE_END()
}; };
static void SaveLoad_PLYR_common(Company *c, CompanyProperties *cprops) static void SaveLoad_PLYR_common(Company *c, CompanyProperties *cprops)

View File

@@ -26,7 +26,6 @@ static const SaveLoad _depot_desc[] = {
SLE_CONDSTR(Depot, name, SLE_STR, 0, SLV_141, SL_MAX_VERSION), SLE_CONDSTR(Depot, name, SLE_STR, 0, SLV_141, SL_MAX_VERSION),
SLE_CONDVAR(Depot, build_date, SLE_INT32, SLV_142, SL_MAX_VERSION), SLE_CONDVAR(Depot, build_date, SLE_INT32, SLV_142, SL_MAX_VERSION),
SLE_CONDNULL_X(4, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPRINGPP, 5)), SLE_CONDNULL_X(4, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPRINGPP, 5)),
SLE_END()
}; };
static void Save_DEPT() static void Save_DEPT()

View File

@@ -47,7 +47,6 @@ static const SaveLoad _economy_desc[] = {
SLE_VAR(Economy, infl_amount_pr, SLE_UINT8), SLE_VAR(Economy, infl_amount_pr, SLE_UINT8),
SLE_CONDVAR(Economy, industry_daily_change_counter, SLE_UINT32, SLV_102, SL_MAX_VERSION), SLE_CONDVAR(Economy, industry_daily_change_counter, SLE_UINT32, SLV_102, SL_MAX_VERSION),
SLE_CONDNULL_X(8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)), SLE_CONDNULL_X(8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)),
SLE_END()
}; };
/** Economy variables */ /** Economy variables */
@@ -68,7 +67,6 @@ static const SaveLoad _cargopayment_desc[] = {
SLE_VAR(CargoPayment, route_profit, SLE_INT64), SLE_VAR(CargoPayment, route_profit, SLE_INT64),
SLE_VAR(CargoPayment, visual_profit, SLE_INT64), SLE_VAR(CargoPayment, visual_profit, SLE_INT64),
SLE_CONDVAR_X(CargoPayment, visual_transfer, SLE_INT64, SLV_181, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_OR, XSLFI_CHILLPP)), SLE_CONDVAR_X(CargoPayment, visual_transfer, SLE_INT64, SLV_181, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_OR, XSLFI_CHILLPP)),
SLE_END()
}; };
static void Save_CAPY() static void Save_CAPY()

View File

@@ -43,8 +43,6 @@ static const SaveLoad _engine_desc[] = {
SLE_CONDSTR(Engine, name, SLE_STR, 0, SLV_84, SL_MAX_VERSION), SLE_CONDSTR(Engine, name, SLE_STR, 0, SLV_84, SL_MAX_VERSION),
SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space
SLE_END()
}; };
static std::vector<Engine*> _temp_engine; static std::vector<Engine*> _temp_engine;
@@ -174,7 +172,6 @@ static const SaveLoad _engine_id_mapping_desc[] = {
SLE_VAR(EngineIDMapping, internal_id, SLE_UINT16), SLE_VAR(EngineIDMapping, internal_id, SLE_UINT16),
SLE_VAR(EngineIDMapping, type, SLE_UINT8), SLE_VAR(EngineIDMapping, type, SLE_UINT8),
SLE_VAR(EngineIDMapping, substitute_id, SLE_UINT8), SLE_VAR(EngineIDMapping, substitute_id, SLE_UINT8),
SLE_END()
}; };
static void Save_EIDS() static void Save_EIDS()

View File

@@ -463,7 +463,6 @@ static void Save_SLXI()
static const SaveLoad _xlsi_sub_chunk_desc[] = { static const SaveLoad _xlsi_sub_chunk_desc[] = {
SLE_STR(SlxiSubChunkInfo, name, SLE_STR, 0), SLE_STR(SlxiSubChunkInfo, name, SLE_STR, 0),
SLE_END()
}; };
// calculate lengths // calculate lengths
@@ -550,9 +549,8 @@ static void Load_SLXI()
if (chunk_flags != 0) SlErrorCorruptFmt("SLXI chunk: unknown chunk header flags: 0x%X", chunk_flags); if (chunk_flags != 0) SlErrorCorruptFmt("SLXI chunk: unknown chunk header flags: 0x%X", chunk_flags);
char name_buffer[256]; char name_buffer[256];
const SaveLoadGlobVarList xlsi_sub_chunk_name_desc[] = { const SaveLoad xlsi_sub_chunk_name_desc[] = {
SLEG_STR(name_buffer, SLE_STRB), SLEG_STR(name_buffer, SLE_STRB),
SLEG_END()
}; };
auto version_error = [](StringID str, const char *feature, int64 p1, int64 p2) { auto version_error = [](StringID str, const char *feature, int64 p1, int64 p2) {

View File

@@ -30,7 +30,6 @@ static const SaveLoad _game_script[] = {
SLEG_SSTR(_game_saveload_settings, SLE_STR), SLEG_SSTR(_game_saveload_settings, SLE_STR),
SLEG_VAR(_game_saveload_version, SLE_UINT32), SLEG_VAR(_game_saveload_version, SLE_UINT32),
SLEG_VAR(_game_saveload_is_random, SLE_BOOL), SLEG_VAR(_game_saveload_is_random, SLE_BOOL),
SLE_END()
}; };
static void SaveReal_GSDT(int *index_ptr) static void SaveReal_GSDT(int *index_ptr)
@@ -117,12 +116,10 @@ static uint _game_saveload_strings;
static const SaveLoad _game_language_header[] = { static const SaveLoad _game_language_header[] = {
SLEG_SSTR(_game_saveload_string, SLE_STR), SLEG_SSTR(_game_saveload_string, SLE_STR),
SLEG_VAR(_game_saveload_strings, SLE_UINT32), SLEG_VAR(_game_saveload_strings, SLE_UINT32),
SLE_END()
}; };
static const SaveLoad _game_language_string[] = { static const SaveLoad _game_language_string[] = {
SLEG_SSTR(_game_saveload_string, SLE_STR | SLF_ALLOW_CONTROL), SLEG_SSTR(_game_saveload_string, SLE_STR | SLF_ALLOW_CONTROL),
SLE_END()
}; };
static void SaveReal_GSTR(const LanguageStrings *ls) static void SaveReal_GSTR(const LanguageStrings *ls)

View File

@@ -18,13 +18,11 @@
static const SaveLoad _glog_action_desc[] = { static const SaveLoad _glog_action_desc[] = {
SLE_VAR(LoggedAction, tick, SLE_UINT16), SLE_VAR(LoggedAction, tick, SLE_UINT16),
SLE_END()
}; };
static const SaveLoad _glog_mode_desc[] = { static const SaveLoad _glog_mode_desc[] = {
SLE_VAR(LoggedChange, mode.mode, SLE_UINT8), SLE_VAR(LoggedChange, mode.mode, SLE_UINT8),
SLE_VAR(LoggedChange, mode.landscape, SLE_UINT8), SLE_VAR(LoggedChange, mode.landscape, SLE_UINT8),
SLE_END()
}; };
static char old_revision_text[GAMELOG_REVISION_LENGTH]; static char old_revision_text[GAMELOG_REVISION_LENGTH];
@@ -35,62 +33,53 @@ static const SaveLoad _glog_revision_desc[] = {
SLE_VAR(LoggedChange, revision.newgrf, SLE_UINT32), SLE_VAR(LoggedChange, revision.newgrf, SLE_UINT32),
SLE_VAR(LoggedChange, revision.slver, SLE_UINT16), SLE_VAR(LoggedChange, revision.slver, SLE_UINT16),
SLE_VAR(LoggedChange, revision.modified, SLE_UINT8), SLE_VAR(LoggedChange, revision.modified, SLE_UINT8),
SLE_END()
}; };
static const SaveLoad _glog_oldver_desc[] = { static const SaveLoad _glog_oldver_desc[] = {
SLE_VAR(LoggedChange, oldver.type, SLE_UINT32), SLE_VAR(LoggedChange, oldver.type, SLE_UINT32),
SLE_VAR(LoggedChange, oldver.version, SLE_UINT32), SLE_VAR(LoggedChange, oldver.version, SLE_UINT32),
SLE_END()
}; };
static const SaveLoad _glog_setting_desc[] = { static const SaveLoad _glog_setting_desc[] = {
SLE_STR(LoggedChange, setting.name, SLE_STR, 128), SLE_STR(LoggedChange, setting.name, SLE_STR, 128),
SLE_VAR(LoggedChange, setting.oldval, SLE_INT32), SLE_VAR(LoggedChange, setting.oldval, SLE_INT32),
SLE_VAR(LoggedChange, setting.newval, SLE_INT32), SLE_VAR(LoggedChange, setting.newval, SLE_INT32),
SLE_END()
}; };
static const SaveLoad _glog_grfadd_desc[] = { static const SaveLoad _glog_grfadd_desc[] = {
SLE_VAR(LoggedChange, grfadd.grfid, SLE_UINT32 ), SLE_VAR(LoggedChange, grfadd.grfid, SLE_UINT32 ),
SLE_ARR(LoggedChange, grfadd.md5sum, SLE_UINT8, 16), SLE_ARR(LoggedChange, grfadd.md5sum, SLE_UINT8, 16),
SLE_END()
}; };
static const SaveLoad _glog_grfrem_desc[] = { static const SaveLoad _glog_grfrem_desc[] = {
SLE_VAR(LoggedChange, grfrem.grfid, SLE_UINT32), SLE_VAR(LoggedChange, grfrem.grfid, SLE_UINT32),
SLE_END()
}; };
static const SaveLoad _glog_grfcompat_desc[] = { static const SaveLoad _glog_grfcompat_desc[] = {
SLE_VAR(LoggedChange, grfcompat.grfid, SLE_UINT32 ), SLE_VAR(LoggedChange, grfcompat.grfid, SLE_UINT32 ),
SLE_ARR(LoggedChange, grfcompat.md5sum, SLE_UINT8, 16), SLE_ARR(LoggedChange, grfcompat.md5sum, SLE_UINT8, 16),
SLE_END()
}; };
static const SaveLoad _glog_grfparam_desc[] = { static const SaveLoad _glog_grfparam_desc[] = {
SLE_VAR(LoggedChange, grfparam.grfid, SLE_UINT32), SLE_VAR(LoggedChange, grfparam.grfid, SLE_UINT32),
SLE_END()
}; };
static const SaveLoad _glog_grfmove_desc[] = { static const SaveLoad _glog_grfmove_desc[] = {
SLE_VAR(LoggedChange, grfmove.grfid, SLE_UINT32), SLE_VAR(LoggedChange, grfmove.grfid, SLE_UINT32),
SLE_VAR(LoggedChange, grfmove.offset, SLE_INT32), SLE_VAR(LoggedChange, grfmove.offset, SLE_INT32),
SLE_END()
}; };
static const SaveLoad _glog_grfbug_desc[] = { static const SaveLoad _glog_grfbug_desc[] = {
SLE_VAR(LoggedChange, grfbug.data, SLE_UINT64), SLE_VAR(LoggedChange, grfbug.data, SLE_UINT64),
SLE_VAR(LoggedChange, grfbug.grfid, SLE_UINT32), SLE_VAR(LoggedChange, grfbug.grfid, SLE_UINT32),
SLE_VAR(LoggedChange, grfbug.bug, SLE_UINT8), SLE_VAR(LoggedChange, grfbug.bug, SLE_UINT8),
SLE_END()
}; };
static const SaveLoad _glog_emergency_desc[] = { static const SaveLoad _glog_emergency_desc[] = {
SLE_END() SLE_CONDNULL(0, SL_MIN_VERSION, SL_MIN_VERSION), // Just an empty list, to keep the rest of the code easier.
}; };
static const SaveLoad * const _glog_desc[] = { static const SaveLoadTable _glog_desc[] = {
_glog_mode_desc, _glog_mode_desc,
_glog_revision_desc, _glog_revision_desc,
_glog_oldver_desc, _glog_oldver_desc,

View File

@@ -21,7 +21,6 @@ static const SaveLoad _goals_desc[] = {
SLE_STR(Goal, text, SLE_STR | SLF_ALLOW_CONTROL, 0), SLE_STR(Goal, text, SLE_STR | SLF_ALLOW_CONTROL, 0),
SLE_CONDSTR(Goal, progress, SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_182, SL_MAX_VERSION), SLE_CONDSTR(Goal, progress, SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_182, SL_MAX_VERSION),
SLE_CONDVAR(Goal, completed, SLE_BOOL, SLV_182, SL_MAX_VERSION), SLE_CONDVAR(Goal, completed, SLE_BOOL, SLV_182, SL_MAX_VERSION),
SLE_END()
}; };
static void Save_GOAL() static void Save_GOAL()

View File

@@ -26,7 +26,6 @@ static const SaveLoad _group_desc[] = {
SLE_CONDVAR(Group, livery.colour1, SLE_UINT8, SLV_GROUP_LIVERIES, SL_MAX_VERSION), SLE_CONDVAR(Group, livery.colour1, SLE_UINT8, SLV_GROUP_LIVERIES, SL_MAX_VERSION),
SLE_CONDVAR(Group, livery.colour2, SLE_UINT8, SLV_GROUP_LIVERIES, SL_MAX_VERSION), SLE_CONDVAR(Group, livery.colour2, SLE_UINT8, SLV_GROUP_LIVERIES, SL_MAX_VERSION),
SLE_CONDVAR(Group, parent, SLE_UINT16, SLV_189, SL_MAX_VERSION), SLE_CONDVAR(Group, parent, SLE_UINT16, SLV_189, SL_MAX_VERSION),
SLE_END()
}; };
static void Save_GRPS() static void Save_GRPS()

View File

@@ -75,8 +75,6 @@ static const SaveLoad _industry_desc[] = {
SLE_CONDSSTR(Industry, text, SLE_STR | SLF_ALLOW_CONTROL, SLV_INDUSTRY_TEXT, SL_MAX_VERSION), SLE_CONDSSTR(Industry, text, SLE_STR | SLF_ALLOW_CONTROL, SLV_INDUSTRY_TEXT, SL_MAX_VERSION),
SLE_CONDNULL(32, SLV_2, SLV_144), // old reserved space SLE_CONDNULL(32, SLV_2, SLV_144), // old reserved space
SLE_END()
}; };
static void Save_INDY() static void Save_INDY()
@@ -139,7 +137,6 @@ static void Ptrs_INDY()
/** Description of the data to save and load in #IndustryBuildData. */ /** Description of the data to save and load in #IndustryBuildData. */
static const SaveLoad _industry_builder_desc[] = { static const SaveLoad _industry_builder_desc[] = {
SLEG_VAR(_industry_builder.wanted_inds, SLE_UINT32), SLEG_VAR(_industry_builder.wanted_inds, SLE_UINT32),
SLEG_END()
}; };
/** Load/save industry builder. */ /** Load/save industry builder. */
@@ -155,7 +152,6 @@ static const SaveLoad _industrytype_builder_desc[] = {
SLE_VAR(IndustryTypeBuildData, target_count, SLE_UINT16), SLE_VAR(IndustryTypeBuildData, target_count, SLE_UINT16),
SLE_VAR(IndustryTypeBuildData, max_wait, SLE_UINT16), SLE_VAR(IndustryTypeBuildData, max_wait, SLE_UINT16),
SLE_VAR(IndustryTypeBuildData, wait_count, SLE_UINT16), SLE_VAR(IndustryTypeBuildData, wait_count, SLE_UINT16),
SLE_END()
}; };
/** Save industry-type build data. */ /** Save industry-type build data. */

View File

@@ -104,7 +104,6 @@ struct LabelObject {
static const SaveLoad _label_object_desc[] = { static const SaveLoad _label_object_desc[] = {
SLE_VAR(LabelObject, label, SLE_UINT32), SLE_VAR(LabelObject, label, SLE_UINT32),
SLE_END(),
}; };
static void Save_RAIL() static void Save_RAIL()

View File

@@ -28,13 +28,12 @@ static uint16 _num_nodes;
* Get a SaveLoad array for a link graph. * Get a SaveLoad array for a link graph.
* @return SaveLoad array for link graph. * @return SaveLoad array for link graph.
*/ */
const SaveLoad *GetLinkGraphDesc() SaveLoadTable GetLinkGraphDesc()
{ {
static const SaveLoad link_graph_desc[] = { static const SaveLoad link_graph_desc[] = {
SLE_VAR(LinkGraph, last_compression, SLE_INT32), SLE_VAR(LinkGraph, last_compression, SLE_INT32),
SLEG_VAR(_num_nodes, SLE_UINT16), SLEG_VAR(_num_nodes, SLE_UINT16),
SLE_VAR(LinkGraph, cargo, SLE_UINT8), SLE_VAR(LinkGraph, cargo, SLE_UINT8),
SLE_END()
}; };
return link_graph_desc; return link_graph_desc;
} }
@@ -55,7 +54,7 @@ void GetLinkGraphJobDayLengthScaleAfterLoad(LinkGraphJob *lgj)
* Of course the settings have to be saved and loaded, too, to avoid desyncs. * Of course the settings have to be saved and loaded, too, to avoid desyncs.
* @return Array of SaveLoad structs. * @return Array of SaveLoad structs.
*/ */
const SaveLoad *GetLinkGraphJobDesc() SaveLoadTable GetLinkGraphJobDesc()
{ {
static std::vector<SaveLoad> saveloads; static std::vector<SaveLoad> saveloads;
static const char *prefix = "linkgraph."; static const char *prefix = "linkgraph.";
@@ -84,28 +83,25 @@ const SaveLoad *GetLinkGraphJobDesc()
SLE_VAR(LinkGraphJob, join_date_ticks, SLE_INT32), SLE_VAR(LinkGraphJob, join_date_ticks, SLE_INT32),
SLE_CONDVAR_X(LinkGraphJob, start_date_ticks, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE)), SLE_CONDVAR_X(LinkGraphJob, start_date_ticks, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE)),
SLE_VAR(LinkGraphJob, link_graph.index, SLE_UINT16), SLE_VAR(LinkGraphJob, link_graph.index, SLE_UINT16),
SLE_END()
}; };
int i = 0; for (auto &sld : job_desc) {
do { saveloads.push_back(sld);
saveloads.push_back(job_desc[i++]); }
} while (saveloads.back().cmd != SL_END);
} }
return &saveloads[0]; return saveloads;
} }
/** /**
* Get a SaveLoad array for the link graph schedule. * Get a SaveLoad array for the link graph schedule.
* @return SaveLoad array for the link graph schedule. * @return SaveLoad array for the link graph schedule.
*/ */
const SaveLoad *GetLinkGraphScheduleDesc() SaveLoadTable GetLinkGraphScheduleDesc()
{ {
static const SaveLoad schedule_desc[] = { static const SaveLoad schedule_desc[] = {
SLE_LST(LinkGraphSchedule, schedule, REF_LINK_GRAPH), SLE_LST(LinkGraphSchedule, schedule, REF_LINK_GRAPH),
SLE_LST(LinkGraphSchedule, running, REF_LINK_GRAPH_JOB), SLE_LST(LinkGraphSchedule, running, REF_LINK_GRAPH_JOB),
SLE_END()
}; };
return schedule_desc; return schedule_desc;
} }
@@ -121,7 +117,6 @@ static const SaveLoad _node_desc[] = {
SLE_VAR(Node, demand, SLE_UINT32), SLE_VAR(Node, demand, SLE_UINT32),
SLE_VAR(Node, station, SLE_UINT16), SLE_VAR(Node, station, SLE_UINT16),
SLE_VAR(Node, last_update, SLE_INT32), SLE_VAR(Node, last_update, SLE_INT32),
SLE_END()
}; };
/** /**
@@ -134,7 +129,6 @@ static const SaveLoad _edge_desc[] = {
SLE_VAR(Edge, last_unrestricted_update, SLE_INT32), SLE_VAR(Edge, last_unrestricted_update, SLE_INT32),
SLE_CONDVAR(Edge, last_restricted_update, SLE_INT32, SLV_187, SL_MAX_VERSION), SLE_CONDVAR(Edge, last_restricted_update, SLE_INT32, SLV_187, SL_MAX_VERSION),
SLE_VAR(Edge, next_edge, SLE_UINT16), SLE_VAR(Edge, next_edge, SLE_UINT16),
SLE_END()
}; };
std::vector<SaveLoad> _filtered_node_desc; std::vector<SaveLoad> _filtered_node_desc;
@@ -157,10 +151,10 @@ void Save_LinkGraph(LinkGraph &lg)
uint16 size = lg.Size(); uint16 size = lg.Size();
for (NodeID from = 0; from < size; ++from) { for (NodeID from = 0; from < size; ++from) {
Node *node = &lg.nodes[from]; Node *node = &lg.nodes[from];
SlObjectSaveFiltered(node, _filtered_node_desc.data()); SlObjectSaveFiltered(node, _filtered_node_desc);
/* ... but as that wasted a lot of space we save a sparse matrix now. */ /* ... but as that wasted a lot of space we save a sparse matrix now. */
for (NodeID to = from; to != INVALID_NODE; to = lg.edges[from][to].next_edge) { for (NodeID to = from; to != INVALID_NODE; to = lg.edges[from][to].next_edge) {
SlObjectSaveFiltered(&lg.edges[from][to], _filtered_edge_desc.data()); SlObjectSaveFiltered(&lg.edges[from][to], _filtered_edge_desc);
} }
} }
} }
@@ -174,17 +168,17 @@ void Load_LinkGraph(LinkGraph &lg)
uint size = lg.Size(); uint size = lg.Size();
for (NodeID from = 0; from < size; ++from) { for (NodeID from = 0; from < size; ++from) {
Node *node = &lg.nodes[from]; Node *node = &lg.nodes[from];
SlObjectLoadFiltered(node, _filtered_node_desc.data()); SlObjectLoadFiltered(node, _filtered_node_desc);
if (IsSavegameVersionBefore(SLV_191)) { if (IsSavegameVersionBefore(SLV_191)) {
/* We used to save the full matrix ... */ /* We used to save the full matrix ... */
for (NodeID to = 0; to < size; ++to) { for (NodeID to = 0; to < size; ++to) {
SlObjectLoadFiltered(&lg.edges[from][to], _filtered_edge_desc.data()); SlObjectLoadFiltered(&lg.edges[from][to], _filtered_edge_desc);
} }
} else { } else {
/* ... but as that wasted a lot of space we save a sparse matrix now. */ /* ... but as that wasted a lot of space we save a sparse matrix now. */
for (NodeID to = from; to != INVALID_NODE; to = lg.edges[from][to].next_edge) { for (NodeID to = from; to != INVALID_NODE; to = lg.edges[from][to].next_edge) {
if (to >= size) SlErrorCorrupt("Link graph structure overflow"); if (to >= size) SlErrorCorrupt("Link graph structure overflow");
SlObjectLoadFiltered(&lg.edges[from][to], _filtered_edge_desc.data()); SlObjectLoadFiltered(&lg.edges[from][to], _filtered_edge_desc);
} }
} }
} }
@@ -196,7 +190,7 @@ void Load_LinkGraph(LinkGraph &lg)
*/ */
static void DoSave_LGRJ(LinkGraphJob *lgj) static void DoSave_LGRJ(LinkGraphJob *lgj)
{ {
SlObjectSaveFiltered(lgj, _filtered_job_desc.data()); SlObjectSaveFiltered(lgj, _filtered_job_desc);
_num_nodes = lgj->Size(); _num_nodes = lgj->Size();
SlObjectSaveFiltered(const_cast<LinkGraph *>(&lgj->Graph()), GetLinkGraphDesc()); // GetLinkGraphDesc has no conditionals SlObjectSaveFiltered(const_cast<LinkGraph *>(&lgj->Graph()), GetLinkGraphDesc()); // GetLinkGraphDesc has no conditionals
Save_LinkGraph(const_cast<LinkGraph &>(lgj->Graph())); Save_LinkGraph(const_cast<LinkGraph &>(lgj->Graph()));
@@ -245,7 +239,7 @@ static void Load_LGRJ()
NOT_REACHED(); NOT_REACHED();
} }
LinkGraphJob *lgj = new (index) LinkGraphJob(); LinkGraphJob *lgj = new (index) LinkGraphJob();
SlObjectLoadFiltered(lgj, _filtered_job_desc.data()); SlObjectLoadFiltered(lgj, _filtered_job_desc);
if (SlXvIsFeatureMissing(XSLFI_LINKGRAPH_DAY_SCALE)) { if (SlXvIsFeatureMissing(XSLFI_LINKGRAPH_DAY_SCALE)) {
GetLinkGraphJobDayLengthScaleAfterLoad(lgj); GetLinkGraphJobDayLengthScaleAfterLoad(lgj);
} }

View File

@@ -25,10 +25,9 @@ static uint32 _map_dim_y;
extern bool _sl_maybe_chillpp; extern bool _sl_maybe_chillpp;
static const SaveLoadGlobVarList _map_dimensions[] = { static const SaveLoad _map_dimensions[] = {
SLEG_CONDVAR(_map_dim_x, SLE_UINT32, SLV_6, SL_MAX_VERSION), SLEG_CONDVAR(_map_dim_x, SLE_UINT32, SLV_6, SL_MAX_VERSION),
SLEG_CONDVAR(_map_dim_y, SLE_UINT32, SLV_6, SL_MAX_VERSION), SLEG_CONDVAR(_map_dim_y, SLE_UINT32, SLV_6, SL_MAX_VERSION),
SLEG_END()
}; };
static void Save_MAPS() static void Save_MAPS()

View File

@@ -72,7 +72,7 @@ void ResetViewportAfterLoadGame()
byte _age_cargo_skip_counter; ///< Skip aging of cargo? Used before savegame version 162. byte _age_cargo_skip_counter; ///< Skip aging of cargo? Used before savegame version 162.
static const SaveLoadGlobVarList _date_desc[] = { static const SaveLoad _date_desc[] = {
SLEG_CONDVAR(_date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), SLEG_CONDVAR(_date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
SLEG_CONDVAR(_date, SLE_INT32, SLV_31, SL_MAX_VERSION), SLEG_CONDVAR(_date, SLE_INT32, SLV_31, SL_MAX_VERSION),
SLEG_VAR(_date_fract, SLE_UINT16), SLEG_VAR(_date_fract, SLE_UINT16),
@@ -99,10 +99,9 @@ static const SaveLoadGlobVarList _date_desc[] = {
SLEG_CONDVAR_X(_road_layout_change_counter, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ROAD_LAYOUT_CHANGE_CTR)), SLEG_CONDVAR_X(_road_layout_change_counter, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ROAD_LAYOUT_CHANGE_CTR)),
SLEG_CONDVAR_X(_extra_aspects, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_REALISTIC_TRAIN_BRAKING, 4)), SLEG_CONDVAR_X(_extra_aspects, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_REALISTIC_TRAIN_BRAKING, 4)),
SLE_CONDNULL(4, SLV_11, SLV_120), SLE_CONDNULL(4, SLV_11, SLV_120),
SLEG_END()
}; };
static const SaveLoadGlobVarList _date_check_desc[] = { static const SaveLoad _date_check_desc[] = {
SLEG_CONDVAR(_load_check_data.current_date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), SLEG_CONDVAR(_load_check_data.current_date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
SLEG_CONDVAR(_load_check_data.current_date, SLE_INT32, SLV_31, SL_MAX_VERSION), SLEG_CONDVAR(_load_check_data.current_date, SLE_INT32, SLV_31, SL_MAX_VERSION),
SLE_NULL(2), // _date_fract SLE_NULL(2), // _date_fract
@@ -129,7 +128,6 @@ static const SaveLoadGlobVarList _date_check_desc[] = {
SLE_CONDNULL_X(4, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ROAD_LAYOUT_CHANGE_CTR)), // _road_layout_change_counter SLE_CONDNULL_X(4, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ROAD_LAYOUT_CHANGE_CTR)), // _road_layout_change_counter
SLE_CONDNULL_X(1, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_REALISTIC_TRAIN_BRAKING, 4)), // _extra_aspects SLE_CONDNULL_X(1, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_REALISTIC_TRAIN_BRAKING, 4)), // _extra_aspects
SLE_CONDNULL(4, SLV_11, SLV_120), SLE_CONDNULL(4, SLV_11, SLV_120),
SLEG_END()
}; };
/* Save load date related variables as well as persistent tick counters /* Save load date related variables as well as persistent tick counters
@@ -149,13 +147,12 @@ static void Check_DATE()
} }
static const SaveLoadGlobVarList _view_desc[] = { static const SaveLoad _view_desc[] = {
SLEG_CONDVAR(_saved_scrollpos_x, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_6), SLEG_CONDVAR(_saved_scrollpos_x, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_6),
SLEG_CONDVAR(_saved_scrollpos_x, SLE_INT32, SLV_6, SL_MAX_VERSION), SLEG_CONDVAR(_saved_scrollpos_x, SLE_INT32, SLV_6, SL_MAX_VERSION),
SLEG_CONDVAR(_saved_scrollpos_y, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_6), SLEG_CONDVAR(_saved_scrollpos_y, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_6),
SLEG_CONDVAR(_saved_scrollpos_y, SLE_INT32, SLV_6, SL_MAX_VERSION), SLEG_CONDVAR(_saved_scrollpos_y, SLE_INT32, SLV_6, SL_MAX_VERSION),
SLEG_VAR(_saved_scrollpos_zoom, SLE_UINT8), SLEG_VAR(_saved_scrollpos_zoom, SLE_UINT8),
SLEG_END()
}; };
static void SaveLoad_VIEW() static void SaveLoad_VIEW()

View File

@@ -21,7 +21,6 @@ static const SaveLoad _newgrf_mapping_desc[] = {
SLE_VAR(EntityIDMapping, grfid, SLE_UINT32), SLE_VAR(EntityIDMapping, grfid, SLE_UINT32),
SLE_VAR(EntityIDMapping, entity_id, SLE_UINT8), SLE_VAR(EntityIDMapping, entity_id, SLE_UINT8),
SLE_VAR(EntityIDMapping, substitute_id, SLE_UINT8), SLE_VAR(EntityIDMapping, substitute_id, SLE_UINT8),
SLE_END()
}; };
/** /**
@@ -69,7 +68,6 @@ static const SaveLoad _grfconfig_desc[] = {
SLE_VAR(GRFConfig, num_params, SLE_UINT8), SLE_VAR(GRFConfig, num_params, SLE_UINT8),
SLE_CONDVAR(GRFConfig, palette, SLE_UINT8, SLV_101, SL_MAX_VERSION), SLE_CONDVAR(GRFConfig, palette, SLE_UINT8, SLV_101, SL_MAX_VERSION),
SLEG_CONDSSTR_X(_grf_name, 0, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_NEWGRF_INFO_EXTRA)), SLEG_CONDSSTR_X(_grf_name, 0, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_NEWGRF_INFO_EXTRA)),
SLE_END()
}; };

View File

@@ -25,8 +25,6 @@ static const SaveLoad _object_desc[] = {
SLE_CONDVAR(Object, colour, SLE_UINT8, SLV_148, SL_MAX_VERSION), SLE_CONDVAR(Object, colour, SLE_UINT8, SLV_148, SL_MAX_VERSION),
SLE_CONDVAR(Object, view, SLE_UINT8, SLV_155, SL_MAX_VERSION), SLE_CONDVAR(Object, view, SLE_UINT8, SLV_155, SL_MAX_VERSION),
SLE_CONDVAR(Object, type, SLE_UINT16, SLV_186, SL_MAX_VERSION), SLE_CONDVAR(Object, type, SLE_UINT16, SLV_186, SL_MAX_VERSION),
SLE_END()
}; };
static void Save_OBJS() static void Save_OBJS()

View File

@@ -236,7 +236,7 @@ static inline bool CheckOldSavegameType(FILE *f, char *temp, const char *last, u
bool ret = VerifyOldNameChecksum(temp, len); bool ret = VerifyOldNameChecksum(temp, len);
temp[len - 2] = '\0'; // name is null-terminated in savegame, but it's better to be sure temp[len - 2] = '\0'; // name is null-terminated in savegame, but it's better to be sure
str_validate(temp, last); StrMakeValidInPlace(temp, last);
return ret; return ret;
} }

View File

@@ -113,7 +113,7 @@ Order UnpackOldOrder(uint16 packed)
return order; return order;
} }
const SaveLoad *GetOrderDescription() SaveLoadTable GetOrderDescription()
{ {
static const SaveLoad _order_desc[] = { static const SaveLoad _order_desc[] = {
SLE_VAR(Order, type, SLE_UINT8), SLE_VAR(Order, type, SLE_UINT8),
@@ -135,7 +135,6 @@ const SaveLoad *GetOrderDescription()
/* Leftover from the minor savegame version stuff /* Leftover from the minor savegame version stuff
* We will never use those free bytes, but we have to keep this line to allow loading of old savegames */ * We will never use those free bytes, but we have to keep this line to allow loading of old savegames */
SLE_CONDNULL(10, SLV_5, SLV_36), SLE_CONDNULL(10, SLV_5, SLV_36),
SLE_END()
}; };
return _order_desc; return _order_desc;
@@ -148,7 +147,7 @@ static void Save_ORDR()
_filtered_desc = SlFilterObject(GetOrderDescription()); _filtered_desc = SlFilterObject(GetOrderDescription());
for (Order *order : Order::Iterate()) { for (Order *order : Order::Iterate()) {
SlSetArrayIndex(order->index); SlSetArrayIndex(order->index);
SlObjectSaveFiltered(order, _filtered_desc.data()); SlObjectSaveFiltered(order, _filtered_desc);
} }
} }
@@ -206,19 +205,18 @@ static void Load_ORDR()
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
Order *order = new (index) Order(); Order *order = new (index) Order();
SlObjectLoadFiltered(order, _filtered_desc.data()); SlObjectLoadFiltered(order, _filtered_desc);
} }
} }
} }
const SaveLoad *GetOrderExtraInfoDescription() const SaveLoadTable GetOrderExtraInfoDescription()
{ {
static const SaveLoad _order_extra_info_desc[] = { static const SaveLoad _order_extra_info_desc[] = {
SLE_CONDARR_X(OrderExtraInfo, cargo_type_flags, SLE_UINT8, 32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_CARGO_TYPE_ORDERS, 1, 2)), SLE_CONDARR_X(OrderExtraInfo, cargo_type_flags, SLE_UINT8, 32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_CARGO_TYPE_ORDERS, 1, 2)),
SLE_CONDARR_X(OrderExtraInfo, cargo_type_flags, SLE_UINT8, NUM_CARGO, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_CARGO_TYPE_ORDERS, 3)), SLE_CONDARR_X(OrderExtraInfo, cargo_type_flags, SLE_UINT8, NUM_CARGO, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_CARGO_TYPE_ORDERS, 3)),
SLE_CONDVAR_X(OrderExtraInfo, xflags, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLE_EXTRA)), SLE_CONDVAR_X(OrderExtraInfo, xflags, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLE_EXTRA)),
SLE_CONDVAR_X(OrderExtraInfo, xdata, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ORDER_EXTRA_DATA)), SLE_CONDVAR_X(OrderExtraInfo, xdata, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ORDER_EXTRA_DATA)),
SLE_END()
}; };
return _order_extra_info_desc; return _order_extra_info_desc;
@@ -230,7 +228,7 @@ void Save_ORDX()
for (Order *order : Order::Iterate()) { for (Order *order : Order::Iterate()) {
if (order->extra) { if (order->extra) {
SlSetArrayIndex(order->index); SlSetArrayIndex(order->index);
SlObjectSaveFiltered(order->extra.get(), _filtered_desc.data()); SlObjectSaveFiltered(order->extra.get(), _filtered_desc);
} }
} }
} }
@@ -243,7 +241,7 @@ void Load_ORDX()
Order *order = Order::GetIfValid(index); Order *order = Order::GetIfValid(index);
assert(order != nullptr); assert(order != nullptr);
order->AllocExtraInfo(); order->AllocExtraInfo();
SlObjectLoadFiltered(order->extra.get(), _filtered_desc.data()); SlObjectLoadFiltered(order->extra.get(), _filtered_desc);
} }
} }
@@ -257,7 +255,7 @@ static void Ptrs_ORDR()
} }
} }
const SaveLoad *GetOrderListDescription() SaveLoadTable GetOrderListDescription()
{ {
static const SaveLoad _orderlist_desc[] = { static const SaveLoad _orderlist_desc[] = {
SLE_REF(OrderList, first, REF_ORDER), SLE_REF(OrderList, first, REF_ORDER),
@@ -269,7 +267,6 @@ const SaveLoad *GetOrderListDescription()
SLE_CONDVAR_X(OrderList, scheduled_dispatch_max_delay, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH)), SLE_CONDVAR_X(OrderList, scheduled_dispatch_max_delay, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH)),
SLEG_CONDVAR_X(_jokerpp_separation_mode, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)), SLEG_CONDVAR_X(_jokerpp_separation_mode, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)),
SLE_CONDNULL_X(21, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)), SLE_CONDNULL_X(21, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)),
SLE_END()
}; };
return _orderlist_desc; return _orderlist_desc;
@@ -312,7 +309,7 @@ void Ptrs_ORDL()
} }
} }
const SaveLoad *GetOrderBackupDescription() SaveLoadTable GetOrderBackupDescription()
{ {
static const SaveLoad _order_backup_desc[] = { static const SaveLoad _order_backup_desc[] = {
SLE_VAR(OrderBackup, user, SLE_UINT32), SLE_VAR(OrderBackup, user, SLE_UINT32),
@@ -338,7 +335,6 @@ const SaveLoad *GetOrderBackupDescription()
SLE_CONDVAR_X(OrderBackup, scheduled_dispatch_start_date, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 2)), SLE_CONDVAR_X(OrderBackup, scheduled_dispatch_start_date, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 2)),
SLE_CONDVAR_X(OrderBackup, scheduled_dispatch_start_full_date_fract, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 2)), SLE_CONDVAR_X(OrderBackup, scheduled_dispatch_start_full_date_fract, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 2)),
SLE_CONDVAR_X(OrderBackup, scheduled_dispatch_max_delay, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 2)), SLE_CONDVAR_X(OrderBackup, scheduled_dispatch_max_delay, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 2)),
SLE_END()
}; };
return _order_backup_desc; return _order_backup_desc;

View File

@@ -22,7 +22,6 @@ static const SaveLoad _plan_desc[] = {
SLE_CONDSSTR_X(Plan, name, 0, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ENH_VIEWPORT_PLANS, 3)), SLE_CONDSSTR_X(Plan, name, 0, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ENH_VIEWPORT_PLANS, 3)),
SLE_CONDSSTR_X(Plan, name, 0, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP, SL_JOKER_1_20)), SLE_CONDSSTR_X(Plan, name, 0, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP, SL_JOKER_1_20)),
SLE_CONDVAR_X(Plan, colour, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ENH_VIEWPORT_PLANS, 4)), SLE_CONDVAR_X(Plan, colour, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ENH_VIEWPORT_PLANS, 4)),
SLE_END()
}; };
static void RealSave_PLAN(Plan *p) static void RealSave_PLAN(Plan *p)

View File

@@ -1112,7 +1112,7 @@ static void SlString(void *ptr, size_t length, VarType conv)
if ((conv & SLF_ALLOW_NEWLINE) != 0) { if ((conv & SLF_ALLOW_NEWLINE) != 0) {
settings = settings | SVS_ALLOW_NEWLINE; settings = settings | SVS_ALLOW_NEWLINE;
} }
str_validate((char *)ptr, (char *)ptr + len, settings); StrMakeValidInPlace((char *)ptr, (char *)ptr + len, settings);
break; break;
} }
case SLA_PTRS: break; case SLA_PTRS: break;
@@ -1151,7 +1151,7 @@ static void SlStdString(std::string &str, VarType conv)
if ((conv & SLF_ALLOW_NEWLINE) != 0) { if ((conv & SLF_ALLOW_NEWLINE) != 0) {
settings = settings | SVS_ALLOW_NEWLINE; settings = settings | SVS_ALLOW_NEWLINE;
} }
str_validate_inplace(str, settings); StrMakeValidInPlace(str, settings);
break; break;
} }
case SLA_PTRS: break; case SLA_PTRS: break;
@@ -1593,10 +1593,10 @@ static void SlDeque(void *deque, VarType conv)
/** Are we going to save this object or not? */ /** Are we going to save this object or not? */
static inline bool SlIsObjectValidInSavegame(const SaveLoad *sld) static inline bool SlIsObjectValidInSavegame(const SaveLoad &sld)
{ {
if (!sld->ext_feature_test.IsFeaturePresent(_sl_version, sld->version_from, sld->version_to)) return false; if (!sld.ext_feature_test.IsFeaturePresent(_sl_version, sld.version_from, sld.version_to)) return false;
if (sld->conv & SLF_NOT_IN_SAVE) return false; if (sld.conv & SLF_NOT_IN_SAVE) return false;
return true; return true;
} }
@@ -1606,10 +1606,10 @@ static inline bool SlIsObjectValidInSavegame(const SaveLoad *sld)
* @note If the variable is skipped it is skipped in the savegame * @note If the variable is skipped it is skipped in the savegame
* bytestream itself as well, so there is no need to skip it somewhere else * bytestream itself as well, so there is no need to skip it somewhere else
*/ */
static inline bool SlSkipVariableOnLoad(const SaveLoad *sld) static inline bool SlSkipVariableOnLoad(const SaveLoad &sld)
{ {
if ((sld->conv & SLF_NO_NETWORK_SYNC) && _sl.action != SLA_SAVE && _networking && !_network_server) { if ((sld.conv & SLF_NO_NETWORK_SYNC) && _sl.action != SLA_SAVE && _networking && !_network_server) {
SlSkipBytes(SlCalcConvMemLen(sld->conv) * sld->length); SlSkipBytes(SlCalcConvMemLen(sld.conv) * sld.length);
return true; return true;
} }
@@ -1618,26 +1618,26 @@ static inline bool SlSkipVariableOnLoad(const SaveLoad *sld)
/** /**
* Calculate the size of an object. * Calculate the size of an object.
* @param object to be measured * @param object to be measured.
* @param sld The SaveLoad description of the object so we know how to manipulate it * @param slt The SaveLoad table with objects to save/load.
* @return size of given object * @return size of given object.
*/ */
size_t SlCalcObjLength(const void *object, const SaveLoad *sld) size_t SlCalcObjLength(const void *object, const SaveLoadTable &slt)
{ {
size_t length = 0; size_t length = 0;
/* Need to determine the length and write a length tag. */ /* Need to determine the length and write a length tag. */
for (; sld->cmd != SL_END; sld++) { for (auto &sld : slt) {
length += SlCalcObjMemberLength(object, sld); length += SlCalcObjMemberLength(object, sld);
} }
return length; return length;
} }
size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld) size_t SlCalcObjMemberLength(const void *object, const SaveLoad &sld)
{ {
assert(_sl.action == SLA_SAVE); assert(_sl.action == SLA_SAVE);
switch (sld->cmd) { switch (sld.cmd) {
case SL_VAR: case SL_VAR:
case SL_REF: case SL_REF:
case SL_ARR: case SL_ARR:
@@ -1651,17 +1651,17 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
/* CONDITIONAL saveload types depend on the savegame version */ /* CONDITIONAL saveload types depend on the savegame version */
if (!SlIsObjectValidInSavegame(sld)) break; if (!SlIsObjectValidInSavegame(sld)) break;
switch (sld->cmd) { switch (sld.cmd) {
case SL_VAR: return SlCalcConvFileLen(sld->conv); case SL_VAR: return SlCalcConvFileLen(sld.conv);
case SL_REF: return SlCalcRefLen(); case SL_REF: return SlCalcRefLen();
case SL_ARR: return SlCalcArrayLen(sld->length, sld->conv); case SL_ARR: return SlCalcArrayLen(sld.length, sld.conv);
case SL_STR: return SlCalcStringLen(GetVariableAddress(object, sld), sld->length, sld->conv); case SL_STR: return SlCalcStringLen(GetVariableAddress(object, sld), sld.length, sld.conv);
case SL_LST: return SlCalcListLen<std::list<void *>>(GetVariableAddress(object, sld)); case SL_LST: return SlCalcListLen<std::list<void *>>(GetVariableAddress(object, sld));
case SL_PTRDEQ: return SlCalcListLen<std::deque<void *>>(GetVariableAddress(object, sld)); case SL_PTRDEQ: return SlCalcListLen<std::deque<void *>>(GetVariableAddress(object, sld));
case SL_VEC: return SlCalcListLen<std::vector<void *>>(GetVariableAddress(object, sld)); case SL_VEC: return SlCalcListLen<std::vector<void *>>(GetVariableAddress(object, sld));
case SL_DEQUE: return SlCalcDequeLen(GetVariableAddress(object, sld), sld->conv); case SL_DEQUE: return SlCalcDequeLen(GetVariableAddress(object, sld), sld.conv);
case SL_VARVEC: { case SL_VARVEC: {
const size_t size_len = SlCalcConvMemLen(sld->conv); const size_t size_len = SlCalcConvMemLen(sld.conv);
switch (size_len) { switch (size_len) {
case 1: return SlCalcVarListLen<std::vector<byte>>(GetVariableAddress(object, sld), 1); case 1: return SlCalcVarListLen<std::vector<byte>>(GetVariableAddress(object, sld), 1);
case 2: return SlCalcVarListLen<std::vector<uint16>>(GetVariableAddress(object, sld), 2); case 2: return SlCalcVarListLen<std::vector<uint16>>(GetVariableAddress(object, sld), 2);
@@ -1689,41 +1689,41 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
* matches with the actual variable size. * matches with the actual variable size.
* @param sld The saveload configuration to test. * @param sld The saveload configuration to test.
*/ */
static bool IsVariableSizeRight(const SaveLoad *sld) static bool IsVariableSizeRight(const SaveLoad &sld)
{ {
switch (sld->cmd) { switch (sld.cmd) {
case SL_VAR: case SL_VAR:
switch (GetVarMemType(sld->conv)) { switch (GetVarMemType(sld.conv)) {
case SLE_VAR_BL: case SLE_VAR_BL:
return sld->size == sizeof(bool); return sld.size == sizeof(bool);
case SLE_VAR_I8: case SLE_VAR_I8:
case SLE_VAR_U8: case SLE_VAR_U8:
return sld->size == sizeof(int8); return sld.size == sizeof(int8);
case SLE_VAR_I16: case SLE_VAR_I16:
case SLE_VAR_U16: case SLE_VAR_U16:
return sld->size == sizeof(int16); return sld.size == sizeof(int16);
case SLE_VAR_I32: case SLE_VAR_I32:
case SLE_VAR_U32: case SLE_VAR_U32:
return sld->size == sizeof(int32); return sld.size == sizeof(int32);
case SLE_VAR_I64: case SLE_VAR_I64:
case SLE_VAR_U64: case SLE_VAR_U64:
return sld->size == sizeof(int64); return sld.size == sizeof(int64);
case SLE_VAR_NAME: case SLE_VAR_NAME:
return sld->size == sizeof(std::string); return sld.size == sizeof(std::string);
default: default:
return sld->size == sizeof(void *); return sld.size == sizeof(void *);
} }
case SL_REF: case SL_REF:
/* These should all be pointer sized. */ /* These should all be pointer sized. */
return sld->size == sizeof(void *); return sld.size == sizeof(void *);
case SL_STR: case SL_STR:
/* These should be pointer sized, or fixed array. */ /* These should be pointer sized, or fixed array. */
return sld->size == sizeof(void *) || sld->size == sld->length; return sld.size == sizeof(void *) || sld.size == sld.length;
case SL_STDSTR: case SL_STDSTR:
/* These should be all pointers to std::string. */ /* These should be all pointers to std::string. */
return sld->size == sizeof(std::string); return sld.size == sizeof(std::string);
default: default:
return true; return true;
@@ -1732,15 +1732,15 @@ static bool IsVariableSizeRight(const SaveLoad *sld)
#endif /* OTTD_ASSERT */ #endif /* OTTD_ASSERT */
void SlFilterObject(const SaveLoad *sld, std::vector<SaveLoad> &save); void SlFilterObject(const SaveLoadTable &slt, std::vector<SaveLoad> &save);
static void SlFilterObjectMember(const SaveLoad *sld, std::vector<SaveLoad> &save) static void SlFilterObjectMember(const SaveLoad &sld, std::vector<SaveLoad> &save)
{ {
#ifdef OTTD_ASSERT #ifdef OTTD_ASSERT
assert(IsVariableSizeRight(sld)); assert(IsVariableSizeRight(sld));
#endif #endif
switch (sld->cmd) { switch (sld.cmd) {
case SL_VAR: case SL_VAR:
case SL_REF: case SL_REF:
case SL_ARR: case SL_ARR:
@@ -1762,7 +1762,7 @@ static void SlFilterObjectMember(const SaveLoad *sld, std::vector<SaveLoad> &sav
break; break;
case SLA_PTRS: case SLA_PTRS:
case SLA_NULL: case SLA_NULL:
switch (sld->cmd) { switch (sld.cmd) {
case SL_REF: case SL_REF:
case SL_LST: case SL_LST:
case SL_PTRDEQ: case SL_PTRDEQ:
@@ -1777,14 +1777,14 @@ static void SlFilterObjectMember(const SaveLoad *sld, std::vector<SaveLoad> &sav
default: NOT_REACHED(); default: NOT_REACHED();
} }
save.push_back(*sld); save.push_back(sld);
break; break;
/* SL_WRITEBYTE writes a value to the savegame to identify the type of an object. /* SL_WRITEBYTE writes a value to the savegame to identify the type of an object.
* When loading, the value is read explictly with SlReadByte() to determine which * When loading, the value is read explictly with SlReadByte() to determine which
* object description to use. */ * object description to use. */
case SL_WRITEBYTE: case SL_WRITEBYTE:
if (_sl.action == SLA_SAVE) save.push_back(*sld); if (_sl.action == SLA_SAVE) save.push_back(sld);
break; break;
/* SL_VEH_INCLUDE loads common code for vehicles */ /* SL_VEH_INCLUDE loads common code for vehicles */
@@ -1800,30 +1800,29 @@ static void SlFilterObjectMember(const SaveLoad *sld, std::vector<SaveLoad> &sav
} }
} }
void SlFilterObject(const SaveLoad *sld, std::vector<SaveLoad> &save) void SlFilterObject(const SaveLoadTable &slt, std::vector<SaveLoad> &save)
{ {
for (; sld->cmd != SL_END; sld++) { for (auto &sld : slt) {
SlFilterObjectMember(sld, save); SlFilterObjectMember(sld, save);
} }
} }
std::vector<SaveLoad> SlFilterObject(const SaveLoad *sld) std::vector<SaveLoad> SlFilterObject(const SaveLoadTable &slt)
{ {
std::vector<SaveLoad> save; std::vector<SaveLoad> save;
SlFilterObject(sld, save); SlFilterObject(slt, save);
save.push_back(SLE_END());
return save; return save;
} }
template <SaveLoadAction action, bool check_version> template <SaveLoadAction action, bool check_version>
bool SlObjectMemberGeneric(void *ptr, const SaveLoad *sld) bool SlObjectMemberGeneric(void *ptr, const SaveLoad &sld)
{ {
#ifdef OTTD_ASSERT #ifdef OTTD_ASSERT
if (check_version) assert(IsVariableSizeRight(sld)); if (check_version) assert(IsVariableSizeRight(sld));
#endif #endif
VarType conv = GB(sld->conv, 0, 8); VarType conv = GB(sld.conv, 0, 8);
switch (sld->cmd) { switch (sld.cmd) {
case SL_VAR: case SL_VAR:
case SL_REF: case SL_REF:
case SL_ARR: case SL_ARR:
@@ -1840,7 +1839,7 @@ bool SlObjectMemberGeneric(void *ptr, const SaveLoad *sld)
if (SlSkipVariableOnLoad(sld)) return false; if (SlSkipVariableOnLoad(sld)) return false;
} }
switch (sld->cmd) { switch (sld.cmd) {
case SL_VAR: SlSaveLoadConvGeneric<action>(ptr, conv); break; case SL_VAR: SlSaveLoadConvGeneric<action>(ptr, conv); break;
case SL_REF: // Reference variable, translate case SL_REF: // Reference variable, translate
switch (action) { switch (action) {
@@ -1860,14 +1859,14 @@ bool SlObjectMemberGeneric(void *ptr, const SaveLoad *sld)
default: NOT_REACHED(); default: NOT_REACHED();
} }
break; break;
case SL_ARR: SlArray(ptr, sld->length, conv); break; case SL_ARR: SlArray(ptr, sld.length, conv); break;
case SL_STR: SlString(ptr, sld->length, sld->conv); break; case SL_STR: SlString(ptr, sld.length, sld.conv); break;
case SL_LST: SlList<std::list<void *>>(ptr, (SLRefType)conv); break; case SL_LST: SlList<std::list<void *>>(ptr, (SLRefType)conv); break;
case SL_PTRDEQ: SlList<std::deque<void *>>(ptr, (SLRefType)conv); break; case SL_PTRDEQ: SlList<std::deque<void *>>(ptr, (SLRefType)conv); break;
case SL_VEC: SlList<std::vector<void *>>(ptr, (SLRefType)conv); break; case SL_VEC: SlList<std::vector<void *>>(ptr, (SLRefType)conv); break;
case SL_DEQUE: SlDeque(ptr, conv); break; case SL_DEQUE: SlDeque(ptr, conv); break;
case SL_VARVEC: { case SL_VARVEC: {
const size_t size_len = SlCalcConvMemLen(sld->conv); const size_t size_len = SlCalcConvMemLen(sld.conv);
switch (size_len) { switch (size_len) {
case 1: SlVarList<std::vector<byte>>(ptr, conv); break; case 1: SlVarList<std::vector<byte>>(ptr, conv); break;
case 2: SlVarList<std::vector<uint16>>(ptr, conv); break; case 2: SlVarList<std::vector<uint16>>(ptr, conv); break;
@@ -1877,7 +1876,7 @@ bool SlObjectMemberGeneric(void *ptr, const SaveLoad *sld)
} }
break; break;
} }
case SL_STDSTR: SlStdString(*static_cast<std::string *>(ptr), sld->conv); break; case SL_STDSTR: SlStdString(*static_cast<std::string *>(ptr), sld.conv); break;
default: NOT_REACHED(); default: NOT_REACHED();
} }
break; break;
@@ -1910,7 +1909,7 @@ bool SlObjectMemberGeneric(void *ptr, const SaveLoad *sld)
return true; return true;
} }
bool SlObjectMember(void *ptr, const SaveLoad *sld) bool SlObjectMember(void *ptr, const SaveLoad &sld)
{ {
switch (_sl.action) { switch (_sl.action) {
case SLA_SAVE: case SLA_SAVE:
@@ -1928,71 +1927,71 @@ bool SlObjectMember(void *ptr, const SaveLoad *sld)
/** /**
* Main SaveLoad function. * Main SaveLoad function.
* @param object The object that is being saved or loaded * @param object The object that is being saved or loaded.
* @param sld The SaveLoad description of the object so we know how to manipulate it * @param slt The SaveLoad table with objects to save/load.
*/ */
void SlObject(void *object, const SaveLoad *sld) void SlObject(void *object, const SaveLoadTable &slt)
{ {
/* Automatically calculate the length? */ /* Automatically calculate the length? */
if (_sl.need_length != NL_NONE) { if (_sl.need_length != NL_NONE) {
SlSetLength(SlCalcObjLength(object, sld)); SlSetLength(SlCalcObjLength(object, slt));
} }
for (; sld->cmd != SL_END; sld++) { for (auto &sld : slt) {
void *ptr = GetVariableAddress(object, sld); void *ptr = GetVariableAddress(object, sld);
SlObjectMember(ptr, sld); SlObjectMember(ptr, sld);
} }
} }
template <SaveLoadAction action, bool check_version> template <SaveLoadAction action, bool check_version>
void SlObjectIterateBase(void *object, const SaveLoad *sld) void SlObjectIterateBase(void *object, const SaveLoadTable &slt)
{ {
for (; sld->cmd != SL_END; sld++) { for (auto &sld : slt) {
void *ptr = sld->global ? sld->address : GetVariableAddress(object, sld); void *ptr = sld.global ? sld.address : GetVariableAddress(object, sld);
SlObjectMemberGeneric<action, check_version>(ptr, sld); SlObjectMemberGeneric<action, check_version>(ptr, sld);
} }
} }
void SlObjectSaveFiltered(void *object, const SaveLoad *sld) void SlObjectSaveFiltered(void *object, const SaveLoadTable &slt)
{ {
if (_sl.need_length != NL_NONE) { if (_sl.need_length != NL_NONE) {
_sl.need_length = NL_NONE; _sl.need_length = NL_NONE;
_sl.dumper->StartAutoLength(); _sl.dumper->StartAutoLength();
SlObjectIterateBase<SLA_SAVE, false>(object, sld); SlObjectIterateBase<SLA_SAVE, false>(object, slt);
auto result = _sl.dumper->StopAutoLength(); auto result = _sl.dumper->StopAutoLength();
_sl.need_length = NL_WANTLENGTH; _sl.need_length = NL_WANTLENGTH;
SlSetLength(result.second); SlSetLength(result.second);
_sl.dumper->CopyBytes(result.first, result.second); _sl.dumper->CopyBytes(result.first, result.second);
} else { } else {
SlObjectIterateBase<SLA_SAVE, false>(object, sld); SlObjectIterateBase<SLA_SAVE, false>(object, slt);
} }
} }
void SlObjectLoadFiltered(void *object, const SaveLoad *sld) void SlObjectLoadFiltered(void *object, const SaveLoadTable &slt)
{ {
SlObjectIterateBase<SLA_LOAD, false>(object, sld); SlObjectIterateBase<SLA_LOAD, false>(object, slt);
} }
void SlObjectPtrOrNullFiltered(void *object, const SaveLoad *sld) void SlObjectPtrOrNullFiltered(void *object, const SaveLoadTable &slt)
{ {
switch (_sl.action) { switch (_sl.action) {
case SLA_PTRS: case SLA_PTRS:
SlObjectIterateBase<SLA_PTRS, false>(object, sld); SlObjectIterateBase<SLA_PTRS, false>(object, slt);
return; return;
case SLA_NULL: case SLA_NULL:
SlObjectIterateBase<SLA_NULL, false>(object, sld); SlObjectIterateBase<SLA_NULL, false>(object, slt);
return; return;
default: NOT_REACHED(); default: NOT_REACHED();
} }
} }
/** /**
* Save or Load (a list of) global variables * Save or Load (a list of) global variables.
* @param sldg The global variable that is being loaded or saved * @param slt The SaveLoad table with objects to save/load.
*/ */
void SlGlobList(const SaveLoadGlobVarList *sldg) void SlGlobList(const SaveLoadTable &slt)
{ {
SlObject(nullptr, (const SaveLoad*)sldg); SlObject(nullptr, slt);
} }
/** /**

View File

@@ -12,6 +12,7 @@
#include "../fileio_type.h" #include "../fileio_type.h"
#include "../strings_type.h" #include "../strings_type.h"
#include "../core/span_type.hpp"
#include "extended_ver_sl.h" #include "extended_ver_sl.h"
#include <stdarg.h> #include <stdarg.h>
@@ -564,7 +565,6 @@ enum SaveLoadTypes {
SL_PTRDEQ = 13, ///< Save/load a pointer type deque. SL_PTRDEQ = 13, ///< Save/load a pointer type deque.
SL_VARVEC = 14, ///< Save/load a primitive type vector. SL_VARVEC = 14, ///< Save/load a primitive type vector.
SL_END = 15
}; };
typedef byte SaveLoadType; ///< Save/load type. @see SaveLoadTypes typedef byte SaveLoadType; ///< Save/load type. @see SaveLoadTypes
@@ -586,8 +586,8 @@ struct SaveLoad {
SlXvFeatureTest ext_feature_test; ///< extended feature test SlXvFeatureTest ext_feature_test; ///< extended feature test
}; };
/** Same as #SaveLoad but global variables are used (for better readability); */ /** A table of SaveLoad entries. */
typedef SaveLoad SaveLoadGlobVarList; using SaveLoadTable = span<const SaveLoad>;
/** /**
* Storage of simple variables, references (pointers), and arrays. * Storage of simple variables, references (pointers), and arrays.
@@ -813,9 +813,6 @@ typedef SaveLoad SaveLoadGlobVarList;
#define SLE_VEH_INCLUDE() {false, SL_VEH_INCLUDE, 0, 0, SL_MIN_VERSION, SL_MAX_VERSION, nullptr, 0, SlXvFeatureTest()} #define SLE_VEH_INCLUDE() {false, SL_VEH_INCLUDE, 0, 0, SL_MIN_VERSION, SL_MAX_VERSION, nullptr, 0, SlXvFeatureTest()}
#define SLE_ST_INCLUDE() {false, SL_ST_INCLUDE, 0, 0, SL_MIN_VERSION, SL_MAX_VERSION, nullptr, 0, SlXvFeatureTest()} #define SLE_ST_INCLUDE() {false, SL_ST_INCLUDE, 0, 0, SL_MIN_VERSION, SL_MAX_VERSION, nullptr, 0, SlXvFeatureTest()}
/** End marker of a struct/class save or load. */
#define SLE_END() {false, SL_END, 0, 0, SL_MIN_VERSION, SL_MIN_VERSION, nullptr, 0, SlXvFeatureTest()}
/** /**
* Storage of global simple variables, references (pointers), and arrays. * Storage of global simple variables, references (pointers), and arrays.
* @param cmd Load/save type. @see SaveLoadType * @param cmd Load/save type. @see SaveLoadType
@@ -983,9 +980,6 @@ typedef SaveLoad SaveLoadGlobVarList;
*/ */
#define SLEG_CONDNULL(length, from, to) {true, SL_ARR, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to, (void*)nullptr, SlXvFeatureTest()} #define SLEG_CONDNULL(length, from, to) {true, SL_ARR, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to, (void*)nullptr, SlXvFeatureTest()}
/** End marker of global variables save or load. */
#define SLEG_END() {true, SL_END, 0, 0, SL_MIN_VERSION, SL_MIN_VERSION, nullptr, 0, SlXvFeatureTest()}
/** /**
* Checks whether the savegame is below \a major.\a minor. * Checks whether the savegame is below \a major.\a minor.
* @param major Major number of the version to check against. * @param major Major number of the version to check against.
@@ -1065,22 +1059,22 @@ static inline bool IsNumericType(VarType conv)
* is taken. If non-null only the offset is stored in the union and we need * is taken. If non-null only the offset is stored in the union and we need
* to add this to the address of the object * to add this to the address of the object
*/ */
static inline void *GetVariableAddress(const void *object, const SaveLoad *sld) static inline void *GetVariableAddress(const void *object, const SaveLoad &sld)
{ {
/* Entry is a global address. */ /* Entry is a global address. */
if (sld->global) return sld->address; if (sld.global) return sld.address;
#ifdef _DEBUG #ifdef _DEBUG
/* Entry is a null-variable, mostly used to read old savegames etc. */ /* Entry is a null-variable, mostly used to read old savegames etc. */
if (GetVarMemType(sld->conv) == SLE_VAR_NULL) { if (GetVarMemType(sld.conv) == SLE_VAR_NULL) {
assert(sld->address == nullptr); assert(sld.address == nullptr);
return nullptr; return nullptr;
} }
/* Everything else should be a non-null pointer. */ /* Everything else should be a non-null pointer. */
assert(object != nullptr); assert(object != nullptr);
#endif #endif
return const_cast<byte *>((const byte *)object + (ptrdiff_t)sld->address); return const_cast<byte *>((const byte *)object + (ptrdiff_t)sld.address);
} }
int64 ReadValue(const void *ptr, VarType conv); int64 ReadValue(const void *ptr, VarType conv);
@@ -1092,8 +1086,8 @@ int SlIterateArray();
void SlAutolength(AutolengthProc *proc, void *arg); void SlAutolength(AutolengthProc *proc, void *arg);
size_t SlGetFieldLength(); size_t SlGetFieldLength();
void SlSetLength(size_t length); void SlSetLength(size_t length);
size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld); size_t SlCalcObjMemberLength(const void *object, const SaveLoad &sld);
size_t SlCalcObjLength(const void *object, const SaveLoad *sld); size_t SlCalcObjLength(const void *object, const SaveLoadTable &slt);
byte SlReadByte(); byte SlReadByte();
void SlWriteByte(byte b); void SlWriteByte(byte b);
@@ -1111,15 +1105,15 @@ void SlSkipBytes(size_t length);
size_t SlGetBytesRead(); size_t SlGetBytesRead();
size_t SlGetBytesWritten(); size_t SlGetBytesWritten();
void SlGlobList(const SaveLoadGlobVarList *sldg); void SlGlobList(const SaveLoadTable &slt);
void SlArray(void *array, size_t length, VarType conv); void SlArray(void *array, size_t length, VarType conv);
void SlObject(void *object, const SaveLoad *sld); void SlObject(void *object, const SaveLoadTable &slt);
bool SlObjectMember(void *object, const SaveLoad *sld); bool SlObjectMember(void *object, const SaveLoad &sld);
std::vector<SaveLoad> SlFilterObject(const SaveLoad *sld); std::vector<SaveLoad> SlFilterObject(const SaveLoadTable &slt);
void SlObjectSaveFiltered(void *object, const SaveLoad *sld); void SlObjectSaveFiltered(void *object, const SaveLoadTable &slt);
void SlObjectLoadFiltered(void *object, const SaveLoad *sld); void SlObjectLoadFiltered(void *object, const SaveLoadTable &slt);
void SlObjectPtrOrNullFiltered(void *object, const SaveLoad *sld); void SlObjectPtrOrNullFiltered(void *object, const SaveLoadTable &slt);
void NORETURN SlError(StringID string, const char *extra_msg = nullptr, bool already_malloced = false); void NORETURN SlError(StringID string, const char *extra_msg = nullptr, bool already_malloced = false);
void NORETURN SlErrorCorrupt(const char *msg, bool already_malloced = false); void NORETURN SlErrorCorrupt(const char *msg, bool already_malloced = false);

View File

@@ -23,7 +23,7 @@ void ResetOldNames();
void ResetOldWaypoints(); void ResetOldWaypoints();
void MoveBuoysToWaypoints(); void MoveBuoysToWaypoints();
void MoveWaypointsToBaseStations(); void MoveWaypointsToBaseStations();
const SaveLoad *GetBaseStationDescription(); SaveLoadTable GetBaseStationDescription();
void AfterLoadVehicles(bool part_of_load); void AfterLoadVehicles(bool part_of_load);
void AfterLoadEngines(); void AfterLoadEngines();

View File

@@ -26,7 +26,6 @@ static const SaveLoad _sign_desc[] = {
SLE_CONDVAR(Sign, owner, SLE_UINT8, SLV_6, SL_MAX_VERSION), SLE_CONDVAR(Sign, owner, SLE_UINT8, SLV_6, SL_MAX_VERSION),
SLE_CONDVAR_X(Sign, z, SLE_FILE_U8 | SLE_VAR_I32, SL_MIN_VERSION, SLV_164, SlXvFeatureTest(XSLFTO_AND, XSLFI_ZPOS_32_BIT, 0, 0)), SLE_CONDVAR_X(Sign, z, SLE_FILE_U8 | SLE_VAR_I32, SL_MIN_VERSION, SLV_164, SlXvFeatureTest(XSLFTO_AND, XSLFI_ZPOS_32_BIT, 0, 0)),
SLE_CONDVAR_X(Sign, z, SLE_INT32, SLV_164, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_OR, XSLFI_ZPOS_32_BIT)), SLE_CONDVAR_X(Sign, z, SLE_INT32, SLV_164, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_OR, XSLFI_ZPOS_32_BIT)),
SLE_END()
}; };
/** Save all signs */ /** Save all signs */

View File

@@ -157,8 +157,6 @@ static const SaveLoad _roadstop_desc[] = {
SLE_CONDNULL(4, SL_MIN_VERSION, SLV_25), SLE_CONDNULL(4, SL_MIN_VERSION, SLV_25),
SLE_CONDNULL(1, SLV_25, SLV_26), SLE_CONDNULL(1, SLV_25, SLV_26),
SLE_END()
}; };
static const SaveLoad _old_station_desc[] = { static const SaveLoad _old_station_desc[] = {
@@ -218,8 +216,6 @@ static const SaveLoad _old_station_desc[] = {
/* reserve extra space in savegame here. (currently 32 bytes) */ /* reserve extra space in savegame here. (currently 32 bytes) */
SLE_CONDNULL(32, SLV_2, SL_MAX_VERSION), SLE_CONDNULL(32, SLV_2, SL_MAX_VERSION),
SLE_END()
}; };
static uint16 _waiting_acceptance; static uint16 _waiting_acceptance;
@@ -232,8 +228,6 @@ static Money _cargo_feeder_share;
static const SaveLoad _station_speclist_desc[] = { static const SaveLoad _station_speclist_desc[] = {
SLE_CONDVAR(StationSpecList, grfid, SLE_UINT32, SLV_27, SL_MAX_VERSION), SLE_CONDVAR(StationSpecList, grfid, SLE_UINT32, SLV_27, SL_MAX_VERSION),
SLE_CONDVAR(StationSpecList, localidx, SLE_UINT8, SLV_27, SL_MAX_VERSION), SLE_CONDVAR(StationSpecList, localidx, SLE_UINT8, SLV_27, SL_MAX_VERSION),
SLE_END()
}; };
CargoPacketList _packets; CargoPacketList _packets;
@@ -253,7 +247,6 @@ static const SaveLoad _flow_desc[] = {
SLE_VAR(FlowSaveLoad, via, SLE_UINT16), SLE_VAR(FlowSaveLoad, via, SLE_UINT16),
SLE_VAR(FlowSaveLoad, share, SLE_UINT32), SLE_VAR(FlowSaveLoad, share, SLE_UINT32),
SLE_CONDVAR(FlowSaveLoad, restricted, SLE_BOOL, SLV_187, SL_MAX_VERSION), SLE_CONDVAR(FlowSaveLoad, restricted, SLE_BOOL, SLV_187, SL_MAX_VERSION),
SLE_END()
}; };
#endif #endif
@@ -262,7 +255,7 @@ static const SaveLoad _flow_desc[] = {
* some of the variables itself are private. * some of the variables itself are private.
* @return the saveload description for GoodsEntry. * @return the saveload description for GoodsEntry.
*/ */
const SaveLoad *GetGoodsDesc() SaveLoadTable GetGoodsDesc()
{ {
static const SaveLoad goods_desc[] = { static const SaveLoad goods_desc[] = {
SLEG_CONDVAR( _waiting_acceptance, SLE_UINT16, SL_MIN_VERSION, SLV_68), SLEG_CONDVAR( _waiting_acceptance, SLE_UINT16, SL_MIN_VERSION, SLV_68),
@@ -289,7 +282,6 @@ const SaveLoad *GetGoodsDesc()
SLE_CONDVAR(GoodsEntry, max_waiting_cargo, SLE_UINT32, SLV_183, SL_MAX_VERSION), SLE_CONDVAR(GoodsEntry, max_waiting_cargo, SLE_UINT32, SLV_183, SL_MAX_VERSION),
SLE_CONDNULL_X(4, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)), SLE_CONDNULL_X(4, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)),
SLE_CONDVAR_X(GoodsEntry, last_vehicle_type, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ST_LAST_VEH_TYPE, 1)), SLE_CONDVAR_X(GoodsEntry, last_vehicle_type, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ST_LAST_VEH_TYPE, 1)),
SLE_END()
}; };
return goods_desc; return goods_desc;
@@ -300,7 +292,6 @@ typedef std::pair<const StationID, CargoPacketList> StationCargoPair;
static const SaveLoad _cargo_list_desc[] = { static const SaveLoad _cargo_list_desc[] = {
SLE_VAR(StationCargoPair, first, SLE_UINT16), SLE_VAR(StationCargoPair, first, SLE_UINT16),
SLE_PTRDEQ(StationCargoPair, second, REF_CARGO_PACKET), SLE_PTRDEQ(StationCargoPair, second, REF_CARGO_PACKET),
SLE_END()
}; };
/** /**
@@ -411,8 +402,6 @@ static const SaveLoad _base_station_desc[] = {
SLE_VAR(BaseStation, random_bits, SLE_UINT16), SLE_VAR(BaseStation, random_bits, SLE_UINT16),
SLE_VAR(BaseStation, waiting_triggers, SLE_UINT8), SLE_VAR(BaseStation, waiting_triggers, SLE_UINT8),
SLE_VAR(BaseStation, num_specs, SLE_UINT8), SLE_VAR(BaseStation, num_specs, SLE_UINT8),
SLE_END()
}; };
static OldPersistentStorage _old_st_persistent_storage; static OldPersistentStorage _old_st_persistent_storage;
@@ -461,8 +450,6 @@ static const SaveLoad _station_desc[] = {
SLE_CONDVAR(Station, always_accepted, SLE_UINT64, SLV_EXTEND_CARGOTYPES, SL_MAX_VERSION), SLE_CONDVAR(Station, always_accepted, SLE_UINT64, SLV_EXTEND_CARGOTYPES, SL_MAX_VERSION),
SLE_CONDNULL_X(32 * 24, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP, SL_JOKER_1_22)), SLE_CONDNULL_X(32 * 24, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP, SL_JOKER_1_22)),
SLE_CONDVAR_X(Station, station_cargo_history_cargoes, SLE_UINT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_STATION_CARGO_HISTORY)), SLE_CONDVAR_X(Station, station_cargo_history_cargoes, SLE_UINT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_STATION_CARGO_HISTORY)),
SLE_END()
}; };
static const SaveLoad _waypoint_desc[] = { static const SaveLoad _waypoint_desc[] = {
@@ -474,15 +461,13 @@ static const SaveLoad _waypoint_desc[] = {
SLE_CONDVAR(Waypoint, train_station.tile, SLE_UINT32, SLV_124, SL_MAX_VERSION), SLE_CONDVAR(Waypoint, train_station.tile, SLE_UINT32, SLV_124, SL_MAX_VERSION),
SLE_CONDVAR(Waypoint, train_station.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_124, SL_MAX_VERSION), SLE_CONDVAR(Waypoint, train_station.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_124, SL_MAX_VERSION),
SLE_CONDVAR(Waypoint, train_station.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_124, SL_MAX_VERSION), SLE_CONDVAR(Waypoint, train_station.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_124, SL_MAX_VERSION),
SLE_END()
}; };
/** /**
* Get the base station description to be used for SL_ST_INCLUDE * Get the base station description to be used for SL_ST_INCLUDE
* @return the base station description. * @return the base station description.
*/ */
const SaveLoad *GetBaseStationDescription() SaveLoadTable GetBaseStationDescription()
{ {
return _base_station_desc; return _base_station_desc;
} }
@@ -511,7 +496,7 @@ static void SetupDescs_ROADSTOP()
static void RealSave_STNN(BaseStation *bst) static void RealSave_STNN(BaseStation *bst)
{ {
bool waypoint = (bst->facilities & FACIL_WAYPOINT) != 0; bool waypoint = (bst->facilities & FACIL_WAYPOINT) != 0;
SlObjectSaveFiltered(bst, waypoint ? _filtered_waypoint_desc.data() : _filtered_station_desc.data()); SlObjectSaveFiltered(bst, waypoint ? SaveLoadTable(_filtered_waypoint_desc) : SaveLoadTable(_filtered_station_desc));
MemoryDumper *dumper = MemoryDumper::GetCurrent(); MemoryDumper *dumper = MemoryDumper::GetCurrent();
@@ -520,7 +505,7 @@ static void RealSave_STNN(BaseStation *bst)
for (CargoID i = 0; i < NUM_CARGO; i++) { for (CargoID i = 0; i < NUM_CARGO; i++) {
_num_dests = (uint32)st->goods[i].cargo.Packets()->MapSize(); _num_dests = (uint32)st->goods[i].cargo.Packets()->MapSize();
_num_flows = (uint32)st->goods[i].flows.size(); _num_flows = (uint32)st->goods[i].flows.size();
SlObjectSaveFiltered(&st->goods[i], _filtered_goods_desc.data()); SlObjectSaveFiltered(&st->goods[i], _filtered_goods_desc);
for (FlowStatMap::const_iterator outer_it(st->goods[i].flows.begin()); outer_it != st->goods[i].flows.end(); ++outer_it) { for (FlowStatMap::const_iterator outer_it(st->goods[i].flows.begin()); outer_it != st->goods[i].flows.end(); ++outer_it) {
uint32 sum_shares = 0; uint32 sum_shares = 0;
FlowSaveLoad flow; FlowSaveLoad flow;
@@ -563,7 +548,7 @@ static void RealSave_STNN(BaseStation *bst)
} }
for (uint i = 0; i < bst->num_specs; i++) { for (uint i = 0; i < bst->num_specs; i++) {
SlObjectSaveFiltered(&bst->speclist[i], _filtered_station_speclist_desc.data()); SlObjectSaveFiltered(&bst->speclist[i], _filtered_station_speclist_desc);
} }
} }
@@ -592,7 +577,7 @@ static void Load_STNN()
bool waypoint = (SlReadByte() & FACIL_WAYPOINT) != 0; bool waypoint = (SlReadByte() & FACIL_WAYPOINT) != 0;
BaseStation *bst = waypoint ? (BaseStation *)new (index) Waypoint() : new (index) Station(); BaseStation *bst = waypoint ? (BaseStation *)new (index) Waypoint() : new (index) Station();
SlObjectLoadFiltered(bst, waypoint ? _filtered_waypoint_desc.data() : _filtered_station_desc.data()); SlObjectLoadFiltered(bst, waypoint ? SaveLoadTable(_filtered_waypoint_desc) : SaveLoadTable(_filtered_station_desc));
if (!waypoint) { if (!waypoint) {
Station *st = Station::From(bst); Station *st = Station::From(bst);
@@ -606,7 +591,7 @@ static void Load_STNN()
} }
for (CargoID i = 0; i < num_cargo; i++) { for (CargoID i = 0; i < num_cargo; i++) {
SlObjectLoadFiltered(&st->goods[i], _filtered_goods_desc.data()); SlObjectLoadFiltered(&st->goods[i], _filtered_goods_desc);
StationID prev_source = INVALID_STATION; StationID prev_source = INVALID_STATION;
if (SlXvIsFeaturePresent(XSLFI_FLOW_STAT_FLAGS)) { if (SlXvIsFeaturePresent(XSLFI_FLOW_STAT_FLAGS)) {
for (uint32 j = 0; j < _num_flows; ++j) { for (uint32 j = 0; j < _num_flows; ++j) {
@@ -684,7 +669,7 @@ static void Load_STNN()
/* Allocate speclist memory when loading a game */ /* Allocate speclist memory when loading a game */
bst->speclist = CallocT<StationSpecList>(bst->num_specs); bst->speclist = CallocT<StationSpecList>(bst->num_specs);
for (uint i = 0; i < bst->num_specs; i++) { for (uint i = 0; i < bst->num_specs; i++) {
SlObjectLoadFiltered(&bst->speclist[i], _filtered_station_speclist_desc.data()); SlObjectLoadFiltered(&bst->speclist[i], _filtered_station_speclist_desc);
} }
} }
} }
@@ -698,7 +683,7 @@ static void Ptrs_STNN()
SetupDescs_STNN(); SetupDescs_STNN();
if (!IsSavegameVersionBefore(SLV_183)) { if (!IsSavegameVersionBefore(SLV_183)) {
assert(_filtered_goods_desc[0].cmd == SL_END); assert(_filtered_goods_desc.size() == 0);
} }
uint num_cargo = IsSavegameVersionBefore(SLV_EXTEND_CARGOTYPES) ? 32 : NUM_CARGO; uint num_cargo = IsSavegameVersionBefore(SLV_EXTEND_CARGOTYPES) ? 32 : NUM_CARGO;
@@ -707,7 +692,7 @@ static void Ptrs_STNN()
GoodsEntry *ge = &st->goods[i]; GoodsEntry *ge = &st->goods[i];
if (IsSavegameVersionBefore(SLV_183) && SlXvIsFeatureMissing(XSLFI_CHILLPP)) { if (IsSavegameVersionBefore(SLV_183) && SlXvIsFeatureMissing(XSLFI_CHILLPP)) {
SwapPackets(ge); SwapPackets(ge);
SlObjectPtrOrNullFiltered(ge, _filtered_goods_desc.data()); SlObjectPtrOrNullFiltered(ge, _filtered_goods_desc);
SwapPackets(ge); SwapPackets(ge);
} else { } else {
//SlObject(ge, GetGoodsDesc()); //SlObject(ge, GetGoodsDesc());
@@ -716,11 +701,11 @@ static void Ptrs_STNN()
} }
} }
} }
SlObjectPtrOrNullFiltered(st, _filtered_station_desc.data()); SlObjectPtrOrNullFiltered(st, _filtered_station_desc);
} }
for (Waypoint *wp : Waypoint::Iterate()) { for (Waypoint *wp : Waypoint::Iterate()) {
SlObjectPtrOrNullFiltered(wp, _filtered_waypoint_desc.data()); SlObjectPtrOrNullFiltered(wp, _filtered_waypoint_desc);
} }
} }
@@ -729,7 +714,7 @@ static void Save_ROADSTOP()
SetupDescs_ROADSTOP(); SetupDescs_ROADSTOP();
for (RoadStop *rs : RoadStop::Iterate()) { for (RoadStop *rs : RoadStop::Iterate()) {
SlSetArrayIndex(rs->index); SlSetArrayIndex(rs->index);
SlObjectSaveFiltered(rs, _filtered_roadstop_desc.data()); SlObjectSaveFiltered(rs, _filtered_roadstop_desc);
} }
} }
@@ -740,7 +725,7 @@ static void Load_ROADSTOP()
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
RoadStop *rs = new (index) RoadStop(INVALID_TILE); RoadStop *rs = new (index) RoadStop(INVALID_TILE);
SlObjectLoadFiltered(rs, _filtered_roadstop_desc.data()); SlObjectLoadFiltered(rs, _filtered_roadstop_desc);
} }
} }
@@ -748,7 +733,7 @@ static void Ptrs_ROADSTOP()
{ {
SetupDescs_ROADSTOP(); SetupDescs_ROADSTOP();
for (RoadStop *rs : RoadStop::Iterate()) { for (RoadStop *rs : RoadStop::Iterate()) {
SlObjectPtrOrNullFiltered(rs, _filtered_roadstop_desc.data()); SlObjectPtrOrNullFiltered(rs, _filtered_roadstop_desc);
} }
} }

View File

@@ -18,7 +18,6 @@ static const SaveLoad _storage_desc[] = {
SLE_CONDVAR(PersistentStorage, grfid, SLE_UINT32, SLV_6, SL_MAX_VERSION), SLE_CONDVAR(PersistentStorage, grfid, SLE_UINT32, SLV_6, SL_MAX_VERSION),
SLE_CONDARR(PersistentStorage, storage, SLE_UINT32, 16, SLV_161, SLV_EXTEND_PERSISTENT_STORAGE), SLE_CONDARR(PersistentStorage, storage, SLE_UINT32, 16, SLV_161, SLV_EXTEND_PERSISTENT_STORAGE),
SLE_CONDARR(PersistentStorage, storage, SLE_UINT32, 256, SLV_EXTEND_PERSISTENT_STORAGE, SL_MAX_VERSION), SLE_CONDARR(PersistentStorage, storage, SLE_UINT32, 256, SLV_EXTEND_PERSISTENT_STORAGE, SL_MAX_VERSION),
SLE_END()
}; };
/** Load persistent storage data. */ /** Load persistent storage data. */

View File

@@ -34,7 +34,6 @@ static const SaveLoad _story_page_elements_desc[] = {
SLE_CONDVAR(StoryPageElement, type, SLE_UINT8, SLV_185, SL_MAX_VERSION), SLE_CONDVAR(StoryPageElement, type, SLE_UINT8, SLV_185, SL_MAX_VERSION),
SLE_VAR(StoryPageElement, referenced_id, SLE_UINT32), SLE_VAR(StoryPageElement, referenced_id, SLE_UINT32),
SLE_STR(StoryPageElement, text, SLE_STR | SLF_ALLOW_CONTROL, 0), SLE_STR(StoryPageElement, text, SLE_STR | SLF_ALLOW_CONTROL, 0),
SLE_END()
}; };
static void Save_STORY_PAGE_ELEMENT() static void Save_STORY_PAGE_ELEMENT()
@@ -69,7 +68,6 @@ static const SaveLoad _story_pages_desc[] = {
SLE_CONDVAR(StoryPage, company, SLE_FILE_U16 | SLE_VAR_U8, SL_MIN_VERSION, SLV_185), SLE_CONDVAR(StoryPage, company, SLE_FILE_U16 | SLE_VAR_U8, SL_MIN_VERSION, SLV_185),
SLE_CONDVAR(StoryPage, company, SLE_UINT8, SLV_185, SL_MAX_VERSION), SLE_CONDVAR(StoryPage, company, SLE_UINT8, SLV_185, SL_MAX_VERSION),
SLE_STR(StoryPage, title, SLE_STR | SLF_ALLOW_CONTROL, 0), SLE_STR(StoryPage, title, SLE_STR | SLF_ALLOW_CONTROL, 0),
SLE_END()
}; };
static void Save_STORY_PAGE() static void Save_STORY_PAGE()

View File

@@ -25,7 +25,6 @@ static const SaveLoad _subsidies_desc[] = {
SLE_CONDVAR(Subsidy, src, SLE_UINT16, SLV_5, SL_MAX_VERSION), SLE_CONDVAR(Subsidy, src, SLE_UINT16, SLV_5, SL_MAX_VERSION),
SLE_CONDVAR(Subsidy, dst, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_5), SLE_CONDVAR(Subsidy, dst, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_5),
SLE_CONDVAR(Subsidy, dst, SLE_UINT16, SLV_5, SL_MAX_VERSION), SLE_CONDVAR(Subsidy, dst, SLE_UINT16, SLV_5, SL_MAX_VERSION),
SLE_END()
}; };
static void Save_SUBS() static void Save_SUBS()

View File

@@ -7,7 +7,6 @@
static const SaveLoad _template_replacement_desc[] = { static const SaveLoad _template_replacement_desc[] = {
SLE_VAR(TemplateReplacement, sel_template, SLE_UINT16), SLE_VAR(TemplateReplacement, sel_template, SLE_UINT16),
SLE_VAR(TemplateReplacement, group, SLE_UINT16), SLE_VAR(TemplateReplacement, group, SLE_UINT16),
SLE_END()
}; };
static void Save_TMPL_RPLS() static void Save_TMPL_RPLS()

View File

@@ -9,7 +9,7 @@
#include "saveload.h" #include "saveload.h"
const SaveLoad* GTD() { const SaveLoadTable GTD() {
static const SaveLoad _template_veh_desc[] = { static const SaveLoad _template_veh_desc[] = {
SLE_REF(TemplateVehicle, next, REF_TEMPLATE_VEHICLE), SLE_REF(TemplateVehicle, next, REF_TEMPLATE_VEHICLE),
@@ -49,15 +49,9 @@ const SaveLoad* GTD() {
SLE_CONDNULL_X(36, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TEMPLATE_REPLACEMENT, 2, 3)), SLE_CONDNULL_X(36, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TEMPLATE_REPLACEMENT, 2, 3)),
SLE_CONDNULL_X(36, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)), SLE_CONDNULL_X(36, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)),
SLE_CONDNULL_X(4, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TEMPLATE_REPLACEMENT, 0, 3)), SLE_CONDNULL_X(4, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TEMPLATE_REPLACEMENT, 0, 3)),
SLE_END()
}; };
static const SaveLoad * const _ret[] = { return _template_veh_desc;
_template_veh_desc,
};
return _ret[0];
} }
static void Save_TMPLS() static void Save_TMPLS()

View File

@@ -243,8 +243,6 @@ static const SaveLoad _town_desc[] = {
SLE_CONDNULL(4, SLV_166, SLV_EXTEND_CARGOTYPES), ///< cargo_produced, no longer in use SLE_CONDNULL(4, SLV_166, SLV_EXTEND_CARGOTYPES), ///< cargo_produced, no longer in use
SLE_CONDNULL(8, SLV_EXTEND_CARGOTYPES, SLV_REMOVE_TOWN_CARGO_CACHE), ///< cargo_produced, no longer in use SLE_CONDNULL(8, SLV_EXTEND_CARGOTYPES, SLV_REMOVE_TOWN_CARGO_CACHE), ///< cargo_produced, no longer in use
SLE_CONDNULL(30, SLV_2, SLV_REMOVE_TOWN_CARGO_CACHE), ///< old reserved space SLE_CONDNULL(30, SLV_2, SLV_REMOVE_TOWN_CARGO_CACHE), ///< old reserved space
SLE_END()
}; };
static const SaveLoad _town_supplied_desc[] = { static const SaveLoad _town_supplied_desc[] = {
@@ -252,8 +250,6 @@ static const SaveLoad _town_supplied_desc[] = {
SLE_CONDVAR(TransportedCargoStat<uint32>, new_max, SLE_UINT32, SLV_165, SL_MAX_VERSION), SLE_CONDVAR(TransportedCargoStat<uint32>, new_max, SLE_UINT32, SLV_165, SL_MAX_VERSION),
SLE_CONDVAR(TransportedCargoStat<uint32>, old_act, SLE_UINT32, SLV_165, SL_MAX_VERSION), SLE_CONDVAR(TransportedCargoStat<uint32>, old_act, SLE_UINT32, SLV_165, SL_MAX_VERSION),
SLE_CONDVAR(TransportedCargoStat<uint32>, new_act, SLE_UINT32, SLV_165, SL_MAX_VERSION), SLE_CONDVAR(TransportedCargoStat<uint32>, new_act, SLE_UINT32, SLV_165, SL_MAX_VERSION),
SLE_END()
}; };
static const SaveLoad _town_received_desc[] = { static const SaveLoad _town_received_desc[] = {
@@ -261,8 +257,6 @@ static const SaveLoad _town_received_desc[] = {
SLE_CONDVAR(TransportedCargoStat<uint16>, new_max, SLE_UINT16, SLV_165, SL_MAX_VERSION), SLE_CONDVAR(TransportedCargoStat<uint16>, new_max, SLE_UINT16, SLV_165, SL_MAX_VERSION),
SLE_CONDVAR(TransportedCargoStat<uint16>, old_act, SLE_UINT16, SLV_165, SL_MAX_VERSION), SLE_CONDVAR(TransportedCargoStat<uint16>, old_act, SLE_UINT16, SLV_165, SL_MAX_VERSION),
SLE_CONDVAR(TransportedCargoStat<uint16>, new_act, SLE_UINT16, SLV_165, SL_MAX_VERSION), SLE_CONDVAR(TransportedCargoStat<uint16>, new_act, SLE_UINT16, SLV_165, SL_MAX_VERSION),
SLE_END()
}; };
static const SaveLoad _town_received_desc_spp[] = { static const SaveLoad _town_received_desc_spp[] = {
@@ -270,8 +264,6 @@ static const SaveLoad _town_received_desc_spp[] = {
SLE_CONDVAR(TransportedCargoStat<uint16>, new_max, SLE_FILE_U32 | SLE_VAR_U16, SLV_165, SL_MAX_VERSION), SLE_CONDVAR(TransportedCargoStat<uint16>, new_max, SLE_FILE_U32 | SLE_VAR_U16, SLV_165, SL_MAX_VERSION),
SLE_CONDVAR(TransportedCargoStat<uint16>, old_act, SLE_FILE_U32 | SLE_VAR_U16, SLV_165, SL_MAX_VERSION), SLE_CONDVAR(TransportedCargoStat<uint16>, old_act, SLE_FILE_U32 | SLE_VAR_U16, SLV_165, SL_MAX_VERSION),
SLE_CONDVAR(TransportedCargoStat<uint16>, new_act, SLE_FILE_U32 | SLE_VAR_U16, SLV_165, SL_MAX_VERSION), SLE_CONDVAR(TransportedCargoStat<uint16>, new_act, SLE_FILE_U32 | SLE_VAR_U16, SLV_165, SL_MAX_VERSION),
SLE_END()
}; };
std::vector<SaveLoad> _filtered_town_desc; std::vector<SaveLoad> _filtered_town_desc;
@@ -297,13 +289,13 @@ static void Load_HIDS()
static void RealSave_Town(Town *t) static void RealSave_Town(Town *t)
{ {
SlObjectSaveFiltered(t, _filtered_town_desc.data()); SlObjectSaveFiltered(t, _filtered_town_desc);
for (CargoID i = 0; i < NUM_CARGO; i++) { for (CargoID i = 0; i < NUM_CARGO; i++) {
SlObjectSaveFiltered(&t->supplied[i], _filtered_town_supplied_desc.data()); SlObjectSaveFiltered(&t->supplied[i], _filtered_town_supplied_desc);
} }
for (int i = TE_BEGIN; i < NUM_TE; i++) { for (int i = TE_BEGIN; i < NUM_TE; i++) {
SlObjectSaveFiltered(&t->received[i], _filtered_town_received_desc.data()); SlObjectSaveFiltered(&t->received[i], _filtered_town_received_desc);
} }
} }
@@ -324,10 +316,10 @@ static void Load_TOWN()
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
Town *t = new (index) Town(); Town *t = new (index) Town();
SlObjectLoadFiltered(t, _filtered_town_desc.data()); SlObjectLoadFiltered(t, _filtered_town_desc);
for (CargoID i = 0; i < num_cargo; i++) { for (CargoID i = 0; i < num_cargo; i++) {
SlObjectLoadFiltered(&t->supplied[i], _filtered_town_supplied_desc.data()); SlObjectLoadFiltered(&t->supplied[i], _filtered_town_supplied_desc);
} }
if (SlXvIsFeaturePresent(XSLFI_SPRINGPP)) { if (SlXvIsFeaturePresent(XSLFI_SPRINGPP)) {
for (int i = TE_BEGIN; i < NUM_TE; i++) { for (int i = TE_BEGIN; i < NUM_TE; i++) {
@@ -335,7 +327,7 @@ static void Load_TOWN()
} }
} else { } else {
for (int i = TE_BEGIN; i < NUM_TE; i++) { for (int i = TE_BEGIN; i < NUM_TE; i++) {
SlObjectLoadFiltered(&t->received[i], _filtered_town_received_desc.data()); SlObjectLoadFiltered(&t->received[i], _filtered_town_received_desc);
} }
} }
@@ -362,7 +354,7 @@ static void Ptrs_TOWN()
SetupDescs_TOWN(); SetupDescs_TOWN();
for (Town *t : Town::Iterate()) { for (Town *t : Town::Iterate()) {
SlObjectPtrOrNullFiltered(t, _filtered_town_desc.data()); SlObjectPtrOrNullFiltered(t, _filtered_town_desc);
} }
} }

View File

@@ -16,7 +16,6 @@
static const SaveLoad _trace_restrict_mapping_desc[] = { static const SaveLoad _trace_restrict_mapping_desc[] = {
SLE_VAR(TraceRestrictMappingItem, program_id, SLE_UINT32), SLE_VAR(TraceRestrictMappingItem, program_id, SLE_UINT32),
SLE_END()
}; };
/** /**
@@ -50,7 +49,6 @@ struct TraceRestrictProgramStub {
static const SaveLoad _trace_restrict_program_stub_desc[] = { static const SaveLoad _trace_restrict_program_stub_desc[] = {
SLE_VAR(TraceRestrictProgramStub, length, SLE_UINT32), SLE_VAR(TraceRestrictProgramStub, length, SLE_UINT32),
SLE_END()
}; };
/** /**
@@ -120,14 +118,12 @@ struct TraceRestrictSlotStub {
static const SaveLoad _trace_restrict_slot_stub_desc[] = { static const SaveLoad _trace_restrict_slot_stub_desc[] = {
SLE_VAR(TraceRestrictSlotStub, length, SLE_UINT32), SLE_VAR(TraceRestrictSlotStub, length, SLE_UINT32),
SLE_END()
}; };
static const SaveLoad _trace_restrict_slot_desc[] = { static const SaveLoad _trace_restrict_slot_desc[] = {
SLE_VAR(TraceRestrictSlot, max_occupancy, SLE_UINT32), SLE_VAR(TraceRestrictSlot, max_occupancy, SLE_UINT32),
SLE_SSTR(TraceRestrictSlot, name, SLF_ALLOW_CONTROL), SLE_SSTR(TraceRestrictSlot, name, SLF_ALLOW_CONTROL),
SLE_VAR(TraceRestrictSlot, owner, SLE_UINT8), SLE_VAR(TraceRestrictSlot, owner, SLE_UINT8),
SLE_END()
}; };
/** /**
@@ -174,7 +170,6 @@ static const SaveLoad _trace_restrict_counter_desc[] = {
SLE_VAR(TraceRestrictCounter, value, SLE_INT32), SLE_VAR(TraceRestrictCounter, value, SLE_INT32),
SLE_SSTR(TraceRestrictCounter, name, SLF_ALLOW_CONTROL), SLE_SSTR(TraceRestrictCounter, name, SLF_ALLOW_CONTROL),
SLE_VAR(TraceRestrictCounter, owner, SLE_UINT8), SLE_VAR(TraceRestrictCounter, owner, SLE_UINT8),
SLE_END()
}; };
/** /**

View File

@@ -18,7 +18,6 @@ static const SaveLoad _train_speed_adaptation_map_desc[] = {
SLE_VAR(SignalSpeedType, first.last_passing_train_dir, SLE_UINT8), SLE_VAR(SignalSpeedType, first.last_passing_train_dir, SLE_UINT8),
SLE_VAR(SignalSpeedType, second.train_speed, SLE_UINT16), SLE_VAR(SignalSpeedType, second.train_speed, SLE_UINT16),
SLE_VAR(SignalSpeedType, second.time_stamp, SLE_UINT64), SLE_VAR(SignalSpeedType, second.time_stamp, SLE_UINT64),
SLE_END()
}; };
static void Load_TSAS() static void Load_TSAS()

View File

@@ -20,7 +20,6 @@ static const SaveLoad _tunnel_desc[] = {
SLE_CONDVAR(Tunnel, tile_s, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION), SLE_CONDVAR(Tunnel, tile_s, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION),
SLE_CONDVAR(Tunnel, height, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION), SLE_CONDVAR(Tunnel, height, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION),
SLE_CONDVAR(Tunnel, is_chunnel, SLE_BOOL, SL_MIN_VERSION, SL_MAX_VERSION), SLE_CONDVAR(Tunnel, is_chunnel, SLE_BOOL, SL_MIN_VERSION, SL_MAX_VERSION),
SLE_END()
}; };
static void Save_TUNN() static void Save_TUNN()

View File

@@ -616,7 +616,7 @@ static uint32 _old_ahead_separation;
* @param vt the vehicle type. Can be VEH_END for the common vehicle description data * @param vt the vehicle type. Can be VEH_END for the common vehicle description data
* @return the saveload description * @return the saveload description
*/ */
const SaveLoad *GetVehicleDescription(VehicleType vt) SaveLoadTable GetVehicleDescription(VehicleType vt)
{ {
/** Save and load of vehicles */ /** Save and load of vehicles */
static const SaveLoad _common_veh_desc[] = { static const SaveLoad _common_veh_desc[] = {
@@ -780,11 +780,8 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
SLE_CONDNULL_X(2, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPRINGPP)), SLE_CONDNULL_X(2, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPRINGPP)),
SLE_CONDNULL_X(160, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)), SLE_CONDNULL_X(160, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)),
SLE_END()
}; };
static const SaveLoad _train_desc[] = { static const SaveLoad _train_desc[] = {
SLE_WRITEBYTE(Vehicle, type), SLE_WRITEBYTE(Vehicle, type),
SLE_VEH_INCLUDE(), SLE_VEH_INCLUDE(),
@@ -809,8 +806,6 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
SLE_CONDVAR_X(Train, speed_restriction, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPEED_RESTRICTION)), SLE_CONDVAR_X(Train, speed_restriction, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPEED_RESTRICTION)),
SLE_CONDVAR_X(Train, signal_speed_restriction, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TRAIN_SPEED_ADAPTATION)), SLE_CONDVAR_X(Train, signal_speed_restriction, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TRAIN_SPEED_ADAPTATION)),
SLE_CONDVAR_X(Train, critical_breakdown_count, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_IMPROVED_BREAKDOWNS, 2)), SLE_CONDVAR_X(Train, critical_breakdown_count, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_IMPROVED_BREAKDOWNS, 2)),
SLE_END()
}; };
static const SaveLoad _roadveh_desc[] = { static const SaveLoad _roadveh_desc[] = {
@@ -833,8 +828,6 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
SLE_CONDNULL(2, SLV_6, SLV_131), SLE_CONDNULL(2, SLV_6, SLV_131),
SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space
SLE_CONDVAR_X(RoadVehicle, critical_breakdown_count, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_IMPROVED_BREAKDOWNS, 6)), SLE_CONDVAR_X(RoadVehicle, critical_breakdown_count, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_IMPROVED_BREAKDOWNS, 6)),
SLE_END()
}; };
static const SaveLoad _ship_desc[] = { static const SaveLoad _ship_desc[] = {
@@ -847,8 +840,6 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
SLE_CONDVAR_X(Ship, critical_breakdown_count, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_IMPROVED_BREAKDOWNS, 8)), SLE_CONDVAR_X(Ship, critical_breakdown_count, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_IMPROVED_BREAKDOWNS, 8)),
SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space
SLE_END()
}; };
static const SaveLoad _aircraft_desc[] = { static const SaveLoad _aircraft_desc[] = {
@@ -872,8 +863,6 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
SLE_CONDVAR(Aircraft, flags, SLE_UINT8, SLV_167, SL_MAX_VERSION), SLE_CONDVAR(Aircraft, flags, SLE_UINT8, SLV_167, SL_MAX_VERSION),
SLE_CONDNULL(13, SLV_2, SLV_144), // old reserved space SLE_CONDNULL(13, SLV_2, SLV_144), // old reserved space
SLE_END()
}; };
static const SaveLoad _special_desc[] = { static const SaveLoad _special_desc[] = {
@@ -904,8 +893,6 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
SLE_CONDVAR(Vehicle, spritenum, SLE_UINT8, SLV_2, SL_MAX_VERSION), SLE_CONDVAR(Vehicle, spritenum, SLE_UINT8, SLV_2, SL_MAX_VERSION),
SLE_CONDNULL(15, SLV_2, SLV_144), // old reserved space SLE_CONDNULL(15, SLV_2, SLV_144), // old reserved space
SLE_END()
}; };
static const SaveLoad _disaster_desc[] = { static const SaveLoad _disaster_desc[] = {
@@ -947,12 +934,10 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
SLE_CONDVAR(DisasterVehicle, flags, SLE_UINT8, SLV_194, SL_MAX_VERSION), SLE_CONDVAR(DisasterVehicle, flags, SLE_UINT8, SLV_194, SL_MAX_VERSION),
SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space
SLE_END()
}; };
static const SaveLoad * const _veh_descs[] = { static const SaveLoadTable _veh_descs[] = {
_train_desc, _train_desc,
_roadveh_desc, _roadveh_desc,
_ship_desc, _ship_desc,
@@ -981,9 +966,9 @@ static std::vector<SaveLoad> * const _filtered_veh_descs[] = {
&_filtered_disaster_desc, &_filtered_disaster_desc,
}; };
const SaveLoad *GetVehicleDescriptionFiltered(VehicleType vt) const SaveLoadTable GetVehicleDescriptionFiltered(VehicleType vt)
{ {
return _filtered_veh_descs[vt]->data(); return *(_filtered_veh_descs[vt]);
} }
static void SetupDescs_VEHS() static void SetupDescs_VEHS()
@@ -1078,7 +1063,7 @@ static void Ptrs_VEHS()
} }
} }
const SaveLoad *GetOrderExtraInfoDescription(); const SaveLoadTable GetOrderExtraInfoDescription();
void Save_VEOX() void Save_VEOX()
{ {
@@ -1103,14 +1088,13 @@ void Load_VEOX()
} }
} }
const SaveLoad *GetVehicleSpeedRestrictionDescription() const SaveLoadTable GetVehicleSpeedRestrictionDescription()
{ {
static const SaveLoad _vehicle_speed_restriction_desc[] = { static const SaveLoad _vehicle_speed_restriction_desc[] = {
SLE_VAR(PendingSpeedRestrictionChange, distance, SLE_UINT16), SLE_VAR(PendingSpeedRestrictionChange, distance, SLE_UINT16),
SLE_VAR(PendingSpeedRestrictionChange, new_speed, SLE_UINT16), SLE_VAR(PendingSpeedRestrictionChange, new_speed, SLE_UINT16),
SLE_VAR(PendingSpeedRestrictionChange, prev_speed, SLE_UINT16), SLE_VAR(PendingSpeedRestrictionChange, prev_speed, SLE_UINT16),
SLE_VAR(PendingSpeedRestrictionChange, flags, SLE_UINT16), SLE_VAR(PendingSpeedRestrictionChange, flags, SLE_UINT16),
SLE_END()
}; };
return _vehicle_speed_restriction_desc; return _vehicle_speed_restriction_desc;
@@ -1391,7 +1375,7 @@ void SlProcessVENC()
} }
} }
const SaveLoad *GetVehicleLookAheadDescription() const SaveLoadTable GetVehicleLookAheadDescription()
{ {
static const SaveLoad _vehicle_look_ahead_desc[] = { static const SaveLoad _vehicle_look_ahead_desc[] = {
SLE_VAR(TrainReservationLookAhead, reservation_end_tile, SLE_UINT32), SLE_VAR(TrainReservationLookAhead, reservation_end_tile, SLE_UINT32),
@@ -1402,13 +1386,12 @@ const SaveLoad *GetVehicleLookAheadDescription()
SLE_VAR(TrainReservationLookAhead, tunnel_bridge_reserved_tiles, SLE_INT16), SLE_VAR(TrainReservationLookAhead, tunnel_bridge_reserved_tiles, SLE_INT16),
SLE_VAR(TrainReservationLookAhead, flags, SLE_UINT16), SLE_VAR(TrainReservationLookAhead, flags, SLE_UINT16),
SLE_VAR(TrainReservationLookAhead, speed_restriction, SLE_UINT16), SLE_VAR(TrainReservationLookAhead, speed_restriction, SLE_UINT16),
SLE_END()
}; };
return _vehicle_look_ahead_desc; return _vehicle_look_ahead_desc;
} }
const SaveLoad *GetVehicleLookAheadItemDescription() const SaveLoadTable GetVehicleLookAheadItemDescription()
{ {
static const SaveLoad _vehicle_look_ahead_item_desc[] = { static const SaveLoad _vehicle_look_ahead_item_desc[] = {
SLE_VAR(TrainReservationLookAheadItem, start, SLE_INT32), SLE_VAR(TrainReservationLookAheadItem, start, SLE_INT32),
@@ -1416,18 +1399,16 @@ const SaveLoad *GetVehicleLookAheadItemDescription()
SLE_VAR(TrainReservationLookAheadItem, z_pos, SLE_INT16), SLE_VAR(TrainReservationLookAheadItem, z_pos, SLE_INT16),
SLE_VAR(TrainReservationLookAheadItem, data_id, SLE_UINT16), SLE_VAR(TrainReservationLookAheadItem, data_id, SLE_UINT16),
SLE_VAR(TrainReservationLookAheadItem, type, SLE_UINT8), SLE_VAR(TrainReservationLookAheadItem, type, SLE_UINT8),
SLE_END()
}; };
return _vehicle_look_ahead_item_desc; return _vehicle_look_ahead_item_desc;
} }
const SaveLoad *GetVehicleLookAheadCurveDescription() const SaveLoadTable GetVehicleLookAheadCurveDescription()
{ {
static const SaveLoad _vehicle_look_ahead_curve_desc[] = { static const SaveLoad _vehicle_look_ahead_curve_desc[] = {
SLE_VAR(TrainReservationLookAheadCurve, position, SLE_INT32), SLE_VAR(TrainReservationLookAheadCurve, position, SLE_INT32),
SLE_VAR(TrainReservationLookAheadCurve, dir_diff, SLE_UINT8), SLE_VAR(TrainReservationLookAheadCurve, dir_diff, SLE_UINT8),
SLE_END()
}; };
return _vehicle_look_ahead_curve_desc; return _vehicle_look_ahead_curve_desc;

View File

@@ -180,8 +180,6 @@ static const SaveLoad _old_waypoint_desc[] = {
SLE_CONDVAR(OldWaypoint, localidx, SLE_UINT8, SLV_3, SL_MAX_VERSION), SLE_CONDVAR(OldWaypoint, localidx, SLE_UINT8, SLV_3, SL_MAX_VERSION),
SLE_CONDVAR(OldWaypoint, grfid, SLE_UINT32, SLV_17, SL_MAX_VERSION), SLE_CONDVAR(OldWaypoint, grfid, SLE_UINT32, SLV_17, SL_MAX_VERSION),
SLE_CONDVAR(OldWaypoint, owner, SLE_UINT8, SLV_101, SL_MAX_VERSION), SLE_CONDVAR(OldWaypoint, owner, SLE_UINT8, SLV_101, SL_MAX_VERSION),
SLE_END()
}; };
static void Load_WAYP() static void Load_WAYP()

View File

@@ -139,7 +139,7 @@
return 1; return 1;
} }
NetworkAdminGameScript(json.c_str()); NetworkAdminGameScript(json);
sq_pushinteger(vm, 1); sq_pushinteger(vm, 1);
return 1; return 1;

View File

@@ -260,7 +260,7 @@
/* static */ bool ScriptCompany::SetAutoRenewStatus(bool autorenew) /* static */ bool ScriptCompany::SetAutoRenewStatus(bool autorenew)
{ {
return ScriptObject::DoCommand(0, ::GetCompanySettingIndex("company.engine_renew"), autorenew ? 1 : 0, CMD_CHANGE_COMPANY_SETTING); return ScriptObject::DoCommand(0, 0, autorenew ? 1 : 0, CMD_CHANGE_COMPANY_SETTING, "company.engine_renew");
} }
/* static */ bool ScriptCompany::GetAutoRenewStatus(CompanyID company) /* static */ bool ScriptCompany::GetAutoRenewStatus(CompanyID company)
@@ -273,7 +273,7 @@
/* static */ bool ScriptCompany::SetAutoRenewMonths(int16 months) /* static */ bool ScriptCompany::SetAutoRenewMonths(int16 months)
{ {
return ScriptObject::DoCommand(0, ::GetCompanySettingIndex("company.engine_renew_months"), months, CMD_CHANGE_COMPANY_SETTING); return ScriptObject::DoCommand(0, 0, months, CMD_CHANGE_COMPANY_SETTING, "company.engine_renew_months");
} }
/* static */ int16 ScriptCompany::GetAutoRenewMonths(CompanyID company) /* static */ int16 ScriptCompany::GetAutoRenewMonths(CompanyID company)
@@ -288,7 +288,7 @@
{ {
EnforcePrecondition(false, money >= 0); EnforcePrecondition(false, money >= 0);
EnforcePrecondition(false, (int64)money <= UINT32_MAX); EnforcePrecondition(false, (int64)money <= UINT32_MAX);
return ScriptObject::DoCommand(0, ::GetCompanySettingIndex("company.engine_renew_money"), money, CMD_CHANGE_COMPANY_SETTING); return ScriptObject::DoCommand(0, 0, money, CMD_CHANGE_COMPANY_SETTING, "company.engine_renew_money");
} }
/* static */ Money ScriptCompany::GetAutoRenewMoney(CompanyID company) /* static */ Money ScriptCompany::GetAutoRenewMoney(CompanyID company)

View File

@@ -118,23 +118,18 @@ bool ScriptEventCompanyAskMerger::AcceptMerger()
return ScriptObject::DoCommand(0, this->owner, 0, CMD_BUY_COMPANY); return ScriptObject::DoCommand(0, this->owner, 0, CMD_BUY_COMPANY);
} }
ScriptEventAdminPort::ScriptEventAdminPort(const char *json) : ScriptEventAdminPort::ScriptEventAdminPort(const std::string &json) :
ScriptEvent(ET_ADMIN_PORT), ScriptEvent(ET_ADMIN_PORT),
json(stredup(json)) json(json)
{ {
} }
ScriptEventAdminPort::~ScriptEventAdminPort()
{
free(this->json);
}
#define SKIP_EMPTY(p) while (*(p) == ' ' || *(p) == '\n' || *(p) == '\r') (p)++; #define SKIP_EMPTY(p) while (*(p) == ' ' || *(p) == '\n' || *(p) == '\r') (p)++;
#define RETURN_ERROR(stack) { ScriptLog::Error("Received invalid JSON data from AdminPort."); if (stack != 0) sq_pop(vm, stack); return nullptr; } #define RETURN_ERROR(stack) { ScriptLog::Error("Received invalid JSON data from AdminPort."); if (stack != 0) sq_pop(vm, stack); return nullptr; }
SQInteger ScriptEventAdminPort::GetObject(HSQUIRRELVM vm) SQInteger ScriptEventAdminPort::GetObject(HSQUIRRELVM vm)
{ {
char *p = this->json; const char *p = this->json.c_str();
if (this->ReadTable(vm, p) == nullptr) { if (this->ReadTable(vm, p) == nullptr) {
sq_pushnull(vm); sq_pushnull(vm);
@@ -144,9 +139,9 @@ SQInteger ScriptEventAdminPort::GetObject(HSQUIRRELVM vm)
return 1; return 1;
} }
char *ScriptEventAdminPort::ReadString(HSQUIRRELVM vm, char *p) const char *ScriptEventAdminPort::ReadString(HSQUIRRELVM vm, const char *p)
{ {
char *value = p; const char *value = p;
bool escape = false; bool escape = false;
for (;;) { for (;;) {
@@ -168,14 +163,14 @@ char *ScriptEventAdminPort::ReadString(HSQUIRRELVM vm, char *p)
p++; p++;
} }
*p = '\0'; size_t len = p - value;
sq_pushstring(vm, value, -1); sq_pushstring(vm, value, len);
*p++ = '"'; p++; // Step past the end-of-string marker (")
return p; return p;
} }
char *ScriptEventAdminPort::ReadTable(HSQUIRRELVM vm, char *p) const char *ScriptEventAdminPort::ReadTable(HSQUIRRELVM vm, const char *p)
{ {
sq_newtable(vm); sq_newtable(vm);
@@ -218,7 +213,7 @@ char *ScriptEventAdminPort::ReadTable(HSQUIRRELVM vm, char *p)
return p; return p;
} }
char *ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, char *p) const char *ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, const char *p)
{ {
SKIP_EMPTY(p); SKIP_EMPTY(p);
@@ -257,7 +252,7 @@ char *ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, char *p)
sq_newarray(vm, 0); sq_newarray(vm, 0);
/* Empty array? */ /* Empty array? */
char *p2 = p + 1; const char *p2 = p + 1;
SKIP_EMPTY(p2); SKIP_EMPTY(p2);
if (*p2 == ']') { if (*p2 == ']') {
p = p2 + 1; p = p2 + 1;

View File

@@ -837,8 +837,7 @@ public:
/** /**
* @param json The JSON string which got sent. * @param json The JSON string which got sent.
*/ */
ScriptEventAdminPort(const char *json); ScriptEventAdminPort(const std::string &json);
~ScriptEventAdminPort();
/** /**
* Convert an ScriptEvent to the real instance. * Convert an ScriptEvent to the real instance.
@@ -853,28 +852,28 @@ public:
SQInteger GetObject(HSQUIRRELVM vm); SQInteger GetObject(HSQUIRRELVM vm);
private: private:
char *json; ///< The JSON string. std::string json; ///< The JSON string.
/** /**
* Read a table from a JSON string. * Read a table from a JSON string.
* @param vm The VM used. * @param vm The VM used.
* @param p The (part of the) JSON string reading. * @param p The (part of the) JSON string reading.
*/ */
char *ReadTable(HSQUIRRELVM vm, char *p); const char *ReadTable(HSQUIRRELVM vm, const char *p);
/** /**
* Read a value from a JSON string. * Read a value from a JSON string.
* @param vm The VM used. * @param vm The VM used.
* @param p The (part of the) JSON string reading. * @param p The (part of the) JSON string reading.
*/ */
char *ReadValue(HSQUIRRELVM vm, char *p); const char *ReadValue(HSQUIRRELVM vm, const char *p);
/** /**
* Read a string from a JSON string. * Read a string from a JSON string.
* @param vm The VM used. * @param vm The VM used.
* @param p The (part of the) JSON string reading. * @param p The (part of the) JSON string reading.
*/ */
char *ReadString(HSQUIRRELVM vm, char *p); const char *ReadString(HSQUIRRELVM vm, const char *p);
}; };
/** /**

View File

@@ -26,9 +26,7 @@
if (!IsValid(setting)) return -1; if (!IsValid(setting)) return -1;
const SettingDesc *sd = GetSettingFromName(setting); const SettingDesc *sd = GetSettingFromName(setting);
return sd->AsIntSetting()->Read(&_settings_game);
void *ptr = GetVariableAddress(&_settings_game, &sd->save);
return (int32)ReadValue(ptr, sd->save.conv);
} }
/* static */ bool ScriptGameSettings::SetValue(const char *setting, int value) /* static */ bool ScriptGameSettings::SetValue(const char *setting, int value)
@@ -39,7 +37,7 @@
if ((sd->save.conv & SLF_NO_NETWORK_SYNC) != 0) return false; if ((sd->save.conv & SLF_NO_NETWORK_SYNC) != 0) return false;
return ScriptObject::DoCommand(0, GetSettingIndex(sd), value, CMD_CHANGE_SETTING); return ScriptObject::DoCommand(0, 0, value, CMD_CHANGE_SETTING, sd->name);
} }
/* static */ bool ScriptGameSettings::IsDisabledVehicleType(ScriptVehicle::VehicleType vehicle_type) /* static */ bool ScriptGameSettings::IsDisabledVehicleType(ScriptVehicle::VehicleType vehicle_type)

View File

@@ -118,7 +118,7 @@
{ {
if (HasWagonRemoval() == enable_removal) return true; if (HasWagonRemoval() == enable_removal) return true;
return ScriptObject::DoCommand(0, ::GetCompanySettingIndex("company.renew_keep_length"), enable_removal ? 1 : 0, CMD_CHANGE_COMPANY_SETTING); return ScriptObject::DoCommand(0, 0, enable_removal ? 1 : 0, CMD_CHANGE_COMPANY_SETTING, "company.renew_keep_length");
} }
/* static */ bool ScriptGroup::HasWagonRemoval() /* static */ bool ScriptGroup::HasWagonRemoval()

View File

@@ -287,7 +287,7 @@ ScriptObject::ActiveInstance::~ActiveInstance()
{ {
char buffer[64]; char buffer[64];
::GetString(buffer, string, lastof(buffer)); ::GetString(buffer, string, lastof(buffer));
::str_validate(buffer, lastof(buffer), SVS_NONE); ::StrMakeValidInPlace(buffer, lastof(buffer), SVS_NONE);
return ::stredup(buffer); return ::stredup(buffer);
} }
@@ -316,7 +316,7 @@ ScriptObject::ActiveInstance::~ActiveInstance()
if (binary_length == 0 && !StrEmpty(text) && (GetCommandFlags(cmd) & CMD_STR_CTRL) == 0) { if (binary_length == 0 && !StrEmpty(text) && (GetCommandFlags(cmd) & CMD_STR_CTRL) == 0) {
/* The string must be valid, i.e. not contain special codes. Since some /* The string must be valid, i.e. not contain special codes. Since some
* can be made with GSText, make sure the control codes are removed. */ * can be made with GSText, make sure the control codes are removed. */
::str_validate(const_cast<char *>(text), text + strlen(text), SVS_NONE); ::StrMakeValidInPlace(const_cast<char *>(text), text + strlen(text), SVS_NONE);
} }
/* Set the default callback to return a true/false result of the DoCommand */ /* Set the default callback to return a true/false result of the DoCommand */

View File

@@ -82,7 +82,7 @@ SQInteger ScriptText::_SetParam(int parameter, HSQUIRRELVM vm)
sq_getstring(vm, -1, &value); sq_getstring(vm, -1, &value);
this->params[parameter] = stredup(value); this->params[parameter] = stredup(value);
ValidateString(this->params[parameter]); StrMakeValidInPlace(this->params[parameter]);
break; break;
} }
@@ -157,7 +157,7 @@ SQInteger ScriptText::_set(HSQUIRRELVM vm)
if (sq_gettype(vm, 2) == OT_STRING) { if (sq_gettype(vm, 2) == OT_STRING) {
const SQChar *key_string; const SQChar *key_string;
sq_getstring(vm, 2, &key_string); sq_getstring(vm, 2, &key_string);
ValidateString(key_string); StrMakeValidInPlace(const_cast<char *>(key_string));
if (strncmp(key_string, "param_", 6) != 0 || strlen(key_string) > 8) return SQ_ERROR; if (strncmp(key_string, "param_", 6) != 0 || strlen(key_string) > 8) return SQ_ERROR;
k = atoi(key_string + 6); k = atoi(key_string + 6);

View File

@@ -122,14 +122,14 @@ SQInteger ScriptInfo::AddSetting(HSQUIRRELVM vm)
while (SQ_SUCCEEDED(sq_next(vm, -2))) { while (SQ_SUCCEEDED(sq_next(vm, -2))) {
const SQChar *key; const SQChar *key;
if (SQ_FAILED(sq_getstring(vm, -2, &key))) return SQ_ERROR; if (SQ_FAILED(sq_getstring(vm, -2, &key))) return SQ_ERROR;
ValidateString(key); StrMakeValidInPlace(const_cast<char *>(key));
if (strcmp(key, "name") == 0) { if (strcmp(key, "name") == 0) {
const SQChar *sqvalue; const SQChar *sqvalue;
if (SQ_FAILED(sq_getstring(vm, -1, &sqvalue))) return SQ_ERROR; if (SQ_FAILED(sq_getstring(vm, -1, &sqvalue))) return SQ_ERROR;
char *name = stredup(sqvalue); char *name = stredup(sqvalue);
char *s; char *s;
ValidateString(name); StrMakeValidInPlace(name);
/* Don't allow '=' and ',' in configure setting names, as we need those /* Don't allow '=' and ',' in configure setting names, as we need those
* 2 chars to nicely store the settings as a string. */ * 2 chars to nicely store the settings as a string. */
@@ -141,7 +141,7 @@ SQInteger ScriptInfo::AddSetting(HSQUIRRELVM vm)
const SQChar *sqdescription; const SQChar *sqdescription;
if (SQ_FAILED(sq_getstring(vm, -1, &sqdescription))) return SQ_ERROR; if (SQ_FAILED(sq_getstring(vm, -1, &sqdescription))) return SQ_ERROR;
config.description = stredup(sqdescription); config.description = stredup(sqdescription);
ValidateString(config.description); StrMakeValidInPlace(const_cast<char *>(config.description));
items |= 0x002; items |= 0x002;
} else if (strcmp(key, "min_value") == 0) { } else if (strcmp(key, "min_value") == 0) {
SQInteger res; SQInteger res;
@@ -226,7 +226,7 @@ SQInteger ScriptInfo::AddLabels(HSQUIRRELVM vm)
{ {
const SQChar *setting_name; const SQChar *setting_name;
if (SQ_FAILED(sq_getstring(vm, -2, &setting_name))) return SQ_ERROR; if (SQ_FAILED(sq_getstring(vm, -2, &setting_name))) return SQ_ERROR;
ValidateString(setting_name); StrMakeValidInPlace(const_cast<char *>(setting_name));
ScriptConfigItem *config = nullptr; ScriptConfigItem *config = nullptr;
for (auto &item : this->config_list) { for (auto &item : this->config_list) {
@@ -253,7 +253,7 @@ SQInteger ScriptInfo::AddLabels(HSQUIRRELVM vm)
/* Because squirrel doesn't support identifiers starting with a digit, /* Because squirrel doesn't support identifiers starting with a digit,
* we skip the first character. */ * we skip the first character. */
int key = atoi(key_string + 1); int key = atoi(key_string + 1);
ValidateString(label); StrMakeValidInPlace(const_cast<char *>(label));
/* !Contains() prevents stredup from leaking. */ /* !Contains() prevents stredup from leaking. */
if (!config->labels->Contains(key)) config->labels->Insert(key, stredup(label)); if (!config->labels->Contains(key)) config->labels->Insert(key, stredup(label));

View File

@@ -370,7 +370,6 @@ static byte _script_sl_byte; ///< Used as source/target by the script saveload c
/** SaveLoad array that saves/loads exactly one byte. */ /** SaveLoad array that saves/loads exactly one byte. */
static const SaveLoad _script_byte[] = { static const SaveLoad _script_byte[] = {
SLEG_VAR(_script_sl_byte, SLE_UINT8), SLEG_VAR(_script_sl_byte, SLE_UINT8),
SLE_END()
}; };
/* static */ bool ScriptInstance::SaveObject(HSQUIRRELVM vm, SQInteger index, int max_depth, bool test) /* static */ bool ScriptInstance::SaveObject(HSQUIRRELVM vm, SQInteger index, int max_depth, bool test)

View File

@@ -465,7 +465,7 @@ bool Squirrel::CallStringMethodStrdup(HSQOBJECT instance, const char *method_nam
if (!this->CallMethod(instance, method_name, &ret, suspend)) return false; if (!this->CallMethod(instance, method_name, &ret, suspend)) return false;
if (ret._type != OT_STRING) return false; if (ret._type != OT_STRING) return false;
*res = stredup(ObjectToString(&ret)); *res = stredup(ObjectToString(&ret));
ValidateString(*res); StrMakeValidInPlace(const_cast<char *>(*res));
return true; return true;
} }

View File

@@ -116,7 +116,7 @@ namespace SQConvert {
char *tmp_str = stredup(tmp); char *tmp_str = stredup(tmp);
sq_poptop(vm); sq_poptop(vm);
ptr->push_back((void *)tmp_str); ptr->push_back((void *)tmp_str);
str_validate(tmp_str, tmp_str + strlen(tmp_str)); StrMakeValidInPlace(tmp_str);
return tmp_str; return tmp_str;
} }

View File

@@ -22,6 +22,7 @@
*/ */
#include "stdafx.h" #include "stdafx.h"
#include <array>
#include <limits> #include <limits>
#include "currency.h" #include "currency.h"
#include "screenshot.h" #include "screenshot.h"
@@ -119,17 +120,6 @@ const SettingDesc *GetSettingDescription(uint index)
return _settings.begin()[index].get(); return _settings.begin()[index].get();
} }
/**
* Get the setting at the given index into the company settings table.
* @param index The index to look for.
* @return The setting at the given index, or nullptr when the index is invalid.
*/
static const SettingDesc *GetCompanySettingDescription(uint index)
{
if (index >= _company_settings.size()) return nullptr;
return _company_settings.begin()[index].get();
}
/** /**
* Groups in openttd.cfg that are actually lists. * Groups in openttd.cfg that are actually lists.
*/ */
@@ -295,7 +285,7 @@ static bool LoadIntList(const char *str, void *array, int nelems, VarType type)
*/ */
void ListSettingDesc::FormatValue(char *buf, const char *last, const void *object) const void ListSettingDesc::FormatValue(char *buf, const char *last, const void *object) const
{ {
const byte *p = static_cast<const byte *>(GetVariableAddress(object, &this->save)); const byte *p = static_cast<const byte *>(GetVariableAddress(object, this->save));
int i, v = 0; int i, v = 0;
for (i = 0; i != this->save.length; i++) { for (i = 0; i != this->save.length; i++) {
@@ -497,7 +487,7 @@ void IntSettingDesc::MakeValueValid(int32 &val) const
*/ */
void IntSettingDesc::Write(const void *object, int32 val) const void IntSettingDesc::Write(const void *object, int32 val) const
{ {
void *ptr = GetVariableAddress(object, &this->save); void *ptr = GetVariableAddress(object, this->save);
WriteValue(ptr, this->save.conv, (int64)val); WriteValue(ptr, this->save.conv, (int64)val);
} }
@@ -508,7 +498,7 @@ void IntSettingDesc::Write(const void *object, int32 val) const
*/ */
int32 IntSettingDesc::Read(const void *object) const int32 IntSettingDesc::Read(const void *object) const
{ {
void *ptr = GetVariableAddress(object, &this->save); void *ptr = GetVariableAddress(object, this->save);
return (int32)ReadValue(ptr, this->save.conv); return (int32)ReadValue(ptr, this->save.conv);
} }
@@ -527,7 +517,7 @@ void StringSettingDesc::MakeValueValid(std::string &str) const
* includes the '\0' termination for network transfer purposes. * includes the '\0' termination for network transfer purposes.
* Also ensure the string is valid after chopping of some bytes. */ * Also ensure the string is valid after chopping of some bytes. */
std::string stdstr(str, this->max_length - 1); std::string stdstr(str, this->max_length - 1);
str.assign(str_validate(stdstr, SVS_NONE)); str.assign(StrMakeValid(stdstr, SVS_NONE));
} }
/** /**
@@ -537,7 +527,7 @@ void StringSettingDesc::MakeValueValid(std::string &str) const
*/ */
void StringSettingDesc::Write(const void *object, const std::string &str) const void StringSettingDesc::Write(const void *object, const std::string &str) const
{ {
reinterpret_cast<std::string *>(GetVariableAddress(object, &this->save))->assign(str); reinterpret_cast<std::string *>(GetVariableAddress(object, this->save))->assign(str);
} }
/** /**
@@ -547,7 +537,7 @@ void StringSettingDesc::Write(const void *object, const std::string &str) const
*/ */
const std::string &StringSettingDesc::Read(const void *object) const const std::string &StringSettingDesc::Read(const void *object) const
{ {
return *reinterpret_cast<std::string *>(GetVariableAddress(object, &this->save)); return *reinterpret_cast<std::string *>(GetVariableAddress(object, this->save));
} }
/** /**
@@ -615,7 +605,7 @@ void StringSettingDesc::ParseValue(const IniItem *item, void *object) const
void ListSettingDesc::ParseValue(const IniItem *item, void *object) const void ListSettingDesc::ParseValue(const IniItem *item, void *object) const
{ {
const char *str = (item == nullptr) ? this->def : item->value.has_value() ? item->value->c_str() : nullptr; const char *str = (item == nullptr) ? this->def : item->value.has_value() ? item->value->c_str() : nullptr;
void *ptr = GetVariableAddress(object, &this->save); void *ptr = GetVariableAddress(object, this->save);
if (!LoadIntList(str, ptr, this->save.length, GetVarMemType(this->save.conv))) { if (!LoadIntList(str, ptr, this->save.length, GetVarMemType(this->save.conv))) {
ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_ARRAY); ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_ARRAY);
msg.SetDParamStr(0, this->name); msg.SetDParamStr(0, this->name);
@@ -1703,7 +1693,9 @@ static void PrepareOldDiffCustom()
*/ */
static void HandleOldDiffCustom(bool savegame) static void HandleOldDiffCustom(bool savegame)
{ {
uint options_to_load = GAME_DIFFICULTY_NUM - ((savegame && IsSavegameVersionBefore(SLV_4)) ? 1 : 0); /* Savegames before v4 didn't have "town_council_tolerance" in savegame yet. */
bool has_no_town_council_tolerance = savegame && IsSavegameVersionBefore(SLV_4);
uint options_to_load = GAME_DIFFICULTY_NUM - (has_no_town_council_tolerance ? 1 : 0);
if (!savegame) { if (!savegame) {
/* If we did read to old_diff_custom, then at least one value must be non 0. */ /* If we did read to old_diff_custom, then at least one value must be non 0. */
@@ -1715,11 +1707,21 @@ static void HandleOldDiffCustom(bool savegame)
if (!old_diff_custom_used) return; if (!old_diff_custom_used) return;
} }
for (uint i = 0; i < options_to_load; i++) { /* Iterate over all the old difficulty settings, and convert the list-value to the new setting. */
const SettingDesc *sd = GetSettingDescription(i); uint i = 0;
/* Skip deprecated options */ for (const auto &name : _old_diff_settings) {
if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue; if (has_no_town_council_tolerance && name == "town_council_tolerance") continue;
int32 value = (int32)((i == 4 ? 1000 : 1) * _old_diff_custom[i]);
std::string fullname = "difficulty." + name;
const SettingDesc *sd = GetSettingFromName(fullname.c_str());
/* Some settings are no longer in use; skip reading those. */
if (sd == nullptr) {
i++;
continue;
}
int32 value = (int32)((name == "max_loan" ? 1000 : 1) * _old_diff_custom[i++]);
sd->AsIntSetting()->MakeValueValidAndWrite(savegame ? &_settings_game : &_settings_newgame, value); sd->AsIntSetting()->MakeValueValidAndWrite(savegame ? &_settings_game : &_settings_newgame, value);
} }
} }
@@ -2177,20 +2179,75 @@ void IntSettingDesc::ChangeValue(const void *object, int32 newval) const
if (_save_config) SaveToConfig(); if (_save_config) SaveToConfig();
} }
/**
* Given a name of setting, return a setting description from the table.
* @param name Name of the setting to return a setting description of.
* @param settings Table to look in for the setting.
* @return Pointer to the setting description of setting \a name if it can be found,
* \c nullptr indicates failure to obtain the description.
*/
static const SettingDesc *GetSettingFromName(const char *name, const SettingTable &settings)
{
/* First check all full names */
for (auto &sd : settings) {
if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue;
if (strcmp(sd->name, name) == 0) return sd.get();
}
/* Then check the shortcut variant of the name. */
for (auto &sd : settings) {
if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue;
const char *short_name = strchr(sd->name, '.');
if (short_name != nullptr) {
short_name++;
if (strcmp(short_name, name) == 0) return sd.get();
}
}
return nullptr;
}
/**
* Given a name of setting, return a company setting description of it.
* @param name Name of the company setting to return a setting description of.
* @return Pointer to the setting description of setting \a name if it can be found,
* \c nullptr indicates failure to obtain the description.
*/
static const SettingDesc *GetCompanySettingFromName(const char *name)
{
if (strncmp(name, "company.", 8) == 0) name += 8;
return GetSettingFromName(name, _company_settings);
}
/**
* Given a name of any setting, return any setting description of it.
* @param name Name of the setting to return a setting description of.
* @return Pointer to the setting description of setting \a name if it can be found,
* \c nullptr indicates failure to obtain the description.
*/
const SettingDesc *GetSettingFromName(const char *name)
{
auto sd = GetSettingFromName(name, _settings);
if (sd != nullptr) return sd;
return GetCompanySettingFromName(name);
}
/** /**
* Network-safe changing of settings (server-only). * Network-safe changing of settings (server-only).
* @param tile unused * @param tile unused
* @param flags operation to perform * @param flags operation to perform
* @param p1 the index of the setting in the SettingDesc array which identifies it * @param p1 unused
* @param p2 the new value for the setting * @param p2 the new value for the setting
* The new value is properly clamped to its minimum/maximum when setting * The new value is properly clamped to its minimum/maximum when setting
* @param text unused * @param text the name of the setting to change
* @return the cost of this operation or an error * @return the cost of this operation or an error
* @see _settings * @see _settings
*/ */
CommandCost CmdChangeSetting(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) CommandCost CmdChangeSetting(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{ {
const SettingDesc *sd = GetSettingDescription(p1); if (StrEmpty(text)) return CMD_ERROR;
const SettingDesc *sd = GetSettingFromName(text);
if (sd == nullptr) return CMD_ERROR; if (sd == nullptr) return CMD_ERROR;
if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) return CMD_ERROR; if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) return CMD_ERROR;
@@ -2219,15 +2276,17 @@ const char *GetSettingNameByIndex(uint32 idx)
* Change one of the per-company settings. * Change one of the per-company settings.
* @param tile unused * @param tile unused
* @param flags operation to perform * @param flags operation to perform
* @param p1 the index of the setting in the _company_settings array which identifies it * @param p1 unused
* @param p2 the new value for the setting * @param p2 the new value for the setting
* The new value is properly clamped to its minimum/maximum when setting * The new value is properly clamped to its minimum/maximum when setting
* @param text unused * @param text the name of the company setting to change
* @return the cost of this operation or an error * @return the cost of this operation or an error
*/ */
CommandCost CmdChangeCompanySetting(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) CommandCost CmdChangeCompanySetting(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{ {
const SettingDesc *sd = GetCompanySettingDescription(p1); if (StrEmpty(text)) return CMD_ERROR;
const SettingDesc *sd = GetCompanySettingFromName(text);
if (sd == nullptr) return CMD_ERROR; if (sd == nullptr) return CMD_ERROR;
if (!sd->IsIntSetting()) return CMD_ERROR; if (!sd->IsIntSetting()) return CMD_ERROR;
@@ -2244,45 +2303,7 @@ const char *GetCompanySettingNameByIndex(uint32 idx)
{ {
if (idx >= _company_settings.size()) return nullptr; if (idx >= _company_settings.size()) return nullptr;
return GetCompanySettingDescription(idx)->name; return _company_settings.begin()[idx]->name;
}
/**
* Get the index of the given setting in the setting table.
* @param settings The settings to look through.
* @param setting The setting to look for.
* @return The index, or UINT32_MAX when it has not been found.
*/
static uint GetSettingIndex(const SettingTable &settings, const SettingDesc *setting)
{
uint index = 0;
for (auto &sd : settings) {
if (sd.get() == setting) return index;
index++;
}
return UINT32_MAX;
}
/**
* Get the index of the setting with this description.
* @param sd the setting to get the index for.
* @return the index of the setting to be used for CMD_CHANGE_SETTING.
*/
uint GetSettingIndex(const SettingDesc *sd)
{
assert(sd != nullptr && (sd->flags & SGF_PER_COMPANY) == 0);
return GetSettingIndex(_settings, sd);
}
/**
* Get the index of the company setting with this description.
* @param sd the setting to get the index for.
* @return the index of the setting to be used for CMD_CHANGE_COMPANY_SETTING.
*/
static uint GetCompanySettingIndex(const SettingDesc *sd)
{
assert(sd != nullptr && (sd->flags & SGF_PER_COMPANY) != 0);
return GetSettingIndex(_company_settings, sd);
} }
/** /**
@@ -2297,7 +2318,7 @@ bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame)
const IntSettingDesc *setting = sd->AsIntSetting(); const IntSettingDesc *setting = sd->AsIntSetting();
if ((setting->flags & SGF_PER_COMPANY) != 0) { if ((setting->flags & SGF_PER_COMPANY) != 0) {
if (Company::IsValidID(_local_company) && _game_mode != GM_MENU) { if (Company::IsValidID(_local_company) && _game_mode != GM_MENU) {
return DoCommandP(0, GetCompanySettingIndex(setting), value, CMD_CHANGE_COMPANY_SETTING); return DoCommandP(0, 0, value, CMD_CHANGE_COMPANY_SETTING, nullptr, setting->name);
} else if (setting->flags & SGF_NO_NEWGAME) { } else if (setting->flags & SGF_NO_NEWGAME) {
return false; return false;
} }
@@ -2327,7 +2348,7 @@ bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame)
/* send non-company-based settings over the network */ /* send non-company-based settings over the network */
if (!_networking || (_networking && (_network_server || _network_settings_access))) { if (!_networking || (_networking && (_network_server || _network_settings_access))) {
return DoCommandP(0, GetSettingIndex(setting), value, CMD_CHANGE_SETTING); return DoCommandP(0, 0, value, CMD_CHANGE_SETTING, nullptr, setting->name);
} }
return false; return false;
} }
@@ -2353,25 +2374,13 @@ void SyncCompanySettings()
{ {
const void *old_object = &Company::Get(_current_company)->settings; const void *old_object = &Company::Get(_current_company)->settings;
const void *new_object = &_settings_client.company; const void *new_object = &_settings_client.company;
uint i = 0;
for (auto &sd : _company_settings) { for (auto &sd : _company_settings) {
uint32 old_value = (uint32)sd->AsIntSetting()->Read(new_object); uint32 old_value = (uint32)sd->AsIntSetting()->Read(new_object);
uint32 new_value = (uint32)sd->AsIntSetting()->Read(old_object); uint32 new_value = (uint32)sd->AsIntSetting()->Read(old_object);
if (old_value != new_value) NetworkSendCommand(0, i, new_value, 0, CMD_CHANGE_COMPANY_SETTING, nullptr, nullptr, _local_company, 0); if (old_value != new_value) NetworkSendCommand(0, 0, new_value, 0, CMD_CHANGE_COMPANY_SETTING, nullptr, sd->name, _local_company, 0);
i++;
} }
} }
/**
* Get the index in the _company_settings array of a setting
* @param name The name of the setting
* @return The index in the _company_settings array
*/
uint GetCompanySettingIndex(const char *name)
{
return GetCompanySettingIndex(GetSettingFromName(name));
}
/** /**
* Set a setting value with a string. * Set a setting value with a string.
* @param sd the setting to change. * @param sd the setting to change.
@@ -2419,42 +2428,11 @@ uint GetSettingIndexByFullName(const char *name)
return UINT32_MAX; return UINT32_MAX;
} }
/** const SettingDesc *GetSettingFromFullName(const char *name)
* Given a name of setting, return a setting description of it.
* @param name Name of the setting to return a setting description of
* @param i Pointer to an integer that will contain the index of the setting after the call, if it is successful.
* @param ignore_version Return a setting even if it not valid for the current savegame version
* @return Pointer to the setting description of setting \a name if it can be found,
* \c nullptr indicates failure to obtain the description
*/
const SettingDesc *GetSettingFromName(const char *name, bool ignore_version)
{ {
/* First check all full names */
for (auto &sd : _settings) { for (auto &sd : _settings) {
if (sd->name == nullptr) continue; if (sd->name != nullptr && strcmp(sd->name, name) == 0) return sd.get();
if (!ignore_version && !SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue;
if (strcmp(sd->name, name) == 0) return sd.get();
} }
/* Then check the shortcut variant of the name. */
for (auto &sd : _settings) {
if (sd->name == nullptr) continue;
if (!ignore_version && !SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue;
const char *short_name = strchr(sd->name, '.');
if (short_name != nullptr) {
short_name++;
if (strcmp(short_name, name) == 0) return sd.get();
}
}
if (strncmp(name, "company.", 8) == 0) name += 8;
/* And finally the company-based settings */
for (auto &sd : _company_settings) {
if (sd->name == nullptr) continue;
if (!ignore_version && !SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue;
if (strcmp(sd->name, name) == 0) return sd.get();
}
return nullptr; return nullptr;
} }
@@ -2581,7 +2559,7 @@ void IConsoleListSettings(const char *prefilter)
*/ */
static void LoadSettingsXref(const SettingDesc *osd, void *object) { static void LoadSettingsXref(const SettingDesc *osd, void *object) {
DEBUG(sl, 3, "PATS chunk: Loading xref setting: '%s'", osd->xref.target); DEBUG(sl, 3, "PATS chunk: Loading xref setting: '%s'", osd->xref.target);
const SettingDesc *setting_xref = GetSettingFromName(osd->xref.target, true); const SettingDesc *setting_xref = GetSettingFromFullName(osd->xref.target);
assert(setting_xref != nullptr); assert(setting_xref != nullptr);
// Generate a new SaveLoad from the xref target using the version params from the source // Generate a new SaveLoad from the xref target using the version params from the source
@@ -2589,9 +2567,9 @@ static void LoadSettingsXref(const SettingDesc *osd, void *object) {
sld.version_from = osd->save.version_from; sld.version_from = osd->save.version_from;
sld.version_to = osd->save.version_to; sld.version_to = osd->save.version_to;
sld.ext_feature_test = osd->save.ext_feature_test; sld.ext_feature_test = osd->save.ext_feature_test;
void *ptr = GetVariableAddress(object, &sld); void *ptr = GetVariableAddress(object, sld);
if (!SlObjectMember(ptr, &sld)) return; if (!SlObjectMember(ptr, sld)) return;
int64 val = ReadValue(ptr, sld.conv); int64 val = ReadValue(ptr, sld.conv);
if (osd->xref.conv != nullptr) val = osd->xref.conv(val); if (osd->xref.conv != nullptr) val = osd->xref.conv(val);
if (setting_xref->IsIntSetting()) { if (setting_xref->IsIntSetting()) {
@@ -2612,14 +2590,14 @@ static void LoadSettings(const SettingTable &settings, void *object)
for (auto &osd : settings) { for (auto &osd : settings) {
if (osd->patx_name != nullptr) continue; if (osd->patx_name != nullptr) continue;
const SaveLoad *sld = &osd->save; const SaveLoad &sld = osd->save;
if (osd->xref.target != nullptr) { if (osd->xref.target != nullptr) {
if (sld->ext_feature_test.IsFeaturePresent(_sl_version, sld->version_from, sld->version_to)) LoadSettingsXref(osd.get(), object); if (sld.ext_feature_test.IsFeaturePresent(_sl_version, sld.version_from, sld.version_to)) LoadSettingsXref(osd.get(), object);
continue; continue;
} }
void *ptr = GetVariableAddress(object, sld); void *ptr = GetVariableAddress(object, sld);
if (!SlObjectMember(ptr, &osd->save)) continue; if (!SlObjectMember(ptr, osd->save)) continue;
if (osd->IsIntSetting()) { if (osd->IsIntSetting()) {
const IntSettingDesc *int_setting = osd->AsIntSetting(); const IntSettingDesc *int_setting = osd->AsIntSetting();
int_setting->MakeValueValidAndWrite(object, int_setting->Read(object)); int_setting->MakeValueValidAndWrite(object, int_setting->Read(object));
@@ -2641,14 +2619,14 @@ static void SaveSettings(const SettingTable &settings, void *object)
for (auto &sd : settings) { for (auto &sd : settings) {
if (sd->patx_name != nullptr) continue; if (sd->patx_name != nullptr) continue;
if (sd->xref.target != nullptr) continue; if (sd->xref.target != nullptr) continue;
length += SlCalcObjMemberLength(object, &sd->save); length += SlCalcObjMemberLength(object, sd->save);
} }
SlSetLength(length); SlSetLength(length);
for (auto &sd : settings) { for (auto &sd : settings) {
if (sd->patx_name != nullptr) continue; if (sd->patx_name != nullptr) continue;
void *ptr = GetVariableAddress(object, &sd->save); void *ptr = GetVariableAddress(object, sd->save);
SlObjectMember(ptr, &sd->save); SlObjectMember(ptr, sd->save);
} }
} }
@@ -2708,7 +2686,6 @@ static const SaveLoad _settings_ext_load_desc[] = {
SLE_VAR(SettingsExtLoad, flags, SLE_UINT32), SLE_VAR(SettingsExtLoad, flags, SLE_UINT32),
SLE_STR(SettingsExtLoad, name, SLE_STRB, 256), SLE_STR(SettingsExtLoad, name, SLE_STRB, 256),
SLE_VAR(SettingsExtLoad, setting_length, SLE_UINT32), SLE_VAR(SettingsExtLoad, setting_length, SLE_UINT32),
SLE_END()
}; };
/** /**
@@ -2724,7 +2701,6 @@ static const SaveLoad _settings_ext_save_desc[] = {
SLE_VAR(SettingsExtSave, flags, SLE_UINT32), SLE_VAR(SettingsExtSave, flags, SLE_UINT32),
SLE_STR(SettingsExtSave, name, SLE_STR, 0), SLE_STR(SettingsExtSave, name, SLE_STR, 0),
SLE_VAR(SettingsExtSave, setting_length, SLE_UINT32), SLE_VAR(SettingsExtSave, setting_length, SLE_UINT32),
SLE_END()
}; };
/** /**
@@ -2762,7 +2738,7 @@ static void LoadSettingsPatx(const SettingTable &settings, void *object)
assert(iter != _sorted_patx_settings.end()); assert(iter != _sorted_patx_settings.end());
// found setting // found setting
const SettingDesc *setting = (*iter); const SettingDesc *setting = (*iter);
const SaveLoad *sld = &(setting->save); const SaveLoad &sld = setting->save;
size_t read = SlGetBytesRead(); size_t read = SlGetBytesRead();
void *ptr = GetVariableAddress(object, sld); void *ptr = GetVariableAddress(object, sld);
SlObjectMember(ptr, sld); SlObjectMember(ptr, sld);
@@ -2799,7 +2775,7 @@ static void SaveSettingsPatx(const SettingTable &settings, void *object)
size_t length = 8; size_t length = 8;
for (auto &sd : settings) { for (auto &sd : settings) {
if (sd->patx_name == nullptr) continue; if (sd->patx_name == nullptr) continue;
uint32 setting_length = (uint32)SlCalcObjMemberLength(object, &sd->save); uint32 setting_length = (uint32)SlCalcObjMemberLength(object, sd->save);
if (!setting_length) continue; if (!setting_length) continue;
current_setting.name = sd->patx_name; current_setting.name = sd->patx_name;
@@ -2825,8 +2801,8 @@ static void SaveSettingsPatx(const SettingTable &settings, void *object)
current_setting.name = desc->patx_name; current_setting.name = desc->patx_name;
current_setting.setting_length = settings_to_add[i].setting_length; current_setting.setting_length = settings_to_add[i].setting_length;
SlObject(&current_setting, _settings_ext_save_desc); SlObject(&current_setting, _settings_ext_save_desc);
void *ptr = GetVariableAddress(object, &desc->save); void *ptr = GetVariableAddress(object, desc->save);
SlObjectMember(ptr, &desc->save); SlObjectMember(ptr, desc->save);
} }
} }
@@ -2903,7 +2879,7 @@ void LoadSettingsPlyx(bool skip)
if (setting != nullptr) { if (setting != nullptr) {
// found setting // found setting
const SaveLoad *sld = &(setting->save); const SaveLoad &sld = setting->save;
size_t read = SlGetBytesRead(); size_t read = SlGetBytesRead();
void *ptr = GetVariableAddress(&(c->settings), sld); void *ptr = GetVariableAddress(&(c->settings), sld);
SlObjectMember(ptr, sld); SlObjectMember(ptr, sld);
@@ -2933,7 +2909,6 @@ void SaveSettingsPlyx()
SLE_VAR(SettingsExtSave, flags, SLE_UINT32), SLE_VAR(SettingsExtSave, flags, SLE_UINT32),
SLE_STR(SettingsExtSave, name, SLE_STR, 0), SLE_STR(SettingsExtSave, name, SLE_STR, 0),
SLE_VAR(SettingsExtSave, setting_length, SLE_UINT32), SLE_VAR(SettingsExtSave, setting_length, SLE_UINT32),
SLE_END()
}; };
std::vector<uint32> company_setting_counts; std::vector<uint32> company_setting_counts;
@@ -2947,7 +2922,7 @@ void SaveSettingsPlyx()
uint32 setting_count = 0; uint32 setting_count = 0;
for (auto &sd : _company_settings) { for (auto &sd : _company_settings) {
if (sd->patx_name == nullptr) continue; if (sd->patx_name == nullptr) continue;
uint32 setting_length = (uint32)SlCalcObjMemberLength(&(c->settings), &sd->save); uint32 setting_length = (uint32)SlCalcObjMemberLength(&(c->settings), sd->save);
if (!setting_length) continue; if (!setting_length) continue;
current_setting.name = sd->patx_name; current_setting.name = sd->patx_name;
@@ -2978,15 +2953,15 @@ void SaveSettingsPlyx()
for (auto &sd : _company_settings) { for (auto &sd : _company_settings) {
if (sd->patx_name == nullptr) continue; if (sd->patx_name == nullptr) continue;
uint32 setting_length = (uint32)SlCalcObjMemberLength(&(c->settings), &sd->save); uint32 setting_length = (uint32)SlCalcObjMemberLength(&(c->settings), sd->save);
if (!setting_length) continue; if (!setting_length) continue;
current_setting.flags = 0; current_setting.flags = 0;
current_setting.name = sd->patx_name; current_setting.name = sd->patx_name;
current_setting.setting_length = setting_length; current_setting.setting_length = setting_length;
SlObject(&current_setting, _settings_plyx_desc); SlObject(&current_setting, _settings_plyx_desc);
void *ptr = GetVariableAddress(&(c->settings), &sd->save); void *ptr = GetVariableAddress(&(c->settings), sd->save);
SlObjectMember(ptr, &sd->save); SlObjectMember(ptr, sd->save);
} }
} }
} }

View File

@@ -32,7 +32,6 @@ struct GRFConfig *LoadGRFPresetFromConfig(const char *config_name);
void SaveGRFPresetToConfig(const char *config_name, struct GRFConfig *config); void SaveGRFPresetToConfig(const char *config_name, struct GRFConfig *config);
void DeleteGRFPresetFromConfig(const char *config_name); void DeleteGRFPresetFromConfig(const char *config_name);
uint GetCompanySettingIndex(const char *name);
void SetDefaultCompanySettings(CompanyID cid); void SetDefaultCompanySettings(CompanyID cid);
void SyncCompanySettings(); void SyncCompanySettings();

View File

@@ -348,9 +348,8 @@ struct XrefSettingDesc : SettingDesc {
typedef std::initializer_list<std::unique_ptr<const SettingDesc>> SettingTable; typedef std::initializer_list<std::unique_ptr<const SettingDesc>> SettingTable;
const SettingDesc *GetSettingFromName(const char *name, bool ignore_version = false); const SettingDesc *GetSettingFromName(const char *name);
bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame = false); bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame = false);
bool SetSettingValue(const StringSettingDesc *sd, const std::string value, bool force_newgame = false); bool SetSettingValue(const StringSettingDesc *sd, const std::string value, bool force_newgame = false);
uint GetSettingIndex(const SettingDesc *sd);
#endif /* SETTINGS_INTERNAL_H */ #endif /* SETTINGS_INTERNAL_H */

View File

@@ -61,6 +61,9 @@ enum IndustryDensity {
/** Settings related to the difficulty of the game */ /** Settings related to the difficulty of the game */
struct DifficultySettings { struct DifficultySettings {
byte competitor_start_time; ///< Unused value, used to load old savegames.
byte competitor_intelligence; ///< Unused value, used to load old savegames.
byte max_no_competitors; ///< the number of competitors (AIs) byte max_no_competitors; ///< the number of competitors (AIs)
byte number_towns; ///< the amount of towns byte number_towns; ///< the amount of towns
byte industry_density; ///< The industry density. @see IndustryDensity byte industry_density; ///< The industry density. @see IndustryDensity

View File

@@ -216,7 +216,7 @@ const char *str_fix_scc_encoded(char *str, const char *last)
template <class T> template <class T>
static void str_validate(T &dst, const char *str, const char *last, StringValidationSettings settings) static void StrMakeValidInPlace(T &dst, const char *str, const char *last, StringValidationSettings settings)
{ {
/* Assume the ABSOLUTE WORST to be in str as it comes from the outside. */ /* Assume the ABSOLUTE WORST to be in str as it comes from the outside. */
@@ -276,51 +276,52 @@ static void str_validate(T &dst, const char *str, const char *last, StringValida
} }
/** /**
* Scans the string for valid characters and if it finds invalid ones, * Scans the string for invalid characters and replaces then with a
* replaces them with a question mark '?' (if not ignored) * question mark '?' (if not ignored).
* @param str the string to validate * @param str The string to validate.
* @param last the last valid character of str * @param last The last valid character of str.
* @param settings the settings for the string validation. * @param settings The settings for the string validation.
* @return pointer to terminating 0. * @return pointer to terminating 0.
*/ */
char *str_validate(char *str, const char *last, StringValidationSettings settings) char *StrMakeValidInPlace(char *str, const char *last, StringValidationSettings settings)
{ {
char *dst = str; char *dst = str;
str_validate(dst, str, last, settings); StrMakeValidInPlace(dst, str, last, settings);
*dst = '\0'; *dst = '\0';
return dst; return dst;
} }
/** /**
* Scans the string for valid characters and if it finds invalid ones, * Scans the string for invalid characters and replaces then with a
* replaces them with a question mark '?' (if not ignored) * question mark '?' (if not ignored).
* @param str the string to validate * Only use this function when you are sure the string ends with a '\0';
* @param settings the settings for the string validation. * otherwise use StrMakeValidInPlace(str, last, settings) variant.
* @param str The string (of which you are sure ends with '\0') to validate.
*/ */
std::string str_validate(const std::string &str, StringValidationSettings settings) void StrMakeValidInPlace(char *str, StringValidationSettings settings)
{
/* We know it is '\0' terminated. */
StrMakeValidInPlace(str, str + strlen(str), settings);
}
/**
* Scans the string for invalid characters and replaces then with a
* question mark '?' (if not ignored).
* @param str The string to validate.
* @param settings The settings for the string validation.
*/
std::string StrMakeValid(const std::string &str, StringValidationSettings settings)
{ {
auto buf = str.data(); auto buf = str.data();
auto last = buf + str.size(); auto last = buf + str.size();
std::ostringstream dst; std::ostringstream dst;
std::ostreambuf_iterator<char> dst_iter(dst); std::ostreambuf_iterator<char> dst_iter(dst);
str_validate(dst_iter, buf, last, settings); StrMakeValidInPlace(dst_iter, buf, last, settings);
return dst.str(); return dst.str();
} }
/**
* Scans the string for valid characters and if it finds invalid ones,
* replaces them with a question mark '?'.
* @param str the string to validate
*/
void ValidateString(const char *str)
{
/* We know it is '\0' terminated. */
str_validate(const_cast<char *>(str), str + strlen(str) + 1);
}
/** /**
* Checks whether the given string is valid, i.e. contains only * Checks whether the given string is valid, i.e. contains only
* valid (printable) characters and is properly terminated. * valid (printable) characters and is properly terminated.
@@ -496,6 +497,16 @@ size_t Utf8StringLength(const char *s)
return len; return len;
} }
/**
* Get the length of an UTF-8 encoded string in number of characters
* and thus not the number of bytes that the encoded string contains.
* @param s The string to get the length for.
* @return The length of the string in characters.
*/
size_t Utf8StringLength(const std::string &str)
{
return Utf8StringLength(str.c_str());
}
/** /**
* Convert a given ASCII string to lowercase. * Convert a given ASCII string to lowercase.

View File

@@ -42,9 +42,9 @@ char *str_vfmt(const char *str, va_list ap) WARN_FORMAT(1, 0);
std::string CDECL stdstr_fmt(const char *str, ...) WARN_FORMAT(1, 2); std::string CDECL stdstr_fmt(const char *str, ...) WARN_FORMAT(1, 2);
std::string stdstr_vfmt(const char *str, va_list va) WARN_FORMAT(1, 0); std::string stdstr_vfmt(const char *str, va_list va) WARN_FORMAT(1, 0);
char *str_validate(char *str, const char *last, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK) NOACCESS(2); char *StrMakeValidInPlace(char *str, const char *last, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK) NOACCESS(2);
[[nodiscard]] std::string str_validate(const std::string &str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK); [[nodiscard]] std::string StrMakeValid(const std::string &str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK);
void ValidateString(const char *str); void StrMakeValidInPlace(char *str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK);
const char *str_fix_scc_encoded(char *str, const char *last) NOACCESS(2); const char *str_fix_scc_encoded(char *str, const char *last) NOACCESS(2);
void str_strip_colours(char *str); void str_strip_colours(char *str);
@@ -171,6 +171,7 @@ static inline const char *Utf8PrevChar(const char *s)
} }
size_t Utf8StringLength(const char *s); size_t Utf8StringLength(const char *s);
size_t Utf8StringLength(const std::string &str);
/** /**
* Is the given character a lead surrogate code point? * Is the given character a lead surrogate code point?

View File

@@ -11,11 +11,11 @@
#include "string_func.h" #include "string_func.h"
#include <string> #include <string>
static inline void str_validate_inplace(std::string &str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK) static inline void StrMakeValidInPlace(std::string &str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK)
{ {
if (str.empty()) return; if (str.empty()) return;
char *buf = str.data(); char *buf = str.data();
str.resize(str_validate(buf, buf + str.size(), settings) - buf); str.resize(StrMakeValidInPlace(buf, buf + str.size(), settings) - buf);
} }
template <typename F> template <typename F>

View File

@@ -1,50 +1,4 @@
set(GENERATED_BINARY_DIR ${CMAKE_BINARY_DIR}/generated) add_subdirectory(settings)
set(TABLE_BINARY_DIR ${GENERATED_BINARY_DIR}/table)
set(TABLE_INI_SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/company_settings.ini
${CMAKE_CURRENT_SOURCE_DIR}/currency_settings.ini
${CMAKE_CURRENT_SOURCE_DIR}/gameopt_settings.ini
${CMAKE_CURRENT_SOURCE_DIR}/misc_settings.ini
${CMAKE_CURRENT_SOURCE_DIR}/settings.ini
${CMAKE_CURRENT_SOURCE_DIR}/win32_settings.ini
${CMAKE_CURRENT_SOURCE_DIR}/window_settings.ini
)
if (HOST_BINARY_DIR)
include(${HOST_BINARY_DIR}/settingsgen.cmake)
endif()
# Generate a command and target to create the settings table
add_custom_command_timestamp(OUTPUT ${TABLE_BINARY_DIR}/settings.h
COMMAND ${CMAKE_COMMAND} -E make_directory ${TABLE_BINARY_DIR}
COMMAND hostsettingsgen
-o ${TABLE_BINARY_DIR}/settings.h
-b ${CMAKE_SOURCE_DIR}/src/table/settings.h.preamble
-a ${CMAKE_SOURCE_DIR}/src/table/settings.h.postamble
${TABLE_INI_SOURCE_FILES}
DEPENDS hostsettingsgen ${TABLE_INI_SOURCE_FILES}
${CMAKE_SOURCE_DIR}/src/table/settings.h.preamble
${CMAKE_SOURCE_DIR}/src/table/settings.h.postamble
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating table/settings.h"
)
add_custom_target_timestamp(table_settings
DEPENDS
${TABLE_BINARY_DIR}/settings.h
)
add_library(settings
INTERFACE
)
target_include_directories(settings
INTERFACE
${GENERATED_BINARY_DIR}
)
add_dependencies(settings
table_settings
)
add_library(openttd::settings ALIAS settings)
add_files( add_files(
airport_defaults.h airport_defaults.h

Some files were not shown because too many files have changed in this diff Show More