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
pull/332/head
Jonathan G Rennison 3 years ago
commit 544da99102

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

@ -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);
} else {
// 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;
}

@ -198,7 +198,7 @@ bmno_full_transparency:
m_colour = r == 0 ? m_colour : cmap; \
m_colour = m != 0 ? m_colour : srcm; \
}
#ifdef _SQ64
#ifdef POINTER_IS_64BIT
uint64 srcs = _mm_cvtsi128_si64(srcABCD);
uint64 dsts;
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 {
#ifdef _SQ64
#ifdef POINTER_IS_64BIT
if (sprite_flags & SF_TRANSLUCENT) {
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);

@ -34,7 +34,7 @@ static inline void InsertSecondUint32(const uint32 value, __m128i &into)
static inline void LoadUint64(const uint64 value, __m128i &into)
{
#ifdef _SQ64
#ifdef POINTER_IS_64BIT
into = _mm_cvtsi64_si128(value);
#else
#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 = m != 0 ? m_colour : srcm; \
}
#ifdef _SQ64
#ifdef POINTER_IS_64BIT
uint64 srcs = _mm_cvtsi128_si64(srcABCD);
uint64 remapped_src = 0;
CMOV_REMAP(c0, 0, srcs, mvX2);

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

@ -536,6 +536,7 @@ enum CommandLogEntryFlag : uint16 {
DECLARE_ENUM_AS_BIT_SET(CommandLogEntryFlag)
struct CommandLogEntry {
std::string text;
TileIndex tile;
uint32 p1;
uint32 p2;
@ -550,8 +551,8 @@ struct CommandLogEntry {
CommandLogEntry() { }
CommandLogEntry(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandLogEntryFlag log_flags)
: tile(tile), p1(p1), p2(p2), cmd(cmd), p3(p3), date(_date), date_fract(_date_fract), tick_skip_counter(_tick_skip_counter),
CommandLogEntry(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandLogEntryFlag log_flags, std::string text)
: 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) { }
};
@ -607,11 +608,8 @@ static void DumpSubCommandLog(char *&buffer, const char *last, const CommandLog
switch (entry.cmd & CMD_ID_MASK) {
case CMD_CHANGE_SETTING:
buffer += seprintf(buffer, last, " [%s]", GetSettingNameByIndex(entry.p1));
break;
case CMD_CHANGE_COMPANY_SETTING:
buffer += seprintf(buffer, last, " [%s]", GetCompanySettingNameByIndex(entry.p1));
buffer += seprintf(buffer, last, " [%s]", entry.text.c_str());
break;
}
@ -806,7 +804,7 @@ Money GetAvailableMoneyForCommand()
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 (_generating_world) log_flags |= CLEF_GENERATING_WORLD;
@ -824,7 +822,16 @@ static void AppendCommandLogEntry(const CommandCost &res, TileIndex tile, uint32
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.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 (binary_length > 0) log_flags |= CLEF_BINARY;
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)) {
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 (binary_length > 0) log_flags |= CLEF_BINARY;
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)) {
CheckCachesFlags flags = CHECK_CACHE_ALL | CHECK_CACHE_EMIT_LOG;

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

@ -550,7 +550,7 @@ DEF_CONSOLE_CMD(ConClearBuffer)
* 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;
@ -604,7 +604,7 @@ DEF_CONSOLE_CMD(ConKick)
if (argc != 2 && argc != 3) return false;
/* 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 */
size_t kick_message_length = strlen(argv[2]);
@ -628,7 +628,7 @@ DEF_CONSOLE_CMD(ConBan)
if (argc != 2 && argc != 3) return false;
/* 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 */
size_t kick_message_length = strlen(argv[2]);
@ -827,7 +827,7 @@ DEF_CONSOLE_CMD(ConClientNickChange)
return true;
}
if (!NetworkServerChangeClientName(client_id, client_name.c_str())) {
if (!NetworkServerChangeClientName(client_id, client_name)) {
IConsoleError("Cannot give a client a duplicate name");
}

@ -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 */

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

@ -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);
}
strecpy(fios->title, t, lastof(fios->title));
str_validate(fios->title, lastof(fios->title));
StrMakeValidInPlace(fios->title, lastof(fios->title));
return true;
}
@ -394,7 +394,7 @@ static void FiosGetFileList(SaveLoadOperation fop, fios_getlist_callback_proc *c
std::string dirname = std::string(d_name) + PATHSEP;
SetDParamStr(0, dirname);
GetString(fios->title, STR_SAVELOAD_DIRECTORY, lastof(fios->title));
str_validate(fios->title, lastof(fios->title));
StrMakeValidInPlace(fios->title, lastof(fios->title));
}
}
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);
assert(title + read <= last);
title[read] = '\0';
str_validate(title, last);
StrMakeValidInPlace(title, last);
FioFCloseFile(f);
}

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

@ -22,7 +22,7 @@
*/
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->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)
{
this->name = str_validate(name);
this->name = StrMakeValid(name);
this->last_item = &this->item;
*parent->last_group = this;
@ -294,7 +294,7 @@ void IniLoadFile::LoadFromDisk(const std::string &filename, Subdirectory subdir,
if (!quoted && e == t) {
item->value.reset();
} else {
item->value = str_validate(std::string(t));
item->value = StrMakeValid(std::string(t));
}
} else {
/* it's an orphan item */

@ -2639,7 +2639,7 @@ STR_NETWORK_ERROR_SERVER_START :{WHITE}서버
STR_NETWORK_ERROR_CLIENT_START :{WHITE}접속할 수 없습니다
STR_NETWORK_ERROR_TIMEOUT :{WHITE}접속자 #{NUM}의 입력 시간이 초과되었습니다
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_WRONG_REVISION :{WHITE}이 접속자의 게임 버전이 서버의 버전과 일치하지 않습니다
STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}잘못된 비밀번호입니다

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

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

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

@ -1075,7 +1075,7 @@ struct QueryStringWindow : public Window
char *last_of = &this->editbox.text.buf[this->editbox.text.max_bytes - 1];
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
* characters (not bytes). max_chars also counts the '\0' characters. */

@ -401,7 +401,7 @@ void Packet::Recv_string(char *buffer, size_t size, StringValidationSettings set
assert(pos <= std::numeric_limits<PacketSize>::max());
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') {}
}
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);
buffer.assign((const char *)(this->buffer.data() + this->pos), length);
this->pos += (uint)length + 1;
str_validate_inplace(buffer, settings);
StrMakeValidInPlace(buffer, settings);
}
/**

@ -30,8 +30,6 @@ static_assert((int)CRR_END == (int)ADMIN_CRR_END);
NetworkAdminSocketHandler::NetworkAdminSocketHandler(SOCKET s) : status(ADMIN_STATUS_INACTIVE)
{
this->sock = s;
this->admin_name[0] = '\0';
this->admin_version[0] = '\0';
}
NetworkRecvStatus NetworkAdminSocketHandler::CloseConnection(bool error)
@ -89,9 +87,9 @@ NetworkRecvStatus NetworkAdminSocketHandler::HandlePacket(Packet *p)
default:
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 {
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();
@ -124,7 +122,7 @@ NetworkRecvStatus NetworkAdminSocketHandler::ReceivePackets()
*/
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;
}

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

