Send skin+color all the way thru clientcfg

This commit is contained in:
Sally Coolatta 2025-09-13 00:57:51 -04:00
parent c743a156b1
commit 6a3ee467a8
5 changed files with 130 additions and 77 deletions

View file

@ -964,12 +964,32 @@ static boolean CL_SendJoin(void)
for (i = 0; i <= splitscreen; i++) for (i = 0; i <= splitscreen; i++)
{ {
// the MAXPLAYERS addition is necessary to communicate that g_localplayers is not yet safe to reference // the MAXPLAYERS addition is necessary to communicate that g_localplayers is not yet safe to reference
player_config_t temp;
CleanupPlayerName(MAXPLAYERS+i, cv_playername[i].zstring); CleanupPlayerName(MAXPLAYERS+i, cv_playername[i].zstring);
strncpy(netbuffer->u.clientcfg.names[i], cv_playername[i].zstring, MAXPLAYERNAME);
strncpy(temp.name, cv_playername[i].zstring, MAXPLAYERNAME);
D_FillPlayerSkinAndColor(i, NULL, &temp);
D_FillPlayerWeaponPref(i, &temp);
netbuffer->u.clientcfg.player_configs[i] = temp;
} }
// privacy shield for the local players not joining this session // privacy shield for the local players not joining this session
for (; i < MAXSPLITSCREENPLAYERS; i++) for (; i < MAXSPLITSCREENPLAYERS; i++)
strncpy(netbuffer->u.clientcfg.names[i], va("Player %c", 'A' + i), MAXPLAYERNAME); {
player_config_t temp;
strncpy(temp.name, va("Player %c", 'A' + i), MAXPLAYERNAME);
temp.skin = 0;
temp.color = SKINCOLOR_NONE;
temp.follower = -1;
temp.follower_color = SKINCOLOR_NONE;
temp.weapon_prefs = 0;
temp.min_delay = 0;
netbuffer->u.clientcfg.player_configs[i] = temp;
}
memcpy(&netbuffer->u.clientcfg.availabilities, R_GetSkinAvailabilities(false, -1), MAXAVAILABILITY*sizeof(UINT8)); memcpy(&netbuffer->u.clientcfg.availabilities, R_GetSkinAvailabilities(false, -1), MAXAVAILABILITY*sizeof(UINT8));
@ -3992,11 +4012,7 @@ static void Got_ServerDeafenPlayer(const UINT8 **p, INT32 playernum)
} }
} }
static boolean SV_AddWaitingPlayers(SINT8 node, UINT8 *availabilities, static boolean SV_AddWaitingPlayers(SINT8 node, UINT8 *availabilities, player_config_t configs[MAXSPLITSCREENPLAYERS])
const char *name, uint8_t *key, UINT16 *pwr,
const char *name2, uint8_t *key2, UINT16 *pwr2,
const char *name3, uint8_t *key3, UINT16 *pwr3,
const char *name4, uint8_t *key4, UINT16 *pwr4)
{ {
INT32 n, newplayernum, i; INT32 n, newplayernum, i;
UINT8 buf[4 + MAXPLAYERNAME + 10 + PUBKEYLENGTH + MAXAVAILABILITY + sizeof(((serverplayer_t *)0)->powerlevels)]; UINT8 buf[4 + MAXPLAYERNAME + 10 + PUBKEYLENGTH + MAXAVAILABILITY + sizeof(((serverplayer_t *)0)->powerlevels)];
@ -4050,6 +4066,30 @@ static boolean SV_AddWaitingPlayers(SINT8 node, UINT8 *availabilities,
// before accepting the join // before accepting the join
I_Assert(newplayernum < MAXPLAYERS); I_Assert(newplayernum < MAXPLAYERS);
if (playerpernode[node] < 1)
{
nodetoplayer[node] = newplayernum;
}
else if (playerpernode[node] < 2)
{
nodetoplayer2[node] = newplayernum;
}
else if (playerpernode[node] < 3)
{
nodetoplayer3[node] = newplayernum;
}
else if (playerpernode[node] < 4)
{
nodetoplayer4[node] = newplayernum;
}
else
{
// I don't know if it's safe to assert here,
// but I do know this should not be allowed
// to be reached.
return newplayer;
}
playernode[newplayernum] = (UINT8)node; playernode[newplayernum] = (UINT8)node;
// Reset the buffer to the start for multiple joiners // Reset the buffer to the start for multiple joiners
@ -4058,42 +4098,16 @@ static boolean SV_AddWaitingPlayers(SINT8 node, UINT8 *availabilities,
WRITEUINT8(buf_p, (UINT8)node); WRITEUINT8(buf_p, (UINT8)node);
WRITEUINT8(buf_p, newplayernum); WRITEUINT8(buf_p, newplayernum);
if (playerpernode[node] < 1) const player_config_t *config = &configs[playerpernode[node]];
{ WRITESTRINGN(buf_p, config->name, MAXPLAYERNAME);
nodetoplayer[node] = newplayernum; WRITEUINT16(buf_p, config->skin);
WRITESTRINGN(buf_p, name, MAXPLAYERNAME); WRITEUINT16(buf_p, config->color);
D_WritePlayerSkinAndColor(0, NULL, &buf_p); WRITEINT16(buf_p, config->follower);
D_WritePlayerWeaponPref(0, &buf_p); WRITEUINT16(buf_p, config->follower_color);
WRITEMEM(buf_p, key, PUBKEYLENGTH); WRITEUINT8(buf_p, config->weapon_prefs);
WRITEMEM(buf_p, pwr, sizeof(((serverplayer_t *)0)->powerlevels)); WRITEUINT8(buf_p, config->min_delay);
} WRITEMEM(buf_p, config->key, PUBKEYLENGTH);
else if (playerpernode[node] < 2) WRITEMEM(buf_p, config->pwr, sizeof(((serverplayer_t *)0)->powerlevels));
{
nodetoplayer2[node] = newplayernum;
WRITESTRINGN(buf_p, name2, MAXPLAYERNAME);
D_WritePlayerSkinAndColor(1, NULL, &buf_p);
D_WritePlayerWeaponPref(1, &buf_p);
WRITEMEM(buf_p, key2, PUBKEYLENGTH);
WRITEMEM(buf_p, pwr2, sizeof(((serverplayer_t *)0)->powerlevels));
}
else if (playerpernode[node] < 3)
{
nodetoplayer3[node] = newplayernum;
WRITESTRINGN(buf_p, name3, MAXPLAYERNAME);
D_WritePlayerSkinAndColor(2, NULL, &buf_p);
D_WritePlayerWeaponPref(2, &buf_p);
WRITEMEM(buf_p, key3, PUBKEYLENGTH);
WRITEMEM(buf_p, pwr3, sizeof(((serverplayer_t *)0)->powerlevels));
}
else if (playerpernode[node] < 4)
{
nodetoplayer4[node] = newplayernum;
WRITESTRINGN(buf_p, name4, MAXPLAYERNAME);
D_WritePlayerSkinAndColor(3, NULL, &buf_p);
D_WritePlayerWeaponPref(3, &buf_p);
WRITEMEM(buf_p, key4, PUBKEYLENGTH);
WRITEMEM(buf_p, pwr4, sizeof(((serverplayer_t *)0)->powerlevels));
}
WRITEUINT8(buf_p, nodetoplayer[node]); // consoleplayer WRITEUINT8(buf_p, nodetoplayer[node]); // consoleplayer
WRITEUINT8(buf_p, playerpernode[node]); // splitscreen num WRITEUINT8(buf_p, playerpernode[node]); // splitscreen num
@ -4272,11 +4286,21 @@ boolean SV_SpawnServer(void)
UINT8 *availabilitiesbuffer = R_GetSkinAvailabilities(false, -1); UINT8 *availabilitiesbuffer = R_GetSkinAvailabilities(false, -1);
SINT8 node = 0; SINT8 node = 0;
for (; node < MAXNETNODES; node++) for (; node < MAXNETNODES; node++)
result |= SV_AddWaitingPlayers(node, availabilitiesbuffer, {
cv_playername[0].zstring, PR_GetLocalPlayerProfile(0)->public_key, SV_GetStatsByKey(PR_GetLocalPlayerProfile(0)->public_key)->powerlevels, player_config_t configs[MAXSPLITSCREENPLAYERS];
cv_playername[1].zstring, PR_GetLocalPlayerProfile(1)->public_key, SV_GetStatsByKey(PR_GetLocalPlayerProfile(1)->public_key)->powerlevels,
cv_playername[2].zstring, PR_GetLocalPlayerProfile(2)->public_key, SV_GetStatsByKey(PR_GetLocalPlayerProfile(2)->public_key)->powerlevels, INT32 i;
cv_playername[3].zstring, PR_GetLocalPlayerProfile(3)->public_key, SV_GetStatsByKey(PR_GetLocalPlayerProfile(3)->public_key)->powerlevels); for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
strncpy(configs[i].name, cv_playername[i].zstring, MAXPLAYERNAME);
D_FillPlayerSkinAndColor(i, NULL, &configs[i]);
D_FillPlayerWeaponPref(i, &configs[i]);
memcpy(configs[i].key, PR_GetLocalPlayerProfile(i)->public_key, sizeof(configs[i].key));
memcpy(configs[i].pwr, SV_GetStatsByKey(PR_GetLocalPlayerProfile(i)->public_key)->powerlevels, sizeof(configs[i].pwr));
}
result |= SV_AddWaitingPlayers(node, availabilitiesbuffer, configs);
}
} }
return result; return result;
#endif #endif
@ -4385,6 +4409,7 @@ static boolean IsPlayerGuest(UINT8 player)
*/ */
static void HandleConnect(SINT8 node) static void HandleConnect(SINT8 node)
{ {
player_config_t configs[MAXSPLITSCREENPLAYERS];
char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME + 1]; char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME + 1];
INT32 i, j; INT32 i, j;
UINT8 availabilitiesbuffer[MAXAVAILABILITY]; UINT8 availabilitiesbuffer[MAXAVAILABILITY];
@ -4508,9 +4533,12 @@ static void HandleConnect(SINT8 node)
int sigcheck; int sigcheck;
boolean newnode = false; boolean newnode = false;
memcpy(configs, netbuffer->u.clientcfg.player_configs, sizeof(configs));
for (i = 0; i < netbuffer->u.clientcfg.localplayers - playerpernode[node]; i++) for (i = 0; i < netbuffer->u.clientcfg.localplayers - playerpernode[node]; i++)
{ {
strlcpy(names[i], netbuffer->u.clientcfg.names[i], MAXPLAYERNAME + 1); strlcpy(names[i], configs[i].name, MAXPLAYERNAME + 1);
if (!EnsurePlayerNameIsGood(names[i], -1)) if (!EnsurePlayerNameIsGood(names[i], -1))
{ {
SV_SendRefuse(node, "Bad player name"); SV_SendRefuse(node, "Bad player name");
@ -4631,11 +4659,15 @@ static void HandleConnect(SINT8 node)
DEBFILE("send savegame\n"); DEBFILE("send savegame\n");
} }
SV_AddWaitingPlayers(node, availabilitiesbuffer, for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
names[0], lastReceivedKey[node][0], SV_GetStatsByKey(lastReceivedKey[node][0])->powerlevels, {
names[1], lastReceivedKey[node][1], SV_GetStatsByKey(lastReceivedKey[node][1])->powerlevels, strlcpy(configs[i].name, names[i], MAXPLAYERNAME + 1);
names[2], lastReceivedKey[node][2], SV_GetStatsByKey(lastReceivedKey[node][2])->powerlevels, memcpy(configs[i].key, lastReceivedKey[node][i], sizeof(configs[i].key));
names[3], lastReceivedKey[node][3], SV_GetStatsByKey(lastReceivedKey[node][3])->powerlevels); memcpy(configs[i].pwr, SV_GetStatsByKey(lastReceivedKey[node][i])->powerlevels, sizeof(configs[i].pwr));
}
SV_AddWaitingPlayers(node, availabilitiesbuffer, configs);
joindelay += cv_joindelay.value * TICRATE; joindelay += cv_joindelay.value * TICRATE;
player_joining = true; player_joining = true;
} }

View file

@ -273,6 +273,19 @@ struct fileack_pak
#define MAXAPPLICATION 16 #define MAXAPPLICATION 16
struct player_config_t
{
char name[MAXPLAYERNAME];
UINT16 skin;
UINT16 color;
INT16 follower;
UINT16 follower_color;
UINT8 weapon_prefs;
UINT8 min_delay;
uint8_t key[PUBKEYLENGTH];
UINT16 pwr[PWRLV_NUMTYPES];
};
struct clientconfig_pak struct clientconfig_pak
{ {
UINT8 _255;/* see serverinfo_pak */ UINT8 _255;/* see serverinfo_pak */
@ -282,9 +295,10 @@ struct clientconfig_pak
UINT8 subversion; // Contains build version UINT8 subversion; // Contains build version
UINT8 localplayers; // number of splitscreen players UINT8 localplayers; // number of splitscreen players
UINT8 mode; UINT8 mode;
char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME]; char _names_outdated[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME];
UINT8 availabilities[MAXAVAILABILITY]; UINT8 availabilities[MAXAVAILABILITY];
uint8_t challengeResponse[MAXSPLITSCREENPLAYERS][SIGNATURELENGTH]; uint8_t challengeResponse[MAXSPLITSCREENPLAYERS][SIGNATURELENGTH];
player_config_t player_configs[MAXSPLITSCREENPLAYERS];
} ATTRPACK; } ATTRPACK;
#define SV_SPEEDMASK 0x03 // used to send kartspeed #define SV_SPEEDMASK 0x03 // used to send kartspeed

