Initial commit

This commit is contained in:
2026-04-03 00:22:39 -05:00
commit eca1e8c458
945 changed files with 218160 additions and 0 deletions

156
ZNet/ZNetPeer.cpp Normal file
View File

@@ -0,0 +1,156 @@
/*
ZNetPeer.cpp
Author: Patrick Baggett <ptbaggett@762studios.com>
Created: 7/18/2013
Purpose:
ZNet peer class, representing a remote host
License:
Copyright 2013, 762 Studios
*/
/*************************************************************************/
#include <ZNet/ZNetPeer.hpp>
#include <ZNet/ZNetPacketChannel.hpp>
#include <ZNet/ZNetHost.hpp>
#include "ZNetPrivate.hpp"
#include <SST/SST_OS.h>
#include <new>
/*************************************************************************/
ZNetPeer::ZNetPeer()
{
lastValidIncoming = 0;
lastOutgoingAck = 0;
socketCopy = 0;
channels = NULL;
userdata = NULL;
nrChannels = 0;
ping = -1;
state = STATE_UNCONNECTED;
}
/*************************************************************************/
bool ZNetPeer::Initialize(ZNetHost* _host, const SST_NetAddress* newAddr, SST_Socket s, uint32_t _nrChannels)
{
SST_OS_DebugAssert(_host != NULL, "Host may not be NULL");
SST_OS_DebugAssert(channels == NULL, "This should have been NULL; memory leak!");
channels = new(std::nothrow) ZNetPacketChannel[_nrChannels];
if(channels == NULL)
return false;
//Initialize channel ID (new[] doesn't allow non-default constructors)
for(uint32_t i=0; i<_nrChannels; i++)
{
channels[i].SetChannelId(i);
channels[i].SetHost(_host);
}
//Store other properties
memcpy(&addr, newAddr, sizeof(SST_NetAddress));
nrChannels = _nrChannels;
socketCopy = s;
userdata = NULL;
lastValidIncoming = SST_OS_GetMilliTime();
state = STATE_HANDSHAKE;
//OK
return true;
}
/*************************************************************************/
void ZNetPeer::Deinitialize()
{
for(uint32_t i=0; i<nrChannels; i++)
channels[i].Deinitialize();
delete[] channels;
}
/*************************************************************************/
ZNetPacketChannel* ZNetPeer::GetPacketChannel(uint32_t chId)
{
//Really, this is trivial, but I don't want asserts to be conditional on whether
//the user of the API has enabled them vs how the library was built.
SST_OS_DebugAssert(chId < nrChannels, "Invalid channel number");
return &channels[chId];
}
/*************************************************************************/
void ZNetPeer::ProcessLocalAcks()
{
for(uint32_t i=0; i<nrChannels; i++)
channels[i].ProcessLocalAcks();
}
/*************************************************************************/
void ZNetPeer::SendAcksForAllChannels()
{
uint8_t data[9000];
uint32_t mtu = this->GetPacketChannel(ZNET_SYSCHANNEL)->GetHost()->GetMTU();
bool unsent = true;
uint64_t now = SST_OS_GetMilliTime();
//TODO: maybe not the best idea...? it will start out by sending an ACK 0...kinda silly I guess
if(lastOutgoingAck == 0 ||
((ping > 0) && (now > lastOutgoingAck + (uint64_t)ping) && (now - lastOutgoingAck > 50)) ) //TODO: does a minimum ack latency of 50 make any sense? in the cases where ping is realllly low (e.g. <= 1msec) don't need to spam?
{
lastOutgoingAck = now;
}
else
return;
ZBinaryBufferWriter writer(data, mtu, ZNET_BYTEORDER);
//Write the write header
ZNetPrivate::WriteWirePacketHeader(&writer);
//Write an ACK point for each channel
for(uint32_t i=0; i<nrChannels; i++)
{
ZNetPacketChannel* channel = GetPacketChannel(i);
uint32_t remain = mtu - (uint32_t)writer.GetOffset();
//Can we fit another ack?
if(remain > ZNetPrivate::WireSizeForSimpleCommand(ZNETCMD_ACK))
{
//TODO: flags??
ZNetPrivate::WriteWireMessageHeader(&writer, i, 0, ZNETCMD_ACK, 0);
writer.WriteU16(channel->GetLocalAck());
writer.WriteU16(channel->GetHighestSent());
unsent = true;
}
else
{
ZNetPrivate::SendAll(socketCopy, &addr, data, (uint32_t)writer.GetOffset());
unsent = false;
//Restart
writer.Rewind();
ZNetPrivate::WriteWirePacketHeader(&writer);
}
}
if(unsent)
ZNetPrivate::SendAll(socketCopy, &addr, data, (uint32_t)writer.GetOffset());
}
/*************************************************************************/