@ -74,7 +74,7 @@ ServerNetworkAdminSocketHandler::ServerNetworkAdminSocketHandler(SOCKET s) : Net
ServerNetworkAdminSocketHandler::~ServerNetworkAdminSocketHandler()
{
_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 (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));
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);
}
@ -473,7 +473,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendChat(NetworkAction action
* Send a notification indicating the rcon command has completed.
* @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);
@ -488,7 +488,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRconEnd(const char *comma
* @param colour The colour of the text.
* @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);
@ -503,14 +503,12 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_RCON(Packet *p)
{
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, this->admin_version, command);
DEBUG(net, 3, "[admin] Rcon command from '%s' (%s): %s", this->admin_name.c_str(), this->admin_version.c_str(), command.c_str());
_redirect_console_to_admin = this->index;
IConsoleCmdExec(command);
IConsoleCmdExec(command.c_str());
_redirect_console_to_admin = INVALID_ADMIN_ID;
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);
char json[NETWORK_GAMESCRIPT_JSON_LENGTH];
p->Recv_string(json, sizeof(json));
std::string json = p->Recv_string(NETWORK_GAMESCRIPT_JSON_LENGTH);
DEBUG(net, 6, "[admin] GameScript JSON from '%s' (%s): %s", this->admin_name, this->admin_version, json);
DEBUG(net, 6, "[admin] GameScript JSON from '%s' (%s): %s", this->admin_name.c_str(), this->admin_version.c_str(), json.c_str());
Game::NewEvent(new ScriptEventAdminPort(json));
return NETWORK_RECV_STATUS_OKAY;
@ -535,7 +531,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_PING(Packet *p)
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);
}
@ -545,13 +541,13 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_PING(Packet *p)
* @param origin The origin of the string.
* @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
* 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%
* 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);
@ -566,12 +562,12 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendConsole(const char *origi
* Send GameScript JSON output.
* @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
* the maximum amount of json data that can be sent. Account also for
* 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);
@ -661,17 +657,17 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_JOIN(Packet *p)
return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
}
p->Recv_string(this->admin_name, sizeof(this->admin_name));
p->Recv_string(this->admin_version, sizeof(this->admin_version));
this->admin_name = p->Recv_string(NETWORK_CLIENT_NAME_LENGTH);
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 */
return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
}
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();
}
@ -691,7 +687,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_UPDATE_FREQUENC
if (type >= ADMIN_UPDATE_END || (_admin_update_type_frequencies[type] & freq) != freq) {
/* 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);
}
@ -761,7 +757,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_POLL(Packet *p)
default:
/* 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);
}
@ -787,7 +783,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_CHAT(Packet *p)
break;
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);
}
@ -925,7 +921,7 @@ void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_i
* @param colour_code The colour of the string.
* @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);
}
@ -935,7 +931,7 @@ void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code,
* @param origin the origin of the message.
* @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()) {
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).
* @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()) {
if (as->update_frequency[ADMIN_UPDATE_GAMESCRIPT] & ADMIN_FREQUENCY_AUTOMATIC) {

@ -62,12 +62,12 @@ public:
NetworkRecvStatus SendCompanyStats();
NetworkRecvStatus SendChat(NetworkAction action, DestType desttype, ClientID client_id, const std::string &msg, NetworkTextMessageData data);
NetworkRecvStatus SendRcon(uint16 colour, const char *command);
NetworkRecvStatus SendConsole(const char *origin, const char *command);
NetworkRecvStatus SendGameScript(const char *json);
NetworkRecvStatus SendRcon(uint16 colour, const std::string_view command);
NetworkRecvStatus SendConsole(const std::string_view origin, const std::string_view command);
NetworkRecvStatus SendGameScript(const std::string_view json);
NetworkRecvStatus SendCmdNames();
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 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 NetworkAdminUpdate(AdminUpdateFrequency freq);
void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code, const char *string);
void NetworkAdminConsole(const char *origin, const char *string);
void NetworkAdminGameScript(const char *json);
void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code, const std::string_view string);
void NetworkAdminConsole(const std::string_view origin, const std::string_view string);
void NetworkAdminGameScript(const std::string_view json);
void NetworkAdminCmdLogging(const NetworkClientSocket *owner, const CommandPacket *cp);
#endif /* NETWORK_ADMIN_H */

@ -612,7 +612,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetPassword(const std::str
* Tell the server that we like to change the name of the client.
* @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);
@ -637,7 +637,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendQuit()
* @param pass The password for the remote 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);
p->Send_string(GenerateCompanyPasswordHash(pass, _password_server_id, _rcon_password_game_seed));
@ -1467,7 +1467,7 @@ void NetworkClient_Connected()
* @param password The password.
* @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);
}
@ -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 */
if (client_name.compare(ci->client_name) != 0) {
if (!_network_server) {
MyClient::SendSetName(client_name.c_str());
MyClient::SendSetName(client_name);
} else {
/* 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];
strecpy(temporary_name, client_name.c_str(), lastof(temporary_name));
if (NetworkFindName(temporary_name, lastof(temporary_name))) {
std::string temporary_name = client_name;
if (NetworkMakeClientNameUnique(temporary_name)) {
NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, temporary_name);
ci->client_name = temporary_name;
NetworkUpdateClientInfo(CLIENT_ID_SERVER);

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

@ -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 = "");
void NetworkClientJoinGame();
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 NetworkClientSendChat(NetworkAction action, DestType type, int dest, const std::string &msg, NetworkTextMessageData data = NetworkTextMessageData());
void NetworkClientSendDesyncMsg(const char *msg);
@ -75,16 +75,16 @@ void NetworkServerUpdateGameInfo();
void NetworkServerShowStatusToConsole();
bool NetworkServerStart();
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 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 NetworkServerKickClient(ClientID client_id, const char *reason);
uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const char *reason);
uint NetworkServerKickOrBanIP(const char *ip, bool ban, const char *reason);
void NetworkServerKickClient(ClientID client_id, const std::string &reason);
uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const std::string &reason);
uint NetworkServerKickOrBanIP(const std::string &ip, bool ban, const std::string &reason);
void NetworkInitChatMessage();
void CDECL NetworkAddChatMessage(TextColour colour, uint duration, const std::string &message);

@ -1676,7 +1676,7 @@ enum DropDownAdmin {
*/
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)
{
if (confirmed) NetworkServerKickOrBanIP(_admin_client_id, true, nullptr);
if (confirmed) NetworkServerKickOrBanIP(_admin_client_id, true, {});
}
/**

@ -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());
uint NetworkCalculateLag(const NetworkClientSocket *cs);
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);
NetworkAddress ParseConnectionString(const std::string &connection_string, uint16 default_port);

@ -443,12 +443,12 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyInfo()
* @param error The error to disconnect for.
* @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);
p->Send_uint8(error);
if (reason != nullptr) p->Send_string(reason);
if (!reason.empty()) p->Send_string(reason);
this->SendPacket(p);
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());
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);
} else {
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 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);
@ -928,8 +928,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p)
return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
}
char name[NETWORK_CLIENT_NAME_LENGTH];
CompanyID playas;
char client_revision[NETWORK_REVISION_LENGTH];
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);
}
p->Recv_string(name, sizeof(name));
playas = (Owner)p->Recv_uint8();
std::string client_name = p->Recv_string(NETWORK_CLIENT_NAME_LENGTH);
CompanyID playas = (Owner)p->Recv_uint8();
if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CLIENT_QUIT;
@ -965,14 +963,14 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p)
break;
}
if (!NetworkIsValidClientName(name)) {
if (!NetworkIsValidClientName(client_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
* wrong. This is probably someone trying to troll us. */
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 */
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);
this->SetInfo(ci);
ci->join_date = _date;
ci->client_name = name;
ci->client_name = client_name;
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);
@ -1528,10 +1526,9 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SET_NAME(Packet
return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
}
char client_name[NETWORK_CLIENT_NAME_LENGTH];
NetworkClientInfo *ci;
p->Recv_string(client_name, sizeof(client_name));
std::string client_name = p->Recv_string(NETWORK_CLIENT_NAME_LENGTH);
ci = this->GetInfo();
if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CLIENT_QUIT;
@ -1545,7 +1542,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SET_NAME(Packet
}
/* 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);
ci->client_name = client_name;
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);
char command[NETWORK_RCONCOMMAND_LENGTH];
if (_settings_client.network.rcon_password.empty()) {
NetworkServerSendRcon(this->client_id, CC_ERROR, "Access Denied");
return NETWORK_RECV_STATUS_OKAY;
}
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)) {
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;
}
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;
IConsoleCmdExec(command);
IConsoleCmdExec(command.c_str());
_redirect_console_to_client = INVALID_CLIENT_ID;
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.
* @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.
*/
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;
char original_name[NETWORK_CLIENT_NAME_LENGTH];
strecpy(original_name, new_name, lastof(original_name));
std::string original_name = name;
while (!found_name) {
found_name = true;
while (!is_name_unique) {
is_name_unique = true;
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 */
found_name = false;
is_name_unique = false;
break;
}
}
/* Check if it is the same as the server-name */
const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER);
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) */
name = original_name + " #" + std::to_string(number);
/* Something's really wrong when there're more names than clients */
if (number++ > MAX_CLIENTS) break;
seprintf(new_name, last, "%s #%d", original_name, number);
/* The constructed client name is larger than the limit,
* so... bail out as no valid name can be created. */
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
* @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 */
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 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);
}
@ -2223,7 +2216,7 @@ void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const cha
* @param client_id The client to kick.
* @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;
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 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);
}
@ -2246,7 +2239,7 @@ uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const char *reason)
* @param ban Whether to ban or just kick.
* @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 */
if (ban) {
@ -2270,7 +2263,7 @@ uint NetworkServerKickOrBanIP(const char *ip, bool ban, const char *reason)
for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
if (cs->client_id == CLIENT_ID_SERVER) 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);
n++;
}

@ -103,11 +103,11 @@ public:
NetworkRecvStatus SendQuit(ClientID client_id);
NetworkRecvStatus SendShutdown();
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 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 SendChat(NetworkAction action, ClientID client_id, bool self_send, const std::string &msg, NetworkTextMessageData data);
NetworkRecvStatus SendJoin(ClientID client_id);

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

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

