2016-09-28 05:34:37 +00:00
# define ASIO_STANDALONE
2016-09-28 05:14:25 +00:00
# include "session.hpp"
# include "game.hpp"
# include "state/commands.hpp"
2016-10-03 20:58:52 +00:00
# include "util.hpp"
2016-09-28 05:14:25 +00:00
# include <iostream>
2016-09-30 17:03:22 +00:00
void trim ( std : : string & str )
2016-09-28 05:14:25 +00:00
{
2016-09-30 17:03:22 +00:00
const std : : string ws = " \t \r \n " ;
size_t endpos = str . find_last_not_of ( ws ) ;
if ( endpos ! = std : : string : : npos ) {
str = str . substr ( 0 , endpos + 1 ) ;
}
// trim leading spaces
size_t startpos = str . find_first_not_of ( ws ) ;
if ( startpos ! = std : : string : : npos ) {
str = str . substr ( startpos ) ;
}
}
bool Session : : parse ( std : : string s )
{
// strip leading/trailing whitespace/newlines as they are always unintional
trim ( s ) ;
std : : string token ;
2016-10-03 20:58:52 +00:00
std : : string rest ;
2016-09-30 17:03:22 +00:00
2016-10-03 20:58:52 +00:00
util : : splitIntoTokenAndRest ( s , token , rest ) ;
2016-09-30 17:03:22 +00:00
//std::cout<<"[session] token='" << token << "' rest='" << rest << "'" << std::endl;
2016-09-28 05:14:25 +00:00
2016-09-28 09:35:56 +00:00
// TODO:
// from knoc:
// ALWAYS use commands here, no direct input!
// thats important!!!!
// TODO
if ( s . size ( ) = = 1 & & s [ 0 ] = = ' q ' ) {
2016-09-28 05:14:25 +00:00
//quit
m_socket . close ( ) ;
m_state - > quitPlayer ( m_pid ) ;
return false ;
2016-09-30 17:03:22 +00:00
2016-09-28 09:35:56 +00:00
} else if ( s . size ( ) = = 1 & & s [ 0 ] = = ' c ' ) {
2016-09-28 05:14:25 +00:00
//clear
m_state - > clear ( m_pid ) ;
2016-09-30 17:03:22 +00:00
2016-09-28 09:35:56 +00:00
} else if ( s . size ( ) > = 3 & & s [ 0 ] = = ' n ' & & s [ 1 ] = = ' ' ) {
2016-09-28 05:14:25 +00:00
//set name
m_state - > setName ( m_pid , s . substr ( 2 ) ) ;
2016-09-30 17:03:22 +00:00
2016-09-28 09:35:56 +00:00
} else if ( s . size ( ) > = 3 & & s [ 0 ] = = ' v ' & & s [ 1 ] = = ' ' ) {
2016-09-28 05:14:25 +00:00
//set speed
double speed = atof ( s . substr ( 2 ) . c_str ( ) ) ;
m_state - > setSpeed ( m_pid , speed ) ;
2016-09-30 17:03:22 +00:00
} else if ( token = = " dev " ) {
m_state - > commandForPlayer ( m_pid , new game : : DeveloperCommand ( rest ) ) ;
2016-09-28 09:35:56 +00:00
} else {
2016-09-28 05:14:25 +00:00
//shoot
double angle = atof ( s . c_str ( ) ) ;
m_state - > commandForPlayer ( m_pid , new game : : ShootCommand ( angle ) ) ;
}
2016-09-30 17:03:22 +00:00
2016-09-28 05:14:25 +00:00
return true ;
}
void Session : : start ( )
{
if ( m_started ) return ;
m_started = true ;
m_pid = m_state - > addPlayer ( ) ;
2016-09-28 09:35:56 +00:00
char hello [ ] = " \n Weclome to KlassischeKeplerKriege v0.1 \n Use \" n name \" to change name, \" v velocity \" to change velocity, \" c \" to clear past shots or \" q \" to close the connection. \n Everything else is interpreted as a shooting angle. \n \n > " ;
2016-09-28 05:14:25 +00:00
do_write ( hello , strlen ( hello ) ) ;
}
void Session : : do_read ( )
{
auto self ( shared_from_this ( ) ) ;
2016-09-28 09:35:56 +00:00
m_socket . async_read_some (
asio : : buffer ( m_rcv_data , max_length ) ,
[ this , self ] ( std : : error_code ec , std : : size_t length )
2016-09-28 05:14:25 +00:00
{
2016-09-28 09:35:56 +00:00
if ( ! ec ) {
std : : string s ( m_rcv_data , length ) ;
if ( parse ( s ) ) {
char c [ ] = " > " ;
do_write ( c , strlen ( c ) ) ;
}
2016-09-28 05:14:25 +00:00
}
2016-09-28 09:35:56 +00:00
} ) ;
2016-09-28 05:14:25 +00:00
}
void Session : : do_write ( char m_snd_data [ ] , std : : size_t length )
{
auto self ( shared_from_this ( ) ) ;
asio : : async_write ( m_socket , asio : : buffer ( m_snd_data , length ) ,
2016-09-28 09:35:56 +00:00
[ this , self ] ( std : : error_code ec , std : : size_t /*length*/ )
2016-09-28 05:14:25 +00:00
{
2016-09-28 09:35:56 +00:00
if ( ! ec ) {
do_read ( ) ;
}
} ) ;
2016-09-28 05:14:25 +00:00
}