games/ktx: New port: Kombat Teams eXtreme is a popular QuakeWorld server modification

https://github.com/QW-Group/ktx/
This commit is contained in:
Vladimir Druzenko 2025-02-22 05:24:12 +03:00
parent dfd3a8bb3f
commit 6bb96dba53
11 changed files with 742 additions and 2 deletions

2
GIDs
View file

@ -440,7 +440,7 @@ openbao:*:482:
# free: 497
rustypaste:*:498:
# free: 499
# free: 500
qw:*:500:
qwfwd:*:501:
birdvty:*:502:
# free: 503

2
UIDs
View file

@ -446,7 +446,7 @@ openbao:*:482:482:daemon:0:0:OpenBao Daemon:/nonexistent:/usr/sbin/nologin
# free: 497
rustypaste:*:498:498::0:0:Minimal file upload/pastebin service:/nonexistent:/usr/sbin/nologin
# free: 499
# free: 500
qw:*:500:500::0:0:QuakeWorld Server:/nonexistent:/usr/sbin/nologin
qwfwd:*:501:501::0:0:QuakeWorld Proxy:/nonexistent:/usr/sbin/nologin
# free: 502
# free: 503

View file

@ -475,6 +475,7 @@
SUBDIR += ksquares
SUBDIR += ksudoku
SUBDIR += ktuberling
SUBDIR += ktx
SUBDIR += kubrick
SUBDIR += kuklomenos
SUBDIR += ladder

63
games/ktx/Makefile Normal file
View file

@ -0,0 +1,63 @@
PORTNAME= ktx
DISTVERSIONPREFIX= v
DISTVERSION= 1.43
CATEGORIES= games
MAINTAINER= vvd@FreeBSD.org
COMMENT= Kombat Teams eXtreme is a popular QuakeWorld server modification
WWW= https://github.com/QW-Group/ktx/
LICENSE= GPLv2
RUN_DEPENDS= mvdsv:games/mvdsv
USES= cmake dos2unix
DOS2UNIX_FILES= resources/example-configs/ktx/ktx.cfg \
resources/example-configs/ktx/mvdsv.cfg \
resources/example-configs/ktx/problem.cfg \
resources/example-configs/ktx/race/routes/ztricks2.route
USE_GITHUB= yes
GH_ACCOUNT= QW-Group
USE_RC_SUBR= ${PORTNAME}
EXTRACT_AFTER_ARGS= --exclude ${PKGNAME}/.git* \
--exclude ${PKGNAME}/build_cmake.sh \
--exclude ${PKGNAME}/resources/example-configs/id1/"copy PAK0 and PAK1 here" \
--exclude ${PKGNAME}/tools/cross-cmake \
--exclude ${PKGNAME}/tools/vs \
--no-same-owner --no-same-permissions
QWDIR= ${PREFIX}/quake
SUB_LIST= QWDIR=${QWDIR} QWUSER=${USERS}
USERS= qw
GROUPS= qw
PLIST_SUB= QWGROUP=${GROUPS}
PORTDATA= *
.include "${.CURDIR}/../quake-data/Makefile.include"
.include <bsd.port.options.mk>
do-install:
${REINPLACE_CMD} -e 's|^set k_defmap|// set k_defmap|' \
${WRKSRC}/resources/example-configs/ktx/ktx.cfg
${MKDIR} ${STAGEDIR}${DATADIR}
cd ${WRKSRC}/resources && \
${COPYTREE_SHARE} 'extralog logo' ${STAGEDIR}${DATADIR}
cd ${WRKSRC}/resources/example-configs && \
${COPYTREE_SHARE} '*' ${STAGEDIR}${QWDIR}
${MKDIR} ${STAGEDIR}${QWDIR}/ktx/demos ${STAGEDIR}${QWDIR}/qw
${MV} ${STAGEDIR}${QWDIR}/id1/maps ${STAGEDIR}${QWDIR}/qw
${INSTALL_PROGRAM} ${BUILD_WRKSRC}/qwprogs.so \
${STAGEDIR}${DATADIR}
${LN} -s ${DATADIR}/qwprogs.so ${STAGEDIR}${QWDIR}/ktx/
${LN} -s ${Q1DIR}/id1/pak0.pak ${STAGEDIR}${QWDIR}/id1/
${LN} -s ${Q1DIR}/id1/pak1.pak ${STAGEDIR}${QWDIR}/id1/
${LN} -s ${Q1DIR}/id1/maps ${STAGEDIR}${QWDIR}/id1/
.for f in port1 port2 port3 portffa servers
cd ${STAGEDIR}${QWDIR} && ${MV} ${f} ${f}.sample
.endfor
.for f in ktx.cfg listip.cfg matchless.cfg mvdfinish.qws mvdsv.cfg \
port1.cfg port2.cfg port3.cfg problem.cfg pwd.cfg server.cfg vip_ip.cfg
cd ${STAGEDIR}${QWDIR}/ktx && ${MV} ${f} ${f}.sample
.endfor
.include <bsd.port.mk>

3
games/ktx/distinfo Normal file
View file

@ -0,0 +1,3 @@
TIMESTAMP = 1740182613
SHA256 (QW-Group-ktx-v1.43_GH0.tar.gz) = 720f719c490d8e9e975b6bcab773e62bf4051c828ac394c61ab8f99e9e9c995b
SIZE (QW-Group-ktx-v1.43_GH0.tar.gz) = 1696285

130
games/ktx/files/ktx.in Executable file
View file

@ -0,0 +1,130 @@
#!/bin/sh
# PROVIDE: ktx
# REQUIRE: LOGIN
# KEYWORD: shutdown
#
# Add the following lines to /etc/rc.conf or /etc/rc.conf.local to
# enable ktx:
# ktx_(instance_)?enable (bool): Set to "NO" by default.
# Set it to "YES" to enable ktx.
# ktx_(instance_)?port (int): UDP port (default 27500).
# ktx_(instance_)?gamedir (str): Gamedir for ktx (default ktx).
# ktx_(instance_)?args (str): Custom additional arguments to be passed
# to ${__qwserver} (default empty).
# ktx_(instance_)?user (str): User to run ${__qwserver} as. Default
# to "%%QWUSER%%" created by the port.
# ktx_(instance_)?qwserver (path): Full path to QuakeWorld server to run ktx
# (default %%LOCALBASE%%/bin/mvdsv).
# ktx_(instance_)?log (path): Console log file (default
# ${__gamedir}/${name}_(instance_)?${__port}.log).
# ktx_(instance_)?randommaps (str): List of maps from which one is randomly
# selected to start the server (default empty).
# ktx_(instance_)?qwdir (path): QuakeWorld root directory
# (default %%QWDIR%%).
# ktx_instances (str): Set to "" by default.
# If defined, list of instances to enable.
. /etc/rc.subr
case $0 in
/etc/rc*)
# during boot (shutdown) $0 is /etc/rc (/etc/rc.shutdown),
# so get the name of the script from $_file
name=$_file
;;
*)
name=$0
;;
esac
name=${name##*/}
rcvar="${name}_enable"
load_rc_config "${name}"
eval "${rcvar}=\${${rcvar}:-'NO'}"
eval "__port=\${${name}_port:-'27500'}"
eval "__gamedir=\${${name}_gamedir:-'ktx'}"
eval "__args=\${${name}_args:-''}"
eval "__user=\${${name}_user:-'%%QWUSER%%'}"
eval "__qwserver=\${${name}_qwserver:-'%%LOCALBASE%%/bin/mvdsv'}"
eval "__log=\${${name}_log:-${__gamedir}/${name}_${__port}.log}"
eval "__randommaps=\${${name}_randommaps:-''}"
eval "__qwdir=\${${name}_qwdir:-'%%QWDIR%%'}"
eval "${name}_chdir=${__qwdir}"
eval "__instances=\${${name}_instances:-''}"
pidfiledir="/var/run"
pidfile="${pidfiledir}/${name}.pid"
if [ -n "$2" ]; then
instance="$2"
load_rc_config ${name}_${instance}
case "${__instances}" in
"$2 "*|*" $2 "*|*" $2"|"$2")
eval "__port=\${${name}_${instance}_port:-${__port}}"
eval "__gamedir=\${${name}_${instance}_gamedir:-${__gamedir}}"
eval "__args=\${${name}_${instance}_args:-${__args}}"
eval "__user=\${${name}_${instance}_user:-${__user}}"
eval "__qwserver=\${${name}_${instance}_qwserver:-${__qwserver}}"
eval "__log=\${${name}_${instance}_log:-${__gamedir}/${name}_${instance}_${__port}.log}"
eval "__randommaps=\${${name}_${instance}_randommaps:-${__randommaps}}"
eval "__qwdir=\${${name}_${instance}_qwdir:-${__qwdir}}"
eval "${name}_chdir=${__qwdir}"
pidfile="${pidfiledir}/${name}_${instance}.pid"
;;
*)
err 1 "$2 not found in ${name}_instances" ;;
esac
else
if [ -n "${__instances}" -a -n "$1" ]; then
for instance in ${__instances}; do
eval "_enable=\${${name}_${instance}_enable}"
eval "__enable=\${_enable:-\${${name}_enable}}"
case "${__enable}" in
[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0)
continue
;;
[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
;;
*)
if [ -z "${_enable}" ]; then
_var=${name}_enable
else
_var=${name}_${instance}_enable
fi
warn "Bad value '${__enable}' for ${_var}. " \
"Instance ${instance} skipped."
continue
;;
esac
echo "===> ${name} instance: ${instance}"
%%PREFIX%%/etc/rc.d/${name} $1 ${instance}
retcode="$?"
if [ "0${retcode}" -eq 0 ]; then
success="${instance} ${success}"
else
failed="${instance} (retcode=${retcode}) ${failed}"
fi
done
echo "===> ${name} instances success: ${success}"
echo "===> ${name} instances failed: ${failed}"
exit 0
fi
fi
if [ -n "${__randommaps}" -a \( "x$1" = "xstart" -o "x$1" = "xrestart" \) ]; then
RAND=`/usr/bin/head -c2 /dev/urandom | /usr/bin/od -An -t d`
#RAND=`echo | awk '{srand(); print rand()*1000000}'`
#RAND=$((`/bin/date +%N | /usr/bin/sed 's|^[0]*||'`+0))
LEN=`echo ${__randommaps} | /usr/bin/wc -w`
N=$((${RAND} % ${LEN} + 1))
MAP=`echo ${__randommaps} | /usr/bin/awk "{print \\$${N}}"`
__args="${__args} +map ${MAP}"
fi
command="/usr/sbin/daemon"
command_args="-P ${pidfile} -u ${__user} -R 5 -f -H -o ${__log} -m 3 ${__qwserver} -port ${__port} -game ${__gamedir} ${__args}"
run_rc_command "$1"