@ -15,6 +15,7 @@
#include "tile_type.h"
#include "vehicle_type.h"
#include "base_consist.h"
#include "saveload/saveload.h"
/** Unique identifier for an order backup. */
typedef uint8 OrderBackupID;
@ -34,7 +35,7 @@ static const uint32 MAKE_ORDER_BACKUP_FLAG = 1U << 31;
*/
struct OrderBackup : OrderBackupPool::PoolItem<&_order_backup_pool>, BaseConsist {
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.
uint32 user; ///< The user that requested the backup.
TileIndex tile; ///< Tile of the depot where the order was changed.

@ -19,6 +19,7 @@
#include "vehicle_type.h"
#include "date_type.h"
#include "schdispatch.h"
#include "saveload/saveload.h"
#include <memory>
#include <vector>
@ -62,9 +63,9 @@ struct OrderExtraInfo {
*/
struct Order : OrderPool::PoolItem<&_order_pool> {
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 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 Save_ORDX(); ///< 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> {
private:
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.
StationID GetBestLoadableNext(const Vehicle *v, const Order *o1, const Order *o2) const;

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

@ -174,7 +174,7 @@ int CDECL main(int argc, char *argv[])
SetRandomSeed(time(nullptr));
/* 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);
}

@ -243,7 +243,7 @@ void CocoaReleaseAutoreleasePool();
int CDECL main(int argc, char *argv[])
{
/* 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
CocoaSetupAutoreleasePool();

@ -436,7 +436,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
argc = ParseCommandLine(cmdline, argv, lengthof(argv));
/* 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);

@ -1970,15 +1970,15 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, DoCommandFlag flags, uin
last_suitable_trackdir = trackdir;
} 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. */
SB(p1, 0, 3, TrackdirToTrack(last_suitable_trackdir));
ClrBit(p1, 17);
SB(param1, 0, 3, TrackdirToTrack(last_suitable_trackdir));
ClrBit(param1, 17);
/* Pick the correct orientation for the track direction. */
signals = 0;
if (HasBit(signal_dir, 0)) signals |= SignalAlongTrackdir(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)) {
/* Blacklist far end of tunnel if we just actioned the near end */
tunnel_bridge_blacklist.push_back(GetOtherTunnelBridgeEnd(last_suitable_tile));

@ -30,7 +30,6 @@ static const SaveLoad _ai_company[] = {
SLEG_SSTR(_ai_saveload_settings, SLE_STR),
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),
SLE_END()
};
static void SaveReal_AIPL(int *index_ptr)

@ -21,7 +21,6 @@ static const SaveLoad _engine_renew_desc[] = {
SLE_REF(EngineRenew, next, REF_ENGINE_RENEWS),
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_END()
};
static void Save_ERNW()

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

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

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

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

@ -294,8 +294,6 @@ static const SaveLoad _company_desc[] = {
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, 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[] = {
@ -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_CONDNULL(63, SLV_2, SLV_144), // old reserved space
SLE_END()
};
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(63, SLV_2, SLV_144), // old reserved space
SLE_END()
};
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, NUM_CARGO, SLV_EXTEND_CARGOTYPES, SL_MAX_VERSION),
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 */
@ -393,7 +385,6 @@ static const SaveLoad _company_ai_desc[] = {
SLE_CONDNULL(32, SL_MIN_VERSION, SLV_107),
SLE_CONDNULL(64, SLV_2, SLV_107),
SLE_END()
};
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(4, SLV_6, SLV_107),
SLE_CONDNULL(8, SL_MIN_VERSION, SLV_107),
SLE_END()
};
static const SaveLoad _company_livery_desc[] = {
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, colour2, SLE_UINT8, SLV_34, SL_MAX_VERSION),
SLE_END()
};
static void SaveLoad_PLYR_common(Company *c, CompanyProperties *cprops)

@ -26,7 +26,6 @@ static const SaveLoad _depot_desc[] = {
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_CONDNULL_X(4, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPRINGPP, 5)),
SLE_END()
};
static void Save_DEPT()

@ -47,7 +47,6 @@ static const SaveLoad _economy_desc[] = {
SLE_VAR(Economy, infl_amount_pr, SLE_UINT8),
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_END()
};
/** Economy variables */
@ -68,7 +67,6 @@ static const SaveLoad _cargopayment_desc[] = {
SLE_VAR(CargoPayment, route_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_END()
};
static void Save_CAPY()

@ -43,8 +43,6 @@ static const SaveLoad _engine_desc[] = {
SLE_CONDSTR(Engine, name, SLE_STR, 0, SLV_84, SL_MAX_VERSION),
SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space
SLE_END()
};
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, type, SLE_UINT8),
SLE_VAR(EngineIDMapping, substitute_id, SLE_UINT8),
SLE_END()
};
static void Save_EIDS()

@ -463,7 +463,6 @@ static void Save_SLXI()
static const SaveLoad _xlsi_sub_chunk_desc[] = {
SLE_STR(SlxiSubChunkInfo, name, SLE_STR, 0),
SLE_END()
};
// 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);
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_END()
};
auto version_error = [](StringID str, const char *feature, int64 p1, int64 p2) {

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

@ -18,13 +18,11 @@
static const SaveLoad _glog_action_desc[] = {
SLE_VAR(LoggedAction, tick, SLE_UINT16),
SLE_END()
};
static const SaveLoad _glog_mode_desc[] = {
SLE_VAR(LoggedChange, mode.mode, SLE_UINT8),
SLE_VAR(LoggedChange, mode.landscape, SLE_UINT8),
SLE_END()
};
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.slver, SLE_UINT16),
SLE_VAR(LoggedChange, revision.modified, SLE_UINT8),
SLE_END()
};
static const SaveLoad _glog_oldver_desc[] = {
SLE_VAR(LoggedChange, oldver.type, SLE_UINT32),
SLE_VAR(LoggedChange, oldver.version, SLE_UINT32),
SLE_END()
};
static const SaveLoad _glog_setting_desc[] = {
SLE_STR(LoggedChange, setting.name, SLE_STR, 128),
SLE_VAR(LoggedChange, setting.oldval, SLE_INT32),
SLE_VAR(LoggedChange, setting.newval, SLE_INT32),
SLE_END()
};
static const SaveLoad _glog_grfadd_desc[] = {
SLE_VAR(LoggedChange, grfadd.grfid, SLE_UINT32 ),
SLE_ARR(LoggedChange, grfadd.md5sum, SLE_UINT8, 16),
SLE_END()
};
static const SaveLoad _glog_grfrem_desc[] = {
SLE_VAR(LoggedChange, grfrem.grfid, SLE_UINT32),
SLE_END()
};
static const SaveLoad _glog_grfcompat_desc[] = {
SLE_VAR(LoggedChange, grfcompat.grfid, SLE_UINT32 ),
SLE_ARR(LoggedChange, grfcompat.md5sum, SLE_UINT8, 16),
SLE_END()
};
static const SaveLoad _glog_grfparam_desc[] = {
SLE_VAR(LoggedChange, grfparam.grfid, SLE_UINT32),
SLE_END()
};
static const SaveLoad _glog_grfmove_desc[] = {
SLE_VAR(LoggedChange, grfmove.grfid, SLE_UINT32),
SLE_VAR(LoggedChange, grfmove.offset, SLE_INT32),
SLE_END()
};
static const SaveLoad _glog_grfbug_desc[] = {
SLE_VAR(LoggedChange, grfbug.data, SLE_UINT64),
SLE_VAR(LoggedChange, grfbug.grfid, SLE_UINT32),
SLE_VAR(LoggedChange, grfbug.bug, SLE_UINT8),
SLE_END()
};
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_revision_desc,
_glog_oldver_desc,

@ -21,7 +21,6 @@ static const SaveLoad _goals_desc[] = {
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_CONDVAR(Goal, completed, SLE_BOOL, SLV_182, SL_MAX_VERSION),
SLE_END()
};
static void Save_GOAL()

@ -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.colour2, SLE_UINT8, SLV_GROUP_LIVERIES, SL_MAX_VERSION),
SLE_CONDVAR(Group, parent, SLE_UINT16, SLV_189, SL_MAX_VERSION),
SLE_END()
};
static void Save_GRPS()

@ -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_CONDNULL(32, SLV_2, SLV_144), // old reserved space
SLE_END()
};
static void Save_INDY()
@ -139,7 +137,6 @@ static void Ptrs_INDY()
/** Description of the data to save and load in #IndustryBuildData. */
static const SaveLoad _industry_builder_desc[] = {
SLEG_VAR(_industry_builder.wanted_inds, SLE_UINT32),
SLEG_END()
};
/** Load/save industry builder. */
@ -155,7 +152,6 @@ static const SaveLoad _industrytype_builder_desc[] = {
SLE_VAR(IndustryTypeBuildData, target_count, SLE_UINT16),
SLE_VAR(IndustryTypeBuildData, max_wait, SLE_UINT16),
SLE_VAR(IndustryTypeBuildData, wait_count, SLE_UINT16),
SLE_END()
};
/** Save industry-type build data. */

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