View file

@ -932,7 +932,7 @@ VaguePartyDescription (int playernum, int size, int default_color)
return party_description; return party_description;
} }
void D_WritePlayerSkinAndColor(const UINT8 n, const player_t *player, UINT8 **p) void D_FillPlayerSkinAndColor(const UINT8 n, const player_t *player, player_config_t *config)
{ {
if (player != NULL) if (player != NULL)
{ {
@ -1008,18 +1008,10 @@ void D_WritePlayerSkinAndColor(const UINT8 n, const player_t *player, UINT8 **p)
} }
} }
WRITEUINT16(*p, (UINT16)cv_skin[n].value); config->skin = (UINT16)cv_skin[n].value;
WRITEUINT16(*p, sendColor); config->color = sendColor;
if (horngoner) config->follower = (horngoner ? -1 : (INT16)cv_follower[n].value);
{ config->follower_color = sendFollowerColor;
WRITEINT16(*p, (-1));
}
else
{
WRITEINT16(*p, (INT16)cv_follower[n].value);
}
//CONS_Printf("Sending follower id %d\n", (INT16)cv_follower[n].value);
WRITEUINT16(*p, sendFollowerColor);
} }
static INT32 snacpending[MAXSPLITSCREENPLAYERS] = {0,0,0,0}; static INT32 snacpending[MAXSPLITSCREENPLAYERS] = {0,0,0,0};
@ -1046,8 +1038,6 @@ static void SendNameAndColor(const UINT8 n)
} }
player_t *player = &players[playernum]; player_t *player = &players[playernum];
UINT8 buf[MAXPLAYERNAME+13];
UINT8 *p = buf;
// Don't change name if muted // Don't change name if muted
if (player_name_changes[player - players] >= MAXNAMECHANGES) if (player_name_changes[player - players] >= MAXNAMECHANGES)
@ -1064,8 +1054,18 @@ static void SendNameAndColor(const UINT8 n)
CleanupPlayerName(player - players, cv_playername[n].zstring); CleanupPlayerName(player - players, cv_playername[n].zstring);
} }
player_config_t config;
D_FillPlayerSkinAndColor(n, player, &config);
UINT8 buf[MAXPLAYERNAME + 13];
UINT8 *p = buf;
WRITESTRINGN(p, cv_playername[n].zstring, MAXPLAYERNAME); WRITESTRINGN(p, cv_playername[n].zstring, MAXPLAYERNAME);
D_WritePlayerSkinAndColor(n, player, &p); WRITEUINT16(p, config.skin);
WRITEUINT16(p, config.color);
WRITEINT16(p, config.follower);
//CONS_Printf("Sending follower id %d\n", config.follower);
WRITEUINT16(p, config.follower_color);
snacpending[n]++; snacpending[n]++;
SendNetXCmdForPlayer(n, XD_NAMEANDCOLOR, buf, p - buf); SendNetXCmdForPlayer(n, XD_NAMEANDCOLOR, buf, p - buf);
@ -1221,7 +1221,7 @@ enum {
// HOURS LOST TO G_PlayerReborn: UNCOUNTABLE // HOURS LOST TO G_PlayerReborn: UNCOUNTABLE
}; };
void D_WritePlayerWeaponPref(const UINT8 n, UINT8 **p) void D_FillPlayerWeaponPref(const UINT8 n, player_config_t *config)
{ {
UINT8 prefs = 0; UINT8 prefs = 0;
@ -1252,15 +1252,21 @@ void D_WritePlayerWeaponPref(const UINT8 n, UINT8 **p)
if (cv_strictfastfall[n].value) if (cv_strictfastfall[n].value)
prefs |= WP_STRICTFASTFALL; prefs |= WP_STRICTFASTFALL;
WRITEUINT8(*p, prefs); config->weapon_prefs = prefs;
WRITEUINT8(*p, cv_mindelay.value); config->min_delay = cv_mindelay.value;
} }
void WeaponPref_Send(UINT8 ssplayer) void WeaponPref_Send(UINT8 ssplayer)
{ {
player_config_t config;
D_FillPlayerWeaponPref(ssplayer, &config);
UINT8 buf[2]; UINT8 buf[2];
UINT8 *p = buf; UINT8 *p = buf;
D_WritePlayerWeaponPref(ssplayer, &p);
WRITEUINT8(p, config.weapon_prefs);
WRITEUINT8(p, config.min_delay);
SendNetXCmdForPlayer(ssplayer, XD_WEAPONPREF, buf, p - buf); SendNetXCmdForPlayer(ssplayer, XD_WEAPONPREF, buf, p - buf);
} }