View file

@ -0,0 +1,45 @@
--- resources/example-configs/ktx/configs/usermodes/matchless/default.cfg.orig 2024-03-10 07:30:18 UTC
+++ resources/example-configs/ktx/configs/usermodes/matchless/default.cfg
@@ -4,7 +4,7 @@ set k_matchless_max_idle_time 0 // maximum time a
// matchless settings
set k_matchless_countdown 0 // countdown in matchless mode (0 = off, 1 = on)
set k_matchless_max_idle_time 0 // maximum time a user can be idle before being forced to spectator in matchless
-set k_pow_min_players 1 // number of players on server required for powerups to be turned on
+set k_pow_min_players 3 // number of players on server required for powerups to be turned on
set k_pow_check_time 10 // how often should ktx check if the k_pow_min_players requirement has been met (seconds)
set k_no_vote_map 0 // allow map voting and /next_map (0 = allow voting, 1 = disallow voting)
set k_no_vote_break 1 // allow vote break (0 = allow break, 1 = disallow break)
@@ -14,14 +14,27 @@ samelevel 0 // change level a
// Other settings
samelevel 0 // change level after match ends
-timelimit 10 // round timelimit in minutes
-maxclients 8 // maximum number of clients to connect
+timelimit 5 // round timelimit in minutes
+fraglimit 30
+maxclients 24 // maximum number of clients to connect
+maxspectators 8
set k_specktalk 1 // spectators can talk to players during round
// map rotation
-set k_ml_0 "dm2"
-set k_ml_1 "dm3"
-set k_ml_2 "e1m2"
-//set k_ml_3 "e1m3" // etc
+set k_ml_0 "bravado"
+set k_ml_1 "ztndm2"
+set k_ml_2 "aerowalk"
+set k_ml_3 "monsoon"
+set k_ml_4 "ztndm5"
+set k_ml_5 "shifter"
+set k_ml_6 "spinev2"
+set k_ml_7 "ztndm3"
+set k_ml_8 "catalyst"
+set k_ml_9 "toxicity"
+set k_ml_10 "ztndm4"
+set k_ml_11 "pkeg1"
+set k_ml_12 "ztndm6"
+set k_ml_13 "skyhigh"
+set k_ml_14 "pocket"
set k_random_maplist 0 // select random map from k_ml_XXX variables (0 = off, 1 = on)

192
games/ktx/files/patch-socd Normal file
View file

