diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index e616a13..1244782 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -22,7 +22,7 @@ include_directories(external/jar) include_directories(external/miniaudio) include_directories(external/dr_libs) -file(GLOB GearSrc_SRC src/*.c src/gl/*.c src/sound/*.c src/external/*.c) +file(GLOB GearSrc_SRC src/*.c src/gl/*.c src/sound/*.c src/net/*.c src/external/*.c) add_library(GearSrc SHARED ${GearSrc_SRC}) target_include_directories(GearSrc PUBLIC include) diff --git a/engine/include/GearSrc/MachDep.h b/engine/include/GearSrc/MachDep.h index 1d14942..15fde1c 100644 --- a/engine/include/GearSrc/MachDep.h +++ b/engine/include/GearSrc/MachDep.h @@ -6,6 +6,9 @@ #include #include #include +#ifndef _WIN32 +#include +#endif #if defined(_GEARSRC) && defined(_WIN32) #define GSDECL extern __declspec(dllexport) diff --git a/engine/include/GearSrc/Net.h b/engine/include/GearSrc/Net.h new file mode 100644 index 0000000..ad172d5 --- /dev/null +++ b/engine/include/GearSrc/Net.h @@ -0,0 +1,35 @@ +#ifndef __GEARSRC_NET_H__ +#define __GEARSRC_NET_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* net_client.c */ +GSDECL GSNetClient GSNetClientOpen(GSClient client, const char* hostname, int port); +GSDECL void GSNetClientClose(GSNetClient client); + +/* net_server.c */ +GSDECL GSNetServer GSNetServerOpen(GSServer server, int port); +GSDECL void GSNetServerClose(GSNetServer server); + +/* net_base.c */ +GSDECL GSBool GSNetBaseHasData(int fd); +GSDECL int GSNetBaseServer(int port); +GSDECL int GSNetBaseClient(const char* hostname, int port); +GSDECL void GSNetBaseClose(int fd); +GSDECL void GSNetBaseRead(int fd, void* data, int size, GSNetAddress* address); /* always read 508 bytes! */ +GSDECL void GSNetBaseWrite(int fd, void* data, int size, GSNetAddress* address); + +/* net_packet.c */ +GSDECL void GSNetPacketRead(int fd, GSNetPacket* packet, GSNetAddress* address); +GSDECL void GSNetPacketWrite(int fd, GSNetPacket* packet, GSNetAddress* address); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/engine/include/GearSrc/TypeDefs.h b/engine/include/GearSrc/TypeDefs.h index fdd995b..fc68deb 100644 --- a/engine/include/GearSrc/TypeDefs.h +++ b/engine/include/GearSrc/TypeDefs.h @@ -41,11 +41,13 @@ typedef GSU8 GSBool; #define GSTrue ((GSBool)1) #define GSFalse ((GSBool)0) -typedef struct _GSVersion GSVersion; -typedef struct _GSEngineParam GSEngineParam; -typedef struct _GSResourceKV GSResourceKV; -typedef struct _GSBox GSBox; -typedef struct _GSNetPacket GSNetPacket; +typedef struct _GSVersion GSVersion; +typedef struct _GSEngineParam GSEngineParam; +typedef struct _GSResourceKV GSResourceKV; +typedef struct _GSBox GSBox; +typedef struct _GSNetPacketHeader GSNetPacketHeader; +typedef struct _GSNetPacket GSNetPacket; +typedef struct _GSNetAddress GSNetAddress; #ifdef _GEARSRC typedef struct _GSClient* GSClient; typedef struct _GSServer* GSServer; @@ -58,6 +60,8 @@ typedef struct _GSModel* GSModel; typedef struct _GSSoundDriver* GSSoundDriver; typedef struct _GSSoundEngine* GSSoundEngine; typedef struct _GSSound* GSSound; +typedef struct _GSNetClient* GSNetClient; +typedef struct _GSNetServer* GSNetServer; typedef struct _GSModelFace GSModelFace; typedef struct _GSModelMaterial GSModelMaterial; @@ -107,13 +111,25 @@ struct _GSResourceKV { }; #pragma pack(1) -struct _GSNetPacket { - GSU8 flag; +struct _GSNetPacketHeader { + GSU8 flag; GSU32 index; GSU32 sequence; }; #pragma pack() +struct _GSNetPacket { + GSNetPacketHeader header; + unsigned char data[508]; + int size; +}; + +/* i hope someone adds ipv6 support :) */ +struct _GSNetAddress { + GSU32 address; + GSU16 port; +}; + #ifdef _GEARSRC #include #include @@ -226,6 +242,14 @@ struct _GSSoundEngine { GSSound* sound; }; +struct _GSNetClient { + GSEngine engine; +}; + +struct _GSNetServer { + GSEngine engine; +}; + struct _GSClient { GSEngine engine; diff --git a/engine/src/net/net_base.c b/engine/src/net/net_base.c new file mode 100644 index 0000000..0b55d09 --- /dev/null +++ b/engine/src/net/net_base.c @@ -0,0 +1,110 @@ +#include + +#ifdef _WIN32 +/* TODO: check if this works */ +#include +#else +#include +#include +#include +#include +#include +#include +#endif + +static int new_socket(void) { + int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + +#ifdef _WIN32 + if(fd == INVALID_SOCKET) return -1; +#else + if(fd < 0) return -1; +#endif + + return fd; +} + +GSBool GSNetBaseHasData(int fd) { + fd_set fds; + + FD_ZERO(&fds); + + FD_SET(fd, &fds); + + select(FD_SETSIZE, &fds, NULL, NULL, NULL); + + if(FD_ISSET(fd, &fds)) return GSTrue; + + return GSFalse; +} + +int GSNetBaseServer(int port) { + int fd; + struct sockaddr_in addr; + int yes = 1; + + if((fd = new_socket()) < 0) return -1; + + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&yes, sizeof(yes)); + + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_port = htons(port); + + if(bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { + GSNetBaseClose(fd); + return -1; + } + + return fd; +} + +int GSNetBaseClient(const char* hostname, int port) { + struct sockaddr_in addr; + int fd; + + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr(hostname); + addr.sin_port = htons(port); + + if(addr.sin_addr.s_addr == 0xffffffff) { + struct hostent* host = gethostbyname(hostname); + if(host == NULL) return -1; + + addr.sin_addr.s_addr = *(GSU32*)host->h_addr_list[0]; + } + + if((fd = new_socket()) < 0) return -1; + + connect(fd, (struct sockaddr*)&addr, sizeof(addr)); + + return fd; +} + +void GSNetBaseClose(int fd) { +#ifdef _WIN32 + closesocket(fd); +#else + close(fd); +#endif +} + +void GSNetBaseRead(int fd, void* data, int size, GSNetAddress* address) { + struct sockaddr_in addr; + int len = sizeof(addr); + + recvfrom(fd, data, size, 0, (struct sockaddr*)&addr, &len); + + address->address = addr.sin_addr.s_addr; + address->port = addr.sin_port; +} + +void GSNetBaseWrite(int fd, void* data, int size, GSNetAddress* address) { + struct sockaddr_in addr; + + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = address->address; + addr.sin_port = address->port; + + sendto(fd, data, size, 0, (struct sockaddr*)&addr, sizeof(addr)); +} diff --git a/engine/src/net/net_client.c b/engine/src/net/net_client.c new file mode 100644 index 0000000..816f2be --- /dev/null +++ b/engine/src/net/net_client.c @@ -0,0 +1 @@ +#include diff --git a/engine/src/net/net_packet.c b/engine/src/net/net_packet.c new file mode 100644 index 0000000..cb4c4f4 --- /dev/null +++ b/engine/src/net/net_packet.c @@ -0,0 +1,9 @@ +#include + +#include + +void GSNetPacketRead(int fd, GSNetPacket* packet, GSNetAddress* address) { +} + +void GSNetPacketWrite(int fd, GSNetPacket* packet, GSNetAddress* address) { +} diff --git a/engine/src/net/net_server.c b/engine/src/net/net_server.c new file mode 100644 index 0000000..816f2be --- /dev/null +++ b/engine/src/net/net_server.c @@ -0,0 +1 @@ +#include