working server and gameloop
This commit is contained in:
2
.vscode/tasks.json
vendored
2
.vscode/tasks.json
vendored
@@ -10,6 +10,8 @@
|
|||||||
"-g",
|
"-g",
|
||||||
"main.c",
|
"main.c",
|
||||||
"court.c",
|
"court.c",
|
||||||
|
"gameServer.c",
|
||||||
|
"term.c",
|
||||||
"network/*.c",
|
"network/*.c",
|
||||||
"-o",
|
"-o",
|
||||||
"netpong",
|
"netpong",
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -2,7 +2,7 @@
|
|||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -Wall -g
|
CFLAGS = -Wall -g
|
||||||
|
|
||||||
NETPONG_SRC = main.c court.c $(wildcard network/*.c)
|
NETPONG_SRC = main.c term.c court.c gameServer.c $(wildcard network/*.c)
|
||||||
|
|
||||||
LIBS = -lncurses
|
LIBS = -lncurses
|
||||||
|
|
||||||
|
|||||||
11
game.h
11
game.h
@@ -1,6 +1,9 @@
|
|||||||
#ifndef GAME_H
|
#ifndef GAME_H
|
||||||
#define GAME_H 1
|
#define GAME_H 1
|
||||||
|
|
||||||
|
#include "network/networking.h"
|
||||||
|
|
||||||
|
|
||||||
// Setup game board
|
// Setup game board
|
||||||
#define TOP_ROW 4
|
#define TOP_ROW 4
|
||||||
#define BOT_ROW 21
|
#define BOT_ROW 21
|
||||||
@@ -16,8 +19,16 @@ typedef struct
|
|||||||
|
|
||||||
} GameData;
|
} GameData;
|
||||||
|
|
||||||
|
void SetupTermWin();
|
||||||
|
void CloseTermWin();
|
||||||
|
|
||||||
|
void CreateGameServer(Server* serv,GameData*gd);
|
||||||
|
void RunGameClient(Client* c);
|
||||||
|
|
||||||
void DrawWalls(GameData);
|
void DrawWalls(GameData);
|
||||||
void DrawHeader(GameData);
|
void DrawHeader(GameData);
|
||||||
|
|
||||||
|
void MGameAlert(int y, int x, char* str);
|
||||||
|
void GameAlert(char* str);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
133
gameServer.c
Normal file
133
gameServer.c
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
#include "game.h"
|
||||||
|
#include <curses.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
void CreateGameServer(Server* serv, GameData* gd)
|
||||||
|
{
|
||||||
|
|
||||||
|
Server s = *serv;
|
||||||
|
|
||||||
|
bool game_running = true;
|
||||||
|
|
||||||
|
fd_set fds;
|
||||||
|
FD_ZERO(&fds);
|
||||||
|
FD_SET(s.server_fd, &fds);
|
||||||
|
|
||||||
|
struct timeval tv = { 0, 0 }; // non-blocking check
|
||||||
|
|
||||||
|
SetupTermWin();
|
||||||
|
|
||||||
|
DrawWalls(*gd);
|
||||||
|
|
||||||
|
while (game_running) {
|
||||||
|
|
||||||
|
fd_set read_fds;
|
||||||
|
FD_ZERO(&read_fds);
|
||||||
|
|
||||||
|
// Add server socket
|
||||||
|
FD_SET(s.server_fd, &read_fds);
|
||||||
|
int max_fd = s.server_fd;
|
||||||
|
|
||||||
|
// Add client sockets
|
||||||
|
for (int i = 0; i < s.client_count; i++) {
|
||||||
|
int fd = s.clients[i];
|
||||||
|
FD_SET(fd, &read_fds);
|
||||||
|
if (fd > max_fd)
|
||||||
|
max_fd = fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Small timeout (prevents 100% CPU usage)
|
||||||
|
struct timeval tv;
|
||||||
|
tv.tv_sec = 0;
|
||||||
|
tv.tv_usec = 1000; // 1ms
|
||||||
|
|
||||||
|
int ret = select(max_fd + 1, &read_fds, NULL, NULL, &tv);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
perror("select");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// New connection
|
||||||
|
if (FD_ISSET(s.server_fd, &read_fds)) {
|
||||||
|
int client_fd = accept(s.server_fd, NULL, NULL);
|
||||||
|
if (client_fd >= 0 && s.client_count < MAX_SERVER_CLIENTS) {
|
||||||
|
s.clients[s.client_count++] = client_fd;
|
||||||
|
|
||||||
|
char msg[64];
|
||||||
|
snprintf(msg, sizeof(msg), "New client connected: %d\n", client_fd);
|
||||||
|
GameAlert(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle client data
|
||||||
|
for (int i = 0; i < s.client_count; i++) {
|
||||||
|
int fd = s.clients[i];
|
||||||
|
|
||||||
|
if (FD_ISSET(fd, &read_fds)) {
|
||||||
|
char buffer[1024];
|
||||||
|
int bytes = recv(fd, buffer, sizeof(buffer) - 1, 0);
|
||||||
|
|
||||||
|
if (bytes > 0) {
|
||||||
|
buffer[bytes] = '\0';
|
||||||
|
|
||||||
|
char msg[1024];
|
||||||
|
snprintf(msg, sizeof(msg), "Client %d says: %s\r", fd, buffer);
|
||||||
|
GameAlert(msg);
|
||||||
|
|
||||||
|
// Example: echo back
|
||||||
|
send(fd, buffer, bytes, 0);
|
||||||
|
} else if (bytes == 0) {
|
||||||
|
char msg[64];
|
||||||
|
snprintf(msg, sizeof(msg), "Client %d disconnected\n", fd);
|
||||||
|
GameAlert(msg);
|
||||||
|
|
||||||
|
RemoveClient(&s, i);
|
||||||
|
i--; // re-check swapped client
|
||||||
|
} else {
|
||||||
|
perror("recv");
|
||||||
|
RemoveClient(&s, i);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s.client_count < 1) {
|
||||||
|
char msg[64];
|
||||||
|
snprintf(msg, sizeof(msg), "Waiting for other player\n");
|
||||||
|
GameAlert(msg);
|
||||||
|
} else {
|
||||||
|
// Process Game Data
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseTermWin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunGameClient(Client* client)
|
||||||
|
{
|
||||||
|
Client c = *client;
|
||||||
|
|
||||||
|
// char* msg = "Hello from client, this is a test, I really want to see what happens if I create a really long packet and try to send it. I would imagine it will be some kind of buffer overflow";
|
||||||
|
// send(c.client_fd, msg, strlen(msg), 0);
|
||||||
|
|
||||||
|
// {
|
||||||
|
// char buffer[1024] = { 0 };
|
||||||
|
// read(c.client_fd, buffer, sizeof(buffer));
|
||||||
|
// printf("Server: %s\n", buffer);
|
||||||
|
// }
|
||||||
|
|
||||||
|
sleep(10);
|
||||||
|
// char* msg2 = "Ok I am leaving now";
|
||||||
|
// send(c.client_fd, msg2, strlen(msg2), 0);
|
||||||
|
// {
|
||||||
|
// char buffer[1024] = { 0 };
|
||||||
|
// read(c.client_fd, buffer, sizeof(buffer));
|
||||||
|
// printf("Server: %s\n", buffer);
|
||||||
|
// }
|
||||||
|
}
|
||||||
117
main.c
117
main.c
@@ -1,13 +1,10 @@
|
|||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include <curses.h>
|
|
||||||
#include <signal.h>
|
#include <unistd.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "network/networking.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main Fucntion
|
* Main Fucntion
|
||||||
*/
|
*/
|
||||||
@@ -38,130 +35,26 @@ int main(int argc, char* argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// srand(getpid());
|
|
||||||
|
|
||||||
// // Setup Terminal
|
|
||||||
// if (initscr() == NULL) {
|
|
||||||
// perror("initscr failed");
|
|
||||||
// exit(1);
|
|
||||||
// }
|
|
||||||
// noecho();
|
|
||||||
// cbreak();
|
|
||||||
// nodelay(stdscr, TRUE);
|
|
||||||
|
|
||||||
int game_running = true;
|
|
||||||
|
|
||||||
if (data.host) {
|
if (data.host) {
|
||||||
// Create Server
|
// Create Server
|
||||||
Server s = StartServer(data.port);
|
Server s = StartServer(data.port);
|
||||||
|
|
||||||
printf("Server Started\n");
|
printf("Server Started\n");
|
||||||
|
|
||||||
fd_set fds;
|
CreateGameServer(&s,&data);
|
||||||
FD_ZERO(&fds);
|
|
||||||
FD_SET(s.server_fd, &fds);
|
|
||||||
|
|
||||||
struct timeval tv = { 0, 0 }; // non-blocking check
|
|
||||||
|
|
||||||
int updateChar = 0;
|
|
||||||
|
|
||||||
while (game_running) {
|
|
||||||
fd_set read_fds;
|
|
||||||
FD_ZERO(&read_fds);
|
|
||||||
|
|
||||||
// Add server socket
|
|
||||||
FD_SET(s.server_fd, &read_fds);
|
|
||||||
int max_fd = s.server_fd;
|
|
||||||
|
|
||||||
// Add client sockets
|
|
||||||
for (int i = 0; i < s.client_count; i++) {
|
|
||||||
int fd = s.clients[i];
|
|
||||||
FD_SET(fd, &read_fds);
|
|
||||||
if (fd > max_fd)
|
|
||||||
max_fd = fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Small timeout (prevents 100% CPU usage)
|
|
||||||
struct timeval tv;
|
|
||||||
tv.tv_sec = 0;
|
|
||||||
tv.tv_usec = 1000; // 1ms
|
|
||||||
|
|
||||||
int ret = select(max_fd + 1, &read_fds, NULL, NULL, &tv);
|
|
||||||
|
|
||||||
if (ret < 0) {
|
|
||||||
perror("select");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// New connection
|
|
||||||
if (FD_ISSET(s.server_fd, &read_fds)) {
|
|
||||||
int client_fd = accept(s.server_fd, NULL, NULL);
|
|
||||||
if (client_fd >= 0 && s.client_count < s.max_clients) {
|
|
||||||
s.clients[s.client_count++] = client_fd;
|
|
||||||
printf("New client connected: %d\n", client_fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle client data
|
|
||||||
for (int i = 0; i < s.client_count; i++) {
|
|
||||||
int fd = s.clients[i];
|
|
||||||
|
|
||||||
if (FD_ISSET(fd, &read_fds)) {
|
|
||||||
char buffer[1024];
|
|
||||||
int bytes = recv(fd, buffer, sizeof(buffer) - 1, 0);
|
|
||||||
|
|
||||||
if (bytes > 0) {
|
|
||||||
buffer[bytes] = '\0';
|
|
||||||
printf("Client %d says: %s\n", fd, buffer);
|
|
||||||
|
|
||||||
// Example: echo back
|
|
||||||
send(fd, buffer, bytes, 0);
|
|
||||||
} else if (bytes == 0) {
|
|
||||||
printf("Client %d disconnected\n", fd);
|
|
||||||
RemoveClient(&s, i);
|
|
||||||
i--; // re-check swapped client
|
|
||||||
} else {
|
|
||||||
perror("recv");
|
|
||||||
RemoveClient(&s, i);
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
close(s.server_fd);
|
close(s.server_fd);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
printf("Connecting to %s:%i\n", data.domain, data.port);
|
printf("Connecting to %s:%i\n", data.domain, data.port);
|
||||||
|
|
||||||
// Create Client
|
|
||||||
|
|
||||||
Client c = StartClient(data.domain, data.port);
|
Client c = StartClient(data.domain, data.port);
|
||||||
|
|
||||||
char* msg = "Hello from client";
|
RunGameClient(&c);
|
||||||
send(c.client_fd, msg, strlen(msg), 0);
|
|
||||||
|
|
||||||
{
|
|
||||||
char buffer[1024] = { 0 };
|
|
||||||
read(c.client_fd, buffer, sizeof(buffer));
|
|
||||||
printf("Server: %s\n", buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
sleep(10);
|
|
||||||
char* msg2 = "Ok I am leaving now";
|
|
||||||
send(c.client_fd, msg2, strlen(msg2), 0);
|
|
||||||
{
|
|
||||||
char buffer[1024] = { 0 };
|
|
||||||
read(c.client_fd, buffer, sizeof(buffer));
|
|
||||||
printf("Server: %s\n", buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
close(c.client_fd);
|
close(c.client_fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// endwin();
|
|
||||||
}
|
}
|
||||||
@@ -7,8 +7,9 @@
|
|||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
|
||||||
Server StartServer(int port) {
|
Server StartServer(int port) {
|
||||||
Server s = {2};
|
Server s;
|
||||||
s.clientID = 0;
|
s.clientID = 0;
|
||||||
|
s.client_count = 0;
|
||||||
|
|
||||||
|
|
||||||
// Create Socket
|
// Create Socket
|
||||||
|
|||||||
@@ -3,8 +3,9 @@
|
|||||||
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#define MAX_SERVER_CLIENTS 2
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const int max_clients;
|
|
||||||
int server_fd;
|
int server_fd;
|
||||||
struct sockaddr_in address;
|
struct sockaddr_in address;
|
||||||
int clients[2];
|
int clients[2];
|
||||||
@@ -20,7 +21,6 @@ typedef struct {
|
|||||||
struct sockaddr_in address;
|
struct sockaddr_in address;
|
||||||
} Client;
|
} Client;
|
||||||
|
|
||||||
|
|
||||||
Client StartClient(char* host, int port);
|
Client StartClient(char* host, int port);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
38
term.c
Normal file
38
term.c
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#include "game.h"
|
||||||
|
|
||||||
|
#include <curses.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
void SetupTermWin()
|
||||||
|
{
|
||||||
|
srand(getpid());
|
||||||
|
|
||||||
|
// Setup Terminal
|
||||||
|
if (initscr() == NULL) {
|
||||||
|
perror("initscr failed");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
noecho();
|
||||||
|
cbreak();
|
||||||
|
nodelay(stdscr, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CloseTermWin()
|
||||||
|
{
|
||||||
|
endwin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameAlert(char* str)
|
||||||
|
{
|
||||||
|
MGameAlert(0,0,str);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MGameAlert(int y, int x, char* str)
|
||||||
|
{
|
||||||
|
move(y, x);
|
||||||
|
clrtoeol();
|
||||||
|
mvaddstr(y, x, str);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user