diff --git a/engine/include/GearSrc/Net.h b/engine/include/GearSrc/Net.h index 2aef51b..77ed36b 100644 --- a/engine/include/GearSrc/Net.h +++ b/engine/include/GearSrc/Net.h @@ -10,13 +10,17 @@ extern "C" { #define GSNetDefaultPort 23903 +#define GSNetPacketFlagAcknowledge (1 << 0) + /* net_client.c */ -GSDECL GSNetClient GSNetClientOpen(GSClient client, const char* hostname, int port); -GSDECL void GSNetClientClose(GSNetClient client); +GSDECL GSNetClient GSNetClientOpen(GSClient net, const char* hostname, int port); +GSDECL void GSNetClientStep(GSNetClient net); +GSDECL void GSNetClientClose(GSNetClient net); /* net_server.c */ -GSDECL GSNetServer GSNetServerOpen(GSServer server, int port); -GSDECL void GSNetServerClose(GSNetServer server); +GSDECL GSNetServer GSNetServerOpen(GSServer net, int port); +GSDECL void GSNetServerStep(GSNetServer net); +GSDECL void GSNetServerClose(GSNetServer net); /* net_base.c */ GSDECL GSBool GSNetBaseHasData(int fd); diff --git a/engine/include/GearSrc/TypeDefs.h b/engine/include/GearSrc/TypeDefs.h index 83b0a96..6fc3415 100644 --- a/engine/include/GearSrc/TypeDefs.h +++ b/engine/include/GearSrc/TypeDefs.h @@ -48,6 +48,7 @@ typedef struct _GSBox GSBox; typedef struct _GSNetPacketHeader GSNetPacketHeader; typedef struct _GSNetPacket GSNetPacket; typedef struct _GSNetAddress GSNetAddress; +typedef struct _GSBinary GSBinary; #ifdef _GEARSRC typedef struct _GSClient* GSClient; typedef struct _GSServer* GSServer; @@ -116,7 +117,7 @@ struct _GSResourceKV { struct _GSNetPacketHeader { GSU8 flag; GSU32 index; - GSU32 sequence; + GSU32 seq; }; #pragma pack() @@ -132,6 +133,11 @@ struct _GSNetAddress { GSU16 port; }; +struct _GSBinary { + void* data; + int size; +}; + #ifdef _GEARSRC #include #include @@ -248,6 +254,19 @@ struct _GSNetClient { GSEngine engine; int fd; + + unsigned int rxseq; + unsigned int rxindex; + unsigned int rxtotal; + unsigned int rxstate; + + unsigned int txseq; + unsigned int txindex; + unsigned int txtotal; + unsigned int txstate; + + GSBinary* rx; + GSBinary* tx; }; struct _GSNetServer { diff --git a/engine/src/client.c b/engine/src/client.c index 8aaa90d..2002207 100644 --- a/engine/src/client.c +++ b/engine/src/client.c @@ -7,6 +7,7 @@ #include #include #include +#include #include @@ -118,6 +119,8 @@ void GSClientStep(GSClient client) { GSVector2 sq[4]; int i, j, k, c, t; + if(client->net != NULL) GSNetClientStep(client->net); + GSGLClear(client->gl); GSGLCameraSetup(client->gl); GSGLSetLight(client->gl); diff --git a/engine/src/core.c b/engine/src/core.c index 9be42e6..b7f5130 100644 --- a/engine/src/core.c +++ b/engine/src/core.c @@ -83,6 +83,8 @@ GSEngine GSEngineCreate(GSEngineParam* param) { if(param->client) engine->shutdown++; if(param->server) engine->shutdown++; + engine->client->net = GSNetClientOpen(engine->client, "localhost", GSNetDefaultPort); + return engine; } diff --git a/engine/src/net/net_base.c b/engine/src/net/net_base.c index d438f68..0e25765 100644 --- a/engine/src/net/net_base.c +++ b/engine/src/net/net_base.c @@ -25,13 +25,17 @@ static int new_socket(void) { } GSBool GSNetBaseHasData(int fd) { - fd_set fds; + fd_set fds; + struct timeval tv; + + tv.tv_sec = 0; + tv.tv_usec = 0; FD_ZERO(&fds); FD_SET(fd, &fds); - select(FD_SETSIZE, &fds, NULL, NULL, NULL); + select(FD_SETSIZE, &fds, NULL, NULL, &tv); if(FD_ISSET(fd, &fds)) return GSTrue; diff --git a/engine/src/net/net_client.c b/engine/src/net/net_client.c index ac11a05..ab07a40 100644 --- a/engine/src/net/net_client.c +++ b/engine/src/net/net_client.c @@ -19,8 +19,39 @@ GSNetClient GSNetClientOpen(GSClient client, const char* hostname, int port) { return net; } -void GSNetClientClose(GSNetClient client) { - if(client->fd >= 0) GSNetBaseClose(client->fd); +enum states { + Acknowledged = 0, + WaitingAcknowledge +}; - free(client); +void GSNetClientStep(GSNetClient net) { + GSNetPacket pkt; + GSNetAddress addr; + + while(GSNetBaseHasData(net->fd)) { + GSNetPacketRead(net->fd, &pkt, &addr); + + if(pkt.header.flag & GSNetPacketFlagAcknowledge) { + if(net->txstate == WaitingAcknowledge && net->txindex == pkt.header.index && net->txseq == pkt.header.seq) { + GSLog(net->engine, GSLogDebug, "ACK received for %d:%d", net->txindex, net->txseq); + + if(net->txseq == net->txtotal) net->txstate = Acknowledged; + } + } else { + if(net->rxstate == Acknowledged && net->rxindex == pkt.header.index && net->rxseq == pkt.header.seq) { + pkt.header.flag |= GSNetPacketFlagAcknowledge; + pkt.header.index = net->rxindex; + pkt.header.seq = net->rxseq; + pkt.size = 0; + + GSNetPacketWrite(net->fd, &pkt, &addr); + } + } + } +} + +void GSNetClientClose(GSNetClient net) { + if(net->fd >= 0) GSNetBaseClose(net->fd); + + free(net); } diff --git a/engine/src/net/net_packet.c b/engine/src/net/net_packet.c index db13b49..7b81344 100644 --- a/engine/src/net/net_packet.c +++ b/engine/src/net/net_packet.c @@ -10,16 +10,16 @@ void GSNetPacketRead(int fd, GSNetPacket* packet, GSNetAddress* address) { memcpy(&packet->header, buf, sizeof(packet->header)); memcpy(packet->data, buf + sizeof(packet->header), packet->size); - packet->header.index = GSEndianSwapU32BE(packet->header.index); - packet->header.sequence = GSEndianSwapU32BE(packet->header.sequence); + packet->header.index = GSEndianSwapU32BE(packet->header.index); + packet->header.seq = GSEndianSwapU32BE(packet->header.seq); } void GSNetPacketWrite(int fd, GSNetPacket* packet, GSNetAddress* address) { GSNetPacketHeader header = packet->header; unsigned char buf[508]; - header.index = GSEndianSwapU32BE(header.index); - header.sequence = GSEndianSwapU32BE(header.sequence); + header.index = GSEndianSwapU32BE(header.index); + header.seq = GSEndianSwapU32BE(header.seq); memcpy(buf, &header, sizeof(header)); memcpy(buf + sizeof(header), packet->data, packet->size); diff --git a/engine/src/net/net_server.c b/engine/src/net/net_server.c index 9471af7..a32dd12 100644 --- a/engine/src/net/net_server.c +++ b/engine/src/net/net_server.c @@ -19,8 +19,11 @@ GSNetServer GSNetServerOpen(GSServer server, int port) { return net; } -void GSNetServerClose(GSNetServer server) { - if(server->fd >= 0) GSNetBaseClose(server->fd); - - free(server); +void GSNetServerStep(GSNetServer net) { +} + +void GSNetServerClose(GSNetServer net) { + if(net->fd >= 0) GSNetBaseClose(net->fd); + + free(net); } diff --git a/engine/src/server.c b/engine/src/server.c index 35dc2c3..a8d4022 100644 --- a/engine/src/server.c +++ b/engine/src/server.c @@ -31,4 +31,5 @@ void GSServerDestroy(GSServer server) { } void GSServerStep(GSServer server) { + GSNetServerStep(server->net); }