Esempio n. 1
0
void TCPBase::NewConnection()
{
    if(IPCSocket)
    {
        // connection should be already finished
        return;
    }

    disconnect(IPCServer, SIGNAL(newConnection()), this, SLOT(NewConnection()));
    IPCSocket = IPCServer->nextPendingConnection();

    if(!IPCSocket) return;

    m_connected = true;

    connect(IPCSocket, SIGNAL(disconnected()), this, SLOT(ClientDisconnect()));
    connect(IPCSocket, SIGNAL(readyRead()), this, SLOT(ClientRead()));
    SendToClientFirst();

    if(simultaneousRun())
    {
        srvsList.removeOne(this);
        emit isReadyNow();
    }
}
Esempio n. 2
0
/**
 * Delete a specific bot
 * @param clientNum [int] bot client id
 */
void G_BotDel( int clientNum ) {
	gentity_t *ent;

	if(clientNum < 0) return;

	ent = &g_entities[clientNum];
	if( !( ent->r.svFlags & SVF_BOT ) ) {
		trap_Print( va("'^7%s^7' is not a bot\n", ent->client->pers.netname) );
		return;
	}
    G_BotDebug(ent, BOT_VERB_IMPORTANT, BOT_DEBUG_GENERAL, "Bot deleted\n");
	ent->inuse = qfalse;
	ent->r.svFlags = 0;
	//BG_Free(ent->bot->path.crumb); 
	if(ent->bot) {
		BG_Free(ent->bot);
	}
    //LEPE:
    if(ent->client->pers.teamSelection == TEAM_HUMANS && level.humanBots > 0) {
        level.humanBots--;
    } else if(ent->client->pers.teamSelection == TEAM_ALIENS && level.alienBots > 0) {
        level.alienBots--;
    }
	ClientDisconnect(clientNum);
}
Esempio n. 3
0
void ServerNetwork::disconnected() {
	QTcpSocket *socket = static_cast<QTcpSocket*>(sender());
	QByteArray *buffer = buffers.value(socket);
	auto clientId = clientManager->GetClient(socket);

	emit ClientDisconnect(clientId);

	qDebug().nospace() << "Disconnected: Instrument #" << clientId << " at " << qPrintable(socket->peerAddress().toString()) << ":" << socket->peerPort();

	clientManager->RemoveClient(socket);
	socket->deleteLater();
	delete buffer;
}
Esempio n. 4
0
int baseq3_qagame_vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11  ) {
#else
int vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11  ) {
#endif // IOS
	switch ( command ) {
	case GAME_INIT:
		G_InitGame( arg0, arg1, arg2 );
		return 0;
	case GAME_SHUTDOWN:
		G_ShutdownGame( arg0 );
		return 0;
	case GAME_CLIENT_CONNECT:
		return (int)ClientConnect( arg0, arg1, arg2 );
	case GAME_CLIENT_THINK:
		ClientThink( arg0 );
		return 0;
	case GAME_CLIENT_USERINFO_CHANGED:
		ClientUserinfoChanged( arg0 );
		return 0;
	case GAME_CLIENT_DISCONNECT:
		ClientDisconnect( arg0 );
		return 0;
	case GAME_CLIENT_BEGIN:
		ClientBegin( arg0 );
		return 0;
	case GAME_CLIENT_COMMAND:
		ClientCommand( arg0 );
		return 0;
	case GAME_RUN_FRAME:
		G_RunFrame( arg0 );
		return 0;
	case GAME_CONSOLE_COMMAND:
		return ConsoleCommand();
	case BOTAI_START_FRAME:
		return BotAIStartFrame( arg0 );
	}

	return -1;
}


void QDECL G_Printf( const char *fmt, ... ) {
	va_list		argptr;
	char		text[1024];

	va_start (argptr, fmt);
	vsprintf (text, fmt, argptr);
	va_end (argptr);

	trap_Printf( text );
}
Esempio n. 5
0
void ServerSystem::Update( double DeltaTime )
{
    PerfTimer.Log( "server update started" );
    ENetEvent event;
    while( enet_host_service ( mServer, & event, 0 ) > 0 )
    {
        //PerfTimer.Log("server enter");
        switch ( event.type )
        {
        case ENET_EVENT_TYPE_CONNECT:
            ClientConnect( event );
            break;
        case ENET_EVENT_TYPE_RECEIVE:
            Receive( event );
            break;

        case ENET_EVENT_TYPE_DISCONNECT:
            ClientDisconnect( event );
            break;
        }
    }
    PerfTimer.Log( "server receive ended" );

    MessageList& messages = mMessageHolder.GetOutgoingMessages();
    if ( messages.mMessages.size() > 0 )
    {
        std::ostringstream oss;
        eos::portable_oarchive oa( oss );
        oa& messages;
        std::string astr( oss.str() );
        // L1("server sends - %s:\n",astr.c_str());
        ENetPacket* packet = enet_packet_create ( astr.c_str(),
                             astr.size(),
                             ENET_PACKET_FLAG_RELIABLE );
        mSentMessagesSize += packet->dataLength * mClients.size();

        enet_host_broadcast( mServer, 0, packet );
        enet_host_flush( mServer );
        mMessageHolder.ClearOutgoingMessages();
    }
    PerfTimer.Log( "server update ended" );

}
/*
================
vmMain

This is the only way control passes into the module.
This must be the very first function compiled into the .q3vm file
================
*/
Q_EXPORT intptr_t vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11  ) {
	switch ( command ) {
	case GAME_INIT:
		G_InitGame( arg0, arg1, arg2 );
		return 0;
	case GAME_SHUTDOWN:
		G_ShutdownGame( arg0 );
		return 0;
	case GAME_CLIENT_CONNECT:
		return (intptr_t)ClientConnect( arg0, arg1, arg2 );
	case GAME_CLIENT_THINK:
		ClientThink( arg0 );
		return 0;
	case GAME_CLIENT_USERINFO_CHANGED:
		ClientUserinfoChanged( arg0 );
		return 0;
	case GAME_CLIENT_DISCONNECT:
		ClientDisconnect( arg0 );
		return 0;
	case GAME_CLIENT_BEGIN:
		ClientBegin( arg0 );
		return 0;
	case GAME_CLIENT_COMMAND:
		ClientCommand( arg0 );
		return 0;
	case GAME_RUN_FRAME:
		G_RunFrame( arg0 );
		return 0;
	case GAME_CONSOLE_COMMAND:
		return ConsoleCommand();
	case BOTAI_START_FRAME:
		return BotAIStartFrame( arg0 );
	}

	return -1;
}
Esempio n. 7
0
/**
Called when a player begins connecting to the server.
Called again for every map change or tournement restart.

The session information will be valid after exit.

Return NULL if the client should be allowed, otherwise return
a string with the reason for denial.

Otherwise, the client will be sent the current gamestate
and will eventually get to ClientBegin.

firstTime will be qtrue the very first time a client connects
to the server machine, but qfalse on map changes and tournement
restarts.
*/
char *ClientConnect(int clientNum, qboolean firstTime, qboolean isBot)
{
	char		name[MAX_NETNAME];
	char		*value, *nameError;
	gclient_t	*client;
	char		userinfo[MAX_INFO_STRING];
	gentity_t	*ent;

	ent = &g_entities[ clientNum ];

	trap_GetUserinfo(clientNum, userinfo, sizeof(userinfo));

	if (G_BanCheck(userinfo)) {
		return "You are banned from this server.";
	}

	value = Info_ValueForKey(userinfo, "ip");

	nameError = Info_ValueForKey(userinfo, "name");
	nameError = ClientCleanName(nameError, name, sizeof name);

	// we don't check password for bots and local client
	// NOTE: local client <-> "ip" "localhost"
	// this means this client is not running in our current process
	if (!isBot && strcmp(value, "localhost")) {
		// check for invalid player name
		if (nameError) {
			return nameError;
		}

		// check for a password
		value = Info_ValueForKey (userinfo, "password");
		if (g_password.string[0] && Q_stricmp(g_password.string, "none") &&
			strcmp(g_password.string, value) != 0)
		{
			return "Invalid password";
		}
	}
	// if a player reconnects quickly after a disconnect, the client disconnect may never be called, thus flag can get lost in the ether
	if (ent->inuse) {
		G_LogPrintf("Forcing disconnect on active client: %i\n", clientNum);
		// so lets just fix up anything that should happen on a disconnect
		ClientDisconnect(clientNum);
	}
	// they can connect
	ent->client = level.clients + clientNum;
	client = ent->client;

	memset(client, 0, sizeof(*client));

	client->pers.connected = CON_CONNECTING;

	// read or initialize the session data
	if (firstTime || level.newSession) {
		G_InitSessionData(client, userinfo);
	}
	G_ReadSessionData(client);

	if (isBot) {
		ent->r.svFlags |= SVF_BOT;
		ent->inuse = qtrue;
		if (!G_BotConnect(clientNum, !firstTime)) {
			return "BotConnectfailed";
		}
	}

	// don't do the "xxx connected" messages if they were caried over from previous level
	if (firstTime) {
		ClientScreenPrint(NULL, "%s ^7connected", name);
	}

	// get and distribute relevent paramters
	G_LogPrintf("ClientConnect: %i\n", clientNum);
	ClientUserinfoChanged(clientNum);

	if (g_gametype.integer >= GT_TEAM && client->sess.sessionTeam != TEAM_SPECTATOR) {
		LogTeamChange(client, -1);
	}

	// count current clients and rank for scoreboard
	CalculateRanks();

	return NULL;
}
Esempio n. 8
0
/*
================
vmMain

This is the only way control passes into the module.
This must be the very first function compiled into the .q3vm file
================
*/
int vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5,
	    int arg6, int arg7, int arg8, int arg9, int arg10, int arg11 )
{
	ClearGlobals();
	switch ( command )
	{
	case GAME_INIT:
		if ( trap_GetApiVersion() < GAME_API_VERSION )
			return 0;

		G_InitGame( arg0, arg1 );
		return ( int ) ( &gamedata );

	case GAME_LOADENTS:
		G_SpawnEntitiesFromString();
		return 1;

	case GAME_START_FRAME:
		StartFrame( arg0 );
		return 1;

	case GAME_CLIENT_CONNECT:
		self = PROG_TO_EDICT( g_globalvars.self );
		if ( arg0 )
			SpectatorConnect();
		else
			ClientConnect();
		return 1;

	case GAME_PUT_CLIENT_IN_SERVER:
		self = PROG_TO_EDICT( g_globalvars.self );
		if ( !arg0 )
			PutClientInServer();
		return 1;

	case GAME_CLIENT_DISCONNECT:
		self = PROG_TO_EDICT( g_globalvars.self );
		if ( arg0 )
			SpectatorDisconnect();
		else
			ClientDisconnect();
		return 1;

	case GAME_SETNEWPARMS:
		SetNewParms();
		return 1;

	case GAME_CLIENT_PRETHINK:
		self = PROG_TO_EDICT( g_globalvars.self );
		if ( !arg0 )
			PlayerPreThink();
		return 1;

	case GAME_CLIENT_POSTTHINK:
		self = PROG_TO_EDICT( g_globalvars.self );
		if ( !arg0 )
			PlayerPostThink();
		else
			SpectatorThink();
		return 1;

	case GAME_EDICT_TOUCH:
		G_EdictTouch();
		return 1;

	case GAME_EDICT_THINK:
		G_EdictThink();
		return 1;

	case GAME_EDICT_BLOCKED:
		G_EdictBlocked();
		return 1;

	case GAME_SETCHANGEPARMS:
		self = PROG_TO_EDICT( g_globalvars.self );
		SetChangeParms();
		return 1;

	case GAME_CLIENT_COMMAND:

		return ClientCommand();

/*	case GAME_SHUTDOWN:
		G_ShutdownGame( arg0 );
		return 0;
	case GAME_CLIENT_USERINFO_CHANGED:
		ClientUserinfoChanged( arg0 );
		return 0;
	case GAME_CONSOLE_COMMAND:
		return ConsoleCommand();*/
	}

	return 0;
}
Esempio n. 9
0
void
ServerGame::clientDisconnect( int clientNum ) const
{
	ClientDisconnect( clientNum );
}
Esempio n. 10
0
int vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5,
            int arg6, int arg7, int arg8, int arg9, int arg10, int arg11 )
{
    ClearGlobals();
    switch ( command )
    {
    case GAME_INIT:
        api_ver = trap_GetApiVersion();
        if ( api_ver < MIN_API_VERSION )
        {
            G_conprintf("Mod requried API_VERSION %d or higher, server have %d\n", MIN_API_VERSION, api_ver);
            return 0;
        }
        if( api_ver >= MIN_API_VERSION && api_ver <= GAME_API_VERSION )
        {
            gamedata.APIversion = api_ver;
        }
        G_InitGame( arg0, arg1 );
        return ( int ) ( &gamedata );

    case GAME_LOADENTS:
        G_SpawnEntitiesFromString();
        return 1;

    case GAME_START_FRAME:
        StartFrame( arg0 );
        return 1;

    case GAME_CLIENT_CONNECT:
        self = PROG_TO_EDICT( g_globalvars.self );
        self->auth_time = g_globalvars.time + 10.0;
        self->isSpectator = arg0?1:0;
        if ( arg0 )
            SpectatorConnect();
        else
            ClientConnect();
        return 1;

    case GAME_PUT_CLIENT_IN_SERVER:
        self = PROG_TO_EDICT( g_globalvars.self );
        if ( !arg0 )
            PutClientInServer();
        return 1;

    case GAME_CLIENT_DISCONNECT:
        self = PROG_TO_EDICT( g_globalvars.self );
        if ( arg0 )
            SpectatorDisconnect();
        else
            ClientDisconnect();
        return 1;

    case GAME_SETNEWPARMS:
        SetNewParms();
        return 1;

    case GAME_CLIENT_PRETHINK:
        self = PROG_TO_EDICT( g_globalvars.self );
        if ( !arg0 )
            PlayerPreThink();
        return 1;

    case GAME_CLIENT_POSTTHINK:
        self = PROG_TO_EDICT( g_globalvars.self );
        if ( !arg0 )
            PlayerPostThink();
        else
            SpectatorThink();
        return 1;

    case GAME_EDICT_TOUCH:
        G_EdictTouch();
        return 1;

    case GAME_EDICT_THINK:
        G_EdictThink();
        return 1;

    case GAME_EDICT_BLOCKED:
        G_EdictBlocked();
        return 1;

    case GAME_SETCHANGEPARMS: //called before spawn new server for save client params
        self = PROG_TO_EDICT( g_globalvars.self );
        SetChangeParms();
        return 1;

    case GAME_CLIENT_COMMAND:
        self = PROG_TO_EDICT( g_globalvars.self );
        return ClientCommand();

    case GAME_CLIENT_USERINFO_CHANGED:
        // called on user /cmd setinfo	if value changed
        // return not zero dont allow change
        // params like GAME_CLIENT_COMMAND, but argv(0) always "setinfo" and argc always 3

        self = PROG_TO_EDICT( g_globalvars.self );
        return ClientUserInfoChanged();

    case GAME_SHUTDOWN:
        return 0;

    case GAME_CONSOLE_COMMAND:

        // called on server console command "mod"
        // params like GAME_CLIENT_COMMAND, but argv(0) always "mod"
        // self - rconner if can detect else world
        // other
        //SV_CMD_CONSOLE		0
        //SV_CMD_RCON			1
        //SV_CMD_MASTER		2
        //SV_CMD_BOT			3
        self = PROG_TO_EDICT( g_globalvars.self );
        ModCommand();
        return 0;
    }

    return 0;
}
Esempio n. 11
0
/*
===========
ClientConnect

Called when a player begins connecting to the server.
Called again for every map change or tournement restart.

The session information will be valid after exit.

Return nullptr if the client should be allowed, otherwise return
a string with the reason for denial.

Otherwise, the client will be sent the current gamestate
and will eventually get to ClientBegin.

firstTime will be true the very first time a client connects
to the server machine, but false on map changes and tournement
restarts.
============
*/
const char *ClientConnect( int clientNum, bool firstTime )
{
	const char      *value;
	const char      *userInfoError;
	gclient_t       *client;
	char            userinfo[ MAX_INFO_STRING ];
	char            pubkey[ RSA_STRING_LENGTH ];
	gentity_t       *ent;
	char            reason[ MAX_STRING_CHARS ] = { "" };
	int             i;
	const char      *country;

	ent = &g_entities[ clientNum ];
	client = &level.clients[ clientNum ];

	// ignore if client already connected
	if ( client->pers.connected != CON_DISCONNECTED )
	{
		return nullptr;
	}

	ent->client = client;
	memset( client, 0, sizeof( *client ) );

	trap_GetUserinfo( clientNum, userinfo, sizeof( userinfo ) );

	value = Info_ValueForKey( userinfo, "ip" );

	// check for local client
	if ( !strcmp( value, "localhost" ) )
	{
		client->pers.localClient = true;
	}

	G_AddressParse( value, &client->pers.ip );

	trap_GetPlayerPubkey( clientNum, pubkey, sizeof( pubkey ) );

	if ( strlen( pubkey ) != RSA_STRING_LENGTH - 1 )
	{
		return "Invalid pubkey key";
	}

	trap_GenFingerprint( pubkey, sizeof( pubkey ), client->pers.guid, sizeof( client->pers.guid ) );
	client->pers.admin = G_admin_admin( client->pers.guid );

	client->pers.pubkey_authenticated = false;

	if ( client->pers.admin )
	{
		Com_GMTime( &client->pers.admin->lastSeen );
	}

	// check for admin ban
	if ( G_admin_ban_check( ent, reason, sizeof( reason ) ) )
	{
		return va( "%s", reason ); // reason is local
	}

	// check for a password
	value = Info_ValueForKey( userinfo, "password" );

	if ( g_password.string[ 0 ] && Q_stricmp( g_password.string, "none" ) &&
	     strcmp( g_password.string, value ) != 0 )
	{
		return "Invalid password";
	}

	// if a player reconnects quickly after a disconnect, the client disconnect may never be called, thus flag can get lost in the ether
	if ( ent->inuse )
	{
		G_LogPrintf( "Forcing disconnect on active client: %i", (int)( ent - g_entities ) );
		// so lets just fix up anything that should happen on a disconnect
		ClientDisconnect( ent-g_entities );
	}

	for ( i = 0; i < level.maxclients; i++ )
	{
		if ( level.clients[ i ].pers.connected == CON_DISCONNECTED )
		{
			continue;
		}

		if ( !( g_entities[i].r.svFlags & SVF_BOT ) && !Q_stricmp( client->pers.guid, level.clients[ i ].pers.guid ) )
		{
			if ( !G_ClientIsLagging( level.clients + i ) )
			{
				trap_SendServerCommand( i, "cp \"Your GUID is not secure\"" );
				return "Duplicate GUID";
			}

			trap_DropClient( i, "Ghost" );
		}
	}

	client->pers.connected = CON_CONNECTING;

	// read or initialize the session data
	if ( firstTime )
	{
		G_InitSessionData( client, userinfo );
	}

	G_ReadSessionData( client );

	// get and distribute relevent paramters
	G_namelog_connect( client );
	userInfoError = ClientUserinfoChanged( clientNum, false );

	if ( userInfoError != nullptr )
	{
		return userInfoError;
	}

	G_LogPrintf( "ClientConnect: %i [%s] (%s) \"%s^7\" \"%s^7\"",
	             clientNum, client->pers.ip.str[0] ? client->pers.ip.str : "127.0.0.1", client->pers.guid,
	             client->pers.netname,
	             client->pers.netname );

	country = Info_ValueForKey( userinfo, "geoip" );
	Q_strncpyz( client->pers.country, country, sizeof( client->pers.country ) );

	G_SendClientPmoveParams(clientNum);

	// don't do the "xxx connected" messages if they were caried over from previous level
	if ( firstTime )
	{
		if ( g_geoip.integer && country && *country )
		{
			trap_SendServerCommand( -1, va( "print_tr %s %s %s", QQ( N_("$1$^7 connected from $2$") ),
			                                Quote( client->pers.netname ), Quote( country ) ) );
		}
		else
		{
			trap_SendServerCommand( -1, va( "print_tr %s %s", QQ( N_("$1$^7 connected") ),
			                                Quote( client->pers.netname ) ) );
		}
	}

	// count current clients and rank for scoreboard
	CalculateRanks();

	// if this is after !restart keepteams or !restart switchteams, apply said selection
	if ( client->sess.restartTeam != TEAM_NONE )
	{
		G_ChangeTeam( ent, client->sess.restartTeam );
		client->sess.restartTeam = TEAM_NONE;
	}

	return nullptr;
}
Esempio n. 12
0
void VM::VMHandleSyscall(uint32_t id, Util::Reader reader) {

	int major = id >> 16;
	int minor = id & 0xffff;
	if (major == VM::QVM) {
		switch (minor) {
		case GAME_STATIC_INIT:
			IPC::HandleMsg<GameStaticInitMsg>(VM::rootChannel, std::move(reader), [] (int milliseconds) {
				VM::InitializeProxies(milliseconds);
				FS::Initialize();
				VM::VMInit();
			});
			break;

		case GAME_INIT:
			IPC::HandleMsg<GameInitMsg>(VM::rootChannel, std::move(reader), [](int levelTime, int randomSeed, bool cheats, bool inClient) {
				g_cheats.integer = cheats;
				G_InitGame(levelTime, randomSeed, inClient);
			});
			break;

		case GAME_SHUTDOWN:
			IPC::HandleMsg<GameShutdownMsg>(VM::rootChannel, std::move(reader), [](bool restart) {
				G_ShutdownGame(restart);
			});
			break;

		case GAME_CLIENT_CONNECT:
			IPC::HandleMsg<GameClientConnectMsg>(VM::rootChannel, std::move(reader), [](int clientNum, bool firstTime, int isBot, bool& denied, std::string& reason) {
				const char* deniedStr = isBot ? ClientBotConnect(clientNum, firstTime, TEAM_NONE) : ClientConnect(clientNum, firstTime);
				denied = deniedStr != nullptr;
				if (denied)
					reason = deniedStr;
			});
			break;

		case GAME_CLIENT_THINK:
			IPC::HandleMsg<GameClientThinkMsg>(VM::rootChannel, std::move(reader), [](int clientNum) {
				ClientThink(clientNum);
			});
			break;

		case GAME_CLIENT_USERINFO_CHANGED:
			IPC::HandleMsg<GameClientUserinfoChangedMsg>(VM::rootChannel, std::move(reader), [](int clientNum) {
				ClientUserinfoChanged(clientNum, false);
			});
			break;

		case GAME_CLIENT_DISCONNECT:
			IPC::HandleMsg<GameClientDisconnectMsg>(VM::rootChannel, std::move(reader), [](int clientNum) {
				ClientDisconnect(clientNum);
			});
			break;

		case GAME_CLIENT_BEGIN:
			IPC::HandleMsg<GameClientBeginMsg>(VM::rootChannel, std::move(reader), [](int clientNum) {
				ClientBegin(clientNum);
			});
			break;

		case GAME_CLIENT_COMMAND:
			IPC::HandleMsg<GameClientCommandMsg>(VM::rootChannel, std::move(reader), [](int clientNum, std::string command) {
				Cmd::PushArgs(command);
				ClientCommand(clientNum);
				Cmd::PopArgs();
			});
			break;

		case GAME_RUN_FRAME:
			IPC::HandleMsg<GameRunFrameMsg>(VM::rootChannel, std::move(reader), [](int levelTime) {
				G_RunFrame(levelTime);
			});
			break;

		case GAME_SNAPSHOT_CALLBACK:
			G_Error("GAME_SNAPSHOT_CALLBACK not implemented");
			break;

		case BOTAI_START_FRAME:
			G_Error("BOTAI_START_FRAME not implemented");
			break;

		case GAME_MESSAGERECEIVED:
			G_Error("GAME_MESSAGERECEIVED not implemented");
			break;

		default:
			G_Error("VMMain(): unknown game command %i", minor);
		}
	} else if (major < VM::LAST_COMMON_SYSCALL) {
		VM::HandleCommonSyscall(major, minor, std::move(reader), VM::rootChannel);
	} else {
		G_Error("unhandled VM major syscall number %i", major);
	}
}
Esempio n. 13
0
/*
===========
ClientConnect

Called when a player begins connecting to the server.
Called again for every map change or tournement restart.

The session information will be valid after exit.

Return NULL if the client should be allowed, otherwise return
a string with the reason for denial.

Otherwise, the client will be sent the current gamestate
and will eventually get to ClientBegin.

firstTime will be true the very first time a client connects
to the server machine, but false on map changes and tournement
restarts.
============
*/
char *ClientConnect( int clientNum, bool firstTime, bool isBot ) {
	char		*value;
//	char		*areabits;
	gclient_t	*client;
	char		userinfo[MAX_INFO_STRING];
	gentity_t	*ent;

	ent = &g_entities[ clientNum ];

	trap->GetUserinfo( clientNum, userinfo, sizeof( userinfo ) );

 	// IP filtering
 	// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=500
 	// recommanding PB based IP / GUID banning, the builtin system is pretty limited
 	// check to see if they are on the banned IP list
	value = Info_ValueForKey (userinfo, "ip");
	if ( G_FilterPacket( value ) ) {
		return "You are banned from this server.";
	}

  // we don't check password for bots and local client
  // NOTE: local client <-> "ip" "localhost"
  //   this means this client is not running in our current process
	if ( !isBot && (strcmp(value, "localhost") != 0)) {
		// check for a password
		value = Info_ValueForKey (userinfo, "password");
		if ( g_password.string[0] && Q_stricmp( g_password.string, "none" ) &&
			strcmp( g_password.string, value) != 0) {
			return "Invalid password";
		}
	}
	// if a player reconnects quickly after a disconnect, the client disconnect may never be called, thus flag can get lost in the ether
	if (ent->inuse) {
		G_LogPrintf("Forcing disconnect on active client: %i\n", clientNum);
		// so lets just fix up anything that should happen on a disconnect
		ClientDisconnect(clientNum);
	}
	// they can connect
	ent->client = level.clients + clientNum;
	client = ent->client;

//	areabits = client->areabits;

	memset( client, 0, sizeof(*client) );

	client->pers.connected = CON_CONNECTING;

	// read or initialize the session data
	if ( firstTime || level.newSession ) {
		G_InitSessionData( client, userinfo );
	}
	G_ReadSessionData( client );

	if( isBot ) {
		ent->r.svFlags |= SVF_BOT;
		ent->inuse = true;
		if( !G_BotConnect( clientNum, !firstTime ) ) {
			return "BotConnectfailed";
		}
	}

	// get and distribute relevent paramters
	G_LogPrintf( "ClientConnect: %i\n", clientNum );
	ClientUserinfoChanged( clientNum );

	// don't do the "xxx connected" messages if they were caried over from previous level
	if ( firstTime ) {
		trap->SendServerCommand( -1, va("print \"%s" S_COLOR_WHITE " connected\n\"", client->pers.netname) );
	}

	if ( g_gametype.integer >= GT_TEAM &&
		client->sess.sessionTeam != TEAM_SPECTATOR ) {
		BroadcastTeamChange( client, -1 );
	}

	// count current clients and rank for scoreboard
	CalculateRanks();

	// for statistics
//	client->areabits = areabits;
//	if ( !client->areabits )
//		client->areabits = G_Alloc( (botlib->aas.AAS_PointReachabilityAreaIndex( NULL ) + 7) / 8 );

	return NULL;
}
Esempio n. 14
0
void __cdecl My_ClientDisconnect(int clientNum) {
	ClientDisconnectDispatcher(clientNum);

	ClientDisconnect(clientNum);
}
Esempio n. 15
0
void TCPBase::StartProcessError(QProcess::ProcessError error)
{
    MessageDialog::ShowFatalMessage(tr("Unable to run engine at %1\nError code: %2").arg(bindir->absolutePath() + "/hwengine").arg(error));
    ClientDisconnect();
}
Esempio n. 16
0
/**
 * Removes and add again a Bot (unused?)
 * @param self [gentity_t] a BOT
 */
