diff --git a/common/sql/test.db3 b/common/sql/test.db3 index d695b7d..ad367f9 100644 Binary files a/common/sql/test.db3 and b/common/sql/test.db3 differ diff --git a/fortran/client/build.sh b/fortran/client/build.sh index b25f2d5..144470e 100755 --- a/fortran/client/build.sh +++ b/fortran/client/build.sh @@ -1,2 +1,2 @@ #!/bin/sh -gfortran -fno-range-check main.f90 raylib.f90 $(pkg-config --libs --cflags raylib) -o client \ No newline at end of file +gfortran -fno-range-check main.f90 raylib.f90 $(pkg-config --libs --cflags raylib) player.f90 -o client \ No newline at end of file diff --git a/fortran/client/main.f90 b/fortran/client/main.f90 index 75cc909..a95191a 100644 --- a/fortran/client/main.f90 +++ b/fortran/client/main.f90 @@ -1,28 +1,50 @@ program main + use iso_fortran_env use iso_c_binding use raylib + use player_mod implicit none integer(c_int) :: screen_width = 800 integer(c_int) :: screen_height = 450 type(camera3d), target :: camera - type(vector3) :: npc_position - type(vector3) :: player_position - real(c_float) :: npc_dir - logical :: player_updated + type(player) :: me + type(player), dimension(:), allocatable :: players + character(len=24):: username + character(len=24):: password + integer :: i, status, in_pipe, out_pipe + logical :: player_updated, exist - ! - ! implement a login and logout screen - ! https://www.raylib.com/examples/core/loader.html?name=core_basic_screen_manager - ! https://www.raylib.com/examples/text/loader.html?name=text_input_box - ! + inquire (file="debug.log", exist=exist) + if (exist) then + open (12, file="debug.log", status="old", position="append", action="write") + else + open (12, file="debug.log", status="new", action="write") + end if - call init_window(screen_width, screen_height, "fortran client : raylib"//c_null_char) + call execute_command_line('rm fortran-mmo-in.pipe') + write(12, *) 'removed fortran-mmo-in.pipe' + call execute_command_line('rm fortran-mmo-out.pipe') + write(12, *) 'removed fortran-mmo-out.pipe' + call execute_command_line('mkfifo fortran-mmo-in.pipe && mkfifo fortran-mmo-out.pipe') + write(12, *) 'created new pipes' + call execute_command_line('nc localhost 35565 < fortran-mmo-in.pipe > fortran-mmo-out.pipe', wait=.false.) + write(12, *) 'started coms' - player_position = vector3( 0.0_c_float, 1.0_c_float, 2.0_c_float ) - npc_position = vector3( -4.0_c_float, 1.0_c_float, 0.0_c_float ) - npc_dir = 0.1_c_float + in_pipe = 13 + open (unit=in_pipe, file="fortran-mmo-in.pipe", form='formatted', access='stream', iostat=status) + write(12, *) 'fortran-mmo-in.pipe open success', status + + out_pipe = 14 + open (unit=out_pipe, file="fortran-mmo-out.pipe", form='formatted', access='stream', iostat=status) + write(12, *) 'fortran-mmo-out.pipe open success', status + + call getarg(1, username) + call getarg(2, password) + + me = player(username, vector3( 0.0_c_float, 1.0_c_float, 2.0_c_float ), PURPLE, in_pipe, out_pipe) + players = me%login(password) camera%position = vector3(0.0_c_float, 10.0_c_float, 10.0_c_float) !Camera position camera%target = vector3(0.0_c_float, 0.0_c_float, 0.0_c_float) !Camera looking at point @@ -30,51 +52,33 @@ program main camera%fovy = 45.0_c_float !Camera field - of - view Y camera%projection = CAMERA_PERSPECTIVE !Camera projection type + call init_window(screen_width, screen_height, "fortran client : raylib"//c_null_char) call set_target_fps(60_c_int) - ! - ! do login stuff here - ! - !call execute_command_line('mkfifo /tmp/fortran-mmo-in.pipe && mkfifo /tmp/fortran-mmo-out.pipe') - !Main game loop do while (.not. window_should_close()) ! Detect window close button or ESC key if (is_key_down(KEY_RIGHT)) then - player_position%x = player_position%x + 0.2_c_float + me%position%x = me%position%x + 0.2_c_float player_updated = .true. else if (is_key_down(KEY_LEFT)) then - player_position%x = player_position%x - 0.2_c_float + me%position%x = me%position%x - 0.2_c_float player_updated = .true. else if (is_key_down(KEY_DOWN)) then - player_position%z = player_position%z + 0.2_c_float + me%position%z = me%position%z + 0.2_c_float player_updated = .true. else if (is_key_down(KEY_UP)) then - player_position%z = player_position%z - 0.2_c_float + me%position%z = me%position%z - 0.2_c_float player_updated = .true. end if - camera%position%x = player_position%x - camera%position%y = player_position%y + 10.0_c_float - camera%position%z = player_position%z + 10.0_c_float - camera%target%x = player_position%x - camera%target%y = player_position%y - camera%target%z = player_position%z + call me%sync_camera(camera) - - ! if player updated - ! send new player postition to server - ! call execute_command_line('nc localhost 35565 < /tmp/fortran-mmo-in.pipe > /tmp/fortran-mmo-out.pipe') - ! else - ! send ping to server - ! read response - ! for each user in logged in - ! if (npc_position%x < -10) then - ! npc_dir = 0.1_c_float - ! else if (npc_position%x > 10) then - ! npc_dir = -0.1_c_float - ! end if - ! npc_position%x = npc_position%x + npc_dir + if (player_updated) then + players = me%move() + else + players = me%ping() + end if call begin_drawing() call clear_background(RAYWHITE) @@ -83,23 +87,21 @@ program main ! Draw floor call draw_grid(30_c_int, 1.0_c_float) - ! Draw other users - call draw_cube(npc_position, 0.5_c_float, 0.5_c_float, 0.5_c_float, GRAY) - call draw_cube_wires(npc_position, 0.5_c_float, 0.5_c_float, 0.5_c_float, DARKGRAY) - - !Draw player cube - call draw_cube(player_position, 0.5_c_float, 0.5_c_float, 0.5_c_float, PURPLE) - call draw_cube_wires(player_position, 0.5_c_float, 0.5_c_float, 0.5_c_float, DARKPURPLE) + do i=1,size(players) + call draw_cube(players(i)%position, 0.5_c_float, 0.5_c_float, 0.5_c_float, players(i)%apperance) + end do call end_mode_3d() call end_drawing() end do - ! - ! send logout call to server - ! - + players = me%logout() + deallocate(players) call close_window() !Close window and OpenGL context - call execute_command_line('rm /tmp/fortran-mmo.pipe') + close(in_pipe) + close(out_pipe) + close(12) + call execute_command_line('rm fortran-mmo-in.pipe') + call execute_command_line('rm fortran-mmo-out.pipe') -end program main \ No newline at end of file +end program main diff --git a/fortran/client/player.f90 b/fortran/client/player.f90 new file mode 100644 index 0000000..a7100e3 --- /dev/null +++ b/fortran/client/player.f90 @@ -0,0 +1,108 @@ +module player_mod + use iso_fortran_env + use iso_c_binding + use raylib + implicit none + + type player + character(len=24):: username + type(vector3) :: position + type(color) :: apperance + integer :: fifo_write + integer :: fifo_read + contains + procedure, public :: login + procedure, public :: logout + procedure, public :: ping + procedure, public :: move + procedure, non_overridable, public :: sync_camera + end type player + +contains + + type(player) function init_player(username, position, apperance, fifo_write, fifo_read) result(this) + character(24) :: username + type(vector3) :: position + type(color) :: apperance + integer :: fifo_write + integer :: fifo_read + + this%username = username + this%position = position + this%apperance = apperance + this%fifo_write = fifo_write + this%fifo_read = fifo_read + end function + + function login(this, password) result(players) + class(player) :: this + character(24) :: password + type(player), dimension(:), allocatable :: players + + players = send_packet(this, 1) + end function login + + function logout(this) result(players) + class(player) :: this + type(player), dimension(:), allocatable :: players + + players = send_packet(this, 2) + end function logout + + function ping(this) result(players) + class(player) :: this + type(player), dimension(:), allocatable :: players + + players = send_packet(this, 0) + end function ping + + function move(this) result(players) + class(player) :: this + type(player), dimension(:), allocatable :: players + + players = send_packet(this, 3) + end function move + + subroutine sync_camera(this, camera) + class(player), intent(inout) :: this + type(camera3d), intent(inout) :: camera + + camera%position%x = this%position%x + camera%position%y = this%position%y + 10.0_c_float + camera%position%z = this%position%z + 10.0_c_float + camera%target%x = this%position%x + camera%target%y = this%position%y + camera%target%z = this%position%z + end subroutine sync_camera + + function send_packet(this, request_type) result(players) + class(player) :: this + type(player), dimension(:), allocatable :: players + integer :: request_type + character(len=24) :: username + integer :: apperance_r, apperance_g, apperance_b, i, count + real(c_float) :: x_pos, y_pos + + write(this%fifo_write, "(i3, 1x, a24, 1x, f8.2, 1x, f8.2)") request_type, & + this%username, this%position%x, this%position%y + call flush(this%fifo_write) + + write(12, "(i3, 1x, a24, 1x, f8.2, 1x, f8.2)") request_type, & + this%username, this%position%x, this%position%y + + read (this%fifo_read, '(i3)') count + do i=0, count, 1 + read(this%fifo_read, "(a, i3, i3, i3, f8.2, f8.2)") username, & + apperance_r, apperance_g, apperance_b, x_pos, y_pos + + if (allocated(players)) then + players = [players, player(username, vector3( x_pos, 1.0_c_float, y_pos ), & + color(apperance_r, apperance_g, apperance_b, 255), -1, -1)] + else + players = [player(username, vector3( x_pos, 1.0_c_float, y_pos ), & + color(apperance_r, apperance_g, apperance_b, 255), -1, -1)] + end if + end do + end function send_packet + +end module player_mod diff --git a/fortran/server/README.md b/fortran/server/README.md index d137d2f..9ed5f51 100644 --- a/fortran/server/README.md +++ b/fortran/server/README.md @@ -3,10 +3,10 @@ - request - int :: request_type - - ping - - login - - logout - - move + - ping # 0 + - login # 1 + - logout # 2 + - move # 3 - str(24) :: username - double :: x_pos - double :: y_pos diff --git a/fortran/server/app/main.f90 b/fortran/server/app/main.f90 index 95cd068..462696d 100644 --- a/fortran/server/app/main.f90 +++ b/fortran/server/app/main.f90 @@ -32,6 +32,8 @@ program main ! read message from stdin read(input_unit, "(i3, 1x, a24, 1x, f8.2, 1x, f8.2)") command, username, x_pos, y_pos + write(12, "(i3, 1x, a24, 1x, f8.2, 1x, f8.2)") command, username, x_pos, y_pos + call flush(12) if (command .eq. 0) then ! get all logged in users and return their positions to client rc = db_count_logged_in_users(db) @@ -46,6 +48,8 @@ program main rc = db_get_logged_in_users(db) else ! (2) if logout update logged_in to database rc = db_logout_user(db, username) + rc = db_count_logged_in_users(db) + rc = db_get_logged_in_users(db) exit server_loop end if end do server_loop