View file

@ -201,9 +201,9 @@ void D_RegisterServerCommands(void);
void D_RegisterClientCommands(void); void D_RegisterClientCommands(void);
void CleanupPlayerName(INT32 playernum, const char *newname); void CleanupPlayerName(INT32 playernum, const char *newname);
boolean EnsurePlayerNameIsGood(char *name, INT32 playernum); boolean EnsurePlayerNameIsGood(char *name, INT32 playernum);
void D_WritePlayerSkinAndColor(const UINT8 n, const player_t *player, UINT8 **p); void D_FillPlayerSkinAndColor(const UINT8 n, const player_t *player, player_config_t *config);
void D_PlayerChangeSkinAndColor(player_t *player, UINT16 skin, UINT16 color, INT16 follower, UINT16 followercolor); void D_PlayerChangeSkinAndColor(player_t *player, UINT16 skin, UINT16 color, INT16 follower, UINT16 followercolor);
void D_WritePlayerWeaponPref(const UINT8 n, UINT8 **p); void D_FillPlayerWeaponPref(const UINT8 n, player_config_t *config);
void WeaponPref_Send(UINT8 ssplayer); void WeaponPref_Send(UINT8 ssplayer);
void WeaponPref_Set(INT32 playernum, UINT8 prefs); void WeaponPref_Set(INT32 playernum, UINT8 prefs);
void WeaponPref_Save(UINT8 **cp, INT32 playernum); void WeaponPref_Save(UINT8 **cp, INT32 playernum);

View file

@ -67,6 +67,7 @@ TYPEDEF (serverconfig_pak);
TYPEDEF (filetx_pak); TYPEDEF (filetx_pak);
TYPEDEF (fileacksegment_t); TYPEDEF (fileacksegment_t);
TYPEDEF (fileack_pak); TYPEDEF (fileack_pak);
TYPEDEF (player_config_t);
TYPEDEF (clientconfig_pak); TYPEDEF (clientconfig_pak);
TYPEDEF (serverinfo_pak); TYPEDEF (serverinfo_pak);
TYPEDEF (serverrefuse_pak); TYPEDEF (serverrefuse_pak);