1
0
mirror of https://github.com/OpenTTD/OpenTTD.git synced 2025-08-26 07:59:09 +00:00

Compare commits

..

4 Commits

11 changed files with 55 additions and 77 deletions

View File

@@ -4559,7 +4559,14 @@ STR_ORDER_DROP_GO_ALWAYS_DEPOT :Always go
STR_ORDER_DROP_SERVICE_DEPOT :Service if needed STR_ORDER_DROP_SERVICE_DEPOT :Service if needed
STR_ORDER_DROP_HALT_DEPOT :Stop STR_ORDER_DROP_HALT_DEPOT :Stop
STR_ORDER_DROP_UNBUNCH :Unbunch STR_ORDER_DROP_UNBUNCH :Unbunch
STR_ORDER_DEPOT_ACTION_TOOLTIP :{BLACK}Select the action to take at this depot
# Depot action tooltips, one per vehicle type
###length VEHICLE_TYPES
STR_ORDER_TRAIN_DEPOT_ACTION_TOOLTIP :{BLACK}Select the action to take at this depot
STR_ORDER_ROAD_DEPOT_ACTION_TOOLTIP :{BLACK}Select the action to take at this depot
STR_ORDER_SHIP_DEPOT_ACTION_TOOLTIP :{BLACK}Select the action to take at this depot
STR_ORDER_HANGAR_ACTION_TOOLTIP :{BLACK}Select the action to take at this hangar
###next-name-looks-similar
STR_ORDER_CONDITIONAL_VARIABLE_TOOLTIP :{BLACK}Vehicle data to base jumping on STR_ORDER_CONDITIONAL_VARIABLE_TOOLTIP :{BLACK}Vehicle data to base jumping on
@@ -5105,7 +5112,6 @@ STR_ERROR_UNBUNCHING_NO_FULL_LOAD :{WHITE}... cann
STR_ERROR_UNBUNCHING_NO_UNBUNCHING_FULL_LOAD :{WHITE}... cannot unbunch a vehicle with a full load order STR_ERROR_UNBUNCHING_NO_UNBUNCHING_FULL_LOAD :{WHITE}... cannot unbunch a vehicle with a full load order
STR_ERROR_UNBUNCHING_NO_CONDITIONAL :{WHITE}... cannot use conditional orders when vehicle has an unbunching order STR_ERROR_UNBUNCHING_NO_CONDITIONAL :{WHITE}... cannot use conditional orders when vehicle has an unbunching order
STR_ERROR_UNBUNCHING_NO_UNBUNCHING_CONDITIONAL :{WHITE}... cannot unbunch a vehicle with a conditional order STR_ERROR_UNBUNCHING_NO_UNBUNCHING_CONDITIONAL :{WHITE}... cannot unbunch a vehicle with a conditional order
STR_ERROR_UNBUNCHING_NO_SERVICE_IF_NEEDED :{WHITE}... vehicle must always visit the depot to unbunch there
# Autoreplace related errors # Autoreplace related errors
STR_ERROR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}{VEHICLE} is too long after replacement STR_ERROR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}{VEHICLE} is too long after replacement

View File

@@ -155,7 +155,6 @@ ClientNetworkGameSocketHandler::~ClientNetworkGameSocketHandler()
assert(ClientNetworkGameSocketHandler::my_client == this); assert(ClientNetworkGameSocketHandler::my_client == this);
ClientNetworkGameSocketHandler::my_client = nullptr; ClientNetworkGameSocketHandler::my_client = nullptr;
delete this->savegame;
delete this->GetInfo(); delete this->GetInfo();
} }
@@ -567,7 +566,7 @@ bool ClientNetworkGameSocketHandler::IsConnected()
* DEF_CLIENT_RECEIVE_COMMAND has parameter: Packet *p * DEF_CLIENT_RECEIVE_COMMAND has parameter: Packet *p
************/ ************/
extern bool SafeLoad(const std::string &filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf = nullptr); extern bool SafeLoad(const std::string &filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, std::shared_ptr<struct LoadFilter> lf);
NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_FULL(Packet *) NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_FULL(Packet *)
{ {
@@ -810,7 +809,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_BEGIN(Packe
if (this->savegame != nullptr) return NETWORK_RECV_STATUS_MALFORMED_PACKET; if (this->savegame != nullptr) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
this->savegame = new PacketReader(); this->savegame = std::make_shared<PacketReader>();
_frame_counter = _frame_counter_server = _frame_counter_max = p->Recv_uint32(); _frame_counter = _frame_counter_server = _frame_counter_max = p->Recv_uint32();
@@ -864,20 +863,12 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DONE(Packet
_network_join_status = NETWORK_JOIN_STATUS_PROCESSING; _network_join_status = NETWORK_JOIN_STATUS_PROCESSING;
SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN); SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
/* this->savegame->Reset();
* Make sure everything is set for reading.
*
* We need the local copy and reset this->savegame because when
* loading fails the network gets reset upon loading the intro
* game, which would cause us to free this->savegame twice.
*/
LoadFilter *lf = this->savegame;
this->savegame = nullptr;
lf->Reset();
/* The map is done downloading, load it */ /* The map is done downloading, load it */
ClearErrorMessages(); ClearErrorMessages();
bool load_success = SafeLoad({}, SLO_LOAD, DFT_GAME_FILE, GM_NORMAL, NO_DIRECTORY, lf); bool load_success = SafeLoad({}, SLO_LOAD, DFT_GAME_FILE, GM_NORMAL, NO_DIRECTORY, this->savegame);
this->savegame = nullptr;
/* Long savegame loads shouldn't affect the lag calculation! */ /* Long savegame loads shouldn't affect the lag calculation! */
this->last_packet = std::chrono::steady_clock::now(); this->last_packet = std::chrono::steady_clock::now();

View File

@@ -16,7 +16,7 @@
class ClientNetworkGameSocketHandler : public ZeroedMemoryAllocator, public NetworkGameSocketHandler { class ClientNetworkGameSocketHandler : public ZeroedMemoryAllocator, public NetworkGameSocketHandler {
private: private:
std::string connection_string; ///< Address we are connected to. std::string connection_string; ///< Address we are connected to.
struct PacketReader *savegame; ///< Packet reader for reading the savegame. std::shared_ptr<struct PacketReader> savegame; ///< Packet reader for reading the savegame.
byte token; ///< The token we need to send back to the server to prove we're the right client. byte token; ///< The token we need to send back to the server to prove we're the right client.
/** Status of the connection with the server. */ /** Status of the connection with the server. */

View File

@@ -576,7 +576,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap()
Debug(net, 9, "client[{}] SendMap(): first_packet", this->client_id); Debug(net, 9, "client[{}] SendMap(): first_packet", this->client_id);
WaitTillSaved(); WaitTillSaved();
this->savegame = new PacketWriter(this); this->savegame = std::make_shared<PacketWriter>(this);
/* Now send the _frame_counter and how many packets are coming */ /* Now send the _frame_counter and how many packets are coming */
Packet *p = new Packet(PACKET_SERVER_MAP_BEGIN); Packet *p = new Packet(PACKET_SERVER_MAP_BEGIN);

View File

@@ -69,7 +69,7 @@ public:
CommandQueue outgoing_queue; ///< The command-queue awaiting delivery CommandQueue outgoing_queue; ///< The command-queue awaiting delivery
size_t receive_limit; ///< Amount of bytes that we can receive at this moment size_t receive_limit; ///< Amount of bytes that we can receive at this moment
struct PacketWriter *savegame; ///< Writer used to write the savegame. std::shared_ptr<struct PacketWriter> savegame; ///< Writer used to write the savegame.
NetworkAddress client_address; ///< IP-address of the client (so they can be banned) NetworkAddress client_address; ///< IP-address of the client (so they can be banned)
ServerNetworkGameSocketHandler(SOCKET s); ServerNetworkGameSocketHandler(SOCKET s);

View File

@@ -966,7 +966,7 @@ static void MakeNewEditorWorld()
* @param subdir default directory to look for filename, set to 0 if not needed * @param subdir default directory to look for filename, set to 0 if not needed
* @param lf Load filter to use, if nullptr: use filename + subdir. * @param lf Load filter to use, if nullptr: use filename + subdir.
*/ */
bool SafeLoad(const std::string &filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf = nullptr) bool SafeLoad(const std::string &filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, std::shared_ptr<LoadFilter> lf = nullptr)
{ {
assert(fop == SLO_LOAD); assert(fop == SLO_LOAD);
assert(dft == DFT_GAME_FILE || (lf == nullptr && dft == DFT_OLD_GAME_FILE)); assert(dft == DFT_GAME_FILE || (lf == nullptr && dft == DFT_OLD_GAME_FILE));

View File

@@ -1300,9 +1300,6 @@ CommandCost CmdModifyOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID se
case MOF_DEPOT_ACTION: case MOF_DEPOT_ACTION:
if (data >= DA_END) return CMD_ERROR; if (data >= DA_END) return CMD_ERROR;
/* The vehicle must always go to the depot (not just if it needs servicing) in order to unbunch there. */
if ((data == DA_SERVICE) && (order->GetDepotActionType() & ODATFB_UNBUNCH)) return_cmd_error(STR_ERROR_UNBUNCHING_NO_SERVICE_IF_NEEDED);
/* Check if we are allowed to add unbunching. We are always allowed to remove it. */ /* Check if we are allowed to add unbunching. We are always allowed to remove it. */
if (data == DA_UNBUNCH) { if (data == DA_UNBUNCH) {
/* Only one unbunching order is allowed in a vehicle's orders. If this order already has an unbunching action, no error is needed. */ /* Only one unbunching order is allowed in a vehicle's orders. If this order already has an unbunching action, no error is needed. */
@@ -1312,8 +1309,6 @@ CommandCost CmdModifyOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID se
if (o->IsType(OT_CONDITIONAL)) return_cmd_error(STR_ERROR_UNBUNCHING_NO_UNBUNCHING_CONDITIONAL); if (o->IsType(OT_CONDITIONAL)) return_cmd_error(STR_ERROR_UNBUNCHING_NO_UNBUNCHING_CONDITIONAL);
/* We don't allow unbunching if the vehicle has a full load order. */ /* We don't allow unbunching if the vehicle has a full load order. */
if (o->IsType(OT_GOTO_STATION) && o->GetLoadType() & (OLFB_FULL_LOAD | OLF_FULL_LOAD_ANY)) return_cmd_error(STR_ERROR_UNBUNCHING_NO_UNBUNCHING_FULL_LOAD); if (o->IsType(OT_GOTO_STATION) && o->GetLoadType() & (OLFB_FULL_LOAD | OLF_FULL_LOAD_ANY)) return_cmd_error(STR_ERROR_UNBUNCHING_NO_UNBUNCHING_FULL_LOAD);
/* The vehicle must always go to the depot (not just if it needs servicing) in order to unbunch there. */
if (o->IsType(OT_GOTO_DEPOT) && o->GetDepotOrderType() & ODTFB_SERVICE) return_cmd_error(STR_ERROR_UNBUNCHING_NO_SERVICE_IF_NEEDED);
} }
} }
break; break;

View File

@@ -785,6 +785,7 @@ public:
this->CreateNestedTree(); this->CreateNestedTree();
this->vscroll = this->GetScrollbar(WID_O_SCROLLBAR); this->vscroll = this->GetScrollbar(WID_O_SCROLLBAR);
this->GetWidget<NWidgetCore>(WID_O_DEPOT_ACTION)->tool_tip = STR_ORDER_TRAIN_DEPOT_ACTION_TOOLTIP + v->type;
this->FinishInitNested(v->index); this->FinishInitNested(v->index);
this->selected_order = -1; this->selected_order = -1;
@@ -1614,7 +1615,7 @@ static constexpr NWidgetPart _nested_orders_train_widgets[] = {
NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_UNLOAD), SetMinimalSize(93, 12), SetFill(1, 0), NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_UNLOAD), SetMinimalSize(93, 12), SetFill(1, 0),
SetDataTip(STR_ORDER_TOGGLE_UNLOAD, STR_ORDER_TOOLTIP_UNLOAD), SetResize(1, 0), SetDataTip(STR_ORDER_TOGGLE_UNLOAD, STR_ORDER_TOOLTIP_UNLOAD), SetResize(1, 0),
NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_DEPOT_ACTION), SetMinimalSize(93, 12), SetFill(1, 0), NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_DEPOT_ACTION), SetMinimalSize(93, 12), SetFill(1, 0),
SetDataTip(STR_JUST_STRING, STR_ORDER_DEPOT_ACTION_TOOLTIP), SetResize(1, 0), SetDataTip(STR_JUST_STRING, STR_NULL), SetResize(1, 0),
EndContainer(), EndContainer(),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_TOP_RIGHT), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_TOP_RIGHT),
NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(93, 12), SetFill(1, 0), SetResize(1, 0), EndContainer(), NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(93, 12), SetFill(1, 0), SetResize(1, 0), EndContainer(),
@@ -1692,7 +1693,7 @@ static constexpr NWidgetPart _nested_orders_widgets[] = {
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_REFIT), SetMinimalSize(186, 12), SetFill(1, 0), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_REFIT), SetMinimalSize(186, 12), SetFill(1, 0),
SetDataTip(STR_ORDER_REFIT, STR_ORDER_REFIT_TOOLTIP), SetResize(1, 0), SetDataTip(STR_ORDER_REFIT, STR_ORDER_REFIT_TOOLTIP), SetResize(1, 0),
NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_DEPOT_ACTION), SetMinimalSize(124, 12), SetFill(1, 0), NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_DEPOT_ACTION), SetMinimalSize(124, 12), SetFill(1, 0),
SetDataTip(STR_JUST_STRING, STR_ORDER_DEPOT_ACTION_TOOLTIP), SetResize(1, 0), SetDataTip(STR_JUST_STRING, STR_NULL), SetResize(1, 0),
EndContainer(), EndContainer(),
/* Buttons for setting a condition. */ /* Buttons for setting a condition. */

View File

@@ -88,14 +88,14 @@ struct ReadBuffer {
byte buf[MEMORY_CHUNK_SIZE]; ///< Buffer we're going to read from. byte buf[MEMORY_CHUNK_SIZE]; ///< Buffer we're going to read from.
byte *bufp; ///< Location we're at reading the buffer. byte *bufp; ///< Location we're at reading the buffer.
byte *bufe; ///< End of the buffer we can read from. byte *bufe; ///< End of the buffer we can read from.
LoadFilter *reader; ///< The filter used to actually read. std::shared_ptr<LoadFilter> reader; ///< The filter used to actually read.
size_t read; ///< The amount of read bytes so far from the filter. size_t read; ///< The amount of read bytes so far from the filter.
/** /**
* Initialise our variables. * Initialise our variables.
* @param reader The filter to actually read data. * @param reader The filter to actually read data.
*/ */
ReadBuffer(LoadFilter *reader) : bufp(nullptr), bufe(nullptr), reader(reader), read(0) ReadBuffer(std::shared_ptr<LoadFilter> reader) : bufp(nullptr), bufe(nullptr), reader(reader), read(0)
{ {
} }
@@ -162,7 +162,7 @@ struct MemoryDumper {
* Flush this dumper into a writer. * Flush this dumper into a writer.
* @param writer The filter we want to use. * @param writer The filter we want to use.
*/ */
void Flush(SaveFilter *writer) void Flush(std::shared_ptr<SaveFilter> writer)
{ {
uint i = 0; uint i = 0;
size_t t = this->GetSize(); size_t t = this->GetSize();
@@ -198,11 +198,11 @@ struct SaveLoadParams {
int array_index, last_array_index; ///< in the case of an array, the current and last positions int array_index, last_array_index; ///< in the case of an array, the current and last positions
bool expect_table_header; ///< In the case of a table, if the header is saved/loaded. bool expect_table_header; ///< In the case of a table, if the header is saved/loaded.
MemoryDumper *dumper; ///< Memory dumper to write the savegame to. std::unique_ptr<MemoryDumper> dumper; ///< Memory dumper to write the savegame to.
SaveFilter *sf; ///< Filter to write the savegame to. std::shared_ptr<SaveFilter> sf; ///< Filter to write the savegame to.
ReadBuffer *reader; ///< Savegame reading buffer. std::unique_ptr<ReadBuffer> reader; ///< Savegame reading buffer.
LoadFilter *lf; ///< Filter to read the savegame from. std::shared_ptr<LoadFilter> lf; ///< Filter to read the savegame from.
StringID error_str; ///< the translatable error message to show StringID error_str; ///< the translatable error message to show
std::string extra_msg; ///< the error message std::string extra_msg; ///< the error message
@@ -2175,9 +2175,6 @@ struct FileReader : LoadFilter {
{ {
if (this->file != nullptr) fclose(this->file); if (this->file != nullptr) fclose(this->file);
this->file = nullptr; this->file = nullptr;
/* Make sure we don't double free. */
_sl.sf = nullptr;
} }
size_t Read(byte *buf, size_t size) override size_t Read(byte *buf, size_t size) override
@@ -2213,9 +2210,6 @@ struct FileWriter : SaveFilter {
~FileWriter() ~FileWriter()
{ {
this->Finish(); this->Finish();
/* Make sure we don't double free. */
_sl.sf = nullptr;
} }
void Write(byte *buf, size_t size) override void Write(byte *buf, size_t size) override
@@ -2249,7 +2243,7 @@ struct LZOLoadFilter : LoadFilter {
* Initialise this filter. * Initialise this filter.
* @param chain The next filter in this chain. * @param chain The next filter in this chain.
*/ */
LZOLoadFilter(LoadFilter *chain) : LoadFilter(chain) LZOLoadFilter(std::shared_ptr<LoadFilter> chain) : LoadFilter(chain)
{ {
if (lzo_init() != LZO_E_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize decompressor"); if (lzo_init() != LZO_E_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize decompressor");
} }
@@ -2296,7 +2290,7 @@ struct LZOSaveFilter : SaveFilter {
* Initialise this filter. * Initialise this filter.
* @param chain The next filter in this chain. * @param chain The next filter in this chain.
*/ */
LZOSaveFilter(SaveFilter *chain, byte) : SaveFilter(chain) LZOSaveFilter(std::shared_ptr<SaveFilter> chain, byte) : SaveFilter(chain)
{ {
if (lzo_init() != LZO_E_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor"); if (lzo_init() != LZO_E_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor");
} }
@@ -2336,7 +2330,7 @@ struct NoCompLoadFilter : LoadFilter {
* Initialise this filter. * Initialise this filter.
* @param chain The next filter in this chain. * @param chain The next filter in this chain.
*/ */
NoCompLoadFilter(LoadFilter *chain) : LoadFilter(chain) NoCompLoadFilter(std::shared_ptr<LoadFilter> chain) : LoadFilter(chain)
{ {
} }
@@ -2352,7 +2346,7 @@ struct NoCompSaveFilter : SaveFilter {
* Initialise this filter. * Initialise this filter.
* @param chain The next filter in this chain. * @param chain The next filter in this chain.
*/ */
NoCompSaveFilter(SaveFilter *chain, byte) : SaveFilter(chain) NoCompSaveFilter(std::shared_ptr<SaveFilter> chain, byte) : SaveFilter(chain)
{ {
} }
@@ -2378,7 +2372,7 @@ struct ZlibLoadFilter : LoadFilter {
* Initialise this filter. * Initialise this filter.
* @param chain The next filter in this chain. * @param chain The next filter in this chain.
*/ */
ZlibLoadFilter(LoadFilter *chain) : LoadFilter(chain) ZlibLoadFilter(std::shared_ptr<LoadFilter> chain) : LoadFilter(chain)
{ {
memset(&this->z, 0, sizeof(this->z)); memset(&this->z, 0, sizeof(this->z));
if (inflateInit(&this->z) != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize decompressor"); if (inflateInit(&this->z) != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize decompressor");
@@ -2423,7 +2417,7 @@ struct ZlibSaveFilter : SaveFilter {
* @param chain The next filter in this chain. * @param chain The next filter in this chain.
* @param compression_level The requested level of compression. * @param compression_level The requested level of compression.
*/ */
ZlibSaveFilter(SaveFilter *chain, byte compression_level) : SaveFilter(chain) ZlibSaveFilter(std::shared_ptr<SaveFilter> chain, byte compression_level) : SaveFilter(chain)
{ {
memset(&this->z, 0, sizeof(this->z)); memset(&this->z, 0, sizeof(this->z));
if (deflateInit(&this->z, compression_level) != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor"); if (deflateInit(&this->z, compression_level) != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor");
@@ -2507,7 +2501,7 @@ struct LZMALoadFilter : LoadFilter {
* Initialise this filter. * Initialise this filter.
* @param chain The next filter in this chain. * @param chain The next filter in this chain.
*/ */
LZMALoadFilter(LoadFilter *chain) : LoadFilter(chain), lzma(_lzma_init) LZMALoadFilter(std::shared_ptr<LoadFilter> chain) : LoadFilter(chain), lzma(_lzma_init)
{ {
/* Allow saves up to 256 MB uncompressed */ /* Allow saves up to 256 MB uncompressed */
if (lzma_auto_decoder(&this->lzma, 1 << 28, 0) != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize decompressor"); if (lzma_auto_decoder(&this->lzma, 1 << 28, 0) != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize decompressor");
@@ -2551,7 +2545,7 @@ struct LZMASaveFilter : SaveFilter {
* @param chain The next filter in this chain. * @param chain The next filter in this chain.
* @param compression_level The requested level of compression. * @param compression_level The requested level of compression.
*/ */
LZMASaveFilter(SaveFilter *chain, byte compression_level) : SaveFilter(chain), lzma(_lzma_init) LZMASaveFilter(std::shared_ptr<SaveFilter> chain, byte compression_level) : SaveFilter(chain), lzma(_lzma_init)
{ {
if (lzma_easy_encoder(&this->lzma, compression_level, LZMA_CHECK_CRC32) != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor"); if (lzma_easy_encoder(&this->lzma, compression_level, LZMA_CHECK_CRC32) != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor");
} }
@@ -2611,8 +2605,8 @@ struct SaveLoadFormat {
const char *name; ///< name of the compressor/decompressor (debug-only) const char *name; ///< name of the compressor/decompressor (debug-only)
uint32_t tag; ///< the 4-letter tag by which it is identified in the savegame uint32_t tag; ///< the 4-letter tag by which it is identified in the savegame
LoadFilter *(*init_load)(LoadFilter *chain); ///< Constructor for the load filter. std::shared_ptr<LoadFilter> (*init_load)(std::shared_ptr<LoadFilter> chain); ///< Constructor for the load filter.
SaveFilter *(*init_write)(SaveFilter *chain, byte compression); ///< Constructor for the save filter. std::shared_ptr<SaveFilter> (*init_write)(std::shared_ptr<SaveFilter> chain, byte compression); ///< Constructor for the save filter.
byte min_compression; ///< the minimum compression level of this format byte min_compression; ///< the minimum compression level of this format
byte default_compression; ///< the default compression level of this format byte default_compression; ///< the default compression level of this format
@@ -2717,16 +2711,9 @@ static void ResetSaveloadData()
*/ */
static inline void ClearSaveLoadState() static inline void ClearSaveLoadState()
{ {
delete _sl.dumper;
_sl.dumper = nullptr; _sl.dumper = nullptr;
delete _sl.sf;
_sl.sf = nullptr; _sl.sf = nullptr;
delete _sl.reader;
_sl.reader = nullptr; _sl.reader = nullptr;
delete _sl.lf;
_sl.lf = nullptr; _sl.lf = nullptr;
} }
@@ -2839,11 +2826,11 @@ void WaitTillSaved()
* @param threaded Whether to try to perform the saving asynchronously. * @param threaded Whether to try to perform the saving asynchronously.
* @return Return the result of the action. #SL_OK or #SL_ERROR * @return Return the result of the action. #SL_OK or #SL_ERROR
*/ */
static SaveOrLoadResult DoSave(SaveFilter *writer, bool threaded) static SaveOrLoadResult DoSave(std::shared_ptr<SaveFilter> writer, bool threaded)
{ {
assert(!_sl.saveinprogress); assert(!_sl.saveinprogress);
_sl.dumper = new MemoryDumper(); _sl.dumper = std::make_unique<MemoryDumper>();
_sl.sf = writer; _sl.sf = writer;
_sl_version = SAVEGAME_VERSION; _sl_version = SAVEGAME_VERSION;
@@ -2871,7 +2858,7 @@ static SaveOrLoadResult DoSave(SaveFilter *writer, bool threaded)
* @param threaded Whether to try to perform the saving asynchronously. * @param threaded Whether to try to perform the saving asynchronously.
* @return Return the result of the action. #SL_OK or #SL_ERROR * @return Return the result of the action. #SL_OK or #SL_ERROR
*/ */
SaveOrLoadResult SaveWithFilter(SaveFilter *writer, bool threaded) SaveOrLoadResult SaveWithFilter(std::shared_ptr<SaveFilter> writer, bool threaded)
{ {
try { try {
_sl.action = SLA_SAVE; _sl.action = SLA_SAVE;
@@ -2888,7 +2875,7 @@ SaveOrLoadResult SaveWithFilter(SaveFilter *writer, bool threaded)
* @param load_check Whether to perform the checking ("preview") or actually load the game. * @param load_check Whether to perform the checking ("preview") or actually load the game.
* @return Return the result of the action. #SL_OK or #SL_REINIT ("unload" the game) * @return Return the result of the action. #SL_OK or #SL_REINIT ("unload" the game)
*/ */
static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check) static SaveOrLoadResult DoLoad(std::shared_ptr<LoadFilter> reader, bool load_check)
{ {
_sl.lf = reader; _sl.lf = reader;
@@ -2950,7 +2937,7 @@ static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check)
} }
_sl.lf = fmt->init_load(_sl.lf); _sl.lf = fmt->init_load(_sl.lf);
_sl.reader = new ReadBuffer(_sl.lf); _sl.reader = std::make_unique<ReadBuffer>(_sl.lf);
_next_offs = 0; _next_offs = 0;
if (!load_check) { if (!load_check) {
@@ -3027,7 +3014,7 @@ static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check)
* @param reader The filter to read the savegame from. * @param reader The filter to read the savegame from.
* @return Return the result of the action. #SL_OK or #SL_REINIT ("unload" the game) * @return Return the result of the action. #SL_OK or #SL_REINIT ("unload" the game)
*/ */
SaveOrLoadResult LoadWithFilter(LoadFilter *reader) SaveOrLoadResult LoadWithFilter(std::shared_ptr<LoadFilter> reader)
{ {
try { try {
_sl.action = SLA_LOAD; _sl.action = SLA_LOAD;
@@ -3114,13 +3101,13 @@ SaveOrLoadResult SaveOrLoad(const std::string &filename, SaveLoadOperation fop,
Debug(desync, 1, "save: {:08x}; {:02x}; {}", TimerGameEconomy::date, TimerGameEconomy::date_fract, filename); Debug(desync, 1, "save: {:08x}; {:02x}; {}", TimerGameEconomy::date, TimerGameEconomy::date_fract, filename);
if (!_settings_client.gui.threaded_saves) threaded = false; if (!_settings_client.gui.threaded_saves) threaded = false;
return DoSave(new FileWriter(fh), threaded); return DoSave(std::make_shared<FileWriter>(fh), threaded);
} }
/* LOAD game */ /* LOAD game */
assert(fop == SLO_LOAD || fop == SLO_CHECK); assert(fop == SLO_LOAD || fop == SLO_CHECK);
Debug(desync, 1, "load: {}", filename); Debug(desync, 1, "load: {}", filename);
return DoLoad(new FileReader(fh), fop == SLO_CHECK); return DoLoad(std::make_shared<FileReader>(fh), fop == SLO_CHECK);
} catch (...) { } catch (...) {
/* This code may be executed both for old and new save games. */ /* This code may be executed both for old and new save games. */
ClearSaveLoadState(); ClearSaveLoadState();

View File

@@ -421,8 +421,8 @@ void DoExitSave();
void DoAutoOrNetsave(FiosNumberedSaveName &counter); void DoAutoOrNetsave(FiosNumberedSaveName &counter);
SaveOrLoadResult SaveWithFilter(struct SaveFilter *writer, bool threaded); SaveOrLoadResult SaveWithFilter(std::shared_ptr<struct SaveFilter> writer, bool threaded);
SaveOrLoadResult LoadWithFilter(struct LoadFilter *reader); SaveOrLoadResult LoadWithFilter(std::shared_ptr<struct LoadFilter> reader);
typedef void AutolengthProc(void *arg); typedef void AutolengthProc(void *arg);

View File

@@ -13,20 +13,19 @@
/** Interface for filtering a savegame till it is loaded. */ /** Interface for filtering a savegame till it is loaded. */
struct LoadFilter { struct LoadFilter {
/** Chained to the (savegame) filters. */ /** Chained to the (savegame) filters. */
LoadFilter *chain; std::shared_ptr<LoadFilter> chain;
/** /**
* Initialise this filter. * Initialise this filter.
* @param chain The next filter in this chain. * @param chain The next filter in this chain.
*/ */
LoadFilter(LoadFilter *chain) : chain(chain) LoadFilter(std::shared_ptr<LoadFilter> chain) : chain(chain)
{ {
} }
/** Make sure the writers are properly closed. */ /** Make sure the writers are properly closed. */
virtual ~LoadFilter() virtual ~LoadFilter()
{ {
delete this->chain;
} }
/** /**
@@ -51,28 +50,27 @@ struct LoadFilter {
* @param chain The next filter in this chain. * @param chain The next filter in this chain.
* @tparam T The type of load filter to create. * @tparam T The type of load filter to create.
*/ */
template <typename T> LoadFilter *CreateLoadFilter(LoadFilter *chain) template <typename T> std::shared_ptr<LoadFilter> CreateLoadFilter(std::shared_ptr<LoadFilter> chain)
{ {
return new T(chain); return std::make_shared<T>(chain);
} }
/** Interface for filtering a savegame till it is written. */ /** Interface for filtering a savegame till it is written. */
struct SaveFilter { struct SaveFilter {
/** Chained to the (savegame) filters. */ /** Chained to the (savegame) filters. */
SaveFilter *chain; std::shared_ptr<SaveFilter> chain;
/** /**
* Initialise this filter. * Initialise this filter.
* @param chain The next filter in this chain. * @param chain The next filter in this chain.
*/ */
SaveFilter(SaveFilter *chain) : chain(chain) SaveFilter(std::shared_ptr<SaveFilter> chain) : chain(chain)
{ {
} }
/** Make sure the writers are properly closed. */ /** Make sure the writers are properly closed. */
virtual ~SaveFilter() virtual ~SaveFilter()
{ {
delete this->chain;
} }
/** /**
@@ -97,9 +95,9 @@ struct SaveFilter {
* @param compression_level The requested level of compression. * @param compression_level The requested level of compression.
* @tparam T The type of save filter to create. * @tparam T The type of save filter to create.
*/ */
template <typename T> SaveFilter *CreateSaveFilter(SaveFilter *chain, byte compression_level) template <typename T> std::shared_ptr<SaveFilter> CreateSaveFilter(std::shared_ptr<SaveFilter> chain, byte compression_level)
{ {
return new T(chain, compression_level); return std::make_shared<T>(chain, compression_level);
} }
#endif /* SAVELOAD_FILTER_H */ #endif /* SAVELOAD_FILTER_H */