@ -28,13 +28,12 @@ static uint16 _num_nodes;
* Get a SaveLoad array for a link graph.
* @return SaveLoad array for link graph.
*/
const SaveLoad *GetLinkGraphDesc()
SaveLoadTable GetLinkGraphDesc()
{
static const SaveLoad link_graph_desc[] = {
SLE_VAR(LinkGraph, last_compression, SLE_INT32),
SLEG_VAR(_num_nodes, SLE_UINT16),
SLE_VAR(LinkGraph, cargo, SLE_UINT8),
SLE_END()
};
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.
* @return Array of SaveLoad structs.
*/
const SaveLoad *GetLinkGraphJobDesc()
SaveLoadTable GetLinkGraphJobDesc()
{
static std::vector<SaveLoad> saveloads;
static const char *prefix = "linkgraph.";
@ -84,28 +83,25 @@ const SaveLoad *GetLinkGraphJobDesc()
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_VAR(LinkGraphJob, link_graph.index, SLE_UINT16),
SLE_END()
};
int i = 0;
do {
saveloads.push_back(job_desc[i++]);
} while (saveloads.back().cmd != SL_END);
for (auto &sld : job_desc) {
saveloads.push_back(sld);
}
}
return &saveloads[0];
return saveloads;
}
/**
* Get a 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[] = {
SLE_LST(LinkGraphSchedule, schedule, REF_LINK_GRAPH),
SLE_LST(LinkGraphSchedule, running, REF_LINK_GRAPH_JOB),
SLE_END()
};
return schedule_desc;
}
@ -121,7 +117,6 @@ static const SaveLoad _node_desc[] = {
SLE_VAR(Node, demand, SLE_UINT32),
SLE_VAR(Node, station, SLE_UINT16),
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_CONDVAR(Edge, last_restricted_update, SLE_INT32, SLV_187, SL_MAX_VERSION),
SLE_VAR(Edge, next_edge, SLE_UINT16),
SLE_END()
};
std::vector<SaveLoad> _filtered_node_desc;
@ -157,10 +151,10 @@ void Save_LinkGraph(LinkGraph &lg)
uint16 size = lg.Size();
for (NodeID from = 0; from < size; ++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. */
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();
for (NodeID from = 0; from < size; ++from) {
Node *node = &lg.nodes[from];
SlObjectLoadFiltered(node, _filtered_node_desc.data());
SlObjectLoadFiltered(node, _filtered_node_desc);
if (IsSavegameVersionBefore(SLV_191)) {
/* We used to save the full matrix ... */
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 {
/* ... 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) {
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)
{
SlObjectSaveFiltered(lgj, _filtered_job_desc.data());
SlObjectSaveFiltered(lgj, _filtered_job_desc);
_num_nodes = lgj->Size();
SlObjectSaveFiltered(const_cast<LinkGraph *>(&lgj->Graph()), GetLinkGraphDesc()); // GetLinkGraphDesc has no conditionals
Save_LinkGraph(const_cast<LinkGraph &>(lgj->Graph()));
@ -245,7 +239,7 @@ static void Load_LGRJ()
NOT_REACHED();
}
LinkGraphJob *lgj = new (index) LinkGraphJob();
SlObjectLoadFiltered(lgj, _filtered_job_desc.data());
SlObjectLoadFiltered(lgj, _filtered_job_desc);
if (SlXvIsFeatureMissing(XSLFI_LINKGRAPH_DAY_SCALE)) {
GetLinkGraphJobDayLengthScaleAfterLoad(lgj);
}

@ -25,10 +25,9 @@ static uint32 _map_dim_y;
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_y, SLE_UINT32, SLV_6, SL_MAX_VERSION),
SLEG_END()
};
static void Save_MAPS()

@ -72,7 +72,7 @@ void ResetViewportAfterLoadGame()
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_INT32, SLV_31, SL_MAX_VERSION),
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(_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),
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_INT32, SLV_31, SL_MAX_VERSION),
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(1, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_REALISTIC_TRAIN_BRAKING, 4)), // _extra_aspects
SLE_CONDNULL(4, SLV_11, SLV_120),
SLEG_END()
};
/* 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_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_INT32, SLV_6, SL_MAX_VERSION),
SLEG_VAR(_saved_scrollpos_zoom, SLE_UINT8),
SLEG_END()
};
static void SaveLoad_VIEW()

@ -21,7 +21,6 @@ static const SaveLoad _newgrf_mapping_desc[] = {
SLE_VAR(EntityIDMapping, grfid, SLE_UINT32),
SLE_VAR(EntityIDMapping, entity_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_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)),
SLE_END()
};

@ -25,8 +25,6 @@ static const SaveLoad _object_desc[] = {
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, type, SLE_UINT16, SLV_186, SL_MAX_VERSION),
SLE_END()
};
static void Save_OBJS()

@ -236,7 +236,7 @@ static inline bool CheckOldSavegameType(FILE *f, char *temp, const char *last, u
bool ret = VerifyOldNameChecksum(temp, len);
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;
}

@ -113,7 +113,7 @@ Order UnpackOldOrder(uint16 packed)
return order;
}
const SaveLoad *GetOrderDescription()
SaveLoadTable GetOrderDescription()
{
static const SaveLoad _order_desc[] = {
SLE_VAR(Order, type, SLE_UINT8),
@ -135,7 +135,6 @@ const SaveLoad *GetOrderDescription()
/* 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 */
SLE_CONDNULL(10, SLV_5, SLV_36),
SLE_END()
};
return _order_desc;
@ -148,7 +147,7 @@ static void Save_ORDR()
_filtered_desc = SlFilterObject(GetOrderDescription());
for (Order *order : Order::Iterate()) {
SlSetArrayIndex(order->index);
SlObjectSaveFiltered(order, _filtered_desc.data());
SlObjectSaveFiltered(order, _filtered_desc);
}
}
@ -206,19 +205,18 @@ static void Load_ORDR()
while ((index = SlIterateArray()) != -1) {
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[] = {
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_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_END()
};
return _order_extra_info_desc;
@ -230,7 +228,7 @@ void Save_ORDX()
for (Order *order : Order::Iterate()) {
if (order->extra) {
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);
assert(order != nullptr);
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[] = {
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)),
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_END()
};
return _orderlist_desc;
@ -312,7 +309,7 @@ void Ptrs_ORDL()
}
}
const SaveLoad *GetOrderBackupDescription()
SaveLoadTable GetOrderBackupDescription()
{
static const SaveLoad _order_backup_desc[] = {
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_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_END()
};
return _order_backup_desc;

@ -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_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_END()
};
static void RealSave_PLAN(Plan *p)

