there is now a player character and the world renders using a cammera
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1,4 +1,10 @@
|
||||
build
|
||||
.cache
|
||||
bin
|
||||
docker_root
|
||||
rsa_id
|
||||
id_rsa
|
||||
rsa_id.pub
|
||||
id_rsa.pub
|
||||
export.sh
|
||||
|
||||
|
||||
@@ -9,5 +9,45 @@ set(CMAKE_COLOR_MAKEFILE ON)
|
||||
set(CMAKE_COLOR_DIAGNOSTICS ON)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
|
||||
add_subdirectory(external)
|
||||
add_subdirectory(source)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E echo "Building for docker")
|
||||
if(DOCKER)
|
||||
target_compile_definitions(sshGameServer PUBLIC
|
||||
DOCKER
|
||||
)
|
||||
find_program(podman_exe podman)
|
||||
if(NOT podman_exe)
|
||||
message(FATIAL_ERROR "Cant find podman")
|
||||
endif()
|
||||
add_custom_target( # This will build the docker container
|
||||
docker
|
||||
COMMAND bash ${CMAKE_SOURCE_DIR}/dockerCompile.sh
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
add_custom_target( # This will deploy that docker image on the server
|
||||
deploy
|
||||
COMMAND bash ${CMAKE_SOURCE_DIR}/dockerCompile.sh --exp --dep
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
USES_TERMINAL
|
||||
)
|
||||
add_custom_target( # This will export the docker image to the server
|
||||
export
|
||||
COMMAND bash ${CMAKE_SOURCE_DIR}/dockerCompile.sh --exp
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
USES_TERMINAL
|
||||
)
|
||||
add_custom_target( # This will build the root image
|
||||
root
|
||||
COMMAND bash ${CMAKE_SOURCE_DIR}/dockerCompile.sh --env
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
USES_TERMINAL
|
||||
)
|
||||
add_custom_target(
|
||||
run
|
||||
COMMAND bash ${CMAKE_SOURCE_DIR}/dockerCompile.sh --run
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
USES_TERMINAL
|
||||
)
|
||||
endif()
|
||||
|
||||
15
Dockerfile
Normal file
15
Dockerfile
Normal file
@@ -0,0 +1,15 @@
|
||||
FROM localhost/skevety-root:latest
|
||||
|
||||
|
||||
COPY ./external/ ./external
|
||||
COPY ./source/ ./source/
|
||||
COPY ./CMakeLists.txt .
|
||||
|
||||
RUN mkdir build
|
||||
RUN cmake -DDOCKER=ON -B build .
|
||||
RUN cmake --build build -j20
|
||||
|
||||
|
||||
WORKDIR /app/build/source
|
||||
|
||||
CMD ["./sshGameServer"]
|
||||
23
dockerCompile.sh
Executable file
23
dockerCompile.sh
Executable file
@@ -0,0 +1,23 @@
|
||||
if [[ $1 == "--env" ]]; then
|
||||
|
||||
mkdir -p ./docker_root
|
||||
podman save -o ./docker_root/backup-image-skevety-server skevety-root:latest
|
||||
podman image rm -f skevety-root
|
||||
podman build ./docker_root/ --no-cache -t skevety-root
|
||||
fi
|
||||
|
||||
podman image rm -f skevety-server
|
||||
podman build ./ --no-cache -t skevety-server
|
||||
|
||||
if [[ $1 == "--exp" ]]; then
|
||||
mkdir -p ./docker_exp
|
||||
rm ./docker_exp/*
|
||||
podman save -o ./docker_exp/image-skevety-server skevety-server:latest
|
||||
source ./export.sh skevety localhost/skevety-server image-skevety-server $2
|
||||
|
||||
fi
|
||||
|
||||
|
||||
if [[ $1 == "--run" ]]; then
|
||||
podman run -d -p 2222:2222 --replace --name skevety skevety-server
|
||||
fi
|
||||
BIN
docker_exp/image-skevety-server
Normal file
BIN
docker_exp/image-skevety-server
Normal file
Binary file not shown.
2
docker_exp/import.sh
Executable file
2
docker_exp/import.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
sudo docker rmi -f localhost/skevety-server
|
||||
sudo docker load -i image-skevety-server
|
||||
3
docker_exp/run.sh
Executable file
3
docker_exp/run.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
sudo docker stop skevety
|
||||
sudo docker rm skevety
|
||||
sudo docker run -d -p 2222:2222 --name skevety localhost/skevety-server
|
||||
2
external/tart
vendored
2
external/tart
vendored
Submodule external/tart updated: 704f624f25...5e8a6685dc
@@ -6,16 +6,16 @@ set(SOURCE_FILES
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
|
||||
|
||||
find_package(mongoc 2.1.2 REQUIRED)
|
||||
#find_package(mongoc 2.1.2 REQUIRED)
|
||||
|
||||
target_link_libraries(
|
||||
${PROJECT_NAME}
|
||||
ssh
|
||||
TartLib
|
||||
mongoc::static
|
||||
# mongoc::static
|
||||
)
|
||||
|
||||
add_subdirectory(game_source)
|
||||
add_subdirectory(client_source)
|
||||
add_subdirectory(Userdb)
|
||||
#add_subdirectory(Userdb)
|
||||
add_subdirectory(server_source)
|
||||
|
||||
@@ -1,22 +1,139 @@
|
||||
#include "client.h"
|
||||
#include <bits/time.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <tart.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include "../game_source/entities/Player.h"
|
||||
#include <sys/random.h>
|
||||
#include <stdio.h>
|
||||
#include <locale.h>
|
||||
#include <time.h>
|
||||
|
||||
#define jump tart_move_cursor
|
||||
#define FPS 60
|
||||
#define FRAME_TIME (1000.0 / FPS)
|
||||
|
||||
int e = 1;
|
||||
|
||||
void aOnExit() {
|
||||
//printf("shutting Down");
|
||||
e = 0;
|
||||
}
|
||||
|
||||
|
||||
void draw_button(tart_window *w,const t_char* label, tart_vec2 position) {
|
||||
|
||||
jump(w, (tart_vec2){position.x,position.y + 0});
|
||||
tart_printf(w, 1, T"┏━━━");
|
||||
int size = t_strlen(label);
|
||||
for(int i = 0; i < size; i++ ) {
|
||||
tart_printf(w, 1, T"━");
|
||||
}
|
||||
tart_printf(w, 1, T"━━━┓");
|
||||
jump(w, (tart_vec2){position.x,position.y + 1});
|
||||
tart_printf(w, 1, T"┃ %ls ┃", label);
|
||||
jump(w, (tart_vec2){position.x,position.y + 2});
|
||||
tart_printf(w, 1, T"┗━━━");
|
||||
for(int i = 0; i < size; i++ ) {
|
||||
tart_printf(w, 1, T"━");
|
||||
}
|
||||
tart_printf(w, 1, T"━━━┛");
|
||||
}
|
||||
int limit_fps(int fps, struct timespec* last_time) {
|
||||
struct timespec current_time;
|
||||
double frame_time = 1.0 / fps;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, ¤t_time);
|
||||
|
||||
double elapsed = (current_time.tv_sec - last_time->tv_sec) +
|
||||
(current_time.tv_nsec - last_time->tv_nsec) / 1e9;
|
||||
|
||||
if (elapsed < frame_time) {
|
||||
return 0;
|
||||
}
|
||||
clock_gettime(CLOCK_MONOTONIC, last_time);
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
int client_auth(void* userdata);
|
||||
|
||||
int client_init(void* cli) {
|
||||
setlocale(LC_CTYPE, "en_US.UTF-8");
|
||||
client* c = (client*)cli;
|
||||
int x = 0;
|
||||
c->last_frame_time = clock();
|
||||
tart_create_window(&c->w, (tart_vec2){150,50}, "testing", c->channel);
|
||||
tart_init(&c->w);
|
||||
//jump(&c->w, (tart_vec2){1,1});
|
||||
//jump(&c->w, (tart_vec2){1,2});
|
||||
tart_disable_cusor(&c->w);
|
||||
|
||||
c->world.size_x = 600;
|
||||
c->world.size_y = 600;
|
||||
|
||||
CreateWorld(&c->world, clock());
|
||||
InitWorld(&c->world);
|
||||
entity* cen = CreatePlayer("testing", c, &c->world);
|
||||
cen->position.x = 3;
|
||||
cen->position.y = 3;
|
||||
AddEntity(&c->world, cen);
|
||||
GenerateWorld(&c->world);
|
||||
CammeraInit(&c->cam, 150,50,0,0,&c->world, &c->w);
|
||||
clock_gettime(CLOCK_MONOTONIC,&c->last_time);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int client_update(ssh_terminal_data* td, void* cli) {
|
||||
//signal(SIGINT, aOnExit);
|
||||
client* c = (client*)cli;
|
||||
|
||||
strcpy(td->outputBuffer, "testing 1212\n\r");
|
||||
tart_window w = c->w;
|
||||
//tart_init(&w);
|
||||
if(limit_fps(FPS, &c->last_time) == 1) {
|
||||
|
||||
int newSize = tart_draw_to_buffer(&w);
|
||||
CammeraRender(&c->cam);
|
||||
|
||||
|
||||
|
||||
tart_jump(&w, (tart_vec2){w.windowSize.x, w.windowSize.y-1});
|
||||
tart_insert_cell(&w, 5, 'a');
|
||||
|
||||
}
|
||||
|
||||
UpdateWorld(&c->world);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int client_stop(void* cli) {
|
||||
client* c = (client*)cli;
|
||||
printf("Clossing connection\n");
|
||||
tart_enable_cusor(&c->w);
|
||||
|
||||
tart_close(&c->w);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int client_resize(int x, int y, void *userdata) {
|
||||
client* c = (client*)userdata;
|
||||
printf("client address %d\n", userdata);
|
||||
printf("cammeraSize %d,%d\n", x, y);
|
||||
int posx = 000000000000;
|
||||
int posy = 000000000000;
|
||||
|
||||
CammeraInit(&c->cam, x, y, posx, posy, &c->world, &c->w);
|
||||
tart_window_resize(&c->w, (tart_vec2){x-1,y});
|
||||
|
||||
|
||||
//CammeraInit(&c->cam, c->cam.size_x, c->cam.size_y, c->cam.pos_x, c->cam.pos_y, &c->world, &c->w);
|
||||
//c->cam.tw = &c->w;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,40 @@
|
||||
#ifndef CLIENT_H
|
||||
#define CLIENT_H
|
||||
#include <libssh/callbacks.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <locale.h>
|
||||
#include <time.h>
|
||||
#include "../ssh_server_client.h"
|
||||
#include <tart.h>
|
||||
#include "../game_source/cammera.h"
|
||||
#include "../game_source/world.h"
|
||||
|
||||
typedef struct {} client;
|
||||
typedef struct {
|
||||
tart_window w;
|
||||
int resize;
|
||||
int newWidth;
|
||||
int newHeight;
|
||||
float xBounce;
|
||||
float xFlip;
|
||||
float yBounce;
|
||||
float yFlip;
|
||||
clock_t last_frame_time;
|
||||
double frame_time_ms;
|
||||
int color0;
|
||||
int color1;
|
||||
int color2;
|
||||
ssh_channel channel;
|
||||
cammera cam;
|
||||
world world;
|
||||
ssh_terminal_data term;
|
||||
struct ssh_server_callbacks_struct server_cb;
|
||||
struct ssh_channel_callbacks_struct channel_cb;
|
||||
struct timespec last_time;
|
||||
|
||||
|
||||
} client;
|
||||
|
||||
int client_auth(void* userdata);
|
||||
|
||||
@@ -12,5 +44,7 @@ int client_update(ssh_terminal_data* td, void*);
|
||||
|
||||
int client_stop(void*);
|
||||
|
||||
int client_resize(int x, int y, void* userdata);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
cammera.c
|
||||
entity.c
|
||||
entity_handler.c
|
||||
cells.c
|
||||
world.c
|
||||
player/player_packet.c
|
||||
|
||||
)
|
||||
|
||||
add_subdirectory(entities)
|
||||
|
||||
82
source/game_source/cammera.c
Normal file
82
source/game_source/cammera.c
Normal file
@@ -0,0 +1,82 @@
|
||||
#include "cammera.h"
|
||||
#include "entity.h"
|
||||
#include <tart.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#define jump tart_move_cursor
|
||||
|
||||
int CammeraInit(cammera* c, int sx, int sy, int px, int py, world* w, tart_window* tw) {
|
||||
c->w = w;
|
||||
c->tw = tw;
|
||||
|
||||
c->pos_x = px;
|
||||
c->pos_y = py;
|
||||
|
||||
c->size_x = sx;
|
||||
c->size_y = sy;
|
||||
|
||||
c->tileCount = c->size_x * c->size_y;
|
||||
//c->frame = (tile*)malloc(c->tileCount * sizeof(tile));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CammeraResize(cammera* c, int sx, int sy) {
|
||||
tart_window_resize(c->tw, (tart_vec2){sx,sy});
|
||||
c->size_x = sx ;
|
||||
c->size_y = sy;
|
||||
|
||||
//free(c->frame);
|
||||
|
||||
c->tileCount = c->size_x * c->size_y;
|
||||
//c->frame = (tile*)malloc(c->tileCount * sizeof(tile));
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CammeraRender(cammera*c) {
|
||||
jump(c->tw, (tart_vec2){0,0});
|
||||
for(int i = 0; i < c->size_y; i++) {
|
||||
for(int j = 0; j < c->size_x - 1; j++) {
|
||||
|
||||
if(c->pos_y+i < c->w->size_y-1 && c->pos_y+i >= 0 && c->pos_x+j < c->w->size_x-1 && c->pos_x+j >= 0){
|
||||
c->tw->palette[2].background.r = c->w->wells[at(c->pos_x+j,c->pos_y+i,c->w)].cell->tile.background.r;
|
||||
c->tw->palette[2].background.g = c->w->wells[at(c->pos_x+j,c->pos_y+i,c->w)].cell->tile.background.g;
|
||||
c->tw->palette[2].background.b = c->w->wells[at(c->pos_x+j,c->pos_y+i,c->w)].cell->tile.background.b;
|
||||
c->tw->palette[2].forground.r = c->w->wells[at(c->pos_x+j,c->pos_y+i,c->w)].cell->tile.forground.r;
|
||||
c->tw->palette[2].forground.g = c->w->wells[at(c->pos_x+j,c->pos_y+i,c->w)].cell->tile.forground.g;
|
||||
c->tw->palette[2].forground.b = c->w->wells[at(c->pos_x+j,c->pos_y+i,c->w)].cell->tile.forground.b;
|
||||
|
||||
tart_jump(c->tw, (tart_vec2){j,i});
|
||||
|
||||
for(int k = 0; k < 1; k++) {
|
||||
if(c->w->wells[at((c->pos_x+j) ,(c->pos_y+i),c->w)].entityIds[0] != 0000) {
|
||||
if(c->w->wells[at(c->pos_x+j,c->pos_y+i,c->w)].entityIds[k]->tile.background.r != 0 &&
|
||||
c->w->wells[at(c->pos_x+j,c->pos_y+i,c->w)].entityIds[k]->tile.background.r != 0 &&
|
||||
c->w->wells[at(c->pos_x+j,c->pos_y+i,c->w)].entityIds[k]->tile.background.r != 0) {
|
||||
|
||||
c->tw->palette[2].background.r = c->w->wells[at(c->pos_x+j,c->pos_y+i,c->w)].entityIds[k]->tile.background.r;
|
||||
c->tw->palette[2].background.g = c->w->wells[at(c->pos_x+j,c->pos_y+i,c->w)].entityIds[k]->tile.background.g;
|
||||
c->tw->palette[2].background.b = c->w->wells[at(c->pos_x+j,c->pos_y+i,c->w)].entityIds[k]->tile.background.b;
|
||||
}
|
||||
c->tw->palette[2].forground.r = c->w->wells[at(c->pos_x+j,c->pos_y+i,c->w)].entityIds[k]->tile.forground.r;
|
||||
c->tw->palette[2].forground.g = c->w->wells[at(c->pos_x+j,c->pos_y+i,c->w)].entityIds[k]->tile.forground.g;
|
||||
c->tw->palette[2].forground.b = c->w->wells[at(c->pos_x+j,c->pos_y+i,c->w)].entityIds[k]->tile.forground.b;
|
||||
tart_insert_cell(c->tw, 2, c->w->wells[at((c->pos_x+j) ,(c->pos_y+i),c->w)]
|
||||
.entityIds[k]->tile.simble);
|
||||
printf("found entity %c\n", c->w->wells[at((c->pos_x+j) ,(c->pos_y+i),c->w)]
|
||||
.entityIds[k]->tile.simble);
|
||||
}
|
||||
}
|
||||
tart_insert_cell(c->tw, 2, c->w->wells[at((c->pos_x+j) ,(c->pos_y+i),c->w)]
|
||||
.cell->tile.simble);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CammeraFree(cammera *c) {
|
||||
//free(c->frame);
|
||||
}
|
||||
27
source/game_source/cammera.h
Normal file
27
source/game_source/cammera.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef CAMMERA_H
|
||||
#define CAMMERA_H
|
||||
#include "tile.h"
|
||||
#include "world.h"
|
||||
#include <tart.h>
|
||||
|
||||
typedef struct {
|
||||
int pos_x;
|
||||
int pos_y;
|
||||
int size_x;
|
||||
int size_y;
|
||||
int tileCount;
|
||||
char x;
|
||||
tile* frame;
|
||||
world* w;
|
||||
tart_window* tw;
|
||||
} cammera;
|
||||
|
||||
|
||||
int CammeraInit(cammera* c, int sx, int sy, int px, int py, world* w, tart_window* tw);
|
||||
|
||||
int CammeraRender(cammera*c);
|
||||
|
||||
void CammeraFree(cammera* c);
|
||||
|
||||
|
||||
#endif // !CAMMERA_H
|
||||
131
source/game_source/cells.c
Normal file
131
source/game_source/cells.c
Normal file
@@ -0,0 +1,131 @@
|
||||
#include "cells.h"
|
||||
#include <string.h>
|
||||
|
||||
static cell c_wall = {
|
||||
.id = 1,
|
||||
.flags = CELL_FLAG_BLOCKING,
|
||||
.tile = {
|
||||
.background = {0x00,0x00,0x00},
|
||||
.forground = {0xee,0xee,0xee},
|
||||
.simble = L'#'
|
||||
},
|
||||
.func = NULL,
|
||||
};
|
||||
static cell c_long_grass = {
|
||||
.id = 7,
|
||||
.flags = CELL_FLAG_FLAMABLE,
|
||||
.tile = {
|
||||
.background = {0x0f, 0x33, 0x0f},
|
||||
.forground = {0x40, 0xff, 0x40},
|
||||
.simble = '"',
|
||||
},
|
||||
.func = NULL,
|
||||
};
|
||||
static cell c_short_grass = {
|
||||
.id = 8,
|
||||
.flags = CELL_FLAG_FLAMABLE,
|
||||
.tile = {
|
||||
.background = {0x0f, 0x33, 0x0f},
|
||||
.forground = {0x40, 0xff, 0x40},
|
||||
.simble = '\'',
|
||||
},
|
||||
.func = NULL,
|
||||
};
|
||||
static cell c_grass = {
|
||||
.id = 9,
|
||||
.flags = CELL_FLAG_FLAMABLE,
|
||||
.tile = {
|
||||
.background = {0x0f, 0x33, 0x0f},
|
||||
.forground = {0x40, 0xff, 0x40},
|
||||
.simble = ' ',
|
||||
},
|
||||
.func = NULL,
|
||||
};
|
||||
static cell c_floar = {
|
||||
.id = 2,
|
||||
.flags = CELL_FLAG_FLORE,
|
||||
.tile = {
|
||||
.background = {0x11,0x11,0x11},
|
||||
.forground = {0xee,0xee,0xee},
|
||||
.simble = '.'
|
||||
},
|
||||
.func = NULL,
|
||||
};
|
||||
static cell c_hard_wall = {
|
||||
.id = 3,
|
||||
.flags = CELL_FLAG_DAMAGEABLE | CELL_FLAG_BLOCKING,
|
||||
.tile = {
|
||||
.background = {0xcc,0xcc,0xcc},
|
||||
.forground = {0xee,0xee,0xee},
|
||||
.simble = '#'
|
||||
},
|
||||
.func = NULL,
|
||||
};
|
||||
static cell c_soft_wall = {
|
||||
.id = 4,
|
||||
.flags = CELL_FLAG_BLOCKING | CELL_FLAG_DAMAGEABLE,
|
||||
.tile = {
|
||||
.background = {0xcc,0xcc,0xcc},
|
||||
.forground = {0xee,0xee,0xee},
|
||||
.simble = L'#'
|
||||
},
|
||||
.func = NULL,
|
||||
};
|
||||
static cell c_water = {
|
||||
.id = 5,
|
||||
.flags = CELL_FLAG_FLORE | CELL_FLAG_SLIPPERY | CELL_FLAG_UNEVEN,
|
||||
.tile = {
|
||||
.background = {0,0,0},
|
||||
.forground = {0xff,0xff,0xff},
|
||||
.simble = '~',
|
||||
},
|
||||
.func = NULL
|
||||
};
|
||||
|
||||
void f_growth(int x, int y, void* data) {
|
||||
// every tick spread to the next availbe flore / grass.
|
||||
}
|
||||
|
||||
static cell c_growth = {
|
||||
.id = 6,
|
||||
.tile = {
|
||||
.background = {0x34,0x0c,0x40},
|
||||
.forground = {0xb0,0x25,0xda},
|
||||
.simble = '*',
|
||||
},
|
||||
.func = f_growth
|
||||
};
|
||||
|
||||
int UpdateCells(cell* cell, int x, int y, void* data) {
|
||||
if(cell->func != NULL) {
|
||||
cell->func(x,y,0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
cell* SetCell(cell_id id) {
|
||||
|
||||
switch (id) {
|
||||
case 1:
|
||||
return &c_wall;
|
||||
case 2:
|
||||
return &c_floar;
|
||||
case 3:
|
||||
return &c_hard_wall;
|
||||
case 4:
|
||||
return &c_soft_wall;
|
||||
case 5:
|
||||
return &c_water;
|
||||
case 6:
|
||||
return &c_growth;
|
||||
case 7:
|
||||
return &c_long_grass;
|
||||
case 8:
|
||||
return &c_short_grass;
|
||||
case 9:
|
||||
return &c_grass;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
50
source/game_source/cells.h
Normal file
50
source/game_source/cells.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef CELLS_H
|
||||
#define CELLS_H
|
||||
|
||||
#define CELL_FLAG_BLOCKING 0b00000000000000000000000000000001
|
||||
#define CELL_FLAG_PARTIAL_COVER 0b00000000000000000000000000000010
|
||||
#define CELL_FLAG_DAMAGEABLE 0b00000000000000000000000000000100
|
||||
#define CELL_FLAG_SLIPPERY 0b00000000000000000000000000001000
|
||||
#define CELL_FLAG_UNEVEN 0b00000000000000000000000000010000
|
||||
#define CELL_FLAG_FLORE 0b00000000000000000000000000100000
|
||||
#define CELL_FLAG_STARE 0b00000000000000000000000001000000
|
||||
#define CELL_FLAG_MOVEABLE 0b00000000000000000000000010000000
|
||||
#define CELL_FLAG_EXPLODING 0b00000000000000000000000100000000
|
||||
#define CELL_FLAG_FLAMABLE 0b00000000000000000000001000000000
|
||||
#define CELL_FLAG_RADIO_ACTIVE 0b00000000000000000000010000000000
|
||||
//#define CELL_FLAG_ 0b00000000000000000000100000000000
|
||||
//#define CELL_FLAG_ 0b00000000000000000001000000000000
|
||||
//#define CELL_FLAG_ 0b00000000000000000010000000000000
|
||||
//#define CELL_FLAG_ 0b00000000000000000100000000000000
|
||||
//#define CELL_FLAG_ 0b00000000000000001000000000000000
|
||||
//#define CELL_FLAG_ 0b00000000000000010000000000000000
|
||||
//#define CELL_FLAG_ 0b00000000000000100000000000000000
|
||||
//#define CELL_FLAG_ 0b00000000000001000000000000000000
|
||||
//#define CELL_FLAG_ 0b00000000000010000000000000000000
|
||||
//#define CELL_FLAG_ 0b00000000000100000000000000000000
|
||||
//#define CELL_FLAG_ 0b00000000001000000000000000000000
|
||||
//#define CELL_FLAG_ 0b00000000010000000000000000000000
|
||||
//#define CELL_FLAG_ 0b00000000100000000000000000000000
|
||||
//#define CELL_FLAG_ 0b00000001000000000000000000000000
|
||||
//#define CELL_FLAG_ 0b00000010000000000000000000000000
|
||||
//#define CELL_FLAG_ 0b00000100000000000000000000000000
|
||||
//#define CELL_FLAG_ 0b00001000000000000000000000000000
|
||||
//#define CELL_FLAG_ 0b00010000000000000000000000000000
|
||||
//#define CELL_FLAG_ 0b00100000000000000000000000000000
|
||||
//#define CELL_FLAG_ 0b01000000000000000000000000000000
|
||||
//#define CELL_FLAG_ 0b10000000000000000000000000000000
|
||||
|
||||
|
||||
#include "tile.h"
|
||||
|
||||
typedef short cell_id;
|
||||
typedef struct {
|
||||
cell_id id;
|
||||
unsigned int flags;
|
||||
tile tile;
|
||||
void(*func)(int x, int y, void* data);
|
||||
} cell;
|
||||
|
||||
int UpdateCells(cell* cell, int x, int y, void* data);
|
||||
cell* SetCell(cell_id id);
|
||||
#endif // !CELLS_H
|
||||
5
source/game_source/entities/CMakeLists.txt
Normal file
5
source/game_source/entities/CMakeLists.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
Player.c
|
||||
Centery.c
|
||||
Gun.c
|
||||
)
|
||||
@@ -1,15 +1,129 @@
|
||||
#include "Centery.h"
|
||||
#include "entity_utils.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int CreateCentery(int tear, int classification) {
|
||||
int CenteryInit(void* self) {
|
||||
entity* ent = self;
|
||||
centery* cen = ent->data;
|
||||
cen->direction = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ServerUpdate(void * ent) {
|
||||
entity* e = (entity*)ent;
|
||||
centery* cen = (centery*)e->userdata;
|
||||
int CenteryUpdate(int arg, void* self) {
|
||||
entity* e = self;
|
||||
world* w = e->world;
|
||||
centery* cen = e->data;
|
||||
vec2 moveTo = {0,0};
|
||||
int goodMove;
|
||||
//do{
|
||||
// goodMove = EntityMove(e,(vec2){e->position.x+ 0, e-> position.y + 1});
|
||||
// if(goodMove == 1) {
|
||||
// switch (cen->direction) {
|
||||
// case 0:
|
||||
// moveTo = (vec2){e->position.x+ 0, e-> position.y + 1};
|
||||
// printf("moveing S\n");
|
||||
// break;
|
||||
// case 1:
|
||||
// moveTo = (vec2){e->position.x+ 1, e-> position.y + 1};
|
||||
// printf("moveing SE\n");
|
||||
// break;
|
||||
// case 2:
|
||||
// moveTo = (vec2){e->position.x+ 1, e-> position.y + 0};
|
||||
// printf("moveing E\n");
|
||||
// break;
|
||||
// case 3:
|
||||
// moveTo = (vec2){e->position.x+ 1, e-> position.y + -1};
|
||||
// printf("moveing NE\n");
|
||||
// break;
|
||||
// case 4:
|
||||
// moveTo = (vec2){e->position.x+ 0, e-> position.y + -1};
|
||||
// printf("moveing N\n");
|
||||
// break;
|
||||
// case 6:
|
||||
// moveTo = (vec2){e->position.x+ -1, e->position.y+ -1};
|
||||
// printf("moveing NW\n");
|
||||
// break;
|
||||
// case 7:
|
||||
// moveTo = (vec2){e->position.x+ -1, e->position.y + 0};
|
||||
// printf("moveing W\n");
|
||||
// break;
|
||||
// case 8:
|
||||
// moveTo = (vec2){e->position.x+ -1, e->position.y + 1};
|
||||
// printf("moveing SW\n");
|
||||
// break;
|
||||
// }
|
||||
// goodMove = EntityMove(e,moveTo);
|
||||
// if(cen->direction > 8) {
|
||||
// cen->direction = 0;
|
||||
// }else {
|
||||
// cen->direction ++;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//}while(goodMove == 1);
|
||||
|
||||
|
||||
|
||||
printf("name of entity %s\n",e->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CenteryFree(void* self) {
|
||||
entity* ent = self;
|
||||
centery* cen = ent->data;
|
||||
free(cen);
|
||||
free(ent);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
entity* CreateCentery(int tear, int classification, world* w) {
|
||||
entity* ent = (entity*)malloc(sizeof(entity));
|
||||
centery* cen = (centery*)malloc(sizeof(centery));
|
||||
|
||||
*cen = (centery){
|
||||
.weapon = 1,
|
||||
.classification = 1,
|
||||
.tear = 3,
|
||||
.alert = 0,
|
||||
.mode = 0,
|
||||
|
||||
.health = 30,
|
||||
.ac = 3,
|
||||
.str = 3,
|
||||
.wis = 3,
|
||||
.dex = 3,
|
||||
};
|
||||
|
||||
*ent = (entity){
|
||||
.id = CENTERY_ID,
|
||||
.name = "Centery",
|
||||
.description = "Your Basic Bad giy",
|
||||
.tile = {
|
||||
.simble = 'C',
|
||||
.background = {0,0,0},
|
||||
.forground = {0x3f,0x5f,0x10},
|
||||
},
|
||||
.position = (vec2){5,5},
|
||||
.data = cen,
|
||||
.world = w,
|
||||
.callback = {
|
||||
.init = CenteryInit,
|
||||
.update = CenteryUpdate,
|
||||
.free = CenteryFree,
|
||||
},
|
||||
|
||||
.cleanup = 0,
|
||||
};
|
||||
|
||||
return ent;
|
||||
}
|
||||
|
||||
int ServerUpdate(void * ent) {
|
||||
//entity* e = (entity*)ent;
|
||||
//centery* cen = (centery*)e->userdata;
|
||||
|
||||
if(
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -17,6 +131,7 @@ int ClientUpdate(int action, void * centery) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int Init(void * ent){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
#ifndef CENTERY_H
|
||||
#define CENTERY_H
|
||||
#define CENTERY_ID 1
|
||||
#include "../entity.h"
|
||||
#include "../world.h"
|
||||
|
||||
typedef struct {
|
||||
entity* target;
|
||||
int weapon;
|
||||
int classification;
|
||||
int tear;
|
||||
int alert;
|
||||
int mode;
|
||||
int direction;
|
||||
|
||||
int health;
|
||||
int ac;
|
||||
@@ -17,7 +19,7 @@ typedef struct {
|
||||
int dex;
|
||||
} centery;
|
||||
|
||||
int CreateCentery(int tear, int classification);
|
||||
entity* CreateCentery(int tear, int classification,world* w);
|
||||
|
||||
int ServerUpdate(void*);
|
||||
int ClientUpdate(int, void*);
|
||||
|
||||
99
source/game_source/entities/Gun.c
Normal file
99
source/game_source/entities/Gun.c
Normal file
@@ -0,0 +1,99 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "Gun.h"
|
||||
|
||||
int GunUpdate(int action, void* data) {
|
||||
printf("Running Gun\n");
|
||||
entity* e = (entity*)data;
|
||||
vec2 bullet_pos = e->position;
|
||||
Gun* g = (Gun*)e->data;
|
||||
world* w = (world*)e->world;
|
||||
if(g->inpact == 0) {
|
||||
switch (g->direction) {
|
||||
case SHOOT_N: bullet_pos.y -= 1; break;
|
||||
case SHOOT_E: bullet_pos.x += 1; break;
|
||||
case SHOOT_S: bullet_pos.y += 1; break;
|
||||
case SHOOT_W: bullet_pos.x -= 1; break;
|
||||
}
|
||||
}
|
||||
int entity_colied = EntityMove(e, bullet_pos);
|
||||
if((entity_colied) && g->inpact == 0) {
|
||||
if(w->wells[at(bullet_pos.x, bullet_pos.y, w)].cell->id == 1) {
|
||||
w->wells[at(bullet_pos.x, bullet_pos.y, w)].cell = SetCell(2);
|
||||
}
|
||||
g->inpact ++;
|
||||
}
|
||||
|
||||
if(g->inpact > 0) {
|
||||
e->tile.simble = '*';
|
||||
e->tile.background = (color){0xff,0x0a,0x0a};
|
||||
e->tile.forground = (color){0xff,0xff,0xff};
|
||||
g->inpact ++;
|
||||
}
|
||||
if(g->inpact > 25) {
|
||||
|
||||
e->tile.simble = 'o';
|
||||
e->tile.background = (color){0xff,0x20,0x20};
|
||||
e->tile.forground = (color){0xff,0x3f,0x3f};
|
||||
}
|
||||
if(g->inpact > 30) {
|
||||
|
||||
e->tile.simble = 'O';
|
||||
e->tile.background = (color){0x01,0x01,0x01};
|
||||
e->tile.forground = (color){0xff,0x0a,0x0a};
|
||||
}
|
||||
if(g->inpact > 40) {
|
||||
|
||||
e->tile.simble = '#';
|
||||
e->tile.background = (color){0x01,0x01,0x01};
|
||||
e->tile.forground = (color){0xff,0x0a,0x0a};
|
||||
}
|
||||
if(g->inpact > 75) {
|
||||
printf("tagged for cleanup\n");
|
||||
e->tile.simble = 'R';
|
||||
e->cleanup = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
entity* CreateGun(int direction, int bullet, world* w) {
|
||||
entity* ent = malloc(sizeof(entity));
|
||||
Gun* g= malloc(sizeof(Gun));
|
||||
|
||||
*g = (Gun){
|
||||
.direction = direction,
|
||||
.projectileId = bullet,
|
||||
.fuse = 10,
|
||||
.currentFuse = 0,
|
||||
.inpact = 0,
|
||||
};
|
||||
|
||||
|
||||
*ent = (entity){
|
||||
.id = 50,
|
||||
.name = "Gun",
|
||||
.description = "description",
|
||||
.tile = {
|
||||
.simble = '-',
|
||||
.background = {0,0,0},
|
||||
.forground = {0xff,0,0},
|
||||
},
|
||||
.position = (vec2){0,0},
|
||||
.data = g,
|
||||
.world = w,
|
||||
.callback = {
|
||||
.init = GunInit,
|
||||
.update = GunUpdate,
|
||||
.free = GunFree,
|
||||
},
|
||||
|
||||
.cleanup = 0,
|
||||
};
|
||||
|
||||
return ent;
|
||||
}
|
||||
|
||||
int GunInit(void* ent) {return 0;}
|
||||
int GunFree(void* ent) {return 0;}
|
||||
|
||||
26
source/game_source/entities/Gun.h
Normal file
26
source/game_source/entities/Gun.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef ENTITY_Gun_H
|
||||
#define ENTITY_Gun_H
|
||||
#include "../entity.h"
|
||||
#include "../world.h"
|
||||
|
||||
#define SHOOT_N 1
|
||||
#define SHOOT_E 2
|
||||
#define SHOOT_S 3
|
||||
#define SHOOT_W 4
|
||||
|
||||
|
||||
typedef struct {
|
||||
int projectileId;
|
||||
int direction;
|
||||
int fuse;
|
||||
int currentFuse;
|
||||
int inpact;
|
||||
} Gun;
|
||||
|
||||
entity* CreateGun(int direction,int bullet, world* w);
|
||||
|
||||
int GunUpdate(int, void*);
|
||||
int GunInit(void*);
|
||||
int GunFree(void*);
|
||||
|
||||
#endif // ENTITY_Gun_H
|
||||
146
source/game_source/entities/Player.c
Normal file
146
source/game_source/entities/Player.c
Normal file
@@ -0,0 +1,146 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "Player.h"
|
||||
#include "Gun.h"
|
||||
#include "Centery.h"
|
||||
#include "../../client_source/client.h"
|
||||
|
||||
void Shoot(entity* e,int direction) {
|
||||
if(direction == SHOOT_N) {
|
||||
entity* g = CreateGun(SHOOT_N, 0, e->world);
|
||||
g->position = (vec2){e->position.x, e->position.y-1};
|
||||
world* w = e->world;
|
||||
AddEntity(w, g);
|
||||
printf("Shoot N\n");
|
||||
}
|
||||
if(direction == SHOOT_E) {
|
||||
entity* g = CreateGun(SHOOT_E, 0, e->world);
|
||||
world* w = e->world;
|
||||
g->position = (vec2){e->position.x + 1, e->position.y};
|
||||
AddEntity(w, g);
|
||||
printf("Shoot E\n");
|
||||
}
|
||||
if(direction == SHOOT_S) {
|
||||
entity* g = CreateGun(SHOOT_S, 0, e->world);
|
||||
world* w = e->world;
|
||||
g->position = (vec2){e->position.x, e->position.y+1};
|
||||
AddEntity(w, g);
|
||||
printf("Shoot S\n");
|
||||
}
|
||||
if(direction == SHOOT_W) {
|
||||
entity* g = CreateGun(SHOOT_W, 0, e->world);
|
||||
world* w = e->world;
|
||||
g->position = (vec2){e->position.x - 1, e->position.y};
|
||||
AddEntity(w, g);
|
||||
printf("Shoot W\n");
|
||||
}
|
||||
}
|
||||
|
||||
int PlayerUpdate(int action, void* data) {
|
||||
entity* e = (entity*)data;
|
||||
player* p= (player*)e->data;
|
||||
world* w = e->world;
|
||||
ssh_terminal_data* td = &p->cli->term;
|
||||
vec2 mv = {e->position.x, e->position.y};
|
||||
vec2 cammera_pos = {
|
||||
p->cli->cam.pos_x + (p->cli->cam.size_x/2),
|
||||
p->cli->cam.pos_y + (p->cli->cam.size_y/2),
|
||||
};
|
||||
int cammera_fallow_readious = 14;
|
||||
|
||||
printf("input buffer for player %s\n", td->inputBuffer);
|
||||
|
||||
if(!strcmp(td->inputBuffer, "k")) {mv.y -= 1;}
|
||||
if(!strcmp(td->inputBuffer, "j")) {mv.y += 1;}
|
||||
if(!strcmp(td->inputBuffer, "h")) {mv.x -= 1;}
|
||||
if(!strcmp(td->inputBuffer, "l")) {mv.x += 1;}
|
||||
|
||||
|
||||
int entity_can_move = EntityMove(e, mv);
|
||||
if(!strcmp(td->inputBuffer, "w")) {Shoot(e,SHOOT_N);}
|
||||
if(!strcmp(td->inputBuffer, "d")) {Shoot(e,SHOOT_E);}
|
||||
if(!strcmp(td->inputBuffer, "s")) {Shoot(e,SHOOT_S);}
|
||||
if(!strcmp(td->inputBuffer, "a")) {Shoot(e,SHOOT_W);}
|
||||
printf("Cammera Position %d,%d\n", cammera_pos.x, cammera_pos.y);
|
||||
|
||||
|
||||
|
||||
|
||||
if((e->position.x < cammera_pos.x - cammera_fallow_readious )){
|
||||
p->cli->cam.pos_x += - 1;
|
||||
}
|
||||
if ((e->position.x > cammera_pos.x + cammera_fallow_readious)) {
|
||||
p->cli->cam.pos_x += 1;
|
||||
}
|
||||
|
||||
if((e->position.y < cammera_pos.y - (cammera_fallow_readious / 2) )){
|
||||
p->cli->cam.pos_y += - 1;
|
||||
}
|
||||
if ((e->position.y > cammera_pos.y + (cammera_fallow_readious / 2))) {
|
||||
p->cli->cam.pos_y += 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if(!entity_can_move) {
|
||||
w->wells[at(mv.x, mv.y, w)].cell = SetCell(6);
|
||||
}
|
||||
printf("is this a good move? %d\n", EntityMove(e, mv));
|
||||
|
||||
|
||||
|
||||
memset(td->inputBuffer,0,32);
|
||||
return 0;
|
||||
}
|
||||
|
||||
entity* CreatePlayer(const char* username, client* cli,world* w) {
|
||||
entity* ent = malloc(sizeof(entity));
|
||||
player* p= malloc(sizeof(player));
|
||||
|
||||
*p = (player){
|
||||
.holding = 0,
|
||||
.class = 0,
|
||||
|
||||
.health = 0,
|
||||
.ac = 0,
|
||||
.str = 0,
|
||||
.wis = 0,
|
||||
.dex = 0,
|
||||
.cli = cli,
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
*ent = (entity){
|
||||
.id = 30,
|
||||
.name = "Testing",
|
||||
.description = "This is a player",
|
||||
.tile = {
|
||||
.simble = '@',
|
||||
.background = {0,0,0},
|
||||
.forground = {0x5f,0x3f,0x10},
|
||||
},
|
||||
.position = (vec2){5,5},
|
||||
.data = p,
|
||||
.world = w,
|
||||
.callback = {
|
||||
.init = PlayerInit,
|
||||
.update = PlayerUpdate,
|
||||
.free = PlayerFree,
|
||||
},
|
||||
.cleanup = 0,
|
||||
|
||||
};
|
||||
|
||||
p->cli->cam.pos_x = ent->position.x - (p->cli->cam.size_x/2);
|
||||
p->cli->cam.pos_y = ent->position.y - (p->cli->cam.size_y/2);
|
||||
return ent;
|
||||
}
|
||||
|
||||
int PlayerServerUpdate(void*);
|
||||
int PlayerClientUpdate(int, void*);
|
||||
int PlayerInit(void* ent) {return 0;}
|
||||
int PlayerFree(void* ent) {return 0;}
|
||||
|
||||
30
source/game_source/entities/Player.h
Normal file
30
source/game_source/entities/Player.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef PLAYER_H
|
||||
#define PLAYER_H
|
||||
|
||||
#include "../entity.h"
|
||||
#include "../../client_source/client.h"
|
||||
#include "../world.h"
|
||||
|
||||
typedef struct {
|
||||
int holding;
|
||||
int class;
|
||||
|
||||
int health;
|
||||
int ac;
|
||||
int str;
|
||||
int wis;
|
||||
int dex;
|
||||
client* cli;
|
||||
|
||||
|
||||
int invintory[30];
|
||||
} player;
|
||||
|
||||
entity* CreatePlayer(const char* username, client* cli ,world* w);
|
||||
|
||||
int PlayerServerUpdate(void*);
|
||||
int PlayerClientUpdate(int, void*);
|
||||
int PlayerInit(void*);
|
||||
int PlayerFree(void*);
|
||||
|
||||
#endif
|
||||
42
source/game_source/entities/templates/Template.c
Normal file
42
source/game_source/entities/templates/Template.c
Normal file
@@ -0,0 +1,42 @@
|
||||
#include <stdlib.h>
|
||||
#include "Template.h"
|
||||
#include "../../client_source/client.h"
|
||||
|
||||
int templateUpdate(int action, void* data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
entity* Createtemplate() {
|
||||
entity* ent = malloc(sizeof(entity));
|
||||
template* p= malloc(sizeof(template));
|
||||
|
||||
*t = (template){
|
||||
};
|
||||
|
||||
|
||||
*ent = (entity){
|
||||
.id = ID,
|
||||
.name = "template",
|
||||
.description = "description",
|
||||
.tile = {
|
||||
.simble = 'T',
|
||||
.background = {0,0,0},
|
||||
.forground = {0,0,0},
|
||||
},
|
||||
.position = (vec2){0,0},
|
||||
.data = t,
|
||||
.world = w,
|
||||
.callback = {
|
||||
.init = PlayerInit,
|
||||
.update = PlayerUpdate,
|
||||
.free = PlayerFree,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
return ent;
|
||||
}
|
||||
|
||||
int templateInit(void* ent) {return 0;}
|
||||
int templateFree(void* ent) {return 0;}
|
||||
|
||||
16
source/game_source/entities/templates/Template.h
Normal file
16
source/game_source/entities/templates/Template.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef ENTITY_template_H
|
||||
#define ENTITY_template_H
|
||||
#include "../entity.h"
|
||||
#include "../world.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
} template;
|
||||
|
||||
entity* Createtemplate(initvar);
|
||||
|
||||
int templateUpdate(int, void*);
|
||||
int templateInit(void*);
|
||||
int templateFree(void*);
|
||||
|
||||
#endif // ENTITY_template_H
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "entity.h"
|
||||
#include "cells.h"
|
||||
#include "vector.h"
|
||||
#include "world.h"
|
||||
|
||||
int EntityMove(entity* e, vec2 pos) {
|
||||
world* world = e->world;
|
||||
|
||||
if(world->wells[at(pos.x,pos.y, world)].cell->flags & (CELL_FLAG_BLOCKING)){
|
||||
return 1;
|
||||
}
|
||||
if(world->wells[at(pos.x,pos.y, world)].entityIds[0] != NULL){
|
||||
return 2;
|
||||
}
|
||||
|
||||
world->wells[at(e->position.x,e->position.y, world)].entityIds[0] = 0;
|
||||
world->wells[at(pos.x,pos.y, world)].entityIds[0] = e;
|
||||
e->position = pos;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
#include "vector.h"
|
||||
#include "tile.h"
|
||||
|
||||
typedef short entity_id;
|
||||
typedef int(*entity_func)(void*);
|
||||
typedef int(*entity_update_func)(int, void*);
|
||||
|
||||
// Entity network transaction.
|
||||
typedef struct {
|
||||
int id;
|
||||
entity_id id;
|
||||
int action;
|
||||
int userdataSize;
|
||||
void* userdata;
|
||||
@@ -23,19 +24,22 @@ typedef struct {
|
||||
|
||||
// Entity Struct
|
||||
typedef struct {
|
||||
int id;
|
||||
entity_id id;
|
||||
const char* name;
|
||||
const char* description;
|
||||
tile tile;
|
||||
vec2 position;
|
||||
void* userdata;
|
||||
void* data;
|
||||
void* world;
|
||||
entity_callbacks callback;
|
||||
entity_transaction ta;
|
||||
unsigned char cleanup;
|
||||
} entity;
|
||||
|
||||
entity* CreateEntity(const char* name, const char* description);
|
||||
int EntityAddCallbacks(entity* e, entity_callbacks cb);
|
||||
int EntitySetUserdat(entity* e, void* userdata);
|
||||
int EntityMove(entity* e, vec2 pos);
|
||||
|
||||
// Gets
|
||||
const char* GetEntityDescription(entity* e);
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
#include "entity_handler.h"
|
||||
#include "world.h"
|
||||
#include <bits/time.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void EntityListInit(entity_list* list) {
|
||||
list->count = 0;
|
||||
for(int i = 0; i < 256; i++) {
|
||||
list->entities[i] = NULL;
|
||||
}
|
||||
clock_gettime(CLOCK_MONOTONIC, &list->start);
|
||||
}
|
||||
|
||||
int EntityListUpdate(entity_list* list) {
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &list->current);
|
||||
double elapsed = (list->current.tv_sec - list->start.tv_sec);
|
||||
elapsed += (list->current.tv_nsec - list->start.tv_nsec) / 1000000000.0;
|
||||
if(elapsed > 0.125/4) {
|
||||
for(int i = 0; i < 256; i++) {
|
||||
if(list->entities[i] != NULL) {
|
||||
printf("running index %d\n", i);
|
||||
list->entities[i]->callback.update(0,list->entities[i]);
|
||||
}
|
||||
}
|
||||
clock_gettime(CLOCK_MONOTONIC, &list->start);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4,10 +4,13 @@
|
||||
#define ENTITY_LIST_ACTION_ADD
|
||||
#define ENTITY_LIST_ACTION_REMOVE
|
||||
#include "entity.h"
|
||||
#include <time.h>
|
||||
|
||||
typedef struct {
|
||||
int count;
|
||||
entity* entities[256];
|
||||
struct timespec start;
|
||||
struct timespec current;
|
||||
} entity_list;
|
||||
|
||||
typedef struct {
|
||||
@@ -17,13 +20,13 @@ typedef struct {
|
||||
}entity_list_transaction;
|
||||
|
||||
void EntityListInit(entity_list* list);
|
||||
int EntityListAddEntity(entity* ent);
|
||||
int EntityListRemoveEntity(entity* ent);
|
||||
//int EntityListAddEntity(entity* ent);
|
||||
//int EntityListRemoveEntity(entity* ent);
|
||||
//
|
||||
//int EntityListTransactionSet(entity_list_transaction* ta, int action, void* data);
|
||||
//int EntityListTransactionSend(entity_list* list, entity_list_transaction* ta);
|
||||
|
||||
int EntityListTransactionSet(entity_list_transaction* ta, int action, void* data);
|
||||
int EntityListTransactionSend(entity_list* list, entity_list_transaction* ta);
|
||||
|
||||
int EntityListUpdate();
|
||||
int EntityListUpdate(entity_list* list);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
13
source/game_source/game_server.h
Normal file
13
source/game_source/game_server.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#include "player/player_packet.h"
|
||||
#ifndef GAME_SERVER_H
|
||||
|
||||
typedef struct {
|
||||
const char* ip;
|
||||
int port;
|
||||
unsigned int sessionId;
|
||||
}game_server_config;
|
||||
|
||||
int ConnectToGameServer(game_server_config* config);
|
||||
|
||||
#define GAME_SERVER_H
|
||||
#endif
|
||||
8
source/game_source/player/player_packet.c
Normal file
8
source/game_source/player/player_packet.c
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "player_packet.h"
|
||||
|
||||
int SendPlayerPacket(player_packet *pakcet, game_server *config) {
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
25
source/game_source/player/player_packet.h
Normal file
25
source/game_source/player/player_packet.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef PLAYER_PACKET_H
|
||||
#define PLAYER_PACKET_H
|
||||
#include "../../server_source/game_client.h"
|
||||
|
||||
#define MOVE_UP 1
|
||||
#define MOVE_DOWN 2
|
||||
#define MOVE_LEFT 3
|
||||
#define MOVE_RIGHT 4
|
||||
|
||||
#define ATTACK_MELEE 11
|
||||
#define ATTACK_WEAPON_1 12
|
||||
#define ATTACK_WEAPON_2 13
|
||||
#define ATTACK_WEAPON_3 14
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
}player_packet;
|
||||
|
||||
|
||||
|
||||
int SendPlayerPacket(player_packet* pakcet, game_server* config);
|
||||
|
||||
#endif
|
||||
@@ -1,8 +1,9 @@
|
||||
#ifndef TILE_H
|
||||
#define TILE_H
|
||||
#include "color.h"
|
||||
#include "tart.h"
|
||||
typedef struct {
|
||||
char simble;
|
||||
t_char simble;
|
||||
color forground;
|
||||
color background;
|
||||
} tile;
|
||||
|
||||
186
source/game_source/world.c
Normal file
186
source/game_source/world.c
Normal file
@@ -0,0 +1,186 @@
|
||||
#include "world.h"
|
||||
#include "cells.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "./entities/Centery.h"
|
||||
#include "./entities/Player.h"
|
||||
#include "entity_handler.h"
|
||||
#include "vector.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define iToX(i) i%w->size_x
|
||||
#define iToY(i) i/w->size_x
|
||||
|
||||
int UpdateWorld(world* w) {
|
||||
for(int i = 0; i < 255; i++ ) {
|
||||
if(w->ent_list->entities[i] != NULL) {
|
||||
if(w->ent_list->entities[i]->cleanup) {
|
||||
printf("CleanningUp Entity %d\n", i);
|
||||
RemoveEntity(w, w->ent_list->entities[i]);
|
||||
w->ent_list->entities[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
EntityListUpdate(w->ent_list);
|
||||
return 0;
|
||||
}
|
||||
int InitWorld(world* w) {
|
||||
EntityListInit(w->ent_list);
|
||||
return 0;
|
||||
}
|
||||
int CreateWorld(world* w, long seed) {
|
||||
int grid_size = w->size_x * w->size_y * sizeof(well);
|
||||
|
||||
w->world_size = grid_size;
|
||||
w->seed = seed;
|
||||
|
||||
w->wells = (well*)malloc(grid_size * sizeof(well));
|
||||
w->prevWells = (well*)malloc(grid_size * sizeof(well));
|
||||
|
||||
if(!w->wells || !w->prevWells) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
entity_list* el = malloc(sizeof(entity_list));
|
||||
w->ent_list = el;
|
||||
|
||||
|
||||
memset(w->wells, 0, grid_size * sizeof(well));
|
||||
memset(w->prevWells, 0, grid_size * sizeof(well));
|
||||
|
||||
return grid_size;
|
||||
}
|
||||
|
||||
int AddEntity(world* w, entity* ent) {
|
||||
for(int i = 0; i < 255; i++) {
|
||||
if(w->ent_list->entities[i] == NULL) {
|
||||
w->ent_list->entities[i] = ent;
|
||||
break;
|
||||
}
|
||||
}
|
||||
w->wells[at(ent->position.x, ent->position.y,w)].entityIds[0] = ent;
|
||||
w->ent_list->count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RemoveEntity(world *w, entity *ent) {
|
||||
printf("removeing entity\n");
|
||||
w->wells[at(ent->position.x, ent->position.y,w)].entityIds[0] = NULL;
|
||||
ent->callback.free(ent);
|
||||
free(ent->data);
|
||||
free(ent);
|
||||
w->ent_list->count--;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GenerateWorld(world *w) {
|
||||
|
||||
|
||||
for(int i = 0; i <= w->size_y; i++) {
|
||||
for(int j = 0; j <= w->size_x; j++) {
|
||||
if(i == 0 || i == w->size_y - 2 || j == 0 || j == w->size_x - 2) {
|
||||
w->wells[at(j, i, w)].cell = SetCell(1);
|
||||
}else {
|
||||
int grass_type = (rand()%3) + 7;
|
||||
|
||||
w->wells[at(j, i, w)].cell = SetCell(grass_type);
|
||||
w->wells[at(j, i, w)].entityIds[0] = 0;
|
||||
w->wells[at(j, i, w)].entityIds[1] = 0;
|
||||
w->wells[at(j, i, w)].entityIds[2] = 0;
|
||||
w->wells[at(j, i, w)].entityIds[3] = 0;
|
||||
w->wells[at(j, i, w)].entityIds[4] = 0;
|
||||
w->wells[at(j, i, w)].entityIds[5] = 0;
|
||||
w->wells[at(j, i, w)].entityIds[6] = 0;
|
||||
w->wells[at(j, i, w)].entityIds[7] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < w->ent_list->count; i++) {
|
||||
entity* ent = w->ent_list->entities[i];
|
||||
w->wells[at(ent->position.x + 1, ent->position.y + 1, w)].entityIds[0] = ent;
|
||||
}
|
||||
|
||||
vec2 building_position = {50,50};
|
||||
vec2 building_size = {100,100};
|
||||
|
||||
for(int i = 0; i <= building_size.y; i++) {
|
||||
for(int j = 0; j <= building_size.x; j++) {
|
||||
w->wells[at(building_position.x + j, building_position.y + i,w)].cell = SetCell(1);
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
vec2 size,pos;
|
||||
int type;
|
||||
} block;
|
||||
|
||||
block roomList[100];
|
||||
block room;
|
||||
int sizeIteration = 0;
|
||||
int continueIdx = 0;
|
||||
|
||||
for(int i = 0; i < 100; i++) {
|
||||
//room.size = (vec2){(rand()%9)+1, (rand()%9)+1};
|
||||
room.size = (vec2){15, 15};
|
||||
room.pos = (vec2){
|
||||
(rand()%(building_size.x - room.size.x) -1),
|
||||
(rand()%(building_size.y - room.size.y) -1)
|
||||
};
|
||||
if(i > 0) {
|
||||
|
||||
for(int j = 0; j < i; j++) {
|
||||
printf("Room[%d] %d,%d, Chalange Room[%d] %d,%d ",i, room.pos.x, room.pos.y, j, roomList[j].pos.x, roomList[j].pos.y);
|
||||
if(!((room.pos.x + room.size.x < -1 + roomList[j].pos.x || room.pos.x > 1 + roomList[j].pos.x + roomList[j].size.x)|| (room.pos.y + room.size.y < -1 + roomList[j].pos.y
|
||||
|| room.pos.y > 1 + roomList[j].pos.y + roomList[j].size.y))) {
|
||||
|
||||
room.pos = (vec2){
|
||||
(rand()%(building_size.x - room.size.x)),
|
||||
(rand()%(building_size.y - room.size.y))
|
||||
};
|
||||
if(sizeIteration >= 5) {
|
||||
printf("iterate Size ");
|
||||
if(room.size.x > 5 && (rand()%2 - 1)) {
|
||||
room.size.x--;
|
||||
}else if(room.size.y > 5) {
|
||||
room.size.y--;
|
||||
}
|
||||
sizeIteration = 0;
|
||||
continueIdx++;
|
||||
}
|
||||
if(continueIdx > 100) {
|
||||
return -1;
|
||||
}
|
||||
sizeIteration++;
|
||||
j = -1;
|
||||
printf("BAD!\n");
|
||||
continue;
|
||||
}
|
||||
printf("Good!\n");
|
||||
}
|
||||
}
|
||||
continueIdx = 0;
|
||||
roomList[i] = room;
|
||||
for(int y = 0; y <= room.size.y; y++) {
|
||||
for(int x = 0; x <= room.size.x; x++) {
|
||||
if(room.pos.x+x > 0 && room.pos.x+x < w->size_x && room.pos.y+y > 0 && room.pos.y+y < w->size_y){
|
||||
if(y == 0 || y == room.size.y || x == 0 || x == room.size.x ) {
|
||||
w->wells[at(
|
||||
building_position.x + room.pos.x + x,
|
||||
building_position.y + room.pos.y + y,
|
||||
w)].cell = SetCell(2);
|
||||
}else {
|
||||
|
||||
w->wells[at(
|
||||
building_position.x + room.pos.x + x,
|
||||
building_position.y + room.pos.y + y,
|
||||
w)].cell = SetCell(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
32
source/game_source/world.h
Normal file
32
source/game_source/world.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef WORLD_H
|
||||
#define WORLD_H
|
||||
#define at(X,Y,w) ((Y) * w->size_x ) + (X)
|
||||
#include "cells.h"
|
||||
#include "entity.h"
|
||||
#include "entity_handler.h"
|
||||
|
||||
typedef struct {
|
||||
cell* cell;
|
||||
entity* entityIds[1];
|
||||
} well;
|
||||
|
||||
typedef struct {
|
||||
int size_x;
|
||||
int size_y;
|
||||
int player_spawn_x;
|
||||
int player_spawn_y;
|
||||
long seed;
|
||||
int world_size;
|
||||
well *wells;
|
||||
well *prevWells;
|
||||
entity_list* ent_list;
|
||||
} world;
|
||||
|
||||
int UpdateWorld(world*);
|
||||
int InitWorld(world*);
|
||||
int CreateWorld(world*, long seed);
|
||||
int AddEntity(world* w, entity* ent);
|
||||
int RemoveEntity(world* w, entity* ent);
|
||||
int GenerateWorld(world* w);
|
||||
|
||||
#endif
|
||||
@@ -18,12 +18,17 @@ int main() {
|
||||
ServerConfig conf = {
|
||||
.id = 123,
|
||||
.port = 2222,
|
||||
.threadCount = 0,
|
||||
.cbs = (ServerLoopCallbacks){
|
||||
.ssh_init = client_init,
|
||||
.ssh_stop = client_stop,
|
||||
.ssh_run = client_update,
|
||||
.ssh_resize = client_resize,
|
||||
}
|
||||
};
|
||||
for(int i = 0; i < 12; i++) {
|
||||
conf.clients[i] = 0;
|
||||
}
|
||||
ssh_start(&conf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
game_client.c
|
||||
server.c
|
||||
transactions.c
|
||||
)
|
||||
|
||||
60
source/server_source/game_client.c
Normal file
60
source/server_source/game_client.c
Normal file
@@ -0,0 +1,60 @@
|
||||
#include "game_client.h"
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
int Connect(game_server* gs) {
|
||||
struct sockaddr_in serverAddr;
|
||||
serverAddr.sin_family = AF_INET;
|
||||
serverAddr.sin_port = htons(gs->info.port);
|
||||
int blocking_mode = 1;
|
||||
|
||||
|
||||
gs->socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
inet_pton(AF_INET, gs->info.ip, &serverAddr.sin_addr);
|
||||
|
||||
if(connect(gs->socket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
|
||||
ioctl(gs->socket, FIONBIO, &blocking_mode); // Shuld be 1
|
||||
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
int Client_Send(game_server* gs,packet* packet) {
|
||||
int sendPacketSize = sizeof(int) + sizeof(int) + packet->size;
|
||||
unsigned char* buffer = malloc(sizeof(int) + sizeof(int) + packet->size);
|
||||
memcpy(buffer, &packet->packetTpye, sizeof(int));
|
||||
memcpy(buffer+sizeof(int), &packet->size, sizeof(int));
|
||||
memcpy(buffer+sizeof(int)+sizeof(int), &packet->packet, packet->size);
|
||||
|
||||
write(gs->socket, buffer, sendPacketSize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Client_Recive(game_server* gs, packet* packet) {
|
||||
|
||||
if(read(gs->socket, &packet->packetTpye, sizeof(int)) <= 0) {
|
||||
return 0;
|
||||
}
|
||||
if(read(gs->socket, &packet->size, sizeof(int)) <= 0 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
packet->packet = malloc(packet->size);
|
||||
|
||||
if(read(gs->socket, &packet->packet, packet->size) <= 0) {
|
||||
free(packet->packet);
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Disconnect(game_server* gs) {
|
||||
close(gs->socket);
|
||||
return 0;
|
||||
}
|
||||
24
source/server_source/game_client.h
Normal file
24
source/server_source/game_client.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef GAME_CLIENT_H
|
||||
#define GAME_CLIENT_H
|
||||
|
||||
#include "transactions.h"
|
||||
|
||||
typedef struct {
|
||||
const char* ip;
|
||||
int port;
|
||||
int id;
|
||||
} server_info;
|
||||
|
||||
typedef struct {
|
||||
int socket;
|
||||
server_info info;
|
||||
}game_server;
|
||||
|
||||
int Connect(game_server* gs);
|
||||
|
||||
int Send(game_server* gs,packet* packet);
|
||||
int Recive(game_server* gs, packet* pakcet);
|
||||
|
||||
int Disconnect(game_server* gs);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,29 @@
|
||||
#include "server.h"
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
int start_server() {
|
||||
struct sockaddr_in server;
|
||||
int serverSock;
|
||||
|
||||
serverSock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons(2223);
|
||||
server.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
if(bind(serverSock, (struct sockaddr*)&serverSock, sizeof(server)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
listen(serverSock, 4);
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
#ifndef SERVER_H
|
||||
#define SERVER_H
|
||||
|
||||
typedef struct {
|
||||
int port;
|
||||
int id;
|
||||
} server_info;
|
||||
#include "transactions.h"
|
||||
|
||||
typedef struct {
|
||||
} client;
|
||||
typedef struct {
|
||||
} client_manager;
|
||||
|
||||
int start_server();
|
||||
|
||||
server_info start_server();
|
||||
|
||||
#endif // !SERVER_H
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
#include "transactions.h"
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#define PORT 2223
|
||||
#define IP_ADDRESS "127.0.0.1"
|
||||
|
||||
|
||||
int CreateTransaction(action *act) {
|
||||
|
||||
int bufferSize = sizeof(int)*3 + act->argsize;
|
||||
|
||||
//unsigned char* buffer = malloc(bufferSize);
|
||||
|
||||
//buffer[0] = act->id;
|
||||
//buffer[sizeof(int)*1] = act->action;
|
||||
//buffer[sizeof(int)*2] = act->argsize;
|
||||
//memcpy(&buffer[sizeof(int)*3], act->userArg, act->argsize);
|
||||
|
||||
|
||||
//free(buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetTransaction(action *act) {
|
||||
|
||||
|
||||
int id;
|
||||
int action;
|
||||
int argsize;
|
||||
void* data;
|
||||
|
||||
|
||||
|
||||
act->id = id;
|
||||
act->action = action;
|
||||
act->argsize = argsize;
|
||||
act->userArg = data;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ProssesTransaction(action *act) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/* =============================================================================
|
||||
* # Server Transactions.
|
||||
* Transactions in the contexts of a entity, is an action. This action could be
|
||||
* anything that my include moving, shooting, douging, etc.
|
||||
*
|
||||
* Transactions take an entity id, action id, argsize and user
|
||||
*
|
||||
*
|
||||
* =============================================================================
|
||||
* */
|
||||
#ifndef TRANSACTIONS_H
|
||||
|
||||
#define ENTITY_ACTION_MOVE_UP 1
|
||||
#define ENTITY_ACTION_MOVE_DOWN 2
|
||||
#define ENTITY_ACTION_MOVE_LEFT 3
|
||||
#define ENTITY_ACTION_MOVE_RIGHT 4
|
||||
|
||||
|
||||
typedef struct {
|
||||
int packetTpye, size;
|
||||
void* packet;
|
||||
}packet;
|
||||
|
||||
typedef struct {
|
||||
int id;
|
||||
int action;
|
||||
int argsize;
|
||||
void* userArg;
|
||||
}action;
|
||||
|
||||
int CreateTransaction(action* act);
|
||||
int GetTransaction(action* act);
|
||||
int ProssesTransaction(action* act);
|
||||
|
||||
#define TRANSACTIONS_H
|
||||
#endif
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <libssh/server.h>
|
||||
#include <libssh/callbacks.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <threads.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@@ -28,9 +29,15 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef DOCKER
|
||||
#define RSA_LOCATION "./id_rsa"
|
||||
#else
|
||||
#define RSA_LOCATION "/root/.ssh/id_rsa"
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef BUF_SIZE
|
||||
#define BUF_SIZE 2049
|
||||
#define BUF_SIZE 32
|
||||
#endif
|
||||
|
||||
#ifndef KEYS_FOLDER
|
||||
@@ -44,6 +51,8 @@
|
||||
|
||||
|
||||
|
||||
int client_stop_thread = 0;
|
||||
|
||||
static int authenticated=0;
|
||||
static int tries = 0;
|
||||
static int error = 0;
|
||||
@@ -52,6 +61,7 @@ static ssh_channel chan[30] ={NULL};
|
||||
typedef struct {
|
||||
ssh_session session;
|
||||
ServerConfig* config;
|
||||
|
||||
} ud;
|
||||
|
||||
static int auth_none(ssh_session session,
|
||||
@@ -110,6 +120,20 @@ static int auth_gssapi_mic(ssh_session session, const char *user, const char *pr
|
||||
}
|
||||
#endif
|
||||
|
||||
static int shell_resize(ssh_session s, ssh_channel ch, int width, int height,
|
||||
int pxwidth, int pwheight, void* userdata) {
|
||||
|
||||
client* cli = (client*)userdata;
|
||||
cli->resize = 1;
|
||||
cli->newHeight = height;
|
||||
cli->newWidth = width;
|
||||
|
||||
|
||||
printf("setting Size to %d,%d\n", cli->newWidth, cli->newHeight);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pty_request(ssh_session session, ssh_channel channel, const char *term,
|
||||
int x,int y, int px, int py, void *userdata){
|
||||
(void) session;
|
||||
@@ -120,6 +144,14 @@ static int pty_request(ssh_session session, ssh_channel channel, const char *ter
|
||||
(void) px;
|
||||
(void) py;
|
||||
(void) userdata;
|
||||
client* cli = (client*)userdata;
|
||||
cli->resize = 1;
|
||||
cli->newHeight = y;
|
||||
cli->newWidth = x;
|
||||
|
||||
|
||||
printf("setting Size to %d,%d\n", cli->newWidth, cli->newHeight);
|
||||
printf("Terminal is %s\n", term);
|
||||
printf("Allocated terminal\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -131,19 +163,25 @@ static int shell_request(ssh_session session, ssh_channel channel, void *userdat
|
||||
printf("Allocated shell\n");
|
||||
return 0;
|
||||
}
|
||||
struct ssh_channel_callbacks_struct channel_cb = {
|
||||
.channel_pty_request_function = pty_request,
|
||||
.channel_shell_request_function = shell_request
|
||||
};
|
||||
//struct ssh_channel_callbacks_struct channel_cb = {
|
||||
// .channel_pty_request_function = pty_request,
|
||||
// .channel_shell_request_function = shell_request,
|
||||
// .channel_pty_window_change_function = shell_resize,
|
||||
//
|
||||
//};
|
||||
|
||||
static ssh_channel new_session_channel(ssh_session session, void *userdata){
|
||||
(void) session;
|
||||
(void) userdata;
|
||||
|
||||
|
||||
client* c = (client*)userdata;
|
||||
ssh_channel* cli = &c->channel;
|
||||
printf("Allocated session channel for id %d\n", *(int*)userdata);
|
||||
*(ssh_channel*)userdata = ssh_channel_new(session);
|
||||
ssh_callbacks_init(&channel_cb);
|
||||
ssh_set_channel_callbacks(*(ssh_channel*)userdata, &channel_cb);
|
||||
return *(ssh_channel*)userdata;
|
||||
*cli = ssh_channel_new(session);
|
||||
ssh_callbacks_init(&c->channel_cb);
|
||||
ssh_set_channel_callbacks(*cli, &c->channel_cb);
|
||||
return *cli;
|
||||
}
|
||||
|
||||
|
||||
@@ -155,17 +193,27 @@ void* Handel_Client(void* d) {
|
||||
int i;
|
||||
ssh_event mainloop;
|
||||
ssh_session session = data.session;
|
||||
ssh_channel c;
|
||||
client* cli = (client*)malloc(sizeof(client));
|
||||
|
||||
struct ssh_server_callbacks_struct cb = {
|
||||
.userdata = (void*)&c,
|
||||
|
||||
printf("og cliet addres %d\n", cli);
|
||||
|
||||
cli->server_cb = (struct ssh_server_callbacks_struct){
|
||||
.userdata = cli,
|
||||
.auth_none_function = auth_none,
|
||||
.auth_password_function = auth_password,
|
||||
.channel_open_request_session_function = new_session_channel,
|
||||
};
|
||||
|
||||
ssh_callbacks_init(&cb);
|
||||
ssh_set_server_callbacks(session, &cb);
|
||||
cli->channel_cb = (struct ssh_channel_callbacks_struct){
|
||||
.userdata = cli,
|
||||
.channel_pty_request_function = pty_request,
|
||||
.channel_shell_request_function = shell_request,
|
||||
.channel_pty_window_change_function = shell_resize,
|
||||
};
|
||||
|
||||
ssh_callbacks_init(&cli->server_cb);
|
||||
ssh_set_server_callbacks(session, &cli->server_cb);
|
||||
|
||||
if (ssh_handle_key_exchange(session)) {
|
||||
printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session));
|
||||
@@ -177,7 +225,7 @@ void* Handel_Client(void* d) {
|
||||
mainloop = ssh_event_new();
|
||||
ssh_event_add_session(mainloop, session);
|
||||
|
||||
while (!(authenticated && c != NULL)){
|
||||
while (!(authenticated && cli->channel != NULL)){
|
||||
if(error)
|
||||
break;
|
||||
r = ssh_event_dopoll(mainloop, -1);
|
||||
@@ -188,80 +236,102 @@ void* Handel_Client(void* d) {
|
||||
}
|
||||
}
|
||||
|
||||
char sendBuf[1024] = {0};
|
||||
int sendBuffSize = 1024;
|
||||
char* sendBuf = (char*)malloc(30);
|
||||
int sendBuffSize = 30;
|
||||
int counter = 0;
|
||||
if(error){
|
||||
printf("Error, exiting loop\n");
|
||||
} else
|
||||
printf("Authenticated and got a channel\n");
|
||||
client* cli = NULL;
|
||||
|
||||
// Data Init
|
||||
data.config->cbs.init_var = cli;
|
||||
data.config->cbs.run_var = cli;
|
||||
data.config->cbs.stop_var = cli;
|
||||
|
||||
data.config->cbs.ssh_init(data.config->cbs.init_var);
|
||||
|
||||
data.config->cbs.ssh_init(cli);
|
||||
|
||||
cli->term = (ssh_terminal_data) {
|
||||
.inputBuffer = buf,
|
||||
.outputBuffer = sendBuf,
|
||||
.inputSize = sizeof(buf),
|
||||
.outputSize = &sendBuffSize,
|
||||
.channel = cli->channel,
|
||||
};
|
||||
|
||||
|
||||
do{ // Update
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
i = 1;
|
||||
//snprintf(sendBuf, 1024, "Counter: %d, id: %d\r", counter, data.config->id);
|
||||
//char kittyBuffer[30] = {0};
|
||||
//sprintf(kittyBuffer, "\e[>%d", 0b1000);
|
||||
//if (ssh_channel_write(c, kittyBuffer, 30) == SSH_ERROR) {
|
||||
i = ssh_channel_read_nonblocking(cli->channel, buf, sizeof(buf)-1, 0);
|
||||
// code go here
|
||||
|
||||
|
||||
if(data.config->cbs.ssh_run(&cli->term,cli) == 0) {
|
||||
// code go here
|
||||
//if (ssh_channel_write(c, tb.outputBuffer, *tb.outputSize) == SSH_ERROR) {
|
||||
// printf("error writing to channel\n");
|
||||
// return NULL;
|
||||
//}
|
||||
i = ssh_channel_read_nonblocking(c, buf, sizeof(buf)-1, 0);
|
||||
counter++;
|
||||
// code go here
|
||||
ssh_terminal_data tb = {
|
||||
.inputBuffer = buf,
|
||||
.outputBuffer = sendBuf,
|
||||
.inputSize = 1024,
|
||||
.outputSize = &sendBuffSize,
|
||||
};
|
||||
data.config->cbs.ssh_run(&tb,data.config->cbs.run_var);
|
||||
// code go here
|
||||
if (ssh_channel_write(c, tb.outputBuffer, 1024) == SSH_ERROR) {
|
||||
printf("error writing to channel\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(i>0) {
|
||||
|
||||
buf[i] = '\0';
|
||||
printf("%s", buf);
|
||||
fflush(stdout);
|
||||
//printf("%s", buf);
|
||||
//fflush(stdout);
|
||||
if(buf[0] == '\x03') {
|
||||
ssh_disconnect(data.session);
|
||||
ssh_free(data.session);
|
||||
authenticated--;
|
||||
//ssh_channel_close(c);
|
||||
//ssh_channel_free(c);
|
||||
data.config->cbs.ssh_stop(cli);
|
||||
ssh_channel_close(cli->channel);
|
||||
ssh_channel_free(cli->channel);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} while (true);
|
||||
if(cli->resize > 0) {
|
||||
printf("running resize %d,%d\n", cli->newWidth, cli->newHeight);
|
||||
client_resize(cli->newWidth, cli->newHeight, cli);
|
||||
cli->resize = 0;
|
||||
}
|
||||
//memset(buf,0,BUF_SIZE);
|
||||
} while (!client_stop_thread);
|
||||
|
||||
data.config->cbs.ssh_stop(cli);
|
||||
ssh_channel_close(cli->channel);
|
||||
ssh_channel_free(cli->channel);
|
||||
|
||||
data.config->cbs.ssh_stop(data.config->cbs.stop_var);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void stop_server(int arg) {
|
||||
printf("\nstopping server\n");
|
||||
client_stop_thread = 1;
|
||||
sleep(1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int ssh_start(ServerConfig* conf){
|
||||
ssh_session session;
|
||||
ssh_bind sshbind;
|
||||
signal(SIGSTOP, stop_server);
|
||||
signal(SIGINT, stop_server);
|
||||
signal(SIGTERM, stop_server);
|
||||
|
||||
int port = 2222;// conf->port;
|
||||
int r =0;
|
||||
|
||||
sshbind=ssh_bind_new();
|
||||
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, "/home/preacher/.ssh/id_rsa");
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, RSA_LOCATION);
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT, &port);
|
||||
|
||||
while(sshbind) {
|
||||
while(sshbind && !client_stop_thread){ //&& !client_stop_thread) {
|
||||
|
||||
if(ssh_bind_listen(sshbind)<0){
|
||||
printf("Error listening to socket: %s\n",ssh_get_error(sshbind));
|
||||
@@ -274,15 +344,31 @@ int ssh_start(ServerConfig* conf){
|
||||
return 1;
|
||||
}
|
||||
ud d = {session, conf};
|
||||
d.config->stop = &client_stop_thread;
|
||||
|
||||
pthread_t thread_id;
|
||||
if(pthread_create(&thread_id, NULL, Handel_Client, (void*)&d) < 0) {
|
||||
for(int i = 0; i < 12; i++) {
|
||||
if(conf->clients[i] == 0) {
|
||||
if(pthread_create(&conf->clients[i], NULL, Handel_Client, (void*)&d) < 0) {
|
||||
ssh_disconnect(session);
|
||||
}
|
||||
conf->threadCount++;
|
||||
break;
|
||||
}
|
||||
//ssh_disconnect(session);
|
||||
//ssh_bind_free(sshbind);
|
||||
//ssh_finalize();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//for(int i = 0; i < 12; i++) {
|
||||
// if(conf->clients[i] != 0) {
|
||||
// printf("working on thread %d\n", i);
|
||||
// sleep(1);
|
||||
// pthread_cancel(conf->clients[i]);
|
||||
// }
|
||||
//}
|
||||
printf("Done\n");
|
||||
ssh_disconnect(session);
|
||||
ssh_bind_free(sshbind);
|
||||
ssh_finalize();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,30 +1,41 @@
|
||||
#ifndef SSH_SERVER_CLIENT_H
|
||||
#define SSH_SERVER_CLIENT_H
|
||||
|
||||
#include <pthread.h>
|
||||
typedef struct {
|
||||
int inputSize;
|
||||
int* outputSize;
|
||||
char* inputBuffer;
|
||||
char* outputBuffer;
|
||||
int width;
|
||||
int height;
|
||||
void* channel;
|
||||
|
||||
|
||||
}ssh_terminal_data;
|
||||
|
||||
typedef int(*ssh_server_callback)(void* userdata);
|
||||
typedef int(*ssh_server_resize_callback)(int,int,void* userdata);
|
||||
typedef int(*ssh_server_run_callback)(ssh_terminal_data* ssh_terminal_data, void* userdata);
|
||||
|
||||
typedef struct {
|
||||
void* init_var;
|
||||
void* run_var;
|
||||
void* stop_var;
|
||||
void* resize_var;
|
||||
ssh_server_callback ssh_init;
|
||||
ssh_server_run_callback ssh_run;
|
||||
ssh_server_callback ssh_stop;
|
||||
ssh_server_resize_callback ssh_resize;
|
||||
}ServerLoopCallbacks;
|
||||
|
||||
typedef struct {
|
||||
int port;
|
||||
int id;
|
||||
ServerLoopCallbacks cbs;
|
||||
pthread_t clients[12];
|
||||
int threadCount;
|
||||
int* stop;
|
||||
}ServerConfig;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user