mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-23 15:52:55 +01:00
Merge pull request #10045 from ZehMatt/fix-9994
Fix #9994: Game action tick collision during server connect and map load
This commit is contained in:
@@ -25,6 +25,7 @@
|
|||||||
- Fix: [#9955] Resizing map in while pause mode does not work and may result in freezes.
|
- Fix: [#9955] Resizing map in while pause mode does not work and may result in freezes.
|
||||||
- Fix: [#9957] When using 'no money' cheat, guests complain of running out of cash.
|
- Fix: [#9957] When using 'no money' cheat, guests complain of running out of cash.
|
||||||
- Fix: [#9970] Wait for quarter load fails.
|
- Fix: [#9970] Wait for quarter load fails.
|
||||||
|
- Fix: [#9994] Game action tick collision during server connect and map load.
|
||||||
- Fix: [#10017] Ghost elements influencing ride excitement.
|
- Fix: [#10017] Ghost elements influencing ride excitement.
|
||||||
- Fix: [#10036] Do not allocate large chunks of memory for save file classification.
|
- Fix: [#10036] Do not allocate large chunks of memory for save file classification.
|
||||||
- Improved: [#9466] Add the rain weather effect to the OpenGL renderer.
|
- Improved: [#9466] Add the rain weather effect to the OpenGL renderer.
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ namespace GameActions
|
|||||||
static GameActionFactory _actions[GAME_COMMAND_COUNT];
|
static GameActionFactory _actions[GAME_COMMAND_COUNT];
|
||||||
static std::multiset<QueuedGameAction> _actionQueue;
|
static std::multiset<QueuedGameAction> _actionQueue;
|
||||||
static uint32_t _nextUniqueId = 0;
|
static uint32_t _nextUniqueId = 0;
|
||||||
|
static bool _suspended = false;
|
||||||
|
|
||||||
GameActionFactory Register(uint32_t id, GameActionFactory factory)
|
GameActionFactory Register(uint32_t id, GameActionFactory factory)
|
||||||
{
|
{
|
||||||
@@ -95,6 +96,16 @@ namespace GameActions
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SuspendQueue()
|
||||||
|
{
|
||||||
|
_suspended = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResumeQueue()
|
||||||
|
{
|
||||||
|
_suspended = false;
|
||||||
|
}
|
||||||
|
|
||||||
void Enqueue(const GameAction* ga, uint32_t tick)
|
void Enqueue(const GameAction* ga, uint32_t tick)
|
||||||
{
|
{
|
||||||
auto action = Clone(ga);
|
auto action = Clone(ga);
|
||||||
@@ -114,6 +125,12 @@ namespace GameActions
|
|||||||
|
|
||||||
void ProcessQueue()
|
void ProcessQueue()
|
||||||
{
|
{
|
||||||
|
if (_suspended)
|
||||||
|
{
|
||||||
|
// Do nothing if suspended, this is usually the case between connect and map loads.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const uint32_t currentTick = gCurrentTicks;
|
const uint32_t currentTick = gCurrentTicks;
|
||||||
|
|
||||||
while (_actionQueue.begin() != _actionQueue.end())
|
while (_actionQueue.begin() != _actionQueue.end())
|
||||||
|
|||||||
@@ -255,6 +255,14 @@ namespace GameActions
|
|||||||
void Register();
|
void Register();
|
||||||
bool IsValidId(uint32_t id);
|
bool IsValidId(uint32_t id);
|
||||||
|
|
||||||
|
// Halts the queue processing until ResumeQueue is called, any calls to ProcessQueue
|
||||||
|
// will have no effect during suspension. It has no effect of actions that will not
|
||||||
|
// cross the network.
|
||||||
|
void SuspendQueue();
|
||||||
|
|
||||||
|
// Resumes queue processing.
|
||||||
|
void ResumeQueue();
|
||||||
|
|
||||||
void Enqueue(const GameAction* ga, uint32_t tick);
|
void Enqueue(const GameAction* ga, uint32_t tick);
|
||||||
void Enqueue(GameAction::Ptr&& ga, uint32_t tick);
|
void Enqueue(GameAction::Ptr&& ga, uint32_t tick);
|
||||||
void ProcessQueue();
|
void ProcessQueue();
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
// This string specifies which version of network stream current build uses.
|
// This string specifies which version of network stream current build uses.
|
||||||
// It is used for making sure only compatible builds get connected, even within
|
// It is used for making sure only compatible builds get connected, even within
|
||||||
// single OpenRCT2 version.
|
// single OpenRCT2 version.
|
||||||
#define NETWORK_STREAM_VERSION "17"
|
#define NETWORK_STREAM_VERSION "18"
|
||||||
#define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION
|
#define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION
|
||||||
|
|
||||||
static Peep* _pickup_peep = nullptr;
|
static Peep* _pickup_peep = nullptr;
|
||||||
@@ -417,6 +417,7 @@ void Network::Close()
|
|||||||
|
|
||||||
client_connection_list.clear();
|
client_connection_list.clear();
|
||||||
GameActions::ClearQueue();
|
GameActions::ClearQueue();
|
||||||
|
GameActions::ResumeQueue();
|
||||||
player_list.clear();
|
player_list.clear();
|
||||||
group_list.clear();
|
group_list.clear();
|
||||||
_serverTickData.clear();
|
_serverTickData.clear();
|
||||||
@@ -493,6 +494,11 @@ bool Network::BeginClient(const std::string& host, uint16_t port)
|
|||||||
BeginChatLog();
|
BeginChatLog();
|
||||||
BeginServerLog();
|
BeginServerLog();
|
||||||
|
|
||||||
|
// We need to wait for the map load before we execute any actions.
|
||||||
|
// If the client has the title screen running then theres a potential
|
||||||
|
// risk of tick collision with the server map and title screen map.
|
||||||
|
GameActions::SuspendQueue();
|
||||||
|
|
||||||
utf8 keyPath[MAX_PATH];
|
utf8 keyPath[MAX_PATH];
|
||||||
network_get_private_key_path(keyPath, sizeof(keyPath), gConfigNetwork.player_name);
|
network_get_private_key_path(keyPath, sizeof(keyPath), gConfigNetwork.player_name);
|
||||||
if (!platform_file_exists(keyPath))
|
if (!platform_file_exists(keyPath))
|
||||||
@@ -2615,6 +2621,8 @@ void Network::Client_Handle_MAP([[maybe_unused]] NetworkConnection& connection,
|
|||||||
// Start of a new map load, clear the queue now as we have to buffer them
|
// Start of a new map load, clear the queue now as we have to buffer them
|
||||||
// until the map is fully loaded.
|
// until the map is fully loaded.
|
||||||
GameActions::ClearQueue();
|
GameActions::ClearQueue();
|
||||||
|
GameActions::SuspendQueue();
|
||||||
|
|
||||||
_serverTickData.clear();
|
_serverTickData.clear();
|
||||||
_clientMapLoaded = false;
|
_clientMapLoaded = false;
|
||||||
}
|
}
|
||||||
@@ -2637,6 +2645,9 @@ void Network::Client_Handle_MAP([[maybe_unused]] NetworkConnection& connection,
|
|||||||
std::memcpy(&chunk_buffer[offset], (void*)packet.Read(chunksize), chunksize);
|
std::memcpy(&chunk_buffer[offset], (void*)packet.Read(chunksize), chunksize);
|
||||||
if (offset + chunksize == size)
|
if (offset + chunksize == size)
|
||||||
{
|
{
|
||||||
|
// Allow queue processing of game actions again.
|
||||||
|
GameActions::ResumeQueue();
|
||||||
|
|
||||||
context_force_close_window_by_class(WC_NETWORK_STATUS);
|
context_force_close_window_by_class(WC_NETWORK_STATUS);
|
||||||
bool has_to_free = false;
|
bool has_to_free = false;
|
||||||
uint8_t* data = &chunk_buffer[0];
|
uint8_t* data = &chunk_buffer[0];
|
||||||
|
|||||||
Reference in New Issue
Block a user