Soooo, I know no one has answered this, but I could still use some help. Here is my ServerCore.cpp file
#include <string>
#include <sstream>
#include "ServerCore.h"
#include "Multisync.h"
#include "DarkGDK.h"
#include <windows.h>
#include <psapi.h> //Mem usage
#include <boost/thread.hpp>
using namespace std;
ServerCore::ServerCore(void)
{
}
ServerCore::~ServerCore(void)
{
//Kick everyone
for( int i = 0; i < fileMaxPlayers; i++ )
{
NetKick(listPlayers[i].getMyId());
}
}
//Overloaded constructor for use of starting the server on the correct ip address
ServerCore::ServerCore(int maxPlayers)
{
goodToGo = false;
int res = 0;
printedStart = false;
//Set tick count to 0
curTickCount = 0;
//Default port for Multisync
listeningPort = 3999;
//Set number of current players to 0
curNumPlayers = 0;
//Set max number of players
fileMaxPlayers = maxPlayers;
//Set server uptime to a timer
serverUpTimeTimer = boost::posix_time::microsec_clock::local_time();
serverUpTimeSeconds = 0;
serverUpTimeMinutes = 0;
serverUpTimeHours = 0;
//Bool for checking threads
createdCheckPlayerThread = false;
checkPlayersThreadTimer = boost::posix_time::microsec_clock::local_time();
for( int i = 0; i < fileMaxPlayers; i++ )
{
listPlayers[i].setMyId(0);
}
try
{
//Host the server with the max amount of players
res = NetHost(maxPlayers);
if( res )
{
goodToGo = true;
}
}catch(char *exception)
{
//Error starting the server
}
}
void ServerCore::runServer(double tickRate)
{
//Server started correctly, allow connections etc.
if( goodToGo )
{
timeStep = 1000.0/tickRate;
if( printedStart == false )
{
dbText(0,0,"Server started successfully!");
dbText(0, 15, "Server listening on port 3999");
dbText(0, 30, " ");
dbText(0, 45, "Connections");
dbText(0, 60, "------------");
}
//==========================================TICK RATE STARTS HERE=================
//Do tickrate number of updates per second
/*
What I am doing:
For every second,
do n number of ticks, each of which do the following:
process incoming server commands (also people joining etc)
check game rules
update ALL object states
After every tick,
Determine if any client needs a world update.
Take a snapshot of the world if necessary ( 99% of the time)
Send to the clients
*/
//Create a thread every second. Itll run the allotted time each second and then is interuptted at the end
//Thread for checking players
//boost::bind(&ServerCore::checkForPlayers, boost::ref(this))
if( !createdCheckPlayerThread )
{
boost::thread thrd(&ServerCore::checkForPlayers, this);
createdCheckPlayerThread = true;
curTickCount++;
}
if( createdCheckPlayerThread )
{
boost::posix_time::time_duration cPlayersTD = boost::posix_time::microsec_clock::local_time() - checkPlayersThreadTimer;
if ( cPlayersTD.total_milliseconds() >= timeStep )
{
//finished
//So interrupt the thread
//Increase tick count
checkPlayersThreadTimer = boost::posix_time::microsec_clock::local_time();
thrd.interrupt();
createdCheckPlayerThread = false;
}
}
//Print out the current connections
printOutCurrentConnections();
//Print tick count
printTickCount();
//Server up time
printServerUpTime(boost::posix_time::microsec_clock::local_time());
string memUsage;
char* buffer = dbStr(getMemUsage()/1024);
memUsage = "Working Set Memory: ";
memUsage += buffer;
memUsage += "kb";
//Print mem usage
dbText(0, dbScreenHeight() - 20, const_cast<char*>(memUsage.c_str()));
delete [] buffer;
}
}
/*
Make sure to set sensible thread interrupts
*/
void ServerCore::checkForPlayers( )
{
boost::this_thread::interruption_point();
//Check for new players connecting
int newPlayerJoinedID = NetPlayerJoined();
while( newPlayerJoinedID > 0 )
{
//Add the player id of the new player to the player array
listPlayers[curNumPlayers].setMyId(newPlayerJoinedID);
//Add to current amount of players;
curNumPlayers++;
newPlayerJoinedID = NetPlayerJoined();
}
boost::this_thread::interruption_point();
int oldPlayerLeft = NetPlayerLeft();
while( oldPlayerLeft > 0 )
{
//Delete that specific player from the server
//using the id from NetPlayerLeft - linear search
for( int i = 0; i < fileMaxPlayers; i++ )
{
if( listPlayers[i].getMyId() == oldPlayerLeft )
{
//Delete them from the array
listPlayers[i].setMyId(0);
//Subtract from current number of players
curNumPlayers--;
}
}
oldPlayerLeft = NetPlayerLeft();
}
boost::this_thread::interruption_point();
}
//Sends out a snapshot to the clients
void ServerCore::sendSnapshot()
{
}
//==============================================================PRINT FUNCTIONS====================================================
void ServerCore::printOutCurrentConnections()
{
string whatToPrint;
stringstream out;
//Print out the server connections
for( int i = 0; i < fileMaxPlayers; i++ )
{
if( listPlayers[i].getMyId() > 0)
{
whatToPrint += "ID: ";
out << listPlayers[i].getMyId();
whatToPrint += out.str();
dbText(0, 60 + (i*dbTextHeight(const_cast<char*>(whatToPrint.c_str()))), const_cast<char*>(whatToPrint.c_str()));
whatToPrint.clear();
out.str("");
}
}
}
void ServerCore::printTickCount()
{
string ticks;
char* buffer = dbStr(curTickCount);
ticks += "Current Tick: ";
ticks += buffer;
dbText(0, dbScreenHeight() - 60, const_cast<char*>(ticks.c_str()));
delete [] buffer;
}
void ServerCore::printServerUpTime(boost::posix_time::ptime cur)
{
string upTime;
//Compare the times
//If the current passed time, is greater than the last recorder serverUpTimeTimer + 1000, then a second has passed
boost::posix_time::time_duration diff = cur - serverUpTimeTimer;
if( diff.total_milliseconds() >= 1000)
{
serverUpTimeSeconds += 1;
if( serverUpTimeSeconds >= 60 )
{
serverUpTimeMinutes++;
serverUpTimeSeconds = 0;
}
if( serverUpTimeMinutes >= 60 )
{
serverUpTimeHours++;
serverUpTimeMinutes = 0;
}
serverUpTimeTimer = boost::posix_time::microsec_clock::local_time();
}
upTime += "Server Uptime: ";
char* buff1 = dbStr(serverUpTimeHours);
upTime += buff1;
upTime += "h:";
char* buff2 = dbStr(serverUpTimeMinutes);
upTime += buff2;
upTime += "m:";
char* buff3 = dbStr(serverUpTimeSeconds);
upTime += buff3;
upTime += "s";
dbText(0, dbScreenHeight() - 40, const_cast<char*>(upTime.c_str()));
//Clear the memory leak by dbStr
delete [] buff1;
delete [] buff2;
delete [] buff3;
}
int ServerCore::getMemUsage()
{
HANDLE hProcess;
PROCESS_MEMORY_COUNTERS pmc;
DWORD processID = GetCurrentProcessId();
int totalMemUsage;
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID );
if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
{
totalMemUsage = (int)pmc.WorkingSetSize;
}
CloseHandle( hProcess );
return totalMemUsage;
}
And my main:
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <sstream>
#include "DarkGDK.h"
#include "Multisync.h"
#include "MessageBuffer.h"
#include "ServerCore.h"
using namespace std;
void readConfigFile(char *filePath); //Reads the config file and stores the values in an array
string getServerValue(char *serverValName); //Give the server name property, split that string in the array and return the value. Will need type conversion
//===========================GLOBAL VARS====================================
string serverInfo[500];
int currentServerInfoCount = 0;
//==========================================================================
//======================================MAIN LOOP============================
void DarkGDK ( void )
{
//Read the config file
readConfigFile("config.cfg");
//Read in tickrate
int serverTickRate = atoi(const_cast<char*>(getServerValue("tickrate").c_str()));
dbSyncOn ( );
dbSyncRate( 0 );
dbSetDisplayModeVSync(800,600,32,0);
dbDisableEscapeKey ( );
//Set the window title
char windowTitle[400] = "Galaxy Gangs Server - ";
strcat_s(windowTitle, 400, const_cast<char*>(getServerValue("ServerName").c_str()));
dbSetWindowTitle(windowTitle);
//Create the server core
ServerCore serverCore(atoi(const_cast<char*>(getServerValue("MaxPlayers").c_str())));
//Enter the loop
while ( LoopGDK ( ) )
{
serverCore.runServer(serverTickRate);
dbSync();
dbCLS();
}
return;
}
//===========================================================================
void readConfigFile(char *filePath)
{
//Create the stream object
ifstream readStream;
//Temp line
string line;
//Open the file
readStream.open(filePath, ios::in);
//Get the configuration data. Like server name, port number, etc.
if( readStream.is_open() )
{
while(getline(readStream,line))
{
if(line.substr(0,2) != "//")
{
serverInfo[currentServerInfoCount] = line;
currentServerInfoCount++;
}
}
//Close the file
readStream.close();
}
}
/*
Search for a given server property by name
Returns server property value if found, otherwise returns a blank string
*/
string getServerValue(char *serverValName)
{
bool found = false;
//Return a string with the correct value and do a type conversion on it.
for( int i = 0; i < sizeof( serverInfo ) / sizeof( serverInfo[0] ); i++ )
{
stringstream strStream(serverInfo[i]);
string token;
while(getline(strStream, token, '='))
{
if( found )
{
return token;
break;
}
if(token.compare(serverValName) == 0)
{
found = true;
}
}
}
return "";
}
It's mainly in the runServer member function that I need some help. The tickRate variable is the one read from the config file, and right now it is 66. The problem is that the curTickCount is never reaching 66 in a second. I know this by using an if statement to sleep the program at 1 second, and see what the tick count is. It has never fully read 66 before.