diff --git a/Server/Plugins/APIDump/APIDesc.lua b/Server/Plugins/APIDump/APIDesc.lua index 2f9157545..ae6e4e0fb 100644 --- a/Server/Plugins/APIDump/APIDesc.lua +++ b/Server/Plugins/APIDump/APIDesc.lua @@ -1870,7 +1870,7 @@ end Type = "number", }, { - Name = "TimeOfDay", + Name = "WorldDate", Type = "number", }, { @@ -1878,7 +1878,7 @@ end Type = "boolean", }, }, - Notes = "Sends the specified time update to the client. WorldAge is the total age of the world, in ticks. TimeOfDay is the current day's time, in ticks (0 - 24000). DoDaylightCycle is a bool that specifies whether the client should automatically move the sun (true) or keep it in the same place (false).", + Notes = "Sends the specified time update to the client. WorldAge is the total age of the world, in ticks. WorldDate is the current date, in ticks, and is used by the client to calculate the days elapsed (F3 debug overlay's day count) and the time of day (rendered sun position). DoDaylightCycle is a bool that specifies whether the client should automatically move the sun (true) or keep it in the same place (false).", }, SetClientBrand = { diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index 8798b2b68..0493804e5 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -35,9 +35,6 @@ extern "C" #include "lua/src/lauxlib.h" } - -#include - #include "../Defines.h" #include "../FunctionRef.h" #include "PluginManager.h" diff --git a/src/Broadcaster.cpp b/src/Broadcaster.cpp index 7cc3deaaa..445bb6d89 100644 --- a/src/Broadcaster.cpp +++ b/src/Broadcaster.cpp @@ -596,7 +596,7 @@ void cWorld::BroadcastTimeUpdate(const cClientHandle * a_Exclude) { ForClientsInWorld(*this, a_Exclude, [&](cClientHandle & a_Client) { - a_Client.SendTimeUpdate(GetWorldAge(), GetTimeOfDay(), IsDaylightCycleEnabled()); + a_Client.SendTimeUpdate(GetWorldAge(), std::chrono::duration_cast(m_WorldDate).count(), IsDaylightCycleEnabled()); } ); } diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 5309ef672..26db7c2df 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -3003,9 +3003,9 @@ void cClientHandle::SendTitleTimes(int a_FadeInTicks, int a_DisplayTicks, int a_ -void cClientHandle::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) +void cClientHandle::SendTimeUpdate(Int64 a_WorldAge, Int64 a_WorldDate, bool a_DoDaylightCycle) { - m_Protocol->SendTimeUpdate(a_WorldAge, a_TimeOfDay, a_DoDaylightCycle); + m_Protocol->SendTimeUpdate(a_WorldAge, a_WorldDate, a_DoDaylightCycle); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index c73a8c873..983cb039d 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -219,7 +219,7 @@ public: // tolua_export void SendTabCompletionResults (const AStringVector & a_Results); void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ); void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks); // tolua_export - void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle); // tolua_export + void SendTimeUpdate (Int64 a_WorldAge, Int64 a_WorldDate, bool a_DoDaylightCycle); // tolua_export void SendUnleashEntity (const cEntity & a_Entity); void SendUnloadChunk (int a_ChunkX, int a_ChunkZ); void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity); diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index e431e4cc5..7d8c3a191 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -83,7 +83,7 @@ const int cPlayer::EATING_TICKS = 30; -cPlayer::cPlayer(const cClientHandlePtr & a_Client) : +cPlayer::cPlayer(const std::shared_ptr & a_Client) : Super(etPlayer, 0.6, 1.8), m_bVisible(true), m_FoodLevel(MAX_FOOD_LEVEL), diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 86d4a2a07..2d31ef84b 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -47,7 +47,7 @@ public: CLASS_PROTODEF(cPlayer) - cPlayer(const cClientHandlePtr & a_Client); + cPlayer(const std::shared_ptr & a_Client); virtual ~cPlayer() override; // tolua_begin @@ -656,7 +656,7 @@ private: /** The item being dragged by the cursor while in a UI window */ cItem m_DraggingItem; - cClientHandlePtr m_ClientHandle; + std::shared_ptr m_ClientHandle; cSlotNums m_InventoryPaintSlots; diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index 3c70cdb55..71fc37d04 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -438,7 +438,7 @@ public: virtual void SendTabCompletionResults (const AStringVector & a_Results) = 0; virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) = 0; virtual void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks) = 0; - virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) = 0; + virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_WorldDate, bool a_DoDaylightCycle) = 0; virtual void SendUnleashEntity (const cEntity & a_Entity) = 0; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) = 0; virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) = 0; diff --git a/src/Protocol/Protocol_1_8.cpp b/src/Protocol/Protocol_1_8.cpp index 79f75fcc5..fe99ab91a 100644 --- a/src/Protocol/Protocol_1_8.cpp +++ b/src/Protocol/Protocol_1_8.cpp @@ -1566,18 +1566,20 @@ void cProtocol_1_8_0::SendTitleTimes(int a_FadeInTicks, int a_DisplayTicks, int -void cProtocol_1_8_0::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) +void cProtocol_1_8_0::SendTimeUpdate(Int64 a_WorldAge, Int64 a_WorldDate, bool a_DoDaylightCycle) { ASSERT(m_State == 3); // In game mode? + if (!a_DoDaylightCycle) { - // When writing a "-" before the number the client ignores it but it will stop the client-side time expiration. - a_TimeOfDay = std::min(-a_TimeOfDay, -1LL); + // Negating the date stops time from advancing on the client + // (the std::min construction is to handle the case where the date is exactly zero): + a_WorldDate = std::min(-a_WorldDate, -1LL); } cPacketizer Pkt(*this, pktTimeUpdate); Pkt.WriteBEInt64(a_WorldAge); - Pkt.WriteBEInt64(a_TimeOfDay); + Pkt.WriteBEInt64(a_WorldDate); } diff --git a/src/Protocol/Protocol_1_8.h b/src/Protocol/Protocol_1_8.h index ae6d09417..d899dc067 100644 --- a/src/Protocol/Protocol_1_8.h +++ b/src/Protocol/Protocol_1_8.h @@ -119,7 +119,7 @@ public: virtual void SendTabCompletionResults (const AStringVector & a_Results) override; virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks) override; - virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override; + virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_WorldDate, bool a_DoDaylightCycle) override; virtual void SendUnleashEntity (const cEntity & a_Entity) override; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override; diff --git a/src/World.cpp b/src/World.cpp index e0f0b6c1c..3be923fff 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -61,14 +61,6 @@ -const int TIME_SUNSET = 12000; -const int TIME_NIGHT_START = 13187; -const int TIME_NIGHT_END = 22812; -const int TIME_SUNRISE = 23999; -const int TIME_SPAWN_DIVISOR = 148; - - - namespace World @@ -167,7 +159,7 @@ cWorld::cWorld( m_BroadcastAchievementMessages(true), m_IsDaylightCycleEnabled(true), m_WorldAge(0), - m_TimeOfDay(0), + m_WorldDate(0), m_WorldTickAge(0), m_LastChunkCheck(0), m_LastSave(0), @@ -483,6 +475,39 @@ void cWorld::CastThunderbolt(Vector3i a_Block) +int cWorld::GetTimeOfDay(void) const +{ + using namespace std::chrono_literals; + + return std::chrono::duration_cast(m_WorldDate % 20min).count(); +} + + + + + +Int64 cWorld::GetWorldAge(void) const +{ + return std::chrono::duration_cast(m_WorldAge).count(); +} + + + + + +void cWorld::SetTimeOfDay(int a_TimeOfDay) +{ + using namespace std::chrono_literals; + + m_WorldDate = (m_WorldDate / 20min) * 20min + cTickTime(a_TimeOfDay); + UpdateSkyDarkness(); + BroadcastTimeUpdate(); +} + + + + + int cWorld::GetDefaultWeatherInterval(eWeather a_Weather) const { auto & Random = GetRandomProvider(); @@ -967,13 +992,7 @@ void cWorld::Tick(std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_La if (m_IsDaylightCycleEnabled) { - m_TimeOfDay += a_Dt; - - // Wrap time of day every 20 minutes (1200 seconds): - if (m_TimeOfDay > std::chrono::minutes(20)) - { - m_TimeOfDay -= std::chrono::minutes(20); - } + m_WorldDate += a_Dt; // Updates the sky darkness based on current time of day: UpdateSkyDarkness(); @@ -1267,7 +1286,13 @@ void cWorld::TickQueuedTasks(void) void cWorld::UpdateSkyDarkness(void) { - int TempTime = std::chrono::duration_cast(m_TimeOfDay).count(); + const int TIME_SUNSET = 12000; + const int TIME_NIGHT_START = 13187; + const int TIME_NIGHT_END = 22812; + const int TIME_SUNRISE = 23999; + const int TIME_SPAWN_DIVISOR = 148; + + const auto TempTime = GetTimeOfDay(); if (TempTime <= TIME_SUNSET) { m_SkyDarkness = 0; diff --git a/src/World.h b/src/World.h index b94bbacdb..0f0ade751 100644 --- a/src/World.h +++ b/src/World.h @@ -1,10 +1,6 @@ #pragma once -#define MAX_PLAYERS 65535 - -#include - #include "Simulator/SimulatorManager.h" #include "ChunkMap.h" #include "WorldStorage/WorldStorage.h" @@ -26,6 +22,8 @@ + + class cFireSimulator; class cFluidSimulator; class cSandSimulator; @@ -33,9 +31,6 @@ class cRedstoneSimulator; class cItem; class cPlayer; class cClientHandle; -typedef std::shared_ptr cClientHandlePtr; -typedef std::list cClientHandlePtrs; -typedef std::list cClientHandles; class cEntity; class cChunkGenerator; // The thread responsible for generating chunks class cBeaconEntity; @@ -120,20 +115,15 @@ public: BroadcastTimeUpdate(); } - virtual Int64 GetWorldAge (void) const override { return std::chrono::duration_cast(m_WorldAge).count(); } - virtual int GetTimeOfDay(void) const override { return std::chrono::duration_cast(m_TimeOfDay).count(); } + virtual int GetTimeOfDay(void) const override; + virtual Int64 GetWorldAge(void) const override; void SetTicksUntilWeatherChange(int a_WeatherInterval) { m_WeatherInterval = a_WeatherInterval; } - virtual void SetTimeOfDay(int a_TimeOfDay) override - { - m_TimeOfDay = cTickTime(a_TimeOfDay); - UpdateSkyDarkness(); - BroadcastTimeUpdate(); - } + virtual void SetTimeOfDay(int a_TimeOfDay) override; /** Returns the default weather interval for the specific weather type. Returns -1 for any unknown weather. */ @@ -1061,12 +1051,12 @@ private: We need sub-tick precision here, that's why we store the time in milliseconds and calculate ticks off of it. */ std::chrono::milliseconds m_WorldAge; - /** The duration of one Minecraft day that has elapsed. - Wraps every 20 minutes. + /** The fully controllable age of the world. + A value used to calculate the current day, and time of day. Settable by plugins and players, and persistent. We need sub-tick precision here, that's why we store the time in milliseconds and calculate ticks off of it. */ - std::chrono::milliseconds m_TimeOfDay; + std::chrono::milliseconds m_WorldDate; - /** The age of the world, in ticks. + /** The time since this world began, in ticks. Monotonic, but does not persist across restarts. Used for less important but heavy tasks that run periodically. These tasks don't need to follow wallclock time, and slowing their rate down if TPS drops is desirable. */ unsigned long long m_WorldTickAge;