mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-08-06 10:44:08 +00:00
Public release of the DLU server code!
Have fun!
This commit is contained in:
258
dNet/dServer.cpp
Normal file
258
dNet/dServer.cpp
Normal file
@@ -0,0 +1,258 @@
|
||||
#define _VARIADIC_MAX 10
|
||||
#include "dServer.h"
|
||||
#include "dNetCommon.h"
|
||||
#include "dLogger.h"
|
||||
|
||||
#include "RakNetworkFactory.h"
|
||||
#include "MessageIdentifiers.h"
|
||||
|
||||
#include "PacketUtils.h"
|
||||
#include "dMessageIdentifiers.h"
|
||||
#include "MasterPackets.h"
|
||||
#include "ZoneInstanceManager.h"
|
||||
|
||||
//! Replica Constructor class
|
||||
class ReplicaConstructor : public ReceiveConstructionInterface {
|
||||
public:
|
||||
ReplicaReturnResult ReceiveConstruction(RakNet::BitStream *inBitStream, RakNetTime timestamp, NetworkID networkID, NetworkIDObject *existingObject, SystemAddress senderId, ReplicaManager *caller) {
|
||||
return REPLICA_PROCESSING_DONE;
|
||||
}
|
||||
} ConstructionCB;
|
||||
|
||||
//! Replica Download Sender class
|
||||
class ReplicaSender : public SendDownloadCompleteInterface {
|
||||
public:
|
||||
ReplicaReturnResult SendDownloadComplete(RakNet::BitStream *outBitStream, RakNetTime currentTime, SystemAddress senderId, ReplicaManager *caller) {
|
||||
return REPLICA_PROCESSING_DONE;
|
||||
}
|
||||
} SendDownloadCompleteCB;
|
||||
|
||||
//! Replica Download Receiver class
|
||||
class ReplicaReceiever : public ReceiveDownloadCompleteInterface {
|
||||
public:
|
||||
ReplicaReturnResult ReceiveDownloadComplete(RakNet::BitStream *inBitStream, SystemAddress senderId, ReplicaManager *caller) {
|
||||
return REPLICA_PROCESSING_DONE;
|
||||
}
|
||||
} ReceiveDownloadCompleteCB;
|
||||
|
||||
dServer::dServer(const std::string& ip, int port, int instanceID, int maxConnections, bool isInternal, bool useEncryption, dLogger* logger, const std::string masterIP, int masterPort, ServerType serverType, unsigned int zoneID) {
|
||||
mIP = ip;
|
||||
mPort = port;
|
||||
mZoneID = zoneID;
|
||||
mInstanceID = instanceID;
|
||||
mMaxConnections = maxConnections;
|
||||
mIsInternal = isInternal;
|
||||
mUseEncryption = useEncryption;
|
||||
mLogger = logger;
|
||||
mMasterIP = masterIP;
|
||||
mMasterPort = masterPort;
|
||||
mMasterConnectionActive = false;
|
||||
mNetIDManager = nullptr;
|
||||
mReplicaManager = nullptr;
|
||||
mServerType = serverType;
|
||||
|
||||
//Attempt to start our server here:
|
||||
mIsOkay = Startup();
|
||||
|
||||
//Forcibly log to both the console and our file what ip, port and possibly zoneID / instanceID we're running on:
|
||||
bool prevLogSetting = mLogger->GetIsLoggingToConsole();
|
||||
mLogger->SetLogToConsole(true);
|
||||
|
||||
if (mIsOkay) {
|
||||
if (zoneID == 0)
|
||||
mLogger->Log("dServer", "Server is listening on %s:%i with encryption: %i\n", ip.c_str(), port, int(useEncryption));
|
||||
else
|
||||
mLogger->Log("dServer", "Server is listening on %s:%i with encryption: %i, running zone %i / %i\n", ip.c_str(), port, int(useEncryption), zoneID, instanceID);
|
||||
}
|
||||
else { mLogger->Log("dServer", "FAILED TO START SERVER ON IP/PORT: %s:%i\n", ip.c_str(), port); return; }
|
||||
|
||||
mLogger->SetLogToConsole(prevLogSetting);
|
||||
|
||||
//Connect to master if we are not master:
|
||||
if (serverType != ServerType::Master) {
|
||||
SetupForMasterConnection();
|
||||
ConnectToMaster();
|
||||
}
|
||||
|
||||
//Set up Replica if we're a world server:
|
||||
if (serverType == ServerType::World) {
|
||||
mNetIDManager = new NetworkIDManager();
|
||||
mNetIDManager->SetIsNetworkIDAuthority(true);
|
||||
|
||||
mReplicaManager = new ReplicaManager();
|
||||
mReplicaManager->SetAutoParticipateNewConnections(false);
|
||||
mReplicaManager->SetAutoConstructToNewParticipants(false);
|
||||
mReplicaManager->SetAutoSerializeInScope(true);
|
||||
mReplicaManager->SetReceiveConstructionCB(&ConstructionCB);
|
||||
mReplicaManager->SetDownloadCompleteCB(&SendDownloadCompleteCB, &ReceiveDownloadCompleteCB);
|
||||
|
||||
mPeer->AttachPlugin(mReplicaManager);
|
||||
mPeer->SetNetworkIDManager(mNetIDManager);
|
||||
}
|
||||
}
|
||||
|
||||
dServer::~dServer() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
Packet* dServer::ReceiveFromMaster() {
|
||||
if (!mMasterPeer) return nullptr;
|
||||
if (!mMasterConnectionActive) ConnectToMaster();
|
||||
|
||||
Packet* packet = mMasterPeer->Receive();
|
||||
if (packet) {
|
||||
if (packet->length < 1) { mMasterPeer->DeallocatePacket(packet); return nullptr; }
|
||||
|
||||
if (packet->data[0] == ID_DISCONNECTION_NOTIFICATION || packet->data[0] == ID_CONNECTION_LOST) {
|
||||
mLogger->Log("Server", "Lost our connection to master, shutting DOWN!\n");
|
||||
mMasterConnectionActive = false;
|
||||
//ConnectToMaster(); //We'll just shut down now
|
||||
}
|
||||
|
||||
if (packet->data[0] == ID_CONNECTION_REQUEST_ACCEPTED) {
|
||||
mLogger->Log("Server", "Established connection to master\n");
|
||||
mMasterConnectionActive = true;
|
||||
mMasterSystemAddress = packet->systemAddress;
|
||||
MasterPackets::SendServerInfo(this, packet);
|
||||
}
|
||||
|
||||
if (packet->data[0] == ID_USER_PACKET_ENUM) {
|
||||
if (packet->data[1] == MASTER) {
|
||||
switch (packet->data[3]) {
|
||||
case MSG_MASTER_REQUEST_ZONE_TRANSFER_RESPONSE: {
|
||||
uint64_t requestID = PacketUtils::ReadPacketU64(8, packet);
|
||||
ZoneInstanceManager::Instance()->HandleRequestZoneTransferResponse(requestID, packet);
|
||||
break;
|
||||
}
|
||||
|
||||
//When we handle these packets in World instead dServer, we just return the packet's pointer.
|
||||
case MSG_MASTER_REQUEST_PERSISTENT_ID_RESPONSE: {
|
||||
return packet;
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_MASTER_SESSION_KEY_RESPONSE: {
|
||||
return packet;
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_MASTER_SHUTDOWN : {
|
||||
return packet;
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_MASTER_AFFIRM_TRANSFER_REQUEST: {
|
||||
return packet;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
mLogger->Log("Server", "Unknown packet ID from master: %i\n", packet->data[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mMasterPeer->DeallocatePacket(packet);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Packet* dServer::Receive() {
|
||||
return mPeer->Receive();
|
||||
}
|
||||
|
||||
void dServer::DeallocatePacket(Packet * packet) {
|
||||
mPeer->DeallocatePacket(packet);
|
||||
}
|
||||
|
||||
void dServer::DeallocateMasterPacket(Packet * packet) {
|
||||
mMasterPeer->DeallocatePacket(packet);
|
||||
}
|
||||
|
||||
void dServer::Send(RakNet::BitStream * bitStream, const SystemAddress & sysAddr, bool broadcast) {
|
||||
mPeer->Send(bitStream, SYSTEM_PRIORITY, RELIABLE_ORDERED, 0, sysAddr, broadcast);
|
||||
}
|
||||
|
||||
void dServer::SendToMaster(RakNet::BitStream* bitStream) {
|
||||
if (!mMasterConnectionActive) ConnectToMaster();
|
||||
mMasterPeer->Send(bitStream, SYSTEM_PRIORITY, RELIABLE_ORDERED, 0, mMasterSystemAddress, false);
|
||||
}
|
||||
|
||||
void dServer::Disconnect(const SystemAddress& sysAddr, uint32_t disconNotifyID) {
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, SERVER, MSG_SERVER_DISCONNECT_NOTIFY);
|
||||
bitStream.Write(disconNotifyID);
|
||||
mPeer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE_ORDERED, 0, sysAddr, false);
|
||||
|
||||
mPeer->CloseConnection(sysAddr, true);
|
||||
}
|
||||
|
||||
bool dServer::IsConnected(const SystemAddress& sysAddr) {
|
||||
return mPeer->IsConnected(sysAddr);
|
||||
}
|
||||
|
||||
bool dServer::Startup() {
|
||||
mSocketDescriptor = SocketDescriptor(uint16_t(mPort), 0);
|
||||
mPeer = RakNetworkFactory::GetRakPeerInterface();
|
||||
|
||||
if (!mPeer) return false;
|
||||
if (!mPeer->Startup(mMaxConnections, 10, &mSocketDescriptor, 1)) return false;
|
||||
|
||||
if (mIsInternal) {
|
||||
mPeer->SetIncomingPassword("3.25 DARKFLAME1", 15);
|
||||
}
|
||||
else {
|
||||
//mPeer->SetPerConnectionOutgoingBandwidthLimit(800000); //100Kb/s
|
||||
mPeer->SetIncomingPassword("3.25 ND1", 8);
|
||||
}
|
||||
|
||||
mPeer->SetMaximumIncomingConnections(mMaxConnections);
|
||||
if (mUseEncryption) mPeer->InitializeSecurity(NULL, NULL, NULL, NULL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dServer::Shutdown() {
|
||||
mPeer->Shutdown(1000);
|
||||
|
||||
if (mNetIDManager) {
|
||||
delete mNetIDManager;
|
||||
mNetIDManager = nullptr;
|
||||
}
|
||||
|
||||
if (mReplicaManager) {
|
||||
delete mReplicaManager;
|
||||
mReplicaManager = nullptr;
|
||||
}
|
||||
|
||||
//RakNetworkFactory::DestroyRakPeerInterface(mPeer); //Not needed, we already called Shutdown ourselves.
|
||||
if (mServerType != ServerType::Master) {
|
||||
mMasterPeer->Shutdown(1000);
|
||||
//RakNetworkFactory::DestroyRakPeerInterface(mMasterPeer);
|
||||
}
|
||||
}
|
||||
|
||||
void dServer::SetupForMasterConnection() {
|
||||
mMasterSocketDescriptor = SocketDescriptor(uint16_t(mPort + 1), 0);
|
||||
mMasterPeer = RakNetworkFactory::GetRakPeerInterface();
|
||||
mMasterPeer->Startup(1, 30, &mMasterSocketDescriptor, 1);
|
||||
}
|
||||
|
||||
bool dServer::ConnectToMaster() {
|
||||
return mMasterPeer->Connect(mMasterIP.c_str(), mMasterPort, "3.25 DARKFLAME1", 15);
|
||||
}
|
||||
|
||||
void dServer::UpdateReplica() {
|
||||
mReplicaManager->Update(mPeer);
|
||||
}
|
||||
|
||||
int dServer::GetPing(const SystemAddress& sysAddr) const
|
||||
{
|
||||
return mPeer->GetAveragePing(sysAddr);
|
||||
}
|
||||
|
||||
int dServer::GetLatestPing(const SystemAddress& sysAddr) const
|
||||
{
|
||||
return mPeer->GetLastPing(sysAddr);
|
||||
}
|
Reference in New Issue
Block a user