summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAldrik Ramaekers <aldrik@amftech.nl>2022-12-14 20:43:26 +0100
committerAldrik Ramaekers <aldrik@amftech.nl>2022-12-14 20:43:26 +0100
commit23d2cc231e5b4c015a8471d3035dc07802de23d5 (patch)
tree4b307a81e5fc566a5d1af9a0659b19534cff11b6 /src
parentee4906ef5fc89f3f10cd6aaf95845a0ae9b2f47e (diff)
leaderboard, network syncing
Diffstat (limited to 'src')
-rw-r--r--src/game.c71
-rw-r--r--src/overlay.c40
-rw-r--r--src/players.c12
3 files changed, 99 insertions, 24 deletions
diff --git a/src/game.c b/src/game.c
index 1bc9f0d..aa5ae3a 100644
--- a/src/game.c
+++ b/src/game.c
@@ -3,12 +3,20 @@
u32 current_id = 0;
+static void server_on_client_disconnect(network_client c) {
+ for (int i = 0; i < max_players; i++) {
+ player p = players[i];
+ if (p.client.ConnectSocket == c.ConnectSocket) players[i].active = false;
+ }
+}
+
void start_server(char* port) {
messages_received_on_server = array_create(sizeof(protocol_generic_message*));
array_reserve(&messages_received_on_server, 100);
global_state.server = networking_create_server();
global_state.server->on_message = server_on_message_received;
+ global_state.server->on_client_disconnect = server_on_client_disconnect;
}
void connect_to_server(char* ip, char* port) {
@@ -19,11 +27,19 @@ void connect_to_server(char* ip, char* port) {
global_state.client = network_connect_to_server(ip, port);
global_state.client->on_message = client_on_message_received;
- if (global_state.client->is_connected) {
- global_state.network_state = WAITING_FOR_ID;
+ if (global_state.server) {
+ my_id = current_id++;
+ spawn_player(my_id, (network_client){0, false, 0, "Host"});
+ global_state.network_state = CONNECTED;
+ printf("Server id: %d\n", my_id);
+ }
+ else {
+ if (global_state.client->is_connected) {
+ global_state.network_state = WAITING_FOR_ID;
- network_message message = create_protocol_get_id_up();
- network_client_send(global_state.client, message);
+ network_message message = create_protocol_get_id_up();
+ network_client_send(global_state.client, message);
+ }
}
}
@@ -57,9 +73,10 @@ void destroy_game() {
static void broadcast_to_clients(network_message message) {
if (!global_state.server || !global_state.server->is_open) return;
- for (int i = 0; i < global_state.server->clients.length; i++) {
- network_client* client = array_at(&global_state.server->clients, i);
- network_client_send(client, message);
+ for (int i = 0; i < max_players; i++) {
+ player p = players[i];
+ if (!p.client.is_connected) continue;
+ if (p.active) network_client_send(&p.client, message);
}
}
@@ -87,7 +104,8 @@ void update_server(platform_window* window) {
{
case MESSAGE_GET_ID_UPSTREAM: {
network_client_send(&msg->client, create_protocol_get_id_down(current_id));
- spawn_player(current_id);
+ spawn_player(current_id, msg->client);
+
current_id++;
log_info("Player connected to server");
} break;
@@ -127,6 +145,22 @@ void update_server(platform_window* window) {
update_timer += update_delta;
}
+static void apply_user_list(protocol_user_list* msg_players) {
+ player* p = get_player_by_id(my_id);
+ player copy;
+ if (p) copy = *p;
+ memcpy(players, msg_players->players, sizeof(players));
+
+ // These properties are simulated locally so dont overwrite.
+ if (p) {
+ p->playerx = copy.playerx;
+ p->playery = copy.playery;
+ p->gunx = copy.gunx;
+ p->guny = copy.guny;
+ p->gun_height = copy.gun_height;
+ }
+}
+
void update_client(platform_window* window) {
for (int i = 0; i < messages_received_on_client.length; i++) {
protocol_generic_client_message* msg = *(protocol_generic_client_message**)array_at(&messages_received_on_client, i);
@@ -134,7 +168,6 @@ void update_client(platform_window* window) {
switch (msg->type)
{
case MESSAGE_GET_ID_DOWNSTREAM: {
- if (global_state.network_state == CONNECTED) break;
protocol_get_id_downstream* msg_id = (protocol_get_id_downstream*)msg;
my_id = msg_id->id;
global_state.network_state = CONNECTED;
@@ -143,20 +176,9 @@ void update_client(platform_window* window) {
} break;
case MESSAGE_USER_LIST: {
+ if (global_state.server) break; // players are simulated on server so dont overwrite data.
protocol_user_list* msg_players = (protocol_user_list*)msg;
- player* p = get_player_by_id(my_id);
- player copy;
- if (p) copy = *p;
- memcpy(players, msg_players->players, sizeof(players));
-
- // These properties are simulated locally so dont overwrite.
- if (p) {
- p->playerx = copy.playerx;
- p->playery = copy.playery;
- p->gunx = copy.gunx;
- p->guny = copy.guny;
- p->gun_height = copy.gun_height;
- }
+ apply_user_list(msg_players);
} break;
case MESSAGE_ZOMBIE_LIST: {
@@ -182,10 +204,13 @@ void update_client(platform_window* window) {
}
void update_game(platform_window* window) {
- update_client(window);
if (global_state.server) {
update_server(window);
}
+ else {
+ update_client(window);
+ }
+
if (global_state.network_state == CONNECTED) {
if (!global_state.server) {
diff --git a/src/overlay.c b/src/overlay.c
index 5a81726..c79ef2e 100644
--- a/src/overlay.c
+++ b/src/overlay.c
@@ -1,5 +1,7 @@
#include "../include/overlay.h"
#include "../include/guns.h"
+#include "../include/players.h"
+#include "../include/asset_defs.h"
#define EDGE_PADDING 10
@@ -21,7 +23,45 @@ static void draw_gun_info(platform_window* window) {
renderer->render_text(fnt_20, (int)_global_camera.x + x, (int)_global_camera.y + y, ammo_txt, rgb(255,255,255));
}
+static void draw_leaderboard_entry(int x, int y, int w, int h, char* name, char* kills, char* deaths, char* ping) {
+ int width_for_name = w / 2;
+ int width_per_entry = (w-width_for_name)/3;
+ renderer->render_text(fnt_20, x, y, name, rgb(0,0,0));
+ renderer->render_text(fnt_20, x+width_for_name+width_per_entry*0, y, kills, rgb(0,0,0));
+ renderer->render_text(fnt_20, x+width_for_name+width_per_entry*1, y, deaths, rgb(0,0,0));
+ renderer->render_text(fnt_20, x+width_for_name+width_per_entry*2, y, ping, rgb(0,0,0));
+}
+
+static void draw_leaderboard(platform_window* window) {
+ if (keyboard_is_key_down(KEY_TAB)) {
+ int minimum_width = 300;
+ int maximum_width = 900;
+ int actual_width = window->width * 0.6f;
+ if (actual_width > maximum_width) actual_width = maximum_width;
+ if (actual_width < minimum_width) actual_width = minimum_width;
+
+ int height_per_row = 20;
+ int height_total = height_per_row * (get_player_count() + 1);
+
+ int x = (int)_global_camera.x + (window->width - actual_width) / 2;
+ int y = (int)_global_camera.y + (window->height - height_total) / 4;
+
+ renderer->render_rectangle(x, y, actual_width, height_total, rgba(255,255,255, 200));
+
+ draw_leaderboard_entry(x, y, actual_width, height_per_row, "Player", "Kills", "Deaths", "Ping");
+ for (int i = 0; i < max_players; i++) {
+ if (!players[i].active) continue;
+
+ char kills[30]; snprintf(kills, 30, "%d", 0);
+ char deaths[30]; snprintf(deaths, 30, "%d", 0);
+ char ping[30]; snprintf(ping, 30, "%d", 0);
+ draw_leaderboard_entry(x, y + ((i+1)*height_per_row), actual_width, height_per_row, players[i].client.ip, kills, deaths, ping);
+ }
+ }
+}
+
void draw_overlay(platform_window* window) {
OVERLAY_RENDER_DEPTH();
draw_gun_info(window);
+ draw_leaderboard(window);
} \ No newline at end of file
diff --git a/src/players.c b/src/players.c
index 1b86944..c4b7bb0 100644
--- a/src/players.c
+++ b/src/players.c
@@ -17,7 +17,16 @@ float get_player_size(platform_window* window) {
int player_size = get_tile_width(window) * get_player_size_in_tile();
}
-void spawn_player(int id) {
+int get_player_count() {
+ int count = 0;
+ for (int i = 0; i < max_players; i++) {
+ if (!players[i].active) continue;
+ count++;
+ }
+ return count;
+}
+
+void spawn_player(int id, network_client client) {
for (int i = 0; i < max_players; i++) {
if (players[i].active) continue;
players[i].active = true;
@@ -29,6 +38,7 @@ void spawn_player(int id) {
players[i].gun_height = 0.0f;
players[i].id = id;
players[i].guntype = GUN_MP5;
+ players[i].client = client;
gun g = get_gun_by_type(players[i].guntype);
players[i].total_ammo = g.max_ammunition;