10-01-2019, 01:15 AM
(10-01-2019, 12:40 AM)xoft Wrote: You're right, that's a mess, but there is some advice I can give.This is very helpful but I dont want any API or premade stuff I dont know how the bytebuffer class works thats the main part I have been struggling with
Use a library that provides event-driven networking. The Minecraft protocol isn't a classical dialog-driven protocol, either side may send any data at any time, so you really need to be processing the data as two separate streams. You can't really expect to call recv() and have all the data you ask for.
If you do decide to stay with raw winsock, you'll at least need two threads, one for reading, another for writing (or a more sophisticated machinery, such as select(), which is btw. a bad idea altogether).
Then you need to organize your code. You have one giant function called start that does basically everything. You should instead have a separate function for sending each packet, so that your main function (in the writer thread) looks something like:
void writerMain() { sendHandshake(1); // Status = 1 in that handshake sendRequest(); waitForResponse(); // waits for the Reader thread to finish reading a response packet sendPing(); // ... }
On the other side, the reader function needs to read individual packets and react to them. In pseudo-code:
void readerMain() { Buffer byteBuffer; while (true) { receiveToBuffer(byteBuffer); while (true) { if (!extractAndHandlePacket(byteBuffer)) { break; } } } } void receiveToBuffer(Buffer aBuffer) { // Append incoming network data to aBuffer char recvBuffer[1024]; auto numRecvd = recv(socket, recvBuffer, sizeof(recvBuffer); aBuffer.append(recvBuffer, numRecvd); } /** Returns true if a whole packet was extracted, false if incomplete. */ bool extractAndHandlePacket(Buffer aBuffer) { auto packetType = aBuffer.read(...); auto packetLen = aBuffer.read(...); if (packetLen > aBuffer.numUsedBytes() - headerSize) { // Incomplete packet return false; } Packet pkt(aBuffer.data() + headerSize, packetLen); handlePacket(pkt); aBuffer.erase(packetLen + headerSize); }