ddnet/src/engine/server/upnp.cpp
Robert Müller d2c9750c65 Add str_from_int function
Add more efficient function for formatting integer values as strings.

A benchmark shows that using this function is significantly faster than using `str_format`. It is faster by a factor of 220 with Clang 15.0 O2 (https://quick-bench.com/q/BlNoLnlyqxipf4jvsFTUxKMHDJU) and by a factor of 11 with GCC 12.2 O2 (https://quick-bench.com/q/Fxf9lDCTqXBF4pIa_IyZ5R0IqYg).

This increases FPS in the editor by ~25% when many numbers are rendered for switch/tele/speedup/tune layers or with "Show Info" being enabled.

The additional static analysis for `std::to_chars` revealed that the wrong size was used in `CHud` for `aScoreTeam[TEAM_RED]` and `aScoreTeam[TEAM_BLUE]`.

This requires incrementing the macOS deployment target from 10.13 to 10.15.
2023-08-24 20:54:17 +02:00

76 lines
1.8 KiB
C++

#ifdef CONF_UPNP
#include "upnp.h"
#include <base/system.h>
#include <engine/shared/config.h>
#include <game/version.h>
#include <miniupnpc/miniupnpc.h>
#include <miniupnpc/upnpcommands.h>
#include <miniupnpc/upnperrors.h>
#include <cstdlib>
void CUPnP::Open(NETADDR Address)
{
if(g_Config.m_SvUseUPnP)
{
m_Enabled = false;
m_Addr = Address;
m_pUPnPUrls = (struct UPNPUrls *)malloc(sizeof(struct UPNPUrls));
m_pUPnPData = (struct IGDdatas *)malloc(sizeof(struct IGDdatas));
char aLanAddr[64];
char aPort[6];
int Error;
m_pUPnPDevice = upnpDiscover(2000, NULL, NULL, 0, 0, 2, &Error);
int Status = UPNP_GetValidIGD(m_pUPnPDevice, m_pUPnPUrls, m_pUPnPData, aLanAddr, sizeof(aLanAddr));
dbg_msg("upnp", "status=%d, lan_addr=%s", Status, aLanAddr);
if(Status == 1)
{
m_Enabled = true;
dbg_msg("upnp", "found valid IGD: %s", m_pUPnPUrls->controlURL);
str_from_int(m_Addr.port, aPort);
Error = UPNP_AddPortMapping(m_pUPnPUrls->controlURL, m_pUPnPData->first.servicetype,
aPort, aPort, aLanAddr,
"DDNet Server " GAME_RELEASE_VERSION,
"UDP", NULL, "0");
if(Error)
dbg_msg("upnp", "failed to map port, error: %s", strupnperror(Error));
else
dbg_msg("upnp", "successfully mapped port");
}
else
dbg_msg("upnp", "no valid IGD found, disabled");
}
}
void CUPnP::Shutdown()
{
if(g_Config.m_SvUseUPnP)
{
if(m_Enabled)
{
char aPort[6];
str_from_int(m_Addr.port, aPort);
int Error = UPNP_DeletePortMapping(m_pUPnPUrls->controlURL, m_pUPnPData->first.servicetype, aPort, "UDP", NULL);
if(Error != 0)
{
dbg_msg("upnp", "failed to delete port mapping on shutdown: %s", strupnperror(Error));
}
FreeUPNPUrls(m_pUPnPUrls);
freeUPNPDevlist(m_pUPnPDevice);
}
free(m_pUPnPUrls);
free(m_pUPnPData);
m_pUPnPUrls = NULL;
m_pUPnPData = NULL;
}
}
#endif