Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions CreateVisualStudio2026Projects.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
@REM Create OpenJK projects for Visual Studio 2026 using CMake
@echo off
for %%X in (cmake.exe) do (set FOUND=%%~$PATH:X)
if not defined FOUND (
echo CMake was not found on your system. Please make sure you have installed CMake
echo from http://www.cmake.org/ and cmake.exe is installed to your system's PATH
echo environment variable.
echo.
pause
exit /b 1
) else (
echo Found CMake!
)
if not exist build\nul (mkdir build)
pushd build
cmake -G "Visual Studio 18 2026" -A Win32 -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -D CMAKE_INSTALL_PREFIX=../install ..
popd
pause
108 changes: 108 additions & 0 deletions assets/japro/ui/jamp/ingame_setup.menu
Original file line number Diff line number Diff line change
Expand Up @@ -4533,6 +4533,114 @@
mouseenter { show highlight9 }
mouseexit { hide highlight9 }
}

itemDef
{
name chatdisableteam
group network
type ITEM_TYPE_MULTI
text "Disable the 'team' chat"
descText "Disable the 'team' chat"
cvar "cg_chatdisableTeam"
cvarFloatList
{
@MENUS_OFF 0
@MENUS_ON 1
}
rect 230 243 300 20
textalign ITEM_ALIGN_RIGHT
textalignx 165
textaligny 0
font 4
textscale 1
forecolor .615 .615 .956 1
visible 0

action
{
play "sound/interface/button1.wav"
}
mouseenter
{
show highlight11
}
mouseexit
{
hide highlight11
}
}

itemDef
{
name chatdisableall
group network
type ITEM_TYPE_MULTI
text "Disable the 'all' chat"
descText "Disable the 'all' chat and whispers"
cvar "cg_chatdisableAll"
cvarFloatList
{
@MENUS_OFF 0
@MENUS_ON 1
}
rect 230 263 300 20
textalign ITEM_ALIGN_RIGHT
textalignx 165
textaligny 0
font 4
textscale 1
forecolor .615 .615 .956 1
visible 0

action
{
play "sound/interface/button1.wav"
}
mouseenter
{
show highlight12
}
mouseexit
{
hide highlight12
}
}

itemDef
{
name chatdisableclan
group network
type ITEM_TYPE_MULTI
text "Disable the 'clan' chat"
descText "Disable the 'clan' chat"
cvar "cg_chatdisableClan"
cvarFloatList
{
@MENUS_OFF 0
@MENUS_ON 1
}
rect 230 283 300 20
textalign ITEM_ALIGN_RIGHT
textalignx 165
textaligny 0
font 4
textscale 1
forecolor .615 .615 .956 1
visible 0

action
{
play "sound/interface/button1.wav"
}
mouseenter
{
show highlight13
}
mouseexit
{
hide highlight13
}
}

// APPLY CHANGES BUTTON
itemDef
Expand Down
98 changes: 98 additions & 0 deletions codemp/cgame/cg_servercmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -1666,6 +1666,94 @@ static void CG_Print_f( void ) {
CG_LogPrintf(cg.log.file, "%s\n", strEd); //Log server console prints?
}


// Variables that hold the information, initialized when calling the funciton for the first time and needs a reboot to reload the file
#define MAX_BAN_WORDS 128
#define MAX_BAN_WORD_LEN 32
static char banWords[MAX_BAN_WORDS][MAX_BAN_WORD_LEN];
static int numBanWords = 0;
static qboolean banWordArrayReady = qfalse;

// Heavily inspired by FS_ReadFile
static void CG_LoadBanWords(void)
{
fileHandle_t file;
int length;
char buffer[8192];
char* ptr;
char* line;

if (banWordArrayReady)
return;

length = trap->FS_Open("banwords.txt", &file, FS_READ);

if (!file || length <= 0) // File don't exist or in bad folder (base INSIDE Debug, not only base in the git repo)
return;

trap->FS_Read(buffer, length, file);
trap->FS_Close(file);

// guarantee that it will have a trailing 0 for string operations
buffer[length] = 0;

ptr = buffer;

// COM_ParseString copy : if COM_ParseExt returns nothing, then we have ended the buffer
while ((line = COM_ParseExt(&ptr, qtrue)) != NULL && line[0]) // If qfalse, it only reads the first line, different than COM_ParseString
{
if (numBanWords >= MAX_BAN_WORDS)
break;

Q_strncpyz(banWords[numBanWords], line, MAX_BAN_WORD_LEN);
numBanWords++;
}

banWordArrayReady = qtrue;
}
static void CG_Chat_CheckBanWord(char* text)
{
CG_LoadBanWords();

for (int i = 0; i < numBanWords; i++)
{
// Q_stristr because it musn't be case sensitive, people will write as they wish on the .txt
// Else I would have used strstr again
char* match = Q_stristr(text, banWords[i]);

while (match) // Found a match in the current word of the list !
{
int len = strlen(banWords[i]);

for (int j = 0; j < len; j++)
match[j] = '*';

match = Q_stristr(match + len, banWords[i]); // Recheck if the same word is present multiple times
}
}
}

