Revision: 226
http://rorserver.svn.sourceforge.net/rorserver/?rev=226&view=rev
Author: aperion
Date: 2008-09-06 07:29:01 +0000 (Sat, 06 Sep 2008)
Log Message:
-----------
Initial implementation of the banning system, depends on boost::regex
as a test to block all users define BANNING_TEST when compiling and all connecting users will be blocked
next steps are to add the command lines required to specify files containing a list of banned expressions for username, truck, and ip address
Modified Paths:
--------------
trunk/source/broadcaster.cpp
trunk/source/config.cpp
trunk/source/config.h
trunk/source/logger.h
trunk/source/receiver.cpp
trunk/source/sequencer.cpp
Modified: trunk/source/broadcaster.cpp
===================================================================
--- trunk/source/broadcaster.cpp 2008-08-17 23:07:00 UTC (rev 225)
+++ trunk/source/broadcaster.cpp 2008-09-06 07:29:01 UTC (rev 226)
@@ -35,9 +35,12 @@
instance->running = false;
instance->queue_mutex.wait( instance->queue_cv );
}
-#ifdef __WIN32__
+#ifdef __GNUC__
Logger::log( LOG_DEBUG, "broadcaster thread %u:%u is exiting",
- (unsigned int) &pthread_self().p, ThreadID::getID() );
+ (unsigned int) pthread_self(), ThreadID::getID() );
+#else
+ Logger::log( LOG_DEBUG, "broadcaster thread %u:%u is exiting",
+ (unsigned int) &pthread_self().p, ThreadID::getID() );
#endif
return NULL;
}
@@ -79,9 +82,12 @@
running = false;
queue_cv.signal();
queue_mutex.unlock();
-#ifdef __WIN32__
+#ifdef __GNUC__
Logger::log( LOG_DEBUG, "joining with broadcaster thread: %u",
- (unsigned int) &thread.p);
+ (unsigned int) thread);
+#else
+ Logger::log( LOG_DEBUG, "joining with broadcaster thread: %u",
+ (unsigned int) &thread);
#endif
pthread_join( thread, NULL );
}
Modified: trunk/source/config.cpp
===================================================================
--- trunk/source/config.cpp 2008-08-17 23:07:00 UTC (rev 225)
+++ trunk/source/config.cpp 2008-09-06 07:29:01 UTC (rev 226)
@@ -10,6 +10,7 @@
#include "sha1_util.h"
#include <cmath>
+#include <fstream>
#ifdef __WIN32__
#include <windows.h>
@@ -67,7 +68,7 @@
{
SWBaseSocket::SWBaseError error;
SWInetSocket mySocket;
-
+
if( !mySocket.connect(80, REPO_SERVER, &error) )
return "";
@@ -76,16 +77,16 @@
Logger::log(LOG_DEBUG, "Query to get public IP: %s\n", query);
if( mySocket.sendmsg(query, &error) < 0 )
return "";
-
+
std::string retval = mySocket.recvmsg(250, &error);
if( error != SWBaseSocket::ok )
return "";
Logger::log(LOG_DEBUG, "Response from public IP request :'%s'", retval.c_str() );
-
+
HttpMsg msg( retval );
retval = msg.getBody();
// printf("Response:'%s'\n", pubip);
-
+
// disconnect
mySocket.disconnect();
return retval;
@@ -100,12 +101,12 @@
" -name <name> Name of the server, no spaces, only \n"
" [a-z,0-9,A-Z]\n"
" -terrain <mapname> Map name (defaults to 'any')\n"
-"Use maxclients OR speed, not both\n"
+" Use maxclients OR speed, not both\n"
" -maxclients|speed <clients> Maximum clients allowed \n"
" -speed <upload in kbps> or maximum upload speed (in kilobits)\n"
" -lan|inet Private or public server (defaults to inet)\n"
"\n"
-" OPTIONAL:\n"
+" OPTIONAL:\n"
" -password <password> Private server password\n"
" -rconpassword <password> Set admin password. This is required for RCON to\n"
" work. Otherwise RCON is disabled.\n"
@@ -149,7 +150,7 @@
bool Config::checkConfig()
{
bool is_valid_config = true;
-
+
switch ( getServerMode() )
{
case SERVER_AUTO:
@@ -173,19 +174,19 @@
Logger::log( LOG_WARN, "no IP address has been specified, attempting to "
"detect.");
setIPAddr( getPublicIP() );
-
+
if( getIPAddr().empty() )
Logger::log(LOG_ERROR, "could not get public IP automatically!");
}
-
+
if( getIPAddr().empty() )
{
- Logger::log( LOG_ERROR, "IP adddress not specified.");
+ Logger::log( LOG_ERROR, "IP address not specified.");
is_valid_config = false;
}
else
Logger::log( LOG_INFO, "ip address: %s", getIPAddr().c_str() );
-
+
if( getMaxClients() > 16 )
{
Logger::log( LOG_ERROR, "max clients is set to greater than 16,"
@@ -194,24 +195,24 @@
}
else
Logger::log(LOG_WARN, "app. full load traffic: %ikbit/s upload and "
- "%ikbit/s download",
+ "%ikbit/s download",
getMaxClients()*(getMaxClients()-1)*64, getMaxClients()*64);
-
+
if( getServerName().empty() )
{
Logger::log( LOG_ERROR, "Server name not specified.");
is_valid_config = false;
}
else
- Logger::log( LOG_INFO, "servername: %s", getServerName().c_str() );
+ Logger::log( LOG_INFO, "servername: %s", getServerName().c_str() );
}
if( !getListenPort() )
{
- Logger::log( LOG_WARN, "No port supllied, randomly generating one");
+ Logger::log( LOG_WARN, "No port supplied, randomly generating one");
setListenPort( getRandomPort() );
}
Logger::log( LOG_INFO, "port: %d", getListenPort() );
-
+
if( getTerrainName().empty() )
{
Logger::log( LOG_ERROR, "terrain not specified" );
@@ -219,7 +220,7 @@
}
else
Logger::log( LOG_INFO, "terrain: %s", getTerrainName().c_str() );
-
+
if( getMaxClients() < 2 || getMaxClients() > 64 )
{
Logger::log( LOG_ERROR, "Max clients need to 2 or more, and 64 or less." );
@@ -227,18 +228,18 @@
}
else
Logger::log( LOG_INFO, "maxclients: %d", getMaxClients());
-
+
Logger::log( LOG_INFO, "server is%s password protected",
getPublicPassword().empty() ? " NOT": "" );
Logger::log( LOG_INFO, "admin password %s admin console",
- getAdminPassword().empty() ? "not set, disabling":
+ getAdminPassword().empty() ? "not set, disabling":
"is set, enabling" );
-
+
return is_valid_config;
- return getMaxClients() && getListenPort() && !getIPAddr().empty() &&
+ return getMaxClients() && getListenPort() && !getIPAddr().empty() &&
!getServerName().empty() &&!getTerrainName().empty();
-
+
}
bool Config::fromArgs( int argc, char* argv[] )
@@ -247,7 +248,7 @@
CSimpleOpt args(argc, argv, cmdline_options);
while (args.Next()) {
if (args.LastError() == SO_SUCCESS) {
- switch( args.OptionId() )
+ switch( args.OptionId() )
{
case OPT_IP:
setIPAddr( args.OptionArg() );
@@ -288,14 +289,15 @@
case OPT_MAXCLIENTS:
setMaxClients( atoi(args.OptionArg()) );
break;
-
- case OPT_HELP:
+
+ case OPT_HELP:
default:
showUsage();
return false;
}
}
}
+ Config::loadBannedUsernames( std::string("") );
return true;
}
@@ -310,7 +312,7 @@
const std::string& Config::getServerName() { return instance.server_name; }
const std::string& Config::getTerrainName() { return instance.terrain_name; }
const std::string& Config::getPublicPassword() { return instance.public_password; }
-const std::string& Config::getAdminPassword() { return instance.admin_password; }
+const std::string& Config::getAdminPassword() { return instance.admin_password; }
const std::string& Config::getIPAddr() { return instance.ip_addr; }
unsigned int Config::getListenPort() { return instance.listen_port; }
ServerType Config::getServerMode() { return instance.server_mode; }
@@ -318,7 +320,7 @@
//! setter functions
//!@{
-bool Config::setMaxClients(unsigned int num) {
+bool Config::setMaxClients(unsigned int num) {
if( num < 2 || (getServerMode() == SERVER_INET) || num > 64 ) return false;
instance.max_clients = num;
return true;
@@ -334,27 +336,27 @@
return true;
}
bool Config::setPublicPass( const std::string& pub_pass ) {
- if(pub_pass.length() > 0 && pub_pass.size() < 250 &&
+ if(pub_pass.length() > 0 && pub_pass.size() < 250 &&
!SHA1FromString(instance.public_password, pub_pass))
{
Logger::log(LOG_ERROR, "could not generate server SHA1 password hash!");
instance.public_password = "";
return false;
}
- Logger::log(LOG_DEBUG,"sha1(%s) = %s", pub_pass.c_str(),
+ Logger::log(LOG_DEBUG,"sha1(%s) = %s", pub_pass.c_str(),
instance.public_password.c_str());
return true;
}
bool Config::setAdminPass( const std::string& admin_pass ) {
- if(admin_pass.length() > 0 && admin_pass.length() < 250 &&
+ if(admin_pass.length() > 0 && admin_pass.length() < 250 &&
!SHA1FromString(instance.admin_password, admin_pass))
{
Logger::log(LOG_ERROR, "could not generate server SHA1 password hash!");
instance.admin_password = "";
return false;
}
- Logger::log(LOG_DEBUG,"sha1(%s) = %s", admin_pass.c_str(),
+ Logger::log(LOG_DEBUG,"sha1(%s) = %s", admin_pass.c_str(),
instance.admin_password.c_str());
return true;
}
@@ -375,3 +377,70 @@
return true;
}
//!@}
+
+
+bool Config::bannedUsername( const std::string& name ) {
+ return bannedRegex( name, instance.bannedNames );
+}
+bool Config::bannedTruck( const std::string& truck_file ) {
+ return bannedRegex( truck_file, instance.bannedTrucks );
+}
+bool Config::bannedIP( const std::string& ip_addr ) {
+ return bannedRegex( ip_addr, instance.bannedIPs );
+}
+
+void Config::loadBannedUsernames( const std::string& filename ) {
+ loadRegexFromFile( filename, instance.bannedNames );
+}
+void Config::loadBannedTrucks( const std::string& filename ) {
+ loadRegexFromFile( filename, instance.bannedTrucks );
+}
+void Config::loadBannedIPaddr( const std::string& filename ) {
+ loadRegexFromFile( filename, instance.bannedIPs );
+}
+
+
+bool Config::bannedRegex( const std::string& checkVal,
+ const std::vector<boost::regex>& regexs)
+{
+ bool match = false;
+ Logger::log( LOG_INFO,"checking %s against %d regular expressions",
+ checkVal.c_str(), regexs.size() );
+ for( std::vector<boost::regex>::const_iterator
+ current( regexs.begin() ), end( regexs.end() );
+ (current != end) && !match; current++ )
+ {
+ match = regex_match( checkVal, *current );
+ }
+ return match;
+}
+
+
+void Config::loadRegexFromFile( const std::string& filename,
+ std::vector<boost::regex>& regexs)
+{
+#ifdef BANNING_TEST
+ if( filename.empty() )
+ {
+ regexs.push_back( boost::regex(".*") ); // block everything as a test
+ Logger::log( LOG_INFO, "no valid names provided, allowing all" );
+ return;
+ }
+#undef BANNING_TEST
+#endif
+
+ std::ifstream file( filename.c_str() );
+ std::string expression;
+ if( file.is_open() )
+ {
+ while ( !file.eof() )
+ {
+ getline( file,expression );
+ Logger::log( LOG_INFO, "got valid regular expression: %s",
+ expression.c_str() );
+
+ regexs.push_back( boost::regex( expression ) );
+ }
+ file.close();
+ }
+}
Modified: trunk/source/config.h
===================================================================
--- trunk/source/config.h 2008-08-17 23:07:00 UTC (rev 225)
+++ trunk/source/config.h 2008-09-06 07:29:01 UTC (rev 226)
@@ -1,6 +1,9 @@
#ifndef CONFIG_H_
#define CONFIG_H_
+
#include <string>
+#include <vector>
+#include <boost/regex.hpp>
// server modes
@@ -18,12 +21,12 @@
//! runs a check that all the required fields are present
static bool checkConfig();
static bool fromArgs( int argc, char* argv[] );
-
+
//! checks if a password has been set for server access
static bool isPublic();
//! checks if the admin password is set, and the admin console is enabled.
static bool hasAdmin();
-
+
//! getter function
//!@{
static unsigned int getMaxClients();
@@ -38,20 +41,33 @@
//! setter functions
//!@{
- static bool setMaxClients(unsigned int num);
+ static bool setMaxClients( unsigned int num );
static bool setServerName( const std::string& name );
- static bool setTerrain( const std::string& name );
+ static bool setTerrain( const std::string& name );
static bool setPublicPass( const std::string& name );
- static bool setAdminPass( const std::string& name );
- static bool setIPAddr( const std::string& name );
+ static bool setAdminPass( const std::string& name );
+ static bool setIPAddr( const std::string& name );
static bool setListenPort( unsigned int port );
- static bool setServerMode( ServerType mode);
+ static bool setServerMode( ServerType mode );
//!@}
-
+
+ static bool bannedUsername( const std::string& name );
+ static bool bannedTruck( const std::string& truck_file );
+ static bool bannedIP( const std::string& ip_addr );
+
+ static void loadBannedUsernames( const std::string& filename );
+ static void loadBannedTrucks( const std::string& filename );
+ static void loadBannedIPaddr( const std::string& filename );
+
private:
Config();
static Config instance;
-
+ static bool bannedRegex( const std::string& checkVal,
+ const std::vector<boost::regex>& regexs);
+
+ static void loadRegexFromFile( const std::string& filename,
+ std::vector<boost::regex>& regexs);
+
unsigned int max_clients;
std::string server_name;
std::string terrain_name;
@@ -60,9 +76,13 @@
std::string ip_addr;
unsigned int listen_port;
ServerType server_mode;
-
-
-
+
+ std::vector<boost::regex> bannedNames;
+ std::vector<boost::regex> bannedTrucks;
+ std::vector<boost::regex> bannedIPs;
+
+
+
};
#endif /*CONFIG_H_*/
Modified: trunk/source/logger.h
===================================================================
--- trunk/source/logger.h 2008-08-17 23:07:00 UTC (rev 225)
+++ trunk/source/logger.h 2008-09-06 07:29:01 UTC (rev 226)
@@ -1,7 +1,7 @@
/**
* Logger Class Header file
* @file logger.h
- * @author Christopher Ritchey (aka Aperion)
+ * @author Christopher Ritchey (aka Aperion)
* A simple Logger with different logging levels. As well as an easy to use
* stack log
*/
@@ -37,16 +37,16 @@
static void log(const LogLevel& level, const char* format, ...);
static void log(const LogLevel& level, const std::string& msg);
-
+
static void setOutputFile(const std::string& filename);
static void setLogLevel(const LogType type, const LogLevel level);
- //! sets the level at which manual file flushing occurs flushing at the
+ //! sets the level at which manual file flushing occurs flushing at the
//! stack level is a heavy hit on performance with only 2 clients connected
//! This prevents any messages below the specified level triggering manual
//! flushing.
//! if set to LOG_ERROR then flushing occurs only when an error is logged
static void setFlushLevel(const LogLevel level );
-
+
private:
Logger();
Logger instance();
@@ -71,7 +71,7 @@
// macros for crossplatform compiling
-#ifndef __GNUC__
+#ifndef __PRETTY_FUNCTION__
#define __PRETTY_FUNCTION__ __FUNCTION__
#endif
Modified: trunk/source/receiver.cpp
===================================================================
--- trunk/source/receiver.cpp 2008-08-17 23:07:00 UTC (rev 225)
+++ trunk/source/receiver.cpp 2008-09-06 07:29:01 UTC (rev 226)
@@ -26,9 +26,12 @@
{
STACKLOG;
((Receiver*)vid)->threadstart();
-#ifdef __WIN32__
+#ifdef __GNUC__
Logger::log( LOG_DEBUG, "Receiver thread %u:%u is exiting",
- (unsigned int) pthread_self().p, ThreadID::getID() );
+ (unsigned int) pthread_self(), ThreadID::getID() );
+#else
+ Logger::log( LOG_DEBUG, "Receiver thread %u:%u is exiting",
+ (unsigned int) pthread_self().p, ThreadID::getID() );
#endif
return NULL;
}
@@ -60,8 +63,11 @@
{
STACKLOG;
running = false;
-#ifdef __WIN32__
+#ifdef __GNUC__
Logger::log( LOG_DEBUG, "joining with receiver thread: %u",
+ (unsigned int) thread);
+#else
+ Logger::log( LOG_DEBUG, "joining with receiver thread: %u",
(unsigned int) &thread.p);
#endif
pthread_join(thread, NULL);
Modified: trunk/source/sequencer.cpp
===================================================================
--- trunk/source/sequencer.cpp 2008-08-17 23:07:00 UTC (rev 225)
+++ trunk/source/sequencer.cpp 2008-09-06 07:29:01 UTC (rev 226)
@@ -32,7 +32,7 @@
#include <iostream>
#include <stdexcept>
#include <sstream>
-//#define REFLECT_DEBUG
+//#define REFLECT_DEBUG
#define UID_NOT_FOUND 0xFFFF
void *s_klthreadstart(void* vid)
@@ -45,10 +45,10 @@
// init the singleton pointer
Sequencer* Sequencer::mInstance = NULL;
-/// retreives the instance of the Sequencer
+/// Retrieves the instance of the Sequencer
Sequencer* Sequencer::Instance() {
STACKLOG;
- if(!mInstance)
+ if(!mInstance)
mInstance = new Sequencer;
return mInstance;
}
@@ -67,11 +67,11 @@
/**
* Inililize, needs to be called before the class is used
- */
+ */
void Sequencer::initilize()
{
STACKLOG;
-
+
Sequencer* instance = Instance();
instance->clients.reserve( Config::getMaxClients() );
instance->listener = new Listener(Config::getListenPort());
@@ -98,14 +98,14 @@
STACKLOG;
Sequencer* instance = Instance();
- for( unsigned int i = 0; i < instance->clients.size(); i++)
+ for( unsigned int i = 0; i < instance->clients.size(); i++)
{
disconnect(instance->clients[i]->uid, "server shutting down");
}
-
+
if( instance->notifier )
delete instance->notifier;
-
+
delete instance->listener;
delete instance->mInstance;
}
@@ -122,12 +122,12 @@
{
STACKLOG;
// WARNING: be sure that this is only called within a clients_mutex lock!
-
+
// check for duplicate names
Sequencer* instance = Instance();
for (unsigned int i = 0; i < instance->clients.size(); i++)
{
- if (!strcmp(nick, instance->clients[i]->nickname))
+ if (!strcmp(nick, instance->clients[i]->nickname))
{
return true;
}
@@ -145,8 +145,6 @@
Logger::log(LOG_DEBUG,"got instance in createClient()");
MutexLocker scoped_lock(instance->clients_mutex);
- bool dupeNick = Sequencer::checkNickUnique(user->username);
- int dupecounter = 2;
// check if server is full
Logger::log(LOG_WARN,"searching free slot for new client...");
@@ -159,7 +157,20 @@
Messaging::sendmessage(sock, MSG2_FULL, 0, 0, 0);
throw std::runtime_error("Server is full");
}
-
+
+ if( Config::bannedUsername( std::string( user->username ) ) )
+ {
+
+ Logger::log(LOG_WARN,"username '%s' is banned!", user->username);
+ // set a low time out because we don't want to cause a back up of
+ // connecting clients
+ sock->set_timeout( 10, 0 );
+ Messaging::sendmessage(sock, MSG2_BANNED, 0, 0, 0);
+ throw std::runtime_error("Invalid username");
+ }
+
+ bool dupeNick = Sequencer::checkNickUnique(user->username);
+ int dupecounter = 2;
if(dupeNick)
{
char buf[20] = "";
@@ -176,13 +187,13 @@
}
Logger::log(LOG_WARN,"chose alternate username: %s\n", buf);
strncpy(user->username, buf, 20);
-
- // we should send him a message about the nickchange later...
+
+ // we should send him a message about the nick change later...
}
-
-
+
+
client_t* to_add = new client_t;
-
+
//okay, create the stuff
to_add->flow=false;
to_add->status=USED;
@@ -218,7 +229,7 @@
to_add->uid=instance->fuid;
instance->fuid++;
to_add->sock = sock;//this won't interlock
-
+
instance->clients.push_back( to_add );
to_add->receiver->reset(to_add->uid, sock);
to_add->broadcaster->reset(to_add->uid, sock,
@@ -232,7 +243,7 @@
{
STACKLOG;
- Sequencer* instance = Instance();
+ Sequencer* instance = Instance();
SWBaseSocket::SWBaseError error;
int clientnum = getNumClients();
// lock this mutex after getNumClients is called to avoid a deadlock
@@ -248,10 +259,10 @@
char playerdata[1024] = "";
char positiondata[128] = "";
instance->clients[i]->position.toString(positiondata);
- sprintf(playerdata, "%d;%s;%s;%s;%s;%s\n", i,
- instance->clients[i]->vehicle_name,
+ sprintf(playerdata, "%d;%s;%s;%s;%s;%s\n", i,
+ instance->clients[i]->vehicle_name,
instance->clients[i]->nickname,
- positiondata,
+ positiondata,
instance->clients[i]->sock->get_peerAddr(&error).c_str(),
instance->clients[i]->uniqueid);
strcat(hearbeatdata, playerdata);
@@ -282,7 +293,7 @@
void Sequencer::killerthreadstart()
{
STACKLOG;
- Sequencer* instance = Instance();
+ Sequencer* instance = Instance();
Logger::log(LOG_DEBUG,"Killer thread ready");
while (1)
{
@@ -293,7 +304,7 @@
instance->killer_mutex.lock();
while( instance->killqueue.empty() )
instance->killer_mutex.wait(instance->killer_cv);
-
+
//pop the kill queue
client_t* to_del = instance->killqueue.front();
instance->killqueue.pop();
@@ -316,7 +327,7 @@
to_del->broadcaster = NULL;
to_del->receiver = NULL;
to_del->sock = NULL;
-
+
delete to_del;
to_del = NULL;
}
@@ -325,19 +336,19 @@
void Sequencer::disconnect(int uid, const char* errormsg)
{
STACKLOG;
- Sequencer* instance = Instance();
-
+ Sequencer* instance = Instance();
+
MutexLocker scoped_lock(instance->killer_mutex);
unsigned short pos = instance->getPosfromUid(uid);
if( UID_NOT_FOUND == pos ) return;
-
+
//this routine is a potential trouble maker as it can be called from many thread contexts
//so we use a killer thread
Logger::log(LOG_VERBOSE, "Disconnecting Slot %d: %s", pos, errormsg);
-
+
client_t *c = instance->clients[pos];
instance->killqueue.push(c);
-
+
//notify the others
for( unsigned int i = 0; i < instance->clients.size(); i++)
{
@@ -350,7 +361,7 @@
}
instance->clients.erase( instance->clients.begin() + pos );
instance->killer_cv.signal();
-
+
printStats();
}
@@ -359,11 +370,11 @@
{
STACKLOG;
Sequencer* instance = Instance();
-
- MutexLocker scoped_lock(instance->clients_mutex);
- unsigned short pos = instance->getPosfromUid(uid);
+
+ MutexLocker scoped_lock(instance->clients_mutex);
+ unsigned short pos = instance->getPosfromUid(uid);
if( UID_NOT_FOUND == pos ) return;
-
+
instance->clients[pos]->flow=true;
// now they are a bonified part of the server, show the new stats
printStats();
@@ -400,10 +411,10 @@
memset(line, 0, 2048);
fgets (line, 2048, f);
linecounter++;
-
+
if(strnlen(line, 2048) <= 2)
continue;
-
+
// strip line (newline char)
char *ptr = line;
while(*ptr)
@@ -426,11 +437,11 @@
{
STACKLOG;
Sequencer* instance = Instance();
-
- MutexLocker scoped_lock(instance->clients_mutex);
- unsigned short pos = instance->getPosfromUid(uid);
+
+ MutexLocker scoped_lock(instance->clients_mutex);
+ unsigned short pos = instance->getPosfromUid(uid);
if( UID_NOT_FOUND == pos ) return;
-
+
for (unsigned int i=0; i<instance->clients.size(); i++)
{
if (i!=pos && instance->clients[i]->status == USED &&
@@ -446,7 +457,7 @@
strlen(instance->clients[i]->nickname) + 2 )),
message );
}
- // not possible to have flow enabled but not have a truck... disconnect
+ // not possible to have flow enabled but not have a truck... disconnect
if ( !strlen(instance->clients[i]->vehicle_name) &&
instance->clients[i]->flow )
{
@@ -461,7 +472,7 @@
void Sequencer::serverSay(std::string msg, int uid, int type)
{
STACKLOG;
- Sequencer* instance = Instance();
+ Sequencer* instance = Instance();
if(type==0)
msg = std::string("SERVER: ") + msg;
@@ -484,15 +495,15 @@
Sequencer* instance = Instance();
MutexLocker scoped_lock(instance->clients_mutex);
- unsigned short pos = instance->getPosfromUid(uid);
+ unsigned short pos = instance->getPosfromUid(uid);
if( UID_NOT_FOUND == pos ) return;
-
+
int publishMode=0;
// publishMode = 0 no broadcast
// publishMode = 1 broadcast to all clients
// publishMode = 2 broadcast to authed users (bots)
- if (type==MSG2_USE_VEHICLE)
+ if (type==MSG2_USE_VEHICLE)
{
data[len]=0;
strncpy(instance->clients[pos]->vehicle_name, data, 129);
@@ -503,7 +514,7 @@
len += (int)strlen(instance->clients[pos]->nickname) + 2;
publishMode = 1;
}
-
+
else if (type==MSG2_DELETE)
{
static int counter_crash=0, counter_deletes=0;
@@ -557,11 +568,11 @@
if( UID_NOT_FOUND == pos ) {
const char *error = "no user with that ID found!";
instance->clients[pos]->broadcaster-> queueMessage(
- 0, MSG2_RCON_COMMAND_FAILED,
+ 0, MSG2_RCON_COMMAND_FAILED,
(int)strlen(error), error );
} else {
instance->clients[pos]->broadcaster->queueMessage(
- -1, MSG2_GAME_CMD,
+ -1, MSG2_GAME_CMD,
(int)strlen(txtbuf), txtbuf);
}
return;
@@ -582,7 +593,7 @@
if( UID_NOT_FOUND == pos ) {
const char *error = "no user with that ID found!";
instance->clients[pos]->broadcaster-> queueMessage(
- 0, MSG2_RCON_COMMAND_FAILED,
+ 0, MSG2_RCON_COMMAND_FAILED,
(int)strlen(error), error );
} else {
instance->clients[pos]->broadcaster->queueMessage(
@@ -610,7 +621,7 @@
if( UID_NOT_FOUND == pos ) {
const char *error = "no user with that ID found!";
instance->clients[pos]->broadcaster-> queueMessage(
- 0, MSG2_RCON_COMMAND_FAILED,
+ 0, MSG2_RCON_COMMAND_FAILED,
(int)strlen(error), error );
} else {
instance->clients[pos]->broadcaster->queueMessage(
@@ -633,7 +644,7 @@
char txtbuf[1024] = "";
memset(txtbuf, 0, 1024);
sprintf(txtbuf, "setoverlayelementcolor %f, %f, %f, %f, %s", r, g, b, a, oname);
-
+
int pos = instance->getPosfromUid(userid);
if( UID_NOT_FOUND == pos ) {
const char *error = "no user with that ID found!";
@@ -642,7 +653,7 @@
(int)strlen(error), error );
} else {
instance->clients[pos]->broadcaster->queueMessage(
- -1, MSG2_GAME_CMD,
+ -1, MSG2_GAME_CMD,
(int)strlen(txtbuf), txtbuf);
}
}
@@ -678,7 +689,7 @@
if(!strncmp(data, "kick", 4))
{
int player = -1;
- int res = sscanf(data, "kick %d", &player);
+ int res = sscanf(data, "kick %d", &player);
if(res == 1 && player != -1 && player < (int)instance->clients.size())
{
if(instance->clients[player]->status == FREE ||
@@ -686,7 +697,7 @@
{
const char *error = "cannot kick free or busy client";
instance->clients[pos]->broadcaster->queueMessage(
- 0, MSG2_RCON_COMMAND_FAILED,
+ 0, MSG2_RCON_COMMAND_FAILED,
(int)strlen(error), error );
} else if(instance->clients[player]->status == USED) {
Logger::log(LOG_WARN, "user %d kicked by user %d via rcmd",
@@ -698,15 +709,15 @@
serverSay(std::string(tmp));
instance->clients[pos]->broadcaster->queueMessage(
- 0, MSG2_RCON_COMMAND_SUCCESS,
+ 0, MSG2_RCON_COMMAND_SUCCESS,
(int)strlen(tmp), tmp );
-
+
disconnect( instance->clients[player]->uid, "kicked" );
}
} else {
const char *error = "invalid client number";
instance->clients[pos]->broadcaster->queueMessage(
- 0, MSG2_RCON_COMMAND_FAILED,
+ 0, MSG2_RCON_COMMAND_FAILED,
(int)strlen(error), error );
}
}
@@ -717,7 +728,7 @@
MSG2_RCON_COMMAND_FAILED, 0, 0 );
serverSay("rcon command unkown");
}
-
+
publishMode=0;
}
else if (type==MSG2_CHAT)
@@ -755,7 +766,7 @@
0, MSG2_RCON_LOGIN_SUCCESS, 0, 0);
return;
}
-
+
if( !Config::hasAdmin() && instance->clients[pos]->rconretries < 3)
{
char pw[255]="";
@@ -767,7 +778,7 @@
{
Logger::log(LOG_WARN, "user %d logged into RCON", pos);
instance->clients[pos]->rconauth=1;
- instance->clients[pos]->broadcaster->queueMessage(
+ instance->clients[pos]->broadcaster->queueMessage(
0, MSG2_RCON_LOGIN_SUCCESS, 0, 0 );
}else
{
@@ -804,7 +815,7 @@
{
if(i >= instance->clients.size())
break;
- if (instance->clients[i]->status == USED &&
+ if (instance->clients[i]->status == USED &&
instance->clients[i]->flow &&
instance->clients[i]->uid==destuid)
instance->clients[i]->broadcaster->queueMessage(
@@ -812,7 +823,7 @@
}
publishMode=0;
}
-
+
if(publishMode>0)
{
if(publishMode == 1)
@@ -854,7 +865,7 @@
{
//this is glitched: the rest of the line is not cleared !!!
//I used to know what the problem was but I forgot it... I'll figure it out, eventually :)
- if (clients[i].status==FREE)
+ if (clients[i].status==FREE)
mvwprintw(win_slots, (i+3), 1, "%4i Free", i);
else if (clients[i].status==BUSY)
mvwprintw(win_slots, (i+3), 1, "%4i Busy %5i %-15s %.10s", i, clients[i].uid, "n/a", clients[i].nickname);
@@ -871,18 +882,18 @@
Logger::log(LOG_INFO, "--------------------------------------------------");
for (unsigned int i = 0; i < instance->clients.size(); i++)
{
- if (instance->clients[i]->status == FREE)
+ if (instance->clients[i]->status == FREE)
Logger::log(LOG_INFO, "%4i Free", i);
else if (instance->clients[i]->status == BUSY)
Logger::log(LOG_INFO, "%4i Busy %5i %-16s %s, %s", i,
- instance->clients[i]->uid, "-",
- instance->clients[i]->nickname,
+ instance->clients[i]->uid, "-",
+ instance->clients[i]->nickname,
instance->clients[i]->vehicle_name);
- else
- Logger::log(LOG_INFO, "%4i Used %5i %-16s %s, %s", i,
- instance->clients[i]->uid,
- instance->clients[i]->sock->get_peerAddr(&error).c_str(),
- instance->clients[i]->nickname,
+ else
+ Logger::log(LOG_INFO, "%4i Used %5i %-16s %s, %s", i,
+ instance->clients[i]->uid,
+ instance->clients[i]->sock->get_peerAddr(&error).c_str(),
+ instance->clients[i]->nickname,
instance->clients[i]->vehicle_name);
}
Logger::log(LOG_INFO, "--------------------------------------------------");
@@ -891,12 +902,12 @@
int upminutes = (timediff-(uphours*60*60))/60;
Logger::log(LOG_INFO, "- traffic statistics (uptime: %d hours, %d "
"minutes):", uphours, upminutes);
- Logger::log(LOG_INFO, "- total: incoming: %0.2fMB , outgoing: %0.2fMB",
- Messaging::getBandwitdthIncoming()/1024/1024,
+ Logger::log(LOG_INFO, "- total: incoming: %0.2fMB , outgoing: %0.2fMB",
+ Messaging::getBandwitdthIncoming()/1024/1024,
Messaging::getBandwidthOutgoing()/1024/1024);
Logger::log(LOG_INFO, "- rate (last minute): incoming: %0.1fkB/s , "
- "outgoing: %0.1fkB/s",
- Messaging::getBandwitdthIncomingRate()/1024,
+ "outgoing: %0.1fkB/s",
+ Messaging::getBandwitdthIncomingRate()/1024,
Messaging::getBandwidthOutgoingRate()/1024);
}
}
@@ -905,14 +916,14 @@
{
STACKLOG;
Sequencer* instance = Instance();
-
+
for (unsigned short i = 0; i < instance->clients.size(); i++)
{
if(instance->clients[i]->uid == uid)
return i;
}
-
- Logger::log( LOG_ERROR, "could not find uid %d", uid);
+
+ Logger::log( LOG_ERROR, "could not find uid %d", uid);
return UID_NOT_FOUND;
}
@@ -922,3 +933,46 @@
Instance()->notifier->unregisterServer();
}
+#if 0
+class student;
+
+class base_course
+{
+public:
+ virtual bool prereqs_met( const student& student ) { return false; }
+};
+
+class student
+{
+private:
+ std::vector<base_course> taken_courses;
+public:
+ bool has_taken( const base_course& course ) const
+ {
+ bool taken = false;
+ for( unsigned int i = 0; i < taken_courses.size() && !taken; i++ )
+ taken = ( taken_courses[i] == course );
+ return taken;
+ }
+};
+
+class elementary_course: public base_course
+{
+public:
+ bool prereqs_met( const student& student ) { return true; }
+};
+
+class complex_course : public base_course
+{
+private:
+ std::vector<base_course> required_courses;
+public:
+ bool prereqs_met( const student& student )
+ {
+ bool reqs_met = true;
+ for( unsigned int i = 0; i < required_courses.size() && reqs_met; i++ )
+ reqs_met = student.has_taken( required_courses[i] );
+ return reqs_met;
+ }
+};
+#endif
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|