@ -0,0 +1,192 @@
From 631b375f3dbb150c3f37430a0a45f237ffac8153 Mon Sep 17 00:00:00 2001
From: blaze <blaze@discord>
Date: Tue, 30 Jul 2024 22:49:02 -0700
Subject: [PATCH] socd detection
---
.gitignore | 3 +++
include/progs.h | 11 ++++++++
src/client.c | 61 ++++++++++++++++++++++++++++++++++++++++++++
src/commands.c | 32 +++++++++++++++++++++--
src/stats.c | 8 ++++++
src/world.c | 2 ++
tools/vs/ktx.vcxproj | 34 ++++++++++++++++++------
7 files changed, 141 insertions(+), 10 deletions(-)
--- include/progs.h.orig
+++ include/progs.h
@@ -944,6 +944,17 @@ typedef struct gedict_s
float fIllegalFPSWarnings;
// ILLEGALFPS]
+// SOCD detectioin
+ float fStrafeChangeCount;
+ float fFramePerfectStrafeChangeCount;
+ int socdDetected;
+ int socdChecksCount;
+ float fLastSideMoveSpeed;
+ int matchStrafeChangeCount;
+ int matchPerfectStrafeCount;
+ int nullStrafeCount;
+// SOCD
+
float shownick_time; // used to force centerprint is off at desired time
clientType_t ct; // client type for client edicts
// { timing
--- src/client.c.orig
+++ src/client.c
@@ -1658,6 +1658,16 @@ void ClientConnect()
SendIntermissionToClient();
}
+// SOCD
+ self->socdChecksCount = 0;
+ self->socdDetected = 0;
+ self->fStrafeChangeCount = 0;
+ self->fFramePerfectStrafeChangeCount = 0;
+ self->fLastSideMoveSpeed = 0;
+ self->matchStrafeChangeCount = 0;
+ self->matchPerfectStrafeCount = 0;
+ self->nullStrafeCount = 0;
+
// ILLEGALFPS[
// Zibbo's frametime checking code
@@ -3520,6 +3530,57 @@ void PlayerPreThink()
}
#endif
+// SOCD detection
+ {
+ float fSideMoveSpeed = self->movement[1];
+
+ if ((fSideMoveSpeed != 0) && (fSideMoveSpeed != self->fLastSideMoveSpeed) && (self->nullStrafeCount < 3)) //strafechange
+ {
+ self->fStrafeChangeCount += 1;
+ if (match_in_progress)
+ self->matchStrafeChangeCount += 1;
+
+ if ((fSideMoveSpeed != 0) && (self->fLastSideMoveSpeed != 0))
+ {
+ self->fFramePerfectStrafeChangeCount += 1;
+ if (match_in_progress)
+ self->matchPerfectStrafeCount += 1;
+ }
+
+ self->nullStrafeCount = 0;
+ }
+ else
+ {
+ if (0 == fSideMoveSpeed)
+ self->nullStrafeCount += 1;
+ else
+ self->nullStrafeCount = 0;
+ }
+
+ self->fLastSideMoveSpeed = fSideMoveSpeed;
+
+ if (self->fStrafeChangeCount >= 16)
+ {
+ if (self->fFramePerfectStrafeChangeCount / self->fStrafeChangeCount >= 0.75)
+ {
+ int k_allow_socd_warning = cvar("k_allow_socd_warning");
+
+ self->socdDetected += 1;
+
+ if ((!match_in_progress) && (!self->isBot) && k_allow_socd_warning)
+ {
+ G_bprint(PRINT_HIGH,
+ "Warning! %s: SOCD movement assistance detected. Please disable iDrive or keyboard SOCD features.\n",
+ self->netname);
+ }
+ }
+
+ self->socdChecksCount += 1;
+ self->fStrafeChangeCount = 0;
+ self->fFramePerfectStrafeChangeCount = 0;
+ }
+ }
+
// ILLEGALFPS[
self->fAverageFrameTime += g_globalvars.frametime;
--- src/commands.c.orig
+++ src/commands.c
@@ -8114,16 +8114,47 @@ void fcheck()
if (!is_real_adm(self))
{
- if (strneq(arg_x, "f_version") && strneq(arg_x, "f_modified") && strneq(arg_x, "f_server"))
+ if (strneq(arg_x, "f_version") && strneq(arg_x, "f_modified") && strneq(arg_x, "f_server") && strneq(arg_x, "f_movement"))
{
G_sprint(self, 2, "You are not allowed to check \020%s\021\n"
- "available checks are: f_version, f_modified and f_server\n",
+ "available checks are: f_version, f_modified, f_server and f_movement\n",
arg_x);
return;
}
}
+ if (streq(arg_x, "f_movement"))
+ {
+ G_bprint(2, "%s is checking \020%s\021\n", self->netname, arg_x);
+
+ for (i = 1; i <= MAX_CLIENTS; i++)
+ {
+ if (!strnull(g_edicts[i].netname))
+ {
+ if (g_edicts[i].socdDetected > 0)
+ {
+ G_bprint(2, "%s: SOCD movement assistance detected!\n", g_edicts[i].netname);
+ }
+ else
+ {
+ if (g_edicts[i].socdChecksCount >= 2)
+ {
+ G_bprint(2, "%s: no assistance detected.\n", g_edicts[i].netname);
+ }
+ else
+ {
+ G_bprint(2, "%s: not enough movement to run SOCD detection. Please move around a map.\n", g_edicts[i].netname);
+ }
+ }
+ G_bprint(2, "%s: %s:%d/%d %s:%d/%d\n", redtext("Movement"), redtext("Perfect strafes"),
+ g_edicts[i].matchPerfectStrafeCount, g_edicts[i].matchStrafeChangeCount,
+ redtext("SOCD detections"), g_edicts[i].socdDetected, g_edicts[i].socdChecksCount);
+ }
+ }
+ return;
+ }
+
for (i = 1; i <= MAX_CLIENTS; i++)
{
if (g_edicts[i].f_checkbuf)
--- src/stats.c.orig
+++ src/stats.c
@@ -763,6 +763,14 @@ void OnePlayerStats(gedict_t *p, int tp)
p->ps.vel_frames > 0 ? p->ps.velocity_sum / p->ps.vel_frames : 0.);
}
+ if (!p->isBot)
+ {
+ G_bprint(2, "%s: %s:%d/%d %s:%d/%d\n", redtext("Movement"), redtext("Perfect strafes"),
+ p->matchPerfectStrafeCount, p->matchStrafeChangeCount, redtext("SOCD detections"),
+ p->socdDetected, p->socdChecksCount);
+ }
+
+
// armors + megahealths
if (!lgc_enabled())
{
--- src/world.c.orig
+++ src/world.c
@@ -1000,6 +1000,8 @@ void FirstFrame()
RegisterCvar("k_teamoverlay"); // q3 like team overlay
+ RegisterCvar("k_allow_socd_warning"); // socd
+
// { SP
RegisterCvarEx("k_monster_spawn_time", "20");
// }

7
games/ktx/pkg-descr Normal file
View file

@ -0,0 +1,7 @@
KTX (Kombat Teams eXtreme) is a popular QuakeWorld server modification,
adding numerous features to the core features of the server.
Although it had been developed to be QuakeWorld server agnostic, it
has over the years been developed very close to MVDSV to which it has
become an extent, thus compatibility with other QuakeWorld servers
might not have been maintained.

17
games/ktx/pkg-message Normal file
View file

@ -0,0 +1,17 @@
[
{ type: install
message: <<EOM
Example configureation in rc.conf:
ktx_enable="YES"
ktx_randommaps="aerowalk bravado catalyst monsoon shifter toxicity ztndm3 dm2 dm3 e1m2 spinev2 pkeg1 ztndm6"
ktx_args="-mem 64"
ktx_instances="ffa 1 2 3 4"
ktx_ffa_args="+exec matchless.cfg"
ktx_ffa_randommaps="aerowalk bravado catalyst monsoon shifter toxicity ztndm3 spinev2 pkeg1 ztndm2 ztndm4 ztndm5 ztndm6 skyhigh"
ktx_1_port="27501"
ktx_2_port="27502"
ktx_3_port="27503"
ktx_4_port="27504"
EOM
}
]

282
games/ktx/pkg-plist Normal file
View file

@ -0,0 +1,282 @@
quake/id1/maps
quake/id1/pak0.pak
quake/id1/pak1.pak
quake/ktx/bots/maps/2towers.bot
quake/ktx/bots/maps/aerowalk.bot
quake/ktx/bots/maps/amphi2.bot
quake/ktx/bots/maps/arenazap.bot
quake/ktx/bots/maps/bravado.bot
quake/ktx/bots/maps/cmt1b.bot
quake/ktx/bots/maps/cmt3.bot
quake/ktx/bots/maps/cmt4.bot
quake/ktx/bots/maps/dm2dmm4.bot
quake/ktx/bots/maps/dm3.bot
quake/ktx/bots/maps/dm3hill.bot
quake/ktx/bots/maps/dm4.bot
quake/ktx/bots/maps/dm6.bot
quake/ktx/bots/maps/dmm4_1.bot
quake/ktx/bots/maps/dmm4_3.bot
quake/ktx/bots/maps/e1m2.bot
quake/ktx/bots/maps/endif.bot
quake/ktx/bots/maps/frobodm2.bot
quake/ktx/bots/maps/marena2.bot
quake/ktx/bots/maps/marena3.bot
quake/ktx/bots/maps/monsoon.bot
quake/ktx/bots/maps/nacmidair.bot
quake/ktx/bots/maps/noentry.bot
quake/ktx/bots/maps/oldcrat.bot
quake/ktx/bots/maps/pkeg1.bot
quake/ktx/bots/maps/povdmm4.bot
quake/ktx/bots/maps/povdmm4b.bot
quake/ktx/bots/maps/ptucket.bot
quake/ktx/bots/maps/pushdmm4.bot
quake/ktx/bots/maps/q1q3monsoon#td.bot
quake/ktx/bots/maps/rarena3.bot
quake/ktx/bots/maps/ravageqwb8.bot
quake/ktx/bots/maps/schloss.bot
quake/ktx/bots/maps/shifter.bot
quake/ktx/bots/maps/skull.bot
quake/ktx/bots/maps/spinev2.bot
quake/ktx/bots/maps/subterfuge.bot
quake/ktx/bots/maps/ukooldm2.bot
quake/ktx/bots/maps/ukooldm3.bot
quake/ktx/bots/maps/ukooldm6.bot
quake/ktx/bots/maps/ukooldm8.bot
quake/ktx/bots/maps/ukpak2.bot
quake/ktx/bots/maps/ultrav.bot
quake/ktx/bots/maps/ztndm1.bot
quake/ktx/bots/maps/ztndm2.bot
quake/ktx/bots/maps/ztndm3.bot
quake/ktx/bots/maps/ztndm4.bot
quake/ktx/bots/maps/ztndm5.bot
quake/ktx/bots/maps/ztndm6.bot
quake/ktx/configs/reset.cfg
quake/ktx/configs/usermodes/10on10/default.cfg
quake/ktx/configs/usermodes/1on1/default.cfg
quake/ktx/configs/usermodes/1on1/ra/default.cfg
quake/ktx/configs/usermodes/2on2/aerowalk.cfg
quake/ktx/configs/usermodes/2on2/default.cfg
quake/ktx/configs/usermodes/2on2/dm4.cfg
quake/ktx/configs/usermodes/2on2/dm6.cfg
quake/ktx/configs/usermodes/2on2on2/default.cfg
quake/ktx/configs/usermodes/3on3/default.cfg
quake/ktx/configs/usermodes/3on3on3/default.cfg
quake/ktx/configs/usermodes/4on4/default.cfg
quake/ktx/configs/usermodes/4on4on4/default.cfg
quake/ktx/configs/usermodes/XonX/default.cfg
quake/ktx/configs/usermodes/amphi.cfg
quake/ktx/configs/usermodes/amphi2.cfg
quake/ktx/configs/usermodes/aqui.cfg
quake/ktx/configs/usermodes/arena3.cfg
quake/ktx/configs/usermodes/ca/default.cfg
quake/ktx/configs/usermodes/ctf/default.cfg
quake/ktx/configs/usermodes/ctf/qwq3wcp9.cfg
quake/ktx/configs/usermodes/default.cfg
quake/ktx/configs/usermodes/dm2dmm4.cfg
quake/ktx/configs/usermodes/dm2dmm4_2.cfg
quake/ktx/configs/usermodes/dmm4_1.cfg
quake/ktx/configs/usermodes/dmm4_2.cfg
quake/ktx/configs/usermodes/dmm4_3.cfg
quake/ktx/configs/usermodes/dmm4_4.cfg
quake/ktx/configs/usermodes/dmm4_5.cfg
quake/ktx/configs/usermodes/dmm4_6.cfg
quake/ktx/configs/usermodes/dmm4_7.cfg
quake/ktx/configs/usermodes/dmm4_8.cfg
quake/ktx/configs/usermodes/dmm4_9.cfg
quake/ktx/configs/usermodes/end.cfg
@comment quake/ktx/configs/usermodes/end2.cfg
quake/ktx/configs/usermodes/endif.cfg
quake/ktx/configs/usermodes/ffa/default.cfg
quake/ktx/configs/usermodes/hammer.cfg
quake/ktx/configs/usermodes/hammerv2.cfg
quake/ktx/configs/usermodes/hammerv3.cfg
quake/ktx/configs/usermodes/matchless/arena3.cfg
quake/ktx/configs/usermodes/matchless/arena5.cfg
quake/ktx/configs/usermodes/matchless/barrel.cfg
quake/ktx/configs/usermodes/matchless/bloodfest.cfg
quake/ktx/configs/usermodes/matchless/ctf.cfg
quake/ktx/configs/usermodes/matchless/default.cfg
quake/ktx/configs/usermodes/matchless/dm4ish.cfg
quake/ktx/configs/usermodes/matchless/e1m7.cfg
quake/ktx/configs/usermodes/matchless/genocide.cfg
quake/ktx/configs/usermodes/matchless/hohoho.cfg
quake/ktx/configs/usermodes/matchless/kenya.cfg
quake/ktx/configs/usermodes/matchless/q1dm17.cfg
quake/ktx/configs/usermodes/matchless/slaug.cfg
quake/ktx/configs/usermodes/nacmidair.cfg
quake/ktx/configs/usermodes/noentry.cfg
quake/ktx/configs/usermodes/oldcrat.cfg
quake/ktx/configs/usermodes/outpost.cfg
quake/ktx/configs/usermodes/povdmm4.cfg
quake/ktx/configs/usermodes/povdmm4a.cfg
quake/ktx/configs/usermodes/povdmm4b.cfg
quake/ktx/configs/usermodes/pushdmm4.cfg
@comment quake/ktx/configs/usermodes/schlossdmm4.cfg
quake/ktx/configs/usermodes/sewer.cfg
quake/ktx/configs/usermodes/tearena.cfg
@comment quake/ktx/configs/usermodes/tot/dm4.cfg
@comment quake/ktx/configs/usermodes/tot/e1m2.cfg
@comment quake/ktx/configs/usermodes/tot/schloss.cfg
@dir(,%%QWGROUP%%,0775) quake/ktx/demos
@sample quake/ktx/ktx.cfg.sample
@sample quake/ktx/listip.cfg.sample
@sample quake/ktx/matchless.cfg.sample
@sample quake/ktx/mvdfinish.qws.sample
@sample quake/ktx/mvdsv.cfg.sample
@sample quake/ktx/port1.cfg.sample
@sample quake/ktx/port2.cfg.sample
@sample quake/ktx/port3.cfg.sample
@sample quake/ktx/problem.cfg.sample
quake/ktx/progs/bit.mdl
quake/ktx/progs/check.mdl
quake/ktx/progs/finish.mdl
quake/ktx/progs/flag.mdl
quake/ktx/progs/spawn.mdl
quake/ktx/progs/star.mdl
quake/ktx/progs/start.mdl
quake/ktx/progs/v_coil.mdl
quake/ktx/progs/v_star.mdl
quake/ktx/progs/vwplayer.mdl
quake/ktx/progs/w_axe.mdl
quake/ktx/progs/w_coil.mdl
quake/ktx/progs/w_light.mdl
quake/ktx/progs/w_nail.mdl
quake/ktx/progs/w_nail2.mdl
quake/ktx/progs/w_rock.mdl
quake/ktx/progs/w_rock2.mdl
quake/ktx/progs/w_shot.mdl
quake/ktx/progs/w_shot2.mdl
@sample(,%%QWGROUP%%,0640) quake/ktx/pwd.cfg.sample
quake/ktx/qwprogs.so
@dir(,%%QWGROUP%%,0775) quake/ktx/race
quake/ktx/race/routes/2bfree.route
quake/ktx/race/routes/aerowalk.route
quake/ktx/race/routes/bravado.route
quake/ktx/race/routes/catalyst.route
quake/ktx/race/routes/cmt3.route
quake/ktx/race/routes/dm1.route
quake/ktx/race/routes/dm2.route
quake/ktx/race/routes/dm3.route
quake/ktx/race/routes/dm4.route
quake/ktx/race/routes/dm5.route
quake/ktx/race/routes/dm6.route
quake/ktx/race/routes/dungeonsurf.route
quake/ktx/race/routes/e1m2.route
quake/ktx/race/routes/escape2a.route
quake/ktx/race/routes/hoppa2.route
quake/ktx/race/routes/jqdf1.route
quake/ktx/race/routes/jqdf3.route
quake/ktx/race/routes/monsoon.route
quake/ktx/race/routes/mvdsv-kg.route
quake/ktx/race/routes/q1q3toxicity.route
quake/ktx/race/routes/race1.route
quake/ktx/race/routes/race10.route
quake/ktx/race/routes/race2.route
quake/ktx/race/routes/race3.route
quake/ktx/race/routes/race4.route
quake/ktx/race/routes/race5.route
quake/ktx/race/routes/race6.route
quake/ktx/race/routes/race7.route
quake/ktx/race/routes/race8.route
quake/ktx/race/routes/race9.route
quake/ktx/race/routes/rampcity.route
quake/ktx/race/routes/rawspeed.route
quake/ktx/race/routes/rj3.route
quake/ktx/race/routes/shifter.route
quake/ktx/race/routes/slide1.route
quake/ktx/race/routes/slide2.route
quake/ktx/race/routes/slide3.route
quake/ktx/race/routes/slide4.route
quake/ktx/race/routes/slide5.route
quake/ktx/race/routes/slide6.route
quake/ktx/race/routes/slide7.route
quake/ktx/race/routes/slide8.route
quake/ktx/race/routes/slide9.route
quake/ktx/race/routes/slidefox.route
quake/ktx/race/routes/slstart.route
quake/ktx/race/routes/speedrush.route
quake/ktx/race/routes/subslide.route
quake/ktx/race/routes/toxicity_ql.route
quake/ktx/race/routes/toxicity_test.route
quake/ktx/race/routes/toxicity_test2.route
quake/ktx/race/routes/zjumps.route
quake/ktx/race/routes/ztndm3.route
quake/ktx/race/routes/ztricks.route
quake/ktx/race/routes/ztricks2.route
@sample quake/ktx/server.cfg.sample
quake/ktx/sound/misc/flagcap.wav
quake/ktx/sound/misc/flagtk.wav
quake/ktx/sound/ra/1.wav
quake/ktx/sound/ra/2.wav
quake/ktx/sound/ra/3.wav
quake/ktx/sound/ra/excelent.wav
quake/ktx/sound/ra/fight.wav
quake/ktx/sound/ra/flawless.wav
quake/ktx/sound/rune/rune1.wav
quake/ktx/sound/rune/rune2.wav
quake/ktx/sound/rune/rune22.wav
quake/ktx/sound/rune/rune3.wav
quake/ktx/sound/rune/rune4.wav
quake/ktx/sound/weapons/bounce2.wav
quake/ktx/sound/weapons/chain1.wav
quake/ktx/sound/weapons/chain2.wav
quake/ktx/sound/weapons/chain3.wav
quake/ktx/sound/weapons/coilgun.wav
@sample quake/ktx/vip_ip.cfg.sample
@sample quake/port1.sample
@sample quake/port2.sample
@sample quake/port3.sample
@sample quake/portffa.sample
@sample quake/servers.sample
quake/qw/maps/arena3.ent
quake/qw/maps/arena5.ent
quake/qw/maps/barrel.ent
quake/qw/maps/bloodfest.ent
quake/qw/maps/ctf/dm1.ent
quake/qw/maps/ctf/dm2.ent
quake/qw/maps/ctf/dm3.ent
quake/qw/maps/ctf/dm4.ent
quake/qw/maps/ctf/dm5.ent
quake/qw/maps/ctf/dm6.ent
quake/qw/maps/ctf/e1m1.ent
quake/qw/maps/ctf/e1m2.ent
quake/qw/maps/ctf/e1m3.ent
quake/qw/maps/ctf/e1m4.ent
quake/qw/maps/ctf/e1m5.ent
quake/qw/maps/ctf/e1m6.ent
quake/qw/maps/ctf/e1m7.ent
quake/qw/maps/ctf/e1m8.ent
quake/qw/maps/ctf/e2m1.ent
quake/qw/maps/ctf/e2m2.ent
quake/qw/maps/ctf/e2m3.ent
quake/qw/maps/ctf/e2m4.ent
quake/qw/maps/ctf/e2m5.ent
quake/qw/maps/ctf/e2m6.ent
quake/qw/maps/ctf/e2m7.ent
quake/qw/maps/ctf/e3m1.ent
quake/qw/maps/ctf/e3m2.ent
quake/qw/maps/ctf/e3m3.ent
quake/qw/maps/ctf/e3m4.ent
quake/qw/maps/ctf/e3m5.ent
quake/qw/maps/ctf/e3m6.ent
quake/qw/maps/ctf/e3m7.ent
quake/qw/maps/ctf/e4m1.ent
quake/qw/maps/ctf/e4m2.ent
quake/qw/maps/ctf/e4m3.ent
quake/qw/maps/ctf/e4m4.ent
quake/qw/maps/ctf/e4m5.ent
quake/qw/maps/ctf/e4m6.ent
quake/qw/maps/ctf/e4m7.ent
quake/qw/maps/ctf/e4m8.ent
quake/qw/maps/ctf/fcast.ent
quake/qw/maps/death6.ent
quake/qw/maps/dm4ish.ent
quake/qw/maps/e1m7.ent
quake/qw/maps/fragyard.ent
quake/qw/maps/genocide.ent
quake/qw/maps/hohoho.ent
quake/qw/maps/kenya.ent
quake/qw/maps/pillar.ent
quake/qw/maps/q1dm17.ent
quake/qw/maps/rz1pondb.ent
quake/qw/maps/slaug.ent