@ -1112,7 +1112,7 @@ static void SlString(void *ptr, size_t length, VarType conv)
if ((conv & SLF_ALLOW_NEWLINE) != 0) {
settings = settings | SVS_ALLOW_NEWLINE;
}
str_validate((char *)ptr, (char *)ptr + len, settings);
StrMakeValidInPlace((char *)ptr, (char *)ptr + len, settings);
break;
}
case SLA_PTRS: break;
@ -1151,7 +1151,7 @@ static void SlStdString(std::string &str, VarType conv)
if ((conv & SLF_ALLOW_NEWLINE) != 0) {
settings = settings | SVS_ALLOW_NEWLINE;
}
str_validate_inplace(str, settings);
StrMakeValidInPlace(str, settings);
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? */
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->conv & SLF_NOT_IN_SAVE) 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;
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
* 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) {
SlSkipBytes(SlCalcConvMemLen(sld->conv) * sld->length);
if ((sld.conv & SLF_NO_NETWORK_SYNC) && _sl.action != SLA_SAVE && _networking && !_network_server) {
SlSkipBytes(SlCalcConvMemLen(sld.conv) * sld.length);
return true;
}
@ -1618,26 +1618,26 @@ static inline bool SlSkipVariableOnLoad(const SaveLoad *sld)
/**
* Calculate the size of an object.
* @param object to be measured
* @param sld The SaveLoad description of the object so we know how to manipulate it
* @return size of given object
* @param object to be measured.
* @param slt The SaveLoad table with objects to save/load.
* @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;
/* Need to determine the length and write a length tag. */
for (; sld->cmd != SL_END; sld++) {
for (auto &sld : slt) {
length += SlCalcObjMemberLength(object, sld);
}
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);
switch (sld->cmd) {
switch (sld.cmd) {
case SL_VAR:
case SL_REF:
case SL_ARR:
@ -1651,17 +1651,17 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
/* CONDITIONAL saveload types depend on the savegame version */
if (!SlIsObjectValidInSavegame(sld)) break;
switch (sld->cmd) {
case SL_VAR: return SlCalcConvFileLen(sld->conv);
switch (sld.cmd) {
case SL_VAR: return SlCalcConvFileLen(sld.conv);
case SL_REF: return SlCalcRefLen();
case SL_ARR: return SlCalcArrayLen(sld->length, sld->conv);
case SL_STR: return SlCalcStringLen(GetVariableAddress(object, sld), 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_LST: return SlCalcListLen<std::list<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_DEQUE: return SlCalcDequeLen(GetVariableAddress(object, sld), sld->conv);
case SL_DEQUE: return SlCalcDequeLen(GetVariableAddress(object, sld), sld.conv);
case SL_VARVEC: {
const size_t size_len = SlCalcConvMemLen(sld->conv);
const size_t size_len = SlCalcConvMemLen(sld.conv);
switch (size_len) {
case 1: return SlCalcVarListLen<std::vector<byte>>(GetVariableAddress(object, sld), 1);
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.
* @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:
switch (GetVarMemType(sld->conv)) {
switch (GetVarMemType(sld.conv)) {
case SLE_VAR_BL:
return sld->size == sizeof(bool);
return sld.size == sizeof(bool);
case SLE_VAR_I8:
case SLE_VAR_U8:
return sld->size == sizeof(int8);
return sld.size == sizeof(int8);
case SLE_VAR_I16:
case SLE_VAR_U16:
return sld->size == sizeof(int16);
return sld.size == sizeof(int16);
case SLE_VAR_I32:
case SLE_VAR_U32:
return sld->size == sizeof(int32);
return sld.size == sizeof(int32);
case SLE_VAR_I64:
case SLE_VAR_U64:
return sld->size == sizeof(int64);
return sld.size == sizeof(int64);
case SLE_VAR_NAME:
return sld->size == sizeof(std::string);
return sld.size == sizeof(std::string);
default:
return sld->size == sizeof(void *);
return sld.size == sizeof(void *);
}
case SL_REF:
/* These should all be pointer sized. */
return sld->size == sizeof(void *);
return sld.size == sizeof(void *);
case SL_STR:
/* 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:
/* These should be all pointers to std::string. */
return sld->size == sizeof(std::string);
return sld.size == sizeof(std::string);
default:
return true;
@ -1732,15 +1732,15 @@ static bool IsVariableSizeRight(const SaveLoad *sld)
#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
assert(IsVariableSizeRight(sld));
#endif
switch (sld->cmd) {
switch (sld.cmd) {
case SL_VAR:
case SL_REF:
case SL_ARR:
@ -1762,7 +1762,7 @@ static void SlFilterObjectMember(const SaveLoad *sld, std::vector<SaveLoad> &sav
break;
case SLA_PTRS:
case SLA_NULL:
switch (sld->cmd) {
switch (sld.cmd) {
case SL_REF:
case SL_LST:
case SL_PTRDEQ:
@ -1777,14 +1777,14 @@ static void SlFilterObjectMember(const SaveLoad *sld, std::vector<SaveLoad> &sav
default: NOT_REACHED();
}
save.push_back(*sld);
save.push_back(sld);
break;
/* 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
* object description to use. */
case SL_WRITEBYTE:
if (_sl.action == SLA_SAVE) save.push_back(*sld);
if (_sl.action == SLA_SAVE) save.push_back(sld);
break;
/* 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);
}
}
std::vector<SaveLoad> SlFilterObject(const SaveLoad *sld)
std::vector<SaveLoad> SlFilterObject(const SaveLoadTable &slt)
{
std::vector<SaveLoad> save;
SlFilterObject(sld, save);
save.push_back(SLE_END());
SlFilterObject(slt, save);
return save;
}
template <SaveLoadAction action, bool check_version>
bool SlObjectMemberGeneric(void *ptr, const SaveLoad *sld)
bool SlObjectMemberGeneric(void *ptr, const SaveLoad &sld)
{
#ifdef OTTD_ASSERT
if (check_version) assert(IsVariableSizeRight(sld));
#endif
VarType conv = GB(sld->conv, 0, 8);
switch (sld->cmd) {
VarType conv = GB(sld.conv, 0, 8);
switch (sld.cmd) {
case SL_VAR:
case SL_REF:
case SL_ARR:
@ -1840,7 +1839,7 @@ bool SlObjectMemberGeneric(void *ptr, const SaveLoad *sld)
if (SlSkipVariableOnLoad(sld)) return false;
}
switch (sld->cmd) {
switch (sld.cmd) {
case SL_VAR: SlSaveLoadConvGeneric<action>(ptr, conv); break;
case SL_REF: // Reference variable, translate
switch (action) {
@ -1860,14 +1859,14 @@ bool SlObjectMemberGeneric(void *ptr, const SaveLoad *sld)
default: NOT_REACHED();
}
break;
case SL_ARR: SlArray(ptr, sld->length, conv); break;
case SL_STR: SlString(ptr, sld->length, sld->conv); break;
case SL_ARR: SlArray(ptr, sld.length, 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_PTRDEQ: SlList<std::deque<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_VARVEC: {
const size_t size_len = SlCalcConvMemLen(sld->conv);
const size_t size_len = SlCalcConvMemLen(sld.conv);
switch (size_len) {
case 1: SlVarList<std::vector<byte>>(ptr, conv); break;
case 2: SlVarList<std::vector<uint16>>(ptr, conv); break;
@ -1877,7 +1876,7 @@ bool SlObjectMemberGeneric(void *ptr, const SaveLoad *sld)
}
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();
}
break;
@ -1910,7 +1909,7 @@ bool SlObjectMemberGeneric(void *ptr, const SaveLoad *sld)
return true;
}
bool SlObjectMember(void *ptr, const SaveLoad *sld)
bool SlObjectMember(void *ptr, const SaveLoad &sld)
{
switch (_sl.action) {
case SLA_SAVE:
@ -1928,71 +1927,71 @@ bool SlObjectMember(void *ptr, const SaveLoad *sld)
/**
* Main SaveLoad function.
* @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 object The object that is being saved or loaded.
* @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? */
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);
SlObjectMember(ptr, sld);
}
}
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++) {
void *ptr = sld->global ? sld->address : GetVariableAddress(object, sld);
for (auto &sld : slt) {
void *ptr = sld.global ? sld.address : GetVariableAddress(object, 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) {
_sl.need_length = NL_NONE;
_sl.dumper->StartAutoLength();
SlObjectIterateBase<SLA_SAVE, false>(object, sld);
SlObjectIterateBase<SLA_SAVE, false>(object, slt);
auto result = _sl.dumper->StopAutoLength();
_sl.need_length = NL_WANTLENGTH;
SlSetLength(result.second);
_sl.dumper->CopyBytes(result.first, result.second);
} 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) {
case SLA_PTRS:
SlObjectIterateBase<SLA_PTRS, false>(object, sld);
SlObjectIterateBase<SLA_PTRS, false>(object, slt);
return;
case SLA_NULL:
SlObjectIterateBase<SLA_NULL, false>(object, sld);
SlObjectIterateBase<SLA_NULL, false>(object, slt);
return;
default: NOT_REACHED();
}
}
/**
* Save or Load (a list of) global variables
* @param sldg The global variable that is being loaded or saved
* Save or Load (a list of) global variables.
* @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);
}
/**

@ -12,6 +12,7 @@
#include "../fileio_type.h"
#include "../strings_type.h"
#include "../core/span_type.hpp"
#include "extended_ver_sl.h"
#include <stdarg.h>
@ -564,7 +565,6 @@ enum SaveLoadTypes {
SL_PTRDEQ = 13, ///< Save/load a pointer type deque.
SL_VARVEC = 14, ///< Save/load a primitive type vector.
SL_END = 15
};
typedef byte SaveLoadType; ///< Save/load type. @see SaveLoadTypes
@ -586,8 +586,8 @@ struct SaveLoad {
SlXvFeatureTest ext_feature_test; ///< extended feature test
};
/** Same as #SaveLoad but global variables are used (for better readability); */
typedef SaveLoad SaveLoadGlobVarList;
/** A table of SaveLoad entries. */
using SaveLoadTable = span<const SaveLoad>;
/**
* 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_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.
* @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()}
/** 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.
* @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
* 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. */
if (sld->global) return sld->address;
if (sld.global) return sld.address;
#ifdef _DEBUG
/* Entry is a null-variable, mostly used to read old savegames etc. */
if (GetVarMemType(sld->conv) == SLE_VAR_NULL) {
assert(sld->address == nullptr);
if (GetVarMemType(sld.conv) == SLE_VAR_NULL) {
assert(sld.address == nullptr);
return nullptr;
}
/* Everything else should be a non-null pointer. */
assert(object != nullptr);
#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);
@ -1092,8 +1086,8 @@ int SlIterateArray();
void SlAutolength(AutolengthProc *proc, void *arg);
size_t SlGetFieldLength();
void SlSetLength(size_t length);
size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld);
size_t SlCalcObjLength(const void *object, const SaveLoad *sld);
size_t SlCalcObjMemberLength(const void *object, const SaveLoad &sld);
size_t SlCalcObjLength(const void *object, const SaveLoadTable &slt);
byte SlReadByte();
void SlWriteByte(byte b);
@ -1111,15 +1105,15 @@ void SlSkipBytes(size_t length);
size_t SlGetBytesRead();
size_t SlGetBytesWritten();
void SlGlobList(const SaveLoadGlobVarList *sldg);
void SlGlobList(const SaveLoadTable &slt);
void SlArray(void *array, size_t length, VarType conv);
void SlObject(void *object, const SaveLoad *sld);
bool SlObjectMember(void *object, const SaveLoad *sld);
void SlObject(void *object, const SaveLoadTable &slt);
bool SlObjectMember(void *object, const SaveLoad &sld);
std::vector<SaveLoad> SlFilterObject(const SaveLoad *sld);
void SlObjectSaveFiltered(void *object, const SaveLoad *sld);
void SlObjectLoadFiltered(void *object, const SaveLoad *sld);
void SlObjectPtrOrNullFiltered(void *object, const SaveLoad *sld);
std::vector<SaveLoad> SlFilterObject(const SaveLoadTable &slt);
void SlObjectSaveFiltered(void *object, const SaveLoadTable &slt);
void SlObjectLoadFiltered(void *object, const SaveLoadTable &slt);
void SlObjectPtrOrNullFiltered(void *object, const SaveLoadTable &slt);
void NORETURN SlError(StringID string, const char *extra_msg = nullptr, bool already_malloced = false);
void NORETURN SlErrorCorrupt(const char *msg, bool already_malloced = false);

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

@ -26,7 +26,6 @@ static const SaveLoad _sign_desc[] = {
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_INT32, SLV_164, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_OR, XSLFI_ZPOS_32_BIT)),
SLE_END()
};
/** Save all signs */

@ -157,8 +157,6 @@ static const SaveLoad _roadstop_desc[] = {
SLE_CONDNULL(4, SL_MIN_VERSION, SLV_25),
SLE_CONDNULL(1, SLV_25, SLV_26),
SLE_END()
};
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) */
SLE_CONDNULL(32, SLV_2, SL_MAX_VERSION),
SLE_END()
};
static uint16 _waiting_acceptance;
@ -232,8 +228,6 @@ static Money _cargo_feeder_share;
static const SaveLoad _station_speclist_desc[] = {
SLE_CONDVAR(StationSpecList, grfid, SLE_UINT32, SLV_27, SL_MAX_VERSION),
SLE_CONDVAR(StationSpecList, localidx, SLE_UINT8, SLV_27, SL_MAX_VERSION),
SLE_END()
};
CargoPacketList _packets;
@ -253,7 +247,6 @@ static const SaveLoad _flow_desc[] = {
SLE_VAR(FlowSaveLoad, via, SLE_UINT16),
SLE_VAR(FlowSaveLoad, share, SLE_UINT32),
SLE_CONDVAR(FlowSaveLoad, restricted, SLE_BOOL, SLV_187, SL_MAX_VERSION),
SLE_END()
};
#endif
@ -262,7 +255,7 @@ static const SaveLoad _flow_desc[] = {
* some of the variables itself are private.
* @return the saveload description for GoodsEntry.
*/
const SaveLoad *GetGoodsDesc()
SaveLoadTable GetGoodsDesc()
{
static const SaveLoad goods_desc[] = {
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_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_END()
};
return goods_desc;
@ -300,7 +292,6 @@ typedef std::pair<const StationID, CargoPacketList> StationCargoPair;
static const SaveLoad _cargo_list_desc[] = {
SLE_VAR(StationCargoPair, first, SLE_UINT16),
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, waiting_triggers, SLE_UINT8),
SLE_VAR(BaseStation, num_specs, SLE_UINT8),
SLE_END()
};
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_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_END()
};
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.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_END()
};
/**
* Get the base station description to be used for SL_ST_INCLUDE
* @return the base station description.
*/
const SaveLoad *GetBaseStationDescription()
SaveLoadTable GetBaseStationDescription()
{
return _base_station_desc;
}
@ -511,7 +496,7 @@ static void SetupDescs_ROADSTOP()
static void RealSave_STNN(BaseStation *bst)
{
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();
@ -520,7 +505,7 @@ static void RealSave_STNN(BaseStation *bst)
for (CargoID i = 0; i < NUM_CARGO; i++) {
_num_dests = (uint32)st->goods[i].cargo.Packets()->MapSize();
_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) {
uint32 sum_shares = 0;
FlowSaveLoad flow;
@ -563,7 +548,7 @@ static void RealSave_STNN(BaseStation *bst)
}
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;
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) {
Station *st = Station::From(bst);
@ -606,7 +591,7 @@ static void Load_STNN()
}
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;
if (SlXvIsFeaturePresent(XSLFI_FLOW_STAT_FLAGS)) {
for (uint32 j = 0; j < _num_flows; ++j) {
@ -684,7 +669,7 @@ static void Load_STNN()
/* Allocate speclist memory when loading a game */
bst->speclist = CallocT<StationSpecList>(bst->num_specs);
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();
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;
@ -707,7 +692,7 @@ static void Ptrs_STNN()
GoodsEntry *ge = &st->goods[i];
if (IsSavegameVersionBefore(SLV_183) && SlXvIsFeatureMissing(XSLFI_CHILLPP)) {
SwapPackets(ge);
SlObjectPtrOrNullFiltered(ge, _filtered_goods_desc.data());
SlObjectPtrOrNullFiltered(ge, _filtered_goods_desc);
SwapPackets(ge);
} else {
//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()) {
SlObjectPtrOrNullFiltered(wp, _filtered_waypoint_desc.data());
SlObjectPtrOrNullFiltered(wp, _filtered_waypoint_desc);
}
}
@ -729,7 +714,7 @@ static void Save_ROADSTOP()
SetupDescs_ROADSTOP();
for (RoadStop *rs : RoadStop::Iterate()) {
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) {
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();
for (RoadStop *rs : RoadStop::Iterate()) {
SlObjectPtrOrNullFiltered(rs, _filtered_roadstop_desc.data());
SlObjectPtrOrNullFiltered(rs, _filtered_roadstop_desc);
}
}

@ -18,7 +18,6 @@ static const SaveLoad _storage_desc[] = {
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, 256, SLV_EXTEND_PERSISTENT_STORAGE, SL_MAX_VERSION),
SLE_END()
};
/** Load persistent storage data. */

@ -34,7 +34,6 @@ static const SaveLoad _story_page_elements_desc[] = {
SLE_CONDVAR(StoryPageElement, type, SLE_UINT8, SLV_185, SL_MAX_VERSION),
SLE_VAR(StoryPageElement, referenced_id, SLE_UINT32),
SLE_STR(StoryPageElement, text, SLE_STR | SLF_ALLOW_CONTROL, 0),
SLE_END()
};
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_UINT8, SLV_185, SL_MAX_VERSION),
SLE_STR(StoryPage, title, SLE_STR | SLF_ALLOW_CONTROL, 0),
SLE_END()
};
static void Save_STORY_PAGE()

@ -25,7 +25,6 @@ static const SaveLoad _subsidies_desc[] = {
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_UINT16, SLV_5, SL_MAX_VERSION),
SLE_END()
};
static void Save_SUBS()

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

@ -9,7 +9,7 @@
#include "saveload.h"
const SaveLoad* GTD() {
const SaveLoadTable GTD() {
static const SaveLoad _template_veh_desc[] = {
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_JOKERPP)),
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[] = {
_template_veh_desc,
};
return _ret[0];
return _template_veh_desc;
}
static void Save_TMPLS()

@ -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(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_END()
};
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>, old_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[] = {
@ -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>, old_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[] = {
@ -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>, 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_END()
};
std::vector<SaveLoad> _filtered_town_desc;
@ -297,13 +289,13 @@ static void Load_HIDS()
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++) {
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++) {
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) {
Town *t = new (index) Town();
SlObjectLoadFiltered(t, _filtered_town_desc.data());
SlObjectLoadFiltered(t, _filtered_town_desc);
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)) {
for (int i = TE_BEGIN; i < NUM_TE; i++) {
@ -335,7 +327,7 @@ static void Load_TOWN()
}
} else {
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();
for (Town *t : Town::Iterate()) {
SlObjectPtrOrNullFiltered(t, _filtered_town_desc.data());
SlObjectPtrOrNullFiltered(t, _filtered_town_desc);
}
}

@ -16,7 +16,6 @@
static const SaveLoad _trace_restrict_mapping_desc[] = {
SLE_VAR(TraceRestrictMappingItem, program_id, SLE_UINT32),
SLE_END()
};
/**
@ -50,7 +49,6 @@ struct TraceRestrictProgramStub {
static const SaveLoad _trace_restrict_program_stub_desc[] = {
SLE_VAR(TraceRestrictProgramStub, length, SLE_UINT32),
SLE_END()
};
/**
@ -120,14 +118,12 @@ struct TraceRestrictSlotStub {
static const SaveLoad _trace_restrict_slot_stub_desc[] = {
SLE_VAR(TraceRestrictSlotStub, length, SLE_UINT32),
SLE_END()
};
static const SaveLoad _trace_restrict_slot_desc[] = {
SLE_VAR(TraceRestrictSlot, max_occupancy, SLE_UINT32),
SLE_SSTR(TraceRestrictSlot, name, SLF_ALLOW_CONTROL),
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_SSTR(TraceRestrictCounter, name, SLF_ALLOW_CONTROL),
SLE_VAR(TraceRestrictCounter, owner, SLE_UINT8),
SLE_END()
};
/**

@ -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, second.train_speed, SLE_UINT16),
SLE_VAR(SignalSpeedType, second.time_stamp, SLE_UINT64),
SLE_END()
};
static void Load_TSAS()

@ -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, height, SLE_UINT8, 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()

@ -616,7 +616,7 @@ static uint32 _old_ahead_separation;
* @param vt the vehicle type. Can be VEH_END for the common vehicle description data
* @return the saveload description
*/
const SaveLoad *GetVehicleDescription(VehicleType vt)
SaveLoadTable GetVehicleDescription(VehicleType vt)
{
/** Save and load of vehicles */
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(160, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)),
SLE_END()
};
static const SaveLoad _train_desc[] = {
SLE_WRITEBYTE(Vehicle, type),
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, 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_END()
};
static const SaveLoad _roadveh_desc[] = {
@ -833,8 +828,6 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
SLE_CONDNULL(2, SLV_6, SLV_131),
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_END()
};
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_CONDNULL(16, SLV_2, SLV_144), // old reserved space
SLE_END()
};
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_CONDNULL(13, SLV_2, SLV_144), // old reserved space
SLE_END()
};
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_CONDNULL(15, SLV_2, SLV_144), // old reserved space
SLE_END()
};
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_CONDNULL(16, SLV_2, SLV_144), // old reserved space
SLE_END()
};
static const SaveLoad * const _veh_descs[] = {
static const SaveLoadTable _veh_descs[] = {
_train_desc,
_roadveh_desc,
_ship_desc,
@ -981,9 +966,9 @@ static std::vector<SaveLoad> * const _filtered_veh_descs[] = {
&_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()
@ -1078,7 +1063,7 @@ static void Ptrs_VEHS()
}
}
const SaveLoad *GetOrderExtraInfoDescription();
const SaveLoadTable GetOrderExtraInfoDescription();
void Save_VEOX()
{
@ -1103,14 +1088,13 @@ void Load_VEOX()
}
}
const SaveLoad *GetVehicleSpeedRestrictionDescription()
const SaveLoadTable GetVehicleSpeedRestrictionDescription()
{
static const SaveLoad _vehicle_speed_restriction_desc[] = {
SLE_VAR(PendingSpeedRestrictionChange, distance, SLE_UINT16),
SLE_VAR(PendingSpeedRestrictionChange, new_speed, SLE_UINT16),
SLE_VAR(PendingSpeedRestrictionChange, prev_speed, SLE_UINT16),
SLE_VAR(PendingSpeedRestrictionChange, flags, SLE_UINT16),
SLE_END()
};
return _vehicle_speed_restriction_desc;
@ -1391,7 +1375,7 @@ void SlProcessVENC()
}
}
const SaveLoad *GetVehicleLookAheadDescription()
const SaveLoadTable GetVehicleLookAheadDescription()
{
static const SaveLoad _vehicle_look_ahead_desc[] = {
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, flags, SLE_UINT16),
SLE_VAR(TrainReservationLookAhead, speed_restriction, SLE_UINT16),
SLE_END()
};
return _vehicle_look_ahead_desc;
}
const SaveLoad *GetVehicleLookAheadItemDescription()
const SaveLoadTable GetVehicleLookAheadItemDescription()
{
static const SaveLoad _vehicle_look_ahead_item_desc[] = {
SLE_VAR(TrainReservationLookAheadItem, start, SLE_INT32),
@ -1416,18 +1399,16 @@ const SaveLoad *GetVehicleLookAheadItemDescription()
SLE_VAR(TrainReservationLookAheadItem, z_pos, SLE_INT16),
SLE_VAR(TrainReservationLookAheadItem, data_id, SLE_UINT16),
SLE_VAR(TrainReservationLookAheadItem, type, SLE_UINT8),
SLE_END()
};
return _vehicle_look_ahead_item_desc;
}
const SaveLoad *GetVehicleLookAheadCurveDescription()
const SaveLoadTable GetVehicleLookAheadCurveDescription()
{
static const SaveLoad _vehicle_look_ahead_curve_desc[] = {
SLE_VAR(TrainReservationLookAheadCurve, position, SLE_INT32),
SLE_VAR(TrainReservationLookAheadCurve, dir_diff, SLE_UINT8),
SLE_END()
};
return _vehicle_look_ahead_curve_desc;

@ -180,8 +180,6 @@ static const SaveLoad _old_waypoint_desc[] = {
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, owner, SLE_UINT8, SLV_101, SL_MAX_VERSION),
SLE_END()
};
static void Load_WAYP()

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

