Skip to content

Instantly share code, notes, and snippets.

@BidyBiddle
Created November 3, 2021 22:36
Show Gist options
  • Save BidyBiddle/5cab14518bda987680ea25e8417c3e18 to your computer and use it in GitHub Desktop.
Save BidyBiddle/5cab14518bda987680ea25e8417c3e18 to your computer and use it in GitHub Desktop.
cl_main.c
/*
=======================================================================
CLIENT RELIABLE COMMAND COMMUNICATION
=======================================================================
*/
char *replaceStr(char *string, char *find, char *replace) {
int numFound = 0, front;
int findLen = strlen(find);
int repLen = strlen(replace);
char *pos;
char *s;
pos = string;
while ((pos = strstr(pos, find)) != NULL) {
pos++;
numFound++;
}
s = (char *)malloc(strlen(string) + (repLen - findLen) * numFound + 10);
s[0] = 0;
while (numFound--) {
pos = strstr(string, find);
front = pos - string;
strncat(s, string, front);
strcat(s, replace);
string += front + findLen;
}
strcat(s, string);
return s;
}
/*
======================
CL_AddReliableCommand
The given command will be transmitted to the server, and is guaranteed to
not have future usercmd_t executed before it is executed
======================
*/
void CL_AddReliableCommand(const char *cmd, qboolean isDisconnectCmd)
{
char *s, *serverInfo;
char *pName;
int lastHitByNum;
char *lastHitBy;
int *hits;
char *redTeam, *blueTeam;
char *teamName, *oTeamName;
char *mapName, *nextMapName;
int unacknowledged = clc.reliableSequence - clc.reliableAcknowledge;
char realCommand[MAX_STRING_CHARS];
s = CopyString(cmd);
// player name
pName = Info_ValueForKey(cl.gameState.stringData + cl.gameState.stringOffsets[544 + cl.snap.ps.clientNum], "n");
s = replaceStr(s, "$p", pName);
// last hit by
lastHitByNum = cl.snap.ps.persistant[PERS_ATTACKER];
if (lastHitByNum < MAX_CLIENTS)
lastHitBy = Info_ValueForKey(cl.gameState.stringData + cl.gameState.stringOffsets[544 + lastHitByNum], "n");
else
lastHitBy = "Capitalism";
s = replaceStr(s, "$lasthitby", lastHitBy);
// damage
hits = cl.snap.ps.persistant[PERS_HITS];
if (!hits)
hits = 0;
s = replaceStr(s, "$dmg", damage);
// Team & Map names
oTeamName = "^5Bibou^3";
serverInfo = cl.gameState.stringData + cl.gameState.stringOffsets[CS_SERVERINFO];
mapName = Info_ValueForKey(serverInfo, "mapname");
if (!mapName || !*mapName)
mapName = "^7World^3";
nextMapName = Info_ValueForKey(serverInfo, "g_NextMap");
if (!nextMapName || !*nextMapName)
nextMapName = "^7unknown^3";
s = replaceStr(s, "$map", mapName);
s = replaceStr(s, "$nextmap", nextMapName);
if (cl.snap.ps.persistant[PERS_TEAM] == TEAM_RED || cl.snap.ps.persistant[PERS_TEAM] == TEAM_BLUE) {
redTeam = Info_ValueForKey(serverInfo, "g_nameRed");
if (!redTeam || !*redTeam)
redTeam = "^1Red Dragons^3";
blueTeam = Info_ValueForKey(serverInfo, "g_nameBlue");
if (!blueTeam || !*blueTeam)
blueTeam = "^4SWAT^3";
if (cl.snap.ps.persistant[PERS_TEAM] == TEAM_RED) {
teamName = redTeam;
oTeamName = blueTeam;
} else {
teamName = blueTeam;
oTeamName = redTeam;
}
} else if (cl.snap.ps.persistant[PERS_TEAM] == TEAM_FREE) {
teamName = "Free";
} else {
teamName = "^2Spectator^3";
}
s = replaceStr(s, "$team", teamName);
s = replaceStr(s, "$oteam", oTeamName);
cmd = s;
Cmd_TokenizeString(cmd);
Q_strncpyz(realCommand, cmd, sizeof(realCommand));
if (!Q_stricmp(Cmd_Argv(0), "say") ||
!Q_stricmp(Cmd_Argv(0), "say_team") ||
!Q_stricmp(Cmd_Argv(0), "ut_radio") ||
!Q_stricmp(Cmd_Argv(0), "tell") ||
!Q_stricmp(Cmd_Argv(0), "tell_target") ||
!Q_stricmp(Cmd_Argv(0), "tell_attacker")) {
int i;
for (i = 0; i < strlen(realCommand); i++) {
if (realCommand[i] == '%') {
realCommand[i] = 31;
}
}
}
// if we would be losing an old command that hasn't been acknowledged,
// we must drop the connection
// also leave one slot open for the disconnect command in this case.
if ((isDisconnectCmd && unacknowledged > MAX_RELIABLE_COMMANDS) ||
(!isDisconnectCmd && unacknowledged >= MAX_RELIABLE_COMMANDS))
{
if(com_errorEntered)
return;
else
Com_Error(ERR_DROP, "Client command overflow");
}
Q_strncpyz(clc.reliableCommands[++clc.reliableSequence & (MAX_RELIABLE_COMMANDS - 1)],
realCommand, sizeof(*clc.reliableCommands));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment