Skip to content

Improve CD key prevalidation - #880

Merged
timangus merged 2 commits into
ioquake:mainfrom
kk1201:cdkey_validation_fix
Jul 8, 2026
Merged

Improve CD key prevalidation#880
timangus merged 2 commits into
ioquake:mainfrom
kk1201:cdkey_validation_fix

Conversation

@kk1201

@kk1201 kk1201 commented Jul 7, 2026

Copy link
Copy Markdown

Fix #877

ioq3/code/client/cl_main.c

Lines 4720 to 4747 in 5d810e5

for (i = 0; i < len; i++) {
ch = *key++;
if (ch>='a' && ch<='z') {
ch -= 32;
}
switch( ch ) {
case '2':
case '3':
case '7':
case 'A':
case 'B':
case 'C':
case 'D':
case 'G':
case 'H':
case 'J':
case 'L':
case 'P':
case 'R':
case 'S':
case 'T':
case 'W':
sum += ch;
continue;
default:
return qfalse;
}
}

This snippet in cl_main.c already includes code to ignore case when validating CD key. The issue was that the UI_CDKeyMenu_PreValidateKey function diverged from this and prematurely failed.

@kk1201 kk1201 changed the title Improve CD key prevalidation, resolves #877 Improve CD key prevalidation Jul 7, 2026
@timangus

timangus commented Jul 7, 2026

Copy link
Copy Markdown
Member

ioq3/code/client/cl_main.c

Lines 4721 to 4724 in 5d810e5

ch = *key++;
if (ch>='a' && ch<='z') {
ch -= 32;
}

This is a bit mad really; it should just use ch = toupper(*key++);. Functionally the same, more obvious what it's doing. Could you employ that method instead, in the original and in your fix. Thanks.

@kk1201

kk1201 commented Jul 8, 2026

Copy link
Copy Markdown
Author

Of course. I'll do tolower() in both though, I think it makes sense since the behaviour was 50/50 between those two files, Quake 3 keys were lowercase, and it fits better with the following. I had a look at Com_WriteCDKey:

ioq3/code/qcommon/common.c

Lines 2531 to 2572 in 5d810e5

static void Com_WriteCDKey( const char *filename, const char *ikey ) {
fileHandle_t f;
char fbuffer[MAX_OSPATH];
char key[17];
#ifndef _WIN32
mode_t savedumask;
#endif
Com_sprintf(fbuffer, sizeof(fbuffer), "%s/q3key", filename);
Q_strncpyz( key, ikey, 17 );
if(!CL_CDKeyValidate(key, NULL) ) {
return;
}
#ifndef _WIN32
savedumask = umask(0077);
#endif
f = FS_BaseDir_FOpenFileWrite_HomeState( fbuffer );
if ( !f ) {
Com_Printf ("Couldn't write CD key to %s.\n", fbuffer );
goto out;
}
FS_Write( key, 16, f );
FS_Printf( f, "\n// generated by " PRODUCT_NAME ", do not modify\r\n" );
FS_Printf( f, "// Do not give this file to ANYONE.\r\n" );
FS_Printf( f, "// id Software and Activision will NOT ask you to send this file to them.\r\n");
FS_FCloseFile( f );
out:
#ifndef _WIN32
umask(savedumask);
#else
;
#endif
}
#endif

When the game boots up and when you press "Accept" on the CD key menu, the game reads & writes the key to the filesystem. If the key is upper/mixed-case then Com_WriteCDKey also writes it as upper/mixed-case. If we care, we can make it output only the valid Quake 3 lower-case version. Tell me if you'd like that added.

The Steam version always overwrites the q3key in its game path with the uppercase version and reads it, so it doesn't really affect that.

@timangus
timangus merged commit b75bee1 into ioquake:main Jul 8, 2026
12 checks passed
ec- pushed a commit to ec-/baseq3a that referenced this pull request Jul 23, 2026
This issue is annoying since Steam provides an uppercase key.

Similar commit in ioquake3:
ioquake/ioq3@b75bee1
(ioquake/ioq3#880).

The engine actually does a case-insensitive comparison:
https://github.com/ec-/Quake3e/blob/ed1064f80fda9cde2e7d33c2d5dce8f8166b12bd/code/qcommon/common.c#L3113-L3140.

I have tested this with the ioq3 engine.
Quake3e seems to have a bug where it doesn't write the CD key file.
tomkidd pushed a commit that referenced this pull request Jul 26, 2026
* Improve CD key prevalidation
* Use tolower instead of ascii math
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support Steam-created improper q3key files

2 participants