@ -260,7 +260,7 @@
/* 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)
@ -273,7 +273,7 @@
/* 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)
@ -288,7 +288,7 @@
{
EnforcePrecondition(false, money >= 0);
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)

@ -118,23 +118,18 @@ bool ScriptEventCompanyAskMerger::AcceptMerger()
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),
json(stredup(json))
json(json)
{
}
ScriptEventAdminPort::~ScriptEventAdminPort()
{
free(this->json);
}
#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; }
SQInteger ScriptEventAdminPort::GetObject(HSQUIRRELVM vm)
{
char *p = this->json;
const char *p = this->json.c_str();
if (this->ReadTable(vm, p) == nullptr) {
sq_pushnull(vm);
@ -144,9 +139,9 @@ SQInteger ScriptEventAdminPort::GetObject(HSQUIRRELVM vm)
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;
for (;;) {
@ -168,14 +163,14 @@ char *ScriptEventAdminPort::ReadString(HSQUIRRELVM vm, char *p)
p++;
}
*p = '\0';
sq_pushstring(vm, value, -1);
*p++ = '"';
size_t len = p - value;
sq_pushstring(vm, value, len);
p++; // Step past the end-of-string marker (")
return p;
}
char *ScriptEventAdminPort::ReadTable(HSQUIRRELVM vm, char *p)
const char *ScriptEventAdminPort::ReadTable(HSQUIRRELVM vm, const char *p)
{
sq_newtable(vm);
@ -218,7 +213,7 @@ char *ScriptEventAdminPort::ReadTable(HSQUIRRELVM vm, char *p)
return p;
}
char *ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, char *p)
const char *ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, const char *p)
{
SKIP_EMPTY(p);
@ -257,7 +252,7 @@ char *ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, char *p)
sq_newarray(vm, 0);
/* Empty array? */
char *p2 = p + 1;
const char *p2 = p + 1;
SKIP_EMPTY(p2);
if (*p2 == ']') {
p = p2 + 1;

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

@ -26,9 +26,7 @@
if (!IsValid(setting)) return -1;
const SettingDesc *sd = GetSettingFromName(setting);
void *ptr = GetVariableAddress(&_settings_game, &sd->save);
return (int32)ReadValue(ptr, sd->save.conv);
return sd->AsIntSetting()->Read(&_settings_game);
}
/* static */ bool ScriptGameSettings::SetValue(const char *setting, int value)
@ -39,7 +37,7 @@
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)

