add server protocol, add test
This commit is contained in:
parent
79859bbec7
commit
0336cfaeb3
|
@ -8,9 +8,6 @@
|
|||
- logout
|
||||
- move
|
||||
- str(24) :: username
|
||||
- int :: timestamp
|
||||
- str(?) :: data
|
||||
- int :: data_length
|
||||
- double :: x_pos
|
||||
- double :: y_pos
|
||||
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
program main
|
||||
use, intrinsic :: iso_c_binding
|
||||
use iso_fortran_env
|
||||
use :: sqlite3
|
||||
use, intrinsic :: iso_c_binding
|
||||
use db
|
||||
implicit none
|
||||
|
||||
|
||||
character, dimension(:), allocatable :: form_data
|
||||
type(db_type) :: db
|
||||
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
|
||||
|
||||
inquire (file="debug.log", exist=exist)
|
||||
|
@ -18,20 +19,38 @@ program main
|
|||
open (12, file="debug.log", status="new", action="write")
|
||||
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
|
||||
server_loop: do
|
||||
|
||||
! 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
|
||||
|
||||
! if logout update logged_in to database
|
||||
|
||||
! end do
|
||||
|
||||
! send logout all to clients
|
||||
|
||||
contains
|
||||
rc = db_close(db)
|
||||
close(12)
|
||||
|
||||
end program main
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
! db.f90
|
||||
module db
|
||||
!! Database abstraction layer.
|
||||
use iso_fortran_env
|
||||
use, intrinsic :: iso_c_binding
|
||||
use :: sqlite3
|
||||
implicit none
|
||||
|
@ -16,7 +16,11 @@ module db
|
|||
public :: db_open
|
||||
public :: db_create_users
|
||||
public :: db_get_logged_in_users
|
||||
public :: db_count_logged_in_users
|
||||
public :: db_add_user
|
||||
public :: db_login_user
|
||||
public :: db_logout_user
|
||||
public :: db_move_user
|
||||
public :: db_delete_user
|
||||
|
||||
private :: db_error
|
||||
|
@ -137,16 +141,48 @@ contains
|
|||
call db_error(rc, 'sqlite3_finalize()')
|
||||
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)
|
||||
!! Prints number of courses per student to standard output.
|
||||
type(db_type), intent(inout) :: db
|
||||
|
||||
type(c_ptr) :: stmt
|
||||
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, &
|
||||
"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)
|
||||
call db_error(rc, 'sqlite3_prepare_v2()')
|
||||
|
||||
|
@ -156,9 +192,13 @@ contains
|
|||
select case (rc)
|
||||
case (SQLITE_ROW)
|
||||
username = sqlite3_column_text(stmt, 0)
|
||||
x_pos = sqlite3_column_double(stmt, 1)
|
||||
y_pos = sqlite3_column_double(stmt, 1)
|
||||
write(12, *) username, x_pos, y_pos
|
||||
apperance_r = sqlite3_column_int(stmt, 1)
|
||||
apperance_g = sqlite3_column_int(stmt, 2)
|
||||
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)
|
||||
exit step_loop
|
||||
|
@ -173,6 +213,69 @@ contains
|
|||
call db_error(rc, 'sqlite3_finalize()')
|
||||
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)
|
||||
!! Prints error message.
|
||||
integer, intent(in) :: code
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#!/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
|
||||
module db
|
||||
!! Database abstraction layer.
|
||||
use iso_fortran_env
|
||||
use, intrinsic :: iso_c_binding
|
||||
use :: sqlite3
|
||||
implicit none
|
||||
|
@ -16,7 +16,11 @@ module db
|
|||
public :: db_open
|
||||
public :: db_create_users
|
||||
public :: db_get_logged_in_users
|
||||
public :: db_count_logged_in_users
|
||||
public :: db_add_user
|
||||
public :: db_login_user
|
||||
public :: db_logout_user
|
||||
public :: db_move_user
|
||||
public :: db_delete_user
|
||||
|
||||
private :: db_error
|
||||
|
@ -137,16 +141,48 @@ contains
|
|||
call db_error(rc, 'sqlite3_finalize()')
|
||||
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)
|
||||
!! Prints number of courses per student to standard output.
|
||||
type(db_type), intent(inout) :: db
|
||||
|
||||
type(c_ptr) :: stmt
|
||||
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, &
|
||||
"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)
|
||||
call db_error(rc, 'sqlite3_prepare_v2()')
|
||||
|
||||
|
@ -156,9 +192,13 @@ contains
|
|||
select case (rc)
|
||||
case (SQLITE_ROW)
|
||||
username = sqlite3_column_text(stmt, 0)
|
||||
x_pos = sqlite3_column_double(stmt, 1)
|
||||
y_pos = sqlite3_column_double(stmt, 1)
|
||||
write(12, *) username, x_pos, y_pos
|
||||
apperance_r = sqlite3_column_int(stmt, 1)
|
||||
apperance_g = sqlite3_column_int(stmt, 2)
|
||||
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)
|
||||
exit step_loop
|
||||
|
@ -173,6 +213,69 @@ contains
|
|||
call db_error(rc, 'sqlite3_finalize()')
|
||||
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)
|
||||
!! Prints error message.
|
||||
integer, intent(in) :: code
|
||||
|
|
Loading…
Reference in New Issue