From 8aced572c985b4ab2155565270ec67a6c074ce69 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 15 May 2020 18:11:05 -0700 Subject: [PATCH 01/27] Some experimental commands to use auth when downloading from HTTP sources --- src/d_clisrv.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/d_netfil.c | 33 ++++++++++++++++++++++ src/d_netfil.h | 11 ++++++++ 3 files changed, 118 insertions(+) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 652ffbcb8..66477bbe0 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3200,6 +3200,76 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) } } +#ifdef HAVE_CURL +/** Add a login for HTTP downloads. If the + * user/password is missing, remove it. + * + * \sa Command_list_http_logins + */ +static void Command_set_http_login (void) +{ + HTTP_login *login; + HTTP_login **prev_next; + + if (COM_Argc() < 2) + { + CONS_Printf( + "set_http_login [user:password]: Set or remove a login to " + "authenticate HTTP downloads.\n" + ); + return; + } + + login = CURLGetLogin(COM_Argv(1), &prev_next); + + if (COM_Argc() == 2) + { + if (login) + { + (*prev_next) = login->next; + CONS_Printf("Login for '%s' removed.\n", login->url); + Z_Free(login); + } + } + else + { + if (login) + Z_Free(login->auth); + else + { + login = ZZ_Alloc(sizeof *login); + login->url = Z_StrDup(COM_Argv(1)); + } + + login->auth = Z_StrDup(COM_Argv(2)); + + login->next = curl_logins; + curl_logins = login; + } +} + +/** List logins for HTTP downloads. + * + * \sa Command_set_http_login + */ +static void Command_list_http_logins (void) +{ + HTTP_login *login; + + for ( + login = curl_logins; + login; + login = login->next + ){ + CONS_Printf( + "'%s' -> '%s'\n", + login->url, + login->auth + ); + } +} +#endif/*HAVE_CURL*/ + static CV_PossibleValue_t netticbuffer_cons_t[] = {{0, "MIN"}, {3, "MAX"}, {0, NULL}}; consvar_t cv_netticbuffer = {"netticbuffer", "1", CV_SAVE, netticbuffer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -3241,6 +3311,10 @@ void D_ClientServerInit(void) COM_AddCommand("reloadbans", Command_ReloadBan); COM_AddCommand("connect", Command_connect); COM_AddCommand("nodes", Command_Nodes); +#ifdef HAVE_CURL + COM_AddCommand("set_http_login", Command_set_http_login); + COM_AddCommand("list_http_logins", Command_list_http_logins); +#endif #ifdef PACKETDROP COM_AddCommand("drop", Command_Drop); COM_AddCommand("droprate", Command_Droprate); diff --git a/src/d_netfil.c b/src/d_netfil.c index 3dc9da68c..006f775b4 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -1062,6 +1062,9 @@ int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ul void CURLPrepareFile(const char* url, int dfilenum) { + HTTP_login *login; + char *final_url; + #ifdef PARANOIA if (M_CheckParm("-nodownload")) I_Error("Attempted to download files in -nodownload mode"); @@ -1090,6 +1093,13 @@ void CURLPrepareFile(const char* url, int dfilenum) curl_easy_setopt(http_handle, CURLOPT_USERAGENT, va("SRB2Kart/v%d.%d.%d", VERSION/100, VERSION%100, SUBVERSION)); // Set user agent as some servers won't accept invalid user agents. + // Authenticate if the user so wishes + curl_easy_getinfo(http_handle, CURLINFO_EFFECTIVE_URL, &final_url); + login = CURLGetLogin(final_url, NULL); + + if (login) + curl_easy_setopt(http_handle, CURLOPT_USERPWD, login->auth); + // Follow a redirect request, if sent by the server. curl_easy_setopt(http_handle, CURLOPT_FOLLOWLOCATION, 1L); @@ -1189,4 +1199,27 @@ void CURLGetFile(void) curl_global_cleanup(); } } + +HTTP_login * +CURLGetLogin (const char *url, HTTP_login ***return_prev_next) +{ + HTTP_login * login; + HTTP_login ** prev_next; + + for ( + prev_next = &curl_logins; + ( login = (*prev_next)); + prev_next = &login->next + ){ + if (strcmp(login->url, url) == 0) + { + if (return_prev_next) + (*return_prev_next) = prev_next; + + return login; + } + } + + return NULL; +} #endif diff --git a/src/d_netfil.h b/src/d_netfil.h index f37df371f..ef414b88b 100644 --- a/src/d_netfil.h +++ b/src/d_netfil.h @@ -58,6 +58,16 @@ extern INT32 lastfilenum; extern boolean curl_failedwebdownload; extern boolean curl_running; extern INT32 curl_transfers; + +typedef struct HTTP_login HTTP_login; + +struct HTTP_login +{ + char * url; + char * auth; + HTTP_login * next; +} +*curl_logins; #endif UINT8 *PutFileNeeded(UINT16 firstfile); @@ -93,6 +103,7 @@ size_t nameonlylength(const char *s); #ifdef HAVE_CURL void CURLPrepareFile(const char* url, int dfilenum); void CURLGetFile(void); +HTTP_login * CURLGetLogin (const char *url, HTTP_login ***return_prev_next); #endif #endif // __D_NETFIL__ From 12bd9370c2f1ce9561ccba3859d18220dd6559d2 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 15 May 2020 19:04:03 -0700 Subject: [PATCH 02/27] I forgot extern, now I am the clown --- src/d_netfil.c | 1 + src/d_netfil.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/d_netfil.c b/src/d_netfil.c index 006f775b4..446f38145 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -124,6 +124,7 @@ static UINT32 curl_origfilesize; static UINT32 curl_origtotalfilesize; static char *curl_realname = NULL; fileneeded_t *curl_curfile = NULL; +HTTP_login *curl_logins; #endif /** Fills a serverinfo packet with information about wad files loaded. diff --git a/src/d_netfil.h b/src/d_netfil.h index ef414b88b..913a2119a 100644 --- a/src/d_netfil.h +++ b/src/d_netfil.h @@ -61,7 +61,7 @@ extern INT32 curl_transfers; typedef struct HTTP_login HTTP_login; -struct HTTP_login +extern struct HTTP_login { char * url; char * auth; From 0de597892eb1488c5359c768fbd19391de0f38c7 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 16 May 2020 21:03:37 -0700 Subject: [PATCH 03/27] Whoops I used the url to the file instead of the http_source --- src/d_netfil.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d_netfil.c b/src/d_netfil.c index 446f38145..d2a6fe550 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -1064,7 +1064,6 @@ int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ul void CURLPrepareFile(const char* url, int dfilenum) { HTTP_login *login; - char *final_url; #ifdef PARANOIA if (M_CheckParm("-nodownload")) @@ -1095,11 +1094,12 @@ void CURLPrepareFile(const char* url, int dfilenum) curl_easy_setopt(http_handle, CURLOPT_USERAGENT, va("SRB2Kart/v%d.%d.%d", VERSION/100, VERSION%100, SUBVERSION)); // Set user agent as some servers won't accept invalid user agents. // Authenticate if the user so wishes - curl_easy_getinfo(http_handle, CURLINFO_EFFECTIVE_URL, &final_url); - login = CURLGetLogin(final_url, NULL); + login = CURLGetLogin(url, NULL); if (login) + { curl_easy_setopt(http_handle, CURLOPT_USERPWD, login->auth); + } // Follow a redirect request, if sent by the server. curl_easy_setopt(http_handle, CURLOPT_FOLLOWLOCATION, 1L); From 70eec29992379e06e2985a8ef6883e0b13d6e67e Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 28 Sep 2020 11:58:24 -0700 Subject: [PATCH 04/27] Mute music instead of pausing if lose focus --- src/s_sound.c | 6 +++--- src/sdl/i_video.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/s_sound.c b/src/s_sound.c index 225863211..ea0a1bbe7 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1952,7 +1952,7 @@ static boolean S_PlayMusic(boolean looping, UINT32 fadeinms) S_InitMusicVolume(); // switch between digi and sequence volume if (window_notinfocus && !cv_playmusicifunfocused.value) - I_PauseSong(); + I_SetMusicVolume(0); return true; } @@ -2418,9 +2418,9 @@ static void PlayMusicIfUnfocused_OnChange(void) if (window_notinfocus) { if (cv_playmusicifunfocused.value) - I_PauseSong(); + I_SetMusicVolume(0); else - I_ResumeSong(); + S_InitMusicVolume(); } } diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 37eedf147..2858e9b6f 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -625,7 +625,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) window_notinfocus = false; if (!paused) - I_ResumeSong(); //resume it + S_InitMusicVolume(); if (cv_gamesounds.value) S_EnableSound(); @@ -641,7 +641,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) // Tell game we lost focus, pause music window_notinfocus = true; if (!cv_playmusicifunfocused.value) - I_PauseSong(); + I_SetMusicVolume(0); if (!cv_playsoundifunfocused.value) S_DisableSound(); From f7a4667bc3f745f48e66352c8c3012e957b21584 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 30 Sep 2020 03:55:16 -0700 Subject: [PATCH 05/27] Use STUN instead of curl to fetch the public IP address for Discord RFC 5389 is a standard protocol that can be used for this instead of ip4.me. I may have gone overboard on the CSPRNG... It was fun though. --- src/Makefile | 4 +- src/d_clisrv.h | 1 + src/d_netcmd.c | 4 + src/discord.c | 138 +++++++++--------------------- src/i_tcp.c | 8 ++ src/m_swap.h | 17 ++-- src/stun.c | 222 +++++++++++++++++++++++++++++++++++++++++++++++++ src/stun.h | 20 +++++ 8 files changed, 305 insertions(+), 109 deletions(-) create mode 100644 src/stun.c create mode 100644 src/stun.h diff --git a/src/Makefile b/src/Makefile index fb859a339..da96f0cf1 100644 --- a/src/Makefile +++ b/src/Makefile @@ -440,8 +440,8 @@ endif ifdef HAVE_DISCORDRPC LIBS+=-ldiscord-rpc -CFLAGS+=-DHAVE_DISCORDRPC -OBJS+=$(OBJDIR)/discord.o +CFLAGS+=-DHAVE_DISCORDRPC -DUSE_STUN +OBJS+=$(OBJDIR)/discord.o $(OBJDIR)/stun.o endif ifndef NO_LUA diff --git a/src/d_clisrv.h b/src/d_clisrv.h index b88e7936b..b7fc56ec9 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -502,6 +502,7 @@ extern INT32 mapchangepending; // Points inside doomcom extern doomdata_t *netbuffer; +extern consvar_t cv_stunserver; extern consvar_t cv_httpsource; extern consvar_t cv_showjoinaddress; extern consvar_t cv_playbackspeed; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 4a90de333..84c1045a1 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -714,6 +714,10 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_dummyconsvar); +#ifdef USE_STUN + CV_RegisterVar(&cv_stunserver); +#endif + CV_RegisterVar(&cv_discordinvites); RegisterNetXCmd(XD_DISCORD, Got_DiscordInfo); } diff --git a/src/discord.c b/src/discord.c index b3798e291..4f72b714a 100644 --- a/src/discord.c +++ b/src/discord.c @@ -12,9 +12,7 @@ #ifdef HAVE_DISCORDRPC -#ifdef HAVE_CURL -#include -#endif // HAVE_CURL +#include #include "i_system.h" #include "d_clisrv.h" @@ -27,6 +25,8 @@ #include "mserv.h" // cv_advertise #include "z_zone.h" #include "byteptr.h" +#include "stun.h" +#include "i_tcp.h" // current_port #include "discord.h" #include "doomdef.h" @@ -45,16 +45,7 @@ struct discordInfo_s discordInfo; discordRequest_t *discordRequestList = NULL; -#ifdef HAVE_CURL -struct SelfIPbuffer -{ - CURL *curl; - char *pointer; - size_t length; -}; - static char self_ip[IP_SIZE]; -#endif // HAVE_CURL /*-------------------------------------------------- static char *DRPC_XORIPString(const char *input) @@ -335,39 +326,23 @@ void DRPC_Init(void) DRPC_UpdatePresence(); } -#ifdef HAVE_CURL /*-------------------------------------------------- - static size_t DRPC_WriteServerIP(char *s, size_t size, size_t n, void *userdata) + static void DRPC_GotServerIP(UINT32 address) - Writing function for use with curl. Only intended to be used with simple text. + Callback triggered by successful STUN response. Input Arguments:- - s - Data to write - size - Always 1. - n - Length of data - userdata - Passed in from CURLOPT_WRITEDATA, intended to be SelfIPbuffer + address - IPv4 address of this machine, in network byte order. Return:- - Number of bytes wrote in this pass. + None --------------------------------------------------*/ -static size_t DRPC_WriteServerIP(char *s, size_t size, size_t n, void *userdata) +static void DRPC_GotServerIP(UINT32 address) { - struct SelfIPbuffer *buffer; - size_t newlength; - - buffer = userdata; - - newlength = buffer->length + size*n; - buffer->pointer = realloc(buffer->pointer, newlength+1); - - memcpy(buffer->pointer + buffer->length, s, size*n); - - buffer->pointer[newlength] = '\0'; - buffer->length = newlength; - - return size*n; + const unsigned char * p = (const unsigned char *)&address; + sprintf(self_ip, "%u.%u.%u.%u:%u", p[0], p[1], p[2], p[3], current_port); + DRPC_UpdatePresence(); } -#endif // HAVE_CURL /*-------------------------------------------------- static const char *DRPC_GetServerIP(void) @@ -387,64 +362,21 @@ static const char *DRPC_GetServerIP(void) { // We're not the server, so we could successfully get the IP! // No need to do anything else :) - return address; + sprintf(self_ip, "%s:%u", address, current_port); + return self_ip; } } -#ifdef HAVE_CURL - // This is a little bit goofy, but - // there's practically no good way to get your own public IP address, - // so we've gotta break out curl for this :V - if (!self_ip[0]) - { - CURL *curl; - - curl_global_init(CURL_GLOBAL_ALL); - curl = curl_easy_init(); - - if (curl) - { - // The API to get your public IP address from. - // Picked because it's stupid simple and it's been up for a long time. - const char *api = "http://ip4only.me/api/"; - - struct SelfIPbuffer buffer; - CURLcode success; - - buffer.length = 0; - buffer.pointer = malloc(buffer.length+1); - buffer.pointer[0] = '\0'; - - curl_easy_setopt(curl, CURLOPT_URL, api); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, DRPC_WriteServerIP); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer); - - success = curl_easy_perform(curl); - - if (success == CURLE_OK) - { - char *tmp; - tmp = strtok(buffer.pointer, ","); - - if (!strcmp(tmp, "IPv4")) // ensure correct type of IP - { - tmp = strtok(NULL, ","); - strncpy(self_ip, tmp, IP_SIZE); // Yay, we have the IP :) - } - } - - free(buffer.pointer); - curl_easy_cleanup(curl); - } - - curl_global_cleanup(); - } - if (self_ip[0]) + { return self_ip; + } else -#endif // HAVE_CURL - return NULL; // Could not get your IP for whatever reason, so we cannot do Discord invites + { + // There happens to be a good way to get it after all! :D + STUN_bind(DRPC_GotServerIP); + return NULL; + } } /*-------------------------------------------------- @@ -510,19 +442,6 @@ void DRPC_UpdatePresence(void) // Server info if (netgame) { - if (cv_advertise.value) - { - discordPresence.state = "Public"; - } - else - { - discordPresence.state = "Private"; - } - - discordPresence.partyId = server_context; // Thanks, whoever gave us Mumble support, for implementing the EXACT thing Discord wanted for this field! - discordPresence.partySize = D_NumPlayers(); // Players in server - discordPresence.partyMax = discordInfo.maxPlayers; // Max players - if (DRPC_InvitesAreAllowed() == true) { const char *join; @@ -536,7 +455,24 @@ void DRPC_UpdatePresence(void) joinSecretSet = true; } + else + { + return; + } } + + if (cv_advertise.value) + { + discordPresence.state = "Public"; + } + else + { + discordPresence.state = "Private"; + } + + discordPresence.partyId = server_context; // Thanks, whoever gave us Mumble support, for implementing the EXACT thing Discord wanted for this field! + discordPresence.partySize = D_NumPlayers(); // Players in server + discordPresence.partyMax = discordInfo.maxPlayers; // Max players } else { diff --git a/src/i_tcp.c b/src/i_tcp.c index 1f1cf4f22..ba973494f 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -182,6 +182,7 @@ static UINT8 UPNP_support = TRUE; #include "d_netfil.h" #include "i_tcp.h" #include "m_argv.h" +#include "stun.h" #include "doomstat.h" @@ -612,6 +613,13 @@ static boolean SOCK_Get(void) (void *)&fromaddress, &fromlen); if (c != ERRSOCKET) { +#ifdef USE_STUN + if (STUN_got_response(doomcom->data, c)) + { + return false; + } +#endif + // find remote node number for (j = 1; j <= MAXNETNODES; j++) //include LAN { diff --git a/src/m_swap.h b/src/m_swap.h index 2d42f6138..c1e5e39b7 100644 --- a/src/m_swap.h +++ b/src/m_swap.h @@ -16,16 +16,12 @@ #include "endian.h" -// Endianess handling. -// WAD files are stored little endian. -#ifdef SRB2_BIG_ENDIAN - -#define SHORT(x) ((INT16)(\ +#define SWAP_SHORT(x) ((INT16)(\ (((UINT16)(x) & (UINT16)0x00ffU) << 8) \ | \ (((UINT16)(x) & (UINT16)0xff00U) >> 8))) \ -#define LONG(x) ((INT32)(\ +#define SWAP_LONG(x) ((INT32)(\ (((UINT32)(x) & (UINT32)0x000000ffUL) << 24) \ | \ (((UINT32)(x) & (UINT32)0x0000ff00UL) << 8) \ @@ -34,9 +30,18 @@ | \ (((UINT32)(x) & (UINT32)0xff000000UL) >> 24))) +// Endianess handling. +// WAD files are stored little endian. +#ifdef SRB2_BIG_ENDIAN +#define SHORT SWAP_SHORT +#define LONG SWAP_LONG +#define MSBF_SHORT(x) ((INT16)(x)) +#define MSBF_LONG(x) ((INT32)(x)) #else #define SHORT(x) ((INT16)(x)) #define LONG(x) ((INT32)(x)) +#define MSBF_SHORT SWAP_SHORT +#define MSBF_LONG SWAP_LONG #endif #endif diff --git a/src/stun.c b/src/stun.c new file mode 100644 index 000000000..96f95d41a --- /dev/null +++ b/src/stun.c @@ -0,0 +1,222 @@ +// SONIC ROBO BLAST 2 KART +//----------------------------------------------------------------------------- +// Copyright (C) 2020 by James R. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file stun.c +/// \brief RFC 5389 client implementation to fetch external IP address. + +/* https://tools.ietf.org/html/rfc5389 */ + +#if defined (__linux__) +#include +#elif defined (_WIN32) +//#include +#elif defined (__APPLE__) +#include +#else +#error "Need CSPRNG." +#endif + +#include "doomdef.h" +#include "d_clisrv.h" +#include "command.h" +#include "i_net.h" +#include "stun.h" + +/* https://gist.github.com/zziuni/3741933 */ +/* I can only trust google to keep their shit up :y */ +consvar_t cv_stunserver = { + "stunserver", "stun.l.google.com:19302", CV_SAVE, NULL, + NULL, 0, NULL, NULL, 0, 0, NULL/* C90 moment */ +}; + +static stun_callback_t stun_callback; + +/* 18.4 STUN UDP and TCP Port Numbers */ + +#define STUN_PORT "3478" + +/* 6. STUN Message Structure */ + +#define BIND_REQUEST 0x0001 +#define BIND_RESPONSE 0x0101 + +static const UINT32 MAGIC_COOKIE = MSBF_LONG (0x2112A442); + +static char transaction_id[12]; + +/* 18.2 STUN Attribute Registry */ + +#define XOR_MAPPED_ADDRESS 0x0020 + +/* 15.1 MAPPED-ADDRESS */ + +#define STUN_IPV4 0x01 + +static SINT8 +STUN_node (void) +{ + SINT8 node; + + char * const colon = strchr(cv_stunserver.zstring, ':'); + + const char * const host = cv_stunserver.zstring; + const char * const port = &colon[1]; + + I_Assert(I_NetMakeNodewPort != NULL); + + if (colon != NULL) + { + *colon = '\0'; + + node = I_NetMakeNodewPort(host, port); + + *colon = ':'; + } + else + { + node = I_NetMakeNodewPort(host, STUN_PORT); + } + + return node; +} + +void +STUN_bind (stun_callback_t callback) +{ + /* 6. STUN Message Structure */ + + const UINT16 type = MSBF_SHORT (BIND_REQUEST); + + const SINT8 node = STUN_node(); + + doomcom->remotenode = node; + doomcom->datalength = 20; + +#if defined (__linux__) + getrandom(transaction_id, 12U, 0U); +#elif defined (_WIN32) + //RtlGenRandom(transaction_id, 12UL); +#elif defined (__APPLE__) + CCRandomGenerateBytes(stun_transcation_id, 12U); +#elif defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) + arc4random_buf(transaction_id, 12U); +#endif + + memcpy(&doomcom->data[0], &type, 2U); + memset(&doomcom->data[2], 0, 2U); + memcpy(&doomcom->data[4], &MAGIC_COOKIE, 4U); + memcpy(&doomcom->data[8], transaction_id, 12U); + + stun_callback = callback; + + I_NetSend(); + Net_CloseConnection(node);/* will handle response at I_NetGet */ +} + +static size_t +STUN_xor_mapped_address (const char * const value) +{ + const UINT32 xaddr = *(const UINT32 *)&value[4]; + const UINT32 addr = xaddr ^ MAGIC_COOKIE; + + (*stun_callback)(addr); + + return 0U; +} + +static size_t +align4 (size_t n) +{ + return n + n % 4U; +} + +static size_t +STUN_parse_attribute (const char * const attribute) +{ + /* 15. STUN Attributes */ + const UINT16 type = MSBF_SHORT (*(const UINT16 *)&attribute[0]); + const UINT16 length = MSBF_SHORT (*(const UINT16 *)&attribute[2]); + + /* 15.2 XOR-MAPPED-ADDRESS */ + if ( + type == XOR_MAPPED_ADDRESS && + length == 8U && + (unsigned char)attribute[5] == STUN_IPV4 + ){ + return STUN_xor_mapped_address(&attribute[4]); + } + + return align4(4U + length); +} + +boolean +STUN_got_response +( + const char * const buffer, + const size_t size +){ + const char * const end = &buffer[size]; + + const char * p = &buffer[20]; + + UINT16 type; + UINT16 length; + + /* + Check for STUN response. + + Header is 20 bytes. + XOR-MAPPED-ADDRESS attribute is required. + Each attribute has a 2 byte header. + The XOR-MAPPED-ADDRESS attribute also has a 8 byte value. + This totals 10 bytes for the attribute. + */ + + if (size < 30U || stun_callback == NULL) + { + return false; + } + + /* 6. STUN Message Structure */ + + if ( + *(const UINT32 *)&buffer[4] == MAGIC_COOKIE && + memcmp(&buffer[8], transaction_id, 12U) == 0 + ){ + type = MSBF_SHORT (*(const UINT16 *)&buffer[0]); + length = MSBF_SHORT (*(const UINT16 *)&buffer[2]); + + if ( + (type >> 14) == 0U && + (length & 0x02) == 0U && + (20U + length) <= size + ){ + if (type == BIND_RESPONSE) + { + do + { + length = STUN_parse_attribute(p); + + if (length == 0U) + { + break; + } + + p += length; + } + while (p < end) ; + } + + stun_callback = NULL; + + return true; + } + } + + return false; +} diff --git a/src/stun.h b/src/stun.h new file mode 100644 index 000000000..de23aeb42 --- /dev/null +++ b/src/stun.h @@ -0,0 +1,20 @@ +// SONIC ROBO BLAST 2 KART +//----------------------------------------------------------------------------- +// Copyright (C) 2020 by James R. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file stun.h +/// \brief RFC 5389 client implementation to fetch external IP address. + +#ifndef KART_STUN_H +#define KART_STUN_H + +typedef void (*stun_callback_t)(UINT32 address); + +void STUN_bind (stun_callback_t); +boolean STUN_got_response (const char * const buffer, const size_t size); + +#endif/*KART_STUN_H*/ From cf73df38b43eca9c19cee0adc6b0df67746bca18 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 30 Sep 2020 12:21:33 -0700 Subject: [PATCH 06/27] Use rand_s for Windoze unsigned int is always 4 bytes on windows btw, so this should align properly. --- src/stun.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/stun.c b/src/stun.c index 96f95d41a..dbcfe58e8 100644 --- a/src/stun.c +++ b/src/stun.c @@ -14,7 +14,7 @@ #if defined (__linux__) #include #elif defined (_WIN32) -//#include +#define _CRT_RAND_S #elif defined (__APPLE__) #include #else @@ -85,6 +85,28 @@ STUN_node (void) return node; } +static void +csprng +( + void * const buffer, + const size_t size +){ +#if defined (_WIN32) + size_t o; + + for (o = 0; o < size; o += sizeof (unsigned int)) + { + rand_s((unsigned int *)&((char *)buffer)[o]); + } +#elif defined (__linux__) + getrandom(buffer, size, 0U); +#elif defined (__APPLE__) + CCRandomGenerateBytes(buffer, size); +#elif defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) + arc4random_buf(buffer, size); +#endif +} + void STUN_bind (stun_callback_t callback) { @@ -97,15 +119,7 @@ STUN_bind (stun_callback_t callback) doomcom->remotenode = node; doomcom->datalength = 20; -#if defined (__linux__) - getrandom(transaction_id, 12U, 0U); -#elif defined (_WIN32) - //RtlGenRandom(transaction_id, 12UL); -#elif defined (__APPLE__) - CCRandomGenerateBytes(stun_transcation_id, 12U); -#elif defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) - arc4random_buf(transaction_id, 12U); -#endif + csprng(transaction_id, 12U); memcpy(&doomcom->data[0], &type, 2U); memset(&doomcom->data[2], 0, 2U); From 186cdea8d5b23d6e1c11db58e0a0d65a72a0676a Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 30 Sep 2020 12:42:53 -0700 Subject: [PATCH 07/27] Reset asksent before CL_ASKJOIN It gets pushed forward for ASKINFO. --- src/d_clisrv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 88fdb35a8..f27d19ce9 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2263,7 +2263,10 @@ static boolean CL_ServerConnectionSearchTicker(tic_t *asksent) cl_mode = CL_CHECKFILES; } else + { cl_mode = CL_ASKJOIN; // files need not be checked for the server. + *asksent = 0; + } return true; } From 8a7044a4ef4549f2c3d905a96d8e55e2afab501d Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 30 Sep 2020 21:15:49 -0700 Subject: [PATCH 08/27] Add STUN to CMakeLists.txt --- src/CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c43464b78..9854567e2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -364,8 +364,9 @@ if(${SRB2_CONFIG_HAVE_DISCORDRPC}) if(${DISCORDRPC_FOUND}) set(SRB2_HAVE_DISCORDRPC ON) add_definitions(-DHAVE_DISCORDRPC) - set(SRB2_DISCORDRPC_SOURCES discord.c) - set(SRB2_DISCORDRPC_HEADERS discord.h) + add_definitions(-DUSE_STUN) + set(SRB2_DISCORDRPC_SOURCES discord.c stun.c) + set(SRB2_DISCORDRPC_HEADERS discord.h stun.h) prepend_sources(SRB2_DISCORDRPC_SOURCES) prepend_sources(SRB2_DISCORDRPC_HEADERS) source_group("Discord Rich Presence" FILES ${SRB2_DISCORDRPC_SOURCES} ${SRB2_DISCORDRPC_HEADERS}) From 67df3cdb12ca86c7a6c68ae49182c37acf35c4f2 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 7 Oct 2020 16:06:49 -0700 Subject: [PATCH 09/27] Download files that were found with wrong checksum --- src/d_netfil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_netfil.c b/src/d_netfil.c index c9bfb4ea7..950608c42 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -430,7 +430,7 @@ INT32 CL_CheckFiles(void) for (i = 0; i < fileneedednum; i++) { - if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_FALLBACK) + if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD || fileneeded[i].status == FS_FALLBACK) downloadrequired = true; if (fileneeded[i].status == FS_FOUND || fileneeded[i].status == FS_NOTFOUND) From c59d456772029b166c8231282fb50a883d2e0143 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 7 Oct 2020 16:09:21 -0700 Subject: [PATCH 10/27] Count any files not already loaded toward filestoload? --- src/d_netfil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_netfil.c b/src/d_netfil.c index 950608c42..1a5b9e41e 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -433,7 +433,7 @@ INT32 CL_CheckFiles(void) if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD || fileneeded[i].status == FS_FALLBACK) downloadrequired = true; - if (fileneeded[i].status == FS_FOUND || fileneeded[i].status == FS_NOTFOUND) + if (fileneeded[i].status != FS_OPEN) filestoload++; if (fileneeded[i].status != FS_NOTCHECKED) //since we're running this over multiple tics now, its possible for us to come across files checked in previous tics From 5d22277aed1575e844173fee083718d78b337271 Mon Sep 17 00:00:00 2001 From: JugadorXEI Date: Tue, 3 Nov 2020 16:41:00 +0100 Subject: [PATCH 11/27] Polyobject and SPB 'lastlook' interaction fix --- src/p_polyobj.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 60c653b16..cdcf37d9f 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1042,6 +1042,10 @@ static void Polyobj_carryThings(polyobj_t *po, fixed_t dx, fixed_t dy) for (; mo; mo = mo->bnext) { + // lastlook is used by the SPB to determine targets, do not let it affect it + if (mo->type == MT_SPB) + continue; + if (mo->lastlook == pomovecount) continue; @@ -1286,6 +1290,10 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta, for (; mo; mo = mo->bnext) { + // lastlook is used by the SPB to determine targets, do not let it affect it + if (mo->type == MT_SPB) + continue; + if (mo->lastlook == pomovecount) continue; From 745b293c477a2b7f7108f90131d153efbe4aa43a Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 5 Nov 2020 20:00:21 -0800 Subject: [PATCH 12/27] Always allow access to the serverplayer --- src/dehacked.c | 7 +++---- src/lua_playerlib.c | 16 +++++++++++++++- src/lua_script.c | 8 ++++++++ src/lua_script.h | 1 + 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 00f4fa96d..101507511 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9704,11 +9704,10 @@ static inline int lib_getenum(lua_State *L) lua_pushinteger(L, mapmusposition); return 1; } else if (fastcmp(word,"server")) { - if ((!multiplayer || !(netgame || demo.playback)) && !playeringame[serverplayer]) - return 0; - LUA_PushUserdata(L, &players[serverplayer], META_PLAYER); - return 1; + return LUA_PushServerPlayer(L); } else if (fastcmp(word,"consoleplayer")) { // Player controlling the console, basically our local player + if (consoleplayer == serverplayer) + return LUA_PushServerPlayer(L); if (consoleplayer < 0 || !playeringame[consoleplayer]) return 0; LUA_PushUserdata(L, &players[consoleplayer], META_PLAYER); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 3aeeed734..c4c996e5e 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -27,17 +27,28 @@ static int lib_iteratePlayers(lua_State *L) { INT32 i = -1; + if (lua_gettop(L) < 2) { //return luaL_error(L, "Don't call players.iterate() directly, use it as 'for player in players.iterate do end'."); lua_pushcfunction(L, lib_iteratePlayers); return 1; } + lua_settop(L, 2); lua_remove(L, 1); // state is unused. + if (!lua_isnil(L, 1)) i = (INT32)(*((player_t **)luaL_checkudata(L, 1, META_PLAYER)) - players); - for (i++; i < MAXPLAYERS; i++) + + i++; + + if (i == serverplayer) + { + return LUA_PushServerPlayer(L); + } + + for (; i < MAXPLAYERS; i++) { if (!playeringame[i]) continue; @@ -46,6 +57,7 @@ static int lib_iteratePlayers(lua_State *L) LUA_PushUserdata(L, &players[i], META_PLAYER); return 1; } + return 0; } @@ -58,6 +70,8 @@ static int lib_getPlayer(lua_State *L) lua_Integer i = luaL_checkinteger(L, 2); if (i < 0 || i >= MAXPLAYERS) return luaL_error(L, "players[] index %d out of range (0 - %d)", i, MAXPLAYERS-1); + if (i == serverplayer) + return LUA_PushServerPlayer(L); if (!playeringame[i]) return 0; if (!players[i].mo) diff --git a/src/lua_script.c b/src/lua_script.c index 7c951efb3..ee49efcc1 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -367,6 +367,14 @@ void LUA_PushUserdata(lua_State *L, void *data, const char *meta) lua_remove(L, -2); // remove LREG_VALID } +int LUA_PushServerPlayer(lua_State *L) +{ + if ((!multiplayer || !(netgame || demo.playback)) && !playeringame[serverplayer]) + return 0; + LUA_PushUserdata(L, &players[serverplayer], META_PLAYER); + return 1; +} + // When userdata is freed, use this function to remove it from Lua. void LUA_InvalidateUserdata(void *data) { diff --git a/src/lua_script.h b/src/lua_script.h index b3ca16bc0..5e2e171f5 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -46,6 +46,7 @@ void LUA_DumpFile(const char *filename); #endif fixed_t LUA_EvalMath(const char *word); void LUA_PushUserdata(lua_State *L, void *data, const char *meta); +int LUA_PushServerPlayer(lua_State *L); void LUA_InvalidateUserdata(void *data); void LUA_InvalidateLevel(void); void LUA_InvalidateMapthings(void); From 3386ff6b902cab5a8c88fc2c4d7cf8ca1651befc Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 5 Nov 2020 20:02:40 -0800 Subject: [PATCH 13/27] Allow accessing a player even if there is no mobj The worst part is you could've just saved the player userdata and accessed it later anyway while player.mo is nil. --- src/lua_playerlib.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index c4c996e5e..24bc6c480 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -52,8 +52,6 @@ static int lib_iteratePlayers(lua_State *L) { if (!playeringame[i]) continue; - if (!players[i].mo) - continue; LUA_PushUserdata(L, &players[i], META_PLAYER); return 1; } @@ -74,8 +72,6 @@ static int lib_getPlayer(lua_State *L) return LUA_PushServerPlayer(L); if (!playeringame[i]) return 0; - if (!players[i].mo) - return 0; LUA_PushUserdata(L, &players[i], META_PLAYER); return 1; } @@ -136,8 +132,6 @@ static int lib_iterateDisplayplayers(lua_State *L) if (i > splitscreen || !playeringame[displayplayers[i]]) return 0; // Stop! There are no more players for us to go through. There will never be a player gap in displayplayers. - if (!players[displayplayers[i]].mo) - continue; LUA_PushUserdata(L, &players[displayplayers[i]], META_PLAYER); lua_pushinteger(L, i); // push this to recall what number we were on for the next function call. I suppose this also means you can retrieve the splitscreen player number with 'for p, n in displayplayers.iterate'! return 2; @@ -158,8 +152,6 @@ static int lib_getDisplayplayers(lua_State *L) return 0; if (!playeringame[displayplayers[i]]) return 0; - if (!players[displayplayers[i]].mo) - return 0; LUA_PushUserdata(L, &players[displayplayers[i]], META_PLAYER); return 1; } From 1cedb32e51735519e9a66a3119019e2ffa6b9484 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 5 Nov 2020 20:05:04 -0800 Subject: [PATCH 14/27] Let access spectator mobj --- src/lua_playerlib.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 24bc6c480..5f034c29d 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -190,12 +190,7 @@ static int player_get(lua_State *L) else if (fastcmp(field,"name")) lua_pushstring(L, player_names[plr-players]); else if (fastcmp(field,"mo")) - { - if (plr->spectator) - lua_pushnil(L); - else - LUA_PushUserdata(L, plr->mo, META_MOBJ); - } + LUA_PushUserdata(L, plr->mo, META_MOBJ); else if (fastcmp(field,"cmd")) LUA_PushUserdata(L, &plr->cmd, META_TICCMD); else if (fastcmp(field,"playerstate")) From d996a6a3b96ce46eecc20c34ce255827c3231ec9 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 20:59:48 -0800 Subject: [PATCH 15/27] Fuck magic numbers; COM_ flags for Lua commands! --- src/command.h | 7 +++++++ src/dehacked.c | 4 ++++ src/lua_consolelib.c | 15 +++++++++++---- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/command.h b/src/command.h index 0880065b2..3a4260ec3 100644 --- a/src/command.h +++ b/src/command.h @@ -20,6 +20,13 @@ // Command buffer & command execution //=================================== +/* Lua command registration flags. */ +enum +{ + COM_ADMIN = 1, + COM_SPLITSCREEN = 2, +}; + typedef void (*com_func_t)(void); void COM_AddCommand(const char *name, com_func_t func); diff --git a/src/dehacked.c b/src/dehacked.c index 00f4fa96d..ccda71625 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8685,6 +8685,10 @@ struct { {"BT_CUSTOM2",BT_CUSTOM2}, // Lua customizable {"BT_CUSTOM3",BT_CUSTOM3}, // Lua customizable + // Lua command registration flags + {"COM_ADMIN",COM_ADMIN}, + {"COM_SPLITSCREEN",COM_SPLITSCREEN}, + // cvflags_t {"CV_SAVE",CV_SAVE}, {"CV_CALL",CV_CALL}, diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 0c73459cb..081a5fab7 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -113,12 +113,12 @@ void COM_Lua_f(void) lua_rawgeti(gL, -1, 2); // push flags from command info table if (lua_isboolean(gL, -1)) - flags = (lua_toboolean(gL, -1) ? 1 : 0); + flags = (lua_toboolean(gL, -1) ? COM_ADMIN : 0); else flags = (UINT8)lua_tointeger(gL, -1); lua_pop(gL, 1); // pop flags - if (flags & 2) // flag 2: splitscreen player command. TODO: support 4P + if (flags & COM_SPLITSCREEN) // flag 2: splitscreen player command. TODO: support 4P { if (!splitscreen) { @@ -133,7 +133,7 @@ void COM_Lua_f(void) UINT8 argc; lua_pop(gL, 1); // pop command info table - if (flags & 1 && !server && !IsPlayerAdmin(playernum)) // flag 1: only server/admin can use this command. + if (flags & COM_ADMIN && !server && !IsPlayerAdmin(playernum)) // flag 1: only server/admin can use this command. { CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); return; @@ -187,7 +187,14 @@ static int lib_comAddCommand(lua_State *L) if (lua_gettop(L) >= 3) { // For the third argument, only take a boolean or a number. lua_settop(L, 3); - if (lua_type(L, 3) != LUA_TBOOLEAN) + if (lua_type(L, 3) == LUA_TBOOLEAN) + { + CONS_Alert(CONS_WARNING, + "Using a boolean is deprecated and will be removed.\n" + "Use \"COM_\" flags instead.\n" + ); + } + else luaL_checktype(L, 3, LUA_TNUMBER); } else From 7e9922febfec1023d1648fa793ab02da76bb06df Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 21:07:28 -0800 Subject: [PATCH 16/27] COM_LOCAL makes your commands NetXCmd free, FUCK NetXCmd --- src/command.h | 1 + src/dehacked.c | 1 + src/lua_consolelib.c | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/command.h b/src/command.h index 3a4260ec3..ae573a16c 100644 --- a/src/command.h +++ b/src/command.h @@ -25,6 +25,7 @@ enum { COM_ADMIN = 1, COM_SPLITSCREEN = 2, + COM_LOCAL = 4, }; typedef void (*com_func_t)(void); diff --git a/src/dehacked.c b/src/dehacked.c index ccda71625..af576554f 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8688,6 +8688,7 @@ struct { // Lua command registration flags {"COM_ADMIN",COM_ADMIN}, {"COM_SPLITSCREEN",COM_SPLITSCREEN}, + {"COM_LOCAL",COM_LOCAL}, // cvflags_t {"CV_SAVE",CV_SAVE}, diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 081a5fab7..5d45da533 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -128,7 +128,7 @@ void COM_Lua_f(void) playernum = displayplayers[1]; } - if (netgame) + if (netgame && !( flags & COM_LOCAL ))/* don't send local commands */ { // Send the command through the network UINT8 argc; lua_pop(gL, 1); // pop command info table From 2ba99dac90599ef0c5f59f6ecc8bac9fdc35117c Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 21:09:07 -0800 Subject: [PATCH 17/27] Improve COM_AddCommand boolean deprecated warning --- src/lua_consolelib.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 5d45da533..49ef6752b 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -190,8 +190,9 @@ static int lib_comAddCommand(lua_State *L) if (lua_type(L, 3) == LUA_TBOOLEAN) { CONS_Alert(CONS_WARNING, - "Using a boolean is deprecated and will be removed.\n" - "Use \"COM_\" flags instead.\n" + "Using a boolean for admin commands is " + "deprecated and will be removed.\n" + "Use \"COM_ADMIN\" instead.\n" ); } else From 3d62b6f2ade8609aac6f1aa40f7b26b1914f930a Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Sat, 27 Jun 2020 15:30:23 +0200 Subject: [PATCH 18/27] Expose "server" and "dedicated" to Lua scripts Careful! Both are local variables and are always false for clients, and therefore should obviously not be used in anything gamelogic-related. --- src/dehacked.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index af576554f..2fae84160 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9718,12 +9718,12 @@ static inline int lib_getenum(lua_State *L) return 0; LUA_PushUserdata(L, &players[consoleplayer], META_PLAYER); return 1; - /*} else if (fastcmp(word,"admin")) { - LUA_Deprecated(L, "admin", "IsPlayerAdmin(player)"); - if (!playeringame[adminplayers[0]] || IsPlayerAdmin(serverplayer)) - return 0; - LUA_PushUserdata(L, &players[adminplayers[0]], META_PLAYER); - return 1;*/ + } else if (fastcmp(word,"isserver")) { + lua_pushboolean(L, server); + return 1; + } else if (fastcmp(word, "isdedicatedserver")) { + lua_pushboolean(L, dedicated); + return 1; } else if (fastcmp(word,"gravity")) { lua_pushinteger(L, gravity); return 1; From 758a43385d8080d2db69d36393e23915615b4d2a Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 20 Oct 2020 16:08:34 -0700 Subject: [PATCH 19/27] Add CV_Set, CV_SetValue, CV_StealthSet, CV_StealthSetValue and CV_AddValue to Lua CV_SetValue merged with CV_Set (same with CV_StealthSetValue and CV_StealthSet). --- src/lua_consolelib.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 49ef6752b..3869fdc72 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -444,6 +444,45 @@ static int lib_cvFindVar(lua_State *L) return 0; } +static int CVarSetFunction +( + lua_State *L, + void (*Set)(consvar_t *, const char *), + void (*SetValue)(consvar_t *, INT32) +){ + consvar_t *cvar = (consvar_t *)luaL_checkudata(L, 1, META_CVAR); + + switch (lua_type(L, 2)) + { + case LUA_TSTRING: + (*Set)(cvar, lua_tostring(L, 2)); + break; + case LUA_TNUMBER: + (*SetValue)(cvar, (INT32)lua_tonumber(L, 2)); + break; + default: + return luaL_typerror(L, 1, "string or number"); + } + + return 0; +} + +static int lib_cvSet(lua_State *L) +{ + return CVarSetFunction(L, CV_Set, CV_SetValue); +} + +static int lib_cvStealthSet(lua_State *L) +{ + return CVarSetFunction(L, CV_StealthSet, CV_StealthSetValue); +} + +static int lib_cvAddValue(lua_State *L) +{ + consvar_t *cvar = (consvar_t *)luaL_checkudata(L, 1, META_CVAR); + CV_AddValue(cvar, (INT32)luaL_checknumber(L, 2)); + return 0; +} // CONS_Printf for a single player // Use 'print' in baselib for a global message. @@ -483,8 +522,11 @@ static luaL_Reg lib[] = { {"COM_BufAddText", lib_comBufAddText}, {"COM_BufInsertText", lib_comBufInsertText}, {"CV_RegisterVar", lib_cvRegisterVar}, - {"CONS_Printf", lib_consPrintf}, {"CV_FindVar", lib_cvFindVar}, + {"CV_Set", lib_cvSet}, + {"CV_StealthSet", lib_cvStealthSet}, + {"CV_AddValue", lib_cvAddValue}, + {"CONS_Printf", lib_consPrintf}, {NULL, NULL} }; From cacca05ed3376c46eddd526cb20a438407672f34 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 5 Nov 2020 21:04:25 -0800 Subject: [PATCH 20/27] PreThinkFrame and PostThinkFrame hooks Changes from e4d1b9491c1137530e2b4b9d34e5f94d2bad10ac, 4456ff50abfb3207dadd9a033e6f3e1e3ee73c92, 20494c4c427f111add919437b87cf833a6196504, ee0e68d8dca67e34d81d7e2b2ee8cac05725e911. --- src/lua_hook.h | 4 ++++ src/lua_hooklib.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++ src/p_tick.c | 16 ++++++++++++++++ 3 files changed, 68 insertions(+) diff --git a/src/lua_hook.h b/src/lua_hook.h index 6af3941f1..bd2afebb4 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -20,7 +20,9 @@ enum hook { hook_MapChange, hook_MapLoad, hook_PlayerJoin, + hook_PreThinkFrame, hook_ThinkFrame, + hook_PostThinkFrame, hook_MobjSpawn, hook_MobjCollide, hook_MobjMoveCollide, @@ -64,7 +66,9 @@ extern boolean hook_cmd_running; // This is used by PlayerCmd and lua_playerlib void LUAh_MapChange(INT16 mapnumber); // Hook for map change (before load) void LUAh_MapLoad(void); // Hook for map load void LUAh_PlayerJoin(int playernum); // Hook for Got_AddPlayer +void LUAh_PreThinkFrame(void); // Hook for frame (before mobj and player thinkers) void LUAh_ThinkFrame(void); // Hook for frame (after mobj and player thinkers) +void LUAh_PostThinkFrame(void); // Hook for frame (at end of tick, ie after overlays, precipitation, specials) boolean LUAh_MobjHook(mobj_t *mo, enum hook which); boolean LUAh_PlayerHook(player_t *plr, enum hook which); #define LUAh_MobjSpawn(mo) LUAh_MobjHook(mo, hook_MobjSpawn) // Hook for P_SpawnMobj by mobj type diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 41a436e01..90a13c6fa 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -31,7 +31,9 @@ const char *const hookNames[hook_MAX+1] = { "MapChange", "MapLoad", "PlayerJoin", + "PreThinkFrame", "ThinkFrame", + "PostThinkFrame", "MobjSpawn", "MobjCollide", "MobjMoveCollide", @@ -402,6 +404,29 @@ void LUAh_PlayerJoin(int playernum) lua_settop(gL, 0); } +// Hook for frame (before mobj and player thinkers) +void LUAh_PreThinkFrame(void) +{ + hook_p hookp; + if (!gL || !(hooksAvailable[hook_PreThinkFrame/8] & (1<<(hook_PreThinkFrame%8)))) + return; + + for (hookp = roothook; hookp; hookp = hookp->next) + { + if (hookp->type != hook_PreThinkFrame) + continue; + + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + if (lua_pcall(gL, 0, 0, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + } + } +} + // Hook for frame (after mobj and player thinkers) void LUAh_ThinkFrame(void) { @@ -423,6 +448,29 @@ void LUAh_ThinkFrame(void) } } +// Hook for frame (at end of tick, ie after overlays, precipitation, specials) +void LUAh_PostThinkFrame(void) +{ + hook_p hookp; + if (!gL || !(hooksAvailable[hook_PostThinkFrame/8] & (1<<(hook_PostThinkFrame%8)))) + return; + + for (hookp = roothook; hookp; hookp = hookp->next) + { + if (hookp->type != hook_PostThinkFrame) + continue; + + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + if (lua_pcall(gL, 0, 0, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + } + } +} + // Hook for Y_Ticker void LUAh_IntermissionThinker(void) { diff --git a/src/p_tick.c b/src/p_tick.c index 4cc6c9ba4..bf0344477 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -648,6 +648,10 @@ void P_Ticker(boolean run) #endif } +#ifdef HAVE_BLUA + LUAh_PreThinkFrame(); +#endif + for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) P_PlayerThink(&players[i]); @@ -779,6 +783,10 @@ void P_Ticker(boolean run) && --mapreset <= 1 && server) // Remember: server uses it for mapchange, but EVERYONE ticks down for the animation D_MapChange(gamemap, gametype, encoremode, true, 0, false, false); + +#ifdef HAVE_BLUA + LUAh_PostThinkFrame(); +#endif } // Always move the camera. @@ -809,6 +817,10 @@ void P_PreTicker(INT32 frames) { P_MapStart(); +#ifdef HAVE_BLUA + LUAh_PreThinkFrame(); +#endif + for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) { @@ -843,6 +855,10 @@ void P_PreTicker(INT32 frames) P_UpdateSpecials(); P_RespawnSpecials(); +#ifdef HAVE_BLUA + LUAh_PostThinkFrame(); +#endif + P_MapEnd(); } } From 7efb33a38edc0f472c4cc8f212f9240b9f9e78c2 Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Sat, 14 Dec 2019 15:28:24 -0600 Subject: [PATCH 21/27] Added PlayerThink hook --- src/lua_hook.h | 2 ++ src/lua_hooklib.c | 2 ++ src/p_user.c | 20 +++++++++++++++++++- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index bd2afebb4..3f2dfd7a5 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -46,6 +46,7 @@ enum hook { hook_HurtMsg, hook_PlayerSpawn, hook_PlayerQuit, + hook_PlayerThink, hook_MusicChange, hook_ShouldSpin, //SRB2KART hook_ShouldExplode, //SRB2KART @@ -110,5 +111,6 @@ boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Allows to write to p void LUAh_IntermissionThinker(void); // Hook for Y_Ticker void LUAh_VoteThinker(void); // Hook for Y_VoteTicker +#define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 90a13c6fa..e9a4d0b40 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -57,6 +57,7 @@ const char *const hookNames[hook_MAX+1] = { "HurtMsg", "PlayerSpawn", "PlayerQuit", + "PlayerThink", "MusicChange", "ShouldSpin", "ShouldExplode", @@ -208,6 +209,7 @@ static int lib_addHook(lua_State *L) case hook_SpinSpecial: case hook_JumpSpinSpecial: case hook_PlayerSpawn: + case hook_PlayerThink: lastp = &playerhooks; break; case hook_LinedefExecute: diff --git a/src/p_user.c b/src/p_user.c index cb6b7bd62..dc22bd940 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8244,7 +8244,12 @@ void P_PlayerThink(player_t *player) player->playerstate = PST_REBORN; } if (player->playerstate == PST_REBORN) + { +#ifdef HAVE_BLUA + LUAh_PlayerThink(player); +#endif return; + } } #ifdef SEENAMES @@ -8368,7 +8373,12 @@ void P_PlayerThink(player_t *player) P_DoTimeOver(player); if (player->playerstate == PST_DEAD) + { +#ifdef HAVE_BLUA + LUAh_PlayerThink(player); +#endif return; + } } } @@ -8432,7 +8442,9 @@ void P_PlayerThink(player_t *player) else player->mo->flags2 &= ~MF2_SHADOW; P_DeathThink(player); - +#ifdef HAVE_BLUA + LUAh_PlayerThink(player); +#endif return; } @@ -8566,6 +8578,12 @@ void P_PlayerThink(player_t *player) } else P_MovePlayer(player); + } + +#ifdef HAVE_BLUA + LUAh_PlayerThink(player); +#endif + if (!player->mo) return; // P_MovePlayer removed player->mo. From 2764c283d2a27dcafe784086863cc7e5923ff79f Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Sat, 28 Dec 2019 17:40:47 -0600 Subject: [PATCH 22/27] Execute LUAh_PlayerThink(player) at the end if the player has a valid mobj_t object --- src/p_user.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index dc22bd940..6f00e410f 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8580,13 +8580,13 @@ void P_PlayerThink(player_t *player) P_MovePlayer(player); } -#ifdef HAVE_BLUA - LUAh_PlayerThink(player); -#endif - - if (!player->mo) + { +#ifdef HAVE_BLUA + LUAh_PlayerThink(player); +#endif return; // P_MovePlayer removed player->mo. + } // Unset statis flags after moving. // In other words, if you manually set stasis via code, @@ -8782,6 +8782,10 @@ void P_PlayerThink(player_t *player) K_KartPlayerThink(player, cmd); // SRB2kart +#ifdef HAVE_BLUA + LUAh_PlayerThink(player); +#endif + /* // Colormap verification { From e2df4cf027c05d8e0bc466863bc3fa8fb1b809a9 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 5 Nov 2020 22:18:41 -0800 Subject: [PATCH 23/27] :V --- src/p_user.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 6f00e410f..8d5536338 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8578,7 +8578,6 @@ void P_PlayerThink(player_t *player) } else P_MovePlayer(player); - } if (!player->mo) { From c902f9addb995dd65852264122f8035d9e450621 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sat, 7 Nov 2020 20:32:44 +0200 Subject: [PATCH 24/27] R_FindPlane optimization from SRB2 --- src/r_plane.c | 61 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index d00274262..9b0691da8 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -46,7 +46,10 @@ //#define SHITPLANESPARENCY //SoM: 3/23/2000: Use Boom visplane hashing. -#define MAXVISPLANES 512 +#define VISPLANEHASHBITS 9 +#define VISPLANEHASHMASK ((1<next) + if (!pfloor) { - if (check->polyobj && pfloor) - continue; - if (polyobj != check->polyobj) - continue; - if (height == check->height && picnum == check->picnum - && lightlevel == check->lightlevel - && xoff == check->xoffs && yoff == check->yoffs - && planecolormap == check->extra_colormap - && !pfloor && !check->ffloor - && check->viewx == viewx && check->viewy == viewy && check->viewz == viewz - && check->viewangle == viewangle - && check->plangle == plangle - && check->slope == slope - && check->noencore == noencore) + hash = visplane_hash(picnum, lightlevel, height); + for (check = visplanes[hash]; check; check = check->next) { - return check; + if (polyobj != check->polyobj) + continue; + if (height == check->height && picnum == check->picnum + && lightlevel == check->lightlevel + && xoff == check->xoffs && yoff == check->yoffs + && planecolormap == check->extra_colormap + && check->viewx == viewx && check->viewy == viewy && check->viewz == viewz + && check->viewangle == viewangle + && check->plangle == plangle + && check->slope == slope + && check->noencore == noencore) + { + return check; + } } } + else + { + hash = MAXVISPLANES - 1; + } check = new_visplane(hash); @@ -559,9 +564,17 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop) } else /* Cannot use existing plane; create a new one */ { - unsigned hash = - visplane_hash(pl->picnum, pl->lightlevel, pl->height); - visplane_t *new_pl = new_visplane(hash); + visplane_t *new_pl; + if (pl->ffloor) + { + new_pl = new_visplane(MAXVISPLANES - 1); + } + else + { + unsigned hash = + visplane_hash(pl->picnum, pl->lightlevel, pl->height); + new_pl = new_visplane(hash); + } new_pl->height = pl->height; new_pl->picnum = pl->picnum; From f27a2b904b0cd6e99af3229da44e0cfe0a6a7cba Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 7 Nov 2020 19:47:50 -0500 Subject: [PATCH 25/27] Use FixedHypot over P_AproxDistance Not convinced that the small speed benefit from P_AproxDistance is worth the "aproximate"[sic] results it gives. Let's instead try a define to replace it with FixedHypot. In Lua, the function gives a deprecated warning. Inspired by the hyperwall fix for vanilla, except for everything. From little testing, actively improves waypoint checks, bumping, speed checks, wall collisions, Jawz targetting, Lightning Shield attacks, so on. The only way I see this as a potential downgrade is A_Look (and related functions) getting slower, which are barely used in Kart. --- src/lua_baselib.c | 3 ++- src/p_maputl.c | 13 ------------- src/p_maputl.h | 2 +- 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 56b1a5a54..c50f53dfc 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -238,7 +238,8 @@ static int lib_pAproxDistance(lua_State *L) fixed_t dx = luaL_checkfixed(L, 1); fixed_t dy = luaL_checkfixed(L, 2); //HUDSAFE - lua_pushfixed(L, P_AproxDistance(dx, dy)); + LUA_Deprecated(L, "P_AproxDistance", "FixedHypot"); + lua_pushfixed(L, FixedHypot(dx, dy)); return 1; } diff --git a/src/p_maputl.c b/src/p_maputl.c index 260eb3ec6..760e45c4f 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -23,19 +23,6 @@ #include "p_slopes.h" #include "z_zone.h" -// -// P_AproxDistance -// Gives an estimation of distance (not exact) -// -fixed_t P_AproxDistance(fixed_t dx, fixed_t dy) -{ - dx = abs(dx); - dy = abs(dy); - if (dx < dy) - return dx + dy - (dx>>1); - return dx + dy - (dy>>1); -} - // // P_ClosestPointOnLine // Finds the closest point on a given line to the supplied point diff --git a/src/p_maputl.h b/src/p_maputl.h index be69e0265..ec4a4aa33 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -41,7 +41,7 @@ typedef boolean (*traverser_t)(intercept_t *in); boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2, INT32 pflags, traverser_t ptrav); -FUNCMATH fixed_t P_AproxDistance(fixed_t dx, fixed_t dy); +#define P_AproxDistance(dx, dy) FixedHypot(dx, dy) void P_ClosestPointOnLine(fixed_t x, fixed_t y, line_t *line, vertex_t *result); void P_ClosestPointOnLine3D(fixed_t x, fixed_t y, fixed_t z, line_t *line, vertex_t *result); INT32 P_PointOnLineSide(fixed_t x, fixed_t y, line_t *line); From def9b7112a6253512bdc7023115c63266cc2d468 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 7 Nov 2020 23:56:46 -0500 Subject: [PATCH 26/27] Use R_PointToDist2 instead Apparently overflows less often --- src/lua_baselib.c | 4 ++-- src/p_maputl.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index c50f53dfc..73295a139 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -238,8 +238,8 @@ static int lib_pAproxDistance(lua_State *L) fixed_t dx = luaL_checkfixed(L, 1); fixed_t dy = luaL_checkfixed(L, 2); //HUDSAFE - LUA_Deprecated(L, "P_AproxDistance", "FixedHypot"); - lua_pushfixed(L, FixedHypot(dx, dy)); + LUA_Deprecated(L, "P_AproxDistance", "R_PointToDist2"); + lua_pushfixed(L, R_PointToDist2(0, 0, dx, dy)); return 1; } diff --git a/src/p_maputl.h b/src/p_maputl.h index ec4a4aa33..5be618d8f 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -41,7 +41,7 @@ typedef boolean (*traverser_t)(intercept_t *in); boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2, INT32 pflags, traverser_t ptrav); -#define P_AproxDistance(dx, dy) FixedHypot(dx, dy) +#define P_AproxDistance(dx, dy) R_PointToDist2(0, 0, dx, dy) void P_ClosestPointOnLine(fixed_t x, fixed_t y, line_t *line, vertex_t *result); void P_ClosestPointOnLine3D(fixed_t x, fixed_t y, fixed_t z, line_t *line, vertex_t *result); INT32 P_PointOnLineSide(fixed_t x, fixed_t y, line_t *line); From b3f4483ac225fab05d2617590680a099136f3647 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 8 Nov 2020 00:45:16 -0500 Subject: [PATCH 27/27] Actually, lets just fix FixedHypot instead. Now FixedHypot uses the code from R_PointToDist2, and R_PointToDist2 just calls FixedHypot. Ultimately, this branch was intended to get rid of a redundant way to retrieve distance and replace it with the one that was actually good at its job. So consolidating FixedHypot and R_PointToDist2 together is just an extension of that. --- src/lua_baselib.c | 4 ++-- src/m_fixed.c | 40 ++++++++++++++++++++++++++++------------ src/p_maputl.h | 2 +- src/r_main.c | 24 +----------------------- 4 files changed, 32 insertions(+), 38 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 73295a139..c50f53dfc 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -238,8 +238,8 @@ static int lib_pAproxDistance(lua_State *L) fixed_t dx = luaL_checkfixed(L, 1); fixed_t dy = luaL_checkfixed(L, 2); //HUDSAFE - LUA_Deprecated(L, "P_AproxDistance", "R_PointToDist2"); - lua_pushfixed(L, R_PointToDist2(0, 0, dx, dy)); + LUA_Deprecated(L, "P_AproxDistance", "FixedHypot"); + lua_pushfixed(L, FixedHypot(dx, dy)); return 1; } diff --git a/src/m_fixed.c b/src/m_fixed.c index 7241be9c0..3724144f7 100644 --- a/src/m_fixed.c +++ b/src/m_fixed.c @@ -18,8 +18,10 @@ #define HAVE_SQRTF #endif #endif + #include "doomdef.h" #include "m_fixed.h" +#include "tables.h" // ANGLETOFINESHIFT #ifdef __USE_C_FIXEDMUL__ @@ -105,20 +107,34 @@ fixed_t FixedSqrt(fixed_t x) fixed_t FixedHypot(fixed_t x, fixed_t y) { - fixed_t ax, yx, yx2, yx1; - if (abs(y) > abs(x)) // |y|>|x| + // Moved the code from R_PointToDist2 to here, + // since R_PointToDist2 did the same thing, + // except less prone to overflowing. + + angle_t angle; + fixed_t dist; + + x = abs(x); + y = abs(y); + + if (y > x) { - ax = abs(y); // |y| => ax - yx = FixedDiv(x, y); // (x/y) + fixed_t temp; + + temp = x; + x = y; + y = temp; } - else // |x|>|y| - { - ax = abs(x); // |x| => ax - yx = FixedDiv(y, x); // (x/y) - } - yx2 = FixedMul(yx, yx); // (x/y)^2 - yx1 = FixedSqrt(1 * FRACUNIT + yx2); // (1 + (x/y)^2)^1/2 - return FixedMul(ax, yx1); // |x|*((1 + (x/y)^2)^1/2) + + if (!y) + return x; + + angle = (tantoangle[FixedDiv(y, x)>>DBITS] + ANGLE_90) >> ANGLETOFINESHIFT; + + // use as cosine + dist = FixedDiv(x, FINESINE(angle)); + + return dist; } vector2_t *FV2_Load(vector2_t *vec, fixed_t x, fixed_t y) diff --git a/src/p_maputl.h b/src/p_maputl.h index 5be618d8f..ec4a4aa33 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -41,7 +41,7 @@ typedef boolean (*traverser_t)(intercept_t *in); boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2, INT32 pflags, traverser_t ptrav); -#define P_AproxDistance(dx, dy) R_PointToDist2(0, 0, dx, dy) +#define P_AproxDistance(dx, dy) FixedHypot(dx, dy) void P_ClosestPointOnLine(fixed_t x, fixed_t y, line_t *line, vertex_t *result); void P_ClosestPointOnLine3D(fixed_t x, fixed_t y, fixed_t z, line_t *line, vertex_t *result); INT32 P_PointOnLineSide(fixed_t x, fixed_t y, line_t *line); diff --git a/src/r_main.c b/src/r_main.c index 5f3639ded..a78cd57eb 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -393,29 +393,7 @@ angle_t R_PointToAngle2(fixed_t pviewx, fixed_t pviewy, fixed_t x, fixed_t y) fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1) { - angle_t angle; - fixed_t dx, dy, dist; - - dx = abs(px1 - px2); - dy = abs(py1 - py2); - - if (dy > dx) - { - fixed_t temp; - - temp = dx; - dx = dy; - dy = temp; - } - if (!dy) - return dx; - - angle = (tantoangle[FixedDiv(dy, dx)>>DBITS] + ANGLE_90) >> ANGLETOFINESHIFT; - - // use as cosine - dist = FixedDiv(dx, FINESINE(angle)); - - return dist; + return FixedHypot(px1 - px2, py1 - py2); } // Little extra utility. Works in the same way as R_PointToAngle2