@ -118,7 +118,7 @@
{
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()

@ -287,7 +287,7 @@ ScriptObject::ActiveInstance::~ActiveInstance()
{
char buffer[64];
::GetString(buffer, string, lastof(buffer));
::str_validate(buffer, lastof(buffer), SVS_NONE);
::StrMakeValidInPlace(buffer, lastof(buffer), SVS_NONE);
return ::stredup(buffer);
}
@ -316,7 +316,7 @@ ScriptObject::ActiveInstance::~ActiveInstance()
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
* 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 */

@ -82,7 +82,7 @@ SQInteger ScriptText::_SetParam(int parameter, HSQUIRRELVM vm)
sq_getstring(vm, -1, &value);
this->params[parameter] = stredup(value);
ValidateString(this->params[parameter]);
StrMakeValidInPlace(this->params[parameter]);
break;
}
@ -157,7 +157,7 @@ SQInteger ScriptText::_set(HSQUIRRELVM vm)
if (sq_gettype(vm, 2) == OT_STRING) {
const SQChar *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;
k = atoi(key_string + 6);

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

@ -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. */
static const SaveLoad _script_byte[] = {
SLEG_VAR(_script_sl_byte, SLE_UINT8),
SLE_END()
};
/* static */ bool ScriptInstance::SaveObject(HSQUIRRELVM vm, SQInteger index, int max_depth, bool test)

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

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

@ -22,6 +22,7 @@
*/
#include "stdafx.h"
#include <array>
#include <limits>
#include "currency.h"
#include "screenshot.h"
@ -119,17 +120,6 @@ const SettingDesc *GetSettingDescription(uint index)
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.
*/
@ -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
{
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;
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 *ptr = GetVariableAddress(object, &this->save);
void *ptr = GetVariableAddress(object, this->save);
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
{
void *ptr = GetVariableAddress(object, &this->save);
void *ptr = GetVariableAddress(object, this->save);
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.
* Also ensure the string is valid after chopping of some bytes. */
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
{
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
{
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
{
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))) {
ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_ARRAY);
msg.SetDParamStr(0, this->name);
@ -1703,7 +1693,9 @@ static void PrepareOldDiffCustom()
*/
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 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;
}
for (uint i = 0; i < options_to_load; i++) {
const SettingDesc *sd = GetSettingDescription(i);
/* Skip deprecated options */
if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue;
int32 value = (int32)((i == 4 ? 1000 : 1) * _old_diff_custom[i]);
/* Iterate over all the old difficulty settings, and convert the list-value to the new setting. */
uint i = 0;
for (const auto &name : _old_diff_settings) {
if (has_no_town_council_tolerance && name == "town_council_tolerance") continue;
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);
}
}
@ -2177,20 +2179,75 @@ void IntSettingDesc::ChangeValue(const void *object, int32 newval) const
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).
* @param tile unused
* @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
* 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
* @see _settings
*/
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 (!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.
* @param tile unused
* @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
* 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
*/
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->IsIntSetting()) return CMD_ERROR;
@ -2244,45 +2303,7 @@ const char *GetCompanySettingNameByIndex(uint32 idx)
{
if (idx >= _company_settings.size()) return nullptr;
return GetCompanySettingDescription(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);
return _company_settings.begin()[idx]->name;
}
/**
@ -2297,7 +2318,7 @@ bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame)
const IntSettingDesc *setting = sd->AsIntSetting();
if ((setting->flags & SGF_PER_COMPANY) != 0) {
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) {
return false;
}
@ -2327,7 +2348,7 @@ bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame)
/* send non-company-based settings over the network */
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;
}
@ -2353,25 +2374,13 @@ void SyncCompanySettings()
{
const void *old_object = &Company::Get(_current_company)->settings;
const void *new_object = &_settings_client.company;
uint i = 0;
for (auto &sd : _company_settings) {
uint32 old_value = (uint32)sd->AsIntSetting()->Read(new_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);
i++;
if (old_value != new_value) NetworkSendCommand(0, 0, new_value, 0, CMD_CHANGE_COMPANY_SETTING, nullptr, sd->name, _local_company, 0);
}
}
/**
* 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.
* @param sd the setting to change.
@ -2419,42 +2428,11 @@ uint GetSettingIndexByFullName(const char *name)
return UINT32_MAX;
}
/**
* 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)
const SettingDesc *GetSettingFromFullName(const char *name)
{
/* First check all full names */
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;
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 (sd->name != nullptr && strcmp(sd->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;
}
@ -2581,7 +2559,7 @@ void IConsoleListSettings(const char *prefilter)
*/
static void LoadSettingsXref(const SettingDesc *osd, void *object) {
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);
// 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_to = osd->save.version_to;
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);
if (osd->xref.conv != nullptr) val = osd->xref.conv(val);
if (setting_xref->IsIntSetting()) {
@ -2612,14 +2590,14 @@ static void LoadSettings(const SettingTable &settings, void *object)
for (auto &osd : settings) {
if (osd->patx_name != nullptr) continue;
const SaveLoad *sld = &osd->save;
const SaveLoad &sld = osd->save;
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;
}
void *ptr = GetVariableAddress(object, sld);
if (!SlObjectMember(ptr, &osd->save)) continue;
if (!SlObjectMember(ptr, osd->save)) continue;
if (osd->IsIntSetting()) {
const IntSettingDesc *int_setting = osd->AsIntSetting();
int_setting->MakeValueValidAndWrite(object, int_setting->Read(object));
@ -2641,14 +2619,14 @@ static void SaveSettings(const SettingTable &settings, void *object)
for (auto &sd : settings) {
if (sd->patx_name != nullptr) continue;
if (sd->xref.target != nullptr) continue;
length += SlCalcObjMemberLength(object, &sd->save);
length += SlCalcObjMemberLength(object, sd->save);
}
SlSetLength(length);
for (auto &sd : settings) {
if (sd->patx_name != nullptr) continue;
void *ptr = GetVariableAddress(object, &sd->save);
SlObjectMember(ptr, &sd->save);
void *ptr = GetVariableAddress(object, sd->save);
SlObjectMember(ptr, sd->save);
}
}
@ -2708,7 +2686,6 @@ static const SaveLoad _settings_ext_load_desc[] = {
SLE_VAR(SettingsExtLoad, flags, SLE_UINT32),
SLE_STR(SettingsExtLoad, name, SLE_STRB, 256),
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_STR(SettingsExtSave, name, SLE_STR, 0),
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());
// found setting
const SettingDesc *setting = (*iter);
const SaveLoad *sld = &(setting->save);
const SaveLoad &sld = setting->save;
size_t read = SlGetBytesRead();
void *ptr = GetVariableAddress(object, sld);
SlObjectMember(ptr, sld);
@ -2799,7 +2775,7 @@ static void SaveSettingsPatx(const SettingTable &settings, void *object)
size_t length = 8;
for (auto &sd : settings) {
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;
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.setting_length = settings_to_add[i].setting_length;
SlObject(&current_setting, _settings_ext_save_desc);
void *ptr = GetVariableAddress(object, &desc->save);
SlObjectMember(ptr, &desc->save);
void *ptr = GetVariableAddress(object, desc->save);
SlObjectMember(ptr, desc->save);
}
}
@ -2903,7 +2879,7 @@ void LoadSettingsPlyx(bool skip)
if (setting != nullptr) {
// found setting
const SaveLoad *sld = &(setting->save);
const SaveLoad &sld = setting->save;
size_t read = SlGetBytesRead();
void *ptr = GetVariableAddress(&(c->settings), sld);
SlObjectMember(ptr, sld);
@ -2933,7 +2909,6 @@ void SaveSettingsPlyx()
SLE_VAR(SettingsExtSave, flags, SLE_UINT32),
SLE_STR(SettingsExtSave, name, SLE_STR, 0),
SLE_VAR(SettingsExtSave, setting_length, SLE_UINT32),
SLE_END()
};
std::vector<uint32> company_setting_counts;
@ -2947,7 +2922,7 @@ void SaveSettingsPlyx()
uint32 setting_count = 0;
for (auto &sd : _company_settings) {
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;
current_setting.name = sd->patx_name;
@ -2978,15 +2953,15 @@ void SaveSettingsPlyx()
for (auto &sd : _company_settings) {
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;
current_setting.flags = 0;
current_setting.name = sd->patx_name;
current_setting.setting_length = setting_length;
SlObject(&current_setting, _settings_plyx_desc);
void *ptr = GetVariableAddress(&(c->settings), &sd->save);
SlObjectMember(ptr, &sd->save);
void *ptr = GetVariableAddress(&(c->settings), sd->save);
SlObjectMember(ptr, sd->save);
}
}
}

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

