Botcraft 26.2
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 int ManagersClient::SendInventoryTransaction(const std::shared_ptr<ServerboundContainerClickPacket>& transaction)
101 {
102 InventoryTransaction inventory_transaction = inventory_manager->PrepareTransaction(transaction);
103#if PROTOCOL_VERSION < 755 /* < 1.17 */
104 inventory_manager->AddPendingTransaction(inventory_transaction);
105 network_manager->Send(transaction);
106 return transaction->GetUid();
107#else
108 network_manager->Send(transaction);
109 // In 1.17+ there is no server confirmation so apply it directly
110 inventory_manager->ApplyTransaction(inventory_transaction);
111 return 1;
112#endif
113 }
114
115 void ManagersClient::SetSharedWorld(const std::shared_ptr<World> world_)
116 {
117 world = world_;
118 }
119
121 {
122 return auto_respawn;
123 }
124
126 {
127 auto_respawn = b;
128 }
129
130 std::shared_ptr<World> ManagersClient::GetWorld() const
131 {
132 return world;
133 }
134
135 std::shared_ptr<EntityManager> ManagersClient::GetEntityManager() const
136 {
137 return entity_manager;
138 }
139
140 std::shared_ptr<LocalPlayer> ManagersClient::GetLocalPlayer() const
141 {
142 return entity_manager == nullptr ? nullptr : entity_manager->GetLocalPlayer();
143 }
144
145 std::shared_ptr<InventoryManager> ManagersClient::GetInventoryManager() const
146 {
147 return inventory_manager;
148 }
149
150 std::shared_ptr<PhysicsManager> ManagersClient::GetPhysicsManager() const
151 {
152 return physics_manager;
153 }
154
155 std::string ManagersClient::GetPlayerName(const UUID& uuid) const
156 {
157 std::shared_lock<std::shared_mutex> lock(player_names_mutex);
158 auto it = player_names.find(uuid);
159 if (it != player_names.end())
160 {
161 return it->second;
162 }
163 else if (entity_manager == nullptr || entity_manager->GetLocalPlayer() == nullptr)
164 {
165 return "";
166 }
167 else if (uuid == entity_manager->GetLocalPlayer()->GetUUID())
168 {
169 return network_manager->GetMyName();
170 }
171 return "";
172 }
173
174
175#if PROTOCOL_VERSION < 768 /* < 1.21.2 */
176 void ManagersClient::Handle(ClientboundGameProfilePacket& packet)
177#else
179#endif
180 {
181 // Create all handlers
182 if (!world)
183 {
184 world = std::make_shared<World>(false);
185 }
186
187 inventory_manager = std::make_shared<InventoryManager>();
188 entity_manager = std::make_shared<EntityManager>(network_manager);
189 // Subscribe them to the network manager
190 network_manager->AddHandler(world.get());
191 network_manager->AddHandler(inventory_manager.get());
192 network_manager->AddHandler(entity_manager.get());
193#if USE_GUI
195 {
196 rendering_manager = Renderer::RenderingManager::CreateRenderingManagerIfPossible(world, inventory_manager, entity_manager);
197 if (rendering_manager == nullptr)
198 {
199 static bool first_time = true;
200 if (first_time)
201 {
202 first_time = false;
204 "Having multiple clients with renderer enabled is not supported.\n" <<
205 "Make sure to destroy the rendered client or disable Botcraft::Renderer::Options before creating another one"
206 );
207 }
208 }
209 else
210 {
211 network_manager->AddHandler(rendering_manager.get());
212 }
213 }
214 physics_manager = std::make_shared<PhysicsManager>(rendering_manager, inventory_manager, entity_manager, network_manager, world);
215#else
216 physics_manager = std::make_shared<PhysicsManager>(inventory_manager, entity_manager, network_manager, world);
217#endif
218 network_manager->AddHandler(physics_manager.get());
219 // Start physics
220 physics_manager->StartPhysics();
221 }
222
224 {
225 difficulty = static_cast<Difficulty>(packet.GetDifficulty());
226#if PROTOCOL_VERSION > 463 /* > 1.13.2 */
227 difficulty_locked = packet.GetLocked();
228#endif
229 }
230
232 {
233#if PROTOCOL_VERSION > 768 /* > 1.21.3 */
235#endif
236
237#if PROTOCOL_VERSION > 737 /* > 1.16.1 */
238 is_hardcore = packet.GetHardcore();
239#else
240 is_hardcore = packet.GetGameType() & 0x08;
241#endif
242
243#if PROTOCOL_VERSION < 464 /* < 1.14 */
244 difficulty = static_cast<Difficulty>(packet.GetDifficulty());
245#endif
246 }
247
249 {
250 if (packet.GetHealth() <= 0.0f && auto_respawn)
251 {
252 Respawn();
253 }
254 }
255
257 {
258 // Override the ConnectionClient Handle as the teleport confirmation is sent by the physics manager instead
259 }
260
262 {
263#if PROTOCOL_VERSION > 768 /* > 1.21.3 */
265#endif
266
267#if PROTOCOL_VERSION < 464 /* < 1.14 */
268 difficulty = static_cast<Difficulty>(packet.GetDifficulty());
269#endif
270 }
271
273 {
274 // abs because the server multiplies by -1 to indicate fixed daytime for versions < 1.21.2
275#if PROTOCOL_VERSION < 775 /* 26.1 */
276 day_time = std::abs(packet.GetDayTime()) % 24000;
277#else
278 // Per dimension updates
279 // TODO: match the dimension to ids using registry?
280 if (world != nullptr)
281 {
282 if (world->GetCurrentDimension() == "minecraft:overworld")
283 {
284 auto it = packet.GetClockUpdates().find(0);
285 if (it != packet.GetClockUpdates().end())
286 {
287 day_time = it->second.GetTotalTicks() % 24000;
288 }
289 }
290 else if (world->GetCurrentDimension() == "minecraft:the_end")
291 {
292 auto it = packet.GetClockUpdates().find(1);
293 if (it != packet.GetClockUpdates().end())
294 {
295 day_time = it->second.GetTotalTicks() % 24000;
296 }
297 }
298 }
299#endif
300 }
301
302#if PROTOCOL_VERSION < 761 /* < 1.19.3 */
303 void ManagersClient::Handle(ClientboundPlayerInfoPacket& packet)
304 {
305 if (packet.GetAction() == PlayerInfoAction::RemovePlayer)
306 {
307 std::scoped_lock<std::shared_mutex> lock(player_names_mutex);
308 for (const auto& [uuid, infos] : packet.GetEntries())
309 {
310 player_names.erase(uuid);
311 }
312 }
313 else if (packet.GetAction() == PlayerInfoAction::AddPlayer)
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 else
323 {
324 player_names[uuid] = infos.GetName();
325 }
326 }
327 }
328 else if (packet.GetAction() == PlayerInfoAction::UpdateDisplayName)
329 {
330 std::scoped_lock<std::shared_mutex> lock(player_names_mutex);
331 for (const auto& [uuid, infos] : packet.GetEntries())
332 {
333 if (infos.GetDisplayName().has_value())
334 {
335 player_names[uuid] = infos.GetDisplayName().value().GetText();
336 }
337 }
338 }
339 }
340#else
342 {
343 std::scoped_lock<std::shared_mutex> lock(player_names_mutex);
344 for (const auto& uuid : packet.GetProfileIds())
345 {
346 player_names.erase(uuid);
347 }
348 }
349
351 {
352 for (const auto& action : packet.GetActions())
353 {
354 if (action == PlayerInfoUpdateAction::AddPlayer)
355 {
356 std::scoped_lock<std::shared_mutex> lock(player_names_mutex);
357 for (const auto& [uuid, infos] : packet.GetEntries())
358 {
359 player_names[uuid] = infos.game_profile.GetName();
360 }
361 continue;
362 }
363 if (action == PlayerInfoUpdateAction::UpdateDisplayName)
364 {
365 std::scoped_lock<std::shared_mutex> lock(player_names_mutex);
366 for (const auto& [uuid, infos] : packet.GetEntries())
367 {
368 if (infos.display_name.has_value())
369 {
370 player_names[uuid] = infos.display_name.value().GetText();
371 }
372 }
373 }
374 }
375 }
376#endif
377} //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
int SendInventoryTransaction(const std::shared_ptr< ProtocolCraft::ServerboundContainerClickPacket > &transaction)
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