v1.0.0-dev
This commit is contained in:
commit
aa0e847547
|
@ -0,0 +1,3 @@
|
||||||
|
.vscode
|
||||||
|
build
|
||||||
|
spaceserver
|
|
@ -0,0 +1,14 @@
|
||||||
|
![logo](images/logo.png)
|
||||||
|
|
||||||
|
[SpaceShooter](https://git.zhirov.kz/games/spaceshooter) Network Game Server.
|
||||||
|
|
||||||
|
This server is under development. Currently, the repository has been suspended since 2020.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
```sh
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake -B . -S ../server
|
||||||
|
make
|
||||||
|
```
|
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
|
@ -0,0 +1,32 @@
|
||||||
|
cmake_minimum_required(VERSION 3.0)
|
||||||
|
project(spaceserver)
|
||||||
|
|
||||||
|
include_directories("lib/" "games/" "objects/" "users/")
|
||||||
|
|
||||||
|
set(SRC_SERVER
|
||||||
|
calculation.c
|
||||||
|
common.c
|
||||||
|
connection.c
|
||||||
|
data.c
|
||||||
|
main.c
|
||||||
|
update.c)
|
||||||
|
|
||||||
|
set(SRC_LIB
|
||||||
|
lib/common.c
|
||||||
|
lib/event.c
|
||||||
|
lib/enet.c
|
||||||
|
lib/message.c
|
||||||
|
lib/timer.c)
|
||||||
|
|
||||||
|
set(SRC_USERS users/users.c)
|
||||||
|
|
||||||
|
set(SRC_OBJECTS objects/objects.c)
|
||||||
|
|
||||||
|
set(SRC_GAMES games/games.c)
|
||||||
|
|
||||||
|
find_library(ENET_LIB enet)
|
||||||
|
find_library(ALLEGRO_LIB allegro)
|
||||||
|
|
||||||
|
add_executable(${PROJECT_NAME} ${SRC_SERVER} ${SRC_LIB} ${SRC_USERS} ${SRC_OBJECTS} ${SRC_GAMES})
|
||||||
|
|
||||||
|
target_link_libraries(${PROJECT_NAME} ${ENET_LIB} ${ALLEGRO_LIB})
|
|
@ -0,0 +1,275 @@
|
||||||
|
#include "calculation.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* SHIP
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void srv_move_ship(SERVER_DATA* data, SERVER_GAME* game, SERVER_MESSAGE_UPDATE* message)
|
||||||
|
{
|
||||||
|
SERVER_OBJECTS* objects = &game->objects;
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->ship_size; i++)
|
||||||
|
{
|
||||||
|
SERVER_SHIP* ship = objects->ships[i];
|
||||||
|
|
||||||
|
if(ship->active)
|
||||||
|
{
|
||||||
|
SERVER_USER* user = NULL;
|
||||||
|
|
||||||
|
for(int j = 0; j < game->user_size; j++)
|
||||||
|
if(game->user[j] && game->user[j]->id == ship->ID)
|
||||||
|
user = game->user[j];
|
||||||
|
|
||||||
|
ship->y += user->command.dy * ship->speed * data->timer.elapsed_time;
|
||||||
|
if(ship->y < 0)
|
||||||
|
ship->y = 0;
|
||||||
|
else if(ship->y > game->display_height)
|
||||||
|
ship->y = game->display_height;
|
||||||
|
|
||||||
|
ship->x += user->command.dx * ship->speed * data->timer.elapsed_time;
|
||||||
|
if(ship->x < 0)
|
||||||
|
ship->x = 0;
|
||||||
|
else if(ship->x > 900 * game->scale_factor)
|
||||||
|
ship->x = 900 * game->scale_factor;
|
||||||
|
|
||||||
|
message->ship[i].dx = user->command.dx;
|
||||||
|
message->ship[i].dy = user->command.dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
message->ship[i].ID = ship->ID;
|
||||||
|
message->ship[i].x = ship->x;
|
||||||
|
message->ship[i].y = ship->y;
|
||||||
|
message->ship[i].lives = ship->lives;
|
||||||
|
message->ship[i].score = ship->score;
|
||||||
|
message->ship[i].active = ship->active;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* BULLET
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void srv_fire_bullet(SERVER_GAME* game)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < game->user_size; i++)
|
||||||
|
{
|
||||||
|
if(game->user[i] && game->user[i]->command.fire)
|
||||||
|
{
|
||||||
|
SERVER_OBJECTS* objects = &game->objects;
|
||||||
|
SERVER_SHIP* ship = NULL;
|
||||||
|
|
||||||
|
for(int j = 0; j < objects->ship_size; j++)
|
||||||
|
if(objects->ships[j]->ID == game->user[i]->id)
|
||||||
|
ship = objects->ships[j];
|
||||||
|
|
||||||
|
if(!ship->active) continue;
|
||||||
|
|
||||||
|
for(int j = 0; j < objects->bullet_size; j++)
|
||||||
|
{
|
||||||
|
SERVER_BULLET* bullet = objects->bullets[j];
|
||||||
|
|
||||||
|
if(!bullet->live && bullet->ID == game->user[i]->id)
|
||||||
|
{
|
||||||
|
bullet->x = ship->x + 17;
|
||||||
|
bullet->y = ship->y;
|
||||||
|
bullet->live = true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_update_bullet(SERVER_DATA* data, SERVER_GAME* game, SERVER_MESSAGE_UPDATE* message)
|
||||||
|
{
|
||||||
|
SERVER_OBJECTS* objects = &game->objects;
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->bullet_size; i++)
|
||||||
|
{
|
||||||
|
SERVER_BULLET* bullet = objects->bullets[i];
|
||||||
|
|
||||||
|
if(bullet->live)
|
||||||
|
{
|
||||||
|
bullet->x += bullet->speed * data->timer.elapsed_time;
|
||||||
|
if(bullet->x > game->display_width)
|
||||||
|
bullet->live = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
message->bullet[i].ID = bullet->ID;
|
||||||
|
message->bullet[i].active = bullet->active;
|
||||||
|
message->bullet[i].live = bullet->live;
|
||||||
|
message->bullet[i].x = bullet->x;
|
||||||
|
message->bullet[i].y = bullet->y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void srv_collide_bullet(SERVER_GAME* game, SERVER_MESSAGE_UPDATE* message)
|
||||||
|
{
|
||||||
|
SERVER_OBJECTS* objects = &game->objects;
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->bullet_size; i++)
|
||||||
|
{
|
||||||
|
SERVER_BULLET* bullet = objects->bullets[i];
|
||||||
|
|
||||||
|
if(bullet->live)
|
||||||
|
{
|
||||||
|
for(int j = 0; j < objects->comet_size; j++)
|
||||||
|
{
|
||||||
|
SERVER_COMET* comet = objects->comets[j];
|
||||||
|
|
||||||
|
if(comet->live)
|
||||||
|
{
|
||||||
|
if(bullet->x > (comet->x - comet->boundx) &&
|
||||||
|
bullet->x < (comet->x + comet->boundx) &&
|
||||||
|
bullet->y > (comet->y - comet->boundy) &&
|
||||||
|
bullet->y < (comet->y + comet->boundy))
|
||||||
|
{
|
||||||
|
bullet->live = false;
|
||||||
|
comet->live = false;
|
||||||
|
|
||||||
|
for(int k = 0; k < objects->ship_size; k++)
|
||||||
|
if(bullet->ID == objects->ships[k]->ID)
|
||||||
|
objects->ships[k]->score++;
|
||||||
|
|
||||||
|
srv_start_explosions(game, message, bullet->x, bullet->y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* COMET
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void srv_start_comet(SERVER_GAME* game)
|
||||||
|
{
|
||||||
|
SERVER_OBJECTS* objects = &game->objects;
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->comet_size; i++)
|
||||||
|
{
|
||||||
|
SERVER_COMET* comet = objects->comets[i];
|
||||||
|
|
||||||
|
if(!comet->live)
|
||||||
|
{
|
||||||
|
if(rand() % 500 == 0)
|
||||||
|
{
|
||||||
|
comet->live = true;
|
||||||
|
comet->x = game->display_width;
|
||||||
|
comet->y = 30 + rand() % (game->display_height - 60);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_update_comet(SERVER_DATA* data, SERVER_GAME* game, SERVER_MESSAGE_UPDATE* message)
|
||||||
|
{
|
||||||
|
SERVER_OBJECTS* objects = &game->objects;
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->comet_size; i++)
|
||||||
|
{
|
||||||
|
SERVER_COMET* comet = objects->comets[i];
|
||||||
|
|
||||||
|
if(comet->live)
|
||||||
|
comet->x -= comet->speed * data->timer.elapsed_time;
|
||||||
|
|
||||||
|
message->comet[i].live = comet->live;
|
||||||
|
message->comet[i].x = comet->x;
|
||||||
|
message->comet[i].y = comet->y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_collide_comet(SERVER_GAME* game, SERVER_MESSAGE_UPDATE* message)
|
||||||
|
{
|
||||||
|
SERVER_OBJECTS* objects = &game->objects;
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->comet_size; i++)
|
||||||
|
{
|
||||||
|
SERVER_COMET* comet = objects->comets[i];
|
||||||
|
|
||||||
|
if(!comet->live) continue;
|
||||||
|
|
||||||
|
for(int j = 0; j < objects->ship_size; j++)
|
||||||
|
{
|
||||||
|
SERVER_SHIP* ship = objects->ships[j];
|
||||||
|
|
||||||
|
if(!ship->active) continue;
|
||||||
|
|
||||||
|
if((comet->x - comet->boundx) < (ship->x + ship->boundx) &&
|
||||||
|
(comet->x + comet->boundx) > (ship->x - ship->boundx) &&
|
||||||
|
(comet->y - comet->boundy) < (ship->y + ship->boundy) &&
|
||||||
|
(comet->y + comet->boundy) > (ship->y - ship->boundy))
|
||||||
|
{
|
||||||
|
ship->lives--;
|
||||||
|
comet->live = false;
|
||||||
|
|
||||||
|
srv_start_explosions(game, message, ship->x, ship->y);
|
||||||
|
}
|
||||||
|
else if(comet->x < 0)
|
||||||
|
{
|
||||||
|
comet->live = false;
|
||||||
|
ship->lives--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ship->lives <= 0)
|
||||||
|
ship->active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* EXPLOSION
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
static void srv_start_explosions(SERVER_GAME* game, SERVER_MESSAGE_UPDATE* message, int x, int y)
|
||||||
|
{
|
||||||
|
SERVER_OBJECTS* objects = &game->objects;
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->explosion_size; i++)
|
||||||
|
{
|
||||||
|
SERVER_EXPLOSION* explosion = objects->explosions[i];
|
||||||
|
|
||||||
|
if(!explosion->live)
|
||||||
|
{
|
||||||
|
explosion->live = true;
|
||||||
|
explosion->x = x;
|
||||||
|
explosion->y = y;
|
||||||
|
|
||||||
|
message->explosion[i].live = explosion->live;
|
||||||
|
message->explosion[i].x = explosion->x;
|
||||||
|
message->explosion[i].y = explosion->y;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_update_explosions(SERVER_DATA* data, SERVER_GAME* game)
|
||||||
|
{
|
||||||
|
SERVER_OBJECTS* objects = &game->objects;
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->explosion_size; i++)
|
||||||
|
{
|
||||||
|
SERVER_EXPLOSION* explosion = objects->explosions[i];
|
||||||
|
|
||||||
|
if(explosion->live)
|
||||||
|
{
|
||||||
|
explosion->lifetime += data->timer.elapsed_time;
|
||||||
|
|
||||||
|
if(explosion->lifetime >= 1.5)
|
||||||
|
{
|
||||||
|
explosion->lifetime = 0;
|
||||||
|
explosion->live = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* File: calculation.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messanger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.26
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef server_calculation
|
||||||
|
#define server_calculation
|
||||||
|
|
||||||
|
#include "games.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "connection.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* SHIP
|
||||||
|
***********************************************************/
|
||||||
|
void srv_move_ship(SERVER_DATA* data, SERVER_GAME* game, SERVER_MESSAGE_UPDATE* message);
|
||||||
|
/************************************************************
|
||||||
|
* BULLET
|
||||||
|
***********************************************************/
|
||||||
|
void srv_fire_bullet(SERVER_GAME* game);
|
||||||
|
void srv_update_bullet(SERVER_DATA* data, SERVER_GAME* game, SERVER_MESSAGE_UPDATE* message);
|
||||||
|
void srv_collide_bullet(SERVER_GAME* game, SERVER_MESSAGE_UPDATE* message);
|
||||||
|
/************************************************************
|
||||||
|
* COMET
|
||||||
|
***********************************************************/
|
||||||
|
void srv_start_comet(SERVER_GAME* game);
|
||||||
|
void srv_update_comet(SERVER_DATA* data, SERVER_GAME* game, SERVER_MESSAGE_UPDATE* message);
|
||||||
|
void srv_collide_comet(SERVER_GAME* game, SERVER_MESSAGE_UPDATE* message);
|
||||||
|
/************************************************************
|
||||||
|
* EXPLOSION
|
||||||
|
***********************************************************/
|
||||||
|
static void srv_start_explosions(SERVER_GAME* game, SERVER_MESSAGE_UPDATE* message, int x, int y);
|
||||||
|
void srv_update_explosions(SERVER_DATA* data, SERVER_GAME* game);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
#define _DEFAULT_SOURCE
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "lib/message.h"
|
||||||
|
|
||||||
|
void srv_catch_signal(int signal, void (*handler)(int))
|
||||||
|
{
|
||||||
|
struct sigaction action;
|
||||||
|
action.sa_handler = handler;
|
||||||
|
sigemptyset(&action.sa_mask);
|
||||||
|
action.sa_flags = 0;
|
||||||
|
|
||||||
|
show_message_error(sigaction(signal, &action, NULL) == 0, "Failed to register signal");
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_stop_server(int signal)
|
||||||
|
{
|
||||||
|
SERVER_DATA* data = srv_get_server_data(NULL);
|
||||||
|
|
||||||
|
data->done = true;
|
||||||
|
|
||||||
|
puts("--------------------------------------------------");
|
||||||
|
puts("Останавливаю сервер! Без паники!");
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* File: common.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messanger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.14
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef server_data
|
||||||
|
#define server_data
|
||||||
|
|
||||||
|
#include "lib/common.h"
|
||||||
|
#include "users.h"
|
||||||
|
#include "games.h"
|
||||||
|
|
||||||
|
typedef struct srv_data
|
||||||
|
{
|
||||||
|
SERVER_ENET enet;
|
||||||
|
SERVER_TIMER timer;
|
||||||
|
SERVER_EVENT event;
|
||||||
|
SERVER_USERS users;
|
||||||
|
SERVER_GAMES games;
|
||||||
|
bool done;
|
||||||
|
} SERVER_DATA;
|
||||||
|
|
||||||
|
SERVER_DATA* srv_create_data(SERVER_DATA* data, SERVER_PARAMETRS parametrs);
|
||||||
|
void srv_destroy_data(SERVER_DATA* data);
|
||||||
|
SERVER_DATA* srv_get_server_data(SERVER_DATA* data);
|
||||||
|
|
||||||
|
void srv_catch_signal(int signal, void (*handler)(int));
|
||||||
|
void srv_stop_server(int signal);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,334 @@
|
||||||
|
#include "connection.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* CONNECTION HANDLING
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void srv_send_receive(SERVER_DATA* data)
|
||||||
|
{
|
||||||
|
ENetPacket *packet;
|
||||||
|
ENetEvent event;
|
||||||
|
SERVER_MESSAGE_NONE* message_none;
|
||||||
|
SERVER_MESSAGE_JOINGAME* message_list;
|
||||||
|
SERVER_MESSAGE_SENDPARTY* message_party;
|
||||||
|
SERVER_MESSAGE_GAME* message_game;
|
||||||
|
|
||||||
|
while (enet_host_service(data->enet.server, &event, 0) > 0)
|
||||||
|
{
|
||||||
|
switch(event.type)
|
||||||
|
{
|
||||||
|
case ENET_EVENT_TYPE_NONE:
|
||||||
|
break;
|
||||||
|
case ENET_EVENT_TYPE_CONNECT:
|
||||||
|
printf("Сервер: новый пользователь из %x:%hu\n", event.peer->address.host, event.peer->address.port);
|
||||||
|
|
||||||
|
SERVER_USER* user = srv_get_free_user(&data->users);
|
||||||
|
show_message_error(user, "Failed to allocate free game");
|
||||||
|
// Отсоединить пользователя
|
||||||
|
// enet_peer_disconnect_now(event.peer, 0);
|
||||||
|
user->peer = event.peer; // сохранить пир в пользователе
|
||||||
|
|
||||||
|
event.peer->data = malloc(sizeof(int));
|
||||||
|
*(int*)event.peer->data = user->id;
|
||||||
|
printf("Сервер: пользователь присоединён #%d\n", user->id);
|
||||||
|
break;
|
||||||
|
case ENET_EVENT_TYPE_RECEIVE:
|
||||||
|
{
|
||||||
|
int user_id = *(int*)event.peer->data;
|
||||||
|
|
||||||
|
switch(data->users.user[user_id]->state)
|
||||||
|
{
|
||||||
|
case STATE_NONE:
|
||||||
|
message_none = (SERVER_MESSAGE_NONE*)event.packet->data;
|
||||||
|
srv_readmessage_none(data, user_id, message_none);
|
||||||
|
break;
|
||||||
|
case STATE_LIST:
|
||||||
|
message_list = (SERVER_MESSAGE_JOINGAME*)event.packet->data;
|
||||||
|
srv_readmessage_list(data, user_id, message_list);
|
||||||
|
break;
|
||||||
|
case STATE_PARTY:
|
||||||
|
message_party = (SERVER_MESSAGE_SENDPARTY*)event.packet->data;
|
||||||
|
srv_readmessage_party(data, user_id, message_party);
|
||||||
|
break;
|
||||||
|
case STATE_GAME:
|
||||||
|
message_game = (SERVER_MESSAGE_GAME*)event.packet->data;
|
||||||
|
srv_readmessage_game(data, user_id, message_game);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
enet_packet_destroy(event.packet);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ENET_EVENT_TYPE_DISCONNECT:
|
||||||
|
{
|
||||||
|
int user_id = *(int*)event.peer->data;
|
||||||
|
srv_removing_from_game(data, data->users.user[user_id]);
|
||||||
|
srv_clear_user(data->users.user[user_id]);
|
||||||
|
|
||||||
|
printf("Сервер: пользователь #%d был отсоединён\n", user_id);
|
||||||
|
// сообщить пользователям об отсоединении клиента
|
||||||
|
|
||||||
|
free(event.peer->data);
|
||||||
|
event.peer->data = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void srv_readmessage_none(SERVER_DATA* data, int user_id, SERVER_MESSAGE_NONE* message)
|
||||||
|
{
|
||||||
|
SERVER_USER* user = data->users.user[user_id];
|
||||||
|
|
||||||
|
user->display_height = message->display_height;
|
||||||
|
user->display_width = message->display_width;
|
||||||
|
user->scale_factor = message->scale_factor;
|
||||||
|
user->is_creator = message->is_creator;
|
||||||
|
user->is_ready = message->is_ready;
|
||||||
|
strncpy(user->nickname, message->nickname, 40);
|
||||||
|
|
||||||
|
if(message->is_creator)
|
||||||
|
srv_create_new_game(data, user, message->game_name);
|
||||||
|
|
||||||
|
srv_change_state(data, user_id, message->state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void srv_readmessage_list(SERVER_DATA* data, int user_id, SERVER_MESSAGE_JOINGAME* message)
|
||||||
|
{
|
||||||
|
SERVER_USER* user = data->users.user[user_id];
|
||||||
|
SERVER_GAME* game = data->games.game[message->id];
|
||||||
|
|
||||||
|
ENetPacket *packet;
|
||||||
|
SERVER_MESSAGE_LIST answer;
|
||||||
|
|
||||||
|
if(game->count_connected < 3)
|
||||||
|
{
|
||||||
|
game->count_connected++;
|
||||||
|
|
||||||
|
srv_change_state(data, user_id, message->state);
|
||||||
|
|
||||||
|
user->game_id = message->id;
|
||||||
|
user->in_game = true;
|
||||||
|
|
||||||
|
for(int i = 0; i < game->user_size; i++)
|
||||||
|
if(!game->user[i])
|
||||||
|
{
|
||||||
|
game->user[i] = user;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
answer.state = message->state;
|
||||||
|
|
||||||
|
packet = enet_packet_create(&answer, sizeof(answer), ENET_PACKET_FLAG_RELIABLE);
|
||||||
|
enet_peer_send(user->peer, 0, packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void srv_readmessage_party(SERVER_DATA* data, int user_id, SERVER_MESSAGE_SENDPARTY* message)
|
||||||
|
{
|
||||||
|
SERVER_USER* user = data->users.user[user_id];
|
||||||
|
|
||||||
|
switch(message->state)
|
||||||
|
{
|
||||||
|
case STATE_LIST:
|
||||||
|
if(message->kick_user)
|
||||||
|
user = data->users.user[message->user_id];
|
||||||
|
|
||||||
|
srv_removing_from_game(data, user);
|
||||||
|
user->state = message->state;
|
||||||
|
user->in_game = false;
|
||||||
|
user->is_ready = false;
|
||||||
|
user->game_id = -1;
|
||||||
|
user->is_creator = false;
|
||||||
|
|
||||||
|
srv_send_change_state(user, message->state);
|
||||||
|
break;
|
||||||
|
case STATE_PARTY:
|
||||||
|
user->is_ready = message->is_ready;
|
||||||
|
break;
|
||||||
|
case STATE_GAME:
|
||||||
|
srv_start_game(data, user);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void srv_readmessage_game(SERVER_DATA* data, int user_id, SERVER_MESSAGE_GAME* message)
|
||||||
|
{
|
||||||
|
SERVER_USER* user = data->users.user[user_id];
|
||||||
|
|
||||||
|
switch(message->state)
|
||||||
|
{
|
||||||
|
case STATE_GAME:
|
||||||
|
{
|
||||||
|
user->command.dx = message->dx;
|
||||||
|
user->command.dy = message->dy;
|
||||||
|
user->command.fire = message->fire;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void srv_change_state(SERVER_DATA* data, int user_id, SERVER_STATE state)
|
||||||
|
{
|
||||||
|
SERVER_USER* user = data->users.user[user_id];
|
||||||
|
|
||||||
|
user->state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void srv_create_new_game(SERVER_DATA* data, SERVER_USER* user, const char* game_name)
|
||||||
|
{
|
||||||
|
// Creating a new game and placing the user there
|
||||||
|
SERVER_GAME* game = srv_get_free_game(&data->games);
|
||||||
|
// Отправить сообщение в случае, если нет места для создания новой игры
|
||||||
|
show_message_error(game, "Failed to allocate free game");
|
||||||
|
|
||||||
|
user->game_id = game->id;
|
||||||
|
user->in_game = true;
|
||||||
|
game->user[0] = user;
|
||||||
|
game->count_connected++;
|
||||||
|
strncpy(game->game_name, game_name, 40);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void srv_removing_from_game(SERVER_DATA* data, SERVER_USER* user)
|
||||||
|
{
|
||||||
|
if(user->in_game)
|
||||||
|
{
|
||||||
|
SERVER_GAME* game = data->games.game[user->game_id];
|
||||||
|
|
||||||
|
for(int i = 0; i < game->user_size; i++)
|
||||||
|
if(game->user[i] && game->user[i]->id == user->id)
|
||||||
|
{
|
||||||
|
game->user[i] = NULL;
|
||||||
|
--game->count_connected;
|
||||||
|
|
||||||
|
if(game->game_started)
|
||||||
|
{
|
||||||
|
for(int j = 0; j < game->objects.ship_size; j++)
|
||||||
|
if(user->id == game->objects.ships[j]->ID)
|
||||||
|
game->objects.ships[j]->active = false;
|
||||||
|
|
||||||
|
for(int j = 0; j < game->objects.bullet_size; j++)
|
||||||
|
if(user->id == game->objects.bullets[j]->ID)
|
||||||
|
game->objects.bullets[j]->active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(game->count_connected == 0)
|
||||||
|
{
|
||||||
|
if(game->game_started)
|
||||||
|
srv_destroy_objects(&game->objects);
|
||||||
|
|
||||||
|
srv_clear_games(game);
|
||||||
|
}
|
||||||
|
else if(user->is_creator)
|
||||||
|
{
|
||||||
|
for(int j = 0; j < game->user_size; j++)
|
||||||
|
if(game->user[j])
|
||||||
|
{
|
||||||
|
game->user[j]->is_creator = true;
|
||||||
|
game->user[j]->is_ready = true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void srv_start_game(SERVER_DATA* data, SERVER_USER* user)
|
||||||
|
{
|
||||||
|
if(user->in_game)
|
||||||
|
{
|
||||||
|
bool users_ready = true;
|
||||||
|
|
||||||
|
SERVER_GAME* game = data->games.game[user->game_id];
|
||||||
|
|
||||||
|
for(int i = 0; i < game->user_size; i++)
|
||||||
|
if(game->user[i])
|
||||||
|
if(!game->user[i]->is_ready)
|
||||||
|
{
|
||||||
|
users_ready = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(users_ready)
|
||||||
|
{
|
||||||
|
game->game_started = true;
|
||||||
|
|
||||||
|
srv_init_objects(game);
|
||||||
|
|
||||||
|
for(int i = 0; i < game->user_size; i++)
|
||||||
|
if(game->user[i])
|
||||||
|
{
|
||||||
|
game->user[i]->command.dx = 0;
|
||||||
|
game->user[i]->command.dy = 0;
|
||||||
|
game->user[i]->command.fire = false;
|
||||||
|
|
||||||
|
game->user[i]->state = STATE_GAME;
|
||||||
|
|
||||||
|
srv_send_change_state(game->user[i], STATE_GAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void srv_send_change_state(SERVER_USER* user, SERVER_STATE state)
|
||||||
|
{
|
||||||
|
ENetPacket *packet;
|
||||||
|
SERVER_MESSAGE_PARTY message;
|
||||||
|
|
||||||
|
message.state = state;
|
||||||
|
packet = enet_packet_create(&message, sizeof(message), ENET_PACKET_FLAG_RELIABLE);
|
||||||
|
enet_peer_send(user->peer, 0, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void srv_init_objects(SERVER_GAME* game)
|
||||||
|
{
|
||||||
|
SERVER_OBJECTS* objects = &game->objects;
|
||||||
|
int count_users = game->count_connected;
|
||||||
|
|
||||||
|
int start_position = 0;
|
||||||
|
int position_ratio = 1; // part user position
|
||||||
|
bool start_ratio = false;
|
||||||
|
int iterator = 0;
|
||||||
|
|
||||||
|
srv_create_objects(objects, count_users, 5 * count_users, 15, 5 * count_users);
|
||||||
|
|
||||||
|
for(int i = 0; i < game->user_size; i++)
|
||||||
|
if(game->user[i] && game->user[i]->is_creator)
|
||||||
|
{
|
||||||
|
game->display_width = game->user[i]->display_width;
|
||||||
|
game->display_height = game->user[i]->display_height;
|
||||||
|
game->scale_factor = game->user[i]->scale_factor;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
start_position = game->display_height / (count_users * 2);
|
||||||
|
|
||||||
|
for(int i = 0; i < game->user_size; i++)
|
||||||
|
if(game->user[i])
|
||||||
|
{
|
||||||
|
if(start_ratio)
|
||||||
|
position_ratio += 2;
|
||||||
|
else
|
||||||
|
start_ratio = true;
|
||||||
|
|
||||||
|
srv_init_ships(objects, iterator, game->user[i]->id, 3, 1, 1, 10, 12, 0, 0, 50, 41, 46, 3, 3, 0, 250, 20, start_position * position_ratio);
|
||||||
|
|
||||||
|
for(int j = iterator++ * 5; j < iterator * 5; j++)
|
||||||
|
srv_init_bullets(objects, j, game->user[i]->id, 500, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->comet_size; i++)
|
||||||
|
srv_init_comets(objects, i, 0, 21, rand() % 2 ? 1 : -1, 35, 35, 0, 0, 2, 96, 96, 143, 250, 0, 0);
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->explosion_size; i++)
|
||||||
|
srv_init_explosions(objects, i, 8, 1, 0, 0, 1, 128, 128, 31, 0, 0);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,155 @@
|
||||||
|
/*
|
||||||
|
* File: connection.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messanger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.14
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef server_connection
|
||||||
|
#define server_connection
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
typedef struct srv_usercommand
|
||||||
|
{
|
||||||
|
int dx;
|
||||||
|
int dy;
|
||||||
|
bool fire;
|
||||||
|
} SERVER_USER_COMMAND;
|
||||||
|
|
||||||
|
typedef struct srv_userdata
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
char nickname[40];
|
||||||
|
bool is_ready;
|
||||||
|
SERVER_USER_COMMAND command;
|
||||||
|
} SERVER_USER_DATA;
|
||||||
|
|
||||||
|
typedef struct srv_gamedata
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
char game_name[40];
|
||||||
|
int count_connected;
|
||||||
|
} SERVER_GAME_DATA;
|
||||||
|
|
||||||
|
typedef struct srv_message_none
|
||||||
|
{
|
||||||
|
int display_width;
|
||||||
|
int display_height;
|
||||||
|
float scale_factor;
|
||||||
|
SERVER_STATE state;
|
||||||
|
char game_name[40];
|
||||||
|
char nickname[40];
|
||||||
|
bool is_creator;
|
||||||
|
bool is_ready;
|
||||||
|
} SERVER_MESSAGE_NONE;
|
||||||
|
|
||||||
|
typedef struct srv_message_list
|
||||||
|
{
|
||||||
|
SERVER_GAME_DATA games[3];
|
||||||
|
SERVER_STATE state;
|
||||||
|
int count_game;
|
||||||
|
} SERVER_MESSAGE_LIST;
|
||||||
|
|
||||||
|
typedef struct srv_message_party
|
||||||
|
{
|
||||||
|
int game_id;
|
||||||
|
int user_id;
|
||||||
|
SERVER_USER_DATA users[3];
|
||||||
|
char game_name[40];
|
||||||
|
int count_connected;
|
||||||
|
bool game_started;
|
||||||
|
bool active;
|
||||||
|
bool is_creator;
|
||||||
|
bool is_ready;
|
||||||
|
SERVER_STATE state;
|
||||||
|
} SERVER_MESSAGE_PARTY;
|
||||||
|
|
||||||
|
typedef struct srv_message_sendparty
|
||||||
|
{
|
||||||
|
SERVER_STATE state;
|
||||||
|
bool is_creator;
|
||||||
|
bool is_ready;
|
||||||
|
bool kick_user;
|
||||||
|
int user_id;
|
||||||
|
} SERVER_MESSAGE_SENDPARTY;
|
||||||
|
|
||||||
|
typedef struct srv_message_joingame
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
SERVER_STATE state;
|
||||||
|
} SERVER_MESSAGE_JOINGAME;
|
||||||
|
|
||||||
|
typedef struct srv_message_game
|
||||||
|
{
|
||||||
|
int dx;
|
||||||
|
int dy;
|
||||||
|
bool fire;
|
||||||
|
SERVER_STATE state;
|
||||||
|
} SERVER_MESSAGE_GAME;
|
||||||
|
|
||||||
|
// GAME
|
||||||
|
|
||||||
|
typedef struct srv_update_ship
|
||||||
|
{
|
||||||
|
int ID;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int dx;
|
||||||
|
int dy;
|
||||||
|
int lives;
|
||||||
|
int score;
|
||||||
|
bool active;
|
||||||
|
} SERVER_UPDATE_SHIP;
|
||||||
|
|
||||||
|
typedef struct srv_update_bullet
|
||||||
|
{
|
||||||
|
int ID;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
bool live;
|
||||||
|
bool active;
|
||||||
|
} SERVER_UPDATE_BULLET;
|
||||||
|
|
||||||
|
typedef struct srv_update_comet
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
bool live;
|
||||||
|
} SERVER_UPDATE_COMET;
|
||||||
|
|
||||||
|
typedef struct srv_update_explosion
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
bool live;
|
||||||
|
} SERVER_UPDATE_EXPLOSION;
|
||||||
|
|
||||||
|
typedef struct srv_message_update
|
||||||
|
{
|
||||||
|
SERVER_UPDATE_SHIP ship[3];
|
||||||
|
SERVER_UPDATE_BULLET bullet[15];
|
||||||
|
SERVER_UPDATE_COMET comet[15];
|
||||||
|
SERVER_UPDATE_EXPLOSION explosion[15];
|
||||||
|
} SERVER_MESSAGE_UPDATE;
|
||||||
|
|
||||||
|
void srv_send_receive(SERVER_DATA* data);
|
||||||
|
static void srv_readmessage_none(SERVER_DATA* data, int user_id, SERVER_MESSAGE_NONE* message);
|
||||||
|
static void srv_readmessage_list(SERVER_DATA* data, int user_id, SERVER_MESSAGE_JOINGAME* message);
|
||||||
|
static void srv_readmessage_party(SERVER_DATA* data, int user_id, SERVER_MESSAGE_SENDPARTY* message);
|
||||||
|
static void srv_readmessage_game(SERVER_DATA* data, int user_id, SERVER_MESSAGE_GAME* message);
|
||||||
|
static void srv_change_state(SERVER_DATA* data, int user_id, SERVER_STATE state);
|
||||||
|
|
||||||
|
static void srv_create_new_game(SERVER_DATA* data, SERVER_USER* user, const char* game_name);
|
||||||
|
static void srv_removing_from_game(SERVER_DATA* data, SERVER_USER* user);
|
||||||
|
static void srv_start_game(SERVER_DATA* data, SERVER_USER* user);
|
||||||
|
|
||||||
|
static void srv_send_change_state(SERVER_USER* user, SERVER_STATE state);
|
||||||
|
|
||||||
|
static void srv_init_objects(SERVER_GAME* game);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
SERVER_DATA* srv_create_data(SERVER_DATA* data, SERVER_PARAMETRS parametrs)
|
||||||
|
{
|
||||||
|
if(!data)
|
||||||
|
{
|
||||||
|
data = (SERVER_DATA*)malloc(sizeof(SERVER_DATA));
|
||||||
|
show_message_error(data, "Failed to allocate space for SERVER_DATA");
|
||||||
|
}
|
||||||
|
|
||||||
|
srv_create_enet(&data->enet, parametrs.port);
|
||||||
|
puts("Enet создан!");
|
||||||
|
srv_create_timer(&data->timer, parametrs.FPS);
|
||||||
|
puts("Таймер загружен. Готов к запуску!");
|
||||||
|
srv_create_event(&data->event, &data->timer);
|
||||||
|
puts("События ждут указаний!");
|
||||||
|
srv_create_users(&data->users, parametrs.users);
|
||||||
|
puts("Место для игроков выделено!");
|
||||||
|
srv_create_games(&data->games, parametrs.games);
|
||||||
|
puts("Место для игр выделено!");
|
||||||
|
puts("Все системы в норме! Запускаю сервер!");
|
||||||
|
puts("--------------------------------------------------");
|
||||||
|
|
||||||
|
data->done = false;
|
||||||
|
|
||||||
|
srv_get_server_data(data);
|
||||||
|
// Server Stop Event Logging
|
||||||
|
srv_catch_signal(SIGINT, srv_stop_server);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_destroy_data(SERVER_DATA* data)
|
||||||
|
{
|
||||||
|
srv_destroy_enet(&data->enet);
|
||||||
|
puts("Почистил Enet!");
|
||||||
|
srv_destroy_event(&data->event);
|
||||||
|
puts("С событиями тоже разобрался!");
|
||||||
|
srv_destroy_timer(&data->timer);
|
||||||
|
puts("Кто говорил, что временем нельзя управлять? Таймер остановлен!");
|
||||||
|
srv_destroy_users(&data->users);
|
||||||
|
puts("Освободил выделенное место для игроков!");
|
||||||
|
srv_destroy_games(&data->games);
|
||||||
|
puts("Освободил выделенное место для игр!");
|
||||||
|
free(data);
|
||||||
|
puts("Сервер остановлен! Порядок!");
|
||||||
|
}
|
||||||
|
|
||||||
|
SERVER_DATA* srv_get_server_data(SERVER_DATA* data)
|
||||||
|
{
|
||||||
|
static SERVER_DATA* server;
|
||||||
|
|
||||||
|
if(data)
|
||||||
|
server = data;
|
||||||
|
|
||||||
|
return server;
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
#include "games.h"
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
SERVER_GAMES* srv_create_games(SERVER_GAMES* games, int game_size)
|
||||||
|
{
|
||||||
|
if(!games)
|
||||||
|
{
|
||||||
|
games = (SERVER_GAMES*)malloc(sizeof(SERVER_GAMES));
|
||||||
|
show_message_error(games, "Failed to allocate space for SERVER_GAMES");
|
||||||
|
}
|
||||||
|
|
||||||
|
games->game_size = game_size;
|
||||||
|
|
||||||
|
if(game_size)
|
||||||
|
{
|
||||||
|
games->game = (SERVER_GAME**)malloc(sizeof(SERVER_GAME*) * game_size);
|
||||||
|
show_message_error(games->game, "Failed to allocate space for SERVER_GAME collection");
|
||||||
|
|
||||||
|
for(int i = 0; i < game_size; i++)
|
||||||
|
{
|
||||||
|
games->game[i] = (SERVER_GAME*)malloc(sizeof(SERVER_GAME));
|
||||||
|
show_message_error(games->game[i], "Failed to allocate space for SERVER_USER");
|
||||||
|
|
||||||
|
games->game[i]->user = (SERVER_USER**)malloc(sizeof(SERVER_USER*) * 3);
|
||||||
|
show_message_error(games->game[i]->user, "Failed to allocate space for SERVER_USER collection");
|
||||||
|
|
||||||
|
games->game[i]->active = false;
|
||||||
|
games->game[i]->game_started = false;
|
||||||
|
games->game[i]->count_connected = 0;
|
||||||
|
games->game[i]->user_size = 3;
|
||||||
|
games->game[i]->game_name[0] = '\0';
|
||||||
|
games->game[i]->display_width = 0;
|
||||||
|
games->game[i]->display_height = 0;
|
||||||
|
games->game[i]->scale_factor = 0;
|
||||||
|
|
||||||
|
for(int j = 0; j < 3; j++)
|
||||||
|
games->game[i]->user[j] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
games->game = NULL;
|
||||||
|
|
||||||
|
return games;
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_free_games(SERVER_GAMES* games)
|
||||||
|
{
|
||||||
|
srv_destroy_games(games);
|
||||||
|
free(games);
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_destroy_games(SERVER_GAMES* games)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < games->game_size; i++)
|
||||||
|
{
|
||||||
|
free(games->game[i]->user);
|
||||||
|
free(games->game[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(games->game);
|
||||||
|
}
|
||||||
|
|
||||||
|
// return pointer
|
||||||
|
SERVER_GAME* srv_get_free_game(SERVER_GAMES* games)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < games->game_size; i++)
|
||||||
|
if(!games->game[i]->active)
|
||||||
|
{
|
||||||
|
games->game[i]->active = true;
|
||||||
|
games->game[i]->id = i;
|
||||||
|
return games->game[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_clear_games(SERVER_GAME* game)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < game->user_size; i++)
|
||||||
|
game->user[i] = NULL;
|
||||||
|
|
||||||
|
game->active = false;
|
||||||
|
game->game_started = false;
|
||||||
|
game->count_connected = 0;
|
||||||
|
game->game_name[0] = '\0';
|
||||||
|
game->display_width = 0;
|
||||||
|
game->display_height = 0;
|
||||||
|
game->scale_factor = 0;
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* File: games.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messanger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.15
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef server_games
|
||||||
|
#define server_games
|
||||||
|
|
||||||
|
#include "users.h"
|
||||||
|
#include "objects.h"
|
||||||
|
|
||||||
|
typedef struct srv_game
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
int display_width;
|
||||||
|
int display_height;
|
||||||
|
float scale_factor;
|
||||||
|
char game_name[40];
|
||||||
|
SERVER_USER** user;
|
||||||
|
int user_size;
|
||||||
|
int count_connected;
|
||||||
|
bool game_started;
|
||||||
|
bool active;
|
||||||
|
SERVER_OBJECTS objects;
|
||||||
|
} SERVER_GAME;
|
||||||
|
|
||||||
|
typedef struct srv_games
|
||||||
|
{
|
||||||
|
SERVER_GAME** game;
|
||||||
|
int game_size;
|
||||||
|
} SERVER_GAMES;
|
||||||
|
|
||||||
|
SERVER_GAMES* srv_create_games(SERVER_GAMES* games, int game_size);
|
||||||
|
void srv_free_games(SERVER_GAMES* games);
|
||||||
|
void srv_destroy_games(SERVER_GAMES* games);
|
||||||
|
|
||||||
|
void srv_clear_games(SERVER_GAME* game);
|
||||||
|
SERVER_GAME* srv_get_free_game(SERVER_GAMES* games);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
#include <allegro5/allegro.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
void srv_load_resources()
|
||||||
|
{
|
||||||
|
show_message_error(al_init(), "Failed to initialize Allegro");
|
||||||
|
show_message_error(srv_check_init_enet(enet_initialize()), "Failed to enet initialize");
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* File: common.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messanger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.13
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef server_common
|
||||||
|
#define server_common
|
||||||
|
|
||||||
|
#include "enet.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include "event.h"
|
||||||
|
|
||||||
|
typedef struct srv_resource
|
||||||
|
{
|
||||||
|
SERVER_ENET enet;
|
||||||
|
SERVER_TIMER timer;
|
||||||
|
SERVER_EVENT event;
|
||||||
|
} SERVER_RESOURCE;
|
||||||
|
|
||||||
|
typedef struct cl_parametrs
|
||||||
|
{
|
||||||
|
int port;
|
||||||
|
int FPS;
|
||||||
|
int users;
|
||||||
|
int games;
|
||||||
|
} SERVER_PARAMETRS;
|
||||||
|
|
||||||
|
void srv_load_resources();
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,36 @@
|
||||||
|
#include "enet.h"
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
SERVER_ENET* srv_create_enet(SERVER_ENET* enet, int port)
|
||||||
|
{
|
||||||
|
if(!enet)
|
||||||
|
{
|
||||||
|
enet = (SERVER_ENET*)malloc(sizeof(SERVER_ENET));
|
||||||
|
show_message_error(enet, "Failed to allocate space for SERVER_ENET");
|
||||||
|
}
|
||||||
|
|
||||||
|
enet->address.host = ENET_HOST_ANY;
|
||||||
|
enet->address.port = port;
|
||||||
|
|
||||||
|
enet->server = enet_host_create(&enet->address, 32, 2, 0, 0);
|
||||||
|
show_message_error(enet->server, "Failed to enet host create");
|
||||||
|
|
||||||
|
return enet;
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_free_enet(SERVER_ENET* enet)
|
||||||
|
{
|
||||||
|
srv_destroy_enet(enet);
|
||||||
|
free(enet);
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_destroy_enet(SERVER_ENET* enet)
|
||||||
|
{
|
||||||
|
enet_host_destroy(enet->server);
|
||||||
|
enet_deinitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool srv_check_init_enet(int result)
|
||||||
|
{
|
||||||
|
return result == 0;
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* File: enet.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messanger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.13
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef server_enet
|
||||||
|
#define server_enet
|
||||||
|
|
||||||
|
#include <enet/enet.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef struct srv_enet
|
||||||
|
{
|
||||||
|
ENetHost* server;
|
||||||
|
ENetAddress address;
|
||||||
|
} SERVER_ENET;
|
||||||
|
|
||||||
|
SERVER_ENET* srv_create_enet(SERVER_ENET* enet, int port);
|
||||||
|
void srv_free_enet(SERVER_ENET* enet);
|
||||||
|
void srv_destroy_enet(SERVER_ENET* enet);
|
||||||
|
|
||||||
|
bool srv_check_init_enet(int result);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,30 @@
|
||||||
|
#include "event.h"
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
SERVER_EVENT* srv_create_event(SERVER_EVENT* event, SERVER_TIMER* timer)
|
||||||
|
{
|
||||||
|
if(!event)
|
||||||
|
{
|
||||||
|
event = (SERVER_EVENT*)malloc(sizeof(SERVER_EVENT));
|
||||||
|
show_message_error(event, "Failed to allocate space for SERVER_EVENT");
|
||||||
|
}
|
||||||
|
|
||||||
|
event->queue = al_create_event_queue();
|
||||||
|
show_message_error(event->queue, "Failed to create Allegro event");
|
||||||
|
|
||||||
|
if(timer)
|
||||||
|
al_register_event_source(event->queue, al_get_timer_event_source(timer->al_timer));
|
||||||
|
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_free_event(SERVER_EVENT* event)
|
||||||
|
{
|
||||||
|
srv_destroy_event(event);
|
||||||
|
free(event);
|
||||||
|
};
|
||||||
|
|
||||||
|
void srv_destroy_event(SERVER_EVENT* event)
|
||||||
|
{
|
||||||
|
al_destroy_event_queue(event->queue);
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* File: event.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messanger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.13
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef server_event
|
||||||
|
#define server_event
|
||||||
|
|
||||||
|
#include <allegro5/allegro5.h>
|
||||||
|
#include "timer.h"
|
||||||
|
|
||||||
|
typedef struct srv_event
|
||||||
|
{
|
||||||
|
ALLEGRO_EVENT_QUEUE* queue;
|
||||||
|
ALLEGRO_EVENT current;
|
||||||
|
} SERVER_EVENT;
|
||||||
|
|
||||||
|
SERVER_EVENT* srv_create_event(SERVER_EVENT* event, SERVER_TIMER* timer);
|
||||||
|
void srv_free_event(SERVER_EVENT* event);
|
||||||
|
void srv_destroy_event(SERVER_EVENT* event);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
void show_message_error(bool result, const char* message)
|
||||||
|
{
|
||||||
|
if(!result)
|
||||||
|
{
|
||||||
|
printf("%s\n", message);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* File: message.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messanger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.13
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef server_message
|
||||||
|
#define server_message
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
void show_message_error(bool result, const char* message);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
#include "timer.h"
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
SERVER_TIMER* srv_create_timer(SERVER_TIMER* timer, int FPS)
|
||||||
|
{
|
||||||
|
if(!timer)
|
||||||
|
{
|
||||||
|
timer = (SERVER_TIMER*)malloc(sizeof(SERVER_TIMER));
|
||||||
|
show_message_error(timer, "Failed to allocate space for SERVER_TIMER");
|
||||||
|
}
|
||||||
|
|
||||||
|
timer->al_timer = al_create_timer(1.0 / FPS);
|
||||||
|
show_message_error(timer->al_timer, "Failed to create Allegro timer");
|
||||||
|
|
||||||
|
timer->last_time = 0.0;
|
||||||
|
timer->current_time = 0.0;
|
||||||
|
timer->elapsed_time = 0.0;
|
||||||
|
|
||||||
|
return timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_free_timer(SERVER_TIMER* timer)
|
||||||
|
{
|
||||||
|
srv_destroy_timer(timer);
|
||||||
|
free(timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_destroy_timer(SERVER_TIMER* timer)
|
||||||
|
{
|
||||||
|
al_destroy_timer(timer->al_timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_update_time(SERVER_TIMER* timer)
|
||||||
|
{
|
||||||
|
timer->last_time = timer->current_time;
|
||||||
|
timer->current_time = al_get_time();
|
||||||
|
timer->elapsed_time = timer->current_time - timer->last_time;
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* File: timer.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messanger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.13
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef server_timer
|
||||||
|
#define server_timer
|
||||||
|
|
||||||
|
#include <allegro5/allegro5.h>
|
||||||
|
|
||||||
|
typedef struct srv_timer
|
||||||
|
{
|
||||||
|
ALLEGRO_TIMER* al_timer;
|
||||||
|
double last_time;
|
||||||
|
double current_time;
|
||||||
|
double elapsed_time;
|
||||||
|
} SERVER_TIMER;
|
||||||
|
|
||||||
|
SERVER_TIMER* srv_create_timer(SERVER_TIMER* timer, int FPS);
|
||||||
|
|
||||||
|
void srv_free_timer(SERVER_TIMER* timer);
|
||||||
|
void srv_destroy_timer(SERVER_TIMER* timer);
|
||||||
|
void srv_update_time(SERVER_TIMER* timer);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "server.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
srv_load_resources();
|
||||||
|
|
||||||
|
SERVER_PARAMETRS parametrs =
|
||||||
|
{
|
||||||
|
.port = 9234,
|
||||||
|
.FPS = 60,
|
||||||
|
.users = 30,
|
||||||
|
.games = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
SERVER_DATA* data = srv_create_data(NULL, parametrs);
|
||||||
|
|
||||||
|
al_start_timer(data->timer.al_timer);
|
||||||
|
data->timer.current_time = al_current_time();
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
|
||||||
|
while(!data->done)
|
||||||
|
{
|
||||||
|
al_wait_for_event(data->event.queue, &data->event.current);
|
||||||
|
|
||||||
|
if(data->event.current.type == ALLEGRO_EVENT_TIMER)
|
||||||
|
{
|
||||||
|
srv_update_time(&data->timer);
|
||||||
|
// возможно тут нужно сделать потоки
|
||||||
|
srv_game_update(data);
|
||||||
|
srv_client_update(data);
|
||||||
|
|
||||||
|
srv_send_receive(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
srv_destroy_data(data);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
|
@ -0,0 +1,194 @@
|
||||||
|
#include "objects.h"
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
SERVER_OBJECTS* srv_create_objects(SERVER_OBJECTS* objects, int ship_size, int bullet_size, int comet_size, int explosion_size)
|
||||||
|
{
|
||||||
|
if(!objects)
|
||||||
|
{
|
||||||
|
SERVER_OBJECTS* objects = (SERVER_OBJECTS*)malloc(sizeof(SERVER_OBJECTS));
|
||||||
|
show_message_error(objects, "Failed to allocate space for SERVER_OBJECTS");
|
||||||
|
}
|
||||||
|
|
||||||
|
objects->ship_size = ship_size;
|
||||||
|
objects->bullet_size = bullet_size;
|
||||||
|
objects->comet_size = comet_size;
|
||||||
|
objects->explosion_size = explosion_size;
|
||||||
|
|
||||||
|
objects->ships = srv_create_ships(ship_size);
|
||||||
|
objects->bullets = srv_create_bullets(bullet_size);
|
||||||
|
objects->comets = srv_create_comets(comet_size);
|
||||||
|
objects->explosions = srv_create_explosions(explosion_size);
|
||||||
|
|
||||||
|
return objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_free_objects(SERVER_OBJECTS* objects)
|
||||||
|
{
|
||||||
|
srv_destroy_objects(objects);
|
||||||
|
free(objects);
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_destroy_objects(SERVER_OBJECTS* objects)
|
||||||
|
{
|
||||||
|
if(objects->ship_size > 0)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < objects->ship_size; i++)
|
||||||
|
free(objects->ships[i]);
|
||||||
|
free(objects->ships);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(objects->bullet_size > 0)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < objects->bullet_size; i++)
|
||||||
|
free(objects->bullets[i]);
|
||||||
|
free(objects->bullets);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(objects->comet_size > 0)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < objects->comet_size; i++)
|
||||||
|
free(objects->comets[i]);
|
||||||
|
free(objects->comets);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(objects->explosion_size > 0)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < objects->explosion_size; i++)
|
||||||
|
free(objects->explosions[i]);
|
||||||
|
free(objects->explosions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static SERVER_SHIP** srv_create_ships(int size)
|
||||||
|
{
|
||||||
|
SERVER_SHIP** ships = (SERVER_SHIP**)malloc(sizeof(SERVER_SHIP*) * size);
|
||||||
|
show_message_error(ships, "Failed to allocate space for SERVER_SHIP collection");
|
||||||
|
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
ships[i] = (SERVER_SHIP*)malloc(sizeof(SERVER_SHIP));
|
||||||
|
show_message_error(ships[i], "Failed to allocate space for SERVER_SHIP");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ships;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SERVER_BULLET** srv_create_bullets(int size)
|
||||||
|
{
|
||||||
|
SERVER_BULLET** bullets = (SERVER_BULLET**)malloc(sizeof(SERVER_BULLET*) * size);
|
||||||
|
show_message_error(bullets, "Failed to allocate space for SERVER_BULLET collection");
|
||||||
|
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
bullets[i] = (SERVER_BULLET*)malloc(sizeof(SERVER_BULLET));
|
||||||
|
show_message_error(bullets[i], "Failed to allocate space for SERVER_BULLET");
|
||||||
|
}
|
||||||
|
|
||||||
|
return bullets;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SERVER_COMET** srv_create_comets(int size)
|
||||||
|
{
|
||||||
|
SERVER_COMET** comets = (SERVER_COMET**)malloc(sizeof(SERVER_COMET*) * size);
|
||||||
|
show_message_error(comets, "Failed to allocate space for SERVER_COMET collection");
|
||||||
|
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
comets[i] = (SERVER_COMET*)malloc(sizeof(SERVER_COMET));
|
||||||
|
show_message_error(comets[i], "Failed to allocate space for SERVER_COMET");
|
||||||
|
}
|
||||||
|
|
||||||
|
return comets;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SERVER_EXPLOSION** srv_create_explosions(int size)
|
||||||
|
{
|
||||||
|
SERVER_EXPLOSION** explosions = (SERVER_EXPLOSION**)malloc(sizeof(SERVER_EXPLOSION*) * size);
|
||||||
|
show_message_error(explosions, "Failed to allocate space for SERVER_EXPLOSION collection");
|
||||||
|
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
explosions[i] = (SERVER_EXPLOSION*)malloc(sizeof(SERVER_EXPLOSION));
|
||||||
|
show_message_error(explosions[i], "Failed to allocate space for SERVER_EXPLOSION");
|
||||||
|
}
|
||||||
|
|
||||||
|
return explosions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_init_ships(SERVER_OBJECTS* objects, int key_ship, int ID, int animation_columns, int animation_direction, int animation_row, int boundx, int boundy, int cur_frame,
|
||||||
|
int frame_count, int frame_delay, int frame_height, int frame_width, int lives, int max_frame, int score, int speed, int x, int y)
|
||||||
|
{
|
||||||
|
SERVER_SHIP* ship = objects->ships[key_ship];
|
||||||
|
|
||||||
|
ship->ID = ID;
|
||||||
|
ship->animation_columns = animation_columns;
|
||||||
|
ship->animation_direction = animation_direction;
|
||||||
|
ship->animation_row = animation_row;
|
||||||
|
ship->boundx = boundx;
|
||||||
|
ship->boundy = boundy;
|
||||||
|
ship->cur_frame = cur_frame;
|
||||||
|
ship->frame_count = frame_count;
|
||||||
|
ship->frame_delay = frame_delay;
|
||||||
|
ship->frame_height = frame_height;
|
||||||
|
ship->frame_width = frame_width;
|
||||||
|
ship->lives = lives;
|
||||||
|
ship->max_frame = max_frame;
|
||||||
|
ship->score = score;
|
||||||
|
ship->speed = speed;
|
||||||
|
ship->x = x;
|
||||||
|
ship->y = y;
|
||||||
|
ship->active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_init_bullets(SERVER_OBJECTS* objects, int key_bullet, int ID, int speed, int x, int y)
|
||||||
|
{
|
||||||
|
SERVER_BULLET* bullet = objects->bullets[key_bullet];
|
||||||
|
|
||||||
|
bullet->ID = ID;
|
||||||
|
bullet->live = false;
|
||||||
|
bullet->speed = speed;
|
||||||
|
bullet->x = x;
|
||||||
|
bullet->y = y;
|
||||||
|
bullet->active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_init_comets(SERVER_OBJECTS* objects, int key_comet, int ID, int animation_columns, int animation_direction, int boundx, int boundy, int cur_frame,
|
||||||
|
int frame_count, int frame_delay, int frame_height, int frame_width, int max_frame, int speed, int x, int y)
|
||||||
|
{
|
||||||
|
SERVER_COMET* comet = objects->comets[key_comet];
|
||||||
|
|
||||||
|
comet->ID = ID;
|
||||||
|
comet->animation_columns = animation_columns;
|
||||||
|
comet->animation_direction = animation_direction;
|
||||||
|
comet->boundx = boundx;
|
||||||
|
comet->boundy = boundy;
|
||||||
|
comet->cur_frame = cur_frame;
|
||||||
|
comet->frame_count = frame_count;
|
||||||
|
comet->frame_delay = frame_delay;
|
||||||
|
comet->frame_height = frame_height;
|
||||||
|
comet->frame_width = frame_width;
|
||||||
|
comet->max_frame = max_frame;
|
||||||
|
comet->speed = speed;
|
||||||
|
comet->live = false;
|
||||||
|
comet->x = x;
|
||||||
|
comet->y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_init_explosions(SERVER_OBJECTS* objects, int key_explosion, int animation_columns, int animation_direction, int cur_frame,
|
||||||
|
int frame_count, int frame_delay, int frame_height, int frame_width, int max_frame, int x, int y)
|
||||||
|
{
|
||||||
|
SERVER_EXPLOSION* explosion = objects->explosions[key_explosion];
|
||||||
|
|
||||||
|
explosion->animation_columns = animation_columns;
|
||||||
|
explosion->animation_direction = animation_direction;
|
||||||
|
explosion->cur_frame = cur_frame;
|
||||||
|
explosion->frame_count = frame_count;
|
||||||
|
explosion->frame_delay = frame_delay;
|
||||||
|
explosion->frame_height = frame_height;
|
||||||
|
explosion->frame_width = frame_width;
|
||||||
|
explosion->live = false;
|
||||||
|
explosion->max_frame = max_frame;
|
||||||
|
explosion->x = x;
|
||||||
|
explosion->y = y;
|
||||||
|
explosion->lifetime = 0;
|
||||||
|
}
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* File: objects.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messanger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.03
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef server_objects
|
||||||
|
#define server_objects
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef struct srv_ship
|
||||||
|
{
|
||||||
|
int ID;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int lives;
|
||||||
|
int speed;
|
||||||
|
int boundx;
|
||||||
|
int boundy;
|
||||||
|
int score;
|
||||||
|
bool active;
|
||||||
|
|
||||||
|
int max_frame;
|
||||||
|
int cur_frame;
|
||||||
|
int frame_count;
|
||||||
|
int frame_delay;
|
||||||
|
int frame_width;
|
||||||
|
int frame_height;
|
||||||
|
int animation_columns;
|
||||||
|
int animation_direction;
|
||||||
|
|
||||||
|
int animation_row;
|
||||||
|
} SERVER_SHIP;
|
||||||
|
|
||||||
|
typedef struct srv_bullet
|
||||||
|
{
|
||||||
|
int ID;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
bool live;
|
||||||
|
int speed;
|
||||||
|
bool active;
|
||||||
|
} SERVER_BULLET;
|
||||||
|
|
||||||
|
typedef struct srv_comet
|
||||||
|
{
|
||||||
|
int ID;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
bool live;
|
||||||
|
int speed;
|
||||||
|
int boundx;
|
||||||
|
int boundy;
|
||||||
|
|
||||||
|
int max_frame;
|
||||||
|
int cur_frame;
|
||||||
|
int frame_count;
|
||||||
|
int frame_delay;
|
||||||
|
int frame_width;
|
||||||
|
int frame_height;
|
||||||
|
int animation_columns;
|
||||||
|
int animation_direction;
|
||||||
|
} SERVER_COMET;
|
||||||
|
|
||||||
|
typedef struct srv_explosion
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
bool live;
|
||||||
|
float lifetime;
|
||||||
|
|
||||||
|
int max_frame;
|
||||||
|
int cur_frame;
|
||||||
|
int frame_count;
|
||||||
|
int frame_delay;
|
||||||
|
int frame_width;
|
||||||
|
int frame_height;
|
||||||
|
int animation_columns;
|
||||||
|
int animation_direction;
|
||||||
|
} SERVER_EXPLOSION;
|
||||||
|
|
||||||
|
typedef struct srv_objects
|
||||||
|
{
|
||||||
|
SERVER_SHIP** ships;
|
||||||
|
int ship_size;
|
||||||
|
SERVER_BULLET** bullets;
|
||||||
|
int bullet_size;
|
||||||
|
SERVER_COMET** comets;
|
||||||
|
int comet_size;
|
||||||
|
SERVER_EXPLOSION** explosions;
|
||||||
|
int explosion_size;
|
||||||
|
} SERVER_OBJECTS;
|
||||||
|
|
||||||
|
SERVER_OBJECTS* srv_create_objects(SERVER_OBJECTS* data, int ship_size, int bullet_size, int comet_size, int explosion_size);
|
||||||
|
void srv_free_objects(SERVER_OBJECTS* objects);
|
||||||
|
void srv_destroy_objects(SERVER_OBJECTS* objects);
|
||||||
|
|
||||||
|
static SERVER_SHIP** srv_create_ships(int size);
|
||||||
|
static SERVER_BULLET** srv_create_bullets(int size);
|
||||||
|
static SERVER_COMET** srv_create_comets(int size);
|
||||||
|
static SERVER_EXPLOSION** srv_create_explosions(int size);
|
||||||
|
|
||||||
|
void srv_init_ships(SERVER_OBJECTS* objects, int key_ship, int ID, int animation_columns, int animation_direction, int animation_row, int boundx, int boundy, int cur_frame,
|
||||||
|
int frame_count, int frame_delay, int frame_height, int frame_width, int lives, int max_frame, int score, int speed, int x, int y);
|
||||||
|
void srv_init_bullets(SERVER_OBJECTS* objects, int key_bullet, int ID, int speed, int x, int y);
|
||||||
|
void srv_init_comets(SERVER_OBJECTS* objects, int key_comet, int ID, int animation_columns, int animation_direction, int boundx, int boundy, int cur_frame,
|
||||||
|
int frame_count, int frame_delay, int frame_height, int frame_width, int max_frame, int speed, int x, int y);
|
||||||
|
void srv_init_explosions(SERVER_OBJECTS* objects, int key_explosion, int animation_columns, int animation_direction, int cur_frame,
|
||||||
|
int frame_count, int frame_delay, int frame_height, int frame_width, int max_frame, int x, int y);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* File: server.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messanger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.14
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SERVER_H
|
||||||
|
#define SERVER_H
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "connection.h"
|
||||||
|
#include "update.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,164 @@
|
||||||
|
#include "update.h"
|
||||||
|
#include "connection.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* UPDATE GAMES
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void srv_game_update(SERVER_DATA* data)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < data->games.game_size; i++)
|
||||||
|
{
|
||||||
|
if(!data->games.game[i]->active) continue;
|
||||||
|
|
||||||
|
SERVER_GAME* game = data->games.game[i];
|
||||||
|
|
||||||
|
if(game->game_started)
|
||||||
|
srv_handle_game(data, game);
|
||||||
|
else
|
||||||
|
srv_handle_party(data, game);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void srv_handle_party(SERVER_DATA* data, SERVER_GAME* game)
|
||||||
|
{
|
||||||
|
ENetPacket *packet;
|
||||||
|
SERVER_MESSAGE_PARTY message;
|
||||||
|
|
||||||
|
int iterator = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < game->user_size; i++)
|
||||||
|
if(game->user[i])
|
||||||
|
{
|
||||||
|
message.users[iterator].id = game->user[i]->id;
|
||||||
|
message.users[iterator].is_ready = game->user[i]->is_ready;
|
||||||
|
strncpy(message.users[iterator].nickname, game->user[i]->nickname, 40);
|
||||||
|
iterator++;
|
||||||
|
}
|
||||||
|
|
||||||
|
message.count_connected = game->count_connected;
|
||||||
|
message.game_id = game->id;
|
||||||
|
message.active = game->active;
|
||||||
|
message.game_started = game->game_started;
|
||||||
|
strncpy(message.game_name, game->game_name, 40);
|
||||||
|
|
||||||
|
for(int i = 0; i < game->user_size; i++)
|
||||||
|
if(game->user[i])
|
||||||
|
{
|
||||||
|
message.is_creator = game->user[i]->is_creator;
|
||||||
|
message.is_ready = game->user[i]->is_ready;
|
||||||
|
message.user_id = game->user[i]->id;
|
||||||
|
packet = enet_packet_create(&message, sizeof(message), ENET_PACKET_FLAG_RELIABLE);
|
||||||
|
enet_peer_send(game->user[i]->peer, 0, packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void srv_handle_game(SERVER_DATA* data, SERVER_GAME* game)
|
||||||
|
{
|
||||||
|
ENetPacket *packet;
|
||||||
|
SERVER_MESSAGE_UPDATE message;
|
||||||
|
|
||||||
|
srv_clear_message(&message);
|
||||||
|
|
||||||
|
srv_update_explosions(data, game);
|
||||||
|
srv_move_ship(data, game, &message);
|
||||||
|
srv_fire_bullet(game);
|
||||||
|
srv_update_bullet(data, game, &message);
|
||||||
|
srv_start_comet(game);
|
||||||
|
srv_update_comet(data, game, &message);
|
||||||
|
srv_collide_bullet(game, &message);
|
||||||
|
srv_collide_comet(game, &message);
|
||||||
|
|
||||||
|
for(int i = 0; i < game->user_size; i++)
|
||||||
|
if(game->user[i])
|
||||||
|
{
|
||||||
|
packet = enet_packet_create(&message, sizeof(message), ENET_PACKET_FLAG_RELIABLE);
|
||||||
|
enet_peer_send(game->user[i]->peer, 0, packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void srv_clear_message(SERVER_MESSAGE_UPDATE* message)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 15; i++)
|
||||||
|
{
|
||||||
|
message->explosion[i].live = false;
|
||||||
|
message->explosion[i].x = 0;
|
||||||
|
message->explosion[i].y = 0;
|
||||||
|
}
|
||||||
|
for(int i = 0; i < 15; i++)
|
||||||
|
{
|
||||||
|
message->comet[i].live = false;
|
||||||
|
message->comet[i].x = 0;
|
||||||
|
message->comet[i].y = 0;
|
||||||
|
}
|
||||||
|
for(int i = 0; i < 15; i++)
|
||||||
|
{
|
||||||
|
message->bullet[i].ID = -1;
|
||||||
|
message->bullet[i].active = false;
|
||||||
|
message->bullet[i].live = false;
|
||||||
|
message->bullet[i].x = 0;
|
||||||
|
message->bullet[i].y = 0;
|
||||||
|
}
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
message->ship[i].ID = -1;
|
||||||
|
message->ship[i].active = false;
|
||||||
|
message->ship[i].dx = 0;
|
||||||
|
message->ship[i].dy = 0;
|
||||||
|
message->ship[i].lives = 0;
|
||||||
|
message->ship[i].score = 0;
|
||||||
|
message->ship[i].x = 0;
|
||||||
|
message->ship[i].y = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* UPDATE USERS
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void srv_client_update(SERVER_DATA* data)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < data->users.user_size; i++)
|
||||||
|
{
|
||||||
|
if(!data->users.user[i]->active) continue;
|
||||||
|
|
||||||
|
SERVER_USER* user = data->users.user[i];
|
||||||
|
|
||||||
|
switch(user->state)
|
||||||
|
{
|
||||||
|
case STATE_LIST:
|
||||||
|
srv_handle_userlist(data, user);
|
||||||
|
break;
|
||||||
|
case STATE_PARTY:
|
||||||
|
break;
|
||||||
|
case STATE_GAME:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void srv_handle_userlist(SERVER_DATA* data, SERVER_USER* user)
|
||||||
|
{
|
||||||
|
ENetPacket *packet;
|
||||||
|
SERVER_MESSAGE_LIST message;
|
||||||
|
|
||||||
|
message.count_game = 0;
|
||||||
|
|
||||||
|
int iterator = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
|
if(data->games.game[i]->active && !data->games.game[i]->game_started)
|
||||||
|
{
|
||||||
|
message.games[iterator].id = data->games.game[i]->id;
|
||||||
|
message.games[iterator].count_connected = data->games.game[i]->count_connected;
|
||||||
|
strncpy(message.games[iterator].game_name, data->games.game[i]->game_name, 40);
|
||||||
|
message.count_game++;
|
||||||
|
iterator++;
|
||||||
|
}
|
||||||
|
|
||||||
|
message.state = STATE_LIST;
|
||||||
|
packet = enet_packet_create(&message, sizeof(message), ENET_PACKET_FLAG_RELIABLE);
|
||||||
|
enet_peer_send(user->peer, 0, packet);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* File: update.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messanger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.15
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef server_update
|
||||||
|
#define server_update
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "calculation.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* UPDATE USERS
|
||||||
|
***********************************************************/
|
||||||
|
void srv_client_update(SERVER_DATA* data);
|
||||||
|
static void srv_handle_userlist(SERVER_DATA* data, SERVER_USER* user);
|
||||||
|
/************************************************************
|
||||||
|
* UPDATE GAMES
|
||||||
|
***********************************************************/
|
||||||
|
void srv_game_update(SERVER_DATA* data);
|
||||||
|
static void srv_handle_party(SERVER_DATA* data, SERVER_GAME* game);
|
||||||
|
static void srv_handle_game(SERVER_DATA* data, SERVER_GAME* game);
|
||||||
|
static void srv_clear_message(SERVER_MESSAGE_UPDATE* message);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
#include "users.h"
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
SERVER_USERS* srv_create_users(SERVER_USERS* users, int user_size)
|
||||||
|
{
|
||||||
|
if(!users)
|
||||||
|
{
|
||||||
|
users = (SERVER_USERS*)malloc(sizeof(SERVER_USERS));
|
||||||
|
show_message_error(users, "Failed to allocate space for SERVER_USERS");
|
||||||
|
}
|
||||||
|
|
||||||
|
users->user_size = user_size;
|
||||||
|
|
||||||
|
if(user_size)
|
||||||
|
{
|
||||||
|
users->user = (SERVER_USER**)malloc(sizeof(SERVER_USER*) * user_size);
|
||||||
|
show_message_error(users->user, "Failed to allocate space for SERVER_USER collection");
|
||||||
|
|
||||||
|
for(int i = 0; i < user_size; i++)
|
||||||
|
{
|
||||||
|
users->user[i] = (SERVER_USER*)malloc(sizeof(SERVER_USER));
|
||||||
|
show_message_error(users->user[i], "Failed to allocate space for SERVER_USER");
|
||||||
|
|
||||||
|
users->user[i]->id = -1;
|
||||||
|
users->user[i]->active = false;
|
||||||
|
users->user[i]->is_creator = false;
|
||||||
|
users->user[i]->is_ready = false;
|
||||||
|
users->user[i]->in_game = false;
|
||||||
|
users->user[i]->game_id = -1;
|
||||||
|
users->user[i]->state = STATE_NONE;
|
||||||
|
users->user[i]->nickname[0] = '\0';
|
||||||
|
users->user[i]->display_width = 0;
|
||||||
|
users->user[i]->display_height = 0;
|
||||||
|
users->user[i]->scale_factor = 0;
|
||||||
|
users->user[i]->command.dx = 0;
|
||||||
|
users->user[i]->command.dy = 0;
|
||||||
|
users->user[i]->command.fire = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
users->user = NULL;
|
||||||
|
|
||||||
|
return users;
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_free_users(SERVER_USERS* users)
|
||||||
|
{
|
||||||
|
srv_destroy_users(users);
|
||||||
|
free(users);
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_destroy_users(SERVER_USERS* users)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < users->user_size; i++)
|
||||||
|
free(users->user[i]);
|
||||||
|
|
||||||
|
free(users->user);
|
||||||
|
}
|
||||||
|
|
||||||
|
SERVER_USER* srv_get_free_user(SERVER_USERS* users)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < users->user_size; i++)
|
||||||
|
if(!users->user[i]->active)
|
||||||
|
{
|
||||||
|
users->user[i]->id = i;
|
||||||
|
users->user[i]->active = true;
|
||||||
|
return users->user[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_clear_user(SERVER_USER* user)
|
||||||
|
{
|
||||||
|
user->id = -1;
|
||||||
|
user->game_id = -1;
|
||||||
|
user->active = false;
|
||||||
|
user->is_ready = false;
|
||||||
|
user->in_game = false;
|
||||||
|
user->state = STATE_NONE;
|
||||||
|
user->nickname[0] = '\0';
|
||||||
|
user->display_width = 0;
|
||||||
|
user->display_height = 0;
|
||||||
|
user->command.dx = 0;
|
||||||
|
user->command.dy = 0;
|
||||||
|
user->command.fire = false;
|
||||||
|
user->scale_factor = 0;
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* File: users.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messanger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.14
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef server_users
|
||||||
|
#define server_users
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <enet/enet.h>
|
||||||
|
|
||||||
|
typedef enum srv_state
|
||||||
|
{
|
||||||
|
STATE_NONE,
|
||||||
|
STATE_LIST,
|
||||||
|
STATE_PARTY,
|
||||||
|
STATE_GAME,
|
||||||
|
STATE_DISCONNECT
|
||||||
|
} SERVER_STATE;
|
||||||
|
|
||||||
|
typedef struct srv_game_command
|
||||||
|
{
|
||||||
|
int dx;
|
||||||
|
int dy;
|
||||||
|
bool fire;
|
||||||
|
} SERVER_GAME_COMMAND;
|
||||||
|
|
||||||
|
typedef struct srv_user
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
int game_id;
|
||||||
|
char nickname[40];
|
||||||
|
int display_width;
|
||||||
|
int display_height;
|
||||||
|
float scale_factor;
|
||||||
|
SERVER_STATE state;
|
||||||
|
bool in_game;
|
||||||
|
bool is_creator; // game creator
|
||||||
|
bool is_ready;
|
||||||
|
bool active;
|
||||||
|
ENetPeer* peer;
|
||||||
|
SERVER_GAME_COMMAND command;
|
||||||
|
} SERVER_USER;
|
||||||
|
|
||||||
|
typedef struct srv_users
|
||||||
|
{
|
||||||
|
SERVER_USER** user;
|
||||||
|
int user_size;
|
||||||
|
} SERVER_USERS;
|
||||||
|
|
||||||
|
SERVER_USERS* srv_create_users(SERVER_USERS* users, int user_size);
|
||||||
|
void srv_free_users(SERVER_USERS* users);
|
||||||
|
void srv_destroy_users(SERVER_USERS* users);
|
||||||
|
|
||||||
|
void srv_clear_user(SERVER_USER* user);
|
||||||
|
SERVER_USER* srv_get_free_user(SERVER_USERS* users);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue