Make the server not just spam packets

This commit is contained in:
Barra Ó Catháin 2023-07-09 17:45:51 +01:00
parent dcccf78b04
commit b87f2d06ba
3 changed files with 55 additions and 29 deletions

View File

@ -49,6 +49,13 @@ I didn't make the client update it's own input in the state constantly, so there
wasn't the required "single-player" feeling in the client. Not exactly what
we're going for, here!
** Entry 05: How client side prediction performs:
After running a basic test on my LAN, it appears as if my naive implementation
isn't performing as expected. It's possible that just spamming the client with
packets that aren't tied to the game tick is causing it; I'm going to change
that. It probably should have been done that way from the start; but I didn't
really think about that.
* Notes On Techniques:
** Entry 00: Where I'm Learning All This From:
I'm using a series of articles from gabrielgambetta.com, which seem to be well

View File

@ -71,7 +71,7 @@ void * networkHandler(void * parameters)
// Point at the server:
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
serverAddress.sin_addr.s_addr = inet_addr("192.168.0.100");
serverAddress.sin_port = htons(5200);
// Create a UDP socket to send through:
@ -231,7 +231,7 @@ int main(int argc, char ** argv)
// Set our IP address and port. Default to localhost for testing:
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
serverAddress.sin_addr.s_addr = inet_addr("192.168.0.100");
serverAddress.sin_port = htons(5200);
// Connect to the server:

View File

@ -24,6 +24,15 @@ struct connectionStatus
uint8_t remainingPongs;
};
// A structure containing the "current" global state:
struct ThreadParameters
{
struct sockaddr_in * clientAddresses;
struct clientInput * message;
struct gameState * state;
int * udpSocket;
};
void sigintHandler(int signal)
{
keepRunning = false;
@ -31,13 +40,11 @@ void sigintHandler(int signal)
void * networkThreadHandler(void * arguments)
{
int udpSocket;
pthread_t networkThread;
struct clientInput message;
socklen_t clientAddressLength;
struct ThreadParameters args = *(struct ThreadParameters *)arguments;
printf("%p\n", args.clientAddresses);
struct sockaddr_in clientAddress, serverAddress;
if ((udpSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
if ((*args.udpSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
exit(EXIT_FAILURE);
}
@ -47,22 +54,22 @@ void * networkThreadHandler(void * arguments)
serverAddress.sin_port = htons(5200);
serverAddress.sin_addr.s_addr = INADDR_ANY;
bind(udpSocket, (struct sockaddr *)&serverAddress, sizeof(struct sockaddr_in));
bind(*args.udpSocket, (struct sockaddr *)&serverAddress, sizeof(struct sockaddr_in));
printf("Started network thread.\n");
socklen_t test = sizeof(clientAddress);
int returnvalue = 0;
bzero(arguments, sizeof(struct gameState));
bzero(args.state, sizeof(struct gameState));
while (true)
{
recvfrom(udpSocket, &message, sizeof(struct clientInput), 0, (struct sockaddr *)&clientAddress, &test);
returnvalue = sendto(udpSocket, arguments, sizeof(struct gameState), 0,
(struct sockaddr *)&clientAddress, (socklen_t)sizeof(struct sockaddr_in));
returnvalue = recvfrom(*(args.udpSocket), args.message, sizeof(struct clientInput), 0, (struct sockaddr *)&clientAddress, &test);
memcpy(&(args.clientAddresses[args.message->clientNumber]), &clientAddress, sizeof(struct sockaddr_in));
if(returnvalue > 0)
{
updateInput(arguments, &message);
updateInput(args.state, args.message);
}
bzero(&message, sizeof(struct clientInput));
bzero(args.message, sizeof(struct clientInput));
}
return NULL;
@ -70,9 +77,16 @@ void * networkThreadHandler(void * arguments)
void * gameThreadHandler(void * arguments)
{
struct ThreadParameters args = *(struct ThreadParameters *)arguments;
sleep(1);
while (true)
{
doGameTick(arguments);
doGameTick(args.state);
for(int index = 0; index < 16; index++)
{
sendto(*(args.udpSocket), args.state, sizeof(struct gameState), 0,
(struct sockaddr *)&(args.clientAddresses[index]), (socklen_t)sizeof(struct sockaddr_in));
}
usleep(15625);
}
}
@ -82,20 +96,25 @@ int main(int argc, char ** argv)
int masterSocket = 0;
int clientSockets[16];
fd_set connectedClients;
pthread_t networkThread, gameThread;
struct gameState currentState;
struct sockaddr_in serverAddress;
struct CsptMessage currentMessage;
pthread_t networkThread, gameThread;
struct connectionStatus clientStatus[16];
struct networkThreadArguments networkArguments;
struct sockaddr_in serverAddress, clientAddress;
struct ThreadParameters * globalState = calloc(1, sizeof(struct ThreadParameters));
globalState->clientAddresses = calloc(16, sizeof(struct sockaddr_in));
globalState->message = calloc(1, sizeof(struct clientInput));
globalState->state = calloc(1, sizeof(struct gameState));
globalState->udpSocket = calloc(1, sizeof(int));
printf("Client-Side Prediction Test - Server Starting.\n");
// Setup the sigint handler:
signal(SIGINT, sigintHandler);
pthread_create(&networkThread, NULL, networkThreadHandler, globalState);
pthread_create(&gameThread, NULL, gameThreadHandler, globalState);
pthread_create(&networkThread, NULL, networkThreadHandler, &currentState);
pthread_create(&gameThread, NULL, gameThreadHandler, &currentState);
// Setup TCP Master Socket:
printf("Setting up master socket... ");
@ -218,11 +237,11 @@ int main(int argc, char ** argv)
case 0:
{
currentMessage.type = 0;
currentState.clients[index].registered = true;
currentState.clients[index].xPosition = 300;
currentState.clients[index].yPosition = 300;
currentState.clients[index].xVelocity = 0;
currentState.clients[index].yVelocity = 0;
globalState->state->clients[index].registered = true;
globalState->state->clients[index].xPosition = 300;
globalState->state->clients[index].yPosition = 300;
globalState->state->clients[index].xVelocity = 0;
globalState->state->clients[index].yVelocity = 0;
currentMessage.content = (uint8_t)index;
send(clientSockets[index], &currentMessage, sizeof(struct CsptMessage), 0);
break;
@ -230,7 +249,7 @@ int main(int argc, char ** argv)
// Goodbye:
case 1:
{
currentState.clients[index].registered = false;
globalState->state->clients[index].registered = false;
FD_CLR(clientSockets[index], &connectedClients);
shutdown(clientSockets[index], SHUT_RDWR);
clientSockets[index] = 0;