Compare commits

...
Author SHA1 Message Date
alufolie91 3204b5c3b4 Merge branch 'Saturn-Next' into netstuff 2026-02-23 17:02:32 +01:00
alufolie91 cd02242a01 fix splitscreen clients being unable to join saturn servers
lmao oops idk dumb copy paste sry
2026-02-23 17:02:13 +01:00
Alug 6cbb8a36cf Merge branch 'Saturn-Next' into netstuff 2026-01-21 20:48:47 +01:00
Gustaf Alhäll bf1aa47854 Simplify textcmd handling 2026-01-09 20:53:15 +01:00
Alug be423b2910 Merge branch 'Saturn-Next' into netstuff 2026-01-08 00:34:19 +01:00
Alug 3bf3bdf641 enable "Wzero-as-null-pointer-constant", fix cases of it
prevent ambiguity and bad practices, i like expressive and "correct" code
shoutout blankart for making me aware this exists
2026-01-08 00:34:15 +01:00
Alug e923777eb6 Acessability: add basic "reducevfx" toggle to disable/reduce certain effects
toggles certain effects, which may be troublesome to some players

-disabled hyudoro flashing, instead makes player translucent
- Makes rainbow colour effects, such as invul, change colours very slowly
- Disables underwater and heatwave screen effects
- Disables palette flashing
- Disables vhs effect

not the most pretty implementation, but im lazy and this works

feel free to suggest more things
2026-01-08 00:33:53 +01:00
Alug cf6eb0010e K_SpawnSparkleTrail: check for blend effect apply outside the loop
tiny optimization
2026-01-08 00:33:50 +01:00
Alug 5184115216 enable "Wzero-as-null-pointer-constant", fix cases of it
prevent ambiguity and bad practices, i like expressive and "correct" code
shoutout blankart for making me aware this exists
2026-01-08 00:33:43 +01:00
Alug 39a46e8f79 Revert "Remove tic provision (vanilla compat edition)"
This reverts commit 4a3c9ccfbb.
2025-12-30 01:09:14 +01:00
Alug d9712cf85e Merge branch 'Saturn-Next' into netstuff 2025-12-27 15:13:50 +01:00
Alug 0691e2d9e2 Merge branch 'Saturn-Next' into netstuff 2025-12-27 13:40:19 +01:00
PAS 08864e27b2 Fix double byte-swap in SV_MakeTic 2025-12-26 21:44:39 +01:00
Alug 4a3c9ccfbb Remove tic provision (vanilla compat edition)
based on https://codeberg.org/srb2classic/srb2classic/commit/7cf14fbe740998c3246dd190904f49a236b2ccec

seems to get rid of some jitter in localhost
2025-12-26 21:44:37 +01:00
Alug cedd789a27 Merge branch 'Saturn-Next' into netstuff 2025-12-26 21:44:34 +01:00
Alug 8f91707164 Merge branch 'Saturn-Next' into netstuff 2025-12-09 18:07:06 +01:00
Alug 37eba186f5 netcode: replace some stuff with memsets + add a little bounds safety in some places 2025-12-09 18:07:02 +01:00
Alug 7eb2ad1e35 slightly cleanup SV_AddWaitingPlayers 2025-12-02 23:23:41 +01:00
Alug f49e57a38c d_cliserv: Cleanup PT_ClientJoin
move refuse message handling into its own function
2025-12-02 23:23:38 +01:00
Alug 265f4a50ef readd check for node before SV_SendSaveGame
Apparently in some cases the server will connect to itself, in this case the server tries to send itself the savegame, leading to a crash in some cases. oops
2025-12-02 23:23:36 +01:00
Alug e83e2659a7 reorder packets again 2025-12-02 23:23:29 +01:00
Alug c680dd3222 fix some packet types not being correctly handled 2025-12-02 23:23:15 +01:00
Alug 96aaaf5261 merge SendNameAndColor & SendWeaponPref
TODO: make a bunch of player specific cvars arrays for splitscreen handling

- also cleanup some strlen usage
2025-12-02 23:23:07 +01:00
Alug efb29e6be5 d_cliserv: do some cleanups
- expose SAVEGAMESIZE
- pass node number to SV_AddWaitingPlayers (saves iterating through all 128 net nodes everytime a player joins) lifted from RR
- move all packet handling to the packet handlers
- Reorder packethandling switches a little, so common/important packets get checked first
- fix wrong clamp for realfirsttic that was too early
- add nowtime division by NEWTICRATERATIO (no change unless ticrate changes)
2025-12-02 23:23:02 +01:00
9 changed files with 523 additions and 839 deletions

No files matched your search

