add server protocol, add test
This commit is contained in:
parent
79859bbec7
commit
0336cfaeb3
|
@ -8,9 +8,6 @@
|
||||||
- logout
|
- logout
|
||||||
- move
|
- move
|
||||||
- str(24) :: username
|
- str(24) :: username
|
||||||
- int :: timestamp
|
|
||||||
- str(?) :: data
|
|
||||||
- int :: data_length
|
|
||||||
- double :: x_pos
|
- double :: x_pos
|
||||||
- double :: y_pos
|
- double :: y_pos
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
program main
|
program main
|
||||||
use, intrinsic :: iso_c_binding
|
|
||||||
use iso_fortran_env
|
use iso_fortran_env
|
||||||
use :: sqlite3
|
use, intrinsic :: iso_c_binding
|
||||||
use db
|
use db
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
|
type(db_type) :: db
|
||||||
character, dimension(:), allocatable :: form_data
|
|
||||||
character(len=128):: db_path
|
character(len=128):: db_path
|
||||||
integer :: err, i, length
|
character(len=24):: username
|
||||||
|
real(kind=c_double) :: x_pos
|
||||||
|
real(kind=c_double) :: y_pos
|
||||||
|
integer :: command, rc
|
||||||
logical :: exist
|
logical :: exist
|
||||||
|
|
||||||
inquire (file="debug.log", exist=exist)
|
inquire (file="debug.log", exist=exist)
|
||||||
|
@ -18,20 +19,38 @@ program main
|
||||||
open (12, file="debug.log", status="new", action="write")
|
open (12, file="debug.log", status="new", action="write")
|
||||||
end if
|
end if
|
||||||
|
|
||||||
|
call getarg(1, db_path)
|
||||||
|
|
||||||
|
inquire (file=db_path(:Len_Trim(db_path)), exist=exist)
|
||||||
|
if (.not. exist) then
|
||||||
|
stop 1
|
||||||
|
end if
|
||||||
|
|
||||||
|
rc = db_open(db, db_path(:Len_Trim(db_path)))
|
||||||
! do while not logged out
|
! do while not logged out
|
||||||
|
server_loop: do
|
||||||
|
|
||||||
! read message from stdin
|
! read message from stdin
|
||||||
|
read(input_unit, "(i3, 1x, a24, 1x, f8.2, 1x, f8.2)") command, username, x_pos, y_pos
|
||||||
|
|
||||||
! if ping then get all logged in users and return their positions to client
|
if (command .eq. 0) then ! get all logged in users and return their positions to client
|
||||||
|
rc = db_count_logged_in_users(db)
|
||||||
|
rc = db_get_logged_in_users(db)
|
||||||
|
else if (command .eq. 1) then
|
||||||
|
rc = db_login_user(db, username)
|
||||||
|
rc = db_count_logged_in_users(db)
|
||||||
|
rc = db_get_logged_in_users(db)
|
||||||
|
else if (command .eq. 3) then ! update new pos to database
|
||||||
|
rc = db_move_user(db, username, x_pos, y_pos)
|
||||||
|
rc = db_count_logged_in_users(db)
|
||||||
|
rc = db_get_logged_in_users(db)
|
||||||
|
else ! (2) if logout update logged_in to database
|
||||||
|
rc = db_logout_user(db, username)
|
||||||
|
exit server_loop
|
||||||
|
end if
|
||||||
|
end do server_loop
|
||||||
|
|
||||||
! if move update new pos to database
|
rc = db_close(db)
|
||||||
|
close(12)
|
||||||
! if logout update logged_in to database
|
|
||||||
|
|
||||||
! end do
|
|
||||||
|
|
||||||
! send logout all to clients
|
|
||||||
|
|
||||||
contains
|
|
||||||
|
|
||||||
end program main
|
end program main
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
! db.f90
|
! db.f90
|
||||||
module db
|
module db
|
||||||
!! Database abstraction layer.
|
use iso_fortran_env
|
||||||
use, intrinsic :: iso_c_binding
|
use, intrinsic :: iso_c_binding
|
||||||
use :: sqlite3
|
use :: sqlite3
|
||||||
implicit none
|
implicit none
|
||||||
|
@ -16,7 +16,11 @@ module db
|
||||||
public :: db_open
|
public :: db_open
|
||||||
public :: db_create_users
|
public :: db_create_users
|
||||||
public :: db_get_logged_in_users
|
public :: db_get_logged_in_users
|
||||||
|
public :: db_count_logged_in_users
|
||||||
public :: db_add_user
|
public :: db_add_user
|
||||||
|
public :: db_login_user
|
||||||
|
public :: db_logout_user
|
||||||
|
public :: db_move_user
|
||||||
public :: db_delete_user
|
public :: db_delete_user
|
||||||
|
|
||||||
private :: db_error
|
private :: db_error
|
||||||
|
@ -137,16 +141,48 @@ contains
|
||||||
call db_error(rc, 'sqlite3_finalize()')
|
call db_error(rc, 'sqlite3_finalize()')
|
||||||
end function db_delete_user
|
end function db_delete_user
|
||||||
|
|
||||||
|
integer function db_count_logged_in_users(db) result(rc)
|
||||||
|
!! Prints number of courses per student to standard output.
|
||||||
|
type(db_type), intent(inout) :: db
|
||||||
|
|
||||||
|
type(c_ptr) :: stmt
|
||||||
|
integer :: count
|
||||||
|
|
||||||
|
rc = sqlite3_prepare_v2(db%ptr, "SELECT count(logged_in) FROM users u WHERE u.logged_in = 1;", stmt)
|
||||||
|
call db_error(rc, 'sqlite3_prepare_v2()')
|
||||||
|
|
||||||
|
step_loop: do
|
||||||
|
rc = sqlite3_step(stmt)
|
||||||
|
|
||||||
|
select case (rc)
|
||||||
|
case (SQLITE_ROW)
|
||||||
|
count = sqlite3_column_int(stmt, 0)
|
||||||
|
write(output_unit, "(i0)") count
|
||||||
|
|
||||||
|
case (SQLITE_DONE)
|
||||||
|
exit step_loop
|
||||||
|
|
||||||
|
case default
|
||||||
|
call db_error(rc, 'sqlite3_step()')
|
||||||
|
exit step_loop
|
||||||
|
end select
|
||||||
|
end do step_loop
|
||||||
|
|
||||||
|
rc = sqlite3_finalize(stmt)
|
||||||
|
call db_error(rc, 'sqlite3_finalize()')
|
||||||
|
end function db_count_logged_in_users
|
||||||
|
|
||||||
integer function db_get_logged_in_users(db) result(rc)
|
integer function db_get_logged_in_users(db) result(rc)
|
||||||
!! Prints number of courses per student to standard output.
|
!! Prints number of courses per student to standard output.
|
||||||
type(db_type), intent(inout) :: db
|
type(db_type), intent(inout) :: db
|
||||||
|
|
||||||
type(c_ptr) :: stmt
|
type(c_ptr) :: stmt
|
||||||
character(len=24) :: username
|
character(len=24) :: username
|
||||||
real(kind=c_double) :: x_pos, y_pos
|
integer :: apperance_r, apperance_g, apperance_b
|
||||||
|
real :: x_pos, y_pos
|
||||||
|
|
||||||
rc = sqlite3_prepare_v2(db%ptr, &
|
rc = sqlite3_prepare_v2(db%ptr, &
|
||||||
"SELECT username, x_pos, y_pos " // &
|
"SELECT username, apperance_r, apperance_g, apperance_b, x_pos, y_pos " // &
|
||||||
"FROM users u WHERE u.logged_in = 1;", stmt)
|
"FROM users u WHERE u.logged_in = 1;", stmt)
|
||||||
call db_error(rc, 'sqlite3_prepare_v2()')
|
call db_error(rc, 'sqlite3_prepare_v2()')
|
||||||
|
|
||||||
|
@ -156,9 +192,13 @@ contains
|
||||||
select case (rc)
|
select case (rc)
|
||||||
case (SQLITE_ROW)
|
case (SQLITE_ROW)
|
||||||
username = sqlite3_column_text(stmt, 0)
|
username = sqlite3_column_text(stmt, 0)
|
||||||
x_pos = sqlite3_column_double(stmt, 1)
|
apperance_r = sqlite3_column_int(stmt, 1)
|
||||||
y_pos = sqlite3_column_double(stmt, 1)
|
apperance_g = sqlite3_column_int(stmt, 2)
|
||||||
write(12, *) username, x_pos, y_pos
|
apperance_b = sqlite3_column_int(stmt, 3)
|
||||||
|
x_pos = sqlite3_column_double(stmt, 4)
|
||||||
|
y_pos = sqlite3_column_double(stmt, 5)
|
||||||
|
write(output_unit, "(a24, 1x, i3, 1x, i3, 1x, i3, 1x, f8.2, 1x, f8.2)") username(:Len_Trim(username)), &
|
||||||
|
apperance_r, apperance_g, apperance_b, x_pos, y_pos
|
||||||
|
|
||||||
case (SQLITE_DONE)
|
case (SQLITE_DONE)
|
||||||
exit step_loop
|
exit step_loop
|
||||||
|
@ -173,6 +213,69 @@ contains
|
||||||
call db_error(rc, 'sqlite3_finalize()')
|
call db_error(rc, 'sqlite3_finalize()')
|
||||||
end function db_get_logged_in_users
|
end function db_get_logged_in_users
|
||||||
|
|
||||||
|
integer function db_login_user(db, username) result(rc)
|
||||||
|
type(db_type), intent(inout) :: db
|
||||||
|
character(len=24), intent(in) :: username
|
||||||
|
type(c_ptr) :: stmt
|
||||||
|
|
||||||
|
rc = sqlite3_prepare_v2(db%ptr, &
|
||||||
|
"UPDATE users SET logged_in = 1 WHERE users.username = ?;", stmt)
|
||||||
|
call db_error(rc, 'sqlite3_prepare_v2()')
|
||||||
|
|
||||||
|
rc = sqlite3_bind_text(stmt, 1, username)
|
||||||
|
call db_error(rc, 'sqlite3_bind_text()')
|
||||||
|
|
||||||
|
rc = sqlite3_step(stmt)
|
||||||
|
call db_error(rc, 'sqlite3_step()')
|
||||||
|
|
||||||
|
rc = sqlite3_finalize(stmt)
|
||||||
|
call db_error(rc, 'sqlite3_finalize()')
|
||||||
|
end function db_login_user
|
||||||
|
|
||||||
|
integer function db_logout_user(db, username) result(rc)
|
||||||
|
type(db_type), intent(inout) :: db
|
||||||
|
character(len=24), intent(in) :: username
|
||||||
|
type(c_ptr) :: stmt
|
||||||
|
|
||||||
|
rc = sqlite3_prepare_v2(db%ptr, &
|
||||||
|
"UPDATE users SET logged_in = 0 WHERE users.username = ?;", stmt)
|
||||||
|
call db_error(rc, 'sqlite3_prepare_v2()')
|
||||||
|
|
||||||
|
rc = sqlite3_bind_text(stmt, 1, username)
|
||||||
|
call db_error(rc, 'sqlite3_bind_text()')
|
||||||
|
|
||||||
|
rc = sqlite3_step(stmt)
|
||||||
|
call db_error(rc, 'sqlite3_step()')
|
||||||
|
|
||||||
|
rc = sqlite3_finalize(stmt)
|
||||||
|
call db_error(rc, 'sqlite3_finalize()')
|
||||||
|
end function db_logout_user
|
||||||
|
|
||||||
|
integer function db_move_user(db, username, x_pos, y_pos) result(rc)
|
||||||
|
type(db_type), intent(inout) :: db
|
||||||
|
character(len=24), intent(in) :: username
|
||||||
|
real(kind=c_double), intent(in) :: x_pos
|
||||||
|
real(kind=c_double), intent(in) :: y_pos
|
||||||
|
type(c_ptr) :: stmt
|
||||||
|
|
||||||
|
rc = sqlite3_prepare_v2(db%ptr, &
|
||||||
|
"UPDATE users SET x_pos = ?, y_pos = ? WHERE users.username = ?;", stmt)
|
||||||
|
call db_error(rc, 'sqlite3_prepare_v2()')
|
||||||
|
|
||||||
|
rc = sqlite3_bind_double(stmt, 1, x_pos)
|
||||||
|
call db_error(rc, 'sqlite3_bind_double()')
|
||||||
|
rc = sqlite3_bind_double(stmt, 2, y_pos)
|
||||||
|
call db_error(rc, 'sqlite3_bind_double()')
|
||||||
|
rc = sqlite3_bind_text(stmt, 3, username)
|
||||||
|
call db_error(rc, 'sqlite3_bind_text()')
|
||||||
|
|
||||||
|
rc = sqlite3_step(stmt)
|
||||||
|
call db_error(rc, 'sqlite3_step()')
|
||||||
|
|
||||||
|
rc = sqlite3_finalize(stmt)
|
||||||
|
call db_error(rc, 'sqlite3_finalize()')
|
||||||
|
end function db_move_user
|
||||||
|
|
||||||
subroutine db_error(code, proc, err_msg)
|
subroutine db_error(code, proc, err_msg)
|
||||||
!! Prints error message.
|
!! Prints error message.
|
||||||
integer, intent(in) :: code
|
integer, intent(in) :: code
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
listen1 'tcp!*!1234' ~/.local/bin/fortran-micro-httpd ../../common/html/index.html ../../common/sql/test.db3
|
listen1 'tcp!*!35565' ~/.local/bin/fortran-mmo-server ../../common/sql/test.db3
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
program main
|
||||||
|
use iso_fortran_env
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
write(output_unit, "(i3, 1x, a24, 1x, f8.2, 1x, f8.2)") 0, 'chakr', 0.0, 0.0
|
||||||
|
|
||||||
|
end program main
|
|
@ -1,6 +1,6 @@
|
||||||
! db.f90
|
! db.f90
|
||||||
module db
|
module db
|
||||||
!! Database abstraction layer.
|
use iso_fortran_env
|
||||||
use, intrinsic :: iso_c_binding
|
use, intrinsic :: iso_c_binding
|
||||||
use :: sqlite3
|
use :: sqlite3
|
||||||
implicit none
|
implicit none
|
||||||
|
@ -16,7 +16,11 @@ module db
|
||||||
public :: db_open
|
public :: db_open
|
||||||
public :: db_create_users
|
public :: db_create_users
|
||||||
public :: db_get_logged_in_users
|
public :: db_get_logged_in_users
|
||||||
|
public :: db_count_logged_in_users
|
||||||
public :: db_add_user
|
public :: db_add_user
|
||||||
|
public :: db_login_user
|
||||||
|
public :: db_logout_user
|
||||||
|
public :: db_move_user
|
||||||
public :: db_delete_user
|
public :: db_delete_user
|
||||||
|
|
||||||
private :: db_error
|
private :: db_error
|
||||||
|
@ -137,16 +141,48 @@ contains
|
||||||
call db_error(rc, 'sqlite3_finalize()')
|
call db_error(rc, 'sqlite3_finalize()')
|
||||||
end function db_delete_user
|
end function db_delete_user
|
||||||
|
|
||||||
|
integer function db_count_logged_in_users(db) result(rc)
|
||||||
|
!! Prints number of courses per student to standard output.
|
||||||
|
type(db_type), intent(inout) :: db
|
||||||
|
|
||||||
|
type(c_ptr) :: stmt
|
||||||
|
integer :: count
|
||||||
|
|
||||||
|
rc = sqlite3_prepare_v2(db%ptr, "SELECT count(logged_in) FROM users u WHERE u.logged_in = 1;", stmt)
|
||||||
|
call db_error(rc, 'sqlite3_prepare_v2()')
|
||||||
|
|
||||||
|
step_loop: do
|
||||||
|
rc = sqlite3_step(stmt)
|
||||||
|
|
||||||
|
select case (rc)
|
||||||
|
case (SQLITE_ROW)
|
||||||
|
count = sqlite3_column_int(stmt, 0)
|
||||||
|
write(output_unit, "(i0)") count
|
||||||
|
|
||||||
|
case (SQLITE_DONE)
|
||||||
|
exit step_loop
|
||||||
|
|
||||||
|
case default
|
||||||
|
call db_error(rc, 'sqlite3_step()')
|
||||||
|
exit step_loop
|
||||||
|
end select
|
||||||
|
end do step_loop
|
||||||
|
|
||||||
|
rc = sqlite3_finalize(stmt)
|
||||||
|
call db_error(rc, 'sqlite3_finalize()')
|
||||||
|
end function db_count_logged_in_users
|
||||||
|
|
||||||
integer function db_get_logged_in_users(db) result(rc)
|
integer function db_get_logged_in_users(db) result(rc)
|
||||||
!! Prints number of courses per student to standard output.
|
!! Prints number of courses per student to standard output.
|
||||||
type(db_type), intent(inout) :: db
|
type(db_type), intent(inout) :: db
|
||||||
|
|
||||||
type(c_ptr) :: stmt
|
type(c_ptr) :: stmt
|
||||||
character(len=24) :: username
|
character(len=24) :: username
|
||||||
real(kind=c_double) :: x_pos, y_pos
|
integer :: apperance_r, apperance_g, apperance_b
|
||||||
|
real :: x_pos, y_pos
|
||||||
|
|
||||||
rc = sqlite3_prepare_v2(db%ptr, &
|
rc = sqlite3_prepare_v2(db%ptr, &
|
||||||
"SELECT username, x_pos, y_pos " // &
|
"SELECT username, apperance_r, apperance_g, apperance_b, x_pos, y_pos " // &
|
||||||
"FROM users u WHERE u.logged_in = 1;", stmt)
|
"FROM users u WHERE u.logged_in = 1;", stmt)
|
||||||
call db_error(rc, 'sqlite3_prepare_v2()')
|
call db_error(rc, 'sqlite3_prepare_v2()')
|
||||||
|
|
||||||
|
@ -156,9 +192,13 @@ contains
|
||||||
select case (rc)
|
select case (rc)
|
||||||
case (SQLITE_ROW)
|
case (SQLITE_ROW)
|
||||||
username = sqlite3_column_text(stmt, 0)
|
username = sqlite3_column_text(stmt, 0)
|
||||||
x_pos = sqlite3_column_double(stmt, 1)
|
apperance_r = sqlite3_column_int(stmt, 1)
|
||||||
y_pos = sqlite3_column_double(stmt, 1)
|
apperance_g = sqlite3_column_int(stmt, 2)
|
||||||
write(12, *) username, x_pos, y_pos
|
apperance_b = sqlite3_column_int(stmt, 3)
|
||||||
|
x_pos = sqlite3_column_double(stmt, 4)
|
||||||
|
y_pos = sqlite3_column_double(stmt, 5)
|
||||||
|
write(output_unit, "(a24, i3, i3, i3, f8.2, f8.2)") username(:Len_Trim(username)), &
|
||||||
|
apperance_r, apperance_g, apperance_b, x_pos, y_pos
|
||||||
|
|
||||||
case (SQLITE_DONE)
|
case (SQLITE_DONE)
|
||||||
exit step_loop
|
exit step_loop
|
||||||
|
@ -173,6 +213,69 @@ contains
|
||||||
call db_error(rc, 'sqlite3_finalize()')
|
call db_error(rc, 'sqlite3_finalize()')
|
||||||
end function db_get_logged_in_users
|
end function db_get_logged_in_users
|
||||||
|
|
||||||
|
integer function db_login_user(db, username) result(rc)
|
||||||
|
type(db_type), intent(inout) :: db
|
||||||
|
character(len=24), intent(in) :: username
|
||||||
|
type(c_ptr) :: stmt
|
||||||
|
|
||||||
|
rc = sqlite3_prepare_v2(db%ptr, &
|
||||||
|
"UPDATE users SET logged_in = 1 WHERE users.username = ?;", stmt)
|
||||||
|
call db_error(rc, 'sqlite3_prepare_v2()')
|
||||||
|
|
||||||
|
rc = sqlite3_bind_text(stmt, 1, username)
|
||||||
|
call db_error(rc, 'sqlite3_bind_text()')
|
||||||
|
|
||||||
|
rc = sqlite3_step(stmt)
|
||||||
|
call db_error(rc, 'sqlite3_step()')
|
||||||
|
|
||||||
|
rc = sqlite3_finalize(stmt)
|
||||||
|
call db_error(rc, 'sqlite3_finalize()')
|
||||||
|
end function db_login_user
|
||||||
|
|
||||||
|
integer function db_logout_user(db, username) result(rc)
|
||||||
|
type(db_type), intent(inout) :: db
|
||||||
|
character(len=24), intent(in) :: username
|
||||||
|
type(c_ptr) :: stmt
|
||||||
|
|
||||||
|
rc = sqlite3_prepare_v2(db%ptr, &
|
||||||
|
"UPDATE users SET logged_in = 0 WHERE users.username = ?;", stmt)
|
||||||
|
call db_error(rc, 'sqlite3_prepare_v2()')
|
||||||
|
|
||||||
|
rc = sqlite3_bind_text(stmt, 1, username)
|
||||||
|
call db_error(rc, 'sqlite3_bind_text()')
|
||||||
|
|
||||||
|
rc = sqlite3_step(stmt)
|
||||||
|
call db_error(rc, 'sqlite3_step()')
|
||||||
|
|
||||||
|
rc = sqlite3_finalize(stmt)
|
||||||
|
call db_error(rc, 'sqlite3_finalize()')
|
||||||
|
end function db_logout_user
|
||||||
|
|
||||||
|
integer function db_move_user(db, username, x_pos, y_pos) result(rc)
|
||||||
|
type(db_type), intent(inout) :: db
|
||||||
|
character(len=24), intent(in) :: username
|
||||||
|
real(kind=c_double), intent(in) :: x_pos
|
||||||
|
real(kind=c_double), intent(in) :: y_pos
|
||||||
|
type(c_ptr) :: stmt
|
||||||
|
|
||||||
|
rc = sqlite3_prepare_v2(db%ptr, &
|
||||||
|
"UPDATE users SET x_pos = ?, y_pos = ? WHERE users.username = ?;", stmt)
|
||||||
|
call db_error(rc, 'sqlite3_prepare_v2()')
|
||||||
|
|
||||||
|
rc = sqlite3_bind_double(stmt, 1, x_pos)
|
||||||
|
call db_error(rc, 'sqlite3_bind_double()')
|
||||||
|
rc = sqlite3_bind_double(stmt, 2, y_pos)
|
||||||
|
call db_error(rc, 'sqlite3_bind_double()')
|
||||||
|
rc = sqlite3_bind_text(stmt, 3, username)
|
||||||
|
call db_error(rc, 'sqlite3_bind_text()')
|
||||||
|
|
||||||
|
rc = sqlite3_step(stmt)
|
||||||
|
call db_error(rc, 'sqlite3_step()')
|
||||||
|
|
||||||
|
rc = sqlite3_finalize(stmt)
|
||||||
|
call db_error(rc, 'sqlite3_finalize()')
|
||||||
|
end function db_move_user
|
||||||
|
|
||||||
subroutine db_error(code, proc, err_msg)
|
subroutine db_error(code, proc, err_msg)
|
||||||
!! Prints error message.
|
!! Prints error message.
|
||||||
integer, intent(in) :: code
|
integer, intent(in) :: code
|
||||||
|
|
Loading…
Reference in New Issue