@ -348,9 +348,8 @@ struct XrefSettingDesc : SettingDesc {
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 StringSettingDesc *sd, const std::string value, bool force_newgame = false);
uint GetSettingIndex(const SettingDesc *sd);
#endif /* SETTINGS_INTERNAL_H */

@ -61,6 +61,9 @@ enum IndustryDensity {
/** Settings related to the difficulty of the game */
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 number_towns; ///< the amount of towns
byte industry_density; ///< The industry density. @see IndustryDensity

@ -216,7 +216,7 @@ const char *str_fix_scc_encoded(char *str, const char *last)
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. */
@ -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,
* replaces them with a question mark '?' (if not ignored)
* @param str the string to validate
* @param last the last valid character of str
* @param settings the settings for the string validation.
* Scans the string for invalid characters and replaces then with a
* question mark '?' (if not ignored).
* @param str The string to validate.
* @param last The last valid character of str.
* @param settings The settings for the string validation.
* @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;
str_validate(dst, str, last, settings);
StrMakeValidInPlace(dst, str, last, settings);
*dst = '\0';
return dst;
}
/**
* Scans the string for valid characters and if it finds invalid ones,
* replaces them with a question mark '?' (if not ignored)
* @param str the string to validate
* @param settings the settings for the string validation.
* Scans the string for invalid characters and replaces then with a
* question mark '?' (if not ignored).
* Only use this function when you are sure the string ends with a '\0';
* 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 last = buf + str.size();
std::ostringstream dst;
std::ostreambuf_iterator<char> dst_iter(dst);
str_validate(dst_iter, buf, last, settings);
StrMakeValidInPlace(dst_iter, buf, last, settings);
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
* valid (printable) characters and is properly terminated.
@ -496,6 +497,16 @@ size_t Utf8StringLength(const char *s)
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.

@ -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 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);
[[nodiscard]] std::string str_validate(const std::string &str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK);
void ValidateString(const char *str);
char *StrMakeValidInPlace(char *str, const char *last, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK) NOACCESS(2);
[[nodiscard]] std::string StrMakeValid(const std::string &str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK);
void StrMakeValidInPlace(char *str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK);
const char *str_fix_scc_encoded(char *str, const char *last) NOACCESS(2);
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 std::string &str);
/**
* Is the given character a lead surrogate code point?

@ -11,11 +11,11 @@
#include "string_func.h"
#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;
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>

@ -1,50 +1,4 @@
set(GENERATED_BINARY_DIR ${CMAKE_BINARY_DIR}/generated)
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_subdirectory(settings)
add_files(
airport_defaults.h

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

Loading…
Cancel
Save