From b0c551bd07e6bd58ff2603def53c2902da4e70b4 Mon Sep 17 00:00:00 2001 From: zongor Date: Sun, 8 Oct 2023 11:54:21 -0400 Subject: [PATCH] add tcp client/server --- .gitignore | 2 + common/sql/test.db3 | Bin 8192 -> 8192 bytes fortran/client/app/main.f90 | 14 +- fortran/client/fpm.toml | 1 + fortran/client/src/player.f90 | 196 ++++++++------ fortran/server/.test.sh.swp | Bin 0 -> 12288 bytes fortran/server/app/main.f90 | 89 +++--- fortran/server/src/db.f90 | 492 ++++++++++++++++++---------------- fortran/server/test.sh | 3 +- 9 files changed, 443 insertions(+), 354 deletions(-) create mode 100644 fortran/server/.test.sh.swp diff --git a/.gitignore b/.gitignore index e943571..9fa917e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ a.out *.mod *.log +*.~undo-tree~ +*.*~ build/ fortran/client/client diff --git a/common/sql/test.db3 b/common/sql/test.db3 index ad367f9ba8d5071b8f0bbc23f994af39d9359541..5d766a5d12b2982e3f06f2d9968fc48d490e7aca 100644 GIT binary patch delta 88 zcmZp0XmFSy&B!`Y#+jd$K`-k9F9QPuBflI2zuaa)fen0<<@jH)JYe8|0OXzIpBTWd prozb0Ag(M2BE=b*m^e5%Sdudmvx^Lkj7?0F7#1+RO8Mu(0RVAJ6jlHL delta 88 zcmZp0XmFSy&B#1a#+jd)K`-qUF9QPuBflI2zuaa)fen0<<@jH)++yIr1>~LNpBTWd prozb0Ag;{F#KghD$&#Frm|bM3l~|mT2EvX>3=0@urTp{Y005(47Ty2= diff --git a/fortran/client/app/main.f90 b/fortran/client/app/main.f90 index ac996b7..f36774d 100644 --- a/fortran/client/app/main.f90 +++ b/fortran/client/app/main.f90 @@ -27,7 +27,7 @@ program main call getarg(2, password) me = player(username, vector3( 0.0_c_float, 1.0_c_float, 2.0_c_float ), PURPLE) - !players = me%login(password) + 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 @@ -58,9 +58,9 @@ program main call me%sync_camera(camera) if (player_updated) then - !players = me%move() + players = me%move() else - !players = me%ping() + players = me%ping() end if call begin_drawing() @@ -71,15 +71,15 @@ program main call draw_grid(30_c_int, 1.0_c_float) call draw_cube(me%position, 0.5_c_float, 0.5_c_float, 0.5_c_float, me%apperance) - !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 + 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 - !players = me%logout() + players = me%logout() if (allocated(players)) then deallocate(players) end if diff --git a/fortran/client/fpm.toml b/fortran/client/fpm.toml index c7e5650..508f25a 100644 --- a/fortran/client/fpm.toml +++ b/fortran/client/fpm.toml @@ -16,3 +16,4 @@ library = false implicit-typing = false implicit-external = false source-form = "free" +[dependencies] \ No newline at end of file diff --git a/fortran/client/src/player.f90 b/fortran/client/src/player.f90 index 05fb28d..d479e2f 100644 --- a/fortran/client/src/player.f90 +++ b/fortran/client/src/player.f90 @@ -1,67 +1,69 @@ module player_mod - use iso_fortran_env - use iso_c_binding - use raylib - use mod_dill, only: ipaddr, ipaddr_remote, IPADDR_IPV4, mrecv, msend, tcp_connect, & - suffix_attach - implicit none + use iso_fortran_env + use iso_c_binding + use raylib + use mod_dill, only: ipaddr, ipaddr_remote, IPADDR_IPV4, mrecv, msend, tcp_connect, & + suffix_attach + implicit none - type player - character(len=24):: username - type(vector3) :: position - type(color) :: apperance - contains - procedure, public :: login - procedure, public :: logout - procedure, public :: ping - procedure, public :: move - procedure, non_overridable, public :: sync_camera - end type player + type player + character(len=24):: username + type(vector3) :: position + type(color) :: apperance + 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 + 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 - end function + this%username = username + this%position = position + this%apperance = apperance + end function - function login(this, password) result(players) - class(player) :: this - character(24) :: password - type(player), dimension(:), allocatable :: players + 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 + print *, password - function logout(this) result(players) - class(player) :: this - type(player), dimension(:), allocatable :: players + players = send_packet(this, 1) + end function login - players = send_packet(this, 2) - end function logout + function logout(this) result(players) + class(player) :: this + type(player), dimension(:), allocatable :: players - function ping(this) result(players) - class(player) :: this - type(player), dimension(:), allocatable :: players + players = send_packet(this, 2) + end function logout - players = send_packet(this, 0) - end function ping + function ping(this) result(players) + class(player) :: this + type(player), dimension(:), allocatable :: players - function move(this) result(players) - class(player) :: this - type(player), dimension(:), allocatable :: players + players = send_packet(this, 0) + end function ping - players = send_packet(this, 3) - end function move + function move(this) result(players) + class(player) :: this + type(player), dimension(:), allocatable :: players - subroutine sync_camera(this, camera) + players = send_packet(this, 3) + end function move + + subroutine sync_camera(this, camera) class(player), intent(inout) :: this type(camera3d), intent(inout) :: camera @@ -71,47 +73,77 @@ contains camera%target%x = this%position%x camera%target%y = this%position%y camera%target%z = this%position%z - end subroutine sync_camera + 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 + 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 - integer(c_int) :: rc, connection - integer(c_size_t) :: message_size, msglen = 256 - type(ipaddr) :: addr - character(c_char) :: message(256) = '' - character(len=*), parameter :: TCP_SUFFIX = c_carriage_return // c_new_line // c_null_char + integer(c_int) :: rc, connection + integer(c_size_t) :: message_size, msglen = 256 + type(ipaddr) :: addr + character(c_char) :: message(256) = '' + character(len=256) :: f_message + character(len=*), parameter :: TCP_SUFFIX = c_carriage_return//c_new_line//c_null_char - rc = ipaddr_remote(addr, '127.0.0.1' // c_null_char, 35565_c_int, IPADDR_IPV4, -1_c_int64_t) - connection = tcp_connect(addr, -1_c_int64_t) - connection = suffix_attach(connection, TCP_SUFFIX, 2_c_size_t) + rc = ipaddr_remote(addr, '127.0.0.1'//c_null_char, 5555_c_int, IPADDR_IPV4, -1_c_int64_t) + connection = tcp_connect(addr, -1_c_int64_t) + connection = suffix_attach(connection, TCP_SUFFIX, 2_c_size_t) - write(message, "(i3, 1x, a24, 1x, f8.2, 1x, f8.2)") request_type, & - this%username, this%position%x, this%position%y + write (f_message, "(f8.2, f8.2, i3, a24)") & + this%position%x, this%position%y, request_type, this%username - rc = msend(connection, message(Len_Trim(message)), transfer(Len_Trim(message), 0_c_size_t), -1_c_int64_t) + print *, f_c_string(f_message, .true.) - message_size = mrecv(connection, message, msglen, -1_c_int64_t) - read (message(:message_size), '(i3)') count - do i=0, count, 1 - message_size = mrecv(connection, message, msglen, -1_c_int64_t) + rc = msend(connection, f_c_string(f_message, .true.), & + transfer(Len_Trim(f_c_string(f_message, .true.)), 0_c_size_t), -1_c_int64_t) - read(message, "(a, i3, i3, i3, f8.2, f8.2)") username, & - apperance_r, apperance_g, apperance_b, x_pos, y_pos + message_size = mrecv(connection, message, msglen, -1_c_int64_t) + print *, 'recv message: ', message(:message_size) + read (message(:message_size), '(i3)') count - 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))] - else - players = [player(username, vector3( x_pos, 1.0_c_float, y_pos ), & - color(apperance_r, apperance_g, apperance_b, 255))] - end if - end do + print *, count + do i = 0, count, 1 + message_size = mrecv(connection, message, msglen, -1_c_int64_t) + + read (message(:message_size), "(i3, i3, i3, f8.2, f8.2, a24)") & + apperance_r, apperance_g, apperance_b, x_pos, y_pos, username + + 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))] + else + players = [player(username, vector3(x_pos, 1.0_c_float, y_pos), & + color(apperance_r, apperance_g, apperance_b, 255))] + end if + end do end function send_packet + ! from ivanpribec `https://fortran-lang.discourse.group/t/best-practices-for-passing-c-strings/104/12` + function f_c_string(string, trim) + use, intrinsic :: iso_c_binding, only: c_char, c_null_char + implicit none + character(len=*), intent(in) :: string + logical, intent(in), optional :: trim + + character(kind=c_char, len=:), allocatable :: f_c_string + logical :: trim_ + + trim_ = .true. + if (present(trim)) trim_ = trim + + block + intrinsic trim + if (trim_) then + f_c_string = trim(string)//c_null_char + else + f_c_string = string//c_null_char + end if + end block + end function + end module player_mod diff --git a/fortran/server/.test.sh.swp b/fortran/server/.test.sh.swp new file mode 100644 index 0000000000000000000000000000000000000000..f528278e48adb7bcbfd9dab38776cfe499e8da89 GIT binary patch literal 12288 zcmeI&Jx;?g6bJCvG9U&7f(tlwsDzZbZ4?AYU|=j_O&pgNk~lanLx&=`3n$_L+=3C| zG|9pcsa>i_e=E_GKVtd)qzqABG`hdNV>jN2Y&#`7eE5yOCVe{kAX=&HQR#A`y*l`svk-v576MB%bFYu5 z{$#v))dv?2J3pIlu>qDs00Izz00bZa0SG_<0$mp{d5_*~68$=ngF5#9#kz|C0SG_< z0uX=z1Rwwb2tWV=5P(1j1;Uu<{e