rebranding

This commit is contained in:
Nishi 2026-01-07 04:31:01 +09:00
commit 08d2c96590
Signed by: nishi
GPG key ID: 27EF69B208EB9343
10 changed files with 157 additions and 221 deletions

View file

@ -1,21 +1,14 @@
cmake_minimum_required(VERSION 3.11)
project(libfishsoup)
project(gbnet)
add_library(fishsoup SHARED src/client.c src/server.c src/socket.c src/stb_ds.c)
add_library(gbnet SHARED src/client.c src/server.c src/socket.c src/stb_ds.c)
target_include_directories(fishsoup PUBLIC include)
target_include_directories(gbnet PUBLIC include)
find_package(PkgConfig)
pkg_check_modules(ZLIB REQUIRED zlib)
target_compile_options(fishsoup PRIVATE ${ZLIB_CFLAGS_OTHER})
target_include_directories(fishsoup PRIVATE ${ZLIB_INCLUDE_DIRS})
target_link_options(fishsoup PRIVATE ${ZLIB_LDFLAGS_OTHER})
target_link_directories(fishsoup PRIVATE ${ZLIB_LIBRARY_DIRS})
target_link_libraries(fishsoup PRIVATE ${ZLIB_LIBRARIES})
include(GNUInstallDirs)
install(
TARGETS fishsoup
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
target_compile_options(gbnet PRIVATE ${ZLIB_CFLAGS_OTHER})
target_include_directories(gbnet PRIVATE ${ZLIB_INCLUDE_DIRS})
target_link_options(gbnet PRIVATE ${ZLIB_LDFLAGS_OTHER})
target_link_directories(gbnet PRIVATE ${ZLIB_LIBRARY_DIRS})
target_link_libraries(gbnet PRIVATE ${ZLIB_LIBRARIES})

View file

@ -1,24 +0,0 @@
Copyright (c) 2025, Fishsoup
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -1,33 +0,0 @@
CC = cc
CFLAGS = -g -Iinclude -fPIC `pkg-config --cflags zlib`
LDFLAGS = -shared
LIBS = `pkg-config --libs zlib`
OBJS = src/client.o src/server.o src/socket.o src/stb_ds.o
LIB = lib
SO = .so
.PHONY: all format clean
.SUFFIXES: .c .o
all: $(LIB)fishsoup$(SO)
format:
clang-format --verbose -i `find src include "(" -name "*.c" -or -name "*.h" ")" -and -not -name "stb_*.h"` test*.c
$(LIB)fishsoup$(SO): $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
testclient: testclient.c $(LIB)fishsoup$(SO)
cc -o $@ testclient.c -Wl,-R./ -L./ -Iinclude -lfishsoup
testserver: testserver.c $(LIB)fishsoup$(SO)
cc -o $@ testserver.c -Wl,-R./ -L./ -Iinclude -lfishsoup
.c.o:
$(CC) $(CFLAGS) -c -o $@ $<
clean:
rm -f *$(SO) $(OBJS) ./testserver ./testclient

View file

@ -1,86 +0,0 @@
#ifndef __FISHSOUP_H__
#define __FISHSOUP_H__
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/tcp.h>
#include <poll.h>
/* TCP */
#define FISHSOUP_PORT 3219
#define FISHSOUP_PING 3
enum fishsoup_packet_type {
FISHSOUP_PACKET_PING = 0,
FISHSOUP_PACKET_PONG,
FISHSOUP_PACKET_USER
};
typedef struct fishsoup_client fishsoup_client_t;
typedef struct fishsoup_server fishsoup_server_t;
typedef struct fishsoup_packet_header fishsoup_packet_header_t;
typedef struct fishsoup_packet fishsoup_packet_t;
struct fishsoup_client {
int fd;
time_t last_ping;
void (*on_packet)(fishsoup_client_t* client, fishsoup_packet_t* packet);
void (*on_disconnect)(fishsoup_client_t* client);
void* user;
struct {
int sent_ping;
int cleanup;
} server;
};
struct fishsoup_server {
int fd;
struct sockaddr_in address;
fishsoup_client_t* clients;
void* user;
void (*on_client)(fishsoup_server_t* server, fishsoup_client_t* client);
void (*on_tick)(fishsoup_server_t* server);
};
#pragma pack(1)
struct fishsoup_packet_header {
unsigned char type;
unsigned short length; /* ok, seriously, who sends 64k at ONCE */
};
#pragma pack()
/* !!! REMEMBER TO FREE DATA AFTER RECV UNLESS IT'S NULL !!! */
struct fishsoup_packet {
fishsoup_packet_header_t header;
void* data;
};
fishsoup_client_t* fishsoup_client(const char* host, int port);
void fishsoup_client_on_packet(fishsoup_client_t* client, void (*on_packet)(fishsoup_client_t* client, fishsoup_packet_t* packet));
void fishsoup_client_on_disconnect(fishsoup_client_t* client, void (*on_disconnect)(fishsoup_client_t* client));
int fishsoup_client_poll(fishsoup_client_t* client);
void fishsoup_client_destroy(fishsoup_client_t* client);
fishsoup_server_t* fishsoup_server(int port);
int fishsoup_server_clients(fishsoup_server_t* server);
void fishsoup_server_loop(fishsoup_server_t* server);
void fishsoup_server_on_client(fishsoup_server_t* server, void (*on_client)(fishsoup_server_t* server, fishsoup_client_t* client));
void fishsoup_server_on_tick(fishsoup_server_t* server, void (*on_tick)(fishsoup_server_t* server));
void fishsoup_server_broadcast(fishsoup_server_t* server, fishsoup_packet_t* packet);
void fishsoup_server_destroy(fishsoup_server_t* server);
int fishsoup_fd_send(int fd, const void* buf, int length);
int fishsoup_fd_recv(int fd, void* buf, int length, int to);
int fishsoup_packet_send(int fd, fishsoup_packet_t* packet);
int fishsoup_packet_recv(int fd, fishsoup_packet_t* packet);
#endif

View file

@ -0,0 +1,86 @@
#ifndef __LIBNET_H__
#define __LIBNET_H__
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/tcp.h>
#include <poll.h>
/* TCP */
#define NET_PORT 3219
#define NET_PING 3
enum gbnet_packet_type {
NET_PACKET_PING = 0,
NET_PACKET_PONG,
NET_PACKET_USER
};
typedef struct gbnet_client gbnet_client_t;
typedef struct gbnet_server gbnet_server_t;
typedef struct gbnet_packet_header gbnet_packet_header_t;
typedef struct gbnet_packet gbnet_packet_t;
struct gbnet_client {
int fd;
time_t last_ping;
void (*on_packet)(gbnet_client_t* client, gbnet_packet_t* packet);
void (*on_disconnect)(gbnet_client_t* client);
void* user;
struct {
int sent_ping;
int cleanup;
} server;
};
struct gbnet_server {
int fd;
struct sockaddr_in address;
gbnet_client_t* clients;
void* user;
void (*on_client)(gbnet_server_t* server, gbnet_client_t* client);
void (*on_tick)(gbnet_server_t* server);
};
#pragma pack(1)
struct gbnet_packet_header {
unsigned char type;
unsigned short length; /* ok, seriously, who sends 64k at ONCE */
};
#pragma pack()
/* !!! REMEMBER TO FREE DATA AFTER RECV UNLESS IT'S NULL !!! */
struct gbnet_packet {
gbnet_packet_header_t header;
void* data;
};
gbnet_client_t* gbnet_client(const char* host, int port);
void gbnet_client_on_packet(gbnet_client_t* client, void (*on_packet)(gbnet_client_t* client, gbnet_packet_t* packet));
void gbnet_client_on_disconnect(gbnet_client_t* client, void (*on_disconnect)(gbnet_client_t* client));
int gbnet_client_poll(gbnet_client_t* client);
void gbnet_client_destroy(gbnet_client_t* client);
gbnet_server_t* gbnet_server(int port);
int gbnet_server_clients(gbnet_server_t* server);
void gbnet_server_loop(gbnet_server_t* server);
void gbnet_server_on_client(gbnet_server_t* server, void (*on_client)(gbnet_server_t* server, gbnet_client_t* client));
void gbnet_server_on_tick(gbnet_server_t* server, void (*on_tick)(gbnet_server_t* server));
void gbnet_server_broadcast(gbnet_server_t* server, gbnet_packet_t* packet);
void gbnet_server_destroy(gbnet_server_t* server);
int gbnet_fd_send(int fd, const void* buf, int length);
int gbnet_fd_recv(int fd, void* buf, int length, int to);
int gbnet_packet_send(int fd, gbnet_packet_t* packet);
int gbnet_packet_recv(int fd, gbnet_packet_t* packet);
#endif

View file

@ -1,13 +1,13 @@
#include <fishsoup.h>
#include <gbnet.h>
fishsoup_client_t* fishsoup_client(const char* host, int port) {
fishsoup_client_t* client = malloc(sizeof(*client));
gbnet_client_t* gbnet_client(const char* host, int port) {
gbnet_client_t* client = malloc(sizeof(*client));
struct addrinfo hints;
char p[32];
struct addrinfo* result;
struct addrinfo* rp;
if(port == 0) port = FISHSOUP_PORT;
if(port == 0) port = NET_PORT;
sprintf(p, "%d", port);
memset(&hints, 0, sizeof(hints));
@ -46,17 +46,17 @@ fishsoup_client_t* fishsoup_client(const char* host, int port) {
return client;
}
void fishsoup_client_on_packet(fishsoup_client_t* client, void (*on_packet)(fishsoup_client_t* client, fishsoup_packet_t* packet)) {
void gbnet_client_on_packet(gbnet_client_t* client, void (*on_packet)(gbnet_client_t* client, gbnet_packet_t* packet)) {
client->on_packet = on_packet;
}
void fishsoup_client_on_disconnect(fishsoup_client_t* client, void (*on_disconnect)(fishsoup_client_t* client)) {
void gbnet_client_on_disconnect(gbnet_client_t* client, void (*on_disconnect)(gbnet_client_t* client)) {
client->on_disconnect = on_disconnect;
}
int fishsoup_client_poll(fishsoup_client_t* client) {
int gbnet_client_poll(gbnet_client_t* client) {
struct pollfd pfd;
fishsoup_packet_t pkt;
gbnet_packet_t pkt;
int ret;
pfd.fd = client->fd;
@ -64,17 +64,17 @@ int fishsoup_client_poll(fishsoup_client_t* client) {
ret = poll(&pfd, 1, 0);
if(ret <= 0) return ret;
ret = fishsoup_packet_recv(client->fd, &pkt);
ret = gbnet_packet_recv(client->fd, &pkt);
if(ret == 0) return -1; /* connection broke, probably */
if(pkt.header.type == FISHSOUP_PACKET_PING) {
fishsoup_packet_t ret;
if(pkt.header.type == NET_PACKET_PING) {
gbnet_packet_t ret;
client->last_ping = time(NULL);
ret.header.type = FISHSOUP_PACKET_PONG;
ret.header.type = NET_PACKET_PONG;
ret.header.length = 0;
ret.data = NULL;
if(fishsoup_packet_send(client->fd, &ret) == 0) {
if(gbnet_packet_send(client->fd, &ret) == 0) {
if(pkt.data != NULL) free(pkt.data);
return -1;
}
@ -86,7 +86,7 @@ int fishsoup_client_poll(fishsoup_client_t* client) {
return 1;
}
void fishsoup_client_destroy(fishsoup_client_t* client) {
void gbnet_client_destroy(gbnet_client_t* client) {
if(client->on_disconnect != NULL) client->on_disconnect(client);
close(client->fd);
free(client);

View file

@ -1,12 +1,12 @@
#include <fishsoup.h>
#include <gbnet.h>
#include "stb_ds.h"
fishsoup_server_t* fishsoup_server(int port) {
fishsoup_server_t* server = malloc(sizeof(*server));
gbnet_server_t* gbnet_server(int port) {
gbnet_server_t* server = malloc(sizeof(*server));
int val;
if(port == 0) port = FISHSOUP_PORT;
if(port == 0) port = NET_PORT;
if((server->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
free(server);
@ -39,11 +39,11 @@ fishsoup_server_t* fishsoup_server(int port) {
return server;
}
int fishsoup_server_clients(fishsoup_server_t* server) {
int gbnet_server_clients(gbnet_server_t* server) {
return arrlen(server->clients);
}
void fishsoup_server_loop(fishsoup_server_t* server) {
void gbnet_server_loop(gbnet_server_t* server) {
struct pollfd* pfd;
while(1) {
@ -68,7 +68,7 @@ void fishsoup_server_loop(fishsoup_server_t* server) {
if(server->on_tick != NULL) server->on_tick(server);
if(pfd[0].revents & POLLIN) {
fishsoup_client_t client;
gbnet_client_t client;
struct sockaddr_in address;
int len = sizeof(address);
@ -91,26 +91,26 @@ void fishsoup_server_loop(fishsoup_server_t* server) {
time_t diff;
if(server->clients[i].server.cleanup) continue;
if(pfd[1 + i].revents & POLLIN) {
fishsoup_packet_t pkt;
gbnet_packet_t pkt;
if(fishsoup_packet_recv(server->clients[i].fd, &pkt) == 0) {
if(gbnet_packet_recv(server->clients[i].fd, &pkt) == 0) {
server->clients[i].server.cleanup = 1;
} else {
if(pkt.header.type == FISHSOUP_PACKET_PONG && server->clients[i].server.sent_ping) {
if(pkt.header.type == NET_PACKET_PONG && server->clients[i].server.sent_ping) {
server->clients[i].last_ping = time(NULL);
server->clients[i].server.sent_ping = 0;
#ifdef DEBUG
fprintf(stderr, "Pong from client %d\n", server->clients[i].fd);
#endif
} else if(pkt.header.type == FISHSOUP_PACKET_PING) {
fishsoup_packet_t ret;
} else if(pkt.header.type == NET_PACKET_PING) {
gbnet_packet_t ret;
ret.header.type = FISHSOUP_PACKET_PONG;
ret.header.type = NET_PACKET_PONG;
ret.header.length = 0;
ret.data = NULL;
if(fishsoup_packet_send(server->clients[i].fd, &ret) == 0) {
if(gbnet_packet_send(server->clients[i].fd, &ret) == 0) {
server->clients[i].server.cleanup = 1;
} else {
#ifdef DEBUG
@ -128,14 +128,14 @@ void fishsoup_server_loop(fishsoup_server_t* server) {
diff = time(NULL) - server->clients[i].last_ping;
if(diff == FISHSOUP_PING && !server->clients[i].server.sent_ping) {
fishsoup_packet_t pkt;
if(diff == NET_PING && !server->clients[i].server.sent_ping) {
gbnet_packet_t pkt;
pkt.header.type = FISHSOUP_PACKET_PING;
pkt.header.type = NET_PACKET_PING;
pkt.header.length = 0;
pkt.data = NULL;
if(fishsoup_packet_send(server->clients[i].fd, &pkt) == 0) {
if(gbnet_packet_send(server->clients[i].fd, &pkt) == 0) {
server->clients[i].server.cleanup = 1;
#ifdef DEBUG
fprintf(stderr, "Failed to ping client %d\n", server->clients[i].fd);
@ -146,7 +146,7 @@ void fishsoup_server_loop(fishsoup_server_t* server) {
fprintf(stderr, "Pinging client %d\n", server->clients[i].fd);
#endif
}
} else if(diff == FISHSOUP_PING * 2 && server->clients[i].server.sent_ping) {
} else if(diff == NET_PING * 2 && server->clients[i].server.sent_ping) {
server->clients[i].server.cleanup = 1;
#ifdef DEBUG
fprintf(stderr, "Ping timeout (client %d)\n", server->clients[i].fd);
@ -170,15 +170,15 @@ void fishsoup_server_loop(fishsoup_server_t* server) {
}
}
void fishsoup_server_on_client(fishsoup_server_t* server, void (*on_client)(fishsoup_server_t* server, fishsoup_client_t* client)) {
void gbnet_server_on_client(gbnet_server_t* server, void (*on_client)(gbnet_server_t* server, gbnet_client_t* client)) {
server->on_client = on_client;
}
void fishsoup_server_on_tick(fishsoup_server_t* server, void (*on_tick)(fishsoup_server_t* server)) {
void gbnet_server_on_tick(gbnet_server_t* server, void (*on_tick)(gbnet_server_t* server)) {
server->on_tick = on_tick;
}
void fishsoup_server_destroy(fishsoup_server_t* server) {
void gbnet_server_destroy(gbnet_server_t* server) {
int i;
for(i = 0; i < arrlen(server->clients); i++) {
if(server->clients[i].on_disconnect != NULL) server->clients[i].on_disconnect(&server->clients[i]);
@ -189,10 +189,10 @@ void fishsoup_server_destroy(fishsoup_server_t* server) {
free(server);
}
void fishsoup_server_broadcast(fishsoup_server_t* server, fishsoup_packet_t* packet) {
void gbnet_server_broadcast(gbnet_server_t* server, gbnet_packet_t* packet) {
int i;
for(i = 0; i < arrlen(server->clients); i++) {
if(fishsoup_packet_send(server->clients[i].fd, packet) == 0) {
if(gbnet_packet_send(server->clients[i].fd, packet) == 0) {
server->clients[i].server.cleanup = 1;
}
}

View file

@ -1,12 +1,12 @@
#include <fishsoup.h>
#include <gbnet.h>
#include <zlib.h>
#define CHUNK 512
int fishsoup_packet_send(int fd, fishsoup_packet_t* packet) {
int gbnet_packet_send(int fd, gbnet_packet_t* packet) {
int r;
fishsoup_packet_header_t h;
gbnet_packet_header_t h;
int len = 0;
unsigned char* data = NULL;
@ -63,11 +63,11 @@ int fishsoup_packet_send(int fd, fishsoup_packet_t* packet) {
memcpy(&h, &packet->header, sizeof(h));
h.length = htons(len);
r = fishsoup_fd_send(fd, &h, sizeof(h));
r = gbnet_fd_send(fd, &h, sizeof(h));
if(r != sizeof(h)) return 0;
if(data != NULL) {
r = fishsoup_fd_send(fd, data, len);
r = gbnet_fd_send(fd, data, len);
if(r != sizeof(h)) {
free(data);
return 0;
@ -78,10 +78,10 @@ int fishsoup_packet_send(int fd, fishsoup_packet_t* packet) {
return sizeof(h) + len;
}
int fishsoup_packet_recv(int fd, fishsoup_packet_t* packet) {
fishsoup_packet_header_t h;
int gbnet_packet_recv(int fd, gbnet_packet_t* packet) {
gbnet_packet_header_t h;
if(fishsoup_fd_recv(fd, &h, sizeof(h), 500) != sizeof(h)) {
if(gbnet_fd_recv(fd, &h, sizeof(h), 500) != sizeof(h)) {
packet->data = NULL;
return 0;
}
@ -97,7 +97,7 @@ int fishsoup_packet_recv(int fd, fishsoup_packet_t* packet) {
int seek = 0;
int len = 0;
unsigned char buf[CHUNK];
if(fishsoup_fd_recv(fd, data, packet->header.length, 50) != packet->header.length) {
if(gbnet_fd_recv(fd, data, packet->header.length, 50) != packet->header.length) {
free(data);
return 0;
}
@ -164,7 +164,7 @@ int fishsoup_packet_recv(int fd, fishsoup_packet_t* packet) {
return sizeof(h) + packet->header.length;
}
int fishsoup_fd_send(int fd, const void* buf, int length) {
int gbnet_fd_send(int fd, const void* buf, int length) {
struct pollfd pfd;
pfd.fd = fd;
pfd.events = POLLOUT | POLLPRI;
@ -175,7 +175,7 @@ int fishsoup_fd_send(int fd, const void* buf, int length) {
return send(fd, buf, length, 0);
}
int fishsoup_fd_recv(int fd, void* buf, int length, int to) {
int gbnet_fd_recv(int fd, void* buf, int length, int to) {
struct pollfd pfd;
int ret;
unsigned char* b = buf;

View file

@ -1,11 +1,11 @@
#include <fishsoup.h>
#include <gbnet.h>
void on(fishsoup_client_t* client, fishsoup_packet_t* pkt) {
if(pkt->header.type == FISHSOUP_PACKET_USER) printf("Received: %s\n", pkt->data);
void on(gbnet_client_t* client, gbnet_packet_t* pkt) {
if(pkt->header.type == NET_PACKET_USER) printf("Received: %s\n", pkt->data);
}
int main() {
fishsoup_client_t* client = fishsoup_client("127.0.0.1", 0);
fishsoup_client_on_packet(client, on);
while(fishsoup_client_poll(client) >= 0);
gbnet_client_t* client = gbnet_client("127.0.0.1", 0);
gbnet_client_on_packet(client, on);
while(gbnet_client_poll(client) >= 0);
}

View file

@ -1,18 +1,18 @@
#include <fishsoup.h>
#include <gbnet.h>
void on(fishsoup_server_t* server, fishsoup_client_t* client) {
fishsoup_packet_t pkt;
void on(gbnet_server_t* server, gbnet_client_t* client) {
gbnet_packet_t pkt;
pkt.data = "Hello world!";
pkt.header.length = strlen(pkt.data) + 1;
pkt.header.flag = 0;
pkt.header.type = FISHSOUP_PACKET_USER;
pkt.header.type = NET_PACKET_USER;
fishsoup_packet_send(client->fd, &pkt);
gbnet_packet_send(client->fd, &pkt);
}
int main() {
fishsoup_server_t* server = fishsoup_server(0);
fishsoup_server_on_client(server, on);
fishsoup_server_loop(server);
gbnet_server_t* server = gbnet_server(0);
gbnet_server_on_client(server, on);
gbnet_server_loop(server);
}