From 7c072503be1da7568c62e89d13708cff1972a591 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 15 May 2020 18:11:05 -0700 Subject: [PATCH 01/36] 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 652ffbcb..66477bbe 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 3dc9da68..006f775b 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 f37df371..ef414b88 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 64e27f369845d2cc60dd501df02b7f48036df6dd Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 15 May 2020 19:04:03 -0700 Subject: [PATCH 02/36] 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 006f775b..446f3814 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 ef414b88..913a2119 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 2d4202ac09dcd29f5794fee49d7732ff12742620 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 16 May 2020 21:03:37 -0700 Subject: [PATCH 03/36] 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 446f3814..d2a6fe55 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 13a34e25454fc81c48820d8ab00ecba90e988da9 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 17 Sep 2020 15:59:02 -0400 Subject: [PATCH 04/36] Link with exchndl, instead of dynamically loading it. It caused problems with crash reports not being made if the current working directory gets changed. Not even recommended anymore per the drmingw readme https://github.com/jrfonseca/drmingw#exchndl --- libs/drmingw/include/exchndl.h | 39 ++++++++++++++++++++++++++++ libs/drmingw/lib/win32/libexchndl.a | Bin 0 -> 3210 bytes libs/drmingw/lib/win32/libmgwhelp.a | Bin 0 -> 85370 bytes src/sdl/i_main.c | 6 ++++- src/win32/Makefile.cfg | 6 +++++ 5 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 libs/drmingw/include/exchndl.h create mode 100644 libs/drmingw/lib/win32/libexchndl.a create mode 100644 libs/drmingw/lib/win32/libmgwhelp.a diff --git a/libs/drmingw/include/exchndl.h b/libs/drmingw/include/exchndl.h new file mode 100644 index 00000000..37dafb88 --- /dev/null +++ b/libs/drmingw/include/exchndl.h @@ -0,0 +1,39 @@ +/* + * Copyright 2002-2015 Jose Fonseca + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#pragma once + + +#include + + +// Set the unhandled exception handler. +// Must be called when exchndll.dll is statically loaded (as opposed to loaded +// dynamically via LoadLibrary) +EXTERN_C VOID APIENTRY +ExcHndlInit(void); + + +// Override the report file name. +// +// Default is prog_name.RPT, in the same directory as the main executable. +// +// You can also pass "-" for stderr. +EXTERN_C BOOL APIENTRY +ExcHndlSetLogFileNameA(const char *szLogFileName); diff --git a/libs/drmingw/lib/win32/libexchndl.a b/libs/drmingw/lib/win32/libexchndl.a new file mode 100644 index 0000000000000000000000000000000000000000..cd462a0df1b7e8f95d34ba2c6fa184161dd1604c GIT binary patch literal 3210 zcmdT`-HOvd6h3LYcDJlQpcmqWL{RWTYWkO5p)M6s6p9Gmi7?GJX&bjqOPgx($_pQ0 zA8FYq@Y1JoJ?G4%owiB4E$HHb%$%J0GL!k{n=|vE>I|Emquf(--U^j+sc4sq&kCk# zag$z}X0c?e4;ncDxCUTY0O_CT{*uq$Il$hz5HE!o4EvwGW;hb=u;&Nuui|*@cU>X< zu751>@g~hq;C6*0{J`mXAVkM=+>O5m@oLh1gB^YF!g{~`+V6Vru)7zvGWO{A24Y3K z`tohyhc#;fu7cq9ympxHPw7hHsbE>QjTG4hB#^C5RiZfIc9U@j5pExy{TN)- zu9iFRcDs;o;VP+y-xmOFqvf1L0TtJIqHfa*eG^RQD3yfK_(>;WG;V0VX@kmnQ~WV6 zJJ_@W!<^8{rww9d*`nSFlY-}1ZoO-Aq|eR<`aCF9mh@>Ox3~B=Ggqz8V#L-RbV#4H zcgSe%;`GUl3x$T8>U{yiuY`+>Q;b$F%O&mHEc0`nz00V#!zm5nXsiTig`IJ5A|tFH zxB`VUyHerAFL63EJwwQUUeY{+BlS{EyAGhrr7Th~MrZ3}zH$Cnrw8wYk%d-}n_+F9 zKAfFrbtB6^{{yu~hZ`wRUmc3<;`0RCKPf#@W&XW9Js#L&OZ? zanpT3{Z$e3EgolMGuu5ZYYL-6Sea)RkLd06bQZ�K}icgdv5{n4~DYAK)Xorgz=b z`KDph%h?_DvyO8)D1|axGzxyDonLC7Y1w^F*F0DH2e}XEdomhb>iRyv15iIQa-y;9UNzT|v@lU%3t_iFX2`j<-osExZy>25r3N$Ej6 wZmRSfIKP_0psOri=@2QMu7`;HpVfU^&2*;j$I;|@W(_POb+5W2Z=37?0OSYSbpQYW literal 0 HcmV?d00001 diff --git a/libs/drmingw/lib/win32/libmgwhelp.a b/libs/drmingw/lib/win32/libmgwhelp.a new file mode 100644 index 0000000000000000000000000000000000000000..330cb52fe52c82ba557712e6cdd55f154f6e041a GIT binary patch literal 85370 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 KQFfWV`+otx_Un8A literal 0 HcmV?d00001 diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index a2ce653e..e6644ec5 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -58,6 +58,10 @@ char logfilename[1024]; #endif #endif +#if defined (_WIN32) +#include "exchndl.h" +#endif + #if defined (_WIN32) #include "../win32/win_dbg.h" typedef BOOL (WINAPI *p_IsDebuggerPresent)(VOID); @@ -170,7 +174,7 @@ int main(int argc, char **argv) ) #endif { - LoadLibraryA("exchndl.dll"); + ExcHndlInit(); } } #ifndef __MINGW32__ diff --git a/src/win32/Makefile.cfg b/src/win32/Makefile.cfg index 935b2722..e9e18280 100644 --- a/src/win32/Makefile.cfg +++ b/src/win32/Makefile.cfg @@ -60,6 +60,12 @@ else endif endif +ifndef MINGW64 + CPPFLAGS+=-I../libs/drmingw/include + LDFLAGS+=-L../libs/drmingw/lib/win32 + LIBS+=-lmgwhelp -lexchndl +endif + # name of the exefile ifdef SDL EXENAME?=srb2kart.exe From 21422703f57960b00e4a076c77b28200f9780f10 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 17 Sep 2020 18:58:44 -0400 Subject: [PATCH 05/36] Fix engine sounds' dampening to a sane value, now that the bug preventing it from working properly was fixed. You can hear engines in 16P again, but it's not as obnoxiously loud as it was before. Additionally, I commented this function better. --- src/k_kart.c | 117 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 79 insertions(+), 38 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index e6afebc7..35de052a 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4401,14 +4401,22 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source) static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd) { const INT32 numsnds = 13; + + const fixed_t closedist = 160*FRACUNIT; + const fixed_t fardist = 1536*FRACUNIT; + + const UINT8 dampenval = 64; // 255 * 64 = close enough to FRACUNIT/4 + INT32 class, s, w; // engine class number + UINT8 volume = 255; - fixed_t volumedampen = 0; + fixed_t volumedampen = FRACUNIT; + INT32 targetsnd = 0; INT32 i; - s = (player->kartspeed-1)/3; - w = (player->kartweight-1)/3; + s = (player->kartspeed - 1) / 3; + w = (player->kartweight - 1) / 3; #define LOCKSTAT(stat) \ if (stat < 0) { stat = 0; } \ @@ -4417,81 +4425,114 @@ static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd) LOCKSTAT(w); #undef LOCKSTAT - class = s+(3*w); + class = s + (3*w); - // Silence the engines if (leveltime < 8 || player->spectator || player->exiting) { - player->kartstuff[k_enginesnd] = 0; // Reset sound number + // Silence the engines, and reset sound number while we're at it. + player->kartstuff[k_enginesnd] = 0; return; } #if 0 if ((leveltime % 8) != ((player-players) % 8)) // Per-player offset, to make engines sound distinct! #else - if (leveltime % 8) // .25 seconds of wait time between engine sounds + if (leveltime % 8) #endif + { + // .25 seconds of wait time between each engine sound playback return; + } - if ((leveltime >= starttime-(2*TICRATE) && leveltime <= starttime) || (player->kartstuff[k_respawn] == 1)) // Startup boosts + if ((leveltime >= starttime-(2*TICRATE) && leveltime <= starttime) || (player->kartstuff[k_respawn] == 1)) + { + // Startup boosts only want to check for BT_ACCELERATE being pressed. targetsnd = ((cmd->buttons & BT_ACCELERATE) ? 12 : 0); + } else - targetsnd = (((6*cmd->forwardmove)/25) + ((player->speed / mapobjectscale)/5))/2; + { + // Average out the value of forwardmove and the speed that you're moving at. + targetsnd = (((6 * cmd->forwardmove) / 25) + ((player->speed / mapobjectscale) / 5)) / 2; + } - if (targetsnd < 0) - targetsnd = 0; - if (targetsnd > 12) - targetsnd = 12; + if (targetsnd < 0) { targetsnd = 0; } + if (targetsnd > 12) { targetsnd = 12; } - if (player->kartstuff[k_enginesnd] < targetsnd) - player->kartstuff[k_enginesnd]++; - if (player->kartstuff[k_enginesnd] > targetsnd) - player->kartstuff[k_enginesnd]--; + if (player->kartstuff[k_enginesnd] < targetsnd) { player->kartstuff[k_enginesnd]++; } + if (player->kartstuff[k_enginesnd] > targetsnd) { player->kartstuff[k_enginesnd]--; } - if (player->kartstuff[k_enginesnd] < 0) - player->kartstuff[k_enginesnd] = 0; - if (player->kartstuff[k_enginesnd] > 12) - player->kartstuff[k_enginesnd] = 12; + if (player->kartstuff[k_enginesnd] < 0) { player->kartstuff[k_enginesnd] = 0; } + if (player->kartstuff[k_enginesnd] > 12) { player->kartstuff[k_enginesnd] = 12; } + + // This code calculates how many players (and thus, how many engine sounds) are within ear shot, + // and rebalances the volume of your engine sound based on how far away they are. + + // This results in multiple things: + // - When on your own, you will hear your own engine sound extremely clearly. + // - When you were alone but someone is gaining on you, yours will go quiet, and you can hear theirs more clearly. + // - When around tons of people, engine sounds will try to rebalance to not be as obnoxious. for (i = 0; i < MAXPLAYERS; i++) { UINT8 thisvol = 0; fixed_t dist; - if (!playeringame[i] || !players[i].mo || players[i].spectator || players[i].exiting) - continue; - - if (P_IsDisplayPlayer(&players[i])) + if (!playeringame[i] || !players[i].mo) { - volumedampen += FRACUNIT; // We already know what this is gonna be, let's not waste our time. + // This player doesn't exist. continue; } - dist = P_AproxDistance(P_AproxDistance(player->mo->x-players[i].mo->x, - player->mo->y-players[i].mo->y), player->mo->z-players[i].mo->z) / 2; + if (players[i].spectator || players[i].exiting) + { + // This player isn't playing an engine sound. + continue; + } + + if (player == &players[i] || P_IsDisplayPlayer(&players[i])) + { + // Don't dampen yourself! + continue; + } + + dist = P_AproxDistance( + P_AproxDistance( + player->mo->x - players[i].mo->x, + player->mo->y - players[i].mo->y), + player->mo->z - players[i].mo->z) / 2; dist = FixedDiv(dist, mapobjectscale); - if (dist > 1536< fardist) + { + // ENEMY OUT OF RANGE ! continue; - else if (dist < 160<>FRACBITS)) / (((1536<>(FRACBITS+4)); + { + thisvol = (15 * ((closedist - dist) / FRACUNIT)) / ((fardist - closedist) >> (FRACBITS+4)); + } - if (thisvol == 0) - continue; - - volumedampen += (thisvol * 257); // 255 * 257 = FRACUNIT + volumedampen += (thisvol * dampenval); } if (volumedampen > FRACUNIT) - volume = FixedDiv(volume<>FRACBITS; + { + volume = FixedDiv(volume * FRACUNIT, volumedampen) / FRACUNIT; + } - if (volume <= 0) // Might as well + if (volume <= 0) + { + // Don't need to play the sound at all. return; + } - S_StartSoundAtVolume(player->mo, (sfx_krta00 + player->kartstuff[k_enginesnd]) + (class*numsnds), volume); + S_StartSoundAtVolume(player->mo, (sfx_krta00 + player->kartstuff[k_enginesnd]) + (class * numsnds), volume); } static void K_UpdateInvincibilitySounds(player_t *player) From eb0a3c9da316d0fb442fe82f2a625a71ad6a6751 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 18 Sep 2020 01:10:59 -0400 Subject: [PATCH 06/36] Make it a bit louder --- src/k_kart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 35de052a..c4bade95 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4405,7 +4405,7 @@ static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd) const fixed_t closedist = 160*FRACUNIT; const fixed_t fardist = 1536*FRACUNIT; - const UINT8 dampenval = 64; // 255 * 64 = close enough to FRACUNIT/4 + const UINT8 dampenval = 48; // 255 * 48 = close enough to FRACUNIT/6 INT32 class, s, w; // engine class number From 0523114f5677915314fd20344c0979c96d9d6f51 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 18 Sep 2020 13:11:49 -0700 Subject: [PATCH 07/36] Kill some nonsense --- src/d_clisrv.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/d_clisrv.h b/src/d_clisrv.h index e94fd7e8..b88e7936 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -35,13 +35,7 @@ applications may follow different packet versions. // SOME numpty changed all the gametype constants and it fell out of sync with vanilla and now we have to pretend to be vanilla when talking to the master server... #define VANILLA_GT_RACE 2 -// Woah, what do these numbers mean? 200 refers to SRB2 2.0, 246 refers to -// SRB2Riders. Both use the old 2.0 gametype numbers. -#if VERSION == 200 || VERSION == 246 -#define VANILLA_GT_MATCH 1 -#else #define VANILLA_GT_MATCH 3 -#endif // Networking and tick handling related. #define BACKUPTICS 32 From b70d765144f8a721706702f4b6aac1b1fa7ba29b Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 24 Sep 2020 14:43:21 -0700 Subject: [PATCH 08/36] Prepend srb2home to luafiles --- src/blua/liolib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blua/liolib.c b/src/blua/liolib.c index a9e71f74..b5ff3361 100644 --- a/src/blua/liolib.c +++ b/src/blua/liolib.c @@ -190,7 +190,7 @@ static int io_open (lua_State *L) { return pushresult(L,0,filename); } - destFilename = va("luafiles"PATHSEP"%s", filename); + destFilename = va("%s"PATHSEP"luafiles"PATHSEP"%s", srb2home, filename); // Make directories as needed splitter = destFilename; From e2749f8fdc910ca797dc4752e6b3e4837206ae7d Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 25 Sep 2020 11:25:15 -0700 Subject: [PATCH 09/36] Include d_main.h --- src/blua/liolib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/blua/liolib.c b/src/blua/liolib.c index b5ff3361..d1d6f469 100644 --- a/src/blua/liolib.c +++ b/src/blua/liolib.c @@ -19,6 +19,7 @@ #include "lualib.h" #include "../i_system.h" #include "../doomdef.h" +#include "../d_main.h" #include "../m_misc.h" From a39762a8fde1e7755d66468057eb2b6a42ef35b7 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 28 Sep 2020 11:58:24 -0700 Subject: [PATCH 10/36] 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 22586321..ea0a1bbe 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 37eedf14..2858e9b6 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 b8bfe9b83a9e2f9a003a87950729765900ab6872 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 30 Sep 2020 03:55:16 -0700 Subject: [PATCH 11/36] 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 fb859a33..da96f0cf 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 b88e7936..b7fc56ec 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 4a90de33..84c1045a 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 b3798e29..4f72b714 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 1f1cf4f2..ba973494 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 2d42f613..c1e5e39b 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 00000000..96f95d41 --- /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 00000000..de23aeb4 --- /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 81a7103b73dbc989f66e6e0031f1a6a4c7e2253b Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 30 Sep 2020 12:21:33 -0700 Subject: [PATCH 12/36] 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 96f95d41..dbcfe58e 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 88c98970eba3cd199ba32a0e49452986b926c23a Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 30 Sep 2020 12:42:53 -0700 Subject: [PATCH 13/36] 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 88fdb35a..f27d19ce 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 dc9466a7f45fb79b69904d714762006f207bc3e8 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 30 Sep 2020 21:15:49 -0700 Subject: [PATCH 14/36] 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 c43464b7..9854567e 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 d96f93f8a911af6ddbdfcc28bfb4faad11643586 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 7 Oct 2020 16:06:49 -0700 Subject: [PATCH 15/36] 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 c9bfb4ea..950608c4 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 dc86206c23ea350140883095d685c106a9b60043 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 7 Oct 2020 16:09:21 -0700 Subject: [PATCH 16/36] 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 950608c4..1a5b9e41 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 2714940be992ba23d258d71371a4ddeda9560ab4 Mon Sep 17 00:00:00 2001 From: JugadorXEI Date: Tue, 3 Nov 2020 16:41:00 +0100 Subject: [PATCH 17/36] 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 60c653b1..cdcf37d9 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 29d8e440550ee00d6cbdf14f75312ea58c781254 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 5 Nov 2020 20:00:21 -0800 Subject: [PATCH 18/36] 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 00f4fa96..10150751 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 3aeeed73..c4c996e5 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 7c951efb..ee49efcc 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 b3ca16bc..5e2e171f 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 9e586c348c3052325593287710141a752fdc7c82 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 5 Nov 2020 20:02:40 -0800 Subject: [PATCH 19/36] 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 c4c996e5..24bc6c48 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 7890c9b83a507a510ba75ebb026f53d6566c01f5 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 5 Nov 2020 20:05:04 -0800 Subject: [PATCH 20/36] 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 24bc6c48..5f034c29 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 bb97e0805e2c6504bf3d28a2a96f5ebf9484d807 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 20:59:48 -0800 Subject: [PATCH 21/36] 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 0880065b..3a4260ec 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 00f4fa96..ccda7162 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 0c73459c..081a5fab 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 933ee4e9618cfd51dccf633080b2ac6cda8b2ca7 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 21:07:28 -0800 Subject: [PATCH 22/36] 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 3a4260ec..ae573a16 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 ccda7162..af576554 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 081a5fab..5d45da53 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 9f54ad4ea3d5137bbcaf0bdc387c58713ac6d032 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 21:09:07 -0800 Subject: [PATCH 23/36] 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 5d45da53..49ef6752 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 ab7ccbc5d58f7ea7506dedb0cf2f8e1106a2b242 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Sat, 27 Jun 2020 15:30:23 +0200 Subject: [PATCH 24/36] 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 af576554..2fae8416 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 3e31bc9e45e9f165616390412db210d24035351c Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 20 Oct 2020 16:08:34 -0700 Subject: [PATCH 25/36] 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 49ef6752..3869fdc7 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 a5db4ca572df07f5dc33a330a14342a958309e64 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 5 Nov 2020 21:04:25 -0800 Subject: [PATCH 26/36] PreThinkFrame and PostThinkFrame hooks Changes from 58dd578b094639405d452593562e0f8cb2b482ce, a36920808b74e068d582dda5a3b75bdf64246463, 41c902b819ac8fdef173c4ba76a8c50ad8107190, 60928db0e0b08fee7ceddd5515adf2246bb655c3. --- 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 6af3941f..bd2afebb 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 41a436e0..90a13c6f 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 4cc6c9ba..bf034447 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 5921d17cc044a430fc998bd88d1f056b48a426cd Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Sat, 14 Dec 2019 15:28:24 -0600 Subject: [PATCH 27/36] 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 bd2afebb..3f2dfd7a 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 90a13c6f..e9a4d0b4 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 cb6b7bd6..dc22bd94 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 a9e851bcf50f193bdc6379a0f4a01ad62ff2fc14 Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Sat, 28 Dec 2019 17:40:47 -0600 Subject: [PATCH 28/36] 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 dc22bd94..6f00e410 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 130a1ccc983d23b37e6ac01c2712546014c3b818 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 5 Nov 2020 22:18:41 -0800 Subject: [PATCH 29/36] :V --- src/p_user.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 6f00e410..8d553633 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 8ee560f21632882ae835cf18f26028c610dcd7a8 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sat, 7 Nov 2020 20:32:44 +0200 Subject: [PATCH 30/36] 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 d0027426..9b0691da 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 d6c497065e246fef85aab86f1d32b217caf5f305 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 7 Nov 2020 19:47:50 -0500 Subject: [PATCH 31/36] 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 56b1a5a5..c50f53df 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 260eb3ec..760e45c4 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 be69e026..ec4a4aa3 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 104208fc84b0f03f9f8b25a3068083cf1498e81d Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 7 Nov 2020 23:56:46 -0500 Subject: [PATCH 32/36] 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 c50f53df..73295a13 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 ec4a4aa3..5be618d8 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 c23364db1210c0ae5d37b8c23e8b943bcda1e33f Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 8 Nov 2020 00:45:16 -0500 Subject: [PATCH 33/36] 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 73295a13..c50f53df 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 7241be9c..3724144f 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 5be618d8..ec4a4aa3 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 5f3639de..a78cd57e 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 From 6533a728dba3552879c7961b036ad9d412ef4747 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 13 Nov 2020 17:30:23 -0800 Subject: [PATCH 34/36] Always unmute music on refocus If the game is paused, music will be resumed when unpause anyway. --- src/sdl/i_video.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 2858e9b6..ba0f7f1d 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -624,8 +624,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) // Tell game we got focus back, resume music if necessary window_notinfocus = false; - if (!paused) - S_InitMusicVolume(); + S_InitMusicVolume(); if (cv_gamesounds.value) S_EnableSound(); From 1a3e883b4ef657cbad3a61c9c44295176735f286 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 24 Nov 2020 19:32:01 -0800 Subject: [PATCH 35/36] Lua: "defrosting" global to tell how many tics are processing in the preticker --- src/dehacked.c | 3 +++ src/lua_hook.h | 1 + src/lua_script.c | 2 ++ src/p_tick.c | 8 ++++++-- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 39fc9414..d509cd49 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9687,6 +9687,9 @@ static inline int lib_getenum(lua_State *L) } else if (fastcmp(word,"leveltime")) { lua_pushinteger(L, leveltime); return 1; + } else if (fastcmp(word,"defrosting")) { + lua_pushinteger(L, hook_defrosting); + return 1; } else if (fastcmp(word,"curWeather")) { lua_pushinteger(L, curWeather); return 1; diff --git a/src/lua_hook.h b/src/lua_hook.h index 3f2dfd7a..a17a7ac7 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -63,6 +63,7 @@ enum hook { extern const char *const hookNames[]; extern boolean hook_cmd_running; // This is used by PlayerCmd and lua_playerlib to prevent anything from being wirtten to player while we run PlayerCmd. +extern int hook_defrosting; void LUAh_MapChange(INT16 mapnumber); // Hook for map change (before load) void LUAh_MapLoad(void); // Hook for map load diff --git a/src/lua_script.c b/src/lua_script.c index ee49efcc..5aff5380 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -35,6 +35,8 @@ lua_State *gL = NULL; +int hook_defrosting; + // List of internal libraries to load from SRB2 static lua_CFunction liblist[] = { LUA_EnumLib, // global metatable for enums diff --git a/src/p_tick.c b/src/p_tick.c index bf034447..6a85027f 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -807,13 +807,15 @@ void P_Ticker(boolean run) // Abbreviated ticker for pre-loading, calls thinkers and assorted things void P_PreTicker(INT32 frames) { - INT32 i,framecnt; + INT32 i; ticcmd_t temptic; for (i = 0; i <= splitscreen; i++) postimgtype[i] = postimg_none; - for (framecnt = 0; framecnt < frames; ++framecnt) + hook_defrosting = frames; + + while (hook_defrosting) { P_MapStart(); @@ -860,5 +862,7 @@ void P_PreTicker(INT32 frames) #endif P_MapEnd(); + + hook_defrosting--; } } From 1f5e9fd8029821e2f66a8559c513f6abbec76f24 Mon Sep 17 00:00:00 2001 From: himie Date: Tue, 14 Jul 2020 14:38:20 -0500 Subject: [PATCH 36/36] Add large address aware flag This allows the final exe to use more than 2gb of RAM in a 64-bit system which should get rid of most out of memory errors on 32-bit builds --- src/win32/Makefile.cfg | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/win32/Makefile.cfg b/src/win32/Makefile.cfg index e9e18280..6286a18b 100644 --- a/src/win32/Makefile.cfg +++ b/src/win32/Makefile.cfg @@ -164,3 +164,7 @@ else endif LIBS+=-ldiscord-rpc endif + +ifndef MINGW64 + LDFLAGS+=-Wl,--large-address-aware +endif