static void CG_Chat_CheckDisabled(char* cmd, char* text)
{
// Same size as text
char* textToDisplay[MAX_NETNAME + MAX_SAY_TEXT] = { 0 };

// Clan : cmd : chat ; message : ^1<Clan>^7(Posto^7): ^1co
// Team : cmd : tchat ; message : (Posto^7): ^5to
// All : cmd : chat ; message : Posto^7: ^2yo
// Whispers are considered "all chat" when hitting this function, only change is color and the server choosing to whom to deliver them

if (cg_chatDisableClan.integer && Q_stricmp(cmd, "chat") == 0 && strstr(text, "<Clan>") != NULL || // If it's a clan chat
cg_chatDisableTeam.integer && Q_stricmp(cmd, "tchat") == 0 || // If it's a team chat
cg_chatDisableAll.integer && Q_stricmp(cmd, "chat") == 0 && strstr(text, "<Clan>") == NULL ) // If it's a all chat
{
Q_strncpyz(textToDisplay, "", sizeof(textToDisplay));
strcpy(text, textToDisplay);
}

return;
}

void CG_ChatBox_AddString(char *chatStr);
static void CG_Chat_f( void ) {
char cmd[MAX_STRING_CHARS] = {0}, text[MAX_NETNAME+MAX_SAY_TEXT] = {0}, logtext[MAX_NETNAME+MAX_SAY_TEXT] = {0};
Expand All @@ -1680,6 +1768,9 @@ static void CG_Chat_f( void ) {
{
CG_RemoveChatEscapeChar( text );

CG_Chat_CheckDisabled(cmd, text);
CG_Chat_CheckBanWord(text);

if (cg_cleanChatbox.integer) {
char cleanMsg[MAX_NETNAME + MAX_SAY_TEXT];

Expand Down Expand Up @@ -1717,6 +1808,9 @@ static void CG_Chat_f( void ) {
{
CG_RemoveChatEscapeChar( text );

CG_Chat_CheckDisabled(cmd, text);
CG_Chat_CheckBanWord(text);

if (cg_cleanChatbox.integer && !Q_strncmp(text, cg.lastChatMsg, strlen(text))) {//Same exact msg/sender as previous //replace this with q_strcmp in entire function..?
return;
}
Expand Down Expand Up @@ -1751,11 +1845,15 @@ static void CG_Chat_f( void ) {
if ( !Q_stricmp( cmd, "lchat" ) && !cg_teamChatsOnly.integer ) {
Com_sprintf( text, sizeof( text ), "%s" S_COLOR_WHITE "<%s> ^%s%s", name, loc, color, message );
CG_RemoveChatEscapeChar( text );
CG_Chat_CheckDisabled(cmd, text);
CG_Chat_CheckBanWord(text);
CG_ChatBox_AddString( text );
}
else if ( !Q_stricmp( cmd, "ltchat" ) ) {
Com_sprintf( text, sizeof( text ), "%s" S_COLOR_WHITE "<%s> ^%s%s", name, loc, color, message );
CG_RemoveChatEscapeChar( text );
CG_Chat_CheckDisabled(cmd, text);
CG_Chat_CheckBanWord(text);
CG_ChatBox_AddString( text );
}
}
Expand Down
4 changes: 4 additions & 0 deletions codemp/cgame/cg_xcvar.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,10 @@ XCVAR_DEF( ui_tm2_c4_cnt, "0", NULL, CVAR_ROM|CVAR_INTERNAL )
XCVAR_DEF( ui_tm2_c5_cnt, "0", NULL, CVAR_ROM|CVAR_INTERNAL )
XCVAR_DEF( ui_tm2_cnt, "0", NULL, CVAR_ROM|CVAR_INTERNAL )
XCVAR_DEF( ui_tm3_cnt, "0", NULL, CVAR_ROM|CVAR_INTERNAL )
// Chat related variables
XCVAR_DEF(cg_chatDisableClan, "0", NULL, CVAR_ARCHIVE)
XCVAR_DEF(cg_chatDisableAll, "0", NULL, CVAR_ARCHIVE)
XCVAR_DEF(cg_chatDisableTeam, "0", NULL, CVAR_ARCHIVE) // Redundant because of cg_teamChatsOnly ?


#undef XCVAR_DEF
9 changes: 9 additions & 0 deletions codemp/game/g_cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -4875,11 +4875,20 @@ void Cmd_SayTeamMod_f(gentity_t *ent)//clanpass
}
if (trap->Argc() == 2) {
if (!Q_stricmp(type, "normal"))
{
Com_Printf("Changing team chat to mode : ^7normal\n");
ent->client->sess.sayteammod = 0;
}
else if (!Q_stricmp(type, "clan"))
{
Com_Printf("Changing team chat to mode : ^7clan\n");
ent->client->sess.sayteammod = 1;
}
else if (!Q_stricmp(type, "admin"))
{
Com_Printf("Changing team chat to mode : ^7admin\n");
ent->client->sess.sayteammod = 2;
}
}
}

Expand Down