From 8e71de537636dbeb0be9d018a8518e49a7e8e667 Mon Sep 17 00:00:00 2001 From: LaG1924 <12997935+LaG1924@users.noreply.github.com> Date: Wed, 29 Jul 2020 08:26:36 +0500 Subject: Improved uncompressed chunks decoding --- src/Section.cpp | 8 ++++---- src/World.cpp | 7 ++++++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Section.cpp b/src/Section.cpp index 4a15c58..1d9c203 100644 --- a/src/Section.cpp +++ b/src/Section.cpp @@ -61,16 +61,16 @@ BlockId Section::GetBlockId(Vector pos) const { return iter->second; } - int value; + unsigned int value; - unsigned char individualValueMask = ((1 << bitsPerBlock) - 1); + unsigned int individualValueMask = ((1 << (unsigned int)bitsPerBlock) - 1); int blockNumber = (((pos.y * 16) + pos.z) * 16) + pos.x; int startLong = (blockNumber * bitsPerBlock) / 64; int startOffset = (blockNumber * bitsPerBlock) % 64; int endLong = ((blockNumber + 1) * bitsPerBlock - 1) / 64; - unsigned char t; + unsigned int t; if (startLong == endLong) { t = (block[startLong] >> startOffset); @@ -85,7 +85,7 @@ BlockId Section::GetBlockId(Vector pos) const { if (t >= palette.size()) { //LOG(ERROR) << "Out of palette: " << t; - value = 0; + value = t; } else value = palette[t]; diff --git a/src/World.cpp b/src/World.cpp index d767871..c3246dc 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -378,7 +378,12 @@ void World::SetBlockId(Vector pos, BlockId block) { std::floor(pos.y / 16.0), std::floor(pos.z / 16.0)); Vector blockPos = pos - (sectionPos * 16); - auto section = std::make_shared
(*GetSectionPtr(sectionPos)); + const Section* sectionPtr = GetSectionPtr(sectionPos); + if (!sectionPtr) { + LOG(ERROR) << "Updating unloaded chunk " << sectionPos; + return; + } + auto section = std::make_shared
(*sectionPtr); section->SetBlockId(blockPos, block); sections[sectionPos] = section; PUSH_EVENT("ChunkChanged",sectionPos); -- cgit v1.2.3 From 3f9ce9f54d342bfaba1f41bb0d6b18aa9cf11a43 Mon Sep 17 00:00:00 2001 From: LaG1924 <12997935+LaG1924@users.noreply.github.com> Date: Thu, 30 Jul 2020 04:34:25 +0500 Subject: Implemented async connection to server --- src/Game.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/src/Game.cpp b/src/Game.cpp index c69ff5d..f0266d4 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -18,35 +18,61 @@ std::unique_ptr render; std::unique_ptr timer; EventListener listener; -void InitEvents() { - /* - * Network Events - */ +std::thread connThread; +std::unique_ptr connNc; +std::unique_ptr connGs; + +void ConnectionThreadExec() { + EventListener connListener; - listener.RegisterHandler("ConnectToServer", [](const Event & eventData) { + bool connRun = true; + + connListener.RegisterHandler("ConnectToServer", [](const Event& eventData) { auto data = eventData.get >(); //address,port,username if (std::get<0>(data) == "" || std::get<1>(data) == 0) LOG(FATAL) << "NOT VALID CONNECT-TO-SERVER EVENT"; - if (nc != nullptr) { + if (connNc != nullptr) { LOG(ERROR) << "Already connected"; return; } LOG(INFO) << "Connecting to server at address " + std::get<0>(data) + ":" + std::to_string(std::get<1>(data)) + " as " + std::get<2>(data); - PUSH_EVENT("Connecting",0); - gs = std::make_unique(); + PUSH_EVENT("Connecting", 0); + connGs = std::make_unique(); try { - nc = std::make_unique(std::get<0>(data), + connNc = std::make_unique(std::get<0>(data), std::get<1>(data), std::get<2>(data)); - } catch (std::exception &e) { + } + catch (std::exception& e) { LOG(WARNING) << "Connection failed"; PUSH_EVENT("ConnectionFailed", std::string(e.what())); - gs.reset(); + connGs.reset(); return; } LOG(INFO) << "Connected to server"; PUSH_EVENT("ConnectionSuccessfull", 0); - }); + }); + + connListener.RegisterHandler("Exit", [&](const Event&) { + connRun = false; + }); + + LoopExecutionTimeController timer(std::chrono::milliseconds(50)); + while (connRun) { + connListener.HandleAllEvents(); + timer.Update(); + } +} + +void InitEvents() { + /* + * Network Events + */ + + listener.RegisterHandler("ConnectionSuccessfull", [](const Event&) { + nc = std::move(connNc); + gs = std::move(connGs); + }); listener.RegisterHandler("Disconnect", [](const Event& eventData) { auto data = eventData.get(); @@ -186,6 +212,8 @@ void RunGame() { render = std::make_unique(900, 480, "AltCraft"); + connThread = std::thread(ConnectionThreadExec); + SetState(State::MainMenu); while (isRunning) { @@ -212,6 +240,8 @@ void RunGame() { } render.reset(); + + connThread.join(); } State GetState() { -- cgit v1.2.3 From 70c32d288fa2134c63c70964611da646fcdfe4e9 Mon Sep 17 00:00:00 2001 From: LaG1924 <12997935+LaG1924@users.noreply.github.com> Date: Thu, 30 Jul 2020 04:36:24 +0500 Subject: Minor protocol support improvement --- src/GameState.cpp | 10 +++++++++ src/Packet.hpp | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/src/GameState.cpp b/src/GameState.cpp index fdb453f..03b13ae 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -268,6 +268,16 @@ void GameState::UpdatePacket(std::shared_ptr ptr) { LOG(INFO) << "Gamemode is " << gameStatus.gamemode << ", Difficulty is " << (int)gameStatus.difficulty << ", Level Type is " << gameStatus.levelType; PUSH_EVENT("PlayerConnected", 0); + + auto packetSettings = std::make_shared("en_us", 0x14, 0, true, 0x7F, 1); + PUSH_EVENT("SendPacket", std::static_pointer_cast(packetSettings)); + + std::string brandStr("\x08""AltCraft"); + std::vector brandData; + std::copy(brandStr.begin(), brandStr.end(), std::back_inserter(brandData)); + auto packetPluginBrand = std::make_shared("MC|Brand", brandData); + PUSH_EVENT("SendPacket", std::static_pointer_cast(packetPluginBrand)); + break; } diff --git a/src/Packet.hpp b/src/Packet.hpp index cca01ec..ccc486f 100644 --- a/src/Packet.hpp +++ b/src/Packet.hpp @@ -1169,3 +1169,64 @@ struct PacketRespawn : Packet { unsigned char Gamemode; std::string LevelType; }; + +struct PacketPluginMessageSB : Packet { + void ToStream(StreamOutput* stream) override { + stream->WriteString(Channel); + stream->WriteByteArray(Data); + } + + void FromStream(StreamInput* stream) override { + + } + + int GetPacketId() override { + return PacketNamePlaySB::PluginMessageSB; + } + + PacketPluginMessageSB(const std::string& channel, const std::vector data) : Channel(channel), Data(data) {} + + std::string Channel; + std::vector Data; +}; + +struct PacketClientSettings : Packet { + void ToStream(StreamOutput* stream) override { + stream->WriteString(Locale); + stream->WriteByte(ViewDistance); + stream->WriteVarInt(ChatMode); + stream->WriteBool(ChatColors); + stream->WriteUByte(DisplayedSkinParts); + stream->WriteVarInt(MainHand); + } + + void FromStream(StreamInput* stream) override { + + } + + int GetPacketId() override { + return PacketNamePlaySB::ClientSettings; + } + + PacketClientSettings( + const std::string locale, + unsigned char viewDistance, + int chatMode, + bool chatColors, + unsigned char displayedSkinParts, + int mainHand) : + Locale(locale), + ViewDistance(viewDistance), + ChatMode(chatMode), + ChatColors(chatColors), + DisplayedSkinParts(displayedSkinParts), + MainHand(mainHand) {} + + std::string Locale; + unsigned char ViewDistance; + int ChatMode; + bool ChatColors; + unsigned char DisplayedSkinParts; + int MainHand; +}; + -- cgit v1.2.3 From 1f49e7e4350298dad2e0a6e340b608a80a625e4b Mon Sep 17 00:00:00 2001 From: LaG1924 <12997935+LaG1924@users.noreply.github.com> Date: Thu, 30 Jul 2020 04:38:19 +0500 Subject: Network usage optimization --- src/Network.cpp | 3 ++- src/Stream.cpp | 9 +++++++-- src/Stream.hpp | 3 +++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Network.cpp b/src/Network.cpp index bb92e7f..4280b50 100644 --- a/src/Network.cpp +++ b/src/Network.cpp @@ -98,7 +98,8 @@ void Network::SendPacket(Packet &packet, int compressionThreshold) { stream->WriteVarInt(packetSize.GetCountedSize()); stream->WriteVarInt(packet.GetPacketId()); packet.ToStream(stream.get()); - } + } + stream->Flush(); } std::shared_ptr Network::ReceivePacketByPacketId(int packetId, ConnectionState state, StreamInput &stream) { diff --git a/src/Stream.cpp b/src/Stream.cpp index efe37d2..5c99724 100644 --- a/src/Stream.cpp +++ b/src/Stream.cpp @@ -360,9 +360,14 @@ void StreamSocket::ReadData(unsigned char *buffPtr, size_t buffLen) { } void StreamSocket::WriteData(unsigned char *buffPtr, size_t buffLen) { - socket->Write(buffPtr, buffLen); + std::copy(buffPtr, buffPtr + buffLen, std::back_inserter(buffer)); } StreamSocket::StreamSocket(Socket *socketPtr) : socket(socketPtr) { -} \ No newline at end of file +} + +void StreamSocket::Flush() { + socket->Write(buffer.data(), buffer.size()); + buffer.clear(); +} diff --git a/src/Stream.hpp b/src/Stream.hpp index a7c161b..9b6e5ff 100644 --- a/src/Stream.hpp +++ b/src/Stream.hpp @@ -100,9 +100,12 @@ public: class StreamSocket : public StreamInput, public StreamOutput { Socket *socket; + std::vector buffer; void ReadData(unsigned char *buffPtr, size_t buffLen) override; void WriteData(unsigned char *buffPtr, size_t buffLen) override; public: StreamSocket(Socket *socketPtr); ~StreamSocket() = default; + + void Flush(); }; \ No newline at end of file -- cgit v1.2.3 From f561980fecbfcda4d2ee2fafbe01991a974ca141 Mon Sep 17 00:00:00 2001 From: LaG1924 <12997935+LaG1924@users.noreply.github.com> Date: Thu, 30 Jul 2020 04:46:07 +0500 Subject: Improved connection exceptions handling --- src/NetworkClient.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/NetworkClient.cpp b/src/NetworkClient.cpp index 6273937..ee79fb9 100644 --- a/src/NetworkClient.cpp +++ b/src/NetworkClient.cpp @@ -24,17 +24,29 @@ NetworkClient::NetworkClient(std::string address, unsigned short port, std::stri auto packet = network->ReceivePacket(Login); - while (!packet) - packet = network->ReceivePacket(Login); + for (int i = 0; i < 10 && !packet; i++) + packet = network->ReceivePacket(Login); + if (!packet) + throw std::runtime_error("Server not answered after LoginStart"); if (packet->GetPacketId() == PacketNameLoginCB::SetCompression) { auto compPacket = std::static_pointer_cast(packet); LOG(INFO) << "Compression threshold: " << compPacket->Threshold; compressionThreshold = compPacket->Threshold; packet.reset(); - while (!packet) - packet = network->ReceivePacket(Login, compressionThreshold >= 0); + for (int i = 0; i < 10 && !packet; i++) + packet = network->ReceivePacket(Login, compressionThreshold >= 0); + if (!packet) + throw std::runtime_error("Server not answered after SetCompression"); } + else if (packet->GetPacketId() == PacketNameLoginCB::Disconnect) { + auto disconnectPacket = std::static_pointer_cast(packet); + LOG(INFO) << "Server not allowed connection: " << disconnectPacket->Reason; + throw std::runtime_error(disconnectPacket->Reason); + } + else if (packet->GetPacketId() != PacketNameLoginCB::LoginSuccess) { + throw std::runtime_error("Unexpected packet type: " + std::to_string(packet->GetPacketId())); + } auto response = std::static_pointer_cast(packet); -- cgit v1.2.3 From 99267ff981c080e2c0b96c38af54a9b8c0623e66 Mon Sep 17 00:00:00 2001 From: LaG1924 <12997935+LaG1924@users.noreply.github.com> Date: Thu, 30 Jul 2020 05:07:56 +0500 Subject: Corrected Game Start conditions --- src/GameState.cpp | 29 ++++++++++++++++++++--------- src/GameState.hpp | 7 +++++++ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/GameState.cpp b/src/GameState.cpp index 03b13ae..3d1714b 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -9,6 +9,22 @@ void GameState::Update(double deltaTime) { OPTICK_EVENT(); + + if (!gameStatus.isGameStarted) { + if (!receivedEnoughChunks) { + receivedEnoughChunks = world.GetSectionsList().size() >= 49; + } + + if (receivedJoinGame && receivedEnoughChunks && receivedFirstPlayerPosAndLook) { + gameStatus.isGameStarted = true; + LOG(INFO) << "Game is started"; + PUSH_EVENT("RemoveLoadingScreen", 0); + + auto packetPerformRespawn = std::make_shared(0); + PUSH_EVENT("SendPacket", std::static_pointer_cast(packetPerformRespawn)); + } + } + if (!gameStatus.isGameStarted) return; @@ -269,6 +285,8 @@ void GameState::UpdatePacket(std::shared_ptr ptr) { << ", Level Type is " << gameStatus.levelType; PUSH_EVENT("PlayerConnected", 0); + receivedJoinGame = true; + auto packetSettings = std::make_shared("en_us", 0x14, 0, true, 0x7F, 1); PUSH_EVENT("SendPacket", std::static_pointer_cast(packetSettings)); @@ -364,18 +382,11 @@ void GameState::UpdatePacket(std::shared_ptr ptr) { PUSH_EVENT("PlayerPosChanged", player->pos); LOG(INFO) << "PlayerPos is " << player->pos << "\t\tAngle: " << player->yaw << "," << player->pitch;; - if (!gameStatus.isGameStarted) { - LOG(INFO) << "Game is started"; - PUSH_EVENT("RemoveLoadingScreen", 0); - } - - gameStatus.isGameStarted = true; + receivedFirstPlayerPosAndLook = true; auto packetResponse = std::make_shared(packet->TeleportId); - auto packetPerformRespawn = std::make_shared(0); - PUSH_EVENT("SendPacket", std::static_pointer_cast(packetResponse)); - PUSH_EVENT("SendPacket", std::static_pointer_cast(packetPerformRespawn)); + break; } diff --git a/src/GameState.hpp b/src/GameState.hpp index 5489ac6..0ca858f 100644 --- a/src/GameState.hpp +++ b/src/GameState.hpp @@ -68,6 +68,13 @@ class GameState { Window playerInventory; std::vector openedWindows; + + bool receivedJoinGame = false; + + bool receivedEnoughChunks = false; + + bool receivedFirstPlayerPosAndLook = false; + public: void Update(double deltaTime); -- cgit v1.2.3