void G_BotReload( gentity_t *ent, int clientNum )
{
	ClientDisconnect( clientNum );
	G_BotAdd( ent->client->pers.netname, ent->client->pers.teamSelection );
	trap_SendServerCommand( -1, "print \"Interfering bot reloaded\n\"" );
}
Esempio n. 17
0
// Module RPC entry point
static void VMMain(int index, RPC::Reader& inputs, RPC::Writer& outputs)
{
	switch (index) {
	case GAME_INIT:
	{
		int levelTime = inputs.ReadInt();
		int randomSeed = inputs.ReadInt();
		qboolean restart = inputs.ReadInt();
		G_InitGame(levelTime, randomSeed, restart);
		break;
	}

	case GAME_SHUTDOWN:
		G_ShutdownGame(inputs.ReadInt());
		break;

	case GAME_CLIENT_CONNECT:
	{
		int clientNum = inputs.ReadInt();
		qboolean firstTime = inputs.ReadInt();
		qboolean isBot = inputs.ReadInt();
		const char* denied = isBot ? ClientBotConnect(clientNum, firstTime, TEAM_NONE) : ClientConnect(clientNum, firstTime);
		outputs.WriteInt(denied ? qtrue : qfalse);
		if (denied)
			outputs.WriteString(denied);
		break;
	}

	case GAME_CLIENT_THINK:
		ClientThink(inputs.ReadInt());
		break;

	case GAME_CLIENT_USERINFO_CHANGED:
		ClientUserinfoChanged(inputs.ReadInt(), qfalse);
		break;

	case GAME_CLIENT_DISCONNECT:
		ClientDisconnect(inputs.ReadInt());
		break;

	case GAME_CLIENT_BEGIN:
		ClientBegin(inputs.ReadInt());
		break;

	case GAME_CLIENT_COMMAND:
		ClientCommand(inputs.ReadInt());
		break;

	case GAME_RUN_FRAME:
		G_RunFrame(inputs.ReadInt());
		break;

	case GAME_CONSOLE_COMMAND:
		outputs.WriteInt(ConsoleCommand());
		break;

	case GAME_SNAPSHOT_CALLBACK:
		G_Error("GAME_SNAPSHOT_CALLBACK not implemented");
		break;

	case BOTAI_START_FRAME:
		G_Error("BOTAI_START_FRAME not implemented");
		break;

	case GAME_MESSAGERECEIVED:
		G_Error("GAME_MESSAGERECEIVED not implemented");
		break;

	default:
		G_Error("VMMain(): unknown game command %i", index);
	}
}
Esempio n. 18
0
/*
===========
ClientConnect

Called when a player begins connecting to the server.
Called again for every map change or tournement restart.

The session information will be valid after exit.

Return NULL if the client should be allowed, otherwise return
a string with the reason for denial.

Otherwise, the client will be sent the current gamestate
and will eventually get to ClientBegin.

firstTime will be qtrue the very first time a client connects
to the server machine, but qfalse on map changes and tournement
restarts.
============
*/
char *ClientConnect(int clientNum, qboolean firstTime) {
	char      *value;
	gclient_t *client;
	char      userinfo[MAX_INFO_STRING];
	gentity_t *ent;
	char      userinfo2[MAX_INFO_STRING]; // Nico, used in connections limit check
	int       i = 0;
	int       clientNum2; // Nico, used in connections limit check
	int       conn_per_ip = 1; // Nico, connections per IP counter
	char      ip[20], ip2[20]; // Nico, used in connections limit check
	char      parsedIp[20], parsedIp2[20]; // Nico, used in connections limit check
	char      cs_name[MAX_NETNAME];

	ent = &g_entities[clientNum];

	trap_GetUserinfo(clientNum, userinfo, sizeof (userinfo));

	// IP filtering
	// show_bug.cgi?id=500
	// recommanding PB based IP / GUID banning, the builtin system is pretty limited
	// check to see if they are on the banned IP list
	value = Info_ValueForKey(userinfo, "ip");
	if (G_FilterIPBanPacket(value)) {
		return "You are banned from this server.";
	}

	// Nico, check maximum connections per IP (from ETpub)
	// (prevents fakeplayers DOS http://aluigi.altervista.org/fakep.htm )
	// note: value is the client ip
	if (!getParsedIp(value, parsedIp)) {
		return "Invalid IP address";
	}
	Q_strncpyz(ip, parsedIp, sizeof (ip));
	for (i = 0; i < level.numConnectedClients; ++i) {
		clientNum2 = level.sortedClients[i];
		if (clientNum == clientNum2) {
			continue;
		}
		trap_GetUserinfo(clientNum2, userinfo2, sizeof (userinfo2));
		value = Info_ValueForKey(userinfo2, "ip");
		if (!getParsedIp(value, parsedIp2)) {
			continue;
		}
		Q_strncpyz(ip2, parsedIp2, sizeof (ip2));
		if (strcmp(ip, ip2) == 0) {
			conn_per_ip++;
		}
	}
	if (conn_per_ip > g_maxConnsPerIP.integer) {
		G_LogPrintf("%s: possible DoS attack, rejecting client from %s (%d connections already)\n", GAME_VERSION, ip, g_maxConnsPerIP.integer);
		return "Too many connections from your IP.";
	}
	// Nico, end of check maximum connections per IP

	// Nico, check name
	value = Info_ValueForKey(userinfo, "name");
	Q_strncpyz(cs_name, value, sizeof (cs_name));
	if (CheckName(cs_name) != qtrue) {
		return "Bad name: extended ASCII characters or too long name. Please change your name.";
	}

	// we don't check password for bots and local client
	// NOTE: local client <-> "ip" "localhost"
	//   this means this client is not running in our current process
	if (strcmp(Info_ValueForKey(userinfo, "ip"), "localhost") != 0) {
		// check for a password
		value = Info_ValueForKey(userinfo, "password");
		if (g_password.string[0] &&
			Q_stricmp(g_password.string, "none") &&
			strcmp(g_password.string, value) != 0 &&
			(!sv_privatepassword.string[0] || strcmp(sv_privatepassword.string, value) != 0)) {
			return "Invalid password";
		}
	}

	// Gordon: porting q3f flag bug fix
	// If a player reconnects quickly after a disconnect, the client disconnect may never be called, thus flag can get lost in the ether
	if (ent->inuse) {
		G_LogPrintf("Forcing disconnect on active client: %d\n", (int)(ent - g_entities));
		// so lets just fix up anything that should happen on a disconnect
		ClientDisconnect(ent - g_entities);
	}

	// they can connect
	ent->client = level.clients + clientNum;
	client      = ent->client;

	memset(client, 0, sizeof (*client));

	client->pers.connected   = CON_CONNECTING;

	// read or initialize the session data
	if (firstTime) {
		G_InitSessionData(client);
		client->pers.enterTime            = level.time;
		client->ps.persistant[PERS_SCORE] = 0;
	} else {
		G_ReadSessionData(client);
	}
	client->pers.enterTime = level.time;

	if (firstTime) {
		// force into spectator
		client->sess.sessionTeam     = TEAM_SPECTATOR;
		client->sess.spectatorState  = SPECTATOR_FREE;
		client->sess.spectatorClient = 0;

		// unlink the entity - just in case they were already connected
		trap_UnlinkEntity(ent);
	}

	// Nico, GeoIP
	if (gidb != NULL) {
		value = Info_ValueForKey (userinfo, "ip");
		if (!strcmp(value, "localhost")) {
			client->sess.countryCode = 0;
		} else {
			char realIP[IP_MAX_LENGTH] = {0};// Nico, used to store IP without :port
			unsigned long ip;

			// Nico, remove :port from IP
			sscanf(value, "%15[0-9.]:%*d", realIP);

			ip = GeoIP_addr_to_num(realIP);

			if (((ip & 0xFF000000) == 0x0A000000) ||
				((ip & 0xFFF00000) == 0xAC100000) ||
				((ip & 0xFFFF0000) == 0xC0A80000) ||
				( ip == 0x7F000001) ) {
				client->sess.countryCode = 246;
			} else {
				unsigned int ret = GeoIP_seek_record(gidb, ip);
				if (ret > 0) {
					client->sess.countryCode = ret;
				} else {
					client->sess.countryCode = 246;
					G_LogPrintf("GeoIP: This IP:%s cannot be located\n", realIP);
				}
			}
		}
	} else {
		client->sess.countryCode = 255;
	}
	// Nico, end of GeoIP

	// get and distribute relevent paramters
	G_LogPrintf("ClientConnect: %i\n", clientNum);
	G_UpdateCharacter(client);
	ClientUserinfoChanged(clientNum);

	// don't do the "xxx connected" messages if they were caried over from previous level
	//		TAT 12/10/2002 - Don't display connected messages in single player

	if (firstTime) {
		trap_SendServerCommand(-1, va("cpm \"%s" S_COLOR_WHITE " connected\n\"", client->pers.netname));
	}

	// count current clients and rank for scoreboard
	CalculateRanks();

	return NULL;
}
Esempio n. 19
0
void CGameServer::ClientDisconnect(int iConnection, CNetworkParameters* p)
{
	TAssert(iConnection == CONNECTION_GAME);

	ClientDisconnect(p->i1);
}