diff options
Diffstat (limited to 'src/gamestate')
-rw-r--r-- | src/gamestate/Game.cpp | 173 | ||||
-rw-r--r-- | src/gamestate/Game.hpp | 58 | ||||
-rw-r--r-- | src/gamestate/GameState.cpp | 1 | ||||
-rw-r--r-- | src/gamestate/GameState.hpp | 8 |
4 files changed, 240 insertions, 0 deletions
diff --git a/src/gamestate/Game.cpp b/src/gamestate/Game.cpp new file mode 100644 index 0000000..15f83e6 --- /dev/null +++ b/src/gamestate/Game.cpp @@ -0,0 +1,173 @@ +#include "Game.hpp" +#include "../packet/PacketParser.hpp" +#include "../packet/PacketBuilder.hpp" +#include <nlohmann/json.hpp> + +Game::Game() { + m_display = new Display(1280, 720, "AltCraft", &m_world); + m_nc = new NetworkClient("127.0.0.1", 25565, "HelloOne"); + Packet &response = *m_nc->GetPacket(); + if (response.GetId() != 0x02) { + std::cout << response.GetId() << std::endl; + throw 127; + } + PacketParser::Parse(response, Login); + g_PlayerUuid = response.GetField(0).GetString(); + g_PlayerName = response.GetField(1).GetString(); + delete &response; + m_networkState = ConnectionState::Play; + std::cout << g_PlayerName << "'s UUID is " << g_PlayerUuid << std::endl; +} + +Game::~Game() { + std::cout << "Stopping game thread..." << std::endl; + m_exit = true; + m_gameThread.join(); + std::cout << "Stopping graphics..." << std::endl; + delete m_display; + std::cout << "Stopping network..." << std::endl; + delete m_nc; +} + +void Game::MainLoop() { + while (!m_exit) { + + ParsePackets(); + if (m_display->IsClosed()) + m_exit = true; + } +} + +void Game::ParsePackets() { + Packet *packetPtr = m_nc->GetPacket(); + if (!packetPtr) { + using namespace std::chrono_literals; + std::this_thread::sleep_for(16ms); + return; + } + Packet packet = *packetPtr; + delete packetPtr; + PacketParser::Parse(packet); + nlohmann::json json; + //std::cout<<"Parsing packet: "<<std::hex<<packet.GetId()<<std::dec<<std::endl; + fflush(stdout); + + switch (packet.GetId()) { + case 0x23: + g_PlayerEid = packet.GetField(0).GetInt(); + g_Gamemode = (packet.GetField(1).GetUByte() & 0b11111011); + g_Dimension = packet.GetField(2).GetInt(); + g_Difficulty = packet.GetField(3).GetUByte(); + g_MaxPlayers = packet.GetField(4).GetUByte(); + g_LevelType = packet.GetField(5).GetString(); + g_ReducedDebugInfo = packet.GetField(6).GetBool(); + std::cout << "Gamemode is " << (int) g_Gamemode << ", Difficulty is " << (int) g_Difficulty + << ", Level Type is " << g_LevelType << std::endl; + break; + case 0x0D: + g_Difficulty = packet.GetField(0).GetUByte(); + std::cout << "Difficulty now is " << (int) g_Difficulty << std::endl; + break; + case 0x43: + g_SpawnPosition = packet.GetField(0).GetPosition(); + std::cout << "Spawn position is " << g_SpawnPosition.GetX() << "," << g_SpawnPosition.GetY() << "," + << g_SpawnPosition.GetZ() << std::endl; + break; + case 0x2B: + g_PlayerInvulnerable = (packet.GetField(0).GetByte() & 0x01) != 0; + g_PlayerFlying = (packet.GetField(0).GetByte() & 0x02) != 0; + g_PlayerAllowFlying = (packet.GetField(0).GetByte() & 0x04) != 0; + g_PlayerCreativeMode = (packet.GetField(0).GetByte() & 0x08) != 0; + g_PlayerFlyingSpeed = packet.GetField(1).GetFloat(); + g_PlayerFovModifier = packet.GetField(2).GetFloat(); + std::cout << "Fov modifier is " << g_PlayerFovModifier << std::endl; + break; + case 0x2E: + if ((packet.GetField(5).GetByte() & 0x10) != 0) { + g_PlayerPitch += packet.GetField(4).GetFloat(); + } else { + g_PlayerPitch = packet.GetField(4).GetFloat(); + }; + + if ((packet.GetField(5).GetByte() & 0x08) != 0) { + g_PlayerYaw += packet.GetField(3).GetFloat(); + } else { + g_PlayerYaw = packet.GetField(3).GetFloat(); + } + + if ((packet.GetField(5).GetByte() & 0x01) != 0) { + g_PlayerX += packet.GetField(0).GetDouble(); + } else { + g_PlayerX = packet.GetField(0).GetDouble(); + } + + if ((packet.GetField(5).GetByte() & 0x02) != 0) { + g_PlayerY += packet.GetField(1).GetDouble(); + } else { + g_PlayerY = packet.GetField(1).GetDouble(); + } + + if ((packet.GetField(5).GetByte() & 0x04) != 0) { + g_PlayerZ += packet.GetField(2).GetDouble(); + } else { + g_PlayerZ = packet.GetField(2).GetDouble(); + } + + g_IsGameStarted = true; + m_nc->AddPacketToQueue(PacketBuilder::CPlay0x03(0)); + m_nc->AddPacketToQueue(PacketBuilder::CPlay0x00(packet.GetField(6).GetVarInt())); + std::cout << "Game is started! " << std::endl; + std::cout << "PlayerPos is " << g_PlayerX << ", " << g_PlayerY << ", " << g_PlayerZ << "\tAngle: " + << g_PlayerYaw + << "," << g_PlayerPitch << std::endl; + m_display->SetPlayerPos(g_PlayerX, g_PlayerY, g_PlayerZ); + gameStartWaiter.notify_all(); + break; + case 0x1A: + json = nlohmann::json::parse(packet.GetField(0).GetString()); + std::cout << "Disconnect reason: " << json["text"].get<std::string>() << std::endl; + throw 119; + break; + case 0x20: + m_world.ParseChunkData(packet); + { + std::vector<Vector>vec; + for (auto &it:m_world.m_sections) { + for (auto& it2:vec){ + if (it2==it.first) + std::cout<<it.first<<std::endl; + } + vec.push_back(it.first); + } + } + break; + case 0x07: + std::cout << "Statistics:" << std::endl; + //int items = packet.GetField(0).GetVarInt(); + for (int i = 0; i < packet.GetField(0).GetVarInt(); i++) { + std::cout << "\t" << packet.GetField(1).GetArray()[0].GetString() << ": " + << packet.GetField(1).GetArray()[1].GetVarInt() << std::endl; + } + break; + default: + //std::cout << std::hex << packet.GetId() << std::dec << std::endl; + break; + } + if (g_IsGameStarted) { + std::chrono::steady_clock clock; + static auto timeOfPreviousSendedPpalPacket(clock.now()); + std::chrono::duration<double, std::milli> delta = clock.now() - timeOfPreviousSendedPpalPacket; + if (delta.count() >= 50) { + m_nc->AddPacketToQueue( + PacketBuilder::CPlay0x0D(g_PlayerX, g_PlayerY, g_PlayerZ, g_PlayerYaw, g_PlayerPitch, true)); + timeOfPreviousSendedPpalPacket = clock.now(); + /*std::cout << "PlayerPos is " << g_PlayerX << "," << g_PlayerY << "," << g_PlayerZ << " " << g_PlayerYaw + << "," << g_PlayerPitch << std::endl;*/ + } + } +} + +void Game::Exec() { + m_gameThread = std::thread(&Game::MainLoop, this); + m_display->MainLoop(); +} diff --git a/src/gamestate/Game.hpp b/src/gamestate/Game.hpp new file mode 100644 index 0000000..adf9059 --- /dev/null +++ b/src/gamestate/Game.hpp @@ -0,0 +1,58 @@ +#pragma once + +#include "../utility/Vector.hpp" +#include "../network/NetworkClient.hpp" +#include "../world/World.hpp" +#include "../graphics/Display.hpp" + +class Game { +public: + Game(); + + ~Game(); + + void Exec(); + +private: + //utility variables + NetworkClient *m_nc; + std::thread m_ncThread; + bool m_exit = false; + ConnectionState m_networkState = ConnectionState::Handshaking; + Display *m_display; + std::thread m_gameThread; + + //utility methods + void ParsePackets(); + void MainLoop(); + + //GameState update - condVars + std::condition_variable gameStartWaiter; + + //game state variables + World m_world; + + std::string g_PlayerUuid; + std::string g_PlayerName; + int g_PlayerEid; + byte g_Gamemode; + byte g_Difficulty; + int g_Dimension; + byte g_MaxPlayers; + std::string g_LevelType; + bool g_ReducedDebugInfo; + Vector g_SpawnPosition; + bool g_PlayerInvulnerable; + bool g_PlayerFlying; + bool g_PlayerAllowFlying; + bool g_PlayerCreativeMode; + int g_PlayerFlyingSpeed; + int g_PlayerFovModifier; + bool g_IsGameStarted = false; + float g_PlayerPitch; + float g_PlayerYaw; + double g_PlayerX; + double g_PlayerY; + double g_PlayerZ; +}; + diff --git a/src/gamestate/GameState.cpp b/src/gamestate/GameState.cpp new file mode 100644 index 0000000..7bcc2d5 --- /dev/null +++ b/src/gamestate/GameState.cpp @@ -0,0 +1 @@ +#include "GameState.hpp" diff --git a/src/gamestate/GameState.hpp b/src/gamestate/GameState.hpp new file mode 100644 index 0000000..e9c433d --- /dev/null +++ b/src/gamestate/GameState.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include "../world/World.hpp" + +class GameState { +public: + World world; +}; |