Finalize Cross-Platform Protocol v2.0.3
This commit is contained in:
parent
86fc77bfd7
commit
446e9ae771
Binary file not shown.
|
|
@ -1 +1 @@
|
|||
v2.0.0
|
||||
v2.0.2
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1 +1 @@
|
|||
v2.0.0
|
||||
v2.0.2
|
||||
|
|
|
|||
161
src/main.cpp
161
src/main.cpp
|
|
@ -733,7 +733,7 @@ int main(void)
|
|||
// By default, windows have minimize, maximize, and close buttons on the top bar.
|
||||
SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_VSYNC_HINT);
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "MorriCraft v2.0.2");
|
||||
InitWindow(screenWidth, screenHeight, "MorriCraft v2.0.3");
|
||||
LoadConfig();
|
||||
SetExitKey(KEY_NULL); // Prevent ESC from closing the window
|
||||
|
||||
|
|
@ -966,57 +966,91 @@ int main(void)
|
|||
|
||||
// Handle incoming data
|
||||
auto handleIncoming = [&](Socket sock, bool isServer, int clientIdx = -1) {
|
||||
PacketHeader head;
|
||||
int bytes = recv(sock, (char*)&head, sizeof(head), 0);
|
||||
if (bytes > 0) {
|
||||
while (true) {
|
||||
// Use a quick non-blocking check to see if more data is available
|
||||
fd_set readfds;
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(sock, &readfds);
|
||||
struct timeval tv = {0, 0};
|
||||
if (select((int)sock + 1, &readfds, NULL, NULL, &tv) <= 0) break;
|
||||
|
||||
PacketHeader head;
|
||||
int bytes = recv(sock, (char*)&head, sizeof(head), 0);
|
||||
if (bytes <= 0) {
|
||||
if (isServer && clientIdx != -1) {
|
||||
std::string leaver = "A player";
|
||||
for (auto it = remotePlayers.begin(); it != remotePlayers.end(); ++it) {
|
||||
if (it->sock == sock) {
|
||||
leaver = it->name;
|
||||
remotePlayers.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
chatLog.push_back({ leaver + " left the game", 5.0f });
|
||||
PacketHeader nHead = { (uint8_t)PACKET_CHAT, (uint32_t)sizeof(PacketChat) };
|
||||
PacketChat nChat;
|
||||
strncpy(nChat.name, "Server", 31);
|
||||
strncpy(nChat.message, (leaver + " left the game").c_str(), 127);
|
||||
for (auto& s : clientSockets) {
|
||||
if (s != sock) {
|
||||
send(s, (char*)&nHead, sizeof(nHead), 0);
|
||||
send(s, (char*)&nChat, sizeof(nChat), 0);
|
||||
}
|
||||
}
|
||||
closesocket(sock);
|
||||
clientSockets.erase(clientSockets.begin() + clientIdx);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (head.type == PACKET_HANDSHAKE) {
|
||||
PacketHandshake hand;
|
||||
recv(sock, (char*)&hand, sizeof(hand), 0);
|
||||
if (isServer) {
|
||||
uint32_t newID = (uint32_t)sock;
|
||||
RemotePlayer rp;
|
||||
rp.sock = sock;
|
||||
rp.id = newID;
|
||||
rp.name = hand.name;
|
||||
rp.position = (Vector3){0,0,0};
|
||||
remotePlayers.push_back(rp);
|
||||
|
||||
// Notify others
|
||||
chatLog.push_back({ std::string(hand.name) + " joined the game", 5.0f });
|
||||
PacketHeader nHead = { (uint8_t)PACKET_CHAT, (uint32_t)sizeof(PacketChat) };
|
||||
PacketChat nChat;
|
||||
strncpy(nChat.name, "Server", 31);
|
||||
strncpy(nChat.message, (std::string(hand.name) + " joined the game").c_str(), 127);
|
||||
for (auto& s : clientSockets) {
|
||||
send(s, (char*)&nHead, sizeof(nHead), 0);
|
||||
send(s, (char*)&nChat, sizeof(nChat), 0);
|
||||
}
|
||||
|
||||
// Send seed and time to new client
|
||||
PacketHeader sHead = { (uint8_t)PACKET_SEED_SYNC, (uint32_t)sizeof(PacketSeedSync) };
|
||||
PacketSeedSync sData = { (int)globalSeedHash };
|
||||
send(sock, (char*)&sHead, sizeof(sHead), 0);
|
||||
send(sock, (char*)&sData, sizeof(sData), 0);
|
||||
|
||||
PacketHeader tHead = { (uint8_t)PACKET_TIME_SYNC, (uint32_t)sizeof(PacketTimeSync) };
|
||||
PacketTimeSync tData = { gameTime };
|
||||
send(sock, (char*)&tHead, sizeof(tHead), 0);
|
||||
send(sock, (char*)&tData, sizeof(tData), 0);
|
||||
|
||||
// Send existing players to new client
|
||||
for (auto& rp : remotePlayers) {
|
||||
if (rp.sock != sock) {
|
||||
PacketHeader pHead = { (uint8_t)PACKET_PLAYER_UPDATE, (uint32_t)sizeof(PacketPlayerUpdate) };
|
||||
PacketPlayerUpdate pData = { rp.position.x, rp.position.y, rp.position.z, rp.yaw, rp.id };
|
||||
send(sock, (char*)&pHead, sizeof(pHead), 0);
|
||||
send(sock, (char*)&pData, sizeof(pData), 0);
|
||||
bool duplicate = false;
|
||||
for (auto& rp : remotePlayers) { if (rp.sock == sock) { duplicate = true; break; } }
|
||||
if (!duplicate) {
|
||||
uint32_t newID = (uint32_t)sock;
|
||||
RemotePlayer rp;
|
||||
rp.sock = sock;
|
||||
rp.id = newID;
|
||||
rp.name = hand.name;
|
||||
rp.position = (Vector3){0,0,0};
|
||||
remotePlayers.push_back(rp);
|
||||
|
||||
chatLog.push_back({ std::string(hand.name) + " joined the game", 5.0f });
|
||||
PacketHeader nHead = { (uint8_t)PACKET_CHAT, (uint32_t)sizeof(PacketChat) };
|
||||
PacketChat nChat;
|
||||
strncpy(nChat.name, "Server", 31);
|
||||
strncpy(nChat.message, (std::string(hand.name) + " joined the game").c_str(), 127);
|
||||
for (auto& s : clientSockets) {
|
||||
send(s, (char*)&nHead, sizeof(nHead), 0);
|
||||
send(s, (char*)&nChat, sizeof(nChat), 0);
|
||||
}
|
||||
|
||||
PacketHeader sHead = { (uint8_t)PACKET_SEED_SYNC, (uint32_t)sizeof(PacketSeedSync) };
|
||||
PacketSeedSync sData = { (int)globalSeedHash };
|
||||
send(sock, (char*)&sHead, sizeof(sHead), 0);
|
||||
send(sock, (char*)&sData, sizeof(sData), 0);
|
||||
|
||||
PacketHeader tHead = { (uint8_t)PACKET_TIME_SYNC, (uint32_t)sizeof(PacketTimeSync) };
|
||||
PacketTimeSync tData = { gameTime };
|
||||
send(sock, (char*)&tHead, sizeof(tHead), 0);
|
||||
send(sock, (char*)&tData, sizeof(tData), 0);
|
||||
|
||||
for (auto& existing : remotePlayers) {
|
||||
if (existing.sock != sock) {
|
||||
PacketHeader pHead = { (uint8_t)PACKET_PLAYER_UPDATE, (uint32_t)sizeof(PacketPlayerUpdate) };
|
||||
PacketPlayerUpdate pData = { existing.position.x, existing.position.y, existing.position.z, existing.yaw, existing.id };
|
||||
send(sock, (char*)&pHead, sizeof(pHead), 0);
|
||||
send(sock, (char*)&pData, sizeof(pData), 0);
|
||||
}
|
||||
}
|
||||
PacketHeader hHead = { (uint8_t)PACKET_PLAYER_UPDATE, (uint32_t)sizeof(PacketPlayerUpdate) };
|
||||
PacketPlayerUpdate hData = { camera3D.position.x, camera3D.position.y - 1.6f, camera3D.position.z, camYaw, 0 };
|
||||
send(sock, (char*)&hHead, sizeof(hHead), 0);
|
||||
send(sock, (char*)&hData, sizeof(hData), 0);
|
||||
}
|
||||
// Send HOST to new client (Host ID is always 0)
|
||||
PacketHeader hHead = { (uint8_t)PACKET_PLAYER_UPDATE, (uint32_t)sizeof(PacketPlayerUpdate) };
|
||||
PacketPlayerUpdate hData = { camera3D.position.x, camera3D.position.y - 1.6f, camera3D.position.z, camYaw, 0 };
|
||||
send(sock, (char*)&hHead, sizeof(hHead), 0);
|
||||
send(sock, (char*)&hData, sizeof(hData), 0);
|
||||
}
|
||||
} else if (head.type == PACKET_PLAYER_UPDATE) {
|
||||
PacketPlayerUpdate pu;
|
||||
|
|
@ -1039,7 +1073,7 @@ int main(void)
|
|||
remotePlayers.push_back(rp);
|
||||
}
|
||||
if (isServer) {
|
||||
pu.playerID = (uint32_t)sock; // Ensure ID is correct
|
||||
pu.playerID = (uint32_t)sock;
|
||||
for (auto& other : clientSockets) {
|
||||
if (other != sock) {
|
||||
send(other, (char*)&head, sizeof(head), 0);
|
||||
|
|
@ -1068,7 +1102,6 @@ int main(void)
|
|||
recv(sock, (char*)&ss, sizeof(ss), 0);
|
||||
if (!isServer) {
|
||||
globalSeedHash = ss.seed;
|
||||
// Regerate world if seed changed
|
||||
for (auto& pair : worldChunks) delete pair.second;
|
||||
worldChunks.clear();
|
||||
}
|
||||
|
|
@ -1084,31 +1117,11 @@ int main(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (bytes == 0 || (bytes < 0 && SOCKET_ERROR_VAL != -1)) {
|
||||
// Disconnect handling
|
||||
if (isServer && clientIdx != -1) {
|
||||
std::string leaver = "A player";
|
||||
for (auto it = remotePlayers.begin(); it != remotePlayers.end(); ++it) {
|
||||
if (it->sock == sock) {
|
||||
leaver = it->name;
|
||||
remotePlayers.erase(it);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (head.size > 0 && head.size < 2048) {
|
||||
std::vector<char> discard(head.size);
|
||||
recv(sock, discard.data(), head.size, 0);
|
||||
}
|
||||
chatLog.push_back({ leaver + " left the game", 5.0f });
|
||||
PacketHeader nHead = { (uint8_t)PACKET_CHAT, (uint32_t)sizeof(PacketChat) };
|
||||
PacketChat nChat;
|
||||
strncpy(nChat.name, "Server", 31);
|
||||
strncpy(nChat.message, (leaver + " left the game").c_str(), 127);
|
||||
for (auto& s : clientSockets) {
|
||||
if (s != sock) {
|
||||
send(s, (char*)&nHead, sizeof(nHead), 0);
|
||||
send(s, (char*)&nChat, sizeof(nChat), 0);
|
||||
}
|
||||
}
|
||||
closesocket(sock);
|
||||
clientSockets.erase(clientSockets.begin() + clientIdx);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -1697,8 +1710,8 @@ int main(void)
|
|||
DrawTexturePro(titleTexture, sourceRec, destRec, origin, 0.0f, WHITE);
|
||||
EndMode2D();
|
||||
|
||||
// Show Version Number (v2.0.2) in Red
|
||||
DrawTextEx(customFont, "v2.0.2", (Vector2){ (float)currentWidth - 140, (float)currentHeight - 40 }, 22, 1.0f, RED);
|
||||
// Show Version Number (v2.0.3) in Red
|
||||
DrawTextEx(customFont, "v2.0.3", (Vector2){ (float)currentWidth - 140, (float)currentHeight - 40 }, 22, 1.0f, RED);
|
||||
|
||||
// --- PLAYER NAME POPUP (IF MISSING) ---
|
||||
if (playerName == "") {
|
||||
|
|
|
|||
Loading…
Reference in New Issue