Technical notes

A forum for online playing, administration, bugs and feature requests
Post Reply
ezee
Intrepid Venturer
Intrepid Venturer
Posts: 703
Joined: Tue Feb 11, 2014 12:47 am
Location: FRANCE
Contact:

Technical notes

Post by ezee »

:!: Since i'm working actually with that part of Vegastrike ( Server + Account Server + database ) , and that i am at the core level of the VS network engine , i open this thread
to share the information that seem to me important , for future devs .

One thing that we want to know is :

WHAT THE SERVER IS DOING IN HIS MAIN LOOP ?

Netserver.cpp , line 384 :
//Server loop
while (keeprun) {
//int nb;

UpdateTime();
if (_Universe->numPlayers() > 0)
ExecuteDirector();
//Check a key press
//keyset.setReadAlwaysTrue( 0);
//this->checkKey( keyset);

//Check received communications
checkMsg( _sock_set );
if (acctserver && acct_con)
//Listen for account server answers
checkAcctMsg( _sock_set );
//And send to it the login request we received
//Then send clients confirmations or errors
curtime = getNewTime();
if (acctserver && !acct_con && (curtime-reconnect_time) > periodrecon) {
std::string netbuf;
reconnect_time = curtime+periodrecon;
//We previously lost connection to account server
//We try to reconnect

if (acct_sock)
delete acct_sock;
acct_sock = new VsnetHTTPSocket( acctsrv, _sock_set );
if ( acct_sock->valid() ) {
LI i;
int j = 0;
COUT<<">>> Reconnected accountserver on socket "<<*acct_sock<<" done."<<endl;
//Send a list of ingame clients
//Build a buffer with number of clients and client serials
//Put first the number of clients

//netbuf.addShort( nbclients);
addSimpleChar( netbuf, ACCT_RESYNC );
for (j = 0, i = allClients.begin(); i != allClients.end(); i++, j++)
//Add the current client's serial to the buffer
addSimpleString( netbuf, (*i)->callsign );
//Passing NULL to AddressIP arg because between servers -> only TCP
//Use the serial packet's field to send the number of clients
if ( !acct_sock->sendstr( netbuf ) )
COUT<<"Failure to resync, SOCKET was : "<<*acct_sock<<endl;
} else {
cerr<<">>> Reconnection to account server failed."<<endl;
}
}
//See if we have some timed out clients and disconnect them
this->checkTimedoutClients_udp();

//Remove all clients to be disconnected
LI j;
for (j = discList.begin(); j != discList.end(); j++)
disconnect( (*j), __FILE__, PSEUDO__LINE__( 328 ) );
discList.clear();
//Remove all clients that logged out
for (j = logoutList.begin(); j != logoutList.end(); j++)
this->logout( (*j) );
logoutList.clear();

/****** VS STUFF TO DO ***********/

//UPDATE STAR SYSTEM -> TO INTEGRATE WITH NETWORKING
//PROCESS JUMPS -> MAKE UNITS CHANGE THEIR STAR SYSTEM


//NETFIXME: Why was StarSystem->Update() commented out?

unsigned int i;
/*
* static float nonactivesystemtime = XMLSupport::parse_float (vs_config->getVariable ("physics","InactiveSystemTime",".3"));
* static unsigned int numrunningsystems = XMLSupport::parse_int (vs_config->getVariable ("physics","NumRunningSystems","4"));
* float systime=nonactivesystemtime;
*/
for (i = 0; i < _Universe->star_system.size(); i++)
//NETFIXME: No Director for you!
_Universe->star_system->Update( 1, true /*need to run python serverside*/ );
StarSystem::ProcessPendingJumps();
/************ VS STUFF TO DO *********************/
if (snapchanged && (curtime-snaptime) > NETWORK_ATOM) {
//COUT<<"SENDING SNAPSHOT ----------"<<end;
//If planet time we send planet and nebula info
if ( (curtime-planettime) > PLANET_ATOM ) {
zonemgr->broadcastSnapshots( true );
planettime = curtime;
}
//Otherwise we just send ships/bases... info
else {
zonemgr->broadcastSnapshots( false );
}
snapchanged = 0;
snaptime = curtime;
}
sendNewUnitQueue();
//Check for automatic server status save time (in seconds)
//curtime = getNewTime();
if ( (curtime-savetime) > SAVE_ATOM ) {
//Not implemented
cout<<">>> Saving server status... Time="<<curtime<<endl;
this->save();
savetime = curtime;
cout<<"<<< Finished saving."<<endl;
}
_sock_set.waste_time( 0, 10000 );
}


I was wondering why i had a crash with my llama when i tried to jump out the atlantis's system ... So it seem that as today , all the MMO is limited to one system .
( that need confirmation , but my experience + the code comments should be enough to
understand the situation )

Perhaps you have noticed that in the same thread ( this loop ) , are made the communications between server and client AND the account server .

I think this design should be discussed , with multithreading in mind ...
The account server ( python ) is not multithreaded :
In socketserver.py
def serve_forever(self, poll_interval=0.5):
"""Handle one request at a time until shutdown.


Even if the connections are non-blocking , i wonder how much the game is affected by
that situation .

My opinion is that for an MMo , the " checkAcctMsg( _sock_set );" should be in a separate thread .

Code: Select all

 if (!track.HasWeapons())
            {
                // So what are you going to threaten me with? Exhaustion gas?
                return ThreatLevel::None;
            }
Vegastrike evolved
DEV YOUTUBE CHANNEL
Vegastrike evolved wiki
ezee
Intrepid Venturer
Intrepid Venturer
Posts: 703
Joined: Tue Feb 11, 2014 12:47 am
Location: FRANCE
Contact:

Re: Technical notes

Post by ezee »

Eye~R reported to me that in his case , the Jumps are working fine
I think the windows , Mac , linux versions can react differently , it would be useful to
soon have a test server online , and start some tests by OS

Test under Windows XP sp3

I have reset my accountserver ( delete file + checkout new ) to test a fresh install
I have the same problem at join time , the password check fails .
After editing it in the table , the login was ok .
EDIT :!: FIXED !
The problem was due to the size of the user_password field , that was set to 30 in
the sql table . The hash was truncated , and so the login failed .
So if you plan to use the accountserver with database , be sure to set up your varchar fields with at least 100 . ( i use 200 now ... )


I tried to dock to a miner base , but that failed .
( the server received the request , but no dock for me )

Something interesting happened in the log , that i hadn't seen before :
ng\lowlevel\vsnet_dloadmgr.cpp:74 Enter VsnetDownload::Client::Manager::Manager
networking\netclient_login.cpp:358 enter NetClient::init_acct with http://127.0.0.1:8080/cgi-bin/accountserver.py
\networking\lowlevel\netui.cpp:18 Initializing Winsock
networking\netclient_login.cpp:365 accountserver on socket 07422118 done.
networking\netclient_login.cpp:141 enter NetClient::loginAcctLoop
networking\netclient_login.cpp:151 Buffering to send with LOGIN_DATA for admin
\networking\lowlevel\netui.cpp:75 Connecting to 127.0.0.1 on port 8080
e\src\networking\netclient.cpp:207 >>> LOGIN DATA --------------------------------------
e\src\networking\netclient.cpp:219 <<< LOGIN DATA --------------------------------------
networking\netclient_login.cpp:186 End of loginAcct loop
networking\netclient_login.cpp:191 Trying to connect to game server...
IP=127.0
So there is a working client downloader ...
Watch it in action :
networking\netclient_login.cpp:214 >>> LOGIN ACCEPTED =( serial #358 )= --------------------------------------
Stardate initialized
WE ARE ON STARDATE 0.0000:000 - converted : 0.0000:000
networking\netclient_login.cpp:269 Initial system = Crucible/Cephid_17.net.system: Downloading system from server...
ng\lowlevel\vsnet_dloadmgr.cpp:88 Enter VsnetDownload::Client::Manager::addItems
ng\lowlevel\vsnet_dloadmgr.cpp:96 adding item: Crucible/Cephid_17.system
king\lowlevel\vsnet_notify.cpp:96 VsnetDownload::Client::Item::changeState Queued 1
ng\lowlevel\vsnet_dloadmgr.cpp:152 Enter VsnetDownload::Client::Manager::private_lower_poll
ng\lowlevel\vsnet_dloadmgr.cpp:351 Enter VsnetDownload::Client::Manager::private_lower_test_access
king\lowlevel\vsnet_notify.cpp:96 VsnetDownload::Client::Item::changeState Resolving 1
e\src\networ
The real download started here :
ng\lowlevel\vsnet_dloadmgr.cpp:113 Enter VsnetDownload::Client::Manager::processCmdDownload
ng\lowlevel\vsnet_dloadmgr.cpp:213 file Crucible/Cephid_17.system found on server
king\lowlevel\vsnet_notify.cpp:107 VsnetDownload::Client::Item::changeState Resolved 1
king\lowlevel\vsnet_notify.cpp:107 VsnetDownload::Client::Item::changeState Requested 1
e\src\networking\netclient.cpp:559 Rcvd TCP: CMD_DOWNLOAD from serial 0
e\src\networking\netclient.cpp:615
ng\lowlevel\vsnet_dloadmgr.cpp:113 Enter VsnetDownload::Client::Manager::processCmdDownload
ng\lowlevel\vsnet_dloadmgr.cpp:271 got data in a DownloadFirstFragment
king\lowlevel\vsnet_notify.cpp:107 VsnetDownload::Client::Item::changeState FragmentReceived 1
e\src\networking\netclient.cpp:559 Rcvd TCP: CMD_DOWNLOAD from serial 0
e\src\networking\netclient.cpp:615
ng\lowlevel\vsnet_dloadmgr.cpp:113 Enter VsnetDownload::Client::Manager::processCmdDownload
ng\lowlevel\vsnet_dloadmgr.cpp:271 got data in a DownloadFragment
king\lowlevel\vsnet_notify.cpp:107 VsnetDownload::Client::Item::changeState FragmentReceived 1
e\src\networking\netclient.cpp:559 Rcvd TCP: CMD_DOWNLOAD from serial 0
e\src\networking\netclient.cpp:615
ng\lowlevel\vsnet_dloadmgr.cpp:113 Enter VsnetDownload::Client::Manager::processCmdDownload
ng\lowlevel\vsnet_dloadmgr.cpp:271 got data in a DownloadFragment
king\lowlevel\vsnet_notify.cpp:107 VsnetDownload::Client::Item::changeState FragmentReceived 1
e\src\networking\netclient.cpp:559 Rcvd TCP: CMD_DOWNLOAD from serial 0
e\src\networking\netclient.cpp:615
ng\lowlevel\vsnet_dloadmgr.cpp:113 Enter VsnetDownload::Client::Manager::processCmdDownload
ng\lowlevel\vsnet_dloadmgr.cpp:271 got data in a DownloadFragment
king\lowlevel\vsnet_notify.cpp:107 VsnetDownload::Client::Item::changeState FragmentReceived 1
e\src\networking\netclient.cpp:559 Rcvd TCP: CMD_DOWNLOAD from serial 0
e\src\networking\netclient.cpp:615
ng\lowlevel\vsnet_dloadmgr.cpp:113 Enter VsnetDownload::Client::Manager::processCmdDownload
ng\lowlevel\vsnet_dloadmgr.cpp:271 got data in a DownloadFragment
king\lowlevel\vsnet_notify.cpp:107 VsnetDownload::Client::Item::changeState FragmentReceived 1
e\src\networking\netclient.cpp:559 Rcvd TCP: CMD_DOWNLOAD from serial 0
e\src\networking\netclient.cpp:615
ng\lowlevel\vsnet_dloadmgr.cpp:113 Enter VsnetDownload::Client::Manager::processCmdDownload
ng\lowlevel\vsnet_dloadmgr.cpp:271 got data in a DownloadLastFragment
king\lowlevel\vsnet_notify.cpp:107 VsnetDownload::Client::Item::changeState Completed 1
networking\netclient_login.cpp:122 End of login loop
Here we learn that the Download manager is working inside of the login loop .
I like that !
:wink:

Code: Select all

 if (!track.HasWeapons())
            {
                // So what are you going to threaten me with? Exhaustion gas?
                return ThreatLevel::None;
            }
Vegastrike evolved
DEV YOUTUBE CHANNEL
Vegastrike evolved wiki
ezee
Intrepid Venturer
Intrepid Venturer
Posts: 703
Joined: Tue Feb 11, 2014 12:47 am
Location: FRANCE
Contact:

Re: Technical notes

Post by ezee »

:!: About using phpbb forum databases with accountserver .

Now that i know that the account server is fully working with a database , i have tried
to use a phpbb forum on my local apache dev server .
I just had to add a table ' accounts ' in the phpbb base , and change the name of the base in data\cgi-accountserver\settings.py

The registration process works fine , and login into vegastrike too .
But ...
The users created by the accountserver can't log in the phpbb forum because of the
Md5 hash password .

The fix could be to add Md5 hash to phpbb .

EDIT :
( :idea: I have found a python lib that reproduce the phpbb hash:
https://github.com/exavolt/python-phpass
Could serve to register with accountserver with the right format for phpbb... )


Another fix would be to modify the python script and add a new table ( vs_users ) to the phpbb base , allowing to store the phpbb pass in his native encryption in the table phpbb_users ,
and store the md5 password in vs_users .

( i am not an old experienced phpbb admin, so if you know the right trick , don't hesitate to share it please ) .

Finally ,
i just verified , the "logged_in_server" update is operational :
chewie
,"Directory","Name","STATUS","Object_Type","Combat...
Crucible/Cephid_17^13500.000000^MacGyver 1.1999999...
1
Very cool , that will allow to see in the forum who is online and in game .

Code: Select all

 if (!track.HasWeapons())
            {
                // So what are you going to threaten me with? Exhaustion gas?
                return ThreatLevel::None;
            }
Vegastrike evolved
DEV YOUTUBE CHANNEL
Vegastrike evolved wiki
ezee
Intrepid Venturer
Intrepid Venturer
Posts: 703
Joined: Tue Feb 11, 2014 12:47 am
Location: FRANCE
Contact:

Re: Technical notes

Post by ezee »

:!: Eye~R made a detailed todo list for the MMO side of Vega strike , i just added it on the wiki : http://wiki.vega-strike.org/Development ... twork_TODO

:idea: Modifications in the Client Class .

There is no real " player " class in vegastrike , and we need to store new attributes for
the players , server side .
The convenient way could be to reuse the actual Client class :
//Network part of a client description
class Client
{
public:
/* Network and identification properties */
UnitContainer game_unit;

//NETFIXME: Move to server subclass.
AddressIP cltadr;
AddressIP cltudpadr;
SOCKETALT *lossy_socket;
SOCKETALT tcp_sock;

//2 timeout vals to check a timeout for client connections
//those vals are server times
double old_timeout;
double latest_timeout;
double elapsed_since_packet;
string callsign; <-- actually used in account server
string name;<-- actually used in account server
string passwd;<-- actually used in account server

/* Accountserver sends this info to us. */
string server_ip;
unsigned short server_port;

/* In-game parameters */
bool ingame; <-- actually used in account server ??
enum Loginstate {CONNECTED, WAITLISTED, LOGGEDIN, SAVEDGAME, INGAME};
int loginstate;

char webcam;
char portaudio;
char secured;
char jumpok;
string jumpfile;
ObjSerial netversion;
vector< string >savegame; <-- actually used in account server ?
float comm_freq;
ClientState last_packet; //Last FullUpdate packet recieved.

string _disconnectReason;

Prediction *prediction;

Client();
Client( SOCKETALT &s );
~Client();

void setLatestTimestamp( unsigned int ts );
void setUDP( SOCKETALT *udpSock, AddressIP &cltudpadr );
void setTCP();
void clearLatestTimestamp();
unsigned int getLatestTimestamp() const;
double getDeltatime() const;
double getNextDeltatime() const;
void versionBuf( NetBuffer &buf ) const; //Sets the netbuffer to this version.

friend std::ostream&operator<<( std::ostream &ostr, const Client &c );

private:
//2 timestamps vals from client time to check receiving old packet after
//newer ones (allowed in case of UDP only)
unsigned int _old_timestamp;
unsigned int _latest_timestamp;
double _deltatime;
double _next_deltatime;

private: Client( const Client& );
Client& operator=( const Client& );

void Init();
};

std::ostream&operator<<( std::ostream &ostr, const Client &c );

#endif
I think some good modifications in the todo list could be done at that level .
Add fields for rank and for faction(default Unadorned)
Add field for IsSuper to indicate SuperUser
Add field for IsFaction to denote Faction Leader status
There is also an interesting class , " Pilot " , that could be used
#include "config.h"
#include "gnuhash.h"
#include <vector>
class Animation;
class Unit;

class Pilot
{
unsigned char gender; //which sound should play
float reaction_time;
float rank;
int faction; //duplicate data...any way round this??
public:
explicit Pilot( int faction );
virtual ~Pilot() {}
void SetComm( Unit *comm_unit ); //so we can specialize base sort of people
Animation * getCommFace( Unit *parent, float moon, unsigned char &gender );
float getReactionTime()
{
return reaction_time;
}
unsigned char getGender()
{
return gender;
}
float getRank()
{
return rank;
} //man it's rank in here


typedef vsUMap< const void*, float >relationmap; //non dereferencable Unit to float
relationmap effective_relationship;
std::vector< Animation* > *comm_face;
float getAnger( const Unit *parent, const Unit *un ) const;
std::vector< Animation* > * getCommFaces( unsigned char &sex )
{
sex = gender;
return comm_face;
}
float GetEffectiveRelationship( const Unit *parent, const Unit *target ) const;
float adjustSpecificRelationship( Unit *parent, void *aggressor, float value, int guessedFaction /*pass in neutral otherwise*/ );
void DoHit( Unit *parent, void *aggressor, int guessedFaction /*pass in neutral otherwise*/ );
};
Seem to serve for AI only actually .
COuld be used in network for the player's comms animations and rank ?

Code: Select all

 if (!track.HasWeapons())
            {
                // So what are you going to threaten me with? Exhaustion gas?
                return ThreatLevel::None;
            }
Vegastrike evolved
DEV YOUTUBE CHANNEL
Vegastrike evolved wiki
Post Reply