Botcraft 26.3
Loading...
Searching...
No Matches
ManagersClient.cpp
Go to the documentation of this file.
13
15#if USE_GUI
18#endif
19
20using namespace ProtocolCraft;
21
22namespace Botcraft
23{
25 {
27 is_hardcore = false;
28#if PROTOCOL_VERSION > 463 /* > 1.13.2 */
29 difficulty_locked = true;
30#endif
31
32 world = nullptr;
33 inventory_manager = nullptr;
34 entity_manager = nullptr;
35 physics_manager = nullptr;
36
37#if USE_GUI
38 rendering_manager = nullptr;
39#endif
40 auto_respawn = false;
41
42 // Ensure the assets are loaded
44 }
45
50
52 {
53 std::thread::id network_process_thread_id;
55 {
56 network_process_thread_id = network_manager->GetProcessingThreadId();
57 }
58
60
62#if PROTOCOL_VERSION > 463 /* > 1.13.2 */
63 difficulty_locked = true;
64#endif
65 is_hardcore = false;
66
67 physics_manager.reset();
68 entity_manager.reset();
69 inventory_manager.reset();
70#if USE_GUI
72 {
73 rendering_manager->Close();
74 }
75 rendering_manager.reset();
76#endif
77
78 if (world)
79 {
80 world->UnloadAllChunks(network_process_thread_id);
81 world.reset();
82 }
83
84 {
85 std::scoped_lock<std::shared_mutex> lock(player_names_mutex);
86 player_names.clear();
87 }
88 }
89
94
96 {
97 return day_time;
98 }
99
100 void ManagersClient::SetSharedWorld(const std::shared_ptr<World> world_)
101 {
102 world = world_;
103 }
104
106 {
107 return auto_respawn;
108 }
109
111 {
112 auto_respawn = b;
113 }
114
115 std::shared_ptr<World> ManagersClient::GetWorld() const
116 {
117 return world;
118 }
119
120 std::shared_ptr<EntityManager> ManagersClient::GetEntityManager() const
121 {
122 return entity_manager;
123 }
124
125 std::shared_ptr<LocalPlayer> ManagersClient::GetLocalPlayer() const
126 {
127 return entity_manager == nullptr ? nullptr : entity_manager->GetLocalPlayer();
128 }
129
130 std::shared_ptr<InventoryManager> ManagersClient::GetInventoryManager() const
131 {
132 return inventory_manager;
133 }
134
135 std::shared_ptr<PhysicsManager> ManagersClient::GetPhysicsManager() const
136 {
137 return physics_manager;
138 }
139
140 std::string ManagersClient::GetPlayerName(const UUID& uuid) const
141 {
142 std::shared_lock<std::shared_mutex> lock(player_names_mutex);
143 auto it = player_names.find(uuid);
144 if (it != player_names.end())
145 {
146 return it->second;
147 }
148 else if (entity_manager == nullptr || entity_manager->GetLocalPlayer() == nullptr)
149 {
150 return "";
151 }
152 else if (uuid == entity_manager->GetLocalPlayer()->GetUUID())
153 {
154 return network_manager->GetMyName();
155 }
156 return "";
157 }
158
159
160#if PROTOCOL_VERSION < 768 /* < 1.21.2 */
161 void ManagersClient::Handle(ClientboundGameProfilePacket& packet)
162#else
164#endif
165 {
166 // Create all handlers
167 if (!world)
168 {
169 world = std::make_shared<World>(false);
170 }
171
172 inventory_manager = std::make_shared<InventoryManager>(network_manager);
173 entity_manager = std::make_shared<EntityManager>(network_manager);
174 // Subscribe them to the network manager
175 network_manager->AddHandler(world.get());
176 network_manager->AddHandler(inventory_manager.get());
177 network_manager->AddHandler(entity_manager.get());
178#if USE_GUI
180 {
181 rendering_manager = Renderer::RenderingManager::CreateRenderingManagerIfPossible(world, inventory_manager, entity_manager);
182 if (rendering_manager == nullptr)
183 {
184 static bool first_time = true;
185 if (first_time)
186 {
187 first_time = false;
189 "Having multiple clients with renderer enabled is not supported.\n" <<
190 "Make sure to destroy the rendered client or disable Botcraft::Renderer::Options before creating another one"
191 );
192 }
193 }
194 else
195 {
196 network_manager->AddHandler(rendering_manager.get());
197 }
198 }
199 physics_manager = std::make_shared<PhysicsManager>(rendering_manager, inventory_manager, entity_manager, network_manager, world);
200#else
201 physics_manager = std::make_shared<PhysicsManager>(inventory_manager, entity_manager, network_manager, world);
202#endif
203 network_manager->AddHandler(physics_manager.get());
204 // Start physics
205 physics_manager->StartPhysics();
206 }
207
209 {
210 difficulty = static_cast<Difficulty>(packet.GetDifficulty());
211#if PROTOCOL_VERSION > 463 /* > 1.13.2 */
212 difficulty_locked = packet.GetLocked();
213#endif
214 }
215
217 {
218#if PROTOCOL_VERSION > 768 /* > 1.21.3 */
220#endif
221
222#if PROTOCOL_VERSION > 737 /* > 1.16.1 */
223 is_hardcore = packet.GetHardcore();
224#else
225 is_hardcore = packet.GetGameType() & 0x08;
226#endif
227
228#if PROTOCOL_VERSION < 464 /* < 1.14 */
229 difficulty = static_cast<Difficulty>(packet.GetDifficulty());
230#endif
231 }
232
234 {
235 if (packet.GetHealth() <= 0.0f && auto_respawn)
236 {
237 Respawn();
238 }
239 }
240
242 {
243 // Override the ConnectionClient Handle as the teleport confirmation is sent by the physics manager instead
244 }
245
247 {
248#if PROTOCOL_VERSION > 768 /* > 1.21.3 */
250#endif
251
252#if PROTOCOL_VERSION < 464 /* < 1.14 */
253 difficulty = static_cast<Difficulty>(packet.GetDifficulty());
254#endif
255 }
256
258 {
259 // abs because the server multiplies by -1 to indicate fixed daytime for versions < 1.21.2
260#if PROTOCOL_VERSION < 775 /* 26.1 */
261 day_time = std::abs(packet.GetDayTime()) % 24000;
262#else
263 // Per dimension updates
264 // TODO: match the dimension to ids using registry?
265 if (world != nullptr)
266 {
267 if (world->GetCurrentDimension() == "minecraft:overworld")
268 {
269 auto it = packet.GetClockUpdates().find(0);
270 if (it != packet.GetClockUpdates().end())
271 {
272 day_time = it->second.GetTotalTicks() % 24000;
273 }
274 }
275 else if (world->GetCurrentDimension() == "minecraft:the_end")
276 {
277 auto it = packet.GetClockUpdates().find(1);
278 if (it != packet.GetClockUpdates().end())
279 {
280 day_time = it->second.GetTotalTicks() % 24000;
281 }
282 }
283 }
284#endif
285 }
286
287#if PROTOCOL_VERSION < 761 /* < 1.19.3 */
288 void ManagersClient::Handle(ClientboundPlayerInfoPacket& packet)
289 {
290 if (packet.GetAction() == PlayerInfoAction::RemovePlayer)
291 {
292 std::scoped_lock<std::shared_mutex> lock(player_names_mutex);
293 for (const auto& [uuid, infos] : packet.GetEntries())
294 {
295 player_names.erase(uuid);
296 }
297 }
298 else if (packet.GetAction() == PlayerInfoAction::AddPlayer)
299 {
300 std::scoped_lock<std::shared_mutex> lock(player_names_mutex);
301 for (const auto& [uuid, infos] : packet.GetEntries())
302 {
303 if (infos.GetDisplayName().has_value())
304 {
305 player_names[uuid] = infos.GetDisplayName().value().GetText();
306 }
307 else
308 {
309 player_names[uuid] = infos.GetName();
310 }
311 }
312 }
313 else if (packet.GetAction() == PlayerInfoAction::UpdateDisplayName)
314 {
315 std::scoped_lock<std::shared_mutex> lock(player_names_mutex);
316 for (const auto& [uuid, infos] : packet.GetEntries())
317 {
318 if (infos.GetDisplayName().has_value())
319 {
320 player_names[uuid] = infos.GetDisplayName().value().GetText();
321 }
322 }
323 }
324 }
325#else
327 {
328 std::scoped_lock<std::shared_mutex> lock(player_names_mutex);
329 for (const auto& uuid : packet.GetProfileIds())
330 {
331 player_names.erase(uuid);
332 }
333 }
334
336 {
337 for (const auto& action : packet.GetActions())
338 {
339 if (action == PlayerInfoUpdateAction::AddPlayer)
340 {
341 std::scoped_lock<std::shared_mutex> lock(player_names_mutex);
342 for (const auto& [uuid, infos] : packet.GetEntries())
343 {
344 player_names[uuid] = infos.game_profile.GetName();
345 }
346 continue;
347 }
348 if (action == PlayerInfoUpdateAction::UpdateDisplayName)
349 {
350 std::scoped_lock<std::shared_mutex> lock(player_names_mutex);
351 for (const auto& [uuid, infos] : packet.GetEntries())
352 {
353 if (infos.display_name.has_value())
354 {
355 player_names[uuid] = infos.display_name.value().GetText();
356 }
357 }
358 }
359 }
360 }
361#endif
362} //Botcraft
#define LOG_WARNING(osstream)
Definition Logger.hpp:44
static AssetsManager & getInstance()
void Respawn()
Ask to respawn when dead.
virtual void Handle(ProtocolCraft::ClientboundLoginDisconnectPacket &packet) override
std::shared_ptr< NetworkManager > network_manager
std::atomic< int > day_time
Utilities::ScopeLockedWrapper< const std::map< ProtocolCraft::UUID, std::string >, std::shared_mutex, std::shared_lock > GetOnlinePlayers() const
Get the list of connected player (tab list)
std::map< ProtocolCraft::UUID, std::string > player_names
Names of all connected players.
std::shared_ptr< EntityManager > GetEntityManager() const
std::shared_ptr< PhysicsManager > GetPhysicsManager() const
void SetSharedWorld(const std::shared_ptr< World > world_)
std::shared_ptr< Renderer::RenderingManager > rendering_manager
std::shared_ptr< LocalPlayer > GetLocalPlayer() const
void SetAutoRespawn(const bool b)
std::shared_ptr< InventoryManager > GetInventoryManager() const
virtual void Disconnect() override
std::shared_ptr< PhysicsManager > physics_manager
std::shared_ptr< InventoryManager > inventory_manager
std::shared_ptr< EntityManager > entity_manager
std::shared_mutex player_names_mutex
std::shared_ptr< World > world
virtual void Handle(ProtocolCraft::ClientboundLoginFinishedPacket &packet) override
int GetDayTime() const
Get the current tick.
std::string GetPlayerName(const ProtocolCraft::UUID &uuid) const
Get the name of a connected player.
std::shared_ptr< World > GetWorld() const
static std::shared_ptr< RenderingManager > CreateRenderingManagerIfPossible(std::shared_ptr< World > world_, std::shared_ptr< InventoryManager > inventory_manager_, std::shared_ptr< EntityManager > entity_manager_)
Mutex protected reference, will be locked until destroyed.
std::array< unsigned char, 16 > UUID