ensure all bytes are sent on non-blocking socket

This commit is contained in:
p2r3
2025-08-20 05:08:57 +03:00
parent 48b6c7cfb4
commit 023b866529
3 changed files with 47 additions and 22 deletions

View File

@@ -60,9 +60,9 @@ int sc_loginSuccess (int client_fd, uint8_t *uuid, char *name) {
uint8_t name_length = strlen(name); uint8_t name_length = strlen(name);
writeVarInt(client_fd, 1 + 16 + sizeVarInt(name_length) + name_length + 1); writeVarInt(client_fd, 1 + 16 + sizeVarInt(name_length) + name_length + 1);
writeVarInt(client_fd, 0x02); writeVarInt(client_fd, 0x02);
send(client_fd, uuid, 16, 0); send_all(client_fd, uuid, 16);
writeVarInt(client_fd, name_length); writeVarInt(client_fd, name_length);
send(client_fd, name, name_length, 0); send_all(client_fd, name, name_length);
writeVarInt(client_fd, 0); writeVarInt(client_fd, 0);
return 0; return 0;
@@ -115,7 +115,7 @@ int sc_knownPacks (int client_fd) {
0x2e, 0x38 0x2e, 0x38
}; };
writeVarInt(client_fd, 24); writeVarInt(client_fd, 24);
send(client_fd, &known_packs, 24, 0); send_all(client_fd, &known_packs, 24);
return 0; return 0;
} }
@@ -148,14 +148,14 @@ int sc_loginPlay (int client_fd) {
writeByte(client_fd, 0x2B); writeByte(client_fd, 0x2B);
// entity id // entity id
uint32_t entity_id = getClientIndex(client_fd); uint32_t entity_id = getClientIndex(client_fd);
send(client_fd, &entity_id, 4, 0); send_all(client_fd, &entity_id, 4);
// hardcore // hardcore
writeByte(client_fd, false); writeByte(client_fd, false);
// dimensions // dimensions
writeVarInt(client_fd, 1); writeVarInt(client_fd, 1);
writeVarInt(client_fd, 19); writeVarInt(client_fd, 19);
const char *dimension = "minecraft:overworld"; const char *dimension = "minecraft:overworld";
send(client_fd, dimension, 19, 0); send_all(client_fd, dimension, 19);
// maxplayers // maxplayers
writeVarInt(client_fd, MAX_PLAYERS); writeVarInt(client_fd, MAX_PLAYERS);
// view distance // view distance
@@ -172,7 +172,7 @@ int sc_loginPlay (int client_fd) {
writeVarInt(client_fd, 0); writeVarInt(client_fd, 0);
// dimension name // dimension name
writeVarInt(client_fd, 19); writeVarInt(client_fd, 19);
send(client_fd, dimension, 19, 0); send_all(client_fd, dimension, 19);
// hashed seed // hashed seed
writeUint64(client_fd, 0x0123456789ABCDEF); writeUint64(client_fd, 0x0123456789ABCDEF);
// gamemode // gamemode
@@ -318,10 +318,10 @@ int sc_chunkDataAndUpdateLight (int client_fd, int _x, int _z) {
writeByte(client_fd, 8); // bits per entry writeByte(client_fd, 8); // bits per entry
writeVarInt(client_fd, 256); // block palette length writeVarInt(client_fd, 256); // block palette length
// block palette as varint buffer // block palette as varint buffer
send(client_fd, network_block_palette, sizeof(network_block_palette), 0); send_all(client_fd, network_block_palette, sizeof(network_block_palette));
// chunk section buffer // chunk section buffer
buildChunkSection(x, y, z); buildChunkSection(x, y, z);
send(client_fd, chunk_section, 4096, 0); send_all(client_fd, chunk_section, 4096);
// biome data // biome data
writeByte(client_fd, 0); // bits per entry writeByte(client_fd, 0); // bits per entry
writeByte(client_fd, W_plains); // biome palette writeByte(client_fd, W_plains); // biome palette
@@ -355,11 +355,11 @@ int sc_chunkDataAndUpdateLight (int client_fd, int _x, int _z) {
for (int i = 2048; i < 4096; i ++) chunk_section[i] = 0; for (int i = 2048; i < 4096; i ++) chunk_section[i] = 0;
for (int i = 0; i < 8; i ++) { for (int i = 0; i < 8; i ++) {
writeVarInt(client_fd, 2048); writeVarInt(client_fd, 2048);
send(client_fd, chunk_section + 2048, 2048, 0); send_all(client_fd, chunk_section + 2048, 2048);
} }
for (int i = 0; i < 18; i ++) { for (int i = 0; i < 18; i ++) {
writeVarInt(client_fd, 2048); writeVarInt(client_fd, 2048);
send(client_fd, chunk_section, 2048, 0); send_all(client_fd, chunk_section, 2048);
} }
// don't send block light // don't send block light
writeVarInt(client_fd, 0); writeVarInt(client_fd, 0);
@@ -472,7 +472,7 @@ int sc_openScreen (int client_fd, uint8_t window, const char *title, uint16_t le
writeByte(client_fd, 8); // string nbt tag writeByte(client_fd, 8); // string nbt tag
writeUint16(client_fd, length); // string length writeUint16(client_fd, length); // string length
send(client_fd, title, length, 0); send_all(client_fd, title, length);
return 0; return 0;
} }
@@ -716,10 +716,10 @@ int sc_playerInfoUpdateAddPlayer (int client_fd, PlayerData player) {
writeByte(client_fd, 1); // Player count (1 per packet) writeByte(client_fd, 1); // Player count (1 per packet)
// Player UUID // Player UUID
send(client_fd, player.uuid, 16, 0); send_all(client_fd, player.uuid, 16);
// Player name // Player name
writeByte(client_fd, strlen(player.name)); writeByte(client_fd, strlen(player.name));
send(client_fd, player.name, strlen(player.name), 0); send_all(client_fd, player.name, strlen(player.name));
// Properties (don't send any) // Properties (don't send any)
writeByte(client_fd, 0); writeByte(client_fd, 0);
@@ -738,7 +738,7 @@ int sc_spawnEntity (
writeByte(client_fd, 0x01); writeByte(client_fd, 0x01);
writeVarInt(client_fd, id); // Entity ID writeVarInt(client_fd, id); // Entity ID
send(client_fd, uuid, 16, 0); // Entity UUID send_all(client_fd, uuid, 16); // Entity UUID
writeVarInt(client_fd, type); // Entity type writeVarInt(client_fd, type); // Entity type
// Position // Position
@@ -837,10 +837,10 @@ int sc_updateEntityRotation (int client_fd, int id, uint8_t yaw, uint8_t pitch)
int sc_registries (int client_fd) { int sc_registries (int client_fd) {
printf("Sending Registries\n\n"); printf("Sending Registries\n\n");
send(client_fd, registries_bin, sizeof(registries_bin), 0); send_all(client_fd, registries_bin, sizeof(registries_bin));
printf("Sending Tags\n\n"); printf("Sending Tags\n\n");
send(client_fd, tags_bin, sizeof(tags_bin), 0); send_all(client_fd, tags_bin, sizeof(tags_bin));
return 0; return 0;

View File

@@ -63,32 +63,56 @@ ssize_t recv_all (int client_fd, void *buf, size_t n, uint8_t require_first) {
return total; // got exactly n bytes return total; // got exactly n bytes
} }
ssize_t send_all (int fd, const void *buf, size_t len) {
const uint8_t *p = (const uint8_t *)buf;
size_t sent = 0;
while (sent < len) {
ssize_t n = send(fd, p + sent, len - sent, MSG_NOSIGNAL);
if (n > 0) {
sent += (size_t)n;
continue;
}
if (n == 0) {
errno = ECONNRESET;
return -1;
}
if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
wdt_reset();
continue;
}
return -1;
}
return 0;
}
ssize_t writeByte (int client_fd, uint8_t byte) { ssize_t writeByte (int client_fd, uint8_t byte) {
return send(client_fd, &byte, 1, 0); return send_all(client_fd, &byte, 1);
} }
ssize_t writeUint16 (int client_fd, uint16_t num) { ssize_t writeUint16 (int client_fd, uint16_t num) {
uint16_t be = htons(num); uint16_t be = htons(num);
return send(client_fd, &be, sizeof(be), 0); return send_all(client_fd, &be, sizeof(be));
} }
ssize_t writeUint32 (int client_fd, uint32_t num) { ssize_t writeUint32 (int client_fd, uint32_t num) {
uint32_t be = htonl(num); uint32_t be = htonl(num);
return send(client_fd, &be, sizeof(be), 0); return send_all(client_fd, &be, sizeof(be));
} }
ssize_t writeUint64 (int client_fd, uint64_t num) { ssize_t writeUint64 (int client_fd, uint64_t num) {
uint64_t be = htonll(num); uint64_t be = htonll(num);
return send(client_fd, &be, sizeof(be), 0); return send_all(client_fd, &be, sizeof(be));
} }
ssize_t writeFloat (int client_fd, float num) { ssize_t writeFloat (int client_fd, float num) {
uint32_t bits; uint32_t bits;
memcpy(&bits, &num, sizeof(bits)); memcpy(&bits, &num, sizeof(bits));
bits = htonl(bits); bits = htonl(bits);
return send(client_fd, &bits, sizeof(bits), 0); return send_all(client_fd, &bits, sizeof(bits));
} }
ssize_t writeDouble (int client_fd, double num) { ssize_t writeDouble (int client_fd, double num) {
uint64_t bits; uint64_t bits;
memcpy(&bits, &num, sizeof(bits)); memcpy(&bits, &num, sizeof(bits));
bits = htonll(bits); bits = htonll(bits);
return send(client_fd, &bits, sizeof(bits), 0); return send_all(client_fd, &bits, sizeof(bits));
} }
uint8_t readByte (int client_fd) { uint8_t readByte (int client_fd) {

View File

@@ -7,6 +7,7 @@
#include "globals.h" #include "globals.h"
ssize_t recv_all (int client_fd, void *buf, size_t n, uint8_t require_first); ssize_t recv_all (int client_fd, void *buf, size_t n, uint8_t require_first);
ssize_t send_all (int fd, const void *buf, size_t len);
ssize_t writeByte (int client_fd, uint8_t byte); ssize_t writeByte (int client_fd, uint8_t byte);
ssize_t writeUint16 (int client_fd, uint16_t num); ssize_t writeUint16 (int client_fd, uint16_t num);