+343 -315
View File
File diff suppressed because it is too large. Load diff
+3 -1
View File
@@ -660,9 +660,11 @@ extern UINT8 hu_redownloadinggamestate;
#endif
extern boolean hu_stopped; // kart, true when the game is stopped for players due to a disconnecting or connecting player
#define SAVEGAMESIZE (768*1024)
typedef struct rewind_s
{
UINT8 savebuffer[(768*1024)];
UINT8 savebuffer[SAVEGAMESIZE];
tic_t leveltime;
size_t demopos;
+1 -5
View File
@@ -612,12 +612,8 @@ void Net_WaitAllAckReceived(UINT32 timeout)
static void InitNode(node_t *node)
{
node->acktosend_head = node->acktosend_tail = 0;
memset(node->acktosend, 0, sizeof(node->acktosend));
node->firstacktosend = 0;
memset(node, 0, sizeof(node_t));
node->nextacknum = 1;
node->remotefirstack = 0;
node->flags = 0;
}
static void InitAck(void)
+144 -482
View File
@@ -1208,11 +1208,11 @@ static boolean AllowedPlayerNameChar(char ch)
static boolean EnsurePlayerNameIsGood(char *name, INT32 playernum)
{
INT32 ix;
size_t ix, len = strlen(name);
if (strlen(name) == 0 || strlen(name) > MAXPLAYERNAME)
if (len == 0 || len > MAXPLAYERNAME)
return false; // Empty or too long.
if (name[0] == ' ' || name[strlen(name)-1] == ' ')
if (name[0] == ' ' || name[len-1] == ' ')
return false; // Starts or ends with a space.
if (isdigit(name[0]))
return false; // Starts with a digit.
@@ -1226,20 +1226,19 @@ static boolean EnsurePlayerNameIsGood(char *name, INT32 playernum)
// Also, anything over 0x80 is disallowed too, since compilers love to
// differ on whether they're printable characters or not.
for (ix = 0; name[ix] != '\0'; ix++)
for (ix = 0; ix < len; ix++)
if (!AllowedPlayerNameChar(name[ix]))
return false;
// Check if a player is currently using the name, case-insensitively.
for (ix = 0; ix < MAXPLAYERS; ix++)
{
if (ix != playernum && playeringame[ix]
if (ix != (size_t)playernum && playeringame[ix]
&& fasticmp(name, player_names[ix]))
{
// We shouldn't kick people out just because
// they joined the game with the same name
// as someone else -- modify the name instead.
size_t len = strlen(name);
// Recursion!
// Slowly strip characters off the end of the
@@ -1458,7 +1457,9 @@ UINT8 CanChangeSkin(INT32 playernum)
return true;
}
if (players[playernum].spectator || players[playernum].playerstate == PST_DEAD || players[playernum].playerstate == PST_REBORN)
if (players[playernum].spectator ||
players[playernum].playerstate == PST_DEAD ||
players[playernum].playerstate == PST_REBORN)
return true;
return false;
@@ -1492,445 +1493,144 @@ static void ForceAllSkins(INT32 forcedskin)
}
}
static INT32 snacpending = 0, snac2pending = 0, snac3pending = 0, snac4pending = 0, chmappending = 0;
static INT32 chmappending;
static INT32 snacpending[MAXSPLITSCREENPLAYERS];
// wonky compat, idk if anything uses this....
#define playerisbot (splitplayer == 1 && botingame)
// name, color, or skin has changed
//
static void SendNameAndColor(void)
static void SendNameAndColor(UINT8 splitplayer)
{
char buf[MAXPLAYERNAME+2];
char *p;
p = buf;
// splitscreen
if (splitscreen < splitplayer && !playerisbot)
return;
const INT32 pnum = P_GetLocalPlayerNumForNum(splitplayer);
player_t *player = &players[pnum];
// TODO: make those cvars arrays
consvar_t *playercolor, *playername, *playerskin;
consvar_t *colorvars[] = {&cv_playercolor, &cv_playercolor2, &cv_playercolor3, &cv_playercolor4};
consvar_t *namevars[] = {&cv_playername, &cv_playername2, &cv_playername3, &cv_playername4};
consvar_t *skinvars[] = {&cv_skin, &cv_skin2, &cv_skin3, &cv_skin4};
playercolor = colorvars[splitplayer];
playername = namevars[splitplayer];
playerskin = skinvars[splitplayer];
// normal player colors
if (G_GametypeHasTeams())
{
if (players[consoleplayer].ctfteam == 1 && cv_playercolor.value != skincolor_redteam)
CV_StealthSetValue(&cv_playercolor, skincolor_redteam);
else if (players[consoleplayer].ctfteam == 2 && cv_playercolor.value != skincolor_blueteam)
CV_StealthSetValue(&cv_playercolor, skincolor_blueteam);
if (player->ctfteam == 1 && playercolor->value != skincolor_redteam)
CV_StealthSetValue(playercolor, skincolor_redteam);
else if (player->ctfteam == 2 && playercolor->value != skincolor_blueteam)
CV_StealthSetValue(playercolor, skincolor_blueteam);
}
// never allow the color "none"
if (!cv_playercolor.value)
if (!playercolor->value)
{
if (players[consoleplayer].skincolor)
CV_StealthSetValue(&cv_playercolor, players[consoleplayer].skincolor);
else if (skins[players[consoleplayer].skin].prefcolor)
CV_StealthSetValue(&cv_playercolor, skins[players[consoleplayer].skin].prefcolor);
if (player->skincolor)
CV_StealthSetValue(playercolor, player->skincolor);
else if (skins[player->skin].prefcolor)
CV_StealthSetValue(playercolor, skins[player->skin].prefcolor);
else
CV_StealthSet(&cv_playercolor, cv_playercolor.defaultvalue);
CV_StealthSet(playercolor, playercolor->defaultvalue);
}
if (fastcmp(cv_playername.string, player_names[consoleplayer])
&& cv_playercolor.value == players[consoleplayer].skincolor
&& fastcmp(cv_skin.string, skins[players[consoleplayer].skin].name))
return;
// We'll handle it later if we're not playing.
if (!Playing())
return;
if (fastcmp(playername->string, player_names[pnum])
&& playercolor->value == player->skincolor
&& fastcmp(playerskin->string, skins[player->skin].name))
return;
if (playerisbot)
{
players[pnum].skincolor = botcolor;
if (players[pnum].mo)
players[pnum].mo->color = players[pnum].skincolor;
SetPlayerSkinByNum(pnum, botskin-1);
return;
}
// If you're not in a netgame, merely update the skin, color, and name.
if (!netgame)
{
INT32 foundskin;
CleanupPlayerName(consoleplayer, cv_playername.zstring);
strcpy(player_names[consoleplayer], cv_playername.zstring);
CleanupPlayerName(pnum, playername->zstring);
strcpy(player_names[pnum], playername->zstring);
players[consoleplayer].skincolor = cv_playercolor.value;
player->skincolor = playercolor->value;
if (players[consoleplayer].mo)
players[consoleplayer].mo->color = players[consoleplayer].skincolor;
if (player->mo)
player->mo->color = player->skincolor;
if ((foundskin = R_SkinAvailable(cv_skin.string)) != -1)
if ((foundskin = R_SkinAvailable(playerskin->string)) != -1)
{
cv_skin.value = foundskin;
SetPlayerSkin(consoleplayer, cv_skin.string);
CV_StealthSet(&cv_skin, skins[cv_skin.value].name);
playerskin->value = foundskin;
SetPlayerSkin(pnum, playerskin->string);
CV_StealthSet(playerskin, skins[playerskin->value].name);
}
else
{
cv_skin.value = players[consoleplayer].skin;
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
playerskin->value = player->skin;
CV_StealthSet(playerskin, skins[player->skin].name);
// will always be same as current
SetPlayerSkin(consoleplayer, cv_skin.string);
SetPlayerSkin(pnum, playerskin->string);
}
return;
}
snacpending++;
snacpending[splitplayer]++;
// Don't change name if muted
if (player_name_changes[consoleplayer] >= MAXNAMECHANGES)
if (player_name_changes[pnum] >= MAXNAMECHANGES)
{
CV_StealthSet(&cv_playername, player_names[consoleplayer]);
CV_StealthSet(playername, player_names[pnum]);
HU_AddChatText("\x85*You must wait to change your name again", false);
}
else if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer)))
CV_StealthSet(&cv_playername, player_names[consoleplayer]);
else if (cv_mute.value && !(server || IsPlayerAdmin(pnum)))
CV_StealthSet(playername, player_names[pnum]);
else // Cleanup name if changing it
CleanupPlayerName(consoleplayer, cv_playername.zstring);
CleanupPlayerName(pnum, playername->zstring);
// Don't change skin if the server doesn't want you to.
if (!CanChangeSkin(consoleplayer))
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
if (!CanChangeSkin(pnum))
CV_StealthSet(playerskin, skins[player->skin].name);
// check if player has the skin loaded (cv_skin may have
// the name of a skin that was available in the previous game)
cv_skin.value = R_SkinAvailable(cv_skin.string);
if (cv_skin.value < 0)
playerskin->value = R_SkinAvailable(playerskin->string);
if (playerskin->value < 0)
{
INT32 skinnum = players[consoleplayer].skin;
CV_StealthSet(&cv_skin, skins[skinnum].name);
cv_skin.value = skinnum;
INT32 skinnum = player->skin;
CV_StealthSet(playerskin, skins[skinnum].name);
playerskin->value = skinnum;
}
// Finally write out the complete packet and send it off.
WRITESTRINGN(p, cv_playername.zstring, MAXPLAYERNAME);
WRITEUINT8(p, (UINT8)cv_playercolor.value);
WRITEUINT8(p, (UINT8)cv_skin.value);
SendNetXCmdForPlayer(0, XD_NAMEANDCOLOR, buf, p - buf);
}
// splitscreen
static void SendNameAndColor2(void)
{
INT32 secondplaya = -1;
char buf[MAXPLAYERNAME+2];
char *p;
if (splitscreen < 1 && !botingame)
return; // can happen if skin2/color2/name2 changed
if (displayplayers[1] != consoleplayer)
secondplaya = displayplayers[1];
else if (!netgame) // HACK
secondplaya = 1;
if (secondplaya == -1)
return;
p = buf;
// normal player colors
if (G_GametypeHasTeams())
{
if (players[secondplaya].ctfteam == 1 && cv_playercolor2.value != skincolor_redteam)
CV_StealthSetValue(&cv_playercolor2, skincolor_redteam);
else if (players[secondplaya].ctfteam == 2 && cv_playercolor2.value != skincolor_blueteam)
CV_StealthSetValue(&cv_playercolor2, skincolor_blueteam);
}
// never allow the color "none"
if (!cv_playercolor2.value)
{
if (players[secondplaya].skincolor)
CV_StealthSetValue(&cv_playercolor2, players[secondplaya].skincolor);
else if (skins[players[secondplaya].skin].prefcolor)
CV_StealthSetValue(&cv_playercolor2, skins[players[secondplaya].skin].prefcolor);
else
CV_StealthSet(&cv_playercolor2, cv_playercolor2.defaultvalue);
}
// We'll handle it later if we're not playing.
if (!Playing())
return;
// If you're not in a netgame, merely update the skin, color, and name.
if (botingame)
{
players[secondplaya].skincolor = botcolor;
if (players[secondplaya].mo)
players[secondplaya].mo->color = players[secondplaya].skincolor;
SetPlayerSkinByNum(secondplaya, botskin-1);
return;
}
else if (!netgame)
{
INT32 foundskin;
CleanupPlayerName(secondplaya, cv_playername2.zstring);
strcpy(player_names[secondplaya], cv_playername2.zstring);
// don't use displayplayers[1]: the second player must be 1
players[secondplaya].skincolor = cv_playercolor2.value;
if (players[secondplaya].mo)
players[secondplaya].mo->color = players[secondplaya].skincolor;
if ((foundskin = R_SkinAvailable(cv_skin2.string)) != -1)
{
cv_skin2.value = foundskin;
SetPlayerSkin(secondplaya, cv_skin2.string);
}
else
{
cv_skin2.value = players[secondplaya].skin;
CV_StealthSet(&cv_skin2, skins[players[secondplaya].skin].name);
// will always be same as current
SetPlayerSkin(secondplaya, cv_skin2.string);
}
return;
}
snac2pending++;
// Don't change name if muted
if (player_name_changes[displayplayers[1]] >= MAXNAMECHANGES)
{
CV_StealthSet(&cv_playername2, player_names[displayplayers[1]]);
HU_AddChatText("\x85*You must wait to change your name again", false);
}
else if (cv_mute.value && !(server || IsPlayerAdmin(displayplayers[1])))
CV_StealthSet(&cv_playername2, player_names[displayplayers[1]]);
else // Cleanup name if changing it
CleanupPlayerName(displayplayers[1], cv_playername2.zstring);
// Don't change skin if the server doesn't want you to.
if (!CanChangeSkin(displayplayers[1]))
CV_StealthSet(&cv_skin2, skins[players[displayplayers[1]].skin].name);
// check if player has the skin loaded (cv_skin2 may have
// the name of a skin that was available in the previous game)
cv_skin2.value = R_SkinAvailable(cv_skin2.string);
if (cv_skin2.value < 0)
{
INT32 skinnum = players[displayplayers[1]].skin;
CV_StealthSet(&cv_skin2, skins[skinnum].name);
cv_skin2.value = skinnum;
}
// Finally write out the complete packet and send it off.
WRITESTRINGN(p, cv_playername2.zstring, MAXPLAYERNAME);
WRITEUINT8(p, (UINT8)cv_playercolor2.value);
WRITEUINT8(p, (UINT8)cv_skin2.value);
SendNetXCmdForPlayer(1, XD_NAMEANDCOLOR, buf, p - buf);
}
static void SendNameAndColor3(void)
{
INT32 thirdplaya = -1;
char buf[MAXPLAYERNAME+2];
char *p;
if (splitscreen < 2)
return; // can happen if skin3/color3/name3 changed
if (displayplayers[2] != consoleplayer)
thirdplaya = displayplayers[2];
else if (!netgame) // HACK
thirdplaya = 2;
if (thirdplaya == -1)
return;
p = buf;
// normal player colors
if (G_GametypeHasTeams())
{
if (players[thirdplaya].ctfteam == 1 && cv_playercolor3.value != skincolor_redteam)
CV_StealthSetValue(&cv_playercolor3, skincolor_redteam);
else if (players[thirdplaya].ctfteam == 2 && cv_playercolor3.value != skincolor_blueteam)
CV_StealthSetValue(&cv_playercolor3, skincolor_blueteam);
}
// never allow the color "none"
if (!cv_playercolor3.value)
{
if (players[thirdplaya].skincolor)
CV_StealthSetValue(&cv_playercolor3, players[thirdplaya].skincolor);
else if (skins[players[thirdplaya].skin].prefcolor)
CV_StealthSetValue(&cv_playercolor3, skins[players[thirdplaya].skin].prefcolor);
else
CV_StealthSet(&cv_playercolor3, cv_playercolor3.defaultvalue);
}
// We'll handle it later if we're not playing.
if (!Playing())
return;
// If you're not in a netgame, merely update the skin, color, and name.
if (!netgame)
{
INT32 foundskin;
CleanupPlayerName(thirdplaya, cv_playername3.zstring);
strcpy(player_names[thirdplaya], cv_playername3.zstring);
// don't use displayplayers[2]: the third player must be 2
players[thirdplaya].skincolor = cv_playercolor3.value;
if (players[thirdplaya].mo)
players[thirdplaya].mo->color = players[thirdplaya].skincolor;
if ((foundskin = R_SkinAvailable(cv_skin3.string)) != -1)
{
cv_skin3.value = foundskin;
SetPlayerSkin(thirdplaya, cv_skin3.string);
}
else
{
cv_skin3.value = players[thirdplaya].skin;
CV_StealthSet(&cv_skin3, skins[players[thirdplaya].skin].name);
// will always be same as current
SetPlayerSkin(thirdplaya, cv_skin3.string);
}
return;
}
snac3pending++;
// Don't change name if muted
if (player_name_changes[displayplayers[2]] >= MAXNAMECHANGES)
{
CV_StealthSet(&cv_playername3, player_names[displayplayers[2]]);
HU_AddChatText("\x85*You must wait to change your name again", false);
}
else if (cv_mute.value && !(server || IsPlayerAdmin(displayplayers[2])))
CV_StealthSet(&cv_playername3, player_names[displayplayers[2]]);
else // Cleanup name if changing it
CleanupPlayerName(displayplayers[2], cv_playername3.zstring);
// Don't change skin if the server doesn't want you to.
if (!CanChangeSkin(displayplayers[2]))
CV_StealthSet(&cv_skin3, skins[players[displayplayers[2]].skin].name);
// check if player has the skin loaded (cv_skin3 may have
// the name of a skin that was available in the previous game)
cv_skin3.value = R_SkinAvailable(cv_skin3.string);
if (cv_skin3.value < 0)
{
INT32 skinnum = players[displayplayers[2]].skin;
CV_StealthSet(&cv_skin3, skins[skinnum].name);
cv_skin3.value = skinnum;
}
// Finally write out the complete packet and send it off.
WRITESTRINGN(p, cv_playername3.zstring, MAXPLAYERNAME);
WRITEUINT8(p, (UINT8)cv_playercolor3.value);
WRITEUINT8(p, (UINT8)cv_skin3.value);
SendNetXCmdForPlayer(2, XD_NAMEANDCOLOR, buf, p - buf);
}
static void SendNameAndColor4(void)
{
INT32 fourthplaya = -1;
char buf[MAXPLAYERNAME+2];
char *p;
if (splitscreen < 3)
return; // can happen if skin4/color4/name4 changed
if (displayplayers[3] != consoleplayer)
fourthplaya = displayplayers[3];
else if (!netgame) // HACK
fourthplaya = 3;
if (fourthplaya == -1)
return;
p = buf;
// normal player colors
if (G_GametypeHasTeams())
{
if (players[fourthplaya].ctfteam == 1 && cv_playercolor4.value != skincolor_redteam)
CV_StealthSetValue(&cv_playercolor4, skincolor_redteam);
else if (players[fourthplaya].ctfteam == 2 && cv_playercolor4.value != skincolor_blueteam)
CV_StealthSetValue(&cv_playercolor4, skincolor_blueteam);
}
// never allow the color "none"
if (!cv_playercolor4.value)
{
if (players[fourthplaya].skincolor)
CV_StealthSetValue(&cv_playercolor4, players[fourthplaya].skincolor);
else if (skins[players[fourthplaya].skin].prefcolor)
CV_StealthSetValue(&cv_playercolor4, skins[players[fourthplaya].skin].prefcolor);
else
CV_StealthSet(&cv_playercolor4, cv_playercolor4.defaultvalue);
}
// We'll handle it later if we're not playing.
if (!Playing())
return;
// If you're not in a netgame, merely update the skin, color, and name.
if (botingame)
{
players[fourthplaya].skincolor = botcolor;
if (players[fourthplaya].mo)
players[fourthplaya].mo->color = players[fourthplaya].skincolor;
SetPlayerSkinByNum(fourthplaya, botskin-1);
return;
}
else if (!netgame)
{
INT32 foundskin;
CleanupPlayerName(fourthplaya, cv_playername4.zstring);
strcpy(player_names[fourthplaya], cv_playername4.zstring);
// don't use displayplayers[3]: the second player must be 4
players[fourthplaya].skincolor = cv_playercolor4.value;
if (players[fourthplaya].mo)
players[fourthplaya].mo->color = players[fourthplaya].skincolor;
if ((foundskin = R_SkinAvailable(cv_skin4.string)) != -1)
{
cv_skin4.value = foundskin;
SetPlayerSkin(fourthplaya, cv_skin4.string);
}
else
{
cv_skin4.value = players[fourthplaya].skin;
CV_StealthSet(&cv_skin4, skins[players[fourthplaya].skin].name);
// will always be same as current
SetPlayerSkin(fourthplaya, cv_skin4.string);
}
return;
}
snac4pending++;
// Don't change name if muted
if (player_name_changes[displayplayers[3]] >= MAXNAMECHANGES)
{
CV_StealthSet(&cv_playername4, player_names[displayplayers[3]]);
HU_AddChatText("\x85*You must wait to change your name again", false);
}
else if (cv_mute.value && !(server || IsPlayerAdmin(displayplayers[3])))
CV_StealthSet(&cv_playername4, player_names[displayplayers[3]]);
else // Cleanup name if changing it
CleanupPlayerName(displayplayers[3], cv_playername4.zstring);
// Don't change skin if the server doesn't want you to.
if (!CanChangeSkin(displayplayers[3]))
CV_StealthSet(&cv_skin4, skins[players[displayplayers[3]].skin].name);
// check if player has the skin loaded (cv_skin4 may have
// the name of a skin that was available in the previous game)
cv_skin4.value = R_SkinAvailable(cv_skin4.string);
if (cv_skin4.value < 0)
{
INT32 skinnum = players[displayplayers[3]].skin;
CV_StealthSet(&cv_skin4, skins[skinnum].name);
cv_skin4.value = skinnum;
}
// Finally write out the complete packet and send it off.
WRITESTRINGN(p, cv_playername4.zstring, MAXPLAYERNAME);
WRITEUINT8(p, (UINT8)cv_playercolor4.value);
WRITEUINT8(p, (UINT8)cv_skin4.value);
SendNetXCmdForPlayer(3, XD_NAMEANDCOLOR, buf, p - buf);
WRITESTRINGN(p, playername->zstring, MAXPLAYERNAME);
WRITEUINT8(p, (UINT8)playercolor->value);
WRITEUINT8(p, (UINT8)playerskin->value);
SendNetXCmdForPlayer(splitplayer, XD_NAMEANDCOLOR, buf, p - buf);
}
static void Got_NameAndColor(const UINT8 **cp, INT32 playernum)
{
player_t *p = &players[playernum];
player_t *player = &players[playernum];
char name[MAXPLAYERNAME+1];
UINT8 color, skin;
@@ -1939,19 +1639,14 @@ static void Got_NameAndColor(const UINT8 **cp, INT32 playernum)
I_Error("There is no player %d!", playernum);
#endif
if (playernum == consoleplayer)
snacpending--; // TODO: make snacpending an array instead of 4 separate vars?
else if (playernum == displayplayers[1])
snac2pending--;
else if (playernum == displayplayers[2])
snac3pending--;
else if (playernum == displayplayers[3])
snac4pending--;
if (P_IsLocalPlayer(player))
{
snacpending[playernum]--;
#ifdef PARANOIA
if (snacpending < 0 || snac2pending < 0 || snac3pending < 0 || snac4pending < 0)
I_Error("snacpending negative!");
if (snacpending[playernum] < 0)
I_Error("snacpending negative!");
#endif
}
READSTRINGN(*cp, name, MAXPLAYERNAME);
color = READUINT8(*cp);
@@ -1965,33 +1660,32 @@ static void Got_NameAndColor(const UINT8 **cp, INT32 playernum)
}
// set color
p->skincolor = color % MAXSKINCOLORS;
if (p->mo)
p->mo->color = (UINT8)p->skincolor;
player->skincolor = color % MAXSKINCOLORS;
if (player->mo)
player->mo->color = (UINT8)player->skincolor;
demo_extradata[playernum] |= DXD_COLOR;
// normal player colors
if (server && (p != &players[consoleplayer] && p != &players[displayplayers[1]]
&& p != &players[displayplayers[2]] && p != &players[displayplayers[3]]))
if (server && !P_IsLocalPlayer(player))
{
boolean kick = false;
// team colors
if (G_GametypeHasTeams())
{
if (p->ctfteam == 1 && p->skincolor != skincolor_redteam)
if (player->ctfteam == 1 && player->skincolor != skincolor_redteam)
kick = true;
else if (p->ctfteam == 2 && p->skincolor != skincolor_blueteam)
else if (player->ctfteam == 2 && player->skincolor != skincolor_blueteam)
kick = true;
}
// don't allow color "none"
if (!p->skincolor)
if (!player->skincolor)
kick = true;
if (kick)
{
CONS_Alert(CONS_WARNING, M_GetText("Illegal color change received from %s (team: %d), color: %d)\n"), player_names[playernum], p->ctfteam, p->skincolor);
CONS_Alert(CONS_WARNING, M_GetText("Illegal color change received from %s (team: %d), color: %d)\n"), player_names[playernum], player->ctfteam, player->skincolor);
SendKick(playernum, KICK_MSG_CON_FAIL);
return;
}
@@ -2003,6 +1697,7 @@ static void Got_NameAndColor(const UINT8 **cp, INT32 playernum)
const INT32 forcedskin = cv_forceskin.value;
SetPlayerSkinByNum(playernum, forcedskin);
// TODO: make cv_skin an array
if (playernum == consoleplayer)
CV_StealthSet(&cv_skin, skins[forcedskin].name);
else if (playernum == displayplayers[1])
@@ -2016,44 +1711,16 @@ static void Got_NameAndColor(const UINT8 **cp, INT32 playernum)
SetPlayerSkinByNum(playernum, skin);
}
void SendWeaponPref(void)
void SendWeaponPref(UINT8 splitplayer)
{
UINT8 buf[1];
buf[0] = 0;
if (cv_flipcam[0].value)
if (cv_flipcam[splitplayer].value)
buf[0] |= 1;
SendNetXCmdForPlayer(0, XD_WEAPONPREF, buf, 1);
}
void SendWeaponPref2(void)
{
UINT8 buf[1];
buf[0] = 0;
if (cv_flipcam[1].value)
buf[0] |= 1;
SendNetXCmdForPlayer(1, XD_WEAPONPREF, buf, 1);
}
void SendWeaponPref3(void)
{
UINT8 buf[1];
buf[0] = 0;
if (cv_flipcam[2].value)
buf[0] |= 1;
SendNetXCmdForPlayer(2, XD_WEAPONPREF, buf, 1);
}
void SendWeaponPref4(void)
{
UINT8 buf[1];
buf[0] = 0;
if (cv_flipcam[3].value)
buf[0] |= 1;
SendNetXCmdForPlayer(3, XD_WEAPONPREF, buf, 1);
SendNetXCmdForPlayer(splitplayer, XD_WEAPONPREF, buf, 1);
}
static void Got_WeaponPref(const UINT8 **cp, INT32 playernum)
@@ -2069,23 +1736,10 @@ static void Got_WeaponPref(const UINT8 **cp, INT32 playernum)
player->pflags |= PF_ANALOGMODE;
}
void D_SendPlayerConfig(void)
void D_SendPlayerConfig(UINT8 splitplayer)
{
SendNameAndColor();
if (splitscreen || botingame)
SendNameAndColor2();
if (splitscreen > 1)
SendNameAndColor3();
if (splitscreen > 2)
SendNameAndColor4();
SendWeaponPref();
if (splitscreen)
SendWeaponPref2();
if (splitscreen > 1)
SendWeaponPref3();
if (splitscreen > 2)
SendWeaponPref4();
SendNameAndColor(splitplayer);
SendWeaponPref(splitplayer);
}
// Only works for displayplayer, sorry!
@@ -2108,10 +1762,12 @@ INT32 D_LookupPlayer(const char *s)
return playernum;
}
const size_t len = strlen(s);
for (playernum = 0; playernum < MAXPLAYERS; ++playernum)
{
/* Match name case-insensitively: fully, or partially the start. */
if (playeringame[playernum] && (strnicmp(player_names[playernum], s, strlen(s)) == 0))
if (playeringame[playernum] && (strnicmp(player_names[playernum], s, len) == 0))
{
return playernum;
}
@@ -2151,13 +1807,15 @@ static void GetViewablePlayerPlaceRange(INT32 *first, INT32 *last)
(*last) = 0;
for (i = 0; i < MAXPLAYERS; ++i)
if (G_CouldView(i))
{
place = players[i].kartstuff[k_position];
if (place < (*first))
(*first) = place;
if (place > (*last))
(*last) = place;
if (G_CouldView(i))
{
place = players[i].kartstuff[k_position];
if (place < (*first))
(*first) = place;
if (place > (*last))
(*last) = place;
}
}
}
@@ -2491,7 +2149,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pencoremode, boolean r
displayplayers[1] = 1;
playeringame[1] = true;
players[1].bot = 1;
SendNameAndColor2();
SendNameAndColor(1);
}
}
@@ -5768,50 +5426,54 @@ static void ForceSkin_OnChange(void)
}
}
//Allows the player's name to be changed if cv_mute is off.
// Allows the player's name to be changed if cv_mute is off.
static void Name_OnChange(void)
{
if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer)))
{
CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n"));
CV_StealthSet(&cv_playername, player_names[consoleplayer]);
return;
}
else
SendNameAndColor();
SendNameAndColor(0);
}
static void Name2_OnChange(void)
{
if (cv_mute.value) //Secondary player can't be admin.
if (cv_mute.value) // Secondary player can't be admin.
{
CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n"));
CV_StealthSet(&cv_playername2, player_names[displayplayers[1]]);
return;
}
else
SendNameAndColor2();
SendNameAndColor(1);
}
static void Name3_OnChange(void)
{
if (cv_mute.value) //Third player can't be admin.
if (cv_mute.value) // Third player can't be admin.
{
CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n"));
CV_StealthSet(&cv_playername3, player_names[displayplayers[2]]);
return;
}
else
SendNameAndColor3();
SendNameAndColor(2);
}
static void Name4_OnChange(void)
{
if (cv_mute.value) //Secondary player can't be admin.
if (cv_mute.value) // Secondary player can't be admin.
{
CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n"));
CV_StealthSet(&cv_playername4, player_names[displayplayers[3]]);
return;
}
else
SendNameAndColor4();
SendNameAndColor(3);
}
/** Sends a skin change for the console player, unless that player is moving.
@@ -5833,7 +5495,7 @@ static void Skin_OnChange(void)
}
if (CanChangeSkin(consoleplayer) && !P_PlayerMoving(consoleplayer))
SendNameAndColor();
SendNameAndColor(0);
else
{
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
@@ -5854,7 +5516,7 @@ static void Skin2_OnChange(void)
return; // do whatever you want
if (CanChangeSkin(displayplayers[1]) && !P_PlayerMoving(displayplayers[1]))
SendNameAndColor2();
SendNameAndColor(1);
else
{
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
@@ -5870,7 +5532,7 @@ static void Skin3_OnChange(void)
return; // do whatever you want
if (CanChangeSkin(displayplayers[2]) && !P_PlayerMoving(displayplayers[2]))
SendNameAndColor3();
SendNameAndColor(2);
else
{
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
@@ -5886,7 +5548,7 @@ static void Skin4_OnChange(void)
return; // do whatever you want
if (CanChangeSkin(displayplayers[3]) && !P_PlayerMoving(displayplayers[3]))
SendNameAndColor4();
SendNameAndColor(3);
else
{
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
@@ -5999,7 +5661,7 @@ static void Color_OnChange(void)
if (!P_PlayerMoving(consoleplayer))
{
// Color change menu scrolling fix is no longer necessary
SendNameAndColor();
SendNameAndColor(0);
}
else
{
@@ -6021,7 +5683,7 @@ static void Color2_OnChange(void)
if (!P_PlayerMoving(displayplayers[1]))
{
// Color change menu scrolling fix is no longer necessary
SendNameAndColor2();
SendNameAndColor(1);
}
else
{
@@ -6038,7 +5700,7 @@ static void Color3_OnChange(void)
if (!P_PlayerMoving(displayplayers[2]))
{
// Color change menu scrolling fix is no longer necessary
SendNameAndColor3();
SendNameAndColor(2);
}
else
{
@@ -6055,7 +5717,7 @@ static void Color4_OnChange(void)
if (!P_PlayerMoving(displayplayers[3]))
{
// Color change menu scrolling fix is no longer necessary
SendNameAndColor4();
SendNameAndColor(3);
}
else
{
+2 -5
View File
@@ -21,10 +21,7 @@ extern "C" {
#include "command.h"
void SendWeaponPref(void);
void SendWeaponPref2(void);
void SendWeaponPref3(void);
void SendWeaponPref4(void);
void SendWeaponPref(UINT8 splitplayer);
// console vars
extern consvar_t cv_playername;
@@ -295,7 +292,7 @@ typedef union {
// add game commands, needs cleanup
void D_RegisterServerCommands(void);
void D_RegisterClientCommands(void);
void D_SendPlayerConfig(void);
void D_SendPlayerConfig(UINT8 splitplayer);
void Command_ExitGame_f(void);
void Command_Retry_f(void);
void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore
+16 -16
View File
@@ -960,7 +960,7 @@ void Got_Filetxpak(void)
|| fastcmp(filename, "music.kart")
|| fastcmp(filename, "patch.kart")
))
I_Error("Tried to download \"%s\"", filename);
I_Error("Tried to download base-game file: \"%s\"", filename);
if (filenum >= fileneedednum)
{
@@ -1019,21 +1019,21 @@ void Got_Filetxpak(void)
switch(file->status)
{
case FS_NOTFOUND:
s = "FS_NOTFOUND";
break;
case FS_FOUND:
s = "FS_FOUND";
break;
case FS_OPEN:
s = "FS_OPEN";
break;
case FS_MD5SUMBAD:
s = "FS_MD5SUMBAD";
break;
default:
s = "unknown";
break;
case FS_NOTFOUND:
s = "FS_NOTFOUND";
break;
case FS_FOUND:
s = "FS_FOUND";
break;
case FS_OPEN:
s = "FS_OPEN";
break;
case FS_MD5SUMBAD:
s = "FS_MD5SUMBAD";
break;
default:
s = "unknown";
break;
}
I_Error("Received a file not requested (file id: %d, file status: %s)\n", filenum, s);
+1 -4
View File
@@ -69,9 +69,6 @@ UINT8 botcolor = 0;
JoyType_t Joystick[MAXSPLITSCREENPLAYERS] = {};
// 1024 bytes is plenty for a savegame
#define SAVEGAMESIZE (1024)
// SRB2kart
char gamedatafilename[64] = "kartdata.dat";
char timeattackfolder[64] = "kart";
@@ -3902,7 +3899,7 @@ void G_SaveGame(UINT32 savegameslot)
char name[VERSIONSIZE];
size_t length;
save.p = save.buffer = (UINT8 *)Z_Malloc(SAVEGAMESIZE, PU_STATIC, NULL);
save.p = save.buffer = (UINT8 *)Z_Malloc(1024, PU_STATIC, NULL); // 1024 bytes is plenty for a savegame
if (!save.p)
{
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for saving game data\n"));
+9 -7
View File
@@ -496,8 +496,10 @@ static void cleanupnodes(void)
// Why can't I start at zero?
for (j = 1; j < MAXNETNODES; j++)
{
if (!(nodeingame[j] || SV_SendingFile(j)))
nodeconnected[j] = false;
}
}
static SINT8 getfreenode(void)
@@ -507,11 +509,13 @@ static SINT8 getfreenode(void)
cleanupnodes();
for (j = 0; j < MAXNETNODES; j++)
{
if (!nodeconnected[j])
{
nodeconnected[j] = true;
return j;
}
}
/** \warning No free node? Just in case a node might not have been freed properly,
* look if there are connected nodes that aren't in game, and forget them.
@@ -812,7 +816,7 @@ static void SOCK_Send(void)
static void SOCK_FreeNodenum(INT32 numnode)
{
// can't disconnect from self :)
if (!numnode || numnode > MAXNETNODES)
if (numnode <= 0 || numnode > MAXNETNODES)
return;
DEBFILE(va("Free node %d (%s)\n", numnode, SOCK_GetNodeAddress(numnode)));
@@ -1432,14 +1436,12 @@ static void SOCK_RegisterHolePunch(void)
static boolean SOCK_OpenSocket(void)
{
size_t i;
memset(clientaddress, 0, sizeof (clientaddress));
memset(clientaddress, 0, sizeof(clientaddress));
memset(nodeconnected, false, sizeof(nodeconnected));
nodeconnected[0] = true; // always connected to self
for (i = 1; i < MAXNETNODES; i++)
nodeconnected[i] = false;
nodeconnected[BROADCASTADDR] = true;
I_NetSend = SOCK_Send;
I_NetGet = SOCK_Get;
I_NetCloseSocket = SOCK_CloseSocket;
@@ -1479,7 +1481,7 @@ static boolean SOCK_Ban(INT32 node)
{
INT32 ban;
if (node > MAXNETNODES)
if (node < 0 || node > MAXNETNODES)
return false;
ban = numbans;
+4 -4
View File
@@ -280,22 +280,22 @@ static void Fov_OnChange(void)
static void FlipCam_OnChange(void)
{
SendWeaponPref();
SendWeaponPref(0);
}
static void FlipCam2_OnChange(void)
{
SendWeaponPref2();
SendWeaponPref(1);
}
static void FlipCam3_OnChange(void)
{
SendWeaponPref3();
SendWeaponPref(2);
}
static void FlipCam4_OnChange(void)
{
SendWeaponPref4();
SendWeaponPref(3);
}
static void Precipstuff_OnChange(void)