Fully Working Game
This commit is contained in:
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "network/networking.h"
|
#include "network/networking.h"
|
||||||
|
|
||||||
|
#define NUM_OF_BALLS 2
|
||||||
|
|
||||||
|
|
||||||
// Setup game board
|
// Setup game board
|
||||||
#define TOP_ROW 4
|
#define TOP_ROW 4
|
||||||
@@ -19,6 +21,8 @@ typedef struct
|
|||||||
|
|
||||||
} GameData;
|
} GameData;
|
||||||
|
|
||||||
|
long GetCurrentMS();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setups the curses terminal environment
|
* Setups the curses terminal environment
|
||||||
*/
|
*/
|
||||||
@@ -45,7 +49,7 @@ void DrawWalls(GameData);
|
|||||||
/**
|
/**
|
||||||
* Draws the scoreboard and header
|
* Draws the scoreboard and header
|
||||||
*/
|
*/
|
||||||
void DrawHeader(GameData);
|
void DrawHeader(GameData* data, int* scores, int numOfBalls);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates text at a location on screen
|
* Creates text at a location on screen
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ Server StartServer(int port);
|
|||||||
*/
|
*/
|
||||||
void RemoveClient(Server* s, int index);
|
void RemoveClient(Server* s, int index);
|
||||||
|
|
||||||
|
void KillServer();
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int client_fd;
|
int client_fd;
|
||||||
struct sockaddr_in address;
|
struct sockaddr_in address;
|
||||||
|
|||||||
@@ -5,5 +5,12 @@
|
|||||||
#include "../object.h"
|
#include "../object.h"
|
||||||
|
|
||||||
int ProcessBallPacket(char* msg, Ball* ball, GameData* gd);
|
int ProcessBallPacket(char* msg, Ball* ball, GameData* gd);
|
||||||
|
int ProcessAlert(char* msg);
|
||||||
|
int ProcessGMSG(char* msg);
|
||||||
|
int ProcessScore(char* msg, int* scores);
|
||||||
|
int ProcessBallLost(char* msg, int fd, GameData* gd, int* scores, int* allowSever, int numOfBalls);
|
||||||
|
int ProcessNumOfBalls(char* msg, int* numOfBalls);
|
||||||
|
|
||||||
|
void SendGameStatus(int fd, char* msg);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -13,8 +13,8 @@ Ball CreateBall(GameData* gd)
|
|||||||
b.lastCharX = 0;
|
b.lastCharX = 0;
|
||||||
b.lastCharY = 0;
|
b.lastCharY = 0;
|
||||||
|
|
||||||
b.vx = -0.2;
|
b.vx = 0;
|
||||||
b.vy = 0.2;
|
b.vy = 0;
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
@@ -108,6 +108,6 @@ void ServeBall(Ball* ball, GameData* gd) {
|
|||||||
|
|
||||||
|
|
||||||
ball->vx = -0.2;
|
ball->vx = -0.2;
|
||||||
ball->vy = 0.2;
|
ball->vy = 0.09;
|
||||||
if (!gd->host) ball->vx *= -1;
|
if (!gd->host) ball->vx *= -1;
|
||||||
}
|
}
|
||||||
@@ -25,9 +25,7 @@ void DrawWalls(GameData data)
|
|||||||
|
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
void DrawHeader(GameData data)
|
void DrawHeader(GameData* data, int* scores, int numOfBalls)
|
||||||
{
|
{
|
||||||
move(TOP_ROW - 2, LEFT_COL);
|
mvprintw(TOP_ROW-1, LEFT_COL, "SCORES: P1: %d P2: %d Balls Left: %d", scores[0],scores[1],numOfBalls);
|
||||||
addch('P');
|
|
||||||
addch('0' + (data.playerNumber + 1));
|
|
||||||
}
|
}
|
||||||
140
src/gameClient.c
Normal file
140
src/gameClient.c
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
#include "../include/game.h"
|
||||||
|
#include "../include/network/packet.h"
|
||||||
|
#include "../include/object.h"
|
||||||
|
#include <curses.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
void RunGameClient(Client* client, GameData* gd)
|
||||||
|
{
|
||||||
|
Client c = *client;
|
||||||
|
|
||||||
|
Paddle paddle = CreatePaddle(gd);
|
||||||
|
Ball ball = CreateBall(gd);
|
||||||
|
int scores[2] = { 0, 0 };
|
||||||
|
|
||||||
|
long lastBallUpdate = GetCurrentMS();
|
||||||
|
|
||||||
|
int numOfBalls = 1;
|
||||||
|
bool game_running = true;
|
||||||
|
|
||||||
|
SetupTermWin();
|
||||||
|
|
||||||
|
GameAlert("Connected to server");
|
||||||
|
MGameAlert(BOT_ROW + 1, LEFT_COL, "Press space to Serve");
|
||||||
|
|
||||||
|
int allowServe = true;
|
||||||
|
|
||||||
|
DrawWalls(*gd);
|
||||||
|
DrawPaddle(&paddle);
|
||||||
|
DrawHeader(gd, scores, numOfBalls);
|
||||||
|
|
||||||
|
SendGameStatus(c.client_fd,"Waiting for serve");
|
||||||
|
|
||||||
|
while (game_running) {
|
||||||
|
|
||||||
|
fd_set read_fds;
|
||||||
|
FD_ZERO(&read_fds);
|
||||||
|
|
||||||
|
// Watch server socket
|
||||||
|
FD_SET(c.client_fd, &read_fds);
|
||||||
|
|
||||||
|
int max_fd = c.client_fd;
|
||||||
|
|
||||||
|
// Small timeout (same idea as server)
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle server messages
|
||||||
|
if (FD_ISSET(c.client_fd, &read_fds)) {
|
||||||
|
char buffer[1024];
|
||||||
|
int bytes = recv(c.client_fd, buffer, sizeof(buffer) - 1, 0);
|
||||||
|
|
||||||
|
if (bytes > 0) {
|
||||||
|
buffer[bytes] = '\0';
|
||||||
|
|
||||||
|
char msg[1024];
|
||||||
|
snprintf(msg, sizeof(msg), "Server says: %s\r", buffer);
|
||||||
|
GameAlert(buffer);
|
||||||
|
|
||||||
|
if (!ProcessBallPacket(buffer, &ball, gd)) {SendGameStatus(c.client_fd,"Ball is in other court");
|
||||||
|
MGameAlert(BOT_ROW+1,LEFT_COL,"");}
|
||||||
|
ProcessAlert(buffer);
|
||||||
|
ProcessGMSG(buffer);
|
||||||
|
if (!ProcessNumOfBalls(buffer, &numOfBalls)) {
|
||||||
|
DrawHeader(gd, scores, numOfBalls);
|
||||||
|
}
|
||||||
|
ProcessBallLost(buffer, c.client_fd, gd, scores, &allowServe, numOfBalls);
|
||||||
|
if (!ProcessScore(buffer, scores)) {
|
||||||
|
DrawHeader(gd, scores, numOfBalls);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (bytes == 0) {
|
||||||
|
GameAlert("Server disconnected. Quitting...");
|
||||||
|
sleep(2);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
perror("recv");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char ch = getch();
|
||||||
|
if (ch == 'w')
|
||||||
|
MovePaddleUP(&paddle);
|
||||||
|
if (ch == 's')
|
||||||
|
MovePaddleDown(&paddle);
|
||||||
|
|
||||||
|
// Process Ball only if on court
|
||||||
|
if (ball.visible) {
|
||||||
|
if (GetCurrentMS() > lastBallUpdate + 10) {
|
||||||
|
lastBallUpdate = GetCurrentMS();
|
||||||
|
UpdateBall(&ball, &paddle);
|
||||||
|
}
|
||||||
|
if (CheckBallCourtChange(gd, &ball)) {
|
||||||
|
GameAlert("Ball is in other court");
|
||||||
|
HideBall(&ball);
|
||||||
|
|
||||||
|
char msg[1024];
|
||||||
|
snprintf(msg, sizeof(msg), "BTRANS %f %f %f", ball.y, ball.vx, ball.vy);
|
||||||
|
send(c.client_fd, msg, strlen(msg), 0);
|
||||||
|
}
|
||||||
|
if (CheckBallLose(gd, &ball)) {
|
||||||
|
HideBall(&ball);
|
||||||
|
DrawWalls(*gd);
|
||||||
|
GameAlert("You lost the ball, other player serves");
|
||||||
|
char msg[1024];
|
||||||
|
snprintf(msg, sizeof(msg), "BALL_LOST Other player point");
|
||||||
|
send(c.client_fd, msg, strlen(msg), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch == 'q') {
|
||||||
|
GameAlert("Quitting...");
|
||||||
|
sleep(1);
|
||||||
|
game_running = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch == ' ' && allowServe) {
|
||||||
|
allowServe = false;
|
||||||
|
ServeBall(&ball, gd);
|
||||||
|
MGameAlert(BOT_ROW + 1, LEFT_COL, "");
|
||||||
|
SendGameStatus(c.client_fd,"Ball is in other court");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseTermWin();
|
||||||
|
}
|
||||||
183
src/gameServer.c
183
src/gameServer.c
@@ -1,6 +1,6 @@
|
|||||||
#include "../include/game.h"
|
#include "../include/game.h"
|
||||||
#include "../include/object.h"
|
|
||||||
#include "../include/network/packet.h"
|
#include "../include/network/packet.h"
|
||||||
|
#include "../include/object.h"
|
||||||
#include <curses.h>
|
#include <curses.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -26,7 +26,9 @@ void CreateGameServer(Server* serv, GameData* gd)
|
|||||||
|
|
||||||
Ball ball = CreateBall(gd);
|
Ball ball = CreateBall(gd);
|
||||||
long lastBallUpdate = GetCurrentMS();
|
long lastBallUpdate = GetCurrentMS();
|
||||||
|
int scores[2] = { 0, 0 };
|
||||||
|
|
||||||
|
int numOfBalls = 1;
|
||||||
bool game_running = true;
|
bool game_running = true;
|
||||||
|
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
@@ -38,6 +40,7 @@ void CreateGameServer(Server* serv, GameData* gd)
|
|||||||
SetupTermWin();
|
SetupTermWin();
|
||||||
|
|
||||||
DrawWalls(*gd);
|
DrawWalls(*gd);
|
||||||
|
DrawHeader(gd, scores, 0);
|
||||||
DrawPaddle(&paddle);
|
DrawPaddle(&paddle);
|
||||||
// DrawBall(&ball);
|
// DrawBall(&ball);
|
||||||
|
|
||||||
@@ -82,6 +85,17 @@ void CreateGameServer(Server* serv, GameData* gd)
|
|||||||
char msg[64];
|
char msg[64];
|
||||||
snprintf(msg, sizeof(msg), "New client connected: %d\n", client_fd);
|
snprintf(msg, sizeof(msg), "New client connected: %d\n", client_fd);
|
||||||
GameAlert(msg);
|
GameAlert(msg);
|
||||||
|
|
||||||
|
numOfBalls = NUM_OF_BALLS;
|
||||||
|
HideBall(&ball);
|
||||||
|
for (int i = 0; i < 2; ++i)
|
||||||
|
scores[i] = 0;
|
||||||
|
DrawWalls(*gd);
|
||||||
|
DrawHeader(gd, scores, numOfBalls);
|
||||||
|
|
||||||
|
char bmsg[1024];
|
||||||
|
snprintf(bmsg, sizeof(bmsg), "NUM_OF_BALLS %d", numOfBalls);
|
||||||
|
send(s.clients[0], bmsg, strlen(bmsg), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,10 +114,25 @@ void CreateGameServer(Server* serv, GameData* gd)
|
|||||||
snprintf(msg, sizeof(msg), "Client %d says: %s\r", fd, buffer);
|
snprintf(msg, sizeof(msg), "Client %d says: %s\r", fd, buffer);
|
||||||
GameAlert(msg);
|
GameAlert(msg);
|
||||||
|
|
||||||
ProcessBallPacket(buffer,&ball,gd);
|
if (!ProcessBallPacket(buffer, &ball, gd)) {
|
||||||
|
SendGameStatus(s.clients[0], "Ball is in other court");
|
||||||
|
MGameAlert(BOT_ROW + 1, LEFT_COL, "");
|
||||||
|
}
|
||||||
|
ProcessAlert(buffer);
|
||||||
|
ProcessGMSG(buffer);
|
||||||
|
if (!ProcessBallLost(buffer, s.clients[0], gd, scores, &allowServe, numOfBalls)) {
|
||||||
|
numOfBalls--;
|
||||||
|
DrawHeader(gd, scores, numOfBalls);
|
||||||
|
char bmsg[1024];
|
||||||
|
snprintf(bmsg, sizeof(bmsg), "NUM_OF_BALLS %d", numOfBalls);
|
||||||
|
send(s.clients[0], bmsg, strlen(bmsg), 0);
|
||||||
|
}
|
||||||
|
if (!ProcessScore(buffer, scores)) {
|
||||||
|
DrawHeader(gd, scores, numOfBalls);
|
||||||
|
}
|
||||||
|
|
||||||
// Example: echo back
|
// Example: echo back
|
||||||
//send(fd, buffer, bytes, 0);
|
// send(fd, buffer, bytes, 0);
|
||||||
} else if (bytes == 0) {
|
} else if (bytes == 0) {
|
||||||
char msg[64];
|
char msg[64];
|
||||||
snprintf(msg, sizeof(msg), "Client %d disconnected\n", fd);
|
snprintf(msg, sizeof(msg), "Client %d disconnected\n", fd);
|
||||||
@@ -131,14 +160,48 @@ void CreateGameServer(Server* serv, GameData* gd)
|
|||||||
lastBallUpdate = GetCurrentMS();
|
lastBallUpdate = GetCurrentMS();
|
||||||
UpdateBall(&ball, &paddle);
|
UpdateBall(&ball, &paddle);
|
||||||
}
|
}
|
||||||
if (CheckBallCourtChange(gd,&ball)) {
|
if (CheckBallCourtChange(gd, &ball)) {
|
||||||
GameAlert("Ball is in other court");
|
GameAlert("Ball is in other court");
|
||||||
HideBall(&ball);
|
HideBall(&ball);
|
||||||
|
|
||||||
char msg[1024];
|
char msg[1024];
|
||||||
snprintf(msg, sizeof(msg), "BTRANS %f %f %f", ball.y,ball.vx,ball.vy);
|
snprintf(msg, sizeof(msg), "BTRANS %f %f %f", ball.y, ball.vx, ball.vy);
|
||||||
send(s.clients[0], msg, strlen(msg), 0);
|
send(s.clients[0], msg, strlen(msg), 0);
|
||||||
}
|
}
|
||||||
|
if (CheckBallLose(gd, &ball)) {
|
||||||
|
HideBall(&ball);
|
||||||
|
DrawWalls(*gd);
|
||||||
|
numOfBalls--;
|
||||||
|
DrawHeader(gd, scores, numOfBalls);
|
||||||
|
GameAlert("You lost the ball, other player serves");
|
||||||
|
char bmsg[1024];
|
||||||
|
snprintf(bmsg, sizeof(bmsg), "NUM_OF_BALLS %d", numOfBalls);
|
||||||
|
send(s.clients[0], bmsg, strlen(bmsg), 0);
|
||||||
|
sleep(1);
|
||||||
|
char msg[1024];
|
||||||
|
snprintf(msg, sizeof(msg), "BALL_LOST Other player point");
|
||||||
|
send(s.clients[0], msg, strlen(msg), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numOfBalls == 0) {
|
||||||
|
|
||||||
|
sleep(1);
|
||||||
|
if (scores[0] == scores[1]) {
|
||||||
|
MGameAlert(BOT_ROW + 1, LEFT_COL, "Game over, it's a tie");
|
||||||
|
SendGameStatus(s.clients[0], "Game over, it's a tie");
|
||||||
|
}
|
||||||
|
if (scores[0] > scores[1]) {
|
||||||
|
MGameAlert(BOT_ROW + 1, LEFT_COL, "Game over, you win!");
|
||||||
|
SendGameStatus(s.clients[0], "Game over, you lost :(");
|
||||||
|
}
|
||||||
|
if (scores[0] < scores[1]) {
|
||||||
|
MGameAlert(BOT_ROW + 1, LEFT_COL, "Game over, you lost :(");
|
||||||
|
SendGameStatus(s.clients[0], "Game over, you win!");
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(3);
|
||||||
|
ch = 'q';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ch == 'q') {
|
if (ch == 'q') {
|
||||||
@@ -148,6 +211,13 @@ void CreateGameServer(Server* serv, GameData* gd)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ch == ' ' && allowServe) {
|
||||||
|
allowServe = false;
|
||||||
|
ServeBall(&ball, gd);
|
||||||
|
MGameAlert(BOT_ROW + 1, LEFT_COL, "");
|
||||||
|
SendGameStatus(s.clients[0], "Ball is in other court");
|
||||||
|
}
|
||||||
|
|
||||||
// if (s.client_count < 1) {
|
// if (s.client_count < 1) {
|
||||||
// char msg[64];
|
// char msg[64];
|
||||||
// snprintf(msg, sizeof(msg), "Waiting for other player\n");
|
// snprintf(msg, sizeof(msg), "Waiting for other player\n");
|
||||||
@@ -160,106 +230,3 @@ void CreateGameServer(Server* serv, GameData* gd)
|
|||||||
|
|
||||||
CloseTermWin();
|
CloseTermWin();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunGameClient(Client* client, GameData* gd)
|
|
||||||
{
|
|
||||||
Client c = *client;
|
|
||||||
|
|
||||||
Paddle paddle = CreatePaddle(gd);
|
|
||||||
Ball ball = CreateBall(gd);
|
|
||||||
|
|
||||||
|
|
||||||
long lastBallUpdate = GetCurrentMS();
|
|
||||||
|
|
||||||
bool game_running = true;
|
|
||||||
|
|
||||||
SetupTermWin();
|
|
||||||
|
|
||||||
GameAlert("Connected to server");
|
|
||||||
int allowServe = true;
|
|
||||||
|
|
||||||
DrawWalls(*gd);
|
|
||||||
DrawPaddle(&paddle);
|
|
||||||
|
|
||||||
while (game_running) {
|
|
||||||
|
|
||||||
fd_set read_fds;
|
|
||||||
FD_ZERO(&read_fds);
|
|
||||||
|
|
||||||
// Watch server socket
|
|
||||||
FD_SET(c.client_fd, &read_fds);
|
|
||||||
|
|
||||||
int max_fd = c.client_fd;
|
|
||||||
|
|
||||||
// Small timeout (same idea as server)
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle server messages
|
|
||||||
if (FD_ISSET(c.client_fd, &read_fds)) {
|
|
||||||
char buffer[1024];
|
|
||||||
int bytes = recv(c.client_fd, buffer, sizeof(buffer) - 1, 0);
|
|
||||||
|
|
||||||
if (bytes > 0) {
|
|
||||||
buffer[bytes] = '\0';
|
|
||||||
|
|
||||||
char msg[1024];
|
|
||||||
snprintf(msg, sizeof(msg), "Server says: %s\r", buffer);
|
|
||||||
GameAlert(msg);
|
|
||||||
|
|
||||||
ProcessBallPacket(buffer,&ball,gd);
|
|
||||||
|
|
||||||
} else if (bytes == 0) {
|
|
||||||
GameAlert("Server disconnected");
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
perror("recv");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char ch = getch();
|
|
||||||
if (ch == 'w')
|
|
||||||
MovePaddleUP(&paddle);
|
|
||||||
if (ch == 's')
|
|
||||||
MovePaddleDown(&paddle);
|
|
||||||
|
|
||||||
// Process Ball only if on court
|
|
||||||
if (ball.visible) {
|
|
||||||
if (GetCurrentMS() > lastBallUpdate + 10) {
|
|
||||||
lastBallUpdate = GetCurrentMS();
|
|
||||||
UpdateBall(&ball, &paddle);
|
|
||||||
}
|
|
||||||
if (CheckBallCourtChange(gd,&ball)) {
|
|
||||||
GameAlert("Ball is in other court");
|
|
||||||
HideBall(&ball);
|
|
||||||
|
|
||||||
char msg[1024];
|
|
||||||
snprintf(msg, sizeof(msg), "BTRANS %f %f %f", ball.y,ball.vx,ball.vy);
|
|
||||||
send(c.client_fd, msg, strlen(msg), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ch == 'q') {
|
|
||||||
GameAlert("Quitting...");
|
|
||||||
sleep(1);
|
|
||||||
game_running = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ch == ' ') {
|
|
||||||
allowServe = false;
|
|
||||||
ServeBall(&ball,gd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseTermWin();
|
|
||||||
}
|
|
||||||
@@ -6,8 +6,12 @@
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
|
||||||
|
|
||||||
|
static Server *g_server = NULL;
|
||||||
|
|
||||||
Server StartServer(int port) {
|
Server StartServer(int port) {
|
||||||
Server s;
|
Server s;
|
||||||
|
g_server = &s;
|
||||||
s.clientID = 0;
|
s.clientID = 0;
|
||||||
s.client_count = 0;
|
s.client_count = 0;
|
||||||
|
|
||||||
@@ -23,6 +27,9 @@ Server StartServer(int port) {
|
|||||||
s.address.sin_addr.s_addr = INADDR_ANY; // listen on all interfaces
|
s.address.sin_addr.s_addr = INADDR_ANY; // listen on all interfaces
|
||||||
s.address.sin_port = htons(port);
|
s.address.sin_port = htons(port);
|
||||||
|
|
||||||
|
signal(SIGINT, KillServer); // ctrl+c
|
||||||
|
signal(SIGTERM, KillServer);
|
||||||
|
|
||||||
// Bind Port
|
// Bind Port
|
||||||
if (bind(s.server_fd, (struct sockaddr *)&s.address, sizeof(s.address)) < 0) {
|
if (bind(s.server_fd, (struct sockaddr *)&s.address, sizeof(s.address)) < 0) {
|
||||||
perror("bind failed");
|
perror("bind failed");
|
||||||
@@ -48,6 +55,15 @@ void RemoveClient(Server* s, int index) {
|
|||||||
s->client_count--;
|
s->client_count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KillServer() {
|
||||||
|
close(g_server->server_fd);
|
||||||
|
|
||||||
|
int c = g_server->client_count;
|
||||||
|
for (int i = 0; i < c; ++i) {
|
||||||
|
RemoveClient(g_server,i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Client StartClient(char* host, int port) {
|
Client StartClient(char* host, int port) {
|
||||||
|
|
||||||
Client c;
|
Client c;
|
||||||
|
|||||||
@@ -5,10 +5,7 @@
|
|||||||
|
|
||||||
int ProcessBallPacket(char* msg, Ball* ball, GameData* gd)
|
int ProcessBallPacket(char* msg, Ball* ball, GameData* gd)
|
||||||
{
|
{
|
||||||
// 1. Verify prefix
|
|
||||||
if (strncmp(msg, "BTRANS", 6) != 0) {
|
if (strncmp(msg, "BTRANS", 6) != 0) {
|
||||||
printf("Invalid prefix\n");
|
|
||||||
printf("\nMSG: %s\n\n\n", msg);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,4 +23,88 @@ int ProcessBallPacket(char* msg, Ball* ball, GameData* gd)
|
|||||||
ball->visible = 1;
|
ball->visible = 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ProcessAlert(char* msg)
|
||||||
|
{
|
||||||
|
if (strncmp(msg, "ALERT:", 6) != 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
char* alertText = msg + 6;
|
||||||
|
if (*alertText == ' ') {
|
||||||
|
alertText++;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameAlert(alertText);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ProcessGMSG(char* msg)
|
||||||
|
{
|
||||||
|
if (strncmp(msg, "GMSG:", 5) != 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
char* alertText = msg + 5;
|
||||||
|
if (*alertText == ' ') {
|
||||||
|
alertText++;
|
||||||
|
}
|
||||||
|
|
||||||
|
MGameAlert(BOT_ROW+1,LEFT_COL,alertText);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ProcessScore(char* msg, int* scores)
|
||||||
|
{
|
||||||
|
if (strncmp(msg, "SCORE", 5) != 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int matched = sscanf(msg, "SCORE %d %d", &scores[0], &scores[1]);
|
||||||
|
if (matched != 2) {
|
||||||
|
printf("Parsing failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ProcessBallLost(char* msg, int fd, GameData* gd, int* scores, int* allowserve, int numOfBalls)
|
||||||
|
{
|
||||||
|
if (strncmp(msg, "BALL_LOST", 9) != 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
scores[!gd->host]++;
|
||||||
|
*allowserve = 1;
|
||||||
|
|
||||||
|
char rmsg[1024];
|
||||||
|
snprintf(rmsg, sizeof(rmsg), "SCORE %d %d", scores[0], scores[1]);
|
||||||
|
send(fd, rmsg, strlen(rmsg), 0);
|
||||||
|
|
||||||
|
DrawHeader(gd, scores,numOfBalls);
|
||||||
|
|
||||||
|
GameAlert("You scored a point!");
|
||||||
|
MGameAlert(BOT_ROW + 1, LEFT_COL, "Press space to Serve");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ProcessNumOfBalls(char* msg, int* numOfBalls) {
|
||||||
|
if (strncmp(msg, "NUM_OF_BALLS", 12) != 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int matched = sscanf(msg, "NUM_OF_BALLS %d", numOfBalls);
|
||||||
|
if (matched != 1) {
|
||||||
|
printf("Parsing failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendGameStatus(int fd, char* msg) {
|
||||||
|
char rmsg[1024];
|
||||||
|
snprintf(rmsg, sizeof(rmsg), "GMSG:%s", msg);
|
||||||
|
send(fd, rmsg, strlen(rmsg), 0);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user