Skip to content

Instantly share code, notes, and snippets.

@jamesu
Created December 5, 2016 23:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamesu/e2e6576bbd91e9fa5332dc51bcf9dc08 to your computer and use it in GitHub Desktop.
Save jamesu/e2e6576bbd91e9fa5332dc51bcf9dc08 to your computer and use it in GitHub Desktop.
Example connection class for Torque2D/Torque3D network code
// Example connection class for Torque2D/Torque3D network code
class ExampleNetConnection : public NetConnection
{
public:
typedef NetConnection Parent;
static const U32 CurrentProtocolVersion;
static const U32 MinRequiredProtocolVersion;
/// Configuration
enum Constants {
BlockTypeMove = NetConnectionBlockTypeCount,
GameConnectionBlockTypeCount,
MaxConnectArgs = 16,
DataBlocksDone = NumConnectionMessages,
DataBlocksDownloadDone,
};
/// @name Event Handling
/// @{
virtual void onTimedOut()
{
Con::printf("ExampleNetConnection::onTimedOut");
}
virtual void onConnectTimedOut()
{
Con::printf("ExampleNetConnection::onConnectTimedOut");
}
virtual void onDisconnect(const char *reason)
{
Con::printf("ExampleNetConnection::onDisconnect(%s)", reason);
}
virtual void onConnectionRejected(const char *reason)
{
Con::printf("ExampleNetConnection::onConnectionRejected(%s)", reason);
}
virtual void onConnectionEstablished(bool isInitiator)
{
Con::printf("ExampleNetConnection::onConnectionEstablished(%s)", isInitiator ? "1" : "0");
if (isInitiator)
{
setSendingEvents(true);
setTranslatesStrings(true);
setIsConnectionToServer();
mServerConnection = this;
Con::printf("Connection established %d", getId());
//onConnectionAccepted_callback();
}
else
{
setSendingEvents(true);
setTranslatesStrings(true);
Sim::getClientGroup()->addObject(this);
}
}
virtual void handleStartupError(const char *errorString)
{
Con::printf("ExampleNetConnection::handleStartupError(%s)", errorString);
}
/// @}
virtual void writeConnectRequest(BitStream *stream)
{
Parent::writeConnectRequest(stream);
stream->writeString("Example");
stream->write(CurrentProtocolVersion);
stream->write(MinRequiredProtocolVersion);
stream->writeString("");
}
virtual bool readConnectRequest(BitStream *stream, const char **errorString)
{
if (!Parent::readConnectRequest(stream, errorString))
return false;
U32 currentProtocol, minProtocol;
char gameString[256];
stream->readString(gameString);
if (dStrcmp(gameString, "Example"))
{
*errorString = "CHR_GAME";
return false;
}
stream->read(&currentProtocol);
stream->read(&minProtocol);
char joinPassword[256];
stream->readString(joinPassword);
if (currentProtocol < MinRequiredProtocolVersion)
{
*errorString = "CHR_PROTOCOL_LESS";
return false;
}
if (minProtocol > CurrentProtocolVersion)
{
*errorString = "CHR_PROTOCOL_GREATER";
return false;
}
setProtocolVersion(currentProtocol < CurrentProtocolVersion ? currentProtocol : CurrentProtocolVersion);
const char *serverPassword = Con::getVariable("pref::Server::Password");
if (serverPassword[0])
{
if (dStrcmp(joinPassword, serverPassword))
{
*errorString = "CHR_PASSWORD";
return false;
}
}
return true;
}
virtual void writeConnectAccept(BitStream *stream)
{
Parent::writeConnectAccept(stream);
stream->write(getProtocolVersion());
}
virtual bool readConnectAccept(BitStream *stream, const char **errorString)
{
if (!Parent::readConnectAccept(stream, errorString))
return false;
U32 protocolVersion;
stream->read(&protocolVersion);
if (protocolVersion < MinRequiredProtocolVersion || protocolVersion > CurrentProtocolVersion)
{
*errorString = "CHR_PROTOCOL"; // this should never happen unless someone is faking us out.
return false;
}
return true;
}
void readPacket(BitStream *bstream)
{
Parent::readPacket(bstream);
}
void writePacket(BitStream *bstream, PacketNotify *note)
{
Parent::writePacket(bstream, note);
}
void packetReceived(PacketNotify *note)
{
Parent::packetReceived(note);
}
void packetDropped(PacketNotify *note)
{
Parent::packetDropped(note);
}
void connectionError(const char *errorString)
{
Con::printf("connectionError(%s)", errorString);
Parent::connectionError(errorString);
}
void writeDemoStartBlock(ResizeBitStream *stream)
{
Parent::writeDemoStartBlock(stream);
}
bool readDemoStartBlock(BitStream *stream)
{
return Parent::readDemoStartBlock(stream);
}
void handleRecordedBlock(U32 type, U32 size, void *data)
{
Parent::handleRecordedBlock(type, size, data);
}
public:
ExampleNetConnection()
{
}
virtual ~ExampleNetConnection()
{
}
bool onAdd()
{
if (Parent::onAdd())
{
return true;
}
return false;
}
void onRemove()
{
if (isNetworkConnection())
{
sendDisconnectPacket("ByeBye");
}
else if (isLocalConnection() && isConnectionToServer())
{
// We're a client-side but local connection
// delete the server side of the connection on our local server so that it updates
// clientgroup and what not (this is so that we can disconnect from a local server
// without needing to destroy and recreate the server before we can connect to it
// again).
// Safe-delete as we don't know whether the server connection is currently being
// worked on.
getRemoteConnection()->safeDeleteObject();
setRemoteConnectionObject(NULL);
}
if (!isConnectionToServer())
{
Con::errorf("Connection %i dropped (%s)", getId(), "ByeBye");
}
Parent::onRemove();
}
bool canRemoteCreate()
{
return true;
}
public:
DECLARE_CONOBJECT(ExampleNetConnection);
};
IMPLEMENT_CONOBJECT(ExampleNetConnection);
const U32 ExampleNetConnection::CurrentProtocolVersion = 1;
const U32 ExampleNetConnection::MinRequiredProtocolVersion = 1;
// Test script function
ConsoleFunction(testConnectTo, const char*, 2, 2, "")
{
NetAddress addr;
Net::stringToAddress(argv[1], &addr);
ExampleNetConnection *server = new ExampleNetConnection();
BitStream *stream = BitStream::getPacketStream();
server->registerObject();
server->connect(&addr);
return server->getIdString();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment