1
0
mirror of https://github.com/OpenTTD/OpenTTD.git synced 2025-08-28 00:49:11 +00:00

Codechange: Split dates and timers into Economy and Calendar time (#10700)

This commit is contained in:
Tyler Trahan
2024-01-22 09:04:34 -05:00
committed by GitHub
parent 419f48dfb3
commit 735abfe111
65 changed files with 952 additions and 550 deletions

View File

@@ -12,7 +12,7 @@
#include "../strings_func.h"
#include "../command_func.h"
#include "../timer/timer_game_tick.h"
#include "../timer/timer_game_calendar.h"
#include "../timer/timer_game_economy.h"
#include "network_admin.h"
#include "network_client.h"
#include "network_query.h"
@@ -263,7 +263,7 @@ void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send,
Utf8Encode(iterator, _current_text_dir == TD_LTR ? CHAR_TD_LRM : CHAR_TD_RLM);
std::string message = stream.str() + GetString(strid);
Debug(desync, 1, "msg: {:08x}; {:02x}; {}", TimerGameCalendar::date, TimerGameCalendar::date_fract, message);
Debug(desync, 1, "msg: {:08x}; {:02x}; {}", TimerGameEconomy::date, TimerGameEconomy::date_fract, message);
IConsolePrint(colour, message);
NetworkAddChatMessage(colour, _settings_client.gui.network_chat_timeout, message);
}
@@ -1043,42 +1043,42 @@ void NetworkGameLoop()
if (_network_server) {
/* Log the sync state to check for in-syncedness of replays. */
if (TimerGameCalendar::date_fract == 0) {
if (TimerGameEconomy::date_fract == 0) {
/* We don't want to log multiple times if paused. */
static TimerGameCalendar::Date last_log;
if (last_log != TimerGameCalendar::date) {
Debug(desync, 1, "sync: {:08x}; {:02x}; {:08x}; {:08x}", TimerGameCalendar::date, TimerGameCalendar::date_fract, _random.state[0], _random.state[1]);
last_log = TimerGameCalendar::date;
static TimerGameEconomy::Date last_log;
if (last_log != TimerGameEconomy::date) {
Debug(desync, 1, "sync: {:08x}; {:02x}; {:08x}; {:08x}", TimerGameEconomy::date, TimerGameEconomy::date_fract, _random.state[0], _random.state[1]);
last_log = TimerGameEconomy::date;
}
}
#ifdef DEBUG_DUMP_COMMANDS
/* Loading of the debug commands from -ddesync>=1 */
static FILE *f = FioFOpenFile("commands.log", "rb", SAVE_DIR);
static TimerGameCalendar::Date next_date(0);
static TimerGameEconomy::Date next_date(0);
static uint32_t next_date_fract;
static CommandPacket *cp = nullptr;
static bool check_sync_state = false;
static uint32_t sync_state[2];
if (f == nullptr && next_date == 0) {
Debug(desync, 0, "Cannot open commands.log");
next_date = TimerGameCalendar::Date(1);
next_date = TimerGameEconomy::Date(1);
}
while (f != nullptr && !feof(f)) {
if (TimerGameCalendar::date == next_date && TimerGameCalendar::date_fract == next_date_fract) {
if (TimerGameEconomy::date == next_date && TimerGameEconomy::date_fract == next_date_fract) {
if (cp != nullptr) {
NetworkSendCommand(cp->cmd, cp->err_msg, nullptr, cp->company, cp->data);
Debug(desync, 0, "Injecting: {:08x}; {:02x}; {:02x}; {:08x}; {} ({})", TimerGameCalendar::date, TimerGameCalendar::date_fract, (int)_current_company, cp->cmd, FormatArrayAsHex(cp->data), GetCommandName(cp->cmd));
Debug(desync, 0, "Injecting: {:08x}; {:02x}; {:02x}; {:08x}; {} ({})", TimerGameEconomy::date, TimerGameEconomy::date_fract, (int)_current_company, cp->cmd, FormatArrayAsHex(cp->data), GetCommandName(cp->cmd));
delete cp;
cp = nullptr;
}
if (check_sync_state) {
if (sync_state[0] == _random.state[0] && sync_state[1] == _random.state[1]) {
Debug(desync, 0, "Sync check: {:08x}; {:02x}; match", TimerGameCalendar::date, TimerGameCalendar::date_fract);
Debug(desync, 0, "Sync check: {:08x}; {:02x}; match", TimerGameEconomy::date, TimerGameEconomy::date_fract);
} else {
Debug(desync, 0, "Sync check: {:08x}; {:02x}; mismatch expected {{{:08x}, {:08x}}}, got {{{:08x}, {:08x}}}",
TimerGameCalendar::date, TimerGameCalendar::date_fract, sync_state[0], sync_state[1], _random.state[0], _random.state[1]);
TimerGameEconomy::date, TimerGameEconomy::date_fract, sync_state[0], sync_state[1], _random.state[0], _random.state[1]);
NOT_REACHED();
}
check_sync_state = false;
@@ -1112,7 +1112,7 @@ void NetworkGameLoop()
uint32_t next_date_raw;
int ret = sscanf(p, "%x; %x; %x; %x; %x; %255s", &next_date_raw, &next_date_fract, &company, &cmd, &cp->err_msg, buffer);
assert(ret == 6);
next_date = TimerGameCalendar::Date((int32_t)next_date_raw);
next_date = TimerGameEconomy::Date((int32_t)next_date_raw);
cp->company = (CompanyID)company;
cp->cmd = (Commands)cmd;
@@ -1129,7 +1129,7 @@ void NetworkGameLoop()
/* Manually insert a pause when joining; this way the client can join at the exact right time. */
uint32_t next_date_raw;
int ret = sscanf(p + 6, "%x; %x", &next_date_raw, &next_date_fract);
next_date = TimerGameCalendar::Date((int32_t)next_date_raw);
next_date = TimerGameEconomy::Date((int32_t)next_date_raw);
assert(ret == 2);
Debug(desync, 0, "Injecting pause for join at {:08x}:{:02x}; please join when paused", next_date, next_date_fract);
cp = new CommandPacket();
@@ -1140,7 +1140,7 @@ void NetworkGameLoop()
} else if (strncmp(p, "sync: ", 6) == 0) {
uint32_t next_date_raw;
int ret = sscanf(p + 6, "%x; %x; %x; %x", &next_date_raw, &next_date_fract, &sync_state[0], &sync_state[1]);
next_date = TimerGameCalendar::Date((int32_t)next_date_raw);
next_date = TimerGameEconomy::Date((int32_t)next_date_raw);
assert(ret == 4);
check_sync_state = true;
} else if (strncmp(p, "msg: ", 5) == 0 || strncmp(p, "client: ", 8) == 0 ||

View File

@@ -14,7 +14,7 @@
#include "core/address.h"
#include "../core/pool_type.hpp"
#include "../company_type.h"
#include "../timer/timer_game_calendar.h"
#include "../timer/timer_game_economy.h"
/** Type for the pool with client information. */
typedef Pool<NetworkClientInfo, ClientIndex, 8, MAX_CLIENT_SLOTS, PT_NCLIENT> NetworkClientInfoPool;
@@ -25,7 +25,7 @@ struct NetworkClientInfo : NetworkClientInfoPool::PoolItem<&_networkclientinfo_p
ClientID client_id; ///< Client identifier (same as ClientState->client_id)
std::string client_name; ///< Name of the client
CompanyID client_playas; ///< As which company is this client playing (CompanyID)
TimerGameCalendar::Date join_date; ///< Gamedate the client has joined
TimerGameEconomy::Date join_date; ///< Gamedate the client has joined
/**
* Create a new client.

View File

@@ -282,7 +282,7 @@ void ClientNetworkGameSocketHandler::ClientError(NetworkRecvStatus res)
if (_sync_seed_1 != _random.state[0]) {
#endif
ShowNetworkError(STR_NETWORK_ERROR_DESYNC);
Debug(desync, 1, "sync_err: {:08x}; {:02x}", TimerGameCalendar::date, TimerGameCalendar::date_fract);
Debug(desync, 1, "sync_err: {:08x}; {:02x}", TimerGameEconomy::date, TimerGameEconomy::date_fract);
Debug(net, 0, "Sync error detected");
my_client->ClientError(NETWORK_RECV_STATUS_DESYNC);
return false;

View File

@@ -32,6 +32,7 @@
#include "../rev.h"
#include "../timer/timer.h"
#include "../timer/timer_game_calendar.h"
#include "../timer/timer_game_economy.h"
#include <mutex>
#include <condition_variable>
@@ -882,10 +883,10 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p)
assert(NetworkClientInfo::CanAllocateItem());
NetworkClientInfo *ci = new NetworkClientInfo(this->client_id);
this->SetInfo(ci);
ci->join_date = TimerGameCalendar::date;
ci->join_date = TimerGameEconomy::date;
ci->client_name = client_name;
ci->client_playas = playas;
Debug(desync, 1, "client: {:08x}; {:02x}; {:02x}; {:02x}", TimerGameCalendar::date, TimerGameCalendar::date_fract, (int)ci->client_playas, (int)ci->index);
Debug(desync, 1, "client: {:08x}; {:02x}; {:02x}; {:02x}", TimerGameEconomy::date, TimerGameEconomy::date_fract, (int)ci->client_playas, (int)ci->index);
/* Make sure companies to which people try to join are not autocleaned */
if (Company::IsValidID(playas)) _network_company_states[playas].months_empty = 0;
@@ -1479,7 +1480,7 @@ void NetworkUpdateClientInfo(ClientID client_id)
if (ci == nullptr) return;
Debug(desync, 1, "client: {:08x}; {:02x}; {:02x}; {:04x}", TimerGameCalendar::date, TimerGameCalendar::date_fract, (int)ci->client_playas, client_id);
Debug(desync, 1, "client: {:08x}; {:02x}; {:02x}; {:04x}", TimerGameEconomy::date, TimerGameEconomy::date_fract, (int)ci->client_playas, client_id);
for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
if (cs->status >= ServerNetworkGameSocketHandler::STATUS_AUTHORIZED) {
@@ -1810,17 +1811,23 @@ void NetworkServer_Tick(bool send_frame)
}
}
/** Yearly "callback". Called whenever the year changes. */
static IntervalTimer<TimerGameCalendar> _network_yearly({TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [](auto)
{
/** Calendar yearly "callback". Called whenever the calendar year changes. */
static IntervalTimer<TimerGameCalendar> _calendar_network_yearly({ TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE }, [](auto) {
if (!_network_server) return;
NetworkCheckRestartMap();
});
/** Economy yearly "callback". Called whenever the economy year changes. */
static IntervalTimer<TimerGameEconomy> _economy_network_yearly({TimerGameEconomy::YEAR, TimerGameEconomy::Priority::NONE}, [](auto)
{
if (!_network_server) return;
NetworkAdminUpdate(ADMIN_FREQUENCY_ANUALLY);
});
/** Quarterly "callback". Called whenever the quarter changes. */
static IntervalTimer<TimerGameCalendar> _network_quarterly({TimerGameCalendar::QUARTER, TimerGameCalendar::Priority::NONE}, [](auto)
/** Quarterly "callback". Called whenever the economy quarter changes. */
static IntervalTimer<TimerGameEconomy> _network_quarterly({TimerGameEconomy::QUARTER, TimerGameEconomy::Priority::NONE}, [](auto)
{
if (!_network_server) return;
@@ -1828,8 +1835,8 @@ static IntervalTimer<TimerGameCalendar> _network_quarterly({TimerGameCalendar::Q
NetworkAdminUpdate(ADMIN_FREQUENCY_QUARTERLY);
});
/** Monthly "callback". Called whenever the month changes. */
static IntervalTimer<TimerGameCalendar> _network_monthly({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::NONE}, [](auto)
/** Economy monthly "callback". Called whenever the economy month changes. */
static IntervalTimer<TimerGameEconomy> _network_monthly({TimerGameEconomy::MONTH, TimerGameEconomy::Priority::NONE}, [](auto)
{
if (!_network_server) return;
@@ -1837,16 +1844,16 @@ static IntervalTimer<TimerGameCalendar> _network_monthly({TimerGameCalendar::MON
NetworkAdminUpdate(ADMIN_FREQUENCY_MONTHLY);
});
/** Weekly "callback". Called whenever the week changes. */
static IntervalTimer<TimerGameCalendar> _network_weekly({TimerGameCalendar::WEEK, TimerGameCalendar::Priority::NONE}, [](auto)
/** Economy weekly "callback". Called whenever the economy week changes. */
static IntervalTimer<TimerGameEconomy> _network_weekly({TimerGameEconomy::WEEK, TimerGameEconomy::Priority::NONE}, [](auto)
{
if (!_network_server) return;
NetworkAdminUpdate(ADMIN_FREQUENCY_WEEKLY);
});
/** Daily "callback". Called whenever the date changes. */
static IntervalTimer<TimerGameCalendar> _network_daily({TimerGameCalendar::DAY, TimerGameCalendar::Priority::NONE}, [](auto)
/** Daily "callback". Called whenever the economy date changes. */
static IntervalTimer<TimerGameEconomy> _economy_network_daily({TimerGameEconomy::DAY, TimerGameEconomy::Priority::NONE}, [](auto)
{
if (!_network_server) return;