diff options
| author | Vladimir Druzenko <vvd@FreeBSD.org> | 2025-02-22 02:24:12 +0000 |
|---|---|---|
| committer | Vladimir Druzenko <vvd@FreeBSD.org> | 2025-02-22 02:24:12 +0000 |
| commit | 6bb96dba53ce7ddf66061facefa348cbd0f27022 (patch) | |
| tree | d5f3fd23a5c8570ab32653aacc1d161879524a9b | |
| parent | dfd3a8bb3f2155fcd512e296787d4736162a82d0 (diff) | |
games/ktx: New port: Kombat Teams eXtreme is a popular QuakeWorld server modification
| -rw-r--r-- | GIDs | 2 | ||||
| -rw-r--r-- | UIDs | 2 | ||||
| -rw-r--r-- | games/Makefile | 1 | ||||
| -rw-r--r-- | games/ktx/Makefile | 63 | ||||
| -rw-r--r-- | games/ktx/distinfo | 3 | ||||
| -rwxr-xr-x | games/ktx/files/ktx.in | 130 | ||||
| -rw-r--r-- | games/ktx/files/patch-resources_example-configs_ktx_configs_usermodes_matchless_default.cfg | 45 | ||||
| -rw-r--r-- | games/ktx/files/patch-socd | 192 | ||||
| -rw-r--r-- | games/ktx/pkg-descr | 7 | ||||
| -rw-r--r-- | games/ktx/pkg-message | 17 | ||||
| -rw-r--r-- | games/ktx/pkg-plist | 282 |
11 files changed, 742 insertions, 2 deletions
@@ -440,7 +440,7 @@ openbao:*:482: # free: 497 rustypaste:*:498: # free: 499 -# free: 500 +qw:*:500: qwfwd:*:501: birdvty:*:502: # free: 503 @@ -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 diff --git a/games/Makefile b/games/Makefile index 9afad89bf7e0..a4086e1704cd 100644 --- a/games/Makefile +++ b/games/Makefile @@ -475,6 +475,7 @@ SUBDIR += ksquares SUBDIR += ksudoku SUBDIR += ktuberling + SUBDIR += ktx SUBDIR += kubrick SUBDIR += kuklomenos SUBDIR += ladder diff --git a/games/ktx/Makefile b/games/ktx/Makefile new file mode 100644 index 000000000000..3f6c877e06dc --- /dev/null +++ b/games/ktx/Makefile @@ -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> diff --git a/games/ktx/distinfo b/games/ktx/distinfo new file mode 100644 index 000000000000..ea3c5fe117e3 --- /dev/null +++ b/games/ktx/distinfo @@ -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 diff --git a/games/ktx/files/ktx.in b/games/ktx/files/ktx.in new file mode 100755 index 000000000000..3e6e3075cc92 --- /dev/null +++ b/games/ktx/files/ktx.in @@ -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" diff --git a/games/ktx/files/patch-resources_example-configs_ktx_configs_usermodes_matchless_default.cfg b/games/ktx/files/patch-resources_example-configs_ktx_configs_usermodes_matchless_default.cfg new file mode 100644 index 000000000000..f10298dabc00 --- /dev/null +++ b/games/ktx/files/patch-resources_example-configs_ktx_configs_usermodes_matchless_default.cfg @@ -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) diff --git a/games/ktx/files/patch-socd b/games/ktx/files/patch-socd new file mode 100644 index 000000000000..03e80334b71e --- /dev/null +++ b/games/ktx/files/patch-socd @@ -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"); + // } diff --git a/games/ktx/pkg-descr b/games/ktx/pkg-descr new file mode 100644 index 000000000000..2a698696b7c8 --- /dev/null +++ b/games/ktx/pkg-descr @@ -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. diff --git a/games/ktx/pkg-message b/games/ktx/pkg-message new file mode 100644 index 000000000000..112a2b8c3e04 --- /dev/null +++ b/games/ktx/pkg-message @@ -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 +} +] diff --git a/games/ktx/pkg-plist b/games/ktx/pkg-plist new file mode 100644 index 000000000000..883706a66600 --- /dev/null +++ b/games/ktx/pkg-plist @@ -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 |
