[Opentnl-cvs] tnl/master Makefile,NONE,1.1 main.cpp,NONE,1.1 master.dsp,NONE,1.1 master.vcproj,NONE,
Brought to you by:
mark_frohnmayer,
s_alanet
From: Ben G. <s_a...@us...> - 2004-04-20 04:27:26
|
Update of /cvsroot/opentnl/tnl/master In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31063/master Added Files: Makefile main.cpp master.dsp master.vcproj masterInterface.cpp masterInterface.h Log Message: Initial commit. --- NEW FILE: masterInterface.h --- //----------------------------------------------------------------------------------- // // Torque Network Library - Master Server // Copyright (C) 2004 GarageGames.com, Inc. // For more information see http://www.opentnl.org // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // For use in products that are not compatible with the terms of the GNU // General Public License, alternative licensing options are available // from GarageGames.com. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // //------------------------------------------------------------------------------------ #ifndef _MASTERINTERFACE_H_ #define _MASTERINTERFACE_H_ #include "tnlEventConnection.h" #include "tnlRPC.h" using namespace TNL; // Useful string constants... static const char *MasterNoSuchHost = "No Such Host"; static const char *MasterRequestTimedOut = "Timed Out"; enum MasterConstants { ConnectRequestTimeout = 30000, IPMessageAddressCount = 30, GameMissionTypesPerPacket = 20, }; /// The MasterServerInterface is the RPC interface to the TNL example Master Server. /// The default Master Server tracks a list of public servers and allows clients /// to query for them based on different filter criteria, including maximum number of players, /// region codes, game or mission type, and others. /// /// When a client wants to initiate a connection with a server listed by the master, it /// can ask the Master Server to arranage a connection. The masterclient example that /// ships with TNL demonstrates a client/server console application that uses the Master /// Server to arrange connections between a client and a server instance. /// /// Client/Server programs using the Master Server for server listing should create /// a subclass of MasterServerInterface named "MasterServerConnection", and override /// all of the RPC methods that begin with m2c, as they signify master to client messages. /// RPC methods can be overridden with the TNL_DECLARE_RPC_OVERRIDE and TNL_IMPLEMENT_RPC_OVERRIDE methods. class MasterServerInterface : public EventConnection { protected: public: enum { MasterServerInterfaceVersion = 1, }; /// c2mQueryGameTypes is sent from the client to the master to request a list of /// game and mission types that current game servers are reporting. The queryId /// is specified by the client to identify the returning list from the master server. TNL_DECLARE_RPC(c2mQueryGameTypes, (U32 queryId)); /// m2cQueryGameTypesResponse is sent by the master server in response to a c2mQueryGameTypes /// from a client. The queryId will match the original queryId sent by the client. Clients /// should override this method in their custom MasterServerConnection classes. If there are /// more game or mission types than will fit in a single message, the master server will send /// multiple m2cQueryGameTypesResponse RPCs. The master will always send a final /// m2cQueryGameTypesResponse with Vectors of size 0 to indicate that no more game or mission /// types are to be added. TNL_DECLARE_RPC(m2cQueryGameTypesResponse, (U32 queryId, const Vector<StringTableEntry> &gameTypes, const Vector<StringTableEntry> &missionTypes)); /// c2mQueryServers is sent by the client to the master server to request a list of /// servers that match the specified filter criteria. A c2mQueryServers request will /// result in one or more m2cQueryServersResponse RPCs, with the final call having an empty /// Vector of servers. TNL_DECLARE_RPC(c2mQueryServers, (U32 queryId, U32 regionMask, U32 minPlayers, U32 maxPlayers, U32 infoFlags, U32 maxBots, U32 minCPUSpeed, StringTableEntry gameType, StringTableEntry missionType)); /// m2cQueryServersResponse is sent by the master server in response to a c2mQueryServers RPC, to /// return a partial list of the servers that matched the specified filter criteria. Because packets /// are limited in size, the response server list is broken up into lists of at most IPMessageAddressCount IP addresses /// per message. The Master Server will always send a final, empty m2cQueryServersResponse to signify that the list /// is complete. TNL_DECLARE_RPC(m2cQueryServersResponse, (U32 queryId, const Vector<IPAddress> &ipList)); /// c2mRequestArrangedConnection is an RPC sent from the client to the master to request an arranged /// connection with the specified server address. The internalAddress should be the client's own self-reported /// IP address. The connectionParameters buffer will be sent without modification to the specified /// server. TNL_DECLARE_RPC(c2mRequestArrangedConnection, (U32 requestId, IPAddressRef remoteAddress, IPAddressRef internalAddress, ByteBufferRef connectionParameters)); /// m2cClientRequestedArranged connection is sent from the master to a server to notify it that /// a client has requested a connection. The possibleAddresses vector is a list of possible IP addresses /// that the server should attempt to connect to for that client if it accepts the connection request. TNL_DECLARE_RPC(m2cClientRequestedArrangedConnection, (U32 requestId, const Vector<IPAddress> &possibleAddresses, ByteBufferRef connectionParameters)); /// c2mAcceptArrangedConnection is sent by a server to notify the master that it will accept the connection /// request from a client. The requestId parameter sent by the MasterServer in m2cClientRequestedArrangedConnection /// should be sent back as the requestId field. The internalAddress is the server's self-determined IP address. TNL_DECLARE_RPC(c2mAcceptArrangedConnection, (U32 requestId, IPAddressRef internalAddress, ByteBufferRef connectionData)); /// c2mRejectArrangedConnection notifies the Master Server that the server is rejecting the arranged connection /// request specified by the requestId. The rejectData will be passed along to the requesting client. TNL_DECLARE_RPC(c2mRejectArrangedConnection, (U32 requestId, ByteBufferRef rejectData)); /// m2cArrangedConnectionAccepted is sent to a client that has previously requested a connection to a listed server /// via c2mRequestArrangedConnection if the server accepted the connection. The possibleAddresses vector is the list /// of IP addresses the client should attempt to connect to, and the connectionData buffer is the buffer sent by the /// server upon accepting the connection. TNL_DECLARE_RPC(m2cArrangedConnectionAccepted, (U32 requestId, const Vector<IPAddress> &possibleAddresses, ByteBufferRef connectionData)); /// m2cArrangedConnectionRejected is sent to a client when an arranged connection request is rejected by the /// server, or when the request times out because the server never responded. TNL_DECLARE_RPC(m2cArrangedConnectionRejected, (U32 requestId, ByteBufferRef rejectData)); /// c2mUpdateServerStatus updates the status of a server to the Master Server, specifying the current game /// and mission types, any player counts and the current info flags. TNL_DECLARE_RPC(c2mUpdateServerStatus, ( StringTableEntry gameType, StringTableEntry missionType, U32 botCount, U32 playerCount, U32 maxPlayers, U32 infoFlags)); }; #endif --- NEW FILE: main.cpp --- //----------------------------------------------------------------------------------- // // Torque Network Library - Master Server // Copyright (C) 2004 GarageGames.com, Inc. // For more information see http://www.opentnl.org // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // For use in products that are not compatible with the terms of the GNU // General Public License, alternative licensing options are available // from GarageGames.com. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // //------------------------------------------------------------------------------------ #include "tnlNetInterface.h" #include "masterInterface.h" #include "tnlVector.h" #include "tnlAsymmetricKey.h" using namespace TNL; NetInterface *gNetInterface = NULL; class MissionGameType : public Object { public: MissionGameType(const StringTableEntry &name) { mName = name; } StringTableEntry mName; }; class MasterServerConnection; class GameConnectRequest { public: SafePtr<MasterServerConnection> initiator; SafePtr<MasterServerConnection> host; U32 initiatorQueryId; U32 hostQueryId; U32 requestTime; }; class MasterServerConnection : public MasterServerInterface { private: typedef MasterServerInterface Parent; protected: /// @name Linked List /// /// The server stores its connections on a linked list. /// /// @{ /// MasterServerConnection *mNext; MasterServerConnection *mPrev; /// @} /// @name Globals /// @{ /// static MasterServerConnection gServerList; static Vector< SafePtr<MissionGameType> > gMissionTypeList; static Vector< SafePtr<MissionGameType> > gGameTypeList; static Vector< GameConnectRequest* > gConnectList; /// @} /// @name Connection Info /// /// General information about this connection. /// /// @{ /// bool mIsGameServer; ///< True if this is a game server. U32 mStrikeCount; ///< Number of "strikes" this connection has... 3 strikes and you're out! U32 mLastQueryId; ///< The last query id for info from this master. U32 mLastActivityTime; ///< The last time we got a request or an update from this host. /// A list of connection requests we're working on fulfilling for this connection. Vector< GameConnectRequest* > mConnectList; /// @} /// @name Server Info /// /// This info is filled in if this connection maps to a /// game server. /// /// @{ U32 mRegionCode; ///< The region code in which this server operates. StringTableEntry mGameString; ///< The unique game string for this server or client. U32 mCPUSpeed; ///< The CPU speed of this server. U32 mInfoFlags; ///< Info flags describing this server. U32 mPlayerCount; ///< Current number of players on this server. U32 mMaxPlayers; ///< Maximum number of players on this server. U32 mNumBots; ///< Current number of bots on this server. RefPtr<MissionGameType> mCurrentGameType; RefPtr<MissionGameType> mCurrentMissionType; void setGameType(const StringTableEntry &gameType) { for(S32 i = 0; i < gGameTypeList.size(); i++) { if(gGameTypeList[i].isValid() && gGameTypeList[i]->mName == gameType) { mCurrentGameType = gGameTypeList[i]; return; } } mCurrentGameType = new MissionGameType(gameType); gGameTypeList.push_back((MissionGameType *)mCurrentGameType); } void setMissionType(const StringTableEntry &missionType) { for(S32 i = 0; i < gMissionTypeList.size(); i++) { if(gMissionTypeList[i].isValid() && gMissionTypeList[i]->mName == missionType) { mCurrentMissionType = gMissionTypeList[i]; return; } } mCurrentMissionType = new MissionGameType(missionType); gMissionTypeList.push_back((MissionGameType *) mCurrentMissionType); } /// @} public: /// Constructor initializes the linked list info with /// "safe" values so we don't explode if we destruct /// right away. MasterServerConnection() { mStrikeCount = 0; mLastActivityTime = 0; mNext = this; mPrev = this; setIsConnectionToClient(); setIsAdaptive(); } /// Destructor removes the connection from the doubly linked list of /// server connections. ~MasterServerConnection() { // unlink it if it's in the list mPrev->mNext = mNext; mNext->mPrev = mPrev; logprintf("%s disconnected", getNetAddress().toString()); } /// Adds this connection to the doubly linked list of servers. void linkToServerList() { mNext = gServerList.mNext; mPrev = gServerList.mNext->mPrev; mNext->mPrev = this; mPrev->mNext = this; } /// RPC's a list of mission and game types to the requesting client. /// This function also cleans up any game types from the global lists /// that are no longer referenced. TNL_DECLARE_RPC_OVERRIDE(c2mQueryGameTypes, (U32 queryId)) { Vector<StringTableEntry> gameTypes(GameMissionTypesPerPacket); Vector<StringTableEntry> missionTypes(GameMissionTypesPerPacket); U32 listSize = 0; // Iterate through game types list, culling out any null entries. // Add all non-null entries to the gameTypes vector. for(S32 i = 0; i < gGameTypeList.size(); ) { if(gGameTypeList[i].isNull()) { gGameTypeList.erase_fast(i); continue; } gameTypes.push_back(gGameTypeList[i]->mName); i++; listSize++; if(listSize >= GameMissionTypesPerPacket) { m2cQueryGameTypesResponse(queryId, gameTypes, missionTypes); listSize = 0; gameTypes.clear(); } } // Iterate through mission types list, culling out any null entries. // Add all non-null entries to the missionTypes vector. for(S32 i = 0; i < gMissionTypeList.size(); ) { if(gMissionTypeList[i].isNull()) { gMissionTypeList.erase_fast(i); continue; } missionTypes.push_back(gMissionTypeList[i]->mName); i++; listSize++; if(listSize >= GameMissionTypesPerPacket) { m2cQueryGameTypesResponse(queryId, gameTypes, missionTypes); listSize = 0; gameTypes.clear(); missionTypes.clear(); } } // Send the last lists to the client. m2cQueryGameTypesResponse(queryId, gameTypes, missionTypes); // Send a pair of empty lists to the client to signify that the // query is done. if(gameTypes.size() || missionTypes.size()) { gameTypes.clear(); missionTypes.clear(); m2cQueryGameTypesResponse(queryId, gameTypes, missionTypes); } } /// The query server method builds a piecewise list of servers /// that match the client's particular filter criteria and /// sends it to the client, followed by a QueryServersDone RPC. TNL_DECLARE_RPC_OVERRIDE(c2mQueryServers, (U32 queryId, U32 regionMask, U32 minPlayers, U32 maxPlayers, U32 infoFlags, U32 maxBots, U32 minCPUSpeed, StringTableEntry gameType, StringTableEntry missionType) ) { Vector<IPAddress> theVector(IPMessageAddressCount); theVector.reserve(IPMessageAddressCount); for(MasterServerConnection *walk = gServerList.mNext; walk != &gServerList; walk = walk->mNext) { // Skip to the next if we don't match on any particular... if(walk->mGameString != mGameString) continue; if(!(walk->mRegionCode & regionMask)) continue; if(walk->mPlayerCount > maxPlayers || walk->mPlayerCount < minPlayers) continue; if(infoFlags & ~walk->mInfoFlags) continue; if(maxBots < walk->mNumBots) continue; if(minCPUSpeed > walk->mCPUSpeed) continue; if(gameType.isNotNull() && (gameType != walk->mCurrentGameType->mName)) continue; if(missionType.isNotNull() && (missionType != walk->mCurrentMissionType->mName)) continue; // Somehow we matched! Add us to the results list. theVector.push_back(walk->getNetAddress().toIPAddress()); // If we get a packet's worth, send it to the client and empty our buffer... if(theVector.size() == IPMessageAddressCount) { m2cQueryServersResponse(queryId, theVector); theVector.clear(); } } m2cQueryServersResponse(queryId, theVector); // If we sent any with the previous message, send another list with no servers. if(theVector.size()) { theVector.clear(); m2cQueryServersResponse(queryId, theVector); } } /// checkActivityTime validates that this particular connection is /// not issuing too many requests at once in an attempt to DOS /// by flooding either the master server or any other server /// connected to it. A client whose last activity time falls /// within the specified delta gets a strike... 3 strikes and /// you're out! Strikes go away after being good for a while. void checkActivityTime(U32 timeDeltaMinimum) { U32 currentTime = Platform::getRealMilliseconds(); if(currentTime - mLastActivityTime < timeDeltaMinimum) { mStrikeCount++; if(mStrikeCount == 3) disconnect("You're out!"); } else if(mStrikeCount > 0) mStrikeCount--; } void removeConnectRequest(GameConnectRequest *gcr) { for(S32 j = 0; j < mConnectList.size(); j++) { if(gcr == mConnectList[j]) { mConnectList.erase_fast(j); break; } } } GameConnectRequest *findAndRemoveRequest(U32 requestId) { GameConnectRequest *req = NULL; for(S32 j = 0; j < mConnectList.size(); j++) { if(mConnectList[j]->hostQueryId == requestId) { req = mConnectList[j]; mConnectList.erase_fast(j); break; } } if(!req) return NULL; if(req->initiator.isValid()) req->initiator->removeConnectRequest(req); for(S32 j = 0; j < gConnectList.size(); j++) { if(gConnectList[j] == req) { gConnectList.erase_fast(j); break; } } return req; } // This is called when a client wishes to arrange a connection with a // server. TNL_DECLARE_RPC_OVERRIDE(c2mRequestArrangedConnection, (U32 requestId, IPAddressRef remoteAddress, IPAddressRef internalAddress, ByteBufferRef connectionParameters)) { // First, make sure that we're connected with the server that they're requesting a connection with. MasterServerConnection *conn = (MasterServerConnection *) gNetInterface->findConnection(remoteAddress); if(!conn) { c2mRejectArrangedConnection(requestId, ByteBuffer((U8 *) MasterNoSuchHost, strlen(MasterNoSuchHost) + 1)); return; } // Record the request... GameConnectRequest *req = new GameConnectRequest; req->initiator = this; req->host = conn; req->initiatorQueryId = requestId; req->hostQueryId = mLastQueryId++; req->requestTime = Platform::getRealMilliseconds(); char buf[256]; strcpy(buf, getNetAddress().toString()); logprintf("Client: %s requested connection to %s", buf, conn->getNetAddress().toString()); // Add the request to the relevan lists (the global list, this connection's list, // and the other connection's list). mConnectList.push_back(req); conn->mConnectList.push_back(req); gConnectList.push_back(req); // Do some DOS checking... checkActivityTime(2000); // Get our address... Address theAddress = conn->getNetAddress(); // Record some different addresses to try... Vector<IPAddress> possibleAddresses; // The address, but port+1 theAddress.port++; possibleAddresses.push_back(theAddress.toIPAddress()); // The address, with the original port theAddress.port--; possibleAddresses.push_back(theAddress.toIPAddress()); // Or the address the port thinks it's talking to. Address theInternalAddress(internalAddress); Address anyAddress; // (Only store that last one if it's not the any address.) if(!theInternalAddress.isEqualAddress(anyAddress) && theInternalAddress != theAddress) possibleAddresses.push_back(internalAddress); // And inform the other part of the request. conn->m2cClientRequestedArrangedConnection(req->hostQueryId, possibleAddresses, connectionParameters); } // Called to indicate a connect request is being accepted. TNL_DECLARE_RPC_OVERRIDE(c2mAcceptArrangedConnection, (U32 requestId, IPAddressRef internalAddress, ByteBufferRef connectionData)) { GameConnectRequest *req = findAndRemoveRequest(requestId); if(!req) return; Address theAddress = getNetAddress(); Vector<IPAddress> possibleAddresses; theAddress.port++; possibleAddresses.push_back(theAddress.toIPAddress()); theAddress.port--; possibleAddresses.push_back(theAddress.toIPAddress()); Address theInternalAddress(internalAddress); Address anyAddress; if(!theInternalAddress.isEqualAddress(anyAddress) && theInternalAddress != theAddress) possibleAddresses.push_back(internalAddress); char buffer[256]; strcpy(buffer, getNetAddress().toString()); logprintf("Server: %s accept connection request from %s", buffer, req->initiator.isValid() ? req->initiator->getNetAddress().toString() : "Unknown"); // If we still know about the requestor, tell him his connection was accepted... if(req->initiator.isValid()) req->initiator->m2cArrangedConnectionAccepted(req->initiatorQueryId, possibleAddresses, connectionData); delete req; } // Called to indicate a connect request is being rejected. TNL_DECLARE_RPC_OVERRIDE(c2mRejectArrangedConnection, (U32 requestId, ByteBufferRef rejectData)) { GameConnectRequest *req = findAndRemoveRequest(requestId); if(!req) return; logprintf("Server: %s reject connection request from %s", getNetAddress().toString(), req->initiator.isValid() ? req->initiator->getNetAddress().toString() : "Unknown"); if(req->initiator.isValid()) req->initiator->m2cArrangedConnectionRejected(req->initiatorQueryId, rejectData); delete req; } // Called to update the status of a game server. TNL_DECLARE_RPC_OVERRIDE(c2mUpdateServerStatus, ( StringTableEntry gameType, StringTableEntry missionType, U32 botCount, U32 playerCount, U32 maxPlayers, U32 infoFlags)) { // If we didn't know we were a game server, don't accept updates. if(!mIsGameServer) return; setGameType(gameType); setMissionType(missionType); mNumBots = botCount; mPlayerCount = playerCount; mMaxPlayers = maxPlayers; mInfoFlags = infoFlags; checkActivityTime(15000); logprintf("Server: %s updated server status (%s, %s, %d, %d, %d)", getNetAddress().toString(), gameType.getString(), missionType.getString(), botCount, playerCount, maxPlayers); } bool readConnectRequest(BitStream *bstream, const char **errorString) { if(!Parent::readConnectRequest(bstream, errorString)) return false; char gameString[256]; bstream->readString(gameString); mGameString = gameString; // If it's a game server, read status info... if((mIsGameServer = bstream->readFlag()) == true) { bstream->read(&mCPUSpeed); bstream->read(&mRegionCode); bstream->read(&mNumBots); bstream->read(&mPlayerCount); bstream->read(&mMaxPlayers); bstream->read(&mInfoFlags); bstream->readString(gameString); setGameType(StringTableEntry(gameString)); bstream->readString(gameString); setMissionType(StringTableEntry(gameString)); linkToServerList(); } logprintf("%s online at %s", mIsGameServer ? "Server" : "client", getNetAddress().toString()); return true; } static void checkConnectTimeouts() { U32 currentTime = Platform::getRealMilliseconds(); // Expire any connect requests that have grown old... for(S32 i = 0; i < gConnectList.size(); ) { GameConnectRequest *gcr = gConnectList[i]; if(currentTime - gcr->requestTime > ConnectRequestTimeout) { // It's old! // So remove it from the initiator's list... if(gcr->initiator.isValid()) { gcr->initiator->removeConnectRequest(gcr); gcr->initiator->c2mRejectArrangedConnection(gcr->initiatorQueryId, ByteBuffer((U8 *) MasterRequestTimedOut, strlen(MasterRequestTimedOut) + 1)); } // And the host's lists.. if(gcr->host.isValid()) gcr->host->removeConnectRequest(gcr); // Delete it... delete gcr; // And remove it from our list, too. gConnectList.erase_fast(i); continue; } i++; } } TNL_DECLARE_NETCONNECTION(MasterServerConnection); }; TNL_IMPLEMENT_NETCONNECTION(MasterServerConnection, NetClassGroupMaster, true); Vector< SafePtr<MissionGameType> > MasterServerConnection::gMissionTypeList; Vector< SafePtr<MissionGameType> > MasterServerConnection::gGameTypeList; Vector< GameConnectRequest* > MasterServerConnection::gConnectList; MasterServerConnection MasterServerConnection::gServerList; //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- #include <stdio.h> class StdoutLogConsumer : public LogConsumer { public: void logString(const char *string) { printf("%s\n", string); } } gStdoutLogConsumer; int main(int argc, const char **argv) { // Parse command line parameters... if(argc < 2) { logprintf("Error - you must specify a port on the command line."); return 0; } U32 port = atoi(argv[1]); // Initialize our net interface so we can accept connections... gNetInterface = new NetInterface(Address(IPProtocol, Address::Any, port)); //for the master server alone, we don't need a key exchange - that would be a waste //gNetInterface->setRequiresKeyExchange(true); //gNetInterface->setPrivateKey(new AsymmetricKey(20)); logprintf("Master Server created - listening on port %d", port); // And until infinity, process whatever comes our way. for(;;) { U32 currentTime = Platform::getRealMilliseconds(); gNetInterface->checkIncomingPackets(); gNetInterface->processConnections(); Platform::sleep(1); } return 0; } --- NEW FILE: master.vcproj --- <?xml version="1.0" encoding="Windows-1252"?> <VisualStudioProject ProjectType="Visual C++" Version="7.10" Name="master" ProjectGUID="{CE4F0113-8119-491D-BCBE-20F5C3A555FC}" Keyword="Win32Proj"> <Platforms> <Platform Name="Win32"/> </Platforms> <Configurations> <Configuration Name="Debug|Win32" OutputDirectory="Debug" IntermediateDirectory="Debug" ConfigurationType="1" CharacterSet="2"> <Tool Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="../tnl" PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" MinimalRebuild="TRUE" BasicRuntimeChecks="3" RuntimeLibrary="5" RuntimeTypeInfo="TRUE" UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="TRUE" DebugInformationFormat="4"/> <Tool Name="VCCustomBuildTool"/> <Tool Name="VCLinkerTool" AdditionalDependencies="wsock32.lib" OutputFile="../exe/masterd.exe" LinkIncremental="2" GenerateDebugInformation="TRUE" ProgramDatabaseFile="$(OutDir)/master.pdb" SubSystem="1" TargetMachine="1"/> <Tool Name="VCMIDLTool"/> <Tool Name="VCPostBuildEventTool"/> <Tool Name="VCPreBuildEventTool"/> <Tool Name="VCPreLinkEventTool"/> <Tool Name="VCResourceCompilerTool"/> <Tool Name="VCWebServiceProxyGeneratorTool"/> <Tool Name="VCXMLDataGeneratorTool"/> <Tool Name="VCWebDeploymentTool"/> <Tool Name="VCManagedWrapperGeneratorTool"/> <Tool Name="VCAuxiliaryManagedWrapperGeneratorTool"/> </Configuration> <Configuration Name="Release|Win32" OutputDirectory="Release" IntermediateDirectory="Release" ConfigurationType="1" CharacterSet="2"> <Tool Name="VCCLCompilerTool" AdditionalIncludeDirectories="../tnl" PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" RuntimeLibrary="4" RuntimeTypeInfo="TRUE" UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="TRUE" DebugInformationFormat="3"/> <Tool Name="VCCustomBuildTool"/> <Tool Name="VCLinkerTool" AdditionalDependencies="wsock32.lib" OutputFile="../exe/master.exe" LinkIncremental="1" GenerateDebugInformation="TRUE" SubSystem="1" OptimizeReferences="2" EnableCOMDATFolding="2" TargetMachine="1"/> <Tool Name="VCMIDLTool"/> <Tool Name="VCPostBuildEventTool"/> <Tool Name="VCPreBuildEventTool"/> <Tool Name="VCPreLinkEventTool"/> <Tool Name="VCResourceCompilerTool"/> <Tool Name="VCWebServiceProxyGeneratorTool"/> <Tool Name="VCXMLDataGeneratorTool"/> <Tool Name="VCWebDeploymentTool"/> <Tool Name="VCManagedWrapperGeneratorTool"/> <Tool Name="VCAuxiliaryManagedWrapperGeneratorTool"/> </Configuration> </Configurations> <References> </References> <Files> <File RelativePath=".\main.cpp"> </File> <File RelativePath=".\masterInterface.cpp"> </File> <File RelativePath=".\masterInterface.h"> </File> </Files> <Globals> </Globals> </VisualStudioProject> --- NEW FILE: masterInterface.cpp --- //----------------------------------------------------------------------------------- // // Torque Network Library - Master Server // Copyright (C) 2004 GarageGames.com, Inc. // For more information see http://www.opentnl.org // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // For use in products that are not compatible with the terms of the GNU // General Public License, alternative licensing options are available // from GarageGames.com. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // //------------------------------------------------------------------------------------ #include "masterInterface.h" // Since this is an interface, we implement a bunch of stubs. TNL_IMPLEMENT_RPC(MasterServerInterface, c2mQueryGameTypes, (U32 queryId), NetClassGroupMasterMask, RPCGuaranteedOrdered, RPCDirClientToServer, 0) {} TNL_IMPLEMENT_RPC(MasterServerInterface, m2cQueryGameTypesResponse, (U32 queryId, const Vector<StringTableEntry> &gameTypes, const Vector<StringTableEntry> &missionTypes), NetClassGroupMasterMask, RPCGuaranteedOrdered, RPCDirServerToClient, 0) {} TNL_IMPLEMENT_RPC(MasterServerInterface, c2mQueryServers, (U32 queryId, U32 regionMask, U32 minPlayers, U32 maxPlayers, U32 infoFlags, U32 maxBots, U32 minCPUSpeed, StringTableEntry gameType, StringTableEntry missionType), NetClassGroupMasterMask, RPCGuaranteedOrdered, RPCDirClientToServer, 0) {} TNL_IMPLEMENT_RPC(MasterServerInterface, m2cQueryServersResponse, (U32 queryId, const Vector<IPAddress> &ipList), NetClassGroupMasterMask, RPCGuaranteedOrdered, RPCDirServerToClient, 0) {} TNL_IMPLEMENT_RPC(MasterServerInterface, c2mRequestArrangedConnection, (U32 requestId, IPAddressRef remoteAddress, IPAddressRef internalAddress, ByteBufferRef connectionParameters), NetClassGroupMasterMask, RPCGuaranteedOrdered, RPCDirClientToServer, 0) {} TNL_IMPLEMENT_RPC(MasterServerInterface, m2cClientRequestedArrangedConnection, (U32 requestId, const Vector<IPAddress> &possibleAddresses, ByteBufferRef connectionParameters), NetClassGroupMasterMask, RPCGuaranteedOrdered, RPCDirServerToClient, 0) {} TNL_IMPLEMENT_RPC(MasterServerInterface, c2mAcceptArrangedConnection, (U32 requestId, IPAddressRef internalAddress, ByteBufferRef connectionData), NetClassGroupMasterMask, RPCGuaranteedOrdered, RPCDirClientToServer, 0) {} TNL_IMPLEMENT_RPC(MasterServerInterface, c2mRejectArrangedConnection, (U32 requestId, ByteBufferRef rejectData), NetClassGroupMasterMask, RPCGuaranteedOrdered, RPCDirClientToServer, 0) {} TNL_IMPLEMENT_RPC(MasterServerInterface, m2cArrangedConnectionAccepted, (U32 requestId, const Vector<IPAddress> &possibleAddresses, ByteBufferRef connectionData), NetClassGroupMasterMask, RPCGuaranteedOrdered, RPCDirServerToClient, 0) {} TNL_IMPLEMENT_RPC(MasterServerInterface, m2cArrangedConnectionRejected, (U32 requestId, ByteBufferRef rejectData), NetClassGroupMasterMask, RPCGuaranteedOrdered, RPCDirServerToClient, 0) {} TNL_IMPLEMENT_RPC(MasterServerInterface, c2mUpdateServerStatus, ( StringTableEntry gameType, StringTableEntry missionType, U32 botCount, U32 playerCount, U32 maxPlayers, U32 infoFlags), NetClassGroupMasterMask, RPCGuaranteedOrdered, RPCDirClientToServer, 0) {} --- NEW FILE: Makefile --- # TNL Makefile # (c) 2003 GarageGames # # This makefile is for Linux atm. # # Configuration # CC=g++ -g -I../tnl #-O2 OBJECTS_MASTER=\ main.o\ masterInterface.o CFLAGS= .cpp.o : $(CC) -c $(CFLAGS) $< default: $(OBJECTS_MASTER) $(CC) -o master $(OBJECTS_MASTER) ../tnl/libtnl.a ../libtomcrypt/libtomcrypt.a -lstdc++ -lm clean: rm -f $(OBJECTS_MASTER) master --- NEW FILE: master.dsp --- # Microsoft Developer Studio Project File - Name="master" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Console Application" 0x0103 CFG=master - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "master.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "master.mak" CFG="master - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "master - Win32 Release" (based on "Win32 (x86) Console Application") !MESSAGE "master - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "master - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD CPP /nologo /W3 /GR /GX /O2 /I "../tnl" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 # ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../exe/master.exe" !ELSEIF "$(CFG)" == "master - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "master___Win32_Debug" # PROP BASE Intermediate_Dir "master___Win32_Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "master___Win32_Debug" # PROP Intermediate_Dir "master___Win32_Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c # ADD CPP /nologo /W3 /Gm /GR /GX /ZI /Od /I "../tnl" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept # ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../exe/masterd.exe" /pdbtype:sept !ENDIF # Begin Target # Name "master - Win32 Release" # Name "master - Win32 Debug" # Begin Source File SOURCE=.\main.cpp # End Source File # Begin Source File SOURCE=.\masterInterface.cpp # End Source File # Begin Source File SOURCE=.\masterInterface.h # End Source File # End Target # End Project |