116 Commits
Author SHA1 Message Date
github-actions[bot] dfc51aa0ec chore: rebuild website roadmap [skip ci] 2026-07-21 00:50:04 +00:00
github-actions[bot] 7e0e338159 chore: rebuild website roadmap [skip ci] 2026-07-21 00:49:44 +00:00
Marc Froehlich 303bb21bd1 Updated preferences functionality and texts 2026-07-21 00:36:34 +02:00
Marc Froehlich 58341902f7 added pstrotator options and fixed some ui stuff 2026-07-21 00:26:14 +02:00
Marc Froehlich f3a1a73231 host key validation fix on AUR package 2026-07-21 00:05:09 +02:00
github-actions[bot] 590ac608cd chore: rebuild website [skip ci] 2026-07-20 21:59:07 +00:00
Marc Froehlich 039e64eea0 website-manual download refactored 2026-07-20 23:58:47 +02:00
Marc Froehlich 0b6120defc another AUR build fix 2026-07-20 23:56:14 +02:00
github-actions[bot] 756f65e825 chore: rebuild website [skip ci] 2026-07-20 21:49:55 +00:00
Marc Froehlich 1de8b77c52 Repaired picture displaying at the website 2026-07-20 23:49:26 +02:00
github-actions[bot] 6b15b98c12 chore: rebuild website [skip ci] 2026-07-20 21:40:39 +00:00
Marc Froehlich b0c04d2238 Installation manual refactoring 2026-07-20 23:40:16 +02:00
Marc Froehlich 01a2d95a8a AUR build fix 2026-07-20 23:24:44 +02:00
github-actions[bot] db844ef4f7 chore: rebuild website [skip ci] 2026-07-20 21:18:32 +00:00
Marc Froehlich 8ee9d59d7a manual refactoring + versioninfo xml refactoring 2026-07-20 23:18:13 +02:00
github-actions[bot] e7631ef688 chore: rebuild website [skip ci] 2026-07-20 21:02:13 +00:00
Marc Froehlich 08dff3e60d manual refactoring + versioninfo xml refactoring 2026-07-20 23:01:53 +02:00
github-actions[bot] b6214fb893 chore: rebuild website [skip ci] 2026-07-20 20:34:49 +00:00
Marc Froehlich 823af70caa manual refactoring 2026-07-20 22:34:31 +02:00
Marc Froehlich 334e5b03a8 manual refactoring 2026-07-20 22:27:53 +02:00
github-actions[bot] 273becf793 chore: rebuild website roadmap [skip ci] 2026-07-16 21:58:51 +00:00
github-actions[bot] 32e28f8797 chore: rebuild website roadmap [skip ci] 2026-07-16 21:58:31 +00:00
github-actions[bot] b3ff39a365 chore: rebuild website roadmap [skip ci] 2026-07-16 21:47:10 +00:00
github-actions[bot] 84ac5eb479 chore: rebuild website roadmap [skip ci] 2026-07-16 21:46:53 +00:00
github-actions[bot] 31bc42982d chore: rebuild website [skip ci] 2026-07-14 23:12:55 +00:00
Rsclub2_2 7acdfca4f5 Fix AUR not liking the .git links 2026-07-15 01:12:37 +02:00
github-actions[bot] c3fd931fee chore: rebuild website [skip ci] 2026-07-14 23:08:56 +00:00
Rsclub2_2 373a30933b News about AUR Packages 2026-07-15 01:08:27 +02:00
github-actions[bot] 43538a277f chore: rebuild website roadmap [skip ci] 2026-07-14 17:29:04 +00:00
github-actions[bot] 5ec16fa458 chore: rebuild website roadmap [skip ci] 2026-07-14 17:28:46 +00:00
github-actions[bot] 9ef0aeef1c chore: rebuild website roadmap [skip ci] 2026-07-14 17:28:29 +00:00
Rsclub2_2 46d722967a fix and Pipeline AUR nightly 2026-07-14 17:19:29 +02:00
Rsclub2_2 fc246a5607 Pipeline AUR 2026-07-14 17:04:29 +02:00
github-actions[bot] 8cdeb2ad63 chore: rebuild website [skip ci] 2026-07-14 14:54:47 +00:00
Rsclub2_2 df0e535fb3 docs: add AUR installation instructions to Wiki 2026-07-14 16:54:19 +02:00
Rsclub2_2 e85d4c2fe2 fix: revert AUR url back to GitHub upstream [skip ci] 2026-07-14 16:47:18 +02:00
Rsclub2_2 360e55633b chore: set AUR package url to kst4contest.hamradioonline.de [skip ci] 2026-07-14 16:43:36 +02:00
Rsclub2_2 367967518e chore: fix kst4contest-git pkgver to 1.42.0 base [skip ci] 2026-07-14 16:41:33 +02:00
github-actions[bot] d8859247c6 chore: update AUR packages to v1.41.1 [skip ci] 2026-07-14 11:35:24 +00:00
github-actions[bot] bf1b72a6b9 chore: rebuild website roadmap [skip ci] 2026-07-13 18:35:32 +00:00
github-actions[bot] 9545e708fd chore: rebuild website roadmap [skip ci] 2026-07-13 18:35:16 +00:00
github-actions[bot] 37121949e4 chore: rebuild website roadmap [skip ci] 2026-07-13 18:22:24 +00:00
github-actions[bot] d70d8d7a24 chore: rebuild website roadmap [skip ci] 2026-07-13 18:20:50 +00:00
github-actions[bot] 6a715567dd chore: rebuild website roadmap [skip ci] 2026-07-13 18:20:37 +00:00
github-actions[bot] a5f96324e6 chore: rebuild website [skip ci] 2026-07-12 22:31:40 +00:00
Marc Froehlich a3e9581c4b modify interactive aircraft scatter hero effect 2026-07-13 00:31:18 +02:00
github-actions[bot] 3285960ee3 chore: rebuild website [skip ci] 2026-07-12 22:27:20 +00:00
Marc Froehlich d532f935d6 modify interactive aircraft scatter hero effect 2026-07-13 00:26:51 +02:00
github-actions[bot] 3988a6d456 chore: rebuild website [skip ci] 2026-07-12 21:52:34 +00:00
Marc Froehlich 598be64306 modify interactive aircraft scatter hero effect 2026-07-12 23:52:11 +02:00
github-actions[bot] 7fcea718ec chore: rebuild website [skip ci] 2026-07-12 21:23:10 +00:00
praktimarc fd7d0a6807 Bugfix/51 selectionmodel fix (#60)
* bugfix for #51. ManagebusManagementThread now never accesses or changes the JAVAFX view-backing ObservableList but using a concurrenthasmap which drives the Tableview backing list with snapshots

* Extending work at #51 for not adding users on UM3 message

* Add interactive aircraft scatter hero effect
2026-07-12 23:22:53 +02:00
github-actions[bot] e424b44cb2 chore: rebuild website [skip ci] 2026-07-11 21:21:26 +00:00
Marc Froehlich dc703fca9e Changes at the website 2026-07-11 23:21:02 +02:00
Marc Froehlich 77c9d34d64 Introduced clustering in the map 2026-07-10 00:30:15 +02:00
github-actions[bot] efd6ed6299 chore: rebuild website roadmap [skip ci] 2026-07-09 21:24:39 +00:00
github-actions[bot] de8e8ba471 chore: rebuild website roadmap [skip ci] 2026-07-09 21:24:26 +00:00
github-actions[bot] eaf611b203 chore: rebuild website roadmap [skip ci] 2026-07-09 16:48:10 +00:00
Rsclub2_2 e339b6fccf implement #49 2026-07-09 18:47:29 +02:00
github-actions[bot] bd9b42d4a5 chore: rebuild website roadmap [skip ci] 2026-07-09 16:46:38 +00:00
github-actions[bot] 275ce48769 chore: rebuild website [skip ci] 2026-07-09 14:12:59 +00:00
Rsclub2_2 d201997587 added automatic Changelog XML to new Website.
also now the XML gets pulled from new Website
2026-07-09 16:12:29 +02:00
github-actions[bot] 250290a1eb chore: rebuild website [skip ci] 2026-07-08 23:14:29 +00:00
Rsclub2_2 052cfea7ad News about Hotfix 2026-07-09 01:14:13 +02:00
github-actions[bot] d930b57196 chore: rebuild website roadmap [skip ci] 2026-07-08 23:03:34 +00:00
github-actions[bot] eb29d56f4e chore: rebuild website roadmap [skip ci] 2026-07-08 23:03:13 +00:00
github-actions[bot] eb2a7f88a4 chore: rebuild website roadmap [skip ci] 2026-07-08 23:02:52 +00:00
github-actions[bot] 8c3e4c15af chore: rebuild website roadmap [skip ci] 2026-07-08 21:55:02 +00:00
github-actions[bot] c8b1f97872 chore: rebuild website roadmap [skip ci] 2026-07-08 21:07:12 +00:00
github-actions[bot] b47fd21dd0 chore: rebuild website roadmap [skip ci] 2026-07-08 21:06:59 +00:00
github-actions[bot] f009ed4b3d chore: rebuild website roadmap [skip ci] 2026-07-08 20:48:02 +00:00
Rsclub2_2 47126f4ae1 Push website rebuild commits via deploy key instead of GITHUB_TOKEN 2026-07-08 22:44:39 +02:00
7d3177ba8a Add selected-band activity indicator for stations in map and details (#53)
* Initial plan

* Add map indicator for selected-band activity hints

* Add selected-band marker to main station table

* Move band-offer star from callsign to worked status cell

* Move band-offer star from wkdany column to per-band worked cells

Fixes a bad merge that had nested a method definition inside another
method (broke compilation), and relocates the new-band-opportunity
star so it appears on the specific band cell it applies to instead of
a single generic wkdany column, since a station can offer several
bands at once.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Changed Indicator to B+ instead of star for better understandability

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Philipp Wagner <philipp@wagnersnetz.de>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-08 22:32:54 +02:00
Rsclub2_2 ff71623b90 Website: Version Dynamic and Roadmap Padding 2026-07-08 22:03:38 +02:00
Rsclub2_2 ead985a741 Website Build with Roadmap. 2026-07-08 21:35:15 +02:00
Rsclub2_2 ef1eeeed36 Bump version to 1.42 now that v1.41.1 hotfix is tagged and released 2026-07-08 21:27:30 +02:00
Rsclub2_2 4a34e28a84 fix Problems with sendfield again #56 2026-07-08 21:09:02 +02:00
Rsclub2_2 38ef50cee8 Revert version bump to 1.42, set to 1.41.1 for upcoming hotfix 2026-07-08 20:52:58 +02:00
Marc Froehlich d45a637d00 Fixed symbol of the show on map -button 2026-07-08 20:35:13 +02:00
Marc Froehlich 1ec2b1a450 Prevent periodic ChatMember refreshes from overwriting manually typed send text, while keeping /cq auto-fill for real user selections. Also ensure /cq messages are sent in the correct chat category and improve text/QTF/QRB filter behavior. 2026-07-08 20:26:44 +02:00
Marc Froehlich 19e8cff6b6 Fix send input selection handling 2026-07-08 20:15:49 +02:00
Rsclub2_2 62999cfed8 Update Nightly Pipeline to run less often, to not put to much stress on Servers 2026-07-07 17:08:13 +02:00
Rsclub2_2 49524146e8 Changed to direct to people to the new Website 2026-07-07 17:01:29 +02:00
Rsclub2_2 dd2ac3bc69 Remove Node_modules as not needed vendored
also changed few Things about Website
2026-07-07 14:05:47 +02:00
Marc Froehlich 098dd31b58 Add legal, privacy, contact and roadmap pages 2026-07-07 01:46:33 +02:00
Marc Froehlich 8ecbf7dfa0 Add legal, privacy, contact and roadmap pages 2026-07-07 01:41:28 +02:00
Marc Froehlich 1b30de34cc Improve download page guidance 2026-07-07 01:24:35 +02:00
Marc Froehlich 65b2e561f4 Add social preview metadata 2026-07-07 01:14:19 +02:00
Marc Froehlich 6907af5c81 Add structured data to feature pages 2026-07-07 01:10:36 +02:00
Marc Froehlich 59b8e2fbbb Improve XML sitemap metadata 2026-07-07 01:07:02 +02:00
Marc Froehlich 5838d3a999 Add RSS feed for news 2026-07-07 01:03:11 +02:00
Marc Froehlich 6d1e08711a Add Markdown-based news content model 2026-07-07 00:51:36 +02:00
Marc Froehlich 67b91a766a Add cache busting for website assets 2026-07-07 00:43:12 +02:00
Marc Froehlich f83cdbd804 Improve cross-browser visual design 2026-07-07 00:36:46 +02:00
Marc Froehlich 9359568a33 Add ordered and featured feature collections 2026-07-07 00:23:45 +02:00
Marc Froehlich 8f46909ebf Add ordered and featured feature collections 2026-07-07 00:12:20 +02:00
Marc Froehlich 59638f6ab3 Move features to Markdown content model 2026-07-07 00:06:47 +02:00
Marc Froehlich 59aade8004 Move features to Markdown content model 2026-07-07 00:01:59 +02:00
Marc Froehlich 42255e2b41 Add direct download links for release assets 2026-07-06 23:33:54 +02:00
Marc Froehlich 217c7e8451 Refactor website into data-driven content model 2026-07-06 23:27:06 +02:00
Marc Froehlich a99d611ea8 Introduce feature content model 2026-07-06 23:03:17 +02:00
Marc Froehlich 7b0c86a5a0 Rewrite manual links for website output 2026-07-06 03:11:22 +02:00
Marc Froehlich 1bd338c7ee Rename website workflow to build-only 2026-07-06 03:05:47 +02:00
Marc Froehlich dfe5e28877 Generate manual overviews from github_docs 2026-07-06 03:02:49 +02:00
Marc Froehlich 248a7c0462 Improve manual landing pages 2026-07-06 03:00:18 +02:00
Marc Froehlich db83d6a9df Improve manual landing pages 2026-07-06 02:49:46 +02:00
Marc Froehlich 006ee7b060 Add FAQ page with structured data 2026-07-06 02:45:44 +02:00
Marc Froehlich 8ae8c9996f Add screenshots and news pages 2026-07-06 02:42:18 +02:00
Marc Froehlich 9d6b2536dd Add SEO feature detail pages 2026-07-06 02:35:46 +02:00
Marc Froehlich 4d903f5344 Add initial feature pages 2026-07-06 02:25:51 +02:00
Marc Froehlich 34c1c68943 Add SEO metadata, robots and sitemap 2026-07-06 02:19:28 +02:00
Marc Froehlich f48b72c54e Change website workflow to build-only 2026-07-06 02:02:47 +02:00
Marc Froehlich 413f69eb6a Add manual and download pages to website 2026-07-06 01:28:20 +02:00
Marc Froehlich 69fe6dc7b1 Add 11ty website deployment workflow 2026-07-06 01:22:31 +02:00
Marc Froehlich 80214bf42d Add initial 11ty website structure 2026-07-06 01:04:53 +02:00
Rsclub2_2 62b6bbdcbc next Version 1.42 2026-07-02 14:15:36 +02:00
153 changed files with 23138 additions and 1648 deletions
+155
View File
@@ -0,0 +1,155 @@
name: AUR Nightly (kst4contest-git)
on:
workflow_run:
workflows: ["Nightly Runtime Artifacts"]
types: [completed]
workflow_dispatch:
permissions:
contents: read
env:
AUR_SSH_DIR: /tmp/aur-ssh
jobs:
update-aur-git:
if: >-
github.event_name == 'workflow_dispatch' ||
github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
container:
image: archlinux:latest
steps:
- name: Install dependencies
run: |
pacman -Sy --noconfirm git openssh base-devel
useradd -m builder
- name: Checkout repository
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Mark workspace as safe Git directory
run: |
git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Compute pkgver
id: ver
run: |
BASE=$(grep -m1 '<version>' pom.xml \
| sed 's/.*<version>\(.*\)<\/version>.*/\1/' \
| sed 's/[-.]nightly//')
GIT_PKGVER="${BASE}.r$(git rev-list --count HEAD).g$(git rev-parse --short HEAD)"
echo "Computed pkgver: ${GIT_PKGVER}"
echo "pkgver=${GIT_PKGVER}" >> "$GITHUB_OUTPUT"
- name: Update PKGBUILD
env:
PKGVER: ${{ steps.ver.outputs.pkgver }}
run: |
sed -i "s/^pkgver=.*/pkgver=${PKGVER}/" \
packaging/aur/kst4contest-git/PKGBUILD
- name: Generate .SRCINFO
run: |
cp -r packaging/aur/kst4contest-git /tmp/kst4contest-git
chown -R builder:builder /tmp/kst4contest-git
su builder -c \
"cd /tmp/kst4contest-git && makepkg --printsrcinfo > .SRCINFO"
cp /tmp/kst4contest-git/.SRCINFO \
packaging/aur/kst4contest-git/.SRCINFO
echo "Generated .SRCINFO:"
cat packaging/aur/kst4contest-git/.SRCINFO
- name: Set up and verify AUR SSH
env:
AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
run: |
mkdir -p "${AUR_SSH_DIR}"
printf '%s\n' "${AUR_SSH_PRIVATE_KEY}" \
> "${AUR_SSH_DIR}/aur_ed25519"
sed -i 's/\r$//' "${AUR_SSH_DIR}/aur_ed25519"
chmod 600 "${AUR_SSH_DIR}/aur_ed25519"
ssh-keygen -y \
-f "${AUR_SSH_DIR}/aur_ed25519" \
> /dev/null
ssh-keyscan \
-T 10 \
-t ed25519 \
aur.archlinux.org \
> "${AUR_SSH_DIR}/known_hosts"
if [ ! -s "${AUR_SSH_DIR}/known_hosts" ]; then
echo "::error::No SSH host key was received from aur.archlinux.org."
exit 1
fi
echo "Received AUR host-key fingerprint:"
ssh-keygen -lf "${AUR_SSH_DIR}/known_hosts"
if ! ssh-keygen -lf "${AUR_SSH_DIR}/known_hosts" \
| grep -Fq "SHA256:RFzBCUItH9LZS0cKB5UE6ceAYhBD5C8GeOBip8Z11+4"; then
echo "::error::The AUR SSH host-key fingerprint does not match the official fingerprint."
exit 1
fi
printf '%s\n' \
"Host aur.archlinux.org" \
" HostName aur.archlinux.org" \
" User aur" \
" IdentityFile ${AUR_SSH_DIR}/aur_ed25519" \
" IdentitiesOnly yes" \
" StrictHostKeyChecking yes" \
" UserKnownHostsFile ${AUR_SSH_DIR}/known_hosts" \
> "${AUR_SSH_DIR}/config"
chmod 600 "${AUR_SSH_DIR}/config"
chmod 600 "${AUR_SSH_DIR}/known_hosts"
- name: Push package metadata to AUR
env:
GIT_SSH_COMMAND: ssh -F /tmp/aur-ssh/config
run: |
git config --global user.email "philipp@wagnersnetz.de"
git config --global user.name "Philipp Wagner"
AUR_DIR="/tmp/aur/kst4contest-git"
mkdir -p "$(dirname "${AUR_DIR}")"
git -c init.defaultBranch=master clone \
"ssh://aur@aur.archlinux.org/kst4contest-git.git" \
"${AUR_DIR}"
cp packaging/aur/kst4contest-git/PKGBUILD \
"${AUR_DIR}/PKGBUILD"
cp packaging/aur/kst4contest-git/.SRCINFO \
"${AUR_DIR}/.SRCINFO"
git -C "${AUR_DIR}" add PKGBUILD .SRCINFO
if git -C "${AUR_DIR}" diff --cached --quiet; then
echo "kst4contest-git: package metadata is already current."
else
git -C "${AUR_DIR}" commit \
-m "Update pkgver to ${{ steps.ver.outputs.pkgver }}"
git -C "${AUR_DIR}" push origin HEAD:master
echo "kst4contest-git: successfully pushed to AUR."
fi
+177
View File
@@ -0,0 +1,177 @@
name: Publish AUR Packages
on:
workflow_run:
workflows: ["Tagged Release Build"]
types: [completed]
workflow_dispatch:
inputs:
version:
description: "Release tag (e.g. v1.41.1) — defaults to latest stable release"
required: false
default: ""
dry_run:
description: "Dry run — skip AUR push and repo commit (for testing)"
type: choice
options: ["false", "true"]
default: "false"
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs:
publish-aur:
if: >-
github.event_name == 'workflow_dispatch' ||
github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
container:
image: archlinux:latest
steps:
- name: Install dependencies
run: |
pacman -Sy --noconfirm git openssh curl base-devel nodejs
useradd -m builder
- name: Checkout
uses: actions/checkout@v4.1.7
with:
fetch-depth: 0
- name: Resolve release version
id: ver
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
INPUT_VERSION: ${{ inputs.version }}
run: |
if [[ -n "${INPUT_VERSION}" ]]; then
TAG="${INPUT_VERSION}"
else
TAG=$(curl -sf \
-H "Authorization: Bearer ${GH_TOKEN}" \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/${{ github.repository }}/releases/latest" \
| grep '"tag_name"' | sed 's/.*"tag_name": *"\([^"]*\)".*/\1/')
fi
PKGVER="${TAG#v}"
echo "tag=${TAG} → pkgver=${PKGVER}"
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
echo "pkgver=${PKGVER}" >> "$GITHUB_OUTPUT"
- name: Compute SHA256 checksums
id: sha
run: |
TAG="${{ steps.ver.outputs.tag }}"
REPO="${{ github.repository }}"
echo "Hashing pre-built Arch package..."
SHA_BIN=$(curl -sfL \
"https://github.com/${REPO}/releases/download/${TAG}/KST4Contest-${TAG}-archlinux-x86_64.pkg.tar.zst" \
| sha256sum | awk '{print $1}')
echo "bin: ${SHA_BIN}"
echo "Hashing source tarball..."
SHA_SRC=$(curl -sfL \
"https://github.com/${REPO}/archive/refs/tags/${TAG}.tar.gz" \
| sha256sum | awk '{print $1}')
echo "src: ${SHA_SRC}"
echo "bin=${SHA_BIN}" >> "$GITHUB_OUTPUT"
echo "src=${SHA_SRC}" >> "$GITHUB_OUTPUT"
- name: Update PKGBUILDs
env:
PKGVER: ${{ steps.ver.outputs.pkgver }}
SHA_BIN: ${{ steps.sha.outputs.bin }}
SHA_SRC: ${{ steps.sha.outputs.src }}
run: |
# kst4contest-bin
sed -i "s/^pkgver=.*/pkgver=${PKGVER}/" packaging/aur/kst4contest-bin/PKGBUILD
sed -i "s/^sha256sums=.*/sha256sums=('${SHA_BIN}')/" packaging/aur/kst4contest-bin/PKGBUILD
# kst4contest (source build)
sed -i "s/^pkgver=.*/pkgver=${PKGVER}/" packaging/aur/kst4contest/PKGBUILD
sed -i "s/^sha256sums=.*/sha256sums=('${SHA_SRC}')/" packaging/aur/kst4contest/PKGBUILD
# kst4contest-git: Basis aus pom.xml, Suffix aus git
BASE_VER=$(grep -m1 '<version>' pom.xml \
| sed 's/.*<version>\(.*\)<\/version>.*/\1/' | sed 's/[-.]nightly//')
GIT_PKGVER="${BASE_VER}.r$(git rev-list --count HEAD).g$(git rev-parse --short HEAD)"
sed -i "s/^pkgver=.*/pkgver=${GIT_PKGVER}/" packaging/aur/kst4contest-git/PKGBUILD
echo "=== Updated PKGBUILD versions ==="
grep -H '^pkgver=\|^sha256sums=' packaging/aur/*/PKGBUILD
- name: Generate .SRCINFO files
run: |
for pkg in kst4contest-bin kst4contest kst4contest-git; do
cp -r "packaging/aur/${pkg}" "/tmp/${pkg}"
chown -R builder:builder "/tmp/${pkg}"
su builder -c "cd /tmp/${pkg} && makepkg --printsrcinfo > .SRCINFO"
cp "/tmp/${pkg}/.SRCINFO" "packaging/aur/${pkg}/.SRCINFO"
echo "=== ${pkg}/.SRCINFO ==="
cat "packaging/aur/${pkg}/.SRCINFO"
done
- name: Commit updated PKGBUILDs to repo
if: inputs.dry_run != 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config user.name "github-actions[bot]"
git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@github.com/${{ github.repository }}.git"
git add packaging/aur/
git diff --cached --quiet && echo "No PKGBUILD changes to commit." && exit 0
git commit -m "chore: update AUR packages to ${{ steps.ver.outputs.tag }} [skip ci]"
git push
- name: Set up AUR SSH
if: inputs.dry_run != 'true'
env:
AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
run: |
mkdir -p ~/.ssh
printf '%s\n' "${AUR_SSH_PRIVATE_KEY}" > ~/.ssh/aur_ed25519
chmod 600 ~/.ssh/aur_ed25519
ssh-keyscan -t ed25519 aur.archlinux.org >> ~/.ssh/known_hosts
cat >> ~/.ssh/config << 'EOF'
Host aur.archlinux.org
IdentityFile ~/.ssh/aur_ed25519
User aur
EOF
- name: Push to AUR
if: inputs.dry_run != 'true'
env:
TAG: ${{ steps.ver.outputs.tag }}
run: |
git config --global user.email "philipp@wagnersnetz.de"
git config --global user.name "Philipp Wagner"
push_to_aur() {
local pkg="$1"
local msg="$2"
local aur_dir="/tmp/aur/${pkg}"
git clone "ssh://aur@aur.archlinux.org/${pkg}.git" "${aur_dir}" 2>/dev/null || {
mkdir -p "${aur_dir}"
git -C "${aur_dir}" init
git -C "${aur_dir}" remote add origin "ssh://aur@aur.archlinux.org/${pkg}.git"
}
cp "packaging/aur/${pkg}/PKGBUILD" "${aur_dir}/"
cp "packaging/aur/${pkg}/.SRCINFO" "${aur_dir}/"
git -C "${aur_dir}" add PKGBUILD .SRCINFO
git -C "${aur_dir}" diff --cached --quiet \
&& echo "${pkg}: no changes, skipping push" && return 0
git -C "${aur_dir}" commit -m "${msg}"
git -C "${aur_dir}" push origin HEAD:master
echo "${pkg}: pushed to AUR"
}
push_to_aur kst4contest-bin "Update to ${TAG}"
push_to_aur kst4contest "Update to ${TAG}"
push_to_aur kst4contest-git \
"Update pkgver to $(grep '^pkgver=' packaging/aur/kst4contest-git/PKGBUILD | cut -d= -f2)"
+6 -2
View File
@@ -4,8 +4,12 @@ on:
push:
branches:
- main
schedule:
- cron: "20 2 * * *"
paths:
- "src/**"
- "pom.xml"
- "mvnw"
- "mvnw.cmd"
- ".github/workflows/nightly-artifacts.yml"
workflow_dispatch:
env:
+6 -4
View File
@@ -435,12 +435,14 @@ jobs:
FLATPAK_GPG_KEY_ID=$(gpg --list-secret-keys --with-colons | awk -F: '/^fpr/{print $10; exit}')
echo "FLATPAK_GPG_KEY_ID=$FLATPAK_GPG_KEY_ID" >> "$GITHUB_ENV"
- name: Determine OSTree branch
- name: Determine OSTree branch and flatpakref filename
run: |
if [[ "${{ github.ref_name }}" == beta-* ]]; then
echo "OSTREE_BRANCH=beta" >> "$GITHUB_ENV"
echo "FLATPAKREF_NAME=de.x08.KST4Contest.beta.flatpakref" >> "$GITHUB_ENV"
else
echo "OSTREE_BRANCH=stable" >> "$GITHUB_ENV"
echo "FLATPAKREF_NAME=de.x08.KST4Contest.flatpakref" >> "$GITHUB_ENV"
fi
- name: Build Flatpak repo
@@ -454,7 +456,7 @@ jobs:
REPO_NAME="${GITHUB_REPOSITORY#*/}"
PAGES_URL="https://${GITHUB_REPOSITORY_OWNER}.github.io/${REPO_NAME}/"
GPG_KEY_B64=$(gpg --export "$FLATPAK_GPG_KEY_ID" | base64 -w 0)
cat > "dist/de.x08.KST4Contest.${OSTREE_BRANCH}.flatpakref" << EOF
cat > "dist/${FLATPAKREF_NAME}" << EOF
[Flatpak Ref]
Name=de.x08.KST4Contest
Branch=${OSTREE_BRANCH}
@@ -469,7 +471,7 @@ jobs:
uses: actions/upload-artifact@v4.3.4
with:
name: flatpakref
path: dist/de.x08.KST4Contest.*.flatpakref
path: dist/*.flatpakref
- name: Upload Flatpak OSTree repo
uses: actions/upload-artifact@v4.3.4
@@ -747,7 +749,7 @@ jobs:
release-assets/debian/KST4Contest-${{ github.ref_name }}-debian-amd64.deb,
release-assets/fedora/KST4Contest-${{ github.ref_name }}-fedora-x86_64.rpm,
release-assets/archlinux/KST4Contest-${{ github.ref_name }}-archlinux-*.pkg.tar.zst,
release-assets/flatpakref/de.x08.KST4Contest.flatpakref,
release-assets/flatpakref/*.flatpakref,
release-assets/macos/KST4Contest-${{ github.ref_name }}-macos-*.dmg,
release-assets/docs/KST4Contest-${{ github.ref_name }}-manual-en.pdf,
release-assets/docs/KST4Contest-${{ github.ref_name }}-manual-de.pdf
+76
View File
@@ -0,0 +1,76 @@
name: Build Website
on:
push:
branches:
- main
paths:
- website/**
- github_docs/**
- .github/workflows/website-build.yml
pull_request:
branches:
- main
paths:
- website/**
- github_docs/**
- .github/workflows/website-build.yml
workflow_dispatch:
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
concurrency:
group: website-build-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
permissions:
contents: read
jobs:
build-website:
name: Build 11ty Website
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4.1.7
with:
ssh-key: ${{ secrets.WEBSITE_DEPLOY_KEY }}
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "24"
cache: npm
cache-dependency-path: website/package-lock.json
- name: Install dependencies
working-directory: website
run: npm ci
- name: Build website
working-directory: website
run: npm run build
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload website artifact
uses: actions/upload-artifact@v4.3.4
with:
name: kst4contest-website
path: website/_site/
retention-days: 7
- name: Commit rebuilt site
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add website/_site
if git diff --cached --quiet; then
echo "No changes to commit"
else
git commit -m "chore: rebuild website [skip ci]"
git push
fi
@@ -0,0 +1,59 @@
name: Rebuild Roadmap
on:
issues:
types: [opened, edited, closed, reopened, labeled, unlabeled, milestoned, demilestoned]
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
concurrency:
group: website-build-${{ github.ref }}
cancel-in-progress: false
permissions:
contents: read
jobs:
rebuild-roadmap:
name: Rebuild website roadmap
runs-on: ubuntu-latest
# Only worth a rebuild if the "enhancement" label is involved: either the
# issue currently carries it, or this event just added/removed it.
if: contains(github.event.issue.labels.*.name, 'enhancement') || github.event.label.name == 'enhancement'
steps:
- name: Checkout
uses: actions/checkout@v4.1.7
with:
ref: main
ssh-key: ${{ secrets.WEBSITE_DEPLOY_KEY }}
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "24"
cache: npm
cache-dependency-path: website/package-lock.json
- name: Install dependencies
working-directory: website
run: npm ci
- name: Build website
working-directory: website
run: npm run build
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Commit rebuilt site
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add website/_site
if git diff --cached --quiet; then
echo "No changes to commit"
else
git commit -m "chore: rebuild website roadmap [skip ci]"
git push
fi
+6
View File
@@ -35,3 +35,9 @@ dist/
#zip files for local backups
*.zip
# node Modules in website
website/node_modules/
# Local secrets for act testing
.secrets
+5 -1
View File
@@ -1,6 +1,10 @@
# KST4Contest
KST4Contest (also known as pratiKST) is a Java-based chat client for ON4KST, focused on VHF/UHF/SHF contest operation.
KST4Contest (also known as pratiKST) is a Java-based chat client for [ON4KST](http://www.on4kst.com/chat), focused on VHF/UHF/SHF contest operation.
## Website
The offical Website of KST4Contest is now instead of [do5amf.funkerportal.de](https://do5amf.funkerportal.de) the new website [here](https://kst4contest.hamradioonline.de) [https://kst4contest.hamradioonline.de](https://kst4contest.hamradioonline.de)
## Documentation
+14 -42
View File
@@ -1,53 +1,25 @@
# KST4Contest Wiki
# KST4Contest
**KST4Contest** (auch bekannt als *PraktiKST*) ist ein Java-basierter Chat-Client für den [ON4KST-Chat](http://www.on4kst.info/chat/), speziell entwickelt für den Contest-Betrieb auf den VHF/UHF/SHF-Bändern.
KST4Contest is a desktop client for the [ON4KST Chat](https://www.on4kst.org/chat/login.php), developed for VHF, UHF and SHF contest operation. It combines chat, candidate selection, sked planning, aircraft scatter information and connections to logging and station software.
Entwickelt von **DO5AMF (Marc Fröhlich)**, Operator bei DM5M.
KST4Contest ist ein Desktop-Client für den [ON4KST-Chat](https://www.on4kst.org/chat/login.php), der für den Contest-Betrieb auf den VHF-, UHF- und SHF-Bändern entwickelt wurde. Er verbindet Chat, Stationsauswahl, Sked-Planung, Aircraft-Scatter-Daten sowie die Anbindung an Log- und Stationssoftware.
Developed by / Entwickelt von **DO5AMF (Marc Fröhlich)**, operator at / Operator bei DM5M.
---
## 🌐 Sprache / Language
## Language / Sprache
| 🇩🇪 Deutsch | 🇬🇧 English |
| Deutsch | English |
|---|---|
| [Startseite (Deutsch)](de-Home) | [Home (English)](en-Home) |
| [Deutsches Handbuch](de-Home) | [English manual](en-Home) |
---
## 🇩🇪 Inhalt (Deutsch)
## Project links / Projektlinks
| Seite | Inhalt |
|---|---|
| [Installation](de-Installation) | Download, Java-Voraussetzungen, Update |
| [Konfiguration](de-Konfiguration) | Alle Einstellungen im Detail |
| [Log-Synchronisation](de-Log-Synchronisation) | UCXLog, N1MM+, QARTest, DXLog.net, WinTest |
| [AirScout-Integration](de-AirScout-Integration) | Flugzeug-Scatter-Erkennung |
| [DX-Cluster-Server](de-DX-Cluster-Server) | Integrierter DX-Cluster für das Log-Programm |
| [Funktionen](de-Funktionen) | Alle Features im Überblick |
| [Makros und Variablen](de-Makros-und-Variablen) | Text-Snippets, Shortcuts, Variablen |
| [Benutzeroberfläche](de-Benutzeroberflaeche) | UI-Erklärung und Bedienung |
| [Changelog](de-Changelog) | Versionsgeschichte |
---
## 🇬🇧 Contents (English)
| Page | Contents |
|---|---|
| [Installation](en-Installation) | Download, Java requirements, updates |
| [Configuration](en-Configuration) | All settings in detail |
| [Log Synchronisation](en-Log-Sync) | UCXLog, N1MM+, QARTest, DXLog.net, WinTest |
| [AirScout Integration](en-AirScout-Integration) | Aircraft scatter detection |
| [DX Cluster Server](en-DX-Cluster-Server) | Built-in DX cluster for your logging software |
| [Features](en-Features) | All features at a glance |
| [Macros and Variables](en-Macros-and-Variables) | Text snippets, shortcuts, variables |
| [User Interface](en-User-Interface) | UI explained and how to operate it |
| [Changelog](en-Changelog) | Version history |
---
## Schnellinfo / Quick Info
- **Download**: https://github.com/praktimarc/kst4contest/releases
- **GitHub**: https://github.com/praktimarc/kst4contest
- **Kontakt / Contact**: praktimarc+kst4contest@gmail.com
- [Project website / Projektwebseite](https://kst4contest.hamradioonline.de/)
- [Download the current stable release / Aktuelle stabile Version herunterladen](https://github.com/praktimarc/kst4contest/releases/latest)
- [Source code / Quellcode](https://github.com/praktimarc/kst4contest)
- [Bug reports and feature requests / Fehler und Funktionswünsche](https://github.com/praktimarc/kst4contest/issues)
- [Online manual / Online-Handbuch](https://kst4contest.hamradioonline.de/manual/)
+89 -34
View File
@@ -1,10 +1,64 @@
# KST4Contest Wiki
# KST4Contest Handbuch
> 🇬🇧 [English version](en-Home) | 🇩🇪 Du liest gerade die deutsche Version
> [English version](en-Home) | Du liest gerade die deutsche Version
**KST4Contest** (auch bekannt als *PraktiKST*) ist ein Java-basierter Chat-Client für den [ON4KST-Chat](http://www.on4kst.info/chat/), der speziell für den Contest-Betrieb auf den VHF/UHF/SHF-Bändern (144 MHz und aufwärts) entwickelt wurde.
KST4Contest ist ein Desktop-Client für den [ON4KST-Chat](https://www.on4kst.org/chat/login.php), der für den Contest-Betrieb auf den VHF-, UHF- und SHF-Bändern entwickelt wurde. Er verbindet Chat, Stationsauswahl, Sked-Planung, Aircraft-Scatter-Daten und die Anbindung an weitere Programme in einer gemeinsamen Arbeitsoberfläche.
Entwickelt von **DO5AMF (Marc Fröhlich)**, Operator bei DM5M.
Entwickelt wird KST4Contest von **DO5AMF (Marc Fröhlich)**, Operator bei DM5M und (seit Mai 2025) **DN9APW (Philipp Wagner)**. Der Quellcode ist öffentlich auf [GitHub](https://github.com/praktimarc/kst4contest) verfügbar.
---
## Wozu braucht man einen eigenen ON4KST-Client?
Der ON4KST-Chat liefert während eines Contests eine große Menge an Informationen: aktive Stationen, Locator, Frequenzen, Sked-Anfragen und Hinweise auf aktuelle Aktivität. Das eigentliche Problem besteht nicht darin, diese Daten zu sehen. Man muss daraus rechtzeitig die nächste sinnvolle Verbindung ableiten.
KST4Contest wertet die verfügbaren Informationen aus, ordnet sie und stellt sie in einem contestgerechten Arbeitsablauf dar. Dabei werden unter anderem Antennenrichtung, Entfernung, bekannte Bänder und Frequenzen, bereits gearbeitete Stationen, Chat-Aktivität und Aircraft-Scatter-Zeiten berücksichtigt.
Das Programm entscheidet jedoch nicht, welches QSO tatsächlich möglich ist. Der Prioritätsscore, die AP-Timeline und die verschiedenen Hervorhebungen sind Entscheidungshilfen. Die endgültige Beurteilung bleibt beim Operator schon deshalb, weil auch ein recht überzeugender Computerbildschirm noch keine Funkverbindung herstellt.
---
## Was KST4Contest im Contest unterstützt
- **Chat beobachten und einordnen:** KST4Contest kann zwei ON4KST-Chat-Kategorien gleichzeitig darstellen. Nachrichten, Frequenzangaben und bekannte Bandaktivitäten werden den jeweiligen Stationen zugeordnet.
- **Relevante Stationen herausfiltern:** Richtungs-, Entfernungs-, Worked- und NOT-QRV-Filter reduzieren die Benutzerliste auf die Stationen, die für den aktuellen Betriebszustand tatsächlich interessant sind.
- **Kandidaten priorisieren:** Das Score-System bewertet aktive Chatmember anhand mehrerer bekannter Kriterien. Die derzeit relevantesten Kandidaten erscheinen zusätzlich in einer eigenen Prioritätsliste.
- **Skeds vorbereiten und im Blick behalten:** Sked-Erinnerungen, automatische Vorwarnungen und die AP-Timeline helfen dabei, vereinbarte Verbindungen nicht zwischen Chat, Log und laufendem CQ-Betrieb zu verlieren.
- **Aircraft Scatter einbeziehen:** Über die AirScout-Schnittstelle werden geeignete Flugzeuge und erwartete Reflexionszeiten in die Stationsbewertung und Zeitplanung übernommen.
- **Log und Funkstation anbinden:** KST4Contest synchronisiert gearbeitete Stationen und Frequenzinformationen mit unterstützten Logprogrammen. Zusätzlich stehen Schnittstellen zu Win-Test, PSTRotator und ein integrierter DX-Cluster-Server zur Verfügung.
- **Stationen und Funkwege darstellen:** Die Stationskarte zeigt aktive Chatmember, Locator-Felder, Antennenrichtungen und den Weg zur ausgewählten Station. Für ausgewählte Verbindungen kann außerdem ein Geländeprofil berechnet werden.
Die Funktionen greifen ineinander. Eine erkannte Frequenz kann beispielsweise einem aktiven Band zugeordnet werden, der Worked-Status stammt aus dem Log, Aircraft-Scatter-Daten ergänzen die zeitliche Bewertung und der daraus berechnete Score beeinflusst die Prioritätsliste. Fehlende oder veraltete Eingangsdaten können deshalb auch das Ergebnis beeinflussen.
---
## Voraussetzungen
Für die Anmeldung ist ein registrierter ON4KST-Account erforderlich. Registrierung und Login sind über die [offizielle ON4KST-Anmeldeseite](https://www.on4kst.org/chat/login.php) erreichbar.
Die offizielle Sprache im ON4KST-Chat ist Englisch. Das gilt auch für Nachrichten an Stationen aus dem eigenen Land. Übliche Amateurfunk-Abkürzungen wie `pse`, `agn`, `qrg`, `dir`, `rrr`, `tnx` oder `73` sind dabei normal und meistens erheblich schneller als ausformulierte Prosa.
Download, unterstützte Betriebssysteme und Installationswege sind im Kapitel [Installation](de-Installation) beschrieben.
---
## Versionsstand dieses Handbuchs
Dieses Handbuch beschreibt die stabile Version **v1.41.1**.
Funktionen oder Änderungen, die nur im aktuellen Entwicklungsstand enthalten sind, werden ausdrücklich als **Nightly / v1.42** gekennzeichnet. Fehlt eine solche Kennzeichnung, bezieht sich die Beschreibung auf die stabile Version.
- [Aktuelle stabile Version herunterladen](https://github.com/praktimarc/kst4contest/releases/latest)
- [Nightly-Builds und automatisierte Builds](https://github.com/praktimarc/kst4contest/actions)
- [Versionsgeschichte](de-Changelog)
Für einen Contest ist grundsätzlich die stabile Version zu empfehlen. Nightly-Builds enthalten neuere Korrekturen und Funktionen, können sich aber zwischen zwei Builds verändern. Sie sind sinnvoll, wenn eine bestimmte Änderung getestet werden soll weniger sinnvoll ist der erste Versuch zehn Minuten vor Contestbeginn.
---
@@ -12,51 +66,52 @@ Entwickelt von **DO5AMF (Marc Fröhlich)**, Operator bei DM5M.
| Seite | Inhalt |
|---|---|
| [Installation](de-Installation) | Download, Java-Voraussetzungen, Update |
| [Konfiguration](de-Konfiguration) | Alle Einstellungen im Detail |
| [Log-Synchronisation](de-Log-Synchronisation) | UCXLog, N1MM+, QARTest, DXLog.net, WinTest |
| [AirScout-Integration](de-AirScout-Integration) | Flugzeug-Scatter-Erkennung |
| [DX-Cluster-Server](de-DX-Cluster-Server) | Integrierter DX-Cluster für das Log-Programm |
| [Funktionen](de-Funktionen) | Alle Features im Überblick |
| [Makros und Variablen](de-Makros-und-Variablen) | Text-Snippets, Shortcuts, Variablen |
| [Benutzeroberfläche](de-Benutzeroberflaeche) | UI-Erklärung und Bedienung |
| [Changelog](de-Changelog) | Versionsgeschichte |
| [Installation](de-Installation) | ON4KST-Account, Download, Installation und Updates |
| [Konfiguration](de-Konfiguration) | Login, Station, Bänder, Benutzeroberfläche und externe Schnittstellen |
| [Log-Synchronisation](de-Log-Synchronisation) | Simplelogfile, UCXLog, N1MM+, QARTest, DXLog.net und Win-Test |
| [AirScout-Integration](de-AirScout-Integration) | Verbindung zu AirScout und Auswertung von Aircraft-Scatter-Zeiten |
| [DX-Cluster-Server](de-DX-Cluster-Server) | Übergabe erkannter Möglichkeiten an das Logprogramm |
| [Funktionen](de-Funktionen) | Arbeitsweise, Herleitung und Grenzen der einzelnen Funktionen |
| [Makros und Variablen](de-Makros-und-Variablen) | Wiederverwendbare Texte, Shortcuts und automatisch ersetzte Werte |
| [Benutzeroberfläche](de-Benutzeroberflaeche) | Aufbau der Oberfläche und Bedienung im Contest |
| [Changelog](de-Changelog) | Releases, Nightly-Änderungen und behobene Fehler |
---
## Was ist KST4Contest?
## Kontakt und Support
Der ON4KST-Chat ist der De-facto-Standard für Skeds auf den 144-MHz-und-höher-Bändern. KST4Contest erweitert die Chat-Nutzung um contest-spezifische Funktionen:
- **Download:** [Aktuelle stabile Version](https://github.com/praktimarc/kst4contest/releases/latest)
- **Quellcode:** [praktimarc/kst4contest](https://github.com/praktimarc/kst4contest)
- **Fehler und Funktionswünsche:** [GitHub Issues](https://github.com/praktimarc/kst4contest/issues)
- **E-Mail:** praktimarc+kst4contest@gmail.com
Bitte nur für Themen verwenden, die KST4Contest betreffen.
- **Worked-Markierung**: Bereits gearbeitete Stationen werden farblich markiert, direkt aus dem Logprogramm via UDP synchronisiert.
- **Sked-Richtungs-Erkennung**: Wenn eine Station eine andere aus deiner Richtung anruft, wird sie grün und fett hervorgehoben.
- **QRG-Erkennung**: KST4Contest liest Frequenzen automatisch aus dem Chat-Verkehr und zeigt sie in der Benutzerliste an.
- **AirScout-Interface**: Anzeige reflektierbarer Flugzeuge direkt in der Benutzerliste.
- **Integrierter DX-Cluster-Server**: Spots werden direkt an das Logprogramm gesendet.
- **Dark Mode** (ab v1.26): Schont die Augen in der Nacht.
- **Multi-Channel-Login** (ab v1.26): Gleichzeitig in zwei Chat-Kategorien einloggen.
### Einen Fehler melden
---
Ein Fehler lässt sich wesentlich schneller nachvollziehen, wenn die Meldung mindestens folgende Angaben enthält:
## Kontakt & Support
1. verwendete KST4Contest-Version,
2. Betriebssystem und Installationsart,
3. genaue Schritte bis zum Fehler,
4. erwartetes und tatsächlich beobachtetes Verhalten,
5. gegebenenfalls einen Screenshot,
6. die Fehler-Logdatei.
- **E-Mail**: praktimarc+kst4contest@gmail.com *(nur für kst4contest-Themen)*
- **GitHub**: https://github.com/praktimarc/kst4contest
- **Download**: https://github.com/praktimarc/kst4contest/releases/latest
Die Fehler-Logdatei wird hier gespeichert:
### Fehler melden (Issue erstellen)
Beim Melden eines Fehlers bitte **immer die Logdatei anhängen**. KST4Contest schreibt automatisch eine Fehler-Logdatei (nur Fehlermeldungen, keine persönlichen Daten):
| Betriebssystem | Pfad zur Logdatei |
| Betriebssystem | Pfad |
|---|---|
| Linux / macOS | `~/.praktiKST/kst4contest-errors.log` |
| Windows | `C:\Users\<Benutzername>\.praktiKST\kst4contest-errors.log` |
Beim Erstellen eines Issues auf GitHub steht eine Vorlage bereit, die alle wichtigen Felder abfragt.
Vor dem Hochladen sollte die Datei kurz geprüft werden. Ein Fehlerprotokoll enthält überwiegend technische Informationen, kann abhängig vom Fehler aber beispielsweise lokale Dateipfade oder weitere Kontextdaten enthalten.
In Datei- und Verzeichnisnamen wird teilweise noch der technische Name `praktiKST` verwendet. Gemeint ist dasselbe Programm.
---
## Danksagungen
Besonderer Dank gilt: Gianluca Costantino (IU3OAR), Alessandro Murador (IZ3VTH), Reczetár István (HA1FV), OM0AAO (Viliam Petrik, DX-Cluster-Idee), DC9DJ (Konrad Neitzel, Projektstruktur), DO5ALF (Andreas, Webmaster funkerportal.de), PE0WGA (Franz van Velzen, Tester) sowie allen weiteren Testern und Ideengebern.
KST4Contest wurde durch Rückmeldungen aus dem praktischen Contest-Betrieb wesentlich verbessert.
Besonderer Dank gilt Gianluca Costantino (IU3OAR), Alessandro Murador (IZ3VTH), Reczetár István (HA1FV), Viliam Petrik (OM0AAO, Idee zum DX-Cluster), Konrad Neitzel (DC9DJ, Projektstruktur), Andreas (DO5ALF, Webmaster von funkerportal.de), Franz van Velzen (PE0WGA, Tester), DN9APW als neuem Entwickler im Team und Master über die CI/CD pipelines sowie allen weiteren Testern und Ideengebern.
+330 -127
View File
@@ -2,219 +2,422 @@
> 🇬🇧 [English version](en-Installation) | 🇩🇪 Du liest gerade die deutsche Version
## Voraussetzungen
KST4Contest wird für Windows, Linux und macOS als fertiges Programmpaket bereitgestellt. Für die offiziellen Release-Pakete muss Java nicht separat installiert werden: Die benötigte Java-Laufzeitumgebung ist bereits enthalten.
Es wird eine Mindestauflösung von 1200px mal 720px empfohlen
Benötigt werden damit im Wesentlichen ein unterstütztes Betriebssystem, eine Internetverbindung und ein ON4KST-Account. Das klingt zunächst überschaubar und ist es normalerweise auch.
## Voraussetzungen
### ON4KST-Account
Um den Chat zu nutzen, ist ein registrierter Account beim ON4KST-Chat-Dienst erforderlich:
KST4Contest ist ein eigenständiger Client für den ON4KST-Chat, ersetzt aber nicht den dazugehörigen Benutzeraccount.
- Registrierung unter: http://www.on4kst.info/chat/register.php
Falls noch kein Account vorhanden ist, kann er über die offizielle ON4KST-Seite angelegt werden:
### Verhaltensregeln im Chat
- [ON4KST-Anmeldung und Registrierung](https://www.on4kst.org/chat/login.php)
Die offizielle Sprache im ON4KST-Chat ist **Englisch**. Auch bei Kommunikation mit Stationen aus dem eigenen Land bitte Englisch verwenden. Übliche HAM-Abkürzungen (agn, dir, pse, rrr, tnx, 73 …) sind gang und gäbe.
ON4KST gibt Englisch als gemeinsame Sprache im Chat vor. Das gilt auch dann, wenn beide beteiligten Stationen dieselbe Muttersprache sprechen. Im Contestbetrieb werden häufig die üblichen Amateurfunk-Abkürzungen wie `pse`, `agn`, `qrg`, `dir`, `rrr`, `tnx` oder `73` verwendet.
### Persönliche Nachrichten
Die eigentliche Bedienung des Chats und das Senden persönlicher Nachrichten werden im Kapitel zur Benutzeroberfläche beschrieben. Für die Installation ist zunächst nur wichtig, dass der Account funktioniert.
Um eine Privatnachricht an eine andere Station zu senden, immer folgendes Format verwenden:
### Bildschirmgröße
```
/CQ RUFZEICHEN Nachrichtentext
```
Eine nutzbare Bildschirmfläche von ungefähr **1200 × 720 Pixeln** oder mehr wird empfohlen.
Beispiel: `/CQ DL5ASG pse sked 144.205?`
KST4Contest passt das Hauptfenster automatisch an die verfügbare Fläche des primären Bildschirms an. Das Programm kann deshalb auch auf kleineren Bildschirmen gestartet werden. Weniger Platz bleibt allerdings weniger Platz: In diesem Fall können nicht alle Tabellen, Filter und Zusatzinformationen gleichzeitig in sinnvoller Größe dargestellt werden.
Bei starkem Chat-Verkehr (56 Nachrichten pro Sekunde im Contest) gehen öffentliche Nachrichten, die an ein bestimmtes Rufzeichen gerichtet sind, leicht unter. KST4Contest fängt solche Nachrichten aber auch dann ab, wenn sie fälschlicherweise öffentlich gepostet werden (siehe [Funktionen PM-Abfang](Funktionen#catching-personal-messages)).
### Java
Für die fertigen Pakete aus den [GitHub Releases](https://github.com/praktimarc/kst4contest/releases/latest) ist keine separate Java-Installation erforderlich. Die benötigte Laufzeitumgebung wird zusammen mit KST4Contest ausgeliefert.
Eine Java-Entwicklungsumgebung wird nur benötigt, wenn KST4Contest selbst aus dem Quellcode gebaut werden soll. Bei den AUR-Paketen `kst4contest` und `kst4contest-git` werden Java 21 und Maven als Build-Abhängigkeiten durch den Paketmanager berücksichtigt.
---
## Stable, Beta oder Nightly?
KST4Contest wird in drei Entwicklungsständen bereitgestellt:
| Kanal | Geeignet für | Einordnung |
|---|---|---|
| **Stable** | Normaler Contestbetrieb | Veröffentlichte und für den regulären Einsatz vorgesehene Version |
| **Beta** | Gezielte Tests vor einem Stable-Release | Vorabversion mit weitgehend festgelegtem Funktionsumfang |
| **Nightly** | Frühe Tests neuer Funktionen | Aktueller Entwicklungsstand aus dem `main`-Branch |
Für den normalen Einsatz wird die **Stable-Version** empfohlen.
Beta- und Nightly-Versionen können Funktionen enthalten, die im Stable-Release noch nicht verfügbar sind. Sie können aber ebenso unfertige Bedienabläufe, geänderte Einstellungen oder neue Fehler enthalten. Das ist kein ungewöhnlicher Defekt im Veröffentlichungsverfahren, sondern der Zweck eines Entwicklungskanals.
Wenn in diesem Manual eine Funktion ausdrücklich mit **Nightly** gekennzeichnet ist, gehört sie noch nicht zwingend zum aktuellen Stable-Release.
---
## Download
### Windows
Die aktuelle Stable-Version ist hier verfügbar:
Die aktuelle Version kann als ZIP-Datei heruntergeladen werden:
- [Aktuelles KST4Contest-Release](https://github.com/praktimarc/kst4contest/releases/latest)
- [Alle veröffentlichten Versionen](https://github.com/praktimarc/kst4contest/releases)
**https://github.com/praktimarc/kst4contest/releases/latest**
Die Release-Seite enthält die Programmpakete sowie die deutschen und englischen PDF-Handbücher.
Der Dateiname hat das Format `praktiKST-v<Versionsnummer>-windows-x64.zip `.
### Welches Paket wird benötigt?
### Linux
Mehrere Paketformate stehen auf der Releases-Seite zur Verfügung:
**https://github.com/praktimarc/kst4contest/releases/latest**
| Format | Dateiname | Geeignet für |
| Betriebssystem | Paket | Typischer Dateiname |
|---|---|---|
| AppImage | `KST4Contest-v<Version>-linux-x86_64.AppImage` | Alle Distributionen |
| Debian-Paket | `KST4Contest-v<Version>-debian-amd64.deb` | Debian, Ubuntu, Linux Mint, … |
| RPM-Paket | `KST4Contest-v<Version>-fedora-x86_64.rpm` | Fedora, RHEL, openSUSE, … |
| Arch-Paket | `KST4Contest-v<Version>-archlinux-x86_64.pkg.tar.zst` | Arch Linux, Manjaro, … |
| Flatpak | `de.x08.KST4Contest.flatpakref` | Alle Distributionen mit Flatpak |
> **Empfehlung für Linux:** Die Flatpak-Installation ist der einfachste Weg, immer aktuell zu bleiben `flatpak update` erledigt alle zukünftigen Updates automatisch. Das Repository ist GPG-signiert.
### macOS
> ⚠️ **Best-Effort-Support:** macOS-Builds werden als zusätzliche Option bereitgestellt, sind aber **nicht umfassend getestet**. Wir bauen und veröffentlichen macOS-Binaries mit jedem Release, können allerdings nicht alle Szenarien unter macOS testen. Bei Problemen freuen wir uns über eine Rückmeldung wir versuchen unser Bestes, können aber nicht den gleichen Support-Umfang wie für Windows und Linux garantieren.
Die aktuelle Version kann als DMG-Disk-Image heruntergeladen werden (für Apple-Silicon- und Intel-Macs verfügbar):
**https://github.com/praktimarc/kst4contest/releases/latest**
Der Dateiname hat das Format `KST4Contest-v<Versionsnummer>-macos-<Architektur>.dmg`, wobei `<Architektur>` entweder `arm64` (Apple Silicon) oder `x86_64` (Intel) ist.
| Windows x64 | ZIP-Paket | `praktiKST-v<Version>-windows-x64.zip` |
| Linux x86_64 | AppImage | `KST4Contest-v<Version>-linux-x86_64.AppImage` |
| Debian/Ubuntu amd64 | DEB-Paket | `KST4Contest-v<Version>-debian-amd64.deb` |
| Fedora/RPM x86_64 | RPM-Paket | `KST4Contest-v<Version>-fedora-x86_64.rpm` |
| Arch Linux x86_64 | Arch-Paket | `KST4Contest-v<Version>-archlinux-x86_64.pkg.tar.zst` |
| Linux mit Flatpak | Flatpak-Referenz | `de.x08.KST4Contest.flatpakref` |
| macOS Apple Silicon | DMG für ARM64 | `KST4Contest-v<Version>-macos-arm64.dmg` |
| macOS Intel | DMG für x86_64 | `KST4Contest-v<Version>-macos-x86_64.dmg` |
Lade Programmpakete nur aus den offiziellen GitHub Releases, dem KST4Contest-Flatpak-Repository oder den verlinkten AUR-Paketen herunter. Dateien aus anderen Quellen können anders gebaut, veraltet oder verändert worden sein.
---
## Installation
## Installation unter Windows
### Windows
KST4Contest wird unter Windows als ZIP-Paket bereitgestellt. Ein klassischer Installer ist nicht erforderlich.
1. ZIP-Datei herunterladen.
2. ZIP-Datei in einen gewünschten Ordner entpacken.
3. `praktiKST.exe` ausführen.
1. Lade `praktiKST-v<Version>-windows-x64.zip` aus dem aktuellen Release herunter.
2. Entpacke die ZIP-Datei vollständig in einen eigenen Ordner.
3. Öffne den entpackten Ordner.
4. Starte `praktiKST.exe`.
Die Einstellungen werden unter `%USERPROFILE%\.praktikst\preferences.xml` gespeichert.
Starte das Programm nicht direkt aus der noch komprimierten ZIP-Datei. KST4Contest besteht aus mehreren Dateien und einer mitgelieferten Laufzeitumgebung. Windows kann diese Struktur nur zuverlässig verwenden, wenn das Archiv vorher vollständig entpackt wurde.
### Linux
Die Programmeinstellungen befinden sich nicht im entpackten Programmordner, sondern im Benutzerverzeichnis:
Die Einstellungen werden immer unter `~/.praktikst/preferences.xml` gespeichert.
```text
%USERPROFILE%\.praktiKST\preferences.xml
```
#### AppImage
Dadurch können neue Programmversionen in einen anderen Ordner entpackt werden, ohne dass die vorhandenen Einstellungen verloren gehen.
1. AppImage herunterladen.
2. Ausführbar machen: `chmod +x KST4Contest-v<Version>-linux-x86_64.AppImage`
3. Starten.
---
#### Debian / Ubuntu
## Installation unter Linux
Unter Linux stehen mehrere Paketformate zur Verfügung. Welches davon sinnvoll ist, hängt weniger von KST4Contest als von der verwendeten Distribution und der gewünschten Update-Methode ab.
| Installationsart | Sinnvoll, wenn … |
|---|---|
| **Flatpak** | Updates zentral verwaltet werden sollen und Flatpak bereits verwendet wird |
| **AppImage** | KST4Contest ohne Installation als einzelne portable Datei gestartet werden soll |
| **DEB/RPM** | die Paketverwaltung der Distribution verwendet werden soll |
| **Arch-Paket/AUR** | Arch Linux, Manjaro oder EndeavourOS eingesetzt wird |
### Flatpak
Flatpak ist für die meisten Linux-Anwender der einfachste Weg, KST4Contest installiert und aktualisierbar zu halten. Das KST4Contest-Repository ist GPG-signiert und enthält die Kanäle Stable, Beta und Nightly.
#### Stable über die Release-Datei installieren
Lade `de.x08.KST4Contest.flatpakref` aus dem aktuellen Release herunter und öffne die Datei mit der Softwareverwaltung der verwendeten Desktop-Umgebung.
Alternativ kann sie im Terminal installiert werden:
```bash
flatpak install ./de.x08.KST4Contest.flatpakref
```
#### KST4Contest-Repository hinzufügen
Das Repository muss nur einmal hinzugefügt werden:
```bash
flatpak remote-add --if-not-exists kst4contest \
https://praktimarc.github.io/kst4contest/kst4contest.flatpakrepo
```
Anschließend kann die Stable-Version installiert werden:
```bash
flatpak install kst4contest de.x08.KST4Contest//stable
```
#### Beta installieren
```bash
flatpak install kst4contest de.x08.KST4Contest//beta
```
#### Nightly installieren
```bash
flatpak install kst4contest de.x08.KST4Contest//nightly
```
KST4Contest verwendet für alle drei Kanäle dieselbe App-ID. Eine parallele Installation mehrerer KST4Contest-Kanäle ist deshalb nicht vorgesehen.
Zum Wechsel von Stable auf Nightly beispielsweise:
```bash
flatpak uninstall de.x08.KST4Contest//stable
flatpak install kst4contest de.x08.KST4Contest//nightly
```
Die persönlichen Einstellungen im Verzeichnis `~/.praktiKST` werden dabei nicht automatisch gelöscht.
Installierte Flatpak-Anwendungen können mit folgendem Befehl aktualisiert werden:
```bash
flatpak update de.x08.KST4Contest
```
Je nach Desktop-Umgebung kann die grafische Softwareverwaltung verfügbare Flatpak-Updates ebenfalls anzeigen oder automatisch installieren. Der Befehl `flatpak update` selbst führt das Update aus; er verspricht nicht, irgendwann von allein vorbeizukommen.
### AppImage
Das AppImage benötigt keine klassische Installation.
1. Lade `KST4Contest-v<Version>-linux-x86_64.AppImage` herunter.
2. Öffne ein Terminal im Download-Verzeichnis.
3. Mache die Datei ausführbar:
```bash
chmod +x KST4Contest-v<Version>-linux-x86_64.AppImage
```
4. Starte KST4Contest:
```bash
./KST4Contest-v<Version>-linux-x86_64.AppImage
```
Das AppImage kann anschließend an einen anderen Ort verschoben werden, beispielsweise nach `~/Applications`.
### Debian und Ubuntu
Installiere das DEB-Paket mit:
```bash
sudo apt install ./KST4Contest-v<Version>-debian-amd64.deb
```
Oder die `.deb`-Datei im Dateimanager doppelklicken.
Alternativ kann die Datei in einer grafischen Paketverwaltung geöffnet werden.
#### Fedora / RHEL
### Fedora und kompatible RPM-Systeme
Installiere das RPM-Paket mit:
```bash
sudo dnf install ./KST4Contest-v<Version>-fedora-x86_64.rpm
```
#### Arch Linux
### Arch Linux: fertiges Release-Paket
Das aus dem GitHub Release heruntergeladene Arch-Paket kann direkt installiert werden:
```bash
sudo pacman -U KST4Contest-v<Version>-archlinux-x86_64.pkg.tar.zst
```
#### Flatpak
### Arch Linux: Installation über den AUR
Im AUR stehen drei Varianten bereit:
| Paket | Inhalt |
|---|---|
| [`kst4contest-bin`](https://aur.archlinux.org/packages/kst4contest-bin) | Vorgefertigtes Paket des aktuellen Stable-Releases |
| [`kst4contest`](https://aur.archlinux.org/packages/kst4contest) | Stable-Release, das lokal aus dem Quellcode gebaut wird |
| [`kst4contest-git`](https://aur.archlinux.org/packages/kst4contest-git) | Aktueller Entwicklungsstand aus dem `main`-Branch |
Für die meisten Anwender ist `kst4contest-bin` die naheliegende Variante:
Die Datei `de.x08.KST4Contest.flatpakref` aus dem [aktuellen Release](https://github.com/praktimarc/kst4contest/releases/latest) herunterladen und öffnen, oder:
```bash
flatpak install de.x08.KST4Contest.flatpakref
yay -S kst4contest-bin
```
Oder den Remote manuell hinzufügen (empfohlen für Nightly/Beta-Zugriff):
Stable aus dem Quellcode bauen:
```bash
flatpak remote-add --if-not-exists kst4contest https://praktimarc.github.io/kst4contest/kst4contest.flatpakrepo
flatpak install kst4contest de.x08.KST4Contest
yay -S kst4contest
```
#### Flatpak-Kanäle (nightly / beta / stable)
Aktuellen Entwicklungsstand bauen:
Das Flatpak-Repository enthält drei Kanäle, die alle im selben Remote liegen:
```bash
yay -S kst4contest-git
```
| Kanal | Inhalt | Wird gebaut bei |
Die drei Pakete stellen dieselbe Anwendung bereit und sind deshalb als gegenseitige Konflikte definiert. Installiere nur eine Variante gleichzeitig.
AUR-Updates werden berücksichtigt, wenn der verwendete AUR-Helper nach Paketaktualisierungen sucht, beispielsweise mit:
```bash
yay -Syu
```
Sie erfolgen nicht allein deshalb automatisch, weil das Paket aus dem AUR stammt.
---
## Installation unter macOS
> **Best-Effort-Support:** Die macOS-Pakete werden zusammen mit den übrigen Releases gebaut, aber nicht in demselben Umfang getestet wie die Windows- und Linux-Versionen. Rückmeldungen sind willkommen; eine vollständig geprüfte Unterstützung aller macOS-Versionen und Hardwarevarianten kann derzeit jedoch nicht zugesagt werden.
Für Apple-Silicon-Macs wird das Paket mit `arm64` benötigt. Für Intel-Macs ist das Paket mit `x86_64` vorgesehen.
1. Lade die passende DMG-Datei herunter.
2. Öffne die DMG-Datei.
3. Ziehe `KST4Contest.app` in den Ordner **Programme**.
4. Starte KST4Contest aus dem Programme-Ordner oder über das Launchpad.
Die Anwendung ist derzeit nicht von Apple notarisiert. macOS kann den ersten Start deshalb blockieren.
Falls die Anwendung aus dem offiziellen GitHub Release stammt:
1. Öffne den Programme-Ordner im Finder.
2. Klicke mit der rechten Maustaste oder mit gedrückter Ctrl-Taste auf `KST4Contest.app`.
3. Wähle **Öffnen**.
4. Bestätige den Start im angezeigten Dialog.
Alternativ kann macOS unter **Systemeinstellungen → Datenschutz & Sicherheit** die Schaltfläche **Trotzdem öffnen** anbieten.
---
## Wo werden die Einstellungen gespeichert?
KST4Contest speichert seine Einstellungen und weitere lokale Arbeitsdateien im Benutzerverzeichnis. Der Programmordner und das Datenverzeichnis sind voneinander getrennt.
| Betriebssystem | Datenverzeichnis | Einstellungsdatei |
|---|---|---|
| `stable` | Aktuelle stabile Version | Jedem normalen Release-Tag |
| `beta` | Vorab-Version | Tags mit `beta-` Präfix |
| `nightly` | Entwicklungsstand (main-Branch) | Täglich / jedem Push auf main |
| Windows | `%USERPROFILE%\.praktiKST\` | `%USERPROFILE%\.praktiKST\preferences.xml` |
| Linux | `~/.praktiKST/` | `~/.praktiKST/preferences.xml` |
| macOS | `~/.praktiKST/` | `~/.praktiKST/preferences.xml` |
Remote einmalig hinzufügen, dann den gewünschten Kanal installieren:
Beachte die Schreibweise `.praktiKST` mit großem `KST`. Unter Linux und macOS wird zwischen Groß- und Kleinschreibung unterschieden. `.praktikst` wäre dort schlicht ein anderes Verzeichnis.
Ein Programmupdate entfernt dieses Verzeichnis nicht. Trotzdem ist es sinnvoll, vor größeren Versionswechseln oder umfangreichen Änderungen an der Konfiguration eine Sicherung davon anzulegen.
---
## Updates
KST4Contest prüft beim Start, ob ein neueres Stable-Release verfügbar ist. Wenn eine neuere Version gefunden wird, erscheint ein Informationsfenster mit:
- der installierten Version,
- der aktuellen Stable-Version,
- einer kurzen Übersicht wesentlicher Änderungen,
- dem Changelog,
- bekannten Problemen,
- einem Link zur passenden GitHub-Release-Seite.
![Update-Hinweis von KST4Contest](update_window.png)
Der Update-Checker installiert nichts selbst. Er informiert über die neue Version und öffnet die plattformneutrale Release-Seite. Dort muss das passende Paket für Windows, Linux oder macOS ausgewählt werden.
### Windows aktualisieren
1. Beende KST4Contest.
2. Lade das neue Windows-ZIP herunter.
3. Entpacke es in einen neuen oder leeren Ordner.
4. Starte die neue Version.
5. Prüfe, ob die bisherigen Einstellungen geladen wurden.
6. Entferne den alten Programmordner erst danach.
Die Einstellungen bleiben erhalten, weil sie unter `%USERPROFILE%\.praktiKST` und nicht im Programmordner gespeichert werden.
### AppImage aktualisieren
1. Lade das neue AppImage herunter.
2. Mache es ausführbar.
3. Starte die neue Datei.
4. Entferne das bisherige AppImage erst, wenn die neue Version funktioniert.
### Debian und Ubuntu aktualisieren
```bash
flatpak remote-add --if-not-exists kst4contest https://praktimarc.github.io/kst4contest/kst4contest.flatpakrepo
# Stable (Standard)
flatpak install kst4contest de.x08.KST4Contest
# Beta
flatpak install kst4contest de.x08.KST4Contest//beta
# Nightly
flatpak install kst4contest de.x08.KST4Contest//nightly
sudo apt install ./KST4Contest-v<Version>-debian-amd64.deb
```
> **Hinweis:** Flatpak erlaubt nur eine installierte Version pro App-ID gleichzeitig. Um den Kanal zu wechseln, zuerst die aktuelle Version deinstallieren:
> ```bash
> flatpak uninstall de.x08.KST4Contest
> flatpak install kst4contest de.x08.KST4Contest//nightly
> ```
### Fedora aktualisieren
Updates erfolgen wie gewohnt mit `flatpak update`.
```bash
sudo dnf upgrade ./KST4Contest-v<Version>-fedora-x86_64.rpm
```
Die `flatpakref`-Dateien für Beta und Stable liegen jeweils im entsprechenden [GitHub-Release](https://github.com/praktimarc/kst4contest/releases). Das Nightly-`flatpakref` (`de.x08.KST4Contest.nightly.flatpakref`) ist als Artifact im [GitHub Actions](https://github.com/praktimarc/kst4contest/actions)-Tab verfügbar (wird 14 Tage aufbewahrt) der Remote-Weg oben ist für Nightly daher meist einfacher.
### Arch-Paket aktualisieren
### macOS
1. DMG-Datei für die eigene Architektur herunterladen (Apple Silicon oder Intel).
2. DMG-Datei öffnen.
3. `KST4Contest.app` in den **Programme**-Ordner ziehen.
4. Beim ersten Start zeigt macOS ggf. eine Warnung, da die App nicht notarisiert ist. Zum Öffnen:
- Rechtsklick (oder Ctrl-Klick) auf `KST4Contest.app` im Finder → **Öffnen** wählen.
- Alternativ: **Systemeinstellungen → Datenschutz & Sicherheit****Trotzdem öffnen** klicken.
5. KST4Contest aus dem Programme-Ordner oder dem Launchpad starten.
```bash
sudo pacman -U KST4Contest-v<Version>-archlinux-x86_64.pkg.tar.zst
```
Die Einstellungen werden unter `~/.praktikst/preferences.xml` gespeichert.
### AUR-Paket aktualisieren
Aktualisiere das installierte Paket über den verwendeten AUR-Helper, beispielsweise:
```bash
yay -Syu
```
### Flatpak aktualisieren
```bash
flatpak update de.x08.KST4Contest
```
### macOS aktualisieren
1. Lade die neue DMG-Datei für die vorhandene Architektur herunter.
2. Beende KST4Contest.
3. Öffne die DMG-Datei.
4. Ersetze `KST4Contest.app` im Programme-Ordner.
5. Starte die neue Version und prüfe die vorhandenen Einstellungen.
Die Konfiguration unter `~/.praktiKST` bleibt davon unberührt.
---
## Update
## Probleme beim ersten Start
KST4Contest enthält einen **automatischen Update-Hinweis-Dienst**: Sobald eine neue Version verfügbar ist, erscheint beim Start ein Fenster mit:
- der Information, dass eine neue Version vorliegt,
- einem Changelog,
- dem Download-Link zur neuen Version.
### Windows meldet eine unbekannte Anwendung
![Beispiel Update Fenster](update_window.png)
KST4Contest ist derzeit nicht mit einem kommerziellen Windows-Code-Signing-Zertifikat signiert. Windows oder ein zusätzlich installiertes Sicherheitsprodukt kann deshalb vor einer unbekannten oder selten heruntergeladenen Anwendung warnen.
### Update-Prozess
Prüfe in diesem Fall zuerst:
#### Windows
- Stammt die Datei aus dem [offiziellen KST4Contest-Release](https://github.com/praktimarc/kst4contest/releases/latest)?
- Passt der Dateiname zum veröffentlichten Release?
- Wurde die Datei vollständig heruntergeladen?
- Nennt das Sicherheitsprogramm einen konkreten Erkennungsnamen oder nur eine allgemeine Reputationswarnung?
Derzeit gibt es nur einen Weg zum Aktualisieren:
Ein Warnhinweis ist allein weder ein sicherer Beweis für Schadsoftware noch automatisch ein Fehlalarm. Wenn die Herkunft der Datei unklar ist, sollte sie nicht gestartet oder aus der Quarantäne wiederhergestellt werden.
1. Den alten Ordner löschen.
2. Das neue ZIP entpacken.
Einige Anwender haben insbesondere Quarantäne-Meldungen von Norton 360 gemeldet. Wenn sich eine Meldung reproduzieren lässt, erstelle bitte einen [GitHub-Issue](https://github.com/praktimarc/kst4contest/issues) und nenne:
Die Einstellungsdatei (`preferences.xml`) bleibt erhalten, da sie im Benutzerordner gespeichert ist nicht im Programmordner.
- die KST4Contest-Version,
- den vollständigen Dateinamen,
- das verwendete Sicherheitsprodukt und dessen Version,
- den angezeigten Erkennungsnamen,
- möglichst einen Screenshot der Meldung.
#### Linux
### Das AppImage startet nicht
- **AppImage**: Neues AppImage herunterladen, ausführbar machen (`chmod +x`), altes optional löschen.
- **Debian/Ubuntu**: `sudo apt install ./KST4Contest-v<Version>-debian-amd64.deb`
- **Fedora/RHEL**: `sudo dnf upgrade ./KST4Contest-v<Version>-fedora-x86_64.rpm`
- **Arch Linux**: `sudo pacman -U KST4Contest-v<Version>-archlinux-x86_64.pkg.tar.zst`
- **Flatpak (Repository)**: `flatpak update` aktualisiert alle Flatpak-Apps einschließlich KST4Contest.
Prüfe zuerst das Ausführungsrecht:
#### macOS
```bash
chmod +x KST4Contest-v<Version>-linux-x86_64.AppImage
```
1. Neue DMG-Datei herunterladen.
2. DMG öffnen.
3. Die neue `KST4Contest.app` in den **Programme**-Ordner ziehen und die alte Version ersetzen.
Starte die Datei anschließend aus einem Terminal. Fehlermeldungen sind dort meist aussagekräftiger als ein Doppelklick, der lediglich nichts Sichtbares tut.
### macOS blockiert die Anwendung
---
Verwende die unter [Installation unter macOS](#installation-unter-macos) beschriebene Funktion **Öffnen** im Kontextmenü. Prüfe vorher, ob die DMG-Datei aus dem offiziellen GitHub Release stammt.
## Bekannte Probleme beim Start
### Das Problem bleibt bestehen
### Norton 360
Prüfe zunächst, ob das Problem bereits unter [GitHub Issues](https://github.com/praktimarc/kst4contest/issues) beschrieben wurde. Falls nicht, erstelle einen neuen Issue mit:
Norton 360 stuft `praktiKST.exe` als gefährlich ein (Fehlalarm). Es muss eine Ausnahme für die Datei eingerichtet werden:
- Betriebssystem und Version,
- verwendeter KST4Contest-Version,
- Installationsart,
- genauer Fehlermeldung,
- den Schritten, mit denen sich das Problem reproduzieren lässt.
1. Norton 360 öffnen.
2. Sicherheit → Verlauf → Das entsprechende Ereignis suchen.
3. „Wiederherstellen & Ausnahme hinzufügen" wählen.
*(Gemeldet von PE0WGA, Franz van Velzen danke!)*
„Geht nicht“ beschreibt den Zustand meistens korrekt, hilft bei der Fehlersuche aber nur begrenzt.
+90 -35
View File
@@ -1,62 +1,117 @@
# KST4Contest Wiki
# KST4Contest User Manual
> 🇬🇧 You are reading the English version | 🇩🇪 [Deutsche Version](de-Home)
> You are reading the English version | [Deutsche Version](de-Home)
**KST4Contest** (also known as *PraktiKST*) is a Java-based chat client for the [ON4KST Chat](http://www.on4kst.info/chat/), specifically designed for contest operation on the VHF/UHF/SHF bands (144 MHz and above).
KST4Contest is a desktop client for the [ON4KST Chat](https://www.on4kst.org/chat/login.php), developed for VHF, UHF and SHF contest operation. It brings chat, candidate selection, sked planning, aircraft scatter data and external station software together in a single operating interface.
Developed by **DO5AMF (Marc Fröhlich)**, operator at DM5M.
KST4Contest is developed by **DO5AMF (Marc Fröhlich)**, operator at DM5M and (since May 2025) **DN9APW (Philipp Wagner)**. The source code is publicly available on [GitHub](https://github.com/praktimarc/kst4contest).
---
## Quick Navigation
## Why use a dedicated ON4KST client?
During a contest, the ON4KST Chat provides a considerable amount of information: active stations, locators, frequencies, sked requests and indications of current activity. The actual problem is not seeing this data. It is turning it into the next useful contact in time.
KST4Contest evaluates the available information, puts it into context and presents it as part of a contest-oriented workflow. This includes antenna direction, distance, known bands and frequencies, worked status, chat activity and aircraft scatter timing.
The program does not decide which QSO is actually possible. Priority scores, the AP timeline and visual highlights are decision aids. The final judgement remains with the operator not least because even a very convincing computer screen cannot complete a radio contact.
---
## How KST4Contest supports contest operation
- **Observe and organise chat activity:** KST4Contest can display two ON4KST chat categories at the same time. Messages, frequency information and known band activity are assigned to the corresponding stations.
- **Reduce the station list:** Direction, distance, worked and NOT-QRV filters help limit the user list to stations that are relevant to the current operating situation.
- **Prioritise candidates:** The score system evaluates active chat members using several known criteria. The currently most relevant candidates are also shown in a separate priority list.
- **Prepare skeds and keep them visible:** Sked reminders, automatic advance messages and the AP timeline help prevent scheduled contacts from disappearing somewhere between chat, logging and ongoing CQ operation.
- **Include aircraft scatter information:** The AirScout interface brings suitable aircraft and expected reflection times into candidate evaluation and sked planning.
- **Connect the logger and station equipment:** KST4Contest synchronises worked stations and frequency information with supported logging software. It also provides interfaces for Win-Test, PSTRotator and a built-in DX Cluster server.
- **Display stations and radio paths:** The station map shows active chat members, locator squares, antenna directions and the path to the selected station. A terrain profile can also be calculated for selected paths.
These functions share information. A detected frequency can indicate an active band, worked status comes from the logger, aircraft scatter data adds timing information and the resulting score affects the priority list. Missing or outdated input data can therefore affect the result as well.
---
## Requirements
A registered ON4KST account is required. Registration and login are available from the [official ON4KST login page](https://www.on4kst.org/chat/login.php).
English is the official language of the ON4KST Chat. This also applies when communicating with stations from your own country. Common amateur radio abbreviations such as `pse`, `agn`, `qrg`, `dir`, `rrr`, `tnx` and `73` are normal and usually considerably faster than carefully written prose.
Downloads, supported operating systems and installation methods are described in [Installation](en-Installation).
---
## Manual version
This manual describes the stable release **v1.41.1**.
Features or changes that are only available in the current development version are explicitly marked as **Nightly / v1.42**. If no such label is present, the description refers to the stable release.
- [Download the current stable release](https://github.com/praktimarc/kst4contest/releases/latest)
- [Nightly and automated builds](https://github.com/praktimarc/kst4contest/actions)
- [Version history](en-Changelog)
For contest operation, the stable release is generally the appropriate choice. Nightly builds contain newer fixes and features, but may change between builds. They are useful when a particular change needs testing. Trying one for the first time ten minutes before a contest is less useful.
---
## Quick navigation
| Page | Contents |
|---|---|
| [Installation](en-Installation) | Download, Java requirements, update |
| [Configuration](en-Configuration) | All settings in detail |
| [Log Synchronisation](en-Log-Sync) | UCXLog, N1MM+, QARTest, DXLog.net, WinTest |
| [AirScout Integration](en-AirScout-Integration) | Aircraft scatter detection |
| [DX Cluster Server](en-DX-Cluster-Server) | Built-in DX cluster for your logging software |
| [Features](en-Features) | All features at a glance |
| [Macros and Variables](en-Macros-and-Variables) | Text snippets, shortcuts, variables |
| [User Interface](en-User-Interface) | UI explanation and operation |
| [Changelog](en-Changelog) | Version history |
| [Installation](en-Installation) | ON4KST account, downloads, installation and updates |
| [Configuration](en-Configuration) | Login, station, bands, user interface and external connections |
| [Log Synchronisation](en-Log-Sync) | Simplelogfile, UCXLog, N1MM+, QARTest, DXLog.net and Win-Test |
| [AirScout Integration](en-AirScout-Integration) | Connecting AirScout and evaluating aircraft scatter timing |
| [DX Cluster Server](en-DX-Cluster-Server) | Passing detected opportunities to logging software |
| [Features](en-Features) | Operation, reasoning and limitations of individual functions |
| [Macros and Variables](en-Macros-and-Variables) | Reusable messages, shortcuts and automatically substituted values |
| [User Interface](en-User-Interface) | Interface layout and operation during a contest |
| [Changelog](en-Changelog) | Releases, Nightly changes and resolved issues |
---
## What is KST4Contest?
## Contact and support
The ON4KST Chat is the de-facto standard for skeds on the 144 MHz and higher bands. KST4Contest enhances the chat experience with contest-specific features:
- **Download:** [Current stable release](https://github.com/praktimarc/kst4contest/releases/latest)
- **Source code:** [praktimarc/kst4contest](https://github.com/praktimarc/kst4contest)
- **Bug reports and feature requests:** [GitHub Issues](https://github.com/praktimarc/kst4contest/issues)
- **Email:** praktimarc+kst4contest@gmail.com
Please use this address only for KST4Contest-related topics.
- **Worked marking**: Stations already worked are highlighted visually, synchronised directly from your logging software via UDP.
- **Sked direction detection**: When a station calls another one from your direction, it is highlighted green and bold.
- **QRG detection**: KST4Contest automatically reads frequencies from the chat traffic and shows them in the user list.
- **AirScout interface**: Reflectable aircraft are shown directly in the user list.
- **Built-in DX cluster server**: Spots are sent directly to your logging software.
- **Dark mode** (from v1.26): Easy on the eyes during night-time operation.
- **Multi-channel login** (from v1.26): Simultaneously logged into two chat categories.
### Reporting a bug
---
A problem is considerably easier to reproduce when the report contains at least:
## Contact & Support
1. the KST4Contest version,
2. the operating system and installation method,
3. the exact steps leading to the problem,
4. the expected and observed behaviour,
5. a screenshot where appropriate,
6. the error log file.
- **Email**: praktimarc+kst4contest@gmail.com *(for kst4contest topics only)*
- **GitHub**: https://github.com/praktimarc/kst4contest
- **Download**: https://github.com/praktimarc/kst4contest/releases/latest
The error log is stored at:
### Reporting a bug (creating an issue)
When reporting a bug, please **always attach the log file**. KST4Contest automatically writes an error log (error messages only, no personal data):
| Operating system | Log file location |
| Operating system | Path |
|---|---|
| Linux / macOS | `~/.praktiKST/kst4contest-errors.log` |
| Windows | `C:\Users\<YourName>\.praktiKST\kst4contest-errors.log` |
When opening an issue on GitHub, a template is provided that guides you through all relevant fields.
Please inspect the file briefly before uploading it. An error log mainly contains technical information, but depending on the problem it may also include local file paths or other contextual data.
Some file and directory names still use the technical name `praktiKST`. They refer to the same program.
---
## Acknowledgements
Special thanks to: Gianluca Costantino (IU3OAR), Alessandro Murador (IZ3VTH), Reczetár István (HA1FV), OM0AAO (Viliam Petrik, DX cluster idea), DC9DJ (Konrad Neitzel, project structure), DO5ALF (Andreas, webmaster funkerportal.de), PE0WGA (Franz van Velzen, tester) and all other testers and contributors.
KST4Contest has benefited considerably from feedback gathered during actual contest operation.
Special thanks go to Gianluca Costantino (IU3OAR), Alessandro Murador (IZ3VTH), Reczetár István (HA1FV), Viliam Petrik (OM0AAO, DX Cluster idea), Konrad Neitzel (DC9DJ, project structure), Andreas (DO5ALF, webmaster of funkerportal.de), Franz van Velzen (PE0WGA, testing), and all other testers and contributors.
+344 -141
View File
@@ -2,219 +2,422 @@
> 🇬🇧 You are reading the English version | 🇩🇪 [Deutsche Version](de-Installation)
## Prerequisites
KST4Contest is distributed as a ready-to-run application package for Windows, Linux and macOS. The official release packages do not require a separate Java installation: the required Java runtime is already included.
An resolution of 1200px by 720px is recommended
In practical terms, you need a supported operating system, an internet connection and an ON4KST account. That sounds manageable—and usually it is.
### ON4KST Account
## Requirements
To use the chat, a registered account with the ON4KST chat service is required:
### ON4KST account
- Register at: http://www.on4kst.info/chat/register.php
KST4Contest is an independent client for the ON4KST chat, but it does not replace the corresponding user account.
### Chat Etiquette
If you do not have an account yet, you can create one on the official ON4KST website:
The official language in the ON4KST Chat is **English**. Please use English even when communicating with stations from your own country. Common HAM abbreviations (agn, dir, pse, rrr, tnx, 73 …) are widely used and understood.
- [ON4KST login and registration](https://www.on4kst.org/chat/login.php)
### Personal Messages
ON4KST specifies English as the common language for the chat. This also applies when both stations happen to share another language. During contests, the usual amateur radio abbreviations such as `pse`, `agn`, `qrg`, `dir`, `rrr`, `tnx` and `73` are widely used.
To send a private message to another station, always use the following format:
Using the chat and sending personal messages are covered in the user interface chapter. For the installation, the only thing that matters at this point is that the account works.
```
/CQ CALLSIGN message text
```
### Screen size
Example: `/CQ DL5ASG pse sked 144.205?`
A usable screen area of approximately **1200 × 720 pixels** or more is recommended.
During heavy chat traffic (56 messages per second in a contest), public messages directed at a specific callsign are easily missed. However, KST4Contest also catches such messages if they are accidentally posted publicly (see [Features PM Catching](Features#catching-personal-messages)).
KST4Contest automatically adapts the main window to the available area of the primary screen. The application can therefore also be started on smaller displays. Less space is still less space, however: not all tables, filters and additional information can then be displayed at a useful size at the same time.
### Java
The ready-made packages from the [GitHub Releases](https://github.com/praktimarc/kst4contest/releases/latest) do not require a separate Java installation. The required runtime is distributed with KST4Contest.
A Java development environment is only required if you want to build KST4Contest from source. For the AUR packages `kst4contest` and `kst4contest-git`, Java 21 and Maven are handled as build dependencies by the package manager.
---
## Stable, Beta or Nightly?
KST4Contest is distributed through three development channels:
| Channel | Intended use | Classification |
|---|---|---|
| **Stable** | Normal contest operation | Published version intended for regular use |
| **Beta** | Focused testing before a Stable release | Pre-release version with a largely defined feature set |
| **Nightly** | Early testing of new features | Current development state from the `main` branch |
The **Stable version** is recommended for normal operation.
Beta and Nightly builds may contain features that are not yet available in the Stable release. They may also contain unfinished workflows, changed settings or new defects. That is not an unusual failure of the release process; it is the purpose of a development channel.
If a function in this manual is explicitly marked as **Nightly**, it is not necessarily part of the current Stable release yet.
---
## Download
### Windows
The current Stable version is available here:
The latest version can be downloaded as a ZIP file:
- [Latest KST4Contest release](https://github.com/praktimarc/kst4contest/releases/latest)
- [All published releases](https://github.com/praktimarc/kst4contest/releases)
**https://github.com/praktimarc/kst4contest/releases/latest**
The release page contains the application packages as well as the English and German PDF manuals.
The filename has the format `praktiKST-v<version_number>-windows-x64.zip`.
### Which package do I need?
### Linux
Multiple package formats are available from the releases page:
**https://github.com/praktimarc/kst4contest/releases/latest**
| Format | Filename | Suitable for |
| Operating system | Package | Typical filename |
|---|---|---|
| AppImage | `KST4Contest-v<version>-linux-x86_64.AppImage` | All distributions |
| Debian package | `KST4Contest-v<version>-debian-amd64.deb` | Debian, Ubuntu, Linux Mint, … |
| RPM package | `KST4Contest-v<version>-fedora-x86_64.rpm` | Fedora, RHEL, openSUSE, … |
| Arch package | `KST4Contest-v<version>-archlinux-x86_64.pkg.tar.zst` | Arch Linux, Manjaro, … |
| Flatpak | `de.x08.KST4Contest.flatpakref` | All distributions with Flatpak |
> **Recommended for Linux:** The Flatpak installation is the easiest way to stay up to date — `flatpak update` handles all future updates automatically. The repository is GPG-signed for security.
### macOS
> ⚠️ **Best-Effort Support:** macOS builds are provided as a convenience but are **not fully tested**. We build and release macOS binaries with every release, but we cannot test every scenario on macOS. If you encounter issues, please report them we will do our best to address them, but cannot guarantee the same level of support as for Windows and Linux.
The latest version can be downloaded as a DMG disk image (available for both Apple Silicon and Intel Macs):
**https://github.com/praktimarc/kst4contest/releases/latest**
The filename has the format `KST4Contest-v<version_number>-macos-<arch>.dmg`, where `<arch>` is `arm64` (Apple Silicon) or `x86_64` (Intel).
| Windows x64 | ZIP package | `praktiKST-v<version>-windows-x64.zip` |
| Linux x86_64 | AppImage | `KST4Contest-v<version>-linux-x86_64.AppImage` |
| Debian/Ubuntu amd64 | DEB package | `KST4Contest-v<version>-debian-amd64.deb` |
| Fedora/RPM x86_64 | RPM package | `KST4Contest-v<version>-fedora-x86_64.rpm` |
| Arch Linux x86_64 | Arch package | `KST4Contest-v<version>-archlinux-x86_64.pkg.tar.zst` |
| Linux with Flatpak | Flatpak reference | `de.x08.KST4Contest.flatpakref` |
| macOS Apple Silicon | DMG for ARM64 | `KST4Contest-v<version>-macos-arm64.dmg` |
| macOS Intel | DMG for x86_64 | `KST4Contest-v<version>-macos-x86_64.dmg` |
Only download application packages from the official GitHub Releases, the KST4Contest Flatpak repository or the linked AUR packages. Files from other sources may have been built differently, may be outdated or may have been modified.
---
## Installation
## Installing on Windows
### Windows
KST4Contest is distributed as a ZIP package for Windows. A conventional installer is not required.
1. Download the ZIP file.
2. Unzip the ZIP file into a folder of your choice.
3. Run `praktiKST.exe`.
1. Download `praktiKST-v<version>-windows-x64.zip` from the latest release.
2. Extract the ZIP file completely into a dedicated folder.
3. Open the extracted folder.
4. Start `praktiKST.exe`.
Settings are stored at `%USERPROFILE%\.praktikst\preferences.xml`.
Do not start the application directly from the compressed ZIP file. KST4Contest consists of several files and a bundled runtime. Windows can only use this structure reliably after the archive has been extracted completely.
### Linux
The application settings are not stored in the extracted program directory. They are stored in your user profile:
Settings are always stored at `~/.praktikst/preferences.xml`.
```text
%USERPROFILE%\.praktiKST\preferences.xml
```
#### AppImage
This allows a new application version to be extracted into a different directory without losing the existing settings.
1. Download the AppImage.
2. Make it executable: `chmod +x KST4Contest-v<version>-linux-x86_64.AppImage`
3. Run it.
---
#### Debian / Ubuntu
## Installing on Linux
Several Linux package formats are available. The appropriate choice depends less on KST4Contest itself than on your distribution and the way you prefer to manage updates.
| Installation method | Useful when … |
|---|---|
| **Flatpak** | updates should be managed centrally and Flatpak is already in use |
| **AppImage** | KST4Contest should run as a portable file without package installation |
| **DEB/RPM** | the distributions native package manager should be used |
| **Arch package/AUR** | Arch Linux, Manjaro or EndeavourOS is being used |
### Flatpak
For most Linux users, Flatpak is the simplest way to keep KST4Contest installed and manageable through the systems update tools. The KST4Contest repository is GPG-signed and contains the Stable, Beta and Nightly channels.
#### Installing Stable from the release file
Download `de.x08.KST4Contest.flatpakref` from the latest release and open it with the software manager provided by your desktop environment.
Alternatively, install it from a terminal:
```bash
flatpak install ./de.x08.KST4Contest.flatpakref
```
#### Adding the KST4Contest repository
The repository only needs to be added once:
```bash
flatpak remote-add --if-not-exists kst4contest \
https://praktimarc.github.io/kst4contest/kst4contest.flatpakrepo
```
You can then install the Stable version:
```bash
flatpak install kst4contest de.x08.KST4Contest//stable
```
#### Installing Beta
```bash
flatpak install kst4contest de.x08.KST4Contest//beta
```
#### Installing Nightly
```bash
flatpak install kst4contest de.x08.KST4Contest//nightly
```
All three KST4Contest channels use the same application ID. Installing multiple KST4Contest channels in parallel is therefore not supported.
For example, to switch from Stable to Nightly:
```bash
flatpak uninstall de.x08.KST4Contest//stable
flatpak install kst4contest de.x08.KST4Contest//nightly
```
This does not automatically remove the personal settings stored in `~/.praktiKST`.
Installed Flatpak applications can be updated with:
```bash
flatpak update de.x08.KST4Contest
```
Depending on the desktop environment, the graphical software manager may also display or automatically install available Flatpak updates. The `flatpak update` command itself performs an update; it does not promise to turn up and run by itself one day.
### AppImage
The AppImage does not require a conventional installation.
1. Download `KST4Contest-v<version>-linux-x86_64.AppImage`.
2. Open a terminal in the download directory.
3. Make the file executable:
```bash
chmod +x KST4Contest-v<version>-linux-x86_64.AppImage
```
4. Start KST4Contest:
```bash
./KST4Contest-v<version>-linux-x86_64.AppImage
```
The AppImage can then be moved to another location, such as `~/Applications`.
### Debian and Ubuntu
Install the DEB package with:
```bash
sudo apt install ./KST4Contest-v<version>-debian-amd64.deb
```
Or double-click the `.deb` file in your file manager.
Alternatively, open the file with a graphical package manager.
#### Fedora / RHEL
### Fedora and compatible RPM systems
Install the RPM package with:
```bash
sudo dnf install ./KST4Contest-v<version>-fedora-x86_64.rpm
```
#### Arch Linux
### Arch Linux: installing the release package
The Arch package downloaded from the GitHub Release can be installed directly:
```bash
sudo pacman -U KST4Contest-v<version>-archlinux-x86_64.pkg.tar.zst
```
#### Flatpak
### Arch Linux: installing from the AUR
Download `de.x08.KST4Contest.flatpakref` from the [latest release](https://github.com/praktimarc/kst4contest/releases/latest) and open it, or run:
```bash
flatpak install de.x08.KST4Contest.flatpakref
```
Three variants are available in the AUR:
Or add the remote manually (recommended for nightly/beta access):
```bash
flatpak remote-add --if-not-exists kst4contest https://praktimarc.github.io/kst4contest/kst4contest.flatpakrepo
flatpak install kst4contest de.x08.KST4Contest
```
| Package | Content |
|---|---|
| [`kst4contest-bin`](https://aur.archlinux.org/packages/kst4contest-bin) | Pre-built package from the current Stable release |
| [`kst4contest`](https://aur.archlinux.org/packages/kst4contest) | Stable release built locally from source |
| [`kst4contest-git`](https://aur.archlinux.org/packages/kst4contest-git) | Current development state from the `main` branch |
#### Flatpak Channels (nightly / beta / stable)
The Flatpak repository provides three channels, all served from the same remote:
| Channel | Content | Built on |
|---|---|---|
| `stable` | Current stable version | Every normal release tag |
| `beta` | Pre-release version | Tags prefixed with `beta-` |
| `nightly` | Development build (main branch) | Every push to main / daily |
Add the remote once, then install the channel you want:
For most users, `kst4contest-bin` is the straightforward option:
```bash
flatpak remote-add --if-not-exists kst4contest https://praktimarc.github.io/kst4contest/kst4contest.flatpakrepo
# Stable (default)
flatpak install kst4contest de.x08.KST4Contest
# Beta
flatpak install kst4contest de.x08.KST4Contest//beta
# Nightly
flatpak install kst4contest de.x08.KST4Contest//nightly
yay -S kst4contest-bin
```
> **Note:** Flatpak only allows one installed version per App-ID at a time. To switch channels, uninstall the current version first:
> ```bash
> flatpak uninstall de.x08.KST4Contest
> flatpak install kst4contest de.x08.KST4Contest//nightly
> ```
To build the Stable release from source:
Updates work as usual with `flatpak update`.
```bash
yay -S kst4contest
```
The `flatpakref` files for beta and stable are attached to their respective [GitHub Releases](https://github.com/praktimarc/kst4contest/releases). The nightly `flatpakref` (`de.x08.KST4Contest.nightly.flatpakref`) is available as an artifact on the [GitHub Actions](https://github.com/praktimarc/kst4contest/actions) tab (kept for 14 days) — for nightly builds, the manual remote approach above is usually more convenient.
To build the current development state:
### macOS
1. Download the DMG file for your architecture (Apple Silicon or Intel).
```bash
yay -S kst4contest-git
```
All three packages provide the same application and are therefore defined as conflicting with one another. Install only one variant at a time.
AUR updates are included when the selected AUR helper checks for package updates, for example:
```bash
yay -Syu
```
They do not happen automatically merely because the package came from the AUR.
---
## Installing on macOS
> **Best-effort support:** The macOS packages are built together with the other releases, but they are not tested to the same extent as the Windows and Linux versions. Feedback is welcome; fully tested support for every macOS version and hardware variant cannot currently be guaranteed.
Apple Silicon Macs require the package marked `arm64`. Intel Macs require the package marked `x86_64`.
1. Download the appropriate DMG file.
2. Open the DMG file.
3. Drag `KST4Contest.app` into your **Applications** folder.
4. On first launch, macOS may show a warning because the app is not notarised. To open it:
- Right-click (or Control-click) on `KST4Contest.app` in Finder and choose **Open**.
- Alternatively, go to **System Settings → Privacy & Security** and click **Open Anyway**.
5. Run KST4Contest from your Applications folder or Launchpad.
3. Drag `KST4Contest.app` into the **Applications** folder.
4. Start KST4Contest from the Applications folder or Launchpad.
Settings are stored at `~/.praktikst/preferences.xml`.
The application is not currently notarized by Apple. macOS may therefore block the first launch.
If the application came from the official GitHub Release:
1. Open the Applications folder in Finder.
2. Right-click or Control-click `KST4Contest.app`.
3. Select **Open**.
4. Confirm the launch in the dialog that appears.
Alternatively, macOS may provide an **Open Anyway** button under **System Settings → Privacy & Security**.
---
## Updating
## Where are the settings stored?
KST4Contest includes an **automatic update notification service**: as soon as a new version is available, a window will appear at startup with:
- information that a new version is available,
- a changelog,
- the download link for the new version.
KST4Contest stores its settings and other local working files in the users home directory. The application directory and the data directory are separate.
![Example Update Window](update_window.png)
| Operating system | Data directory | Settings file |
|---|---|---|
| Windows | `%USERPROFILE%\.praktiKST\` | `%USERPROFILE%\.praktiKST\preferences.xml` |
| Linux | `~/.praktiKST/` | `~/.praktiKST/preferences.xml` |
| macOS | `~/.praktiKST/` | `~/.praktiKST/preferences.xml` |
### Update Process
#### Windows
Currently, there is only one way to update:
1. Delete the old folder.
2. Unzip the new ZIP file.
The settings file (`preferences.xml`) is preserved because it is stored in the user folder, not the program folder.
#### Linux
- **AppImage**: Download the new AppImage, make it executable (`chmod +x`), optionally delete the old one.
- **Debian/Ubuntu**: `sudo apt install ./KST4Contest-v<version>-debian-amd64.deb`
- **Fedora/RHEL**: `sudo dnf upgrade ./KST4Contest-v<version>-fedora-x86_64.rpm`
- **Arch Linux**: `sudo pacman -U KST4Contest-v<version>-archlinux-x86_64.pkg.tar.zst`
- **Flatpak (repository)**: `flatpak update` updates all Flatpak apps including KST4Contest.
#### macOS
1. Download the new DMG file.
2. Open the DMG.
3. Drag the new `KST4Contest.app` into your **Applications** folder, replacing the old version.
Note the spelling `.praktiKST` with an uppercase `KST`. Linux and macOS distinguish between uppercase and lowercase letters. `.praktikst` would simply be a different directory.
An application update does not remove this directory. Even so, creating a backup before a major version change or extensive configuration work is sensible.
---
## Known Issues at Startup
## Updates
### Norton 360
When KST4Contest starts, it checks whether a newer Stable release is available. If it finds one, it displays an information window containing:
Norton 360 classifies `praktiKST.exe` as dangerous (false positive). An exception must be created for the file:
- the installed version,
- the latest Stable version,
- a short overview of the main changes,
- the changelog,
- known issues,
- a link to the corresponding GitHub Release page.
1. Open Norton 360.
2. Security → History → Find the corresponding event.
3. Select "Restore & Add Exception".
![KST4Contest update notification](update_window.png)
*(Reported by PE0WGA, Franz van Velzen thank you!)*
The update checker does not install anything. It reports the new version and opens the platform-neutral release page. From there, you must select the appropriate package for Windows, Linux or macOS.
### Updating Windows
1. Close KST4Contest.
2. Download the new Windows ZIP package.
3. Extract it into a new or empty directory.
4. Start the new version.
5. Check that the existing settings have been loaded.
6. Remove the old application directory only after that.
The settings are preserved because they are stored under `%USERPROFILE%\.praktiKST`, not in the application directory.
### Updating an AppImage
1. Download the new AppImage.
2. Make it executable.
3. Start the new file.
4. Remove the previous AppImage only after the new version works.
### Updating Debian and Ubuntu
```bash
sudo apt install ./KST4Contest-v<version>-debian-amd64.deb
```
### Updating Fedora
```bash
sudo dnf upgrade ./KST4Contest-v<version>-fedora-x86_64.rpm
```
### Updating the Arch package
```bash
sudo pacman -U KST4Contest-v<version>-archlinux-x86_64.pkg.tar.zst
```
### Updating an AUR package
Update the installed package through the selected AUR helper, for example:
```bash
yay -Syu
```
### Updating Flatpak
```bash
flatpak update de.x08.KST4Contest
```
### Updating macOS
1. Download the new DMG file for the appropriate architecture.
2. Close KST4Contest.
3. Open the DMG file.
4. Replace `KST4Contest.app` in the Applications folder.
5. Start the new version and check the existing settings.
The configuration under `~/.praktiKST` is not affected.
---
## Problems during the first launch
### Windows reports an unknown application
KST4Contest is not currently signed with a commercial Windows code-signing certificate. Windows or an additional security product may therefore warn about an unknown or rarely downloaded application.
Check the following first:
- Did the file come from the [official KST4Contest release](https://github.com/praktimarc/kst4contest/releases/latest)?
- Does the filename match the published release?
- Was the file downloaded completely?
- Does the security product report a specific detection name or only a general reputation warning?
A warning alone is neither reliable proof of malware nor automatically a false positive. If the origin of the file is unclear, do not run it or restore it from quarantine.
Some users have reported quarantine messages from Norton 360 in particular. If the warning can be reproduced, please create a [GitHub issue](https://github.com/praktimarc/kst4contest/issues) and include:
- the KST4Contest version,
- the complete filename,
- the security product and its version,
- the reported detection name,
- a screenshot of the warning, if possible.
### The AppImage does not start
Check the executable permission first:
```bash
chmod +x KST4Contest-v<version>-linux-x86_64.AppImage
```
Then start the file from a terminal. Error messages shown there are usually more useful than a double-click that simply produces no visible result.
### macOS blocks the application
Use the **Open** function described under [Installing on macOS](#installing-on-macos). Before doing so, verify that the DMG file came from the official GitHub Release.
### The problem remains
First check whether the problem has already been reported under [GitHub Issues](https://github.com/praktimarc/kst4contest/issues). If it has not, create a new issue containing:
- the operating system and version,
- the KST4Contest version,
- the installation method,
- the exact error message,
- the steps required to reproduce the problem.
“It does not work” usually describes the situation accurately, but it is of limited value during diagnosis.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 48 KiB

+16
View File
@@ -0,0 +1,16 @@
pkgbase = kst4contest-bin
pkgdesc = ON4KST Chat Client for VHF/UHF contest operation (pre-built)
pkgver = 1.41.1
pkgrel = 1
url = https://github.com/praktimarc/kst4contest
arch = x86_64
license = GPL-3.0-only
depends = gst-plugins-base
depends = gst-plugins-good
provides = kst4contest
conflicts = kst4contest
conflicts = kst4contest-git
source = KST4Contest-v1.41.1-archlinux-x86_64.pkg.tar.zst::https://github.com/praktimarc/kst4contest/releases/download/v1.41.1/KST4Contest-v1.41.1-archlinux-x86_64.pkg.tar.zst
sha256sums = 8e9a53ff832920c9ef2733635b90c5a4ffcd57a2958aaa251e92bd031142c614
pkgname = kst4contest-bin
+17
View File
@@ -0,0 +1,17 @@
# Maintainer: Philipp Wagner <philipp@wagnersnetz.de>
pkgname=kst4contest-bin
pkgver=1.41.1
pkgrel=1
pkgdesc="ON4KST Chat Client for VHF/UHF contest operation (pre-built)"
arch=('x86_64')
url="https://github.com/praktimarc/kst4contest"
license=('GPL-3.0-only')
depends=('gst-plugins-base' 'gst-plugins-good')
provides=('kst4contest')
conflicts=('kst4contest' 'kst4contest-git')
source=("KST4Contest-v${pkgver}-archlinux-${CARCH}.pkg.tar.zst::https://github.com/praktimarc/kst4contest/releases/download/v${pkgver}/KST4Contest-v${pkgver}-archlinux-${CARCH}.pkg.tar.zst")
sha256sums=('8e9a53ff832920c9ef2733635b90c5a4ffcd57a2958aaa251e92bd031142c614')
package() {
cp -a "${srcdir}/usr" "${pkgdir}/"
}
+19
View File
@@ -0,0 +1,19 @@
pkgbase = kst4contest-git
pkgdesc = ON4KST Chat Client for VHF/UHF contest operation (git)
pkgver = 1.42.0.r145.gd885924
pkgrel = 1
url = https://github.com/praktimarc/kst4contest
arch = x86_64
license = GPL-3.0-only
makedepends = java-environment=21
makedepends = maven
makedepends = git
depends = gst-plugins-base
depends = gst-plugins-good
provides = kst4contest
conflicts = kst4contest
conflicts = kst4contest-bin
source = kst4contest::git+https://github.com/praktimarc/kst4contest.git
sha256sums = SKIP
pkgname = kst4contest-git
+76
View File
@@ -0,0 +1,76 @@
# Maintainer: Philipp Wagner <philipp@wagnersnetz.de>
pkgname=kst4contest-git
pkgver=1.42.0.r145.gd885924
pkgrel=1
pkgdesc="ON4KST Chat Client for VHF/UHF contest operation (git)"
arch=('x86_64')
url="https://github.com/praktimarc/kst4contest"
license=('GPL-3.0-only')
depends=('gst-plugins-base' 'gst-plugins-good')
makedepends=('java-environment=21' 'maven' 'git')
provides=('kst4contest')
conflicts=('kst4contest' 'kst4contest-bin')
source=("kst4contest::git+https://github.com/praktimarc/kst4contest.git")
sha256sums=('SKIP')
pkgver() {
cd "${srcdir}/kst4contest"
BASE=$(grep -m1 '<version>' pom.xml \
| sed 's/.*<version>\(.*\)<\/version>.*/\1/' | sed 's/[-.]nightly//')
printf '%s.r%s.g%s' "${BASE}" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}
build() {
cd "${srcdir}/kst4contest"
export JAVA_HOME=$(find /usr/lib/jvm -maxdepth 1 -name 'java-21-*' -type d | head -n 1)
export PATH="${JAVA_HOME}/bin:${PATH}"
mvn -B -DskipTests package dependency:copy-dependencies \
-DincludeScope=runtime \
-DoutputDirectory=target/dist-libs
cp "$(ls -t target/praktiKST-*.jar | head -n 1)" target/dist-libs/app.jar
mkdir -p dist
jpackage \
--type app-image \
--name KST4Contest \
--input target/dist-libs \
--main-jar app.jar \
--main-class kst4contest.view.Kst4ContestApplication \
--module-path target/dist-libs \
--add-modules javafx.controls,javafx.graphics,javafx.fxml,javafx.web,javafx.media,java.sql,java.net.http,jdk.crypto.ec \
--dest dist
}
package() {
cd "${srcdir}/kst4contest"
install -dm755 "${pkgdir}/usr/lib/KST4Contest"
cp -a dist/KST4Contest/. "${pkgdir}/usr/lib/KST4Contest/"
install -dm755 "${pkgdir}/usr/bin"
printf '#!/bin/sh\nexec /usr/lib/KST4Contest/bin/KST4Contest "$@"\n' \
> "${pkgdir}/usr/bin/KST4Contest"
chmod 755 "${pkgdir}/usr/bin/KST4Contest"
install -dm755 "${pkgdir}/usr/share/applications"
cat > "${pkgdir}/usr/share/applications/KST4Contest.desktop" << 'EOF'
[Desktop Entry]
Type=Application
Name=KST4Contest
Comment=ON4KST Chat Client for VHF/UHF contest operation
Exec=KST4Contest
Icon=KST4Contest
Categories=Network;HamRadio;
Terminal=false
EOF
if [[ -f "${pkgdir}/usr/lib/KST4Contest/lib/KST4Contest.png" ]]; then
install -Dm644 "${pkgdir}/usr/lib/KST4Contest/lib/KST4Contest.png" \
"${pkgdir}/usr/share/icons/hicolor/256x256/apps/KST4Contest.png"
fi
install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
}
+18
View File
@@ -0,0 +1,18 @@
pkgbase = kst4contest
pkgdesc = ON4KST Chat Client for VHF/UHF contest operation
pkgver = 1.41.1
pkgrel = 1
url = https://github.com/praktimarc/kst4contest
arch = x86_64
license = GPL-3.0-only
makedepends = java-environment=21
makedepends = maven
depends = gst-plugins-base
depends = gst-plugins-good
provides = kst4contest
conflicts = kst4contest-bin
conflicts = kst4contest-git
source = kst4contest-1.41.1.tar.gz::https://github.com/praktimarc/kst4contest/archive/refs/tags/v1.41.1.tar.gz
sha256sums = e96207a2d3fee19d35e34717f5312beb28bb087c040164e352337e749ce53b8d
pkgname = kst4contest
+69
View File
@@ -0,0 +1,69 @@
# Maintainer: Philipp Wagner <philipp@wagnersnetz.de>
pkgname=kst4contest
pkgver=1.41.1
pkgrel=1
pkgdesc="ON4KST Chat Client for VHF/UHF contest operation"
arch=('x86_64')
url="https://github.com/praktimarc/kst4contest"
license=('GPL-3.0-only')
depends=('gst-plugins-base' 'gst-plugins-good')
makedepends=('java-environment=21' 'maven')
provides=('kst4contest')
conflicts=('kst4contest-bin' 'kst4contest-git')
source=("${pkgname}-${pkgver}.tar.gz::https://github.com/praktimarc/kst4contest/archive/refs/tags/v${pkgver}.tar.gz")
sha256sums=('e96207a2d3fee19d35e34717f5312beb28bb087c040164e352337e749ce53b8d')
build() {
cd "${srcdir}/kst4contest-${pkgver}"
export JAVA_HOME=$(find /usr/lib/jvm -maxdepth 1 -name 'java-21-*' -type d | head -n 1)
export PATH="${JAVA_HOME}/bin:${PATH}"
mvn -B -DskipTests package dependency:copy-dependencies \
-DincludeScope=runtime \
-DoutputDirectory=target/dist-libs
cp "$(ls -t target/praktiKST-*.jar | head -n 1)" target/dist-libs/app.jar
mkdir -p dist
jpackage \
--type app-image \
--name KST4Contest \
--input target/dist-libs \
--main-jar app.jar \
--main-class kst4contest.view.Kst4ContestApplication \
--module-path target/dist-libs \
--add-modules javafx.controls,javafx.graphics,javafx.fxml,javafx.web,javafx.media,java.sql,java.net.http,jdk.crypto.ec \
--dest dist
}
package() {
cd "${srcdir}/kst4contest-${pkgver}"
install -dm755 "${pkgdir}/usr/lib/KST4Contest"
cp -a dist/KST4Contest/. "${pkgdir}/usr/lib/KST4Contest/"
install -dm755 "${pkgdir}/usr/bin"
printf '#!/bin/sh\nexec /usr/lib/KST4Contest/bin/KST4Contest "$@"\n' \
> "${pkgdir}/usr/bin/KST4Contest"
chmod 755 "${pkgdir}/usr/bin/KST4Contest"
install -dm755 "${pkgdir}/usr/share/applications"
cat > "${pkgdir}/usr/share/applications/KST4Contest.desktop" << 'EOF'
[Desktop Entry]
Type=Application
Name=KST4Contest
Comment=ON4KST Chat Client for VHF/UHF contest operation
Exec=KST4Contest
Icon=KST4Contest
Categories=Network;HamRadio;
Terminal=false
EOF
if [[ -f "${pkgdir}/usr/lib/KST4Contest/lib/KST4Contest.png" ]]; then
install -Dm644 "${pkgdir}/usr/lib/KST4Contest/lib/KST4Contest.png" \
"${pkgdir}/usr/share/icons/hicolor/256x256/apps/KST4Contest.png"
fi
install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
}
+1 -1
View File
@@ -6,7 +6,7 @@
<groupId>de.x08</groupId>
<artifactId>praktiKST</artifactId>
<version>1.41.0-nightly</version>
<version>1.42.0-nightly</version>
<name>praktiKST</name>
@@ -18,11 +18,18 @@ public class ApplicationConstants {
public static final String APPLICATION_NAME = "praktiKST";
/**
* Name of file to store preferences in.
* Version shown to the user and used for semantic version comparison.
*/
public static final double APPLICATION_CURRENTVERSIONNUMBER = 1.41;
public static final String APPLICATION_CURRENT_VERSION = "1.42";
public static final String VERSIONINFOURLFORUPDATES_KST4CONTEST = "https://do5amf.funkerportal.de/kst4ContestVersionInfo.xml";
/**
* Legacy numeric representation used only while older update feeds and
* application versions still exist.
*/
@Deprecated
public static final double APPLICATION_CURRENTVERSIONNUMBER = 1.42;
public static final String VERSIONINFOURLFORUPDATES_KST4CONTEST = "https://kst4contest.hamradioonline.de/kst4ContestVersionInfo.xml";
public static final String VERSIONINFDOWNLOADEDLOCALFILE = "kst4ContestVersionInfo.xml";
public static final String STYLECSSFILE_DEFAULT_DAYLIGHT = "KST4ContestDefaultDay.css";
@@ -48,7 +48,8 @@ public class BeaconTask extends TimerTask {
replaceVariables = replaceVariables.replaceAll("MYCALL", this.chatController.getChatPreferences().getStn_loginCallSign());
replaceVariables = replaceVariables.replaceAll("MYLOCATOR", this.chatController.getChatPreferences().getStn_loginLocatorMainCat());
replaceVariables = replaceVariables.replaceAll("MYQTF", this.chatController.getChatPreferences().getActualQTF().getValue() + "");
replaceVariables = replaceVariables.replaceAll("SECONDQRG", this.chatController.getChatPreferences().getActualQTF().getValue() + "");
replaceVariables = replaceVariables.replaceAll("SECONDQRG", this.chatController.getChatPreferences().getMYQRGSecondCat().getValue() + "");
beaconMSG.setMessageText(
@@ -24,6 +24,7 @@ import kst4contest.logic.PriorityCalculator;
import kst4contest.model.*;
import kst4contest.test.MockKstServer;
import kst4contest.utils.PlayAudioUtils;
import kst4contest.locatorUtils.Location;
import kst4contest.view.Kst4ContestApplication;
import java.io.*;
@@ -34,6 +35,7 @@ import java.util.function.Predicate;
/**
*
* Central Chat kst4contest.controller. Instantiate only one time per category of kst Chat.
@@ -162,11 +164,13 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList
public void initRotor() {
// Beispiel: PSTRotator läuft lokal auf Port 12060
// Der Client wird automatisch auf 12061 hören.
rotatorClient = new PstRotatorClient("127.0.0.1", 12000, this, this); //TODO: IP anpassen, Port auch aus den prefs holen, default 12000
rotatorClient = new PstRotatorClient(
chatPreferences.getStn_pstRotatorHost(),
chatPreferences.getStn_pstRotatorPort(),
this,
this
);
// Startet den Thread und das Polling
rotatorClient.start();
}
@@ -318,10 +322,8 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList
EnumSet<Band> offered = EnumSet.noneOf(Band.class);
synchronized (getLst_chatMemberList()) {
for (ChatMember cm : getLst_chatMemberList()) {
for (ChatMember cm : findActiveChatMembersByRawCall(callRaw)) {
if (cm == null || cm.getCallSignRaw() == null) continue;
if (!normalizeCallRaw(cm.getCallSignRaw()).equals(callRaw)) continue;
Map<Band, ChatMember.ActiveFrequencyInfo> map = cm.getKnownActiveBands();
if (map == null || map.isEmpty()) continue;
@@ -340,11 +342,9 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList
+ " freq=" + e.getValue().frequency
+ " ageMs=" + age);
}
}
}
}
}
}
return offered;
}
@@ -356,10 +356,8 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList
EnumSet<Band> worked = EnumSet.noneOf(Band.class);
synchronized (getLst_chatMemberList()) {
for (ChatMember cm : getLst_chatMemberList()) {
for (ChatMember cm : findActiveChatMembersByRawCall(callRaw)) {
if (cm == null || cm.getCallSignRaw() == null) continue;
if (!normalizeCallRaw(cm.getCallSignRaw()).equals(callRaw)) continue;
if (cm.isWorked144()) worked.add(Band.B_144);
if (cm.isWorked432()) worked.add(Band.B_432);
@@ -368,9 +366,9 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList
if (cm.isWorked3400()) worked.add(Band.B_3400);
if (cm.isWorked5600()) worked.add(Band.B_5760);
if (cm.isWorked10G()) worked.add(Band.B_10G);
if (cm.isWorked24G()) worked.add(Band.B_24G); // optional, only if your Band enum supports it
}
if (cm.isWorked24G()) worked.add(Band.B_24G);
}
return worked;
}
@@ -645,7 +643,8 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList
// rotatorClient.
this.lst_chatMemberList.clear();;
// this.lst_chatMemberList.clear();;
this.clearActiveChatMembers();
this.lst_clusterMemberList.clear();
this.setDisconnected(true);
@@ -713,7 +712,7 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList
}
} else if (action.equals(ApplicationConstants.DISCSTRING_DISCONNECTONLY)){
this.lst_chatMemberList.clear();;
this.clearActiveChatMembers();
this.lst_clusterMemberList.clear();
@@ -959,16 +958,9 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList
if (targetCallsignRaw == null || targetCallsignRaw.isBlank()) {
return null;
}
String normalizedTargetCall = normalizeCallRaw(targetCallsignRaw);
synchronized (getLst_chatMemberList()) {
for (ChatMember member : getLst_chatMemberList()) {
if (member == null || member.getCallSignRaw() == null) continue;
if (normalizeCallRaw(member.getCallSignRaw()).equals(normalizedTargetCall)) {
return member;
}
}
}
return null;
List<ChatMember> matchingMembers = findActiveChatMembersByRawCall(targetCallsignRaw);
return matchingMembers.isEmpty() ? null : matchingMembers.get(0);
}
private String resolveSkedTargetLocator(String targetCallsignRaw) {
@@ -976,22 +968,43 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList
return null;
}
String normalizedTargetCall = normalizeCallRaw(targetCallsignRaw);
synchronized (getLst_chatMemberList()) {
for (ChatMember member : getLst_chatMemberList()) {
if (member == null || member.getCallSignRaw() == null) continue;
if (!normalizeCallRaw(member.getCallSignRaw()).equals(normalizedTargetCall)) continue;
for (ChatMember member : findActiveChatMembersByRawCall(targetCallsignRaw)) {
String locator = member.getQra();
if (locator != null && !locator.isBlank()) {
return locator.trim().toUpperCase(Locale.ROOT);
}
}
}
return null;
}
// private ChatMember resolveSkedTargetMember(String targetCallsignRaw) {
// if (targetCallsignRaw == null || targetCallsignRaw.isBlank()) {
// return null;
// }
//
// List<ChatMember> matchingMembers = findActiveChatMembersByRawCall(targetCallsignRaw);
// return matchingMembers.isEmpty() ? null : matchingMembers.get(0);
//
// }
//
// private String resolveSkedTargetLocator(String targetCallsignRaw) {
// if (targetCallsignRaw == null || targetCallsignRaw.isBlank()) {
// return null;
// }
//
// String normalizedTargetCall = normalizeCallRaw(targetCallsignRaw);
//
// for (ChatMember member : findActiveChatMembersByRawCall(targetCallsignRaw)) {
// String locator = member.getQra();
// if (locator != null && !locator.isBlank()) {
// return locator.trim().toUpperCase(Locale.ROOT);
// }
// }
//
// return null;
// }
public StationMetricsService getStationMetricsService() {
return stationMetricsService;
}
@@ -1014,10 +1027,14 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList
return new HashMap<>(lastInboundCategoryByCallSignRaw);
}
// public List<ChatMember> snapshotChatMembers() {
// synchronized (getLst_chatMemberList()) {
// return new ArrayList<>(getLst_chatMemberList());
// }
// }
public List<ChatMember> snapshotChatMembers() {
synchronized (getLst_chatMemberList()) {
return new ArrayList<>(getLst_chatMemberList());
}
return new ArrayList<>(activeChatMembersByCallAndCategory.values());
}
public List<ContestSked> snapshotActiveSkeds() {
@@ -1126,13 +1143,27 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList
private ObservableList<ChatMember> chatMemberList = FXCollections.observableArrayList(); // List of active stations
private ObservableList<ChatMember> lst_chatMemberList = FXCollections.synchronizedObservableList(chatMemberList); // List
// of active stn in chat
private FilteredList<ChatMember> lst_chatMemberListFiltered = new FilteredList<ChatMember>(chatMemberList);
private SortedList<ChatMember> lst_chatMemberSortedFilteredList = new SortedList<ChatMember>(lst_chatMemberListFiltered);
private ObservableList<ChatMember> lst_chatMemberList = FXCollections.synchronizedObservableList(chatMemberList); // List
private ObservableList<Predicate<ChatMember>> lst_chatMemberListFilterPredicates = FXCollections.observableArrayList();
private ObservableList<ClusterMessage> lst_clusterMemberList = FXCollections.observableArrayList();
/*
* Thread-safe active-member model.
*
* MessageBusManagementThread must not use the JavaFX TableView backing list as
* its primary data model. Otherwise every add/remove fires FilteredList,
* SortedList and TableView selection listeners on the MessageBus thread and JavaFX
* can throw "Not on FX application thread" or internal listener NPEs.
*
* This map is the worker-thread safe source of truth. The ObservableList below
* remains a UI mirror and is mutated only on the JavaFX application thread.
*/
private final java.util.concurrent.ConcurrentMap<String, ChatMember> activeChatMembersByCallAndCategory =
new java.util.concurrent.ConcurrentHashMap<>();
/*
* Message table update buffers.
@@ -1161,6 +1192,254 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList
// ******************************************************************************************************************************************
/**
* Executes UI-bound work on the JavaFX application thread.
*
* Worker threads may call this safely. If the caller is already on the FX
* thread, the action is executed immediately to preserve ordering.
*/
private void runOnFxThread(Runnable action) {
if (action == null) {
return;
}
if (Platform.isFxApplicationThread()) {
action.run();
} else {
Platform.runLater(action);
}
}
/**
* Builds the active-member key. The raw/base callsign alone is not enough
* because the same station can be logged into multiple ON4KST categories at
* the same time. Therefore the category number is part of the key.
*/
private String buildActiveChatMemberKey(String callSign, ChatCategory category) {
String normalizedCallsign = ChatMember.normalizeCallSignToBaseCallSign(callSign);
if (normalizedCallsign == null || normalizedCallsign.isBlank()) {
return null;
}
int categoryNumber = category == null ? -1 : category.getCategoryNumber();
return normalizedCallsign.trim().toUpperCase(Locale.ROOT) + "|" + categoryNumber;
}
private String buildActiveChatMemberKey(ChatMember member) {
if (member == null) {
return null;
}
String callSign = member.getCallSignRaw() != null ? member.getCallSignRaw() : member.getCallSign();
return buildActiveChatMemberKey(callSign, member.getChatCategory());
}
/**
* Adds or replaces an active chat member in the worker-thread model and mirrors
* that change to the JavaFX list. This is the only supported path for ON4KST
* user-enter events.
*/
public void addOrUpdateActiveChatMember(ChatMember member) {
String key = buildActiveChatMemberKey(member);
if (key == null) {
return;
}
activeChatMembersByCallAndCategory.put(key, member);
runOnFxThread(() -> {
int existingIndex = findChatMemberIndexInUiListByKey(key);
if (existingIndex >= 0) {
lst_chatMemberList.set(existingIndex, member);
} else {
lst_chatMemberList.add(member);
}
});
}
/**
* Removes an active chat member from the worker-thread model and from the UI
* mirror. Removal from the ObservableList is always performed on the FX thread
* because the list is bound to FilteredList/SortedList/TableView.
*/
public boolean removeActiveChatMember(ChatMember member) {
String key = buildActiveChatMemberKey(member);
if (key == null) {
return false;
}
ChatMember removedMember = activeChatMembersByCallAndCategory.remove(key);
runOnFxThread(() -> lst_chatMemberList.removeIf(currentMember -> key.equals(buildActiveChatMemberKey(currentMember))));
return removedMember != null;
}
/**
* Clears the active-member model and the JavaFX UI mirror. Use this instead of
* getLst_chatMemberList().clear() from timers or worker threads.
*/
public void clearActiveChatMembers() {
activeChatMembersByCallAndCategory.clear();
runOnFxThread(() -> lst_chatMemberList.clear());
}
/**
* Resolves a member from the thread-safe active model. This avoids reading the
* TableView backing list from MessageBusManagementThread.
*/
public ChatMember findActiveChatMember(ChatMember lookForThis) {
String key = buildActiveChatMemberKey(lookForThis);
return key == null ? null : activeChatMembersByCallAndCategory.get(key);
}
public ChatMember findActiveChatMember(String callSign, ChatCategory category) {
String key = buildActiveChatMemberKey(callSign, category);
return key == null ? null : activeChatMembersByCallAndCategory.get(key);
}
public int getActiveChatMemberCount() {
return activeChatMembersByCallAndCategory.size();
}
/**
* Returns all active category variants of a callsign. This is used when a QRG or
* band hint should be propagated from one category instance to the same station
* in another category.
*/
public List<ChatMember> findActiveChatMembersByRawCall(String callSignRaw) {
String normalizedCallsign = ChatMember.normalizeCallSignToBaseCallSign(callSignRaw);
if (normalizedCallsign == null || normalizedCallsign.isBlank()) {
return Collections.emptyList();
}
String normalizedKeyPart = normalizedCallsign.trim().toUpperCase(Locale.ROOT);
List<ChatMember> matchingMembers = new ArrayList<>();
for (ChatMember member : activeChatMembersByCallAndCategory.values()) {
if (member == null) {
continue;
}
String memberCall = member.getCallSignRaw() != null ? member.getCallSignRaw() : member.getCallSign();
String normalizedMemberCall = ChatMember.normalizeCallSignToBaseCallSign(memberCall);
if (normalizedMemberCall != null && normalizedMemberCall.equalsIgnoreCase(normalizedKeyPart)) {
matchingMembers.add(member);
}
}
return matchingMembers;
}
/**
* Updates locator and derived direction values in the active model. The UI list
* contains the same member object, but the user-list refresh is still triggered
* on the JavaFX thread so TableView/map derived displays can repaint safely.
*/
public boolean updateActiveChatMemberLocator(ChatMember lookupMember, String newLocator) {
ChatMember activeMember = findActiveChatMember(lookupMember);
if (activeMember == null) {
return false;
}
activeMember.setQra(newLocator);
activeMember.setQrb(new Location().getDistanceKmByTwoLocatorStrings(chatPreferences.getStn_loginLocatorMainCat(), newLocator));
activeMember.setQTFdirection(new Location(chatPreferences.getStn_loginLocatorMainCat()).getBearing(new Location(newLocator)));
fireUserListUpdate("Locator changed");
return true;
}
public boolean updateActiveChatMemberState(ChatMember lookupMember, int newState) {
ChatMember activeMember = findActiveChatMember(lookupMember);
if (activeMember == null) {
return false;
}
activeMember.setState(newState);
fireUserListUpdate("User state changed");
return true;
}
/**
* Applies a UM3-style user-info update only to an already active chat member.
*
* ON4KST may send UM3 messages for stations that are not logged into the
* current channel, for example when a user changes locator/profile data on the
* website. Such stations must not be added to the visible chat member list,
* because they cannot be addressed in the channel. Their full information will
* be delivered again with UA0/UA5/UA2 when they actually join.
*
* @return true if an active member was found and updated, false if the UM3
* information was intentionally ignored.
*/
public boolean updateActiveChatMemberInfoIfPresent(ChatMember updatedMember) {
String key = buildActiveChatMemberKey(updatedMember);
if (key == null) {
return false;
}
ChatMember activeMember = activeChatMembersByCallAndCategory.get(key);
if (activeMember == null) {
return false;
}
activeMember.setName(updatedMember.getName());
activeMember.setQra(updatedMember.getQra());
activeMember.setState(updatedMember.getState());
activeMember.setLastActivity(updatedMember.getLastActivity());
activeMember.setActivityTimeLastInEpoch(updatedMember.getActivityTimeLastInEpoch());
activeMember.setQrb(updatedMember.getQrb());
activeMember.setQTFdirection(updatedMember.getQTFdirection());
fireUserListUpdate("User info updated");
return true;
}
/**
* Backward-compatible wrapper for older call sites. Despite the historic name,
* this method no longer adds unknown UM3 users to the active member model.
*/
public boolean updateOrAddActiveChatMemberInfo(ChatMember updatedMember) {
return updateActiveChatMemberInfoIfPresent(updatedMember);
}
/**
* Stores a newly detected QRG/band on all active category variants of a station.
* The old StringProperty is still set for compatibility with existing TableView
* columns and DXCluster code.
*/
public void applyDetectedFrequencyToActiveMembers(ChatMember sender, Band detectedBand, double detectedFrequencyMhz) {
if (sender == null || detectedBand == null || detectedFrequencyMhz <= 0) {
return;
}
String displayFrequency = String.valueOf(detectedFrequencyMhz);
String rawCall = sender.getCallSignRaw() != null ? sender.getCallSignRaw() : sender.getCallSign();
for (ChatMember member : findActiveChatMembersByRawCall(rawCall)) {
if (member == null) {
continue;
}
member.addKnownFrequency(detectedBand, detectedFrequencyMhz);
member.setFrequency(new SimpleStringProperty(displayFrequency));
}
// Also cover dummy senders that are not in the active model, e.g. [n/a] senders.
sender.addKnownFrequency(detectedBand, detectedFrequencyMhz);
sender.setFrequency(new SimpleStringProperty(displayFrequency));
fireUserListUpdate("Frequency detected");
}
private int findChatMemberIndexInUiListByKey(String key) {
if (key == null) {
return -1;
}
for (int i = 0; i < lst_chatMemberList.size(); i++) {
if (key.equals(buildActiveChatMemberKey(lst_chatMemberList.get(i)))) {
return i;
}
}
return -1;
}
@@ -1916,7 +2195,11 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList
messageTXBus = new LinkedBlockingQueue<ChatMessage>();
// socket = new Socket(hostname, port);//socket for the on4kst chat server
socket = new Socket(chatController.chatPreferences.getStn_on4kstServersDns(), port);//socket for the on4kst chat server
socket = new Socket(
chatPreferences.getStn_on4kstServersDns(),
chatPreferences.getStn_on4kstServersPort()
);//socket for the on4kst chat server
System.out.println("Connected to the chat server: " + socket.isConnected());
ByteBuffer buffer = ByteBuffer.allocate(1024);
@@ -2011,7 +2294,7 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList
socket.close();
chatController.setConnectedAndLoggedIn(false);
chatController.getLst_chatMemberList().clear();
chatController.clearActiveChatMembers();
System.out.println("[Chatcontroller, Warning: ] Socket closed or disconnected");
@@ -2256,7 +2539,7 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList
String loginString = "";
loginString = "LOGINC|" + chatPreferences.getStn_loginCallSign() + "|" + chatPreferences.getStn_loginPassword()
+ "|" + chatPreferences.getLoginChatCategoryMain().getCategoryNumber() + "|praktiKST v" + ApplicationConstants.APPLICATION_CURRENTVERSIONNUMBER
+ "|" + chatPreferences.getLoginChatCategoryMain().getCategoryNumber() + "|praktiKST v" + ApplicationConstants.APPLICATION_CURRENT_VERSION
+ "|25|0|1|" + "0" + "|0|";
// System.out.println(loginString);
@@ -34,9 +34,9 @@ public class MessageBusManagementThread extends Thread {
private ThreadStatusCallback callBackToController;
private PrintWriter writer;
// private Socket socket;
// private Socket socket;
private ChatController client;
// private File fileLogRAW;
// private File fileLogRAW;
// private TimerTask userActualizationTask; // Is used as a temporary userout-print
// private TimerTask userActualizationTask; //kst4contest.test 4 23001
// private boolean serverReady = false; //kst4contest.test 4 23001
@@ -324,31 +324,12 @@ public class MessageBusManagementThread extends Thread {
// --- STEP 3: Process Result ---
if (finalDetectedBand != null && finalDetectedFrequency > 0) {
// 1. Store in the new Map (for future context/history)
sender.addKnownFrequency(finalDetectedBand, finalDetectedFrequency);
// No automatic full terrain analysis here.
// The frequency is stored for later map/manual reachability requests.
//propagate known frequency to all instances of the same callsign (callRaw may exist multiple times)
try {
ArrayList<Integer> sameCallIdx = client.checkListForChatMemberIndexesByCallSign(sender);
for (int idx : sameCallIdx) {
ChatMember cm = client.getLst_chatMemberList().get(idx);
if (cm != null && cm != sender) {
cm.addKnownFrequency(finalDetectedBand, finalDetectedFrequency);
// No automatic full terrain analysis here.
// Avoids exhausting the online terrain API when many stations mention QRGs.
}
}
} catch (Exception e) {
System.out.println("[SmartParser, warning]: failed to propagate known frequency across duplicates: " + e.getMessage());
}
// 2. Set the old String-Property for GUI compatibility
// We assume standard display format (MHz)
sender.setFrequency(new javafx.beans.property.SimpleStringProperty(String.valueOf(finalDetectedFrequency)));
/*
* Store the detected QRG in the thread-safe active-member model.
* The UI table is only a JavaFX mirror, so the MessageBus must not scan
* or mutate getLst_chatMemberList() here.
*/
client.applyDetectedFrequencyToActiveMembers(sender, finalDetectedBand, finalDetectedFrequency);
System.out.println("[SmartParser] Detected for " + sender.getCallSign() + ": " +
finalDetectedFrequency + " MHz (" + finalDetectedBand + ") " +
@@ -491,6 +472,92 @@ public class MessageBusManagementThread extends Thread {
return -1; // if it´s not found, the method will always end here and return -1
}
/**
* Creates a minimal receiver object for ON4KST broadcast messages.
* Keeping this as an object, not null, protects all downstream chat filters
* and debug logging from null receiver paths.
*/
private ChatMember createAllReceiver() {
ChatMember dummy = new ChatMember();
dummy.setCallSign("ALL");
dummy.setAirPlaneReflectInfo(new AirPlaneReflectionInfo());
return dummy;
}
/**
* Resolves a message sender from the thread-safe active-member model. If a
* CH/CR message arrives before the matching user-enter message, a marked
* fallback sender is used. The returned sender is never null.
*/
private ChatMember resolveInboundSender(String senderCallSign, ChatCategory category, ChatMessage message) {
ChatMember lookup = new ChatMember();
lookup.setCallSign(senderCallSign);
lookup.setChatCategory(category);
ChatMember senderObj = this.client.findActiveChatMember(lookup);
if (senderObj != null) {
senderObj.setActivityTimeLastInEpoch(new Utils4KST().time_generateCurrentEpochTime());
// Remember the last active category so later outgoing replies can be routed correctly.
this.client.rememberLastInboundCategory(senderObj.getCallSignRaw(), senderObj.getChatCategory());
// Metrics influence priority scoring; process them after message text is known.
this.client.getStationMetricsService().onInboundMessage(
senderObj.getCallSignRaw(),
System.currentTimeMillis(),
message == null ? null : message.getMessageText(),
this.client.getChatPreferences(),
this.client.getChatPreferences().getStn_loginCallSign()
);
this.client.getScoreService().requestRecompute("rx-chat-message");
return senderObj;
}
ChatMember fallbackSender = new ChatMember();
String myCall = this.client.getChatPreferences().getStn_loginCallSign();
if (senderCallSign != null && senderCallSign.equalsIgnoreCase(myCall)) {
fallbackSender.setCallSign(myCall);
} else {
fallbackSender.setCallSign("[n/a]" + senderCallSign);
}
fallbackSender.setChatCategory(category);
fallbackSender.setAirPlaneReflectInfo(new AirPlaneReflectionInfo());
return fallbackSender;
}
/**
* Resolves a message receiver from the active-member model. Unknown receivers
* are represented as explicit fallback objects instead of null. This keeps PM
* echo display and historic messages stable even if the target station already
* left the chat.
*/
private ChatMember resolveInboundReceiver(String receiverCallSign, ChatCategory category) {
if (receiverCallSign == null || receiverCallSign.equals("0")) {
return createAllReceiver();
}
ChatMember lookup = new ChatMember();
lookup.setCallSign(receiverCallSign);
lookup.setChatCategory(category);
ChatMember receiverObj = this.client.findActiveChatMember(lookup);
if (receiverObj != null) {
return receiverObj;
}
ChatMember fallbackReceiver = new ChatMember();
String myCall = this.client.getChatPreferences().getStn_loginCallSign();
if (receiverCallSign.equalsIgnoreCase(myCall)) {
fallbackReceiver.setCallSign(myCall);
} else {
fallbackReceiver.setCallSign(receiverCallSign + "(left)");
}
fallbackReceiver.setChatCategory(category);
fallbackReceiver.setAirPlaneReflectInfo(new AirPlaneReflectionInfo());
return fallbackReceiver;
}
/**
* Processes received messages via port 23001 (improved telnet Interface)
*
@@ -590,7 +657,7 @@ public class MessageBusManagementThread extends Thread {
if (!client.getChatPreferences().getStn_loginCallSign().equals(newMember.getCallSign())) {
this.client.getLst_chatMemberList().add(newMember); //the own call will not be in the list
this.client.addOrUpdateActiveChatMember(newMember); // the own call will not be in the list
// this.client.getReachabilityService().ensureAutoTropoMarginCalculated(newMember);
// Reachability is calculated on demand only: map click, selected station, or manual request.
}
@@ -637,7 +704,7 @@ public class MessageBusManagementThread extends Thread {
newMember = this.client.getDbHandler().fetchChatMemberWkdDataForOnlyOneCallsignFromDB(newMember);
this.client.getLst_chatMemberList().add(newMember);
this.client.addOrUpdateActiveChatMember(newMember);
// this.client.getReachabilityService().ensureAutoTropoMarginCalculated(newMember);
this.client.getDbHandler().storeChatMember(newMember);
@@ -665,17 +732,11 @@ public class MessageBusManagementThread extends Thread {
newMember.setCallSign(splittedMessageLine[2]);
System.out.println("[MSGBUSMGT, Info:] User left Chat and will be removed from list ["
+ this.client.getLst_chatMemberList().size() + "] :" + newMember.getCallSign());
try {
this.client.getLst_chatMemberList().remove(
checkListForChatMemberIndexByCallSign(this.client.getLst_chatMemberList(), newMember));
+ this.client.getActiveChatMemberCount() + "] :" + newMember.getCallSign());
//since 1.26 new method design to detect chatcategory, too!
} catch (Exception e) {
System.out.println("[MSGBUSMGT, EXC!, Error:] User sent left chat but had not been there ... ["
+ this.client.getLst_chatMemberList().size() + "] :" + newMember.getCallSign() + "\n"
+ e.getStackTrace());
if (!this.client.removeActiveChatMember(newMember)) {
System.out.println("[MSGBUSMGT, Info:] User sent left chat but was not active: "
+ newMember.getCallSign() + " / " + newMember.getChatCategory());
}
} else
@@ -695,9 +756,12 @@ public class MessageBusManagementThread extends Thread {
chategoryForMessageAndMessageSender = newMessageArrived.getChatCategory();
newMessageArrived.setMessageGeneratedTime(splittedMessageLine[2]);
newMessageArrived.setMessageSenderName(splittedMessageLine[4]);
newMessageArrived.setMessageText(splittedMessageLine[6]);
if (splittedMessageLine[3].equals("SERVER")) {
ChatMember dummy = new ChatMember();
dummy.setAirPlaneReflectInfo(new AirPlaneReflectionInfo());
dummy.setCallSign("SERVER");
dummy.setName("Sysop");
newMessageArrived.setSender(dummy);
@@ -707,77 +771,16 @@ public class MessageBusManagementThread extends Thread {
} else {
ChatMember sender = new ChatMember();
sender.setCallSign(splittedMessageLine[3]);
sender.setChatCategory(chategoryForMessageAndMessageSender);
int index = checkListForChatMemberIndexByCallSign(this.client.getLst_chatMemberList(), sender);
if (index != -1) {
//user not found in the chatmember list
try {
// newMessageArrived.setSender(this.client.getLst_chatMemberList().get(index)); // set sender to member of
// this.client.getLst_chatMemberList().get(index).setActivityTimeLastInEpoch(new Utils4KST().time_generateCurrentEpochTime());
ChatMember senderObj = this.client.getLst_chatMemberList().get(index);
newMessageArrived.setSender(senderObj);
senderObj.setActivityTimeLastInEpoch(new Utils4KST().time_generateCurrentEpochTime());
// Remember last inbound category per callsignRaw (required for correct send-routing later)
this.client.rememberLastInboundCategory(senderObj.getCallSignRaw(), senderObj.getChatCategory());
// Metrics for scoring: momentum, response-time, no-reply, positive signals
this.client.getStationMetricsService().onInboundMessage(
senderObj.getCallSignRaw(),
System.currentTimeMillis(),
newMessageArrived.getMessageText(),
this.client.getChatPreferences(),
this.client.getChatPreferences().getStn_loginCallSign()
);
// Activity/category changes influence priority => request recompute
this.client.getScoreService().requestRecompute("rx-chat-message");
} catch (Exception exc) {
ChatMember aSenderDummy = new ChatMember();
aSenderDummy.setCallSign(splittedMessageLine[3] + "[n/a]");
aSenderDummy.setAirPlaneReflectInfo(new AirPlaneReflectionInfo());
newMessageArrived.setSender(aSenderDummy);
System.out.println("MsgBusmgtT: Catched Error! " + exc.getMessage() + " // " + splittedMessageLine[3] + " is not in the list! Faking sender!");
exc.printStackTrace();
}
// b4 init list
} else {
//user not found in chatmember list, mark it, sender can not be set
if (!sender.getCallSign().equals(this.client.getChatPreferences().getStn_loginCallSign().toUpperCase())) {
sender.setCallSign("[n/a]" + sender.getCallSign());
// if someone sent a message without being in the userlist (cause
// on4kst missed implementing....), callsign will be marked
} else {
//that means, message was by own station, broadcasted to all other
ChatMember dummy = new ChatMember();
dummy.setCallSign("ALL");
newMessageArrived.setReceiver(dummy);
AirPlaneReflectionInfo preventNullpointerExc = new AirPlaneReflectionInfo();
preventNullpointerExc.setAirPlanesReachableCntr(0);
sender.setAirPlaneReflectInfo(preventNullpointerExc);
newMessageArrived.setSender(sender); //my own call is the sender
}
newMessageArrived.setSender(resolveInboundSender(
splittedMessageLine[3],
chategoryForMessageAndMessageSender,
newMessageArrived));
}
// newMessageArrived.setSender(this.client.getChatMemberTable().get(splittedMessageLine[3]));
}
newMessageArrived.setMessageSenderName(splittedMessageLine[4]);
newMessageArrived.setMessageText(splittedMessageLine[6]);
if (splittedMessageLine[7].equals("0")) {
// message is not directed to anyone, move it to the cq messages!
ChatMember dummy = new ChatMember();
dummy.setCallSign("ALL");
newMessageArrived.setReceiver(dummy);
// message is not directed to anyone, move it to the cq messages.
newMessageArrived.setReceiver(createAllReceiver());
this.client.publishChatMessage(newMessageArrived); // sdtout to all message-List (new from v1.7)
@@ -786,36 +789,9 @@ public class MessageBusManagementThread extends Thread {
} else {
//message is directed to another chatmember, process as such!
ChatMember receiver = new ChatMember();
receiver.setChatCategory(chategoryForMessageAndMessageSender); //got out of message itself
receiver.setCallSign(splittedMessageLine[7]);
int index = checkListForChatMemberIndexByCallSign(this.client.getLst_chatMemberList(), receiver);
if (index != -1) {
newMessageArrived.setReceiver(this.client.getLst_chatMemberList().get(index));// -1: Member left Chat
// before...
} else { //found in active member list
if (receiver.getCallSign().equals(client.getChatPreferences().getStn_loginCallSign())) {
/**
* If mycallsign sent a message to the server, server will publish that message and
* send it to all chatmember including me.
* As mycall is not in the userlist, the message would not been displayed if I handle
* it in the next case (marking left user, just for information). But I want an echo.
*/
receiver.setCallSign(client.getChatPreferences().getStn_loginCallSign());
newMessageArrived.setReceiver(receiver);
} else {
//this are user which left chat but had been adressed by this message
receiver.setCallSign(receiver.getCallSign() + "(left)");
newMessageArrived.setReceiver(receiver);
}
}
newMessageArrived.setReceiver(resolveInboundReceiver(
splittedMessageLine[7],
chategoryForMessageAndMessageSender));
// System.out.println("message directed to: " + newMessageArrived.getReceiver().getCallSign() + ". EQ?: " + this.client.getownChatMemberObject().getCallSign() + " sent by: " + newMessageArrived.getSender().getCallSign().toUpperCase() + " -> EQ?: "+ this.client.getChatPreferences().getLoginCallSign().toUpperCase());
@@ -853,7 +829,7 @@ public class MessageBusManagementThread extends Thread {
versionInfo.setSender(itsMe);
versionInfo.setReceiver(newMessageArrived.getSender());
versionInfo.setMessageText("/CQ " + newMessageArrived.getSender().getCallSign() + " " + ApplicationConstants.AUTOANSWER_PREFIX + " " + "KST4Contest " + " v" + ApplicationConstants.APPLICATION_CURRENTVERSIONNUMBER + " by DO5AMF");
versionInfo.setMessageText("/CQ " + newMessageArrived.getSender().getCallSign() + " " + ApplicationConstants.AUTOANSWER_PREFIX + " " + "KST4Contest " + " v" + ApplicationConstants.APPLICATION_CURRENT_VERSION + " by DO5AMF");
this.client.getMessageTXBus().add(versionInfo);
}
@@ -979,7 +955,21 @@ public class MessageBusManagementThread extends Thread {
// the "to me message list" with modified messagetext, added rxers callsign
} else {
//message sent to other user
/*
* Message sent from one other station to another other station.
*
* The old code reached this point only with members from the visible user list.
* With explicit fallback sender/receiver objects, this path may also see
* stations that already left the chat or arrived before their user-list entry.
* In that case locators may be missing, so angle/range analysis and DX spotting
* must be skipped while the chat message itself is still published.
*/
boolean senderHasLocator = newMessageArrived.getSender().getQra() != null
&& !newMessageArrived.getSender().getQra().isBlank();
boolean receiverHasLocator = newMessageArrived.getReceiver().getQra() != null
&& !newMessageArrived.getReceiver().getQra().isBlank();
if (senderHasLocator && receiverHasLocator) {
if (DirectionUtils.isInAngleAndRange(client.getChatPreferences().getStn_loginLocatorMainCat(),
newMessageArrived.getSender().getQra(),
newMessageArrived.getReceiver().getQra(),
@@ -998,7 +988,7 @@ public class MessageBusManagementThread extends Thread {
if (client.getChatPreferences().isNotify_dxClusterServerEnabled()) {
try {
if (newMessageArrived.getSender().getFrequency() != null) {
//TODO: testing for next version 3.33: addinitional information will be displayed in cluster if there is such an information
//TODO: testing for next version 3.33: additional information will be displayed in cluster if there is such information
ChatMember onlyForSpottingObject = new ChatMember();
onlyForSpottingObject.setCallSign(newMessageArrived.getSender().getCallSign());
onlyForSpottingObject.setFrequency(newMessageArrived.getSender().getFrequency());
@@ -1014,11 +1004,10 @@ public class MessageBusManagementThread extends Thread {
newMessageArrived.getSender().getAirPlaneReflectInfo().getRisingAirplanes().get(1).getPotential() + "%");
}
} else {
onlyForSpottingObject.setQra(newMessageArrived.getSender().getQra());
}
this.client.getDxClusterServer().broadcastSingleDXClusterEntryToLoggers(onlyForSpottingObject); //tells the DXCluster server to send a DXC message for this member to the logbook software
this.client.getDxClusterServer().broadcastSingleDXClusterEntryToLoggers(onlyForSpottingObject);
}
} catch (Exception exception) {
System.out.println("[MSGBUSMGT, ERROR:] DXCluster messageserver error while processing spot for 0: " + newMessageArrived.getSender().getCallSign() + " // " + exception.getMessage());
@@ -1036,14 +1025,21 @@ public class MessageBusManagementThread extends Thread {
" ; sender bearing to me: " + new Location(newMessageArrived.getSender().getQra()).getBearing(new Location(client.getChatPreferences().getStn_loginLocatorMainCat())));
newMessageArrived.getSender().setInAngleAndRange(false);
}
} else {
newMessageArrived.getSender().setInAngleAndRange(false);
System.out.println("[MSGBUSMGT, Info:] Skipping angle/range analysis for message with missing locator: "
+ newMessageArrived.getSender().getCallSign() + " -> "
+ newMessageArrived.getReceiver().getCallSign());
}
// this.client.getLst_globalChatMessageList().add(0, newMessageArrived);
this.client.publishChatMessage(newMessageArrived); // sdtout to all message-List (new from v1.7)
// System.out.println("MSGBS bgfx: tx call = " + newMessageArrived.getSender().getCallSign() + " / rx call = " + newMessageArrived.getReceiver().getCallSign());
}
} catch (NullPointerException referenceDeletedByUserLeftChatDuringMessageprocessing) {
System.out.println("MSGBS bgfx, <<<catched error>>>: referenced user left the chat during messageprocessing or message got before user entered chat message: " + referenceDeletedByUserLeftChatDuringMessageprocessing.getStackTrace());
// referenceDeletedByUserLeftChatDuringMessageprocessing.printStackTrace();
System.out.println("MSGBS bgfx, <<<catched error>>>: referenced user left the chat during messageprocessing or message got before user entered chat message: "
+ referenceDeletedByUserLeftChatDuringMessageprocessing.getMessage());
referenceDeletedByUserLeftChatDuringMessageprocessing.printStackTrace();
}
// sdtout to me message-List
@@ -1062,7 +1058,8 @@ public class MessageBusManagementThread extends Thread {
+ " " + newMessageArrived.getSender().getCallSign() + ", " + newMessageArrived.getMessageSenderName() + " -> "
+ newMessageArrived.getReceiver().getCallSign() + ": " + newMessageArrived.getMessageText());
} catch (Exception exceptionOccured) {
System.out.println("[MSGMgtBus: ERROR CHATCHED ON MAYBE NULL ISSUE]: " + exceptionOccured.getMessage() + "\n" + exceptionOccured.getStackTrace());
System.out.println("[MSGMgtBus: ERROR CHATCHED ON MAYBE NULL ISSUE]: " + exceptionOccured.getMessage());
exceptionOccured.printStackTrace();
}
// --- Band/QRG recognition (fills ChatMember.knownActiveBands) ---
@@ -1085,24 +1082,21 @@ public class MessageBusManagementThread extends Thread {
temp4.setQra(splittedMessageLine[3]);
temp4.setLastActivity(new Utils4KST().time_generateActualTimeInDateFormat());
int index = checkListForChatMemberIndexByCallSign(this.client.getLst_chatMemberList(), temp4);
if (index != -1) {
ChatMember foundThisInChatMemberList = this.client.findActiveChatMember(temp4);
if (foundThisInChatMemberList == null && this.client.getChatCategorySecondChat() != null) {
/*
* LOC messages do not carry the category. The old implementation checked
* only the main category. Try the second active category as a fallback so
* dual-channel operation can still update locator changes.
*/
temp4.setChatCategory(this.client.getChatCategorySecondChat());
foundThisInChatMemberList = this.client.findActiveChatMember(temp4);
}
if (foundThisInChatMemberList != null) {
System.out.println("[MSGBUSMGT:] Locator Change of [" + (splittedMessageLine[2] + "], old was: "
+ this.client.getLst_chatMemberList().get(index).getQra() + " new is: "
+ splittedMessageLine[3]));
ChatMember foundThisInChatMemberList = this.client.getLst_chatMemberList().get(index); //make less list accesses
// this.client.getLst_chatMemberList().get(index).setQra(splittedMessageLine[3]);
// this.client.getLst_chatMemberList().get(index).setQrb(new Location().getDistanceKmByTwoLocatorStrings(client.getChatPreferences().getLoginLocator(), splittedMessageLine[3]));
// this.client.getLst_chatMemberList().get(index).setQTFdirection(new Location(client.getChatPreferences().getLoginLocator()).getBearing(new Location(splittedMessageLine[3])));
foundThisInChatMemberList.setQra(splittedMessageLine[3]);
foundThisInChatMemberList.setQrb(new Location().getDistanceKmByTwoLocatorStrings(client.getChatPreferences().getStn_loginLocatorMainCat(), splittedMessageLine[3]));
foundThisInChatMemberList.setQTFdirection(new Location(client.getChatPreferences().getStn_loginLocatorMainCat()).getBearing(new Location(splittedMessageLine[3])));
+ foundThisInChatMemberList.getQra() + " new is: " + splittedMessageLine[3]));
this.client.updateActiveChatMemberLocator(temp4, splittedMessageLine[3]);
} else {
System.out.println("[MSGBUSMGT:] ERROR! Locator Change of ["
+ (splittedMessageLine[2] + "] is not possible, user is not in the Table!"));
@@ -1232,11 +1226,9 @@ public class MessageBusManagementThread extends Thread {
stateChangeMember.setChatCategory(util_getChatCategoryByCategoryNrString(splittedMessageLine[1]));
int index = checkListForChatMemberIndexByCallSign(this.client.getLst_chatMemberList(),
stateChangeMember);
if (index != -1 && index != 0) {
this.client.getLst_chatMemberList().get(index).setState(stateChangeMember.getState());
if (!this.client.updateActiveChatMemberState(stateChangeMember, stateChangeMember.getState())) {
System.out.println("[MSGBUSMGT, Info:] State change for inactive user: "
+ stateChangeMember.getCallSign() + " / " + stateChangeMember.getChatCategory());
}
// this.client.getChatMemberTable().get(stateChangeMember.getCallSign())
@@ -1249,31 +1241,43 @@ public class MessageBusManagementThread extends Thread {
*/
if (splittedMessageLine[0].contains(USERINFOUPDATEORUSERISBACK)) {
if (splittedMessageLine.length < 6) {
System.out.println("[MSGBUSMGT, warning:] Malformed UM3 message ignored: "
+ messageToProcess.getMessageText());
} else {
ChatMember stateChangeMember = new ChatMember();
stateChangeMember.setChatCategory(util_getChatCategoryByCategoryNrString(splittedMessageLine[1]));
stateChangeMember.setCallSign(splittedMessageLine[2]);
stateChangeMember.setName(splittedMessageLine[3]);
stateChangeMember.setQra(splittedMessageLine[4]);
stateChangeMember.setState(Integer.parseInt(splittedMessageLine[5]));
stateChangeMember.setLastActivity(new Utils4KST().time_generateActualTimeInDateFormat());
stateChangeMember.setQrb(new Location().getDistanceKmByTwoLocatorStrings(client.getChatPreferences().getStn_loginLocatorMainCat(), stateChangeMember.getQra()));
stateChangeMember.setQTFdirection(new Location(client.getChatPreferences().getStn_loginLocatorMainCat()).getBearing(new Location(stateChangeMember.getQra())));
stateChangeMember.setQrb(new Location().getDistanceKmByTwoLocatorStrings(
client.getChatPreferences().getStn_loginLocatorMainCat(),
stateChangeMember.getQra()));
stateChangeMember.setQTFdirection(new Location(client.getChatPreferences().getStn_loginLocatorMainCat())
.getBearing(new Location(stateChangeMember.getQra())));
this.client.getDbHandler().storeChatMember(stateChangeMember); // TODO: not clean, it should be an
// upodate
// System.out.println("[MSGBUSMGT:] DXCluster Message detected ");
int index = checkListForChatMemberIndexByCallSign(this.client.getLst_chatMemberList(),
stateChangeMember);
//-1 could be the case if mycall is processed
if (index != -1) {
this.client.getLst_chatMemberList().get(index).setName(stateChangeMember.getName());
this.client.getLst_chatMemberList().get(index).setQra(stateChangeMember.getQra());
this.client.getLst_chatMemberList().get(index).setState(stateChangeMember.getState());
/*
* UM3 is only an info/profile update. ON4KST also sends it for stations
* that are not logged into this channel. Such stations must not become
* visible chat members, otherwise the user could try to address an
* offline callsign and receive server-side errors.
*
* Therefore UM3 updates existing active members only. Unknown UM3 calls
* are intentionally ignored; if the station joins later, UA0/UA5/UA2
* will deliver the complete current user information again.
*/
if (!client.getChatPreferences().getStn_loginCallSign().equalsIgnoreCase(stateChangeMember.getCallSign())) {
boolean updatedActiveMember = this.client.updateActiveChatMemberInfoIfPresent(stateChangeMember);
if (updatedActiveMember) {
this.client.getDbHandler().storeChatMember(stateChangeMember); // TODO: not clean, it should be an update
} else {
System.out.println("[MSGBUSMGT, Info:] UM3 ignored for inactive user: "
+ stateChangeMember.getCallSign() + " / " + stateChangeMember.getChatCategory());
}
}
}
} else
@@ -1297,6 +1301,8 @@ public class MessageBusManagementThread extends Thread {
chategoryForMessageAndMessageSender = newMessageArrived.getChatCategory();
newMessageArrived.setMessageGeneratedTime(splittedMessageLine[2]);
newMessageArrived.setMessageSenderName(splittedMessageLine[4]);
newMessageArrived.setMessageText(splittedMessageLine[6]);
if (splittedMessageLine[3].equals("SERVER")) {
ChatMember dummy = new ChatMember();
@@ -1309,76 +1315,16 @@ public class MessageBusManagementThread extends Thread {
} else {
ChatMember sender = new ChatMember();
sender.setCallSign(splittedMessageLine[3]);
sender.setChatCategory(chategoryForMessageAndMessageSender);
int index = checkListForChatMemberIndexByCallSign(this.client.getLst_chatMemberList(), sender);
if (index != -1) {
//user not found in the chatmember list
try {
// newMessageArrived.setSender(this.client.getLst_chatMemberList().get(index)); // set sender to member of
// this.client.getLst_chatMemberList().get(index).setActivityTimeLastInEpoch(new Utils4KST().time_generateCurrentEpochTime());
ChatMember senderObj = this.client.getLst_chatMemberList().get(index);
newMessageArrived.setSender(senderObj);
senderObj.setActivityTimeLastInEpoch(new Utils4KST().time_generateCurrentEpochTime());
// Remember last inbound category per callsignRaw (required for correct send-routing later)
this.client.rememberLastInboundCategory(senderObj.getCallSignRaw(), senderObj.getChatCategory());
// Metrics for scoring: momentum, response-time, no-reply, positive signals
this.client.getStationMetricsService().onInboundMessage(
senderObj.getCallSignRaw(),
System.currentTimeMillis(),
newMessageArrived.getMessageText(),
this.client.getChatPreferences(),
this.client.getChatPreferences().getStn_loginCallSign()
);
// Activity/category changes influence priority => request recompute
this.client.getScoreService().requestRecompute("rx-chat-message");
} catch (Exception exc) {
ChatMember aSenderDummy = new ChatMember();
aSenderDummy.setCallSign(splittedMessageLine[3] + "[n/a]");
aSenderDummy.setAirPlaneReflectInfo(new AirPlaneReflectionInfo());
newMessageArrived.setSender(aSenderDummy);
System.out.println("MsgBusmgtT: Catched Error! " + exc.getMessage() + " // " + splittedMessageLine[3] + " is not in the list! Faking sender!");
exc.printStackTrace();
}
// b4 init list
} else {
//user not found in chatmember list, mark it, sender can not be set
if (!sender.getCallSign().equals(this.client.getChatPreferences().getStn_loginCallSign().toUpperCase())) {
sender.setCallSign("[n/a]" + sender.getCallSign());
// if someone sent a message without being in the userlist (cause
// on4kst missed implementing....), callsign will be marked
} else {
//that means, message was by own station, broadcasted to all other
ChatMember dummy = new ChatMember();
dummy.setCallSign("ALL");
newMessageArrived.setReceiver(dummy);
AirPlaneReflectionInfo preventNullpointerExc = new AirPlaneReflectionInfo();
preventNullpointerExc.setAirPlanesReachableCntr(0);
sender.setAirPlaneReflectInfo(preventNullpointerExc);
newMessageArrived.setSender(sender); //my own call is the sender
}
newMessageArrived.setSender(resolveInboundSender(
splittedMessageLine[3],
chategoryForMessageAndMessageSender,
newMessageArrived));
}
// newMessageArrived.setSender(this.client.getChatMemberTable().get(splittedMessageLine[3]));
}
newMessageArrived.setMessageSenderName(splittedMessageLine[4]);
newMessageArrived.setMessageText(splittedMessageLine[6]);
if (splittedMessageLine[7].equals("0")) {
// message is not directed to anyone, move it to the cq messages!
ChatMember dummy = new ChatMember();
dummy.setCallSign("ALL");
newMessageArrived.setReceiver(dummy);
// message is not directed to anyone, move it to the cq messages.
newMessageArrived.setReceiver(createAllReceiver());
// this.client.getLst_globalChatMessageList().add(0, newMessageArrived); // sdtout to all message-List
this.client.publishChatMessage(newMessageArrived); // sdtout to all message-List (new from v1.7)
@@ -1386,35 +1332,9 @@ public class MessageBusManagementThread extends Thread {
} else {
//message is directed to another chatmember, process as such!
ChatMember receiver = new ChatMember();
receiver.setChatCategory(chategoryForMessageAndMessageSender); //got out of message itself
receiver.setCallSign(splittedMessageLine[7]);
int index = checkListForChatMemberIndexByCallSign(this.client.getLst_chatMemberList(), receiver);
if (index != -1) {
newMessageArrived.setReceiver(this.client.getLst_chatMemberList().get(index));// -1: Member left Chat
// before...
} else { //found in active member list
if (receiver.getCallSign().equals(client.getChatPreferences().getStn_loginCallSign())) {
/**
* If mycallsign sent a message to the server, server will publish that message and
* send it to all chatmember including me.
* As mycall is not in the userlist, the message would not been displayed if I handle
* it in the next case (marking left user, just for information). But I want an echo.
*/
receiver.setCallSign(client.getChatPreferences().getStn_loginCallSign());
newMessageArrived.setReceiver(receiver);
} else {
//this are user which left chat but had been adressed by this message
receiver.setCallSign(receiver.getCallSign() + "(left)");
newMessageArrived.setReceiver(receiver);
}
}
newMessageArrived.setReceiver(resolveInboundReceiver(
splittedMessageLine[7],
chategoryForMessageAndMessageSender));
// System.out.println("message directed to: " + newMessageArrived.getReceiver().getCallSign() + ". EQ?: " + this.client.getownChatMemberObject().getCallSign() + " sent by: " + newMessageArrived.getSender().getCallSign().toUpperCase() + " -> EQ?: "+ this.client.getChatPreferences().getLoginCallSign().toUpperCase());
@@ -1447,7 +1367,16 @@ public class MessageBusManagementThread extends Thread {
} else {
//message sent to other user
if (DirectionUtils.isInAngleAndRange(client.getChatPreferences().getStn_loginLocatorMainCat(),
// message sent from one other station to another other station
boolean senderHasLocator = newMessageArrived.getSender().getQra() != null
&& !newMessageArrived.getSender().getQra().isBlank();
boolean receiverHasLocator = newMessageArrived.getReceiver().getQra() != null
&& !newMessageArrived.getReceiver().getQra().isBlank();
if (senderHasLocator && receiverHasLocator) {
if (DirectionUtils.isInAngleAndRange(
client.getChatPreferences().getStn_loginLocatorMainCat(),
newMessageArrived.getSender().getQra(),
newMessageArrived.getReceiver().getQra(),
client.getChatPreferences().getStn_maxQRBDefault(),
@@ -1456,17 +1385,24 @@ public class MessageBusManagementThread extends Thread {
newMessageArrived.getSender().setInAngleAndRange(true);
} else {
newMessageArrived.getSender().setInAngleAndRange(false);
}
} else {
/*
* Historic fallback senders/receivers may not have locators.
* The message is still valid and should be displayed, but angle/range
* analysis cannot be calculated without both locators.
*/
newMessageArrived.getSender().setInAngleAndRange(false);
}
// this.client.getLst_globalChatMessageList().add(0, newMessageArrived);
this.client.publishChatMessage(newMessageArrived); // sdtout to all message-List (new from v1.7)
this.client.publishChatMessage(newMessageArrived);
// System.out.println("MSGBS bgfx: tx call = " + newMessageArrived.getSender().getCallSign() + " / rx call = " + newMessageArrived.getReceiver().getCallSign());
}
} catch (NullPointerException referenceDeletedByUserLeftChatDuringMessageprocessing) {
System.out.println("MSGBS bgfx, <<<catched error>>>: referenced user left the chat during messageprocessing or message got before user entered chat message: " + referenceDeletedByUserLeftChatDuringMessageprocessing.getStackTrace());
// referenceDeletedByUserLeftChatDuringMessageprocessing.printStackTrace();
System.out.println("MSGBS bgfx, <<<catched error>>>: referenced user left the chat during messageprocessing or message got before user entered chat message: "
+ referenceDeletedByUserLeftChatDuringMessageprocessing.getMessage());
referenceDeletedByUserLeftChatDuringMessageprocessing.printStackTrace();
}
// sdtout to me message-List
@@ -1479,7 +1415,8 @@ public class MessageBusManagementThread extends Thread {
+ " " + newMessageArrived.getSender().getCallSign() + ", " + newMessageArrived.getMessageSenderName() + " -> "
+ newMessageArrived.getReceiver().getCallSign() + ": " + newMessageArrived.getMessageText());
} catch (Exception exceptionOccured) {
System.out.println("[MSGMgtBus: ERROR CHATCHED ON MAYBE NULL ISSUE]: " + exceptionOccured.getMessage() + "\n" + exceptionOccured.getStackTrace());
System.out.println("[MSGMgtBus: ERROR CHATCHED ON MAYBE NULL ISSUE]: " + exceptionOccured.getMessage());
exceptionOccured.printStackTrace();
}
// --- Band/QRG recognition (fills ChatMember.knownActiveBands) ---
@@ -1534,7 +1471,7 @@ public class MessageBusManagementThread extends Thread {
for (int i = 0; i < 10; i++) {
client.getLst_globalChatMessageList().add(pwErrorMsg);
client.publishChatMessage(pwErrorMsg);
// client.getLst_toMeMessageList().add(pwErrorMsg);
// client.getLst_toAllMessageList().add(pwErrorMsg);
}
@@ -1546,6 +1483,10 @@ public class MessageBusManagementThread extends Thread {
// this.client.disconnect();
}
else if (splittedMessageLine[0].equals("DE")) {
// DXCluster delimiter/end marker; intentionally ignored.
}
else {
// bufwrtrDBGMSGOut.write(new Utils4KST().time_generateCurrentMMDDhhmmTimeString()
@@ -1751,6 +1692,10 @@ public class MessageBusManagementThread extends Thread {
} catch (SQLException e) {
System.out.println("MsgBusMgt: process23001 went wrong / SQL Error");
e.printStackTrace();
} catch (RuntimeException e) {
System.out.println("MsgBusMgt: process23001 went wrong / Runtime Error while processing: "
+ messageTextRaw.getMessageText());
e.printStackTrace();
}
}
@@ -319,6 +319,14 @@ public class ReadUDPbyUCXMessageThread extends Thread {
NodeList list = doc.getElementsByTagName("contactinfo");
if (list.getLength() != 0) {
/*
* QSO and TRX information share the same UDP receiver. The log-sync
* preference therefore controls processing, not ownership of the socket.
*/
if (!client.getChatPreferences().isLogsynch_ucxUDPWkdCallListenerEnabled()) {
return "";
}
for (int temp = 0; temp < list.getLength(); temp++) {
Node node = list.item(temp);
@@ -591,6 +599,15 @@ public class ReadUDPbyUCXMessageThread extends Thread {
} else {
list = doc.getElementsByTagName("RadioInfo");
/*
* RadioInfo packets may arrive on the shared UDP port even when automatic
* QRG synchronization is disabled. Ignore them unless TRX sync is enabled.
*/
if (list.getLength() != 0
&& !client.getChatPreferences().isTrxSynch_ucxLogUDPListenerEnabled()) {
return "";
}
for (int temp = 0; temp < list.getLength(); temp++) {
Node node = list.item(temp);
@@ -108,6 +108,16 @@ public class UpdateChecker {
Element element = (Element) node;
updateInfos.setLatestVersionNumberOnServer(Double.parseDouble(element.getElementsByTagName("versionNumber").item(0).getTextContent()));
NodeList semanticVersionNodes =
element.getElementsByTagName("semanticVersion");
if (semanticVersionNodes.getLength() > 0) {
updateInfos.setLatestSemanticVersionOnServer(
semanticVersionNodes.item(0).getTextContent()
);
}
updateInfos.setAdminMessage(element.getElementsByTagName("adminMessage").item(0).getTextContent());
updateInfos.setMajorChanges(element.getElementsByTagName("majorChanges").item(0)
.getTextContent());
@@ -26,6 +26,14 @@ public class UserActualizationTask extends TimerTask {
Thread.currentThread().setName("UserActualizationTask");
/*
* File-based log synchronization is optional. Do not create, open or parse the
* configured file while the feature is disabled.
*/
if (!client.getChatPreferences().isLogsynch_fileBasedWkdCallInterpreterEnabled()) {
return;
}
// System.out.println("[Useract: ] Thread runned now");
// System.out.println("***********************Useract started");
@@ -159,6 +159,8 @@ public class ChatPreferences {
int stn_on4kstServersPort = 23001;
boolean stn_pstRotatorEnabled = false;
String stn_pstRotatorHost = "127.0.0.1";
int stn_pstRotatorPort = 12000;
boolean stn_loginAFKState = false; //always start as here
String stn_loginCallSign = "do5amf";
@@ -307,8 +309,8 @@ public class ChatPreferences {
String messageHandling_unworkedStnRequesterBeaconsText;
String messageHandling_beaconUnworkedstationsPrefix;
String messageHandling_autoAnswerTextMainCat = "Hi, sry I am not qrv, just testing new features of KST4Contest " + ApplicationConstants.APPLICATION_CURRENTVERSIONNUMBER;
String messageHandling_autoAnswerTextSecondCat = "Hi, sry I am not qrv, just testing new features of KST4Contest " + ApplicationConstants.APPLICATION_CURRENTVERSIONNUMBER;
String messageHandling_autoAnswerTextMainCat = "Hi, sry I am not qrv, just testing new features of KST4Contest " + ApplicationConstants.APPLICATION_CURRENT_VERSION;
String messageHandling_autoAnswerTextSecondCat = "Hi, sry I am not qrv, just testing new features of KST4Contest " + ApplicationConstants.APPLICATION_CURRENT_VERSION;
boolean messageHandling_autoAnswerEnabled = false;
boolean messageHandling_autoAnswerEnabledSecondCat = false;
@@ -761,6 +763,30 @@ public class ChatPreferences {
this.stn_pstRotatorEnabled = stn_pstRotatorEnabled;
}
public String getStn_pstRotatorHost() {
return stn_pstRotatorHost;
}
public void setStn_pstRotatorHost(String stn_pstRotatorHost) {
if (stn_pstRotatorHost == null || stn_pstRotatorHost.isBlank()) {
this.stn_pstRotatorHost = "127.0.0.1";
} else {
this.stn_pstRotatorHost = stn_pstRotatorHost.trim();
}
}
public int getStn_pstRotatorPort() {
return stn_pstRotatorPort;
}
public void setStn_pstRotatorPort(int stn_pstRotatorPort) {
if (stn_pstRotatorPort < 1 || stn_pstRotatorPort > 65535) {
this.stn_pstRotatorPort = 12000;
} else {
this.stn_pstRotatorPort = stn_pstRotatorPort;
}
}
public SimpleStringProperty getNotify_optionalFrequencyPrefix() {
return notify_optionalFrequencyPrefix;
}
@@ -1418,6 +1444,13 @@ public class ChatPreferences {
stn_pstRotatorEnabled.setTextContent(this.stn_pstRotatorEnabled + "");
station.appendChild(stn_pstRotatorEnabled);
Element stn_pstRotatorHost = doc.createElement("stn_pstRotatorHost");
stn_pstRotatorHost.setTextContent(this.stn_pstRotatorHost);
station.appendChild(stn_pstRotatorHost);
Element stn_pstRotatorPort = doc.createElement("stn_pstRotatorPort");
stn_pstRotatorPort.setTextContent(Integer.toString(this.stn_pstRotatorPort));
station.appendChild(stn_pstRotatorPort);
/**
@@ -2092,6 +2125,22 @@ public class ChatPreferences {
stn_pstRotatorEnabled = getBoolean(stationEl, stn_pstRotatorEnabled, "stn_pstRotatorEnabled");
setStn_pstRotatorHost(
getText(
stationEl,
stn_pstRotatorHost,
"stn_pstRotatorHost"
)
);
setStn_pstRotatorPort(
getInt(
stationEl,
stn_pstRotatorPort,
"stn_pstRotatorPort"
)
);
}
/**
@@ -3,7 +3,10 @@ package kst4contest.model;
import java.util.ArrayList;
public class UpdateInformation {
double latestVersionNumberOnServer = 1.26; //dummy value to prevent nullpointerexc
// double latestVersionNumberOnServer = 1.26; //dummy value to prevent nullpointerexc
double latestVersionNumberOnServer = 0.0;
String latestSemanticVersionOnServer = "";
String adminMessage ="";
String majorChanges ="";
String latestVersionPathOnWebserver="";
@@ -36,6 +39,27 @@ public class UpdateInformation {
public void setLatestVersionNumberOnServer(double latestVersionNumberOnServer) {
this.latestVersionNumberOnServer = latestVersionNumberOnServer;
}
public String getLatestSemanticVersionOnServer() {
return latestSemanticVersionOnServer;
}
public void setLatestSemanticVersionOnServer(String latestSemanticVersionOnServer) {
this.latestSemanticVersionOnServer =
latestSemanticVersionOnServer == null ? "" : latestSemanticVersionOnServer.trim();
}
public boolean hasSemanticVersion() {
return !latestSemanticVersionOnServer.isBlank();
}
public String getLatestVersionForDisplay() {
if (hasSemanticVersion()) {
return latestSemanticVersionOnServer;
}
return Double.toString(latestVersionNumberOnServer);
}
public String getAdminMessage() {
return adminMessage;
@@ -0,0 +1,68 @@
package kst4contest.utils;
public final class VersionUtils {
private VersionUtils() {
}
/**
* Compares numeric release versions such as 1.41, 1.41.1 and 1.41.10.
*
* Pre-release and build suffixes are ignored because the update feed
* currently publishes stable releases only.
*/
public static int compareStableVersions(String left, String right) {
int[] leftParts = parseVersion(left);
int[] rightParts = parseVersion(right);
int partCount = Math.max(leftParts.length, rightParts.length);
for (int index = 0; index < partCount; index++) {
int leftPart = index < leftParts.length ? leftParts[index] : 0;
int rightPart = index < rightParts.length ? rightParts[index] : 0;
int comparison = Integer.compare(leftPart, rightPart);
if (comparison != 0) {
return comparison;
}
}
return 0;
}
private static int[] parseVersion(String version) {
if (version == null || version.isBlank()) {
throw new IllegalArgumentException("Version must not be empty");
}
String normalized = version.trim();
if (normalized.startsWith("v") || normalized.startsWith("V")) {
normalized = normalized.substring(1);
}
int hyphenIndex = normalized.indexOf('-');
int plusIndex = normalized.indexOf('+');
int suffixIndex;
if (hyphenIndex < 0) {
suffixIndex = plusIndex;
} else if (plusIndex < 0) {
suffixIndex = hyphenIndex;
} else {
suffixIndex = Math.min(hyphenIndex, plusIndex);
}
if (suffixIndex >= 0) {
normalized = normalized.substring(0, suffixIndex);
}
String[] textParts = normalized.split("\\.");
int[] numericParts = new int[textParts.length];
for (int index = 0; index < textParts.length; index++) {
numericParts[index] = Integer.parseInt(textParts[index]);
}
return numericParts;
}
}
File diff suppressed because it is too large Load Diff
@@ -20,6 +20,7 @@ public record MapCallsignRawSnapshot(
double longitudeDeg,
String bandSummary,
Map<String, String> lastKnownFrequenciesByBand,
boolean offersSelectedBand,
boolean warningToMyDirection,
boolean worked,
boolean selected,
@@ -59,9 +60,10 @@ public record MapCallsignRawSnapshot(
}
public String markerLabel() {
return bandSummary.isBlank()
String baseLabel = bandSummary.isBlank()
? displayCallSign
: displayCallSign + " (" + bandSummary + ")";
return offersSelectedBand ? baseLabel + " B+" : baseLabel;
}
public String detailFrequencyText() {
@@ -8,11 +8,13 @@ import kst4contest.model.ChatMember;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.EnumMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Pattern;
/**
* Builds immutable map snapshots from the currently visible chat members.
@@ -22,8 +24,11 @@ import java.util.Map;
*/
public final class MapCallsignRawSnapshotBuilder {
private static final Pattern TOKEN_SPLIT_PATTERN = Pattern.compile("[^A-Z0-9]+");
public List<MapCallsignRawSnapshot> buildSnapshots(Collection<ChatMember> visibleChatMembers,
ChatMember selectedChatMember) {
ChatMember selectedChatMember,
EnumSet<Band> selectedBands) {
if (visibleChatMembers == null || visibleChatMembers.isEmpty()) {
return List.of();
@@ -69,7 +74,9 @@ public final class MapCallsignRawSnapshotBuilder {
Location location = new Location(locator6);
LinkedHashMap<String, String> frequenciesByBand = collectLastKnownFrequenciesByBand(variants);
String bandSummary = String.join(", ", frequenciesByBand.keySet());
EnumSet<Band> sureBands = collectSureBands(variants, frequenciesByBand);
String bandSummary = buildBandSummary(sureBands);
boolean offersSelectedBand = hasAnySelectedBand(sureBands, selectedBands);
boolean warningToMyDirection = variants.stream().anyMatch(ChatMember::isInAngleAndRange);
boolean worked = variants.stream().anyMatch(this::isWorkedAtAnyBand);
@@ -92,6 +99,7 @@ public final class MapCallsignRawSnapshotBuilder {
location.getLongitude().toDegrees(),
bandSummary,
frequenciesByBand,
offersSelectedBand,
warningToMyDirection,
worked,
selected,
@@ -182,6 +190,101 @@ public final class MapCallsignRawSnapshotBuilder {
return ordered;
}
private EnumSet<Band> collectSureBands(List<ChatMember> variants,
LinkedHashMap<String, String> frequenciesByBand) {
EnumSet<Band> sureBands = EnumSet.noneOf(Band.class);
if (frequenciesByBand != null) {
for (String label : frequenciesByBand.keySet()) {
Band mappedBand = bandFromDisplayLabel(label);
if (mappedBand != null) {
sureBands.add(mappedBand);
}
}
}
for (ChatMember variant : variants) {
if (variant == null || variant.getName() == null || variant.getName().isBlank()) {
continue;
}
sureBands.addAll(detectBandsFromStationName(variant.getName()));
}
return sureBands;
}
private EnumSet<Band> detectBandsFromStationName(String stationName) {
EnumSet<Band> detectedBands = EnumSet.noneOf(Band.class);
if (stationName == null || stationName.isBlank()) {
return detectedBands;
}
String normalized = stationName.toUpperCase(Locale.ROOT);
String[] tokens = TOKEN_SPLIT_PATTERN.split(normalized);
for (String token : tokens) {
if (token == null || token.isBlank()) {
continue;
}
switch (token) {
case "2", "2M", "144", "144MHZ" -> detectedBands.add(Band.B_144);
case "70", "70CM", "432", "432MHZ" -> detectedBands.add(Band.B_432);
case "23", "23CM", "1296", "1296MHZ" -> detectedBands.add(Band.B_1296);
case "13", "13CM", "2300", "2320", "2320MHZ" -> detectedBands.add(Band.B_2320);
case "9", "9CM", "3400", "3400MHZ" -> detectedBands.add(Band.B_3400);
case "6", "6CM", "5600", "5760", "5760MHZ" -> detectedBands.add(Band.B_5760);
case "3", "3CM", "10G", "10GHZ", "10368", "10368MHZ" -> detectedBands.add(Band.B_10G);
case "24G", "24GHZ", "24048", "24048MHZ" -> detectedBands.add(Band.B_24G);
default -> {
}
}
}
return detectedBands;
}
private String buildBandSummary(EnumSet<Band> sureBands) {
if (sureBands == null || sureBands.isEmpty()) {
return "";
}
List<String> labels = sureBands.stream()
.sorted()
.map(this::toBandDisplayLabel)
.toList();
return String.join(", ", labels);
}
private boolean hasAnySelectedBand(EnumSet<Band> sureBands, EnumSet<Band> selectedBands) {
if (sureBands == null || sureBands.isEmpty() || selectedBands == null || selectedBands.isEmpty()) {
return false;
}
for (Band band : selectedBands) {
if (sureBands.contains(band)) {
return true;
}
}
return false;
}
private Band bandFromDisplayLabel(String label) {
if (label == null || label.isBlank()) {
return null;
}
return switch (label) {
case "144" -> Band.B_144;
case "432" -> Band.B_432;
case "1296" -> Band.B_1296;
case "2320" -> Band.B_2320;
case "3400" -> Band.B_3400;
case "5760" -> Band.B_5760;
case "10368" -> Band.B_10G;
case "24048" -> Band.B_24G;
default -> null;
};
}
/**
* Fallback for stations where the current displayed QRG exists but the
* knownActiveBands history has not yet been filled.
@@ -13,8 +13,12 @@ import java.nio.charset.StandardCharsets;
* - inspectPoint(x,y) returns what is under the cursor
* - zoomIn()/zoomOut() are callable from Java
* - grid / beam / connection use non-interactive panes
* - JavaScript logs are forwarded to Java through javaMapBridge
* - JavaScript errors are forwarded to Java through javaMapBridge
* - setTheme(light|dark) aligns the map with the JavaFX application theme
*
* Important:
* This version intentionally uses integer Leaflet zoom levels again.
* Fractional zoom in JavaFX WebView caused unreliable marker positioning.
*/
public final class MapHtmlResources {
@@ -184,6 +188,111 @@ public final class MapHtmlResources {
font-weight: 800;
}
.station-cluster-wrapper {
background: transparent;
border: none;
box-shadow: none;
}
.station-cluster-root {
position: relative;
width: 1px;
height: 1px;
pointer-events: auto;
cursor: pointer;
user-select: none;
}
/*
* Cluster design aligned with normal KST4Contest station markers:
* - dark center like station-dot
* - blue border for normal clustered stations
* - yellow border when the cluster contains worked stations
* - orange hover border similar to selected station state
*/
.station-cluster-bubble {
position: absolute;
left: -16px;
top: -16px;
min-width: 32px;
height: 32px;
padding: 0 7px;
border-radius: 18px;
background: #1d1d1d;
color: #f4f7fa;
border: 2px solid #4da6ff;
box-shadow:
0 0 0 1px rgba(0, 0, 0, 0.35),
0 2px 7px rgba(0, 0, 0, 0.42);
box-sizing: border-box;
font-size: 13px;
font-weight: 800;
line-height: 28px;
text-align: center;
white-space: nowrap;
}
.station-cluster-bubble.medium {
left: -18px;
top: -18px;
min-width: 36px;
height: 36px;
border-radius: 20px;
font-size: 14px;
line-height: 32px;
}
.station-cluster-bubble.large {
left: -21px;
top: -21px;
min-width: 42px;
height: 42px;
border-radius: 23px;
font-size: 15px;
line-height: 38px;
}
.station-cluster-bubble.worked {
border-color: #ffd24d;
}
.station-cluster-bubble.warning {
border-color: #00ff66;
color: #00ff66;
}
.station-cluster-root:hover .station-cluster-bubble {
border-color: #ff9900;
box-shadow:
0 0 0 2px rgba(255, 153, 0, 0.28),
0 2px 9px rgba(0, 0, 0, 0.48);
}
body.kst-theme-dark .station-cluster-bubble {
background: #202428;
color: #f1f3f5;
border-color: #4da6ff;
box-shadow:
0 0 0 1px rgba(255, 255, 255, 0.12),
0 2px 8px rgba(0, 0, 0, 0.58);
}
body.kst-theme-dark .station-cluster-bubble.worked {
border-color: #ffd24d;
}
body.kst-theme-dark .station-cluster-bubble.warning {
border-color: #00ff66;
color: #00ff66;
}
body.kst-theme-dark .station-cluster-root:hover .station-cluster-bubble {
border-color: #ff9900;
box-shadow:
0 0 0 2px rgba(255, 153, 0, 0.32),
0 2px 10px rgba(0, 0, 0, 0.65);
}
.maidenhead-grid-label-wrapper {
background: transparent;
border: none;
@@ -225,9 +334,6 @@ public final class MapHtmlResources {
<script>window._kstTileProxyPort=__TILE_PROXY_PORT__;</script>
<script>
window.kstMapApi = (function () {
let map;
let stationLayer;
@@ -235,11 +341,77 @@ public final class MapHtmlResources {
let beamLayer;
let connectionLayer;
let profileHoverMarker;
/*
* Currently visible individual station markers.
*
* A callsign is present here only when it is rendered individually.
* If the station is inside a cluster, stationsByCallsignRaw is used
* for focus/zoom operations.
*/
let markersByCallsignRaw = {};
/*
* All station data as received from Java.
*/
let stationData = [];
let stationsByCallsignRaw = {};
let clustersById = {};
let clusterSequence = 0;
let activeTheme = 'light';
let invalidateNotifyTimer = 0;
/*
* Integer zoom only.
*
* Fractional zoom is intentionally disabled because JavaFX WebView
* and Leaflet marker positioning were unreliable at intermediate
* zoom levels.
*/
const KST_ZOOM_STEP = 1;
const KST_MIN_ZOOM = 3;
const KST_MAX_ZOOM = 18;
/*
* Enables verbose JavaScript map logging.
*
* Keep this false for normal operation. jsError() still reports
* real errors.
*/
const KST_MAP_DEBUG = false;
/*
* Cluster settings.
*
* With integer zoom, clustering is disabled at zoom >= 8.
* At zoom 7 only very close stations are grouped.
*/
const KST_CLUSTER_DISABLE_ZOOM = 8;
/*
* Do not cluster pairs immediately. Two nearby stations are still
* readable and should remain individually clickable.
*/
const KST_CLUSTER_MIN_STATIONS = 3;
/*
* Cluster cell sizes in screen pixels.
*
* Smaller cells make clustering less aggressive. Stations must be
* closer together on screen before they are grouped.
*/
const KST_CLUSTER_CELL_SIZE_HIGH_ZOOM = 55;
const KST_CLUSTER_CELL_SIZE_MEDIUM_ZOOM = 70;
const KST_CLUSTER_CELL_SIZE_LOW_ZOOM = 95;
const KST_CLUSTER_CELL_SIZE_VERY_LOW_ZOOM = 125;
function jsLog(message) {
if (!KST_MAP_DEBUG) {
return;
}
try {
if (window.javaMapBridge) {
window.javaMapBridge.onJsLog(String(message));
@@ -358,6 +530,331 @@ public final class MapHtmlResources {
+ '</div>';
}
function getStationCallsignKey(station) {
if (!station || station.callSignRaw === null || station.callSignRaw === undefined) {
return '';
}
return String(station.callSignRaw);
}
function isStationPositionValid(station) {
if (!station) {
return false;
}
return isFinite(station.latitudeDeg) && isFinite(station.longitudeDeg);
}
/**
* Returns true for stations that must not be hidden inside a cluster.
*
* These stations remain individually visible even at low zoom levels
* because they are operationally important during contest operation.
*/
function shouldRenderStationIndividually(station) {
if (!station) {
return false;
}
if (station.selected) {
return true;
}
if (station.warningToMyDirection) {
return true;
}
return false;
}
/**
* Returns the cluster grid size in screen pixels for the current zoom level.
*
* The cluster calculation is screen-based, not locator-based. This makes
* the decision match the real visual problem: too many labels in the same
* screen area.
*/
function getClusterCellSizePx() {
if (!map) {
return KST_CLUSTER_CELL_SIZE_MEDIUM_ZOOM;
}
const zoom = Number(map.getZoom());
if (zoom >= 7) {
return KST_CLUSTER_CELL_SIZE_HIGH_ZOOM;
}
if (zoom >= 6) {
return KST_CLUSTER_CELL_SIZE_MEDIUM_ZOOM;
}
if (zoom >= 5) {
return KST_CLUSTER_CELL_SIZE_LOW_ZOOM;
}
return KST_CLUSTER_CELL_SIZE_VERY_LOW_ZOOM;
}
function buildClusterMarkerHtml(clusterId, clusterStations) {
const count = clusterStations ? clusterStations.length : 0;
let bubbleClasses = 'station-cluster-bubble';
if (count >= 20) {
bubbleClasses += ' large';
} else if (count >= 8) {
bubbleClasses += ' medium';
}
const containsWorkedStation = clusterStations
&& clusterStations.some(station => station && station.worked);
const containsWarningStation = clusterStations
&& clusterStations.some(station => station && station.warningToMyDirection);
if (containsWarningStation) {
bubbleClasses += ' warning';
} else if (containsWorkedStation) {
bubbleClasses += ' worked';
}
return '<div class="station-cluster-root" data-cluster-id="' + escapeHtml(clusterId) + '">'
+ '<div class="' + bubbleClasses + '">' + count + '</div>'
+ '</div>';
}
function buildClusterTooltipHtml(clusterStations) {
if (!clusterStations || clusterStations.length === 0) {
return '';
}
const callsigns = clusterStations
.map(station => station.markerLabel || station.callSignRaw || station.callSign || '')
.filter(value => value !== null && value !== undefined && String(value).trim() !== '')
.map(value => String(value).trim())
.sort();
const maxPreviewCount = 20;
const preview = callsigns
.slice(0, maxPreviewCount)
.map(value => escapeHtml(value))
.join('<br>');
const remainingCount = Math.max(0, callsigns.length - maxPreviewCount);
let html = '<b>' + clusterStations.length + ' stations</b>';
if (preview) {
html += '<br>' + preview;
}
if (remainingCount > 0) {
html += '<br>+' + remainingCount + ' more';
}
html += '<br><i>Click to zoom in</i>';
return html;
}
function addStationMarker(station) {
if (!stationLayer || !isStationPositionValid(station)) {
return;
}
const marker = L.marker(
[station.latitudeDeg, station.longitudeDeg],
{
interactive: true,
keyboard: false,
icon: L.divIcon({
className: 'station-marker-wrapper',
html: buildStationMarkerHtml(station),
iconSize: [1, 1],
iconAnchor: [0, 0]
})
}
);
marker.addTo(stationLayer);
const callSignKey = getStationCallsignKey(station);
if (callSignKey) {
markersByCallsignRaw[callSignKey] = marker;
}
}
function addClusterMarker(clusterStations) {
if (!stationLayer || !clusterStations || clusterStations.length === 0) {
return;
}
let latSum = 0.0;
let lonSum = 0.0;
let validCount = 0;
clusterStations.forEach(station => {
if (isStationPositionValid(station)) {
latSum += Number(station.latitudeDeg);
lonSum += Number(station.longitudeDeg);
validCount++;
}
});
if (validCount === 0) {
return;
}
const centerLat = latSum / validCount;
const centerLon = lonSum / validCount;
const clusterId = 'cluster-' + (++clusterSequence);
clustersById[clusterId] = clusterStations;
const clusterMarker = L.marker(
[centerLat, centerLon],
{
interactive: true,
keyboard: false,
icon: L.divIcon({
className: 'station-cluster-wrapper',
html: buildClusterMarkerHtml(clusterId, clusterStations),
iconSize: [1, 1],
iconAnchor: [0, 0]
})
}
);
clusterMarker.on('click', function () {
zoomToCluster(clusterStations);
});
clusterMarker.bindTooltip(buildClusterTooltipHtml(clusterStations), {
direction: 'top',
sticky: true,
opacity: 0.95
});
clusterMarker.addTo(stationLayer);
}
function renderAllStationsIndividually() {
stationData.forEach(station => {
addStationMarker(station);
});
}
/**
* Renders stations with simple screen-grid clustering.
*
* Important stations such as the currently selected station and warning
* stations are rendered individually before clustering. They remain
* visible even at low zoom levels.
*/
function renderClusteredStations() {
const clusterCellSizePx = getClusterCellSizePx();
const buckets = {};
stationData.forEach(station => {
if (!isStationPositionValid(station)) {
return;
}
if (shouldRenderStationIndividually(station)) {
addStationMarker(station);
return;
}
const point = map.latLngToContainerPoint([station.latitudeDeg, station.longitudeDeg]);
const cellX = Math.floor(point.x / clusterCellSizePx);
const cellY = Math.floor(point.y / clusterCellSizePx);
const key = cellX + ':' + cellY;
if (!buckets[key]) {
buckets[key] = [];
}
buckets[key].push(station);
});
Object.keys(buckets).forEach(key => {
const bucketStations = buckets[key];
if (bucketStations.length >= KST_CLUSTER_MIN_STATIONS) {
addClusterMarker(bucketStations);
} else {
bucketStations.forEach(station => addStationMarker(station));
}
});
}
/**
* Re-renders station markers for the current zoom and viewport.
*
* This is called when stations arrive from Java and after zoom/move
* events, because screen-grid clusters depend on the current viewport.
*/
function renderStationMarkers() {
if (!map || !stationLayer) {
return;
}
stationLayer.clearLayers();
markersByCallsignRaw = {};
clustersById = {};
clusterSequence = 0;
if (!stationData || stationData.length === 0) {
return;
}
if (Number(map.getZoom()) >= KST_CLUSTER_DISABLE_ZOOM) {
renderAllStationsIndividually();
} else {
renderClusteredStations();
}
}
/**
* Zooms into a cluster.
*
* A cluster click does not select one station. It moves the map towards
* the cluster center and increases zoom until individual stations become
* visible.
*/
function zoomToCluster(clusterStations) {
if (!map || !clusterStations || clusterStations.length === 0) {
return;
}
const latLngs = [];
clusterStations.forEach(station => {
if (isStationPositionValid(station)) {
latLngs.push(L.latLng(station.latitudeDeg, station.longitudeDeg));
}
});
if (latLngs.length === 0) {
return;
}
const bounds = L.latLngBounds(latLngs);
const currentZoom = Number(map.getZoom());
const targetZoom = clampZoomToLeafletLimits(
Math.min(KST_CLUSTER_DISABLE_ZOOM, currentZoom + 1)
);
map.setView(bounds.getCenter(), targetZoom, {
animate: false
});
notifyViewport();
}
function init() {
if (map) {
return true;
@@ -372,6 +869,17 @@ public final class MapHtmlResources {
map = L.map('map', {
zoomControl: true,
minZoom: KST_MIN_ZOOM,
maxZoom: KST_MAX_ZOOM,
/*
* Integer zoom only.
* This keeps station positions stable in JavaFX WebView.
*/
zoomSnap: 1,
zoomDelta: 1,
wheelPxPerZoomLevel: 120,
zoomAnimation: false,
fadeAnimation: false,
markerZoomAnimation: false,
@@ -383,7 +891,8 @@ public final class MapHtmlResources {
const tileLayer = L.tileLayer(
'http://127.0.0.1:' + window._kstTileProxyPort + '/tiles/{s}/{z}/{x}/{y}.png',
{
maxZoom: 18,
minZoom: KST_MIN_ZOOM,
maxZoom: KST_MAX_ZOOM,
updateWhenZooming: false,
keepBuffer: 4,
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
@@ -419,12 +928,12 @@ public final class MapHtmlResources {
connectionLayer = L.layerGroup().addTo(map);
map.on('zoomend', function () {
jsLog('zoomend -> ' + map.getZoom());
renderStationMarkers();
notifyViewport();
});
map.on('moveend', function () {
jsLog('moveend');
renderStationMarkers();
notifyViewport();
});
@@ -476,20 +985,39 @@ public final class MapHtmlResources {
invalidateSize();
}
function zoomIn() {
/**
* Keeps the zoom value inside the explicit KST zoom limits.
*/
function clampZoomToLeafletLimits(zoom) {
return Math.max(KST_MIN_ZOOM, Math.min(KST_MAX_ZOOM, zoom));
}
/**
* Changes the zoom in stable integer steps.
*/
function changeZoomByKstStep(delta) {
if (!map) {
return;
}
map.setZoom(map.getZoom() + 1, { animate: false });
const currentZoom = Number(map.getZoom());
const nextZoom = clampZoomToLeafletLimits(currentZoom + delta);
if (nextZoom === currentZoom) {
return;
}
map.setZoom(nextZoom, {
animate: false
});
}
function zoomIn() {
changeZoomByKstStep(KST_ZOOM_STEP);
}
function zoomOut() {
if (!map) {
return;
}
map.setZoom(map.getZoom() - 1, { animate: false });
changeZoomByKstStep(-KST_ZOOM_STEP);
}
function getViewportState() {
@@ -522,6 +1050,12 @@ public final class MapHtmlResources {
return 'station|' + callSignRaw + '|' + el.tagName + '|' + (el.className || '') + '|' + (el.textContent || '').trim();
}
const clusterRoot = el.closest('.station-cluster-root');
if (clusterRoot) {
const clusterId = clusterRoot.getAttribute('data-cluster-id') || '';
return 'cluster|' + clusterId + '|' + el.tagName + '|' + (el.className || '') + '|' + (el.textContent || '').trim();
}
const zoomInButton = el.closest('.leaflet-control-zoom-in');
if (zoomInButton) {
return 'zoomIn||' + el.tagName + '|' + (el.className || '') + '|' + (el.textContent || '').trim();
@@ -542,8 +1076,8 @@ public final class MapHtmlResources {
if (!init()) {
return;
}
jsLog('setHome lat=' + lat + ' lon=' + lon + ' zoom=' + zoom);
map.setView([lat, lon], zoom);
map.setView([lat, lon], clampZoomToLeafletLimits(Math.round(Number(zoom))));
}
function setStations(stationsJson) {
@@ -551,30 +1085,17 @@ public final class MapHtmlResources {
return;
}
stationLayer.clearLayers();
markersByCallsignRaw = {};
stationData = JSON.parse(stationsJson);
stationsByCallsignRaw = {};
const stations = JSON.parse(stationsJson);
jsLog('setStations count=' + stations.length);
stations.forEach(station => {
const marker = L.marker(
[station.latitudeDeg, station.longitudeDeg],
{
interactive: true,
keyboard: false,
icon: L.divIcon({
className: 'station-marker-wrapper',
html: buildStationMarkerHtml(station),
iconSize: [1, 1],
iconAnchor: [0, 0]
})
stationData.forEach(station => {
const callSignKey = getStationCallsignKey(station);
if (callSignKey) {
stationsByCallsignRaw[callSignKey] = station;
}
);
marker.addTo(stationLayer);
markersByCallsignRaw[station.callSignRaw] = marker;
});
renderStationMarkers();
}
function setBeam(beamJson) {
@@ -592,8 +1113,6 @@ public final class MapHtmlResources {
return;
}
jsLog('setBeam points=' + points.length);
const latLngs = points.map(point => [point.lat, point.lon]);
L.polygon(latLngs, {
@@ -621,8 +1140,6 @@ public final class MapHtmlResources {
return;
}
jsLog('setConnection');
L.polyline(points.map(point => [point.lat, point.lon]), {
pane: 'connectionPane',
color: connectionColor(),
@@ -671,7 +1188,6 @@ public final class MapHtmlResources {
gridLayer.clearLayers();
const cells = JSON.parse(gridJson);
jsLog('setGrid cells=' + cells.length);
cells.forEach(cell => {
const rectangle = L.rectangle(
@@ -717,21 +1233,33 @@ public final class MapHtmlResources {
}
const marker = markersByCallsignRaw[callSignRaw];
if (!marker) {
jsLog('focusCallsignRaw skipped for ' + callSignRaw);
return;
}
jsLog('focusCallsignRaw ' + callSignRaw);
if (marker) {
map.panTo(marker.getLatLng(), {
animate: false
});
notifyViewport();
return;
}
/*
* If the station is currently hidden inside a cluster, there is no
* individual marker. Use the raw station data and zoom in far enough
* so clustering is disabled and the station becomes visible.
*/
const station = stationsByCallsignRaw[callSignRaw];
if (station && isStationPositionValid(station)) {
const focusZoom = clampZoomToLeafletLimits(
Math.max(Number(map.getZoom()), KST_CLUSTER_DISABLE_ZOOM)
);
map.setView([station.latitudeDeg, station.longitudeDeg], focusZoom, {
animate: false
});
notifyViewport();
}
}
return {
init: init,
@@ -11,6 +11,7 @@ import kst4contest.model.ChatPreferences;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
@@ -142,8 +143,13 @@ public final class StationMapBridge {
private void refreshNow() {
List<ChatMember> visibleChatMembers = new ArrayList<>(chatController.getLst_chatMemberSortedFilteredList());
ChatMember selectedChatMember = chatController.getScoreService().getSelectedChatMember();
EnumSet<Band> selectedBands = chatController.getReachabilityService().getEnabledStationBands();
List<MapCallsignRawSnapshot> snapshots = snapshotBuilder.buildSnapshots(visibleChatMembers, selectedChatMember);
List<MapCallsignRawSnapshot> snapshots = snapshotBuilder.buildSnapshots(
visibleChatMembers,
selectedChatMember,
selectedBands
);
MapCallsignRawSnapshot selectedSnapshot = null;
if (selectedChatMember != null && selectedChatMember.getCallSignRaw() != null) {
@@ -41,6 +41,14 @@ import javafx.scene.layout.ColumnConstraints;
*/
public final class StationMapView {
/**
* Enables verbose map debug output.
*
* Keep this false for normal operation because scroll and viewport logs are very
* noisy during map interaction.
*/
private static final boolean MAP_DEBUG_LOGGING = false;
private final PathProfileChart detailPathProfileChart = new PathProfileChart();
private final Label detailPathModeValue = new Label("-");
@@ -287,12 +295,17 @@ public final class StationMapView {
webView.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> handleWebViewClick(event));
webView.addEventHandler(ScrollEvent.SCROLL, event -> {
if (MAP_DEBUG_LOGGING) {
System.out.println("[StationMap FX] SCROLL x=" + (int) event.getX()
+ " y=" + (int) event.getY()
+ " deltaY=" + event.getDeltaY());
}
InteractiveTarget target = inspectInteractiveTarget(event.getX(), event.getY());
if (MAP_DEBUG_LOGGING) {
System.out.println("[StationMap FX] inspect scroll -> " + target);
}
if (event.getDeltaY() > 0) {
executeMapScriptSafely("window.kstMapApi.zoomIn();");
@@ -855,7 +868,11 @@ public final class StationMapView {
detailLocatorValue.setText(selectedSnapshot.locator6());
detailQrbValue.setText(String.format(Locale.US, "%.0f km", selectedSnapshot.qrbKm()));
detailQtfValue.setText(String.format(Locale.US, "%.0f°", selectedSnapshot.qtfDeg()));
detailBandsValue.setText(selectedSnapshot.bandSummary().isBlank() ? "-" : selectedSnapshot.bandSummary());
String bandText = selectedSnapshot.bandSummary().isBlank() ? "-" : selectedSnapshot.bandSummary();
if (selectedSnapshot.offersSelectedBand()) {
bandText += " B+";
}
detailBandsValue.setText(bandText);
detailFrequenciesArea.setText(selectedSnapshot.detailFrequencyText());
detailAirplanesValue.setText(String.valueOf(selectedSnapshot.reachableAirplanes()));
triggerClusterSpotButton.setDisable(false);
@@ -650,6 +650,8 @@ svg.leaflet-image-layer.leaflet-interactive path {
border-right-color: #fff;
}
/* Printing */
@media print {
@@ -0,0 +1,56 @@
package kst4contest.test;
import kst4contest.model.Band;
import kst4contest.model.ChatMember;
import kst4contest.view.map.MapCallsignRawSnapshot;
import kst4contest.view.map.MapCallsignRawSnapshotBuilder;
import org.junit.jupiter.api.Test;
import java.util.EnumSet;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
class MapCallsignRawSnapshotBuilderTest {
@Test
void marksSnapshotWhenNameAdvertisesSelectedBand() {
ChatMember station = buildStation("DL1ABC", "QRV 2-70-23", "JN58TD", 1_000L);
MapCallsignRawSnapshotBuilder builder = new MapCallsignRawSnapshotBuilder();
List<MapCallsignRawSnapshot> snapshots = builder.buildSnapshots(
List.of(station),
null,
EnumSet.of(Band.B_1296)
);
assertEquals(1, snapshots.size());
assertTrue(snapshots.get(0).offersSelectedBand());
}
@Test
void keepsSnapshotUnmarkedWhenNoSelectedBandMatches() {
ChatMember station = buildStation("DL1ABC", "QRV 2m only", "JN58TD", 1_000L);
MapCallsignRawSnapshotBuilder builder = new MapCallsignRawSnapshotBuilder();
List<MapCallsignRawSnapshot> snapshots = builder.buildSnapshots(
List.of(station),
null,
EnumSet.of(Band.B_2320)
);
assertEquals(1, snapshots.size());
assertFalse(snapshots.get(0).offersSelectedBand());
}
private ChatMember buildStation(String callSign, String name, String locator, long activityEpoch) {
ChatMember chatMember = new ChatMember();
chatMember.setCallSign(callSign);
chatMember.setName(name);
chatMember.setQra(locator);
chatMember.setActivityTimeLastInEpoch(activityEpoch);
return chatMember;
}
}
+220
View File
@@ -0,0 +1,220 @@
const fs = require("fs");
const path = require("path");
const markdownIt = require("markdown-it");
const markdownItAnchor = require("markdown-it-anchor");
const MANUAL_PAGE_ORDER = {
de: [
"home",
"installation",
"konfiguration",
"log-synchronisation",
"airscout-integration",
"dx-cluster-server",
"funktionen",
"makros-und-variablen",
"benutzeroberflaeche",
"changelog"
],
en: [
"home",
"installation",
"configuration",
"log-sync",
"airscout-integration",
"dx-cluster-server",
"features",
"macros-and-variables",
"user-interface",
"changelog"
]
};
function markdownToPlainText(value) {
return (value || "")
.replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1")
.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1")
.replace(/<[^>]+>/g, "")
.replace(/[*_~`]/g, "")
.replace(/\s+/g, " ")
.trim();
}
function extractManualTitle(raw, fallbackTitle) {
const heading = (raw || "").match(/^#\s+(.+)$/m);
return heading ? markdownToPlainText(heading[1]) : fallbackTitle;
}
function extractManualSummary(raw) {
const blocks = (raw || "").split(/\r?\n\s*\r?\n/);
for (const block of blocks) {
const trimmed = block.trim();
if (!trimmed
|| /^(#|>|\||---|```|!\[)/.test(trimmed)
|| /^[-*+]\s/.test(trimmed)
|| /^\d+[.)]\s/.test(trimmed)) {
continue;
}
return markdownToPlainText(trimmed);
}
return "";
}
function getManualPageOrder(lang, slug) {
const configuredOrder = MANUAL_PAGE_ORDER[lang] || [];
const index = configuredOrder.indexOf(slug);
return index >= 0 ? index : 999;
}
function rewriteManualLinks(content, lang) {
return (content || "")
// Manual images are stored next to the Markdown sources in github_docs.
// The website publishes them from one shared, language-neutral directory.
.replace(
/!\[([^\]]*)\]\((?!https?:\/\/|\/)([^)\s]+\.(?:png|jpe?g|gif|svg|webp))\)/gi,
(match, altText, imagePath) => {
const fileName = path.posix.basename(
imagePath.replace(/\\/g, "/")
);
return `![${altText}](/manual/assets/${fileName})`;
}
)
// GitHub-Wiki-Links im Stil [[de-Installation]] oder [[en-Installation]]
.replace(/\[\[(en|de)-([^\]|]+)\]\]/g, (match, linkLang, slug) => {
return `[${slug.replace(/-/g, " ")}](/manual/${linkLang}/${slug.toLowerCase()}/)`;
})
// GitHub-Wiki-Links mit Label: [[Text|de-Installation]]
.replace(/\[\[([^\]|]+)\|(en|de)-([^\]]+)\]\]/g, (match, label, linkLang, slug) => {
return `[${label}](/manual/${linkLang}/${slug.toLowerCase()}/)`;
})
// Markdown-Links auf de-/en-Dateien ohne .md
.replace(/\]\((en|de)-([^)#]+)\)/g, (match, linkLang, slug) => {
return `](/manual/${linkLang}/${slug.toLowerCase()}/)`;
})
// Markdown-Links auf de-/en-Dateien mit .md
.replace(/\]\((en|de)-([^)#]+)\.md\)/g, (match, linkLang, slug) => {
return `](/manual/${linkLang}/${slug.toLowerCase()}/)`;
});
}
module.exports = function (eleventyConfig) {
eleventyConfig.addFilter("dateToIso", function (dateObj) {
return new Date(dateObj).toISOString().split("T")[0];
});
eleventyConfig.addFilter("dateToRfc822", function (dateObj) {
return new Date(dateObj).toUTCString();
});
eleventyConfig.addFilter("readableDate", function (dateObj) {
return new Intl.DateTimeFormat("en", {
year: "numeric",
month: "long",
day: "numeric"
}).format(dateObj);
});
eleventyConfig.addCollection("sortedFeatures", function (collectionApi) {
return collectionApi.getFilteredByTag("features").sort((a, b) => {
return (a.data.order || 999) - (b.data.order || 999);
});
});
eleventyConfig.addCollection("featuredFeatures", function (collectionApi) {
return collectionApi.getFilteredByTag("features")
.filter(item => item.data.featured)
.sort((a, b) => {
return (a.data.order || 999) - (b.data.order || 999);
});
});
eleventyConfig.addFilter("whereTag", function(collection, tag) {
return collection.filter(item => item.data.tags && item.data.tags.includes(tag));
});
eleventyConfig.addPassthroughCopy({ "src/assets": "assets" });
eleventyConfig.addPassthroughCopy({
"../github_docs/*.{png,jpg,jpeg,gif,svg,webp}": "manual/assets"
});
const md = markdownIt({
html: true,
linkify: true,
typographer: true
}).use(markdownItAnchor, {
permalink: markdownItAnchor.permalink.headerLink()
});
eleventyConfig.addFilter("markdown", function (value) {
return md.render(value || "");
});
eleventyConfig.addCollection("manualPages", function () {
const docsDir = path.join(__dirname, "..", "github_docs");
if (!fs.existsSync(docsDir)) {
return [];
}
return fs.readdirSync(docsDir)
.filter(file => /^(en|de)-.+\.md$/.test(file))
.map(file => {
const fullPath = path.join(docsDir, file);
const raw = fs.readFileSync(fullPath, "utf8");
const lang = file.startsWith("de-") ? "de" : "en";
const slug = file
.replace(/^en-/, "")
.replace(/^de-/, "")
.replace(/\.md$/, "")
.toLowerCase();
const fallbackTitle = file
.replace(/^en-/, "")
.replace(/^de-/, "")
.replace(/\.md$/, "")
.replace(/-/g, " ");
const title = extractManualTitle(raw, fallbackTitle);
return {
file,
lang,
slug,
title,
summary: extractManualSummary(raw),
order: getManualPageOrder(lang, slug),
content: rewriteManualLinks(raw, lang)
};
})
.sort((a, b) => {
return a.lang.localeCompare(b.lang)
|| a.order - b.order
|| a.title.localeCompare(b.title);
});
});
return {
dir: {
input: "src",
output: "_site",
includes: "_includes",
layouts: "_layouts"
},
markdownTemplateEngine: "njk",
htmlTemplateEngine: "njk"
};
};
+51
View File
@@ -0,0 +1,51 @@
# KST4Contest Website Architecture
## Goals
KST4Contest uses GitHub as the central source for code, documentation and releases.
The website is generated statically with Eleventy (11ty) and deployed to:
https://kst4contest.hamradioonline.de
## Documentation Source
The existing `github_docs/` directory remains the single source of truth for the manual.
It is used for:
- GitHub Wiki
- PDF manual generation
- Website manual pages
## Website Source
The `website/` directory contains the Eleventy project.
Manual content must not be duplicated inside `website/`.
Marketing, SEO, news, screenshots and download pages belong into `website/src/`.
## URL Structure
- `/`
- `/features/`
- `/download/`
- `/screenshots/`
- `/news/`
- `/manual/`
- `/manual/en/`
- `/manual/de/`
- `/faq/`
## Deployment
The generated static output is deployed to:
`/srv/www/kst4contest/current`
Nginx serves this directory.
## Build Strategy
GitHub Actions will later build the 11ty website and deploy the generated output to the server.
+137
View File
@@ -0,0 +1,137 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>About KST4Contest</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="About KST4Contest and its contest-oriented ON4KST workflow.">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/about/">
<meta property="og:type" content="website">
<meta property="og:title" content="About KST4Contest">
<meta property="og:description" content="About KST4Contest and its contest-oriented ON4KST workflow.">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/about/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="About KST4Contest">
<meta name="twitter:description" content="About KST4Contest and its contest-oriented ON4KST workflow.">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="hero">
<p class="badge">About</p>
<h1>Built for real contest operation.</h1>
<p class="lead">
KST4Contest was created to turn ON4KST chat activity into actionable contest workflow.
</p>
</section>
<section class="section narrow">
<article class="card content-card">
<h2>Why KST4Contest exists</h2>
<p>
Generic chat clients display messages. KST4Contest goes further:
it helps operators identify candidates, manage skeds, use AirScout timing,
synchronize with loggers and reduce workload during VHF/UHF/SHF contests.
</p>
<h2>Open source and practical</h2>
<p>
The project is open source and focused on practical contest station workflows.
Features are designed around real operating pressure, not theoretical UI concepts.
</p>
<h2>Community supported</h2>
<p>
KST4Contest is developed independently.
Community support helps finance hosting,
online services,
testing across multiple operating systems
and future contest-oriented features.
</p>
</article>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
+807
View File
@@ -0,0 +1,807 @@
:root {
--bg: #050816;
--bg2: #0b1224;
--panel: rgba(15, 23, 42, 0.78);
--panel2: rgba(30, 41, 59, 0.72);
--border: rgba(148, 163, 184, 0.22);
--text: #f8fafc;
--muted: #aab6ca;
--soft: #64748b;
--accent: #38bdf8;
--accent2: #a855f7;
--accent3: #22c55e;
--shadow: 0 24px 80px rgba(0, 0, 0, 0.45);
}
* {
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
background: var(--bg);
}
body {
margin: 0;
min-height: 100vh;
background:
radial-gradient(circle at 14% 12%, rgba(168, 85, 247, 0.30), transparent 28%),
radial-gradient(circle at 82% 16%, rgba(56, 189, 248, 0.24), transparent 30%),
radial-gradient(circle at 50% 85%, rgba(34, 197, 94, 0.11), transparent 35%),
linear-gradient(180deg, #050816 0%, #07111f 100%);
color: var(--text);
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
line-height: 1.65;
overflow-x: hidden;
}
body::before {
content: "";
position: fixed;
inset: -20%;
z-index: -3;
background:
radial-gradient(circle at 20% 20%, rgba(168, 85, 247, 0.22), transparent 28%),
radial-gradient(circle at 78% 18%, rgba(56, 189, 248, 0.18), transparent 30%),
radial-gradient(circle at 45% 80%, rgba(34, 197, 94, 0.10), transparent 26%);
filter: blur(48px);
transform: translateZ(0);
}
body::after {
content: "";
position: fixed;
inset: 0;
z-index: -2;
pointer-events: none;
background-image:
linear-gradient(rgba(255,255,255,0.038) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,255,255,0.038) 1px, transparent 1px);
background-size: 54px 54px;
-webkit-mask-image: radial-gradient(circle at center, black 0%, black 46%, transparent 78%);
mask-image: radial-gradient(circle at center, black 0%, black 46%, transparent 78%);
}
.site-bg {
position: fixed;
inset: 0;
z-index: -1;
pointer-events: none;
background:
linear-gradient(180deg, rgba(5, 8, 22, 0.10), rgba(5, 8, 22, 0.84)),
radial-gradient(circle at 8% 24%, rgba(168, 85, 247, 0.18), transparent 26%),
radial-gradient(circle at 82% 20%, rgba(56, 189, 248, 0.16), transparent 30%);
}
.site-bg::before {
content: "";
position: absolute;
inset: 0;
background:
radial-gradient(circle at top, transparent 0%, rgba(5, 8, 22, 0.42) 72%),
linear-gradient(90deg, rgba(5, 8, 22, 0.25), transparent 50%, rgba(5, 8, 22, 0.25));
}
.site-bg::after {
content: "";
position: absolute;
inset: 0;
background-image:
radial-gradient(circle at 1px 1px, rgba(255,255,255,0.10) 1px, transparent 0);
background-size: 28px 28px;
opacity: 0.11;
-webkit-mask-image: radial-gradient(circle at 50% 22%, black 0%, transparent 68%);
mask-image: radial-gradient(circle at 50% 22%, black 0%, transparent 68%);
}
a {
color: var(--accent);
text-decoration: none;
}
a:hover {
color: white;
}
.site-header {
position: sticky;
top: 0;
z-index: 10;
display: flex;
justify-content: space-between;
gap: 24px;
align-items: center;
padding: 18px 6vw;
background: rgba(5, 8, 22, 0.76);
-webkit-backdrop-filter: blur(18px);
backdrop-filter: blur(18px);
border-bottom: 1px solid var(--border);
}
.brand {
display: flex;
gap: 12px;
align-items: center;
color: white;
}
.brand-mark {
display: grid;
place-items: center;
width: 40px;
height: 40px;
border-radius: 14px;
background:
radial-gradient(circle at 30% 20%, white, transparent 22%),
linear-gradient(135deg, var(--accent), var(--accent2));
box-shadow:
0 0 26px rgba(168, 85, 247, 0.45),
0 0 50px rgba(56, 189, 248, 0.18);
}
.brand strong {
display: block;
font-size: 1.05rem;
letter-spacing: 0.02em;
}
.brand small {
display: block;
color: var(--muted);
font-size: 0.78rem;
margin-top: -4px;
}
.site-nav {
display: flex;
align-items: center;
gap: 16px;
flex-wrap: wrap;
}
.site-nav a {
color: var(--muted);
font-size: 0.95rem;
}
.site-nav a:hover {
color: white;
}
.nav-cta {
padding: 9px 14px;
border-radius: 999px;
color: white !important;
background: linear-gradient(135deg, var(--accent), var(--accent2));
box-shadow: 0 0 22px rgba(56, 189, 248, 0.28);
}
.hero {
position: relative;
padding: 92px 6vw 62px;
max-width: 1180px;
}
.hero::before {
content: "";
position: absolute;
inset: -160px -12vw auto -12vw;
height: 420px;
z-index: -1;
pointer-events: none;
background:
radial-gradient(circle at 24% 40%, rgba(168, 85, 247, 0.20), transparent 36%),
radial-gradient(circle at 62% 30%, rgba(56, 189, 248, 0.14), transparent 40%);
filter: blur(74px);
}
.hero-split {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(360px, 0.9fr);
gap: 42px;
align-items: center;
max-width: 1500px;
}
.hero h1 {
margin: 0 0 22px;
font-size: clamp(3rem, 8vw, 6.5rem);
line-height: 0.95;
letter-spacing: -0.07em;
background: linear-gradient(90deg, #ffffff 0%, #7dd3fc 40%, #a855f7 78%);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.hero .lead,
.hero > p,
.section-heading p,
.cta-panel p {
color: var(--muted);
font-size: 1.18rem;
max-width: 850px;
}
.badge,
.eyebrow {
display: inline-flex;
width: fit-content;
align-items: center;
gap: 8px;
color: #e9d5ff;
background: rgba(168, 85, 247, 0.13);
border: 1px solid rgba(168, 85, 247, 0.34);
padding: 6px 12px;
border-radius: 999px;
text-transform: uppercase;
letter-spacing: 0.08em;
font-size: 0.74rem;
font-weight: 800;
box-shadow: 0 0 22px rgba(168, 85, 247, 0.12);
}
.actions {
display: flex;
gap: 14px;
margin-top: 30px;
flex-wrap: wrap;
}
.button {
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 46px;
padding: 12px 18px;
border-radius: 14px;
color: #020617;
background: linear-gradient(135deg, var(--accent), var(--accent2));
font-weight: 800;
box-shadow:
0 16px 44px rgba(56, 189, 248, 0.25),
inset 0 1px 0 rgba(255, 255, 255, 0.35);
}
.button:hover {
color: white;
transform: translateY(-1px);
}
.button.secondary {
color: white;
background: rgba(30, 41, 59, 0.85);
border: 1px solid var(--border);
box-shadow: none;
}
.button.ghost {
color: white;
background: transparent;
border: 1px solid var(--border);
box-shadow: none;
}
.hero-panel,
.card,
.cta-panel {
background:
linear-gradient(180deg, rgba(255,255,255,0.045), transparent 42%),
var(--panel);
border: 1px solid var(--border);
border-radius: 26px;
box-shadow: var(--shadow);
-webkit-backdrop-filter: blur(16px);
backdrop-filter: blur(16px);
}
.hero-panel {
position: relative;
overflow: hidden;
transform: perspective(1200px) rotateY(-5deg) rotateX(2deg);
}
.hero-panel::before {
content: "";
position: absolute;
inset: -1px;
pointer-events: none;
background:
linear-gradient(135deg, rgba(56, 189, 248, 0.45), transparent 35%, rgba(168, 85, 247, 0.38));
opacity: 0.18;
}
.terminal-bar {
display: flex;
gap: 8px;
align-items: center;
padding: 14px 16px;
border-bottom: 1px solid var(--border);
background: rgba(2, 6, 23, 0.74);
}
.terminal-bar span {
width: 11px;
height: 11px;
border-radius: 50%;
background: var(--accent2);
}
.terminal-bar span:nth-child(2) {
background: #f59e0b;
}
.terminal-bar span:nth-child(3) {
background: var(--accent3);
}
.terminal-bar strong {
margin-left: 8px;
color: var(--muted);
font-size: 0.85rem;
}
.mock-grid {
display: grid;
gap: 12px;
padding: 18px;
}
.mini-card {
padding: 14px;
border-radius: 16px;
background: rgba(15, 23, 42, 0.88);
border: 1px solid rgba(148, 163, 184, 0.16);
}
.mini-card strong,
.mini-card small {
display: block;
}
.mini-card small {
color: var(--muted);
margin-top: 4px;
}
.section {
padding: 52px 6vw;
}
.section.narrow {
max-width: 1040px;
}
.section-heading {
margin-bottom: 26px;
}
.section h2 {
font-size: clamp(2rem, 4vw, 3.4rem);
line-height: 1.05;
margin: 12px 0 14px;
letter-spacing: -0.04em;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 18px;
}
.card {
padding: 24px;
transition: transform 180ms ease, border-color 180ms ease, background 180ms ease, box-shadow 180ms ease;
}
.card:hover {
transform: translateY(-4px);
border-color: rgba(56, 189, 248, 0.45);
background:
linear-gradient(180deg, rgba(255,255,255,0.055), transparent 42%),
rgba(15, 23, 42, 0.92);
box-shadow:
0 26px 90px rgba(0, 0, 0, 0.50),
0 0 30px rgba(56, 189, 248, 0.08);
}
.card h3,
.card h2 {
margin-top: 0;
}
.card p {
color: var(--muted);
}
.roadmap-version + .roadmap-version {
margin-top: 24px;
}
.roadmap-version ul {
padding-left: 20px;
}
.roadmap-version li {
margin-bottom: 8px;
}
.roadmap-done a {
color: var(--muted);
text-decoration: line-through;
}
.feature-icon {
font-size: 2rem;
margin-bottom: 14px;
}
.feature-icon.large {
font-size: 4rem;
}
.content-card {
max-width: 980px;
}
.tag-list {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.tag-list span {
padding: 7px 11px;
border-radius: 999px;
color: var(--muted);
background: rgba(15, 23, 42, 0.85);
border: 1px solid var(--border);
}
.download-card {
min-height: 220px;
}
.screenshot-placeholder {
display: grid;
place-items: center;
min-height: 180px;
margin-bottom: 16px;
border-radius: 18px;
background:
linear-gradient(135deg, rgba(56, 189, 248, 0.20), rgba(168, 85, 247, 0.20)),
rgba(2, 6, 23, 0.7);
border: 1px solid var(--border);
color: white;
font-weight: 800;
}
.cta-panel {
padding: clamp(28px, 5vw, 60px);
}
.manual-content {
max-width: 980px;
}
.manual-content h1,
.manual-content h2,
.manual-content h3 {
line-height: 1.2;
}
.manual-content pre {
overflow-x: auto;
padding: 16px;
border-radius: 14px;
background: #020617;
}
.manual-content code {
color: #bae6fd;
}
.manual-content table {
width: 100%;
border-collapse: collapse;
overflow-x: auto;
}
.manual-content th,
.manual-content td {
border-bottom: 1px solid rgba(148, 163, 184, 0.22);
padding: 10px;
text-align: left;
}
.site-footer {
padding: 42px 6vw;
color: var(--muted);
border-top: 1px solid var(--border);
}
@media (max-width: 900px) {
.hero-split {
grid-template-columns: 1fr;
}
.hero-panel {
transform: none;
}
.site-header {
align-items: flex-start;
flex-direction: column;
}
}
@media (prefers-reduced-motion: no-preference) {
.button,
.card {
transition: all 180ms ease;
}
}
.footer-grid {
display: grid;
grid-template-columns: 2fr repeat(3, 1fr);
gap: 24px;
}
.footer-grid strong {
color: white;
}
.footer-grid p {
margin: 8px 0;
}
@media (max-width: 800px) {
.footer-grid {
grid-template-columns: 1fr;
}
}
/* ================================================================
KST4Contest brand recovery: green operator-console identity
and full-screen interactive hero
================================================================ */
:root {
--bg: #050806;
--bg2: #0b140f;
--panel: rgba(15, 28, 20, 0.82);
--panel2: rgba(24, 43, 31, 0.84);
--border: rgba(125, 178, 134, 0.22);
--text: #f4f7f3;
--muted: #a9b8ad;
--soft: #6e8173;
--accent: #54d63d;
--accent2: #8aef64;
--accent3: #31b54a;
--fx-plane: #79ff73;
--fx-plane-muted: rgba(121, 255, 115, 0.42);
--fx-beam: #52ff65;
--fx-beam-glow: rgba(82, 255, 101, 0.28);
--fx-reflection: #d2ffc8;
--fx-trail: rgba(121, 255, 115, 0.17);
--fx-grid: rgba(121, 255, 115, 0.055);
}
body {
background:
radial-gradient(circle at 14% 12%, rgba(52, 165, 57, 0.20), transparent 30%),
radial-gradient(circle at 82% 16%, rgba(95, 218, 82, 0.14), transparent 32%),
radial-gradient(circle at 50% 85%, rgba(32, 126, 55, 0.12), transparent 36%),
linear-gradient(180deg, #070b09 0%, #0b1410 100%);
}
body::before {
background:
radial-gradient(circle at 20% 20%, rgba(60, 173, 61, 0.18), transparent 28%),
radial-gradient(circle at 78% 18%, rgba(97, 222, 80, 0.13), transparent 30%),
radial-gradient(circle at 45% 80%, rgba(34, 122, 53, 0.11), transparent 26%);
}
body::after {
background-image:
linear-gradient(rgba(160,255,160,0.032) 1px, transparent 1px),
linear-gradient(90deg, rgba(160,255,160,0.032) 1px, transparent 1px);
}
.site-bg {
background:
linear-gradient(180deg, rgba(5, 8, 6, 0.10), rgba(5, 8, 6, 0.84)),
radial-gradient(circle at 8% 24%, rgba(52, 165, 57, 0.14), transparent 26%),
radial-gradient(circle at 82% 20%, rgba(95, 218, 82, 0.12), transparent 30%);
}
.site-header {
background: rgba(5, 8, 7, 0.82);
}
.brand-mark,
.nav-cta,
.button {
background: linear-gradient(135deg, var(--accent), var(--accent2));
}
.brand-mark {
box-shadow:
0 0 26px rgba(84, 214, 61, 0.42),
0 0 50px rgba(49, 181, 74, 0.16);
}
.nav-cta {
color: #061008 !important;
box-shadow: 0 0 22px rgba(84, 214, 61, 0.28);
}
main {
width: 100%;
}
.hero.hero-split {
position: relative;
width: 100%;
max-width: none;
min-height: calc(100vh - 73px);
display: grid;
grid-template-columns: minmax(420px, 0.9fr) minmax(520px, 1.1fr);
gap: clamp(40px, 5vw, 110px);
align-items: center;
align-content: center;
padding: clamp(56px, 7vh, 100px) clamp(28px, 6vw, 110px);
overflow: hidden;
}
.hero.hero-split > *:not(.hero-radio-fx):not(.hero-fx-vignette) {
position: relative;
z-index: 3;
}
.hero-copy {
max-width: 760px;
}
.hero.hero-split h1 {
font-size: clamp(3.4rem, 8vw, 7rem);
background: linear-gradient(90deg, #ffffff 0%, #c9ffd0 28%, #77ec70 58%, #45bd4d 100%);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.badge,
.eyebrow {
color: #caffc0;
background: rgba(52, 165, 57, 0.12);
border-color: rgba(105, 232, 88, 0.32);
box-shadow: 0 0 22px rgba(82, 255, 101, 0.08);
}
.button {
color: #041007;
box-shadow:
0 16px 44px rgba(84, 214, 61, 0.22),
inset 0 1px 0 rgba(255,255,255,0.35);
}
.button.secondary {
color: white;
background: rgba(28, 43, 32, 0.90);
}
.hero-panel {
width: min(100%, 760px);
justify-self: center;
transform: perspective(1200px) rotateY(-4deg) rotateX(1.5deg);
}
.hero-panel,
.card,
.cta-panel {
background:
linear-gradient(180deg, rgba(255,255,255,0.045), transparent 42%),
rgba(15, 28, 20, 0.82);
}
.mini-card {
background: rgba(12, 25, 17, 0.88);
border-color: rgba(148, 184, 155, 0.16);
}
.card:hover {
border-color: rgba(84, 214, 61, 0.42);
background:
linear-gradient(180deg, rgba(255,255,255,0.055), transparent 42%),
rgba(12, 25, 17, 0.94);
box-shadow:
0 26px 90px rgba(0,0,0,0.50),
0 0 30px rgba(84,214,61,0.07);
}
.hero-radio-fx {
position: absolute;
inset: 0;
z-index: 0;
width: 100%;
height: 100%;
pointer-events: none;
opacity: 0.78;
}
.hero-fx-vignette {
position: absolute;
inset: 0;
z-index: 1;
pointer-events: none;
background:
linear-gradient(90deg,
rgba(7,11,9,0.92) 0%,
rgba(7,11,9,0.70) 32%,
rgba(7,11,9,0.17) 62%,
rgba(7,11,9,0.38) 100%),
linear-gradient(180deg,
rgba(7,11,9,0.08),
rgba(7,11,9,0.58));
}
html[data-theme="light"] {
--bg: #f4f4f2;
--bg2: #ffffff;
--panel: rgba(255,255,255,0.90);
--panel2: rgba(242,242,239,0.94);
--border: rgba(91,91,86,0.20);
--text: #252522;
--muted: #656560;
--soft: #888881;
--accent: #d33732;
--accent2: #f25a51;
--accent3: #ae2727;
--fx-plane: #df3732;
--fx-plane-muted: rgba(211,55,50,0.38);
--fx-beam: #ef4039;
--fx-beam-glow: rgba(239,64,57,0.22);
--fx-reflection: #ff8d84;
--fx-trail: rgba(211,55,50,0.15);
--fx-grid: rgba(185,47,43,0.045);
}
@media (min-width: 1600px) {
.hero.hero-split {
grid-template-columns: minmax(520px, 0.85fr) minmax(620px, 1.15fr);
}
.hero-panel {
width: min(100%, 820px);
}
}
@media (max-width: 1000px) {
.hero.hero-split {
min-height: auto;
grid-template-columns: 1fr;
padding-top: 64px;
padding-bottom: 64px;
}
.hero-panel {
width: min(100%, 760px);
transform: none;
}
.hero-radio-fx {
opacity: 0.50;
}
.hero-fx-vignette {
background: linear-gradient(180deg, rgba(7,11,9,0.84), rgba(7,11,9,0.34));
}
}
@media (prefers-reduced-motion: reduce) {
.hero-radio-fx {
opacity: 0.28;
}
}
+509
View File
@@ -0,0 +1,509 @@
(() => {
"use strict";
const canvas = document.querySelector("[data-hero-radio-fx]");
if (!(canvas instanceof HTMLCanvasElement)) return;
const hero = canvas.closest(".hero");
const ctx = canvas.getContext("2d", { alpha: true, desynchronized: true });
if (!(hero instanceof HTMLElement) || !ctx) return;
const reducedMotion = matchMedia("(prefers-reduced-motion: reduce)");
const coarsePointer = matchMedia("(pointer: coarse)");
const state = {
width: 0,
height: 0,
dpr: 1,
running: false,
visible: true,
lastFrame: 0,
spawnTime: 0,
beamTime: 0,
frameId: 0,
pointer: { x: 0, y: 0, active: false },
planes: [],
beams: [],
reflections: []
};
const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
const random = (min, max) => min + Math.random() * (max - min);
function css(name, fallback) {
return getComputedStyle(document.documentElement).getPropertyValue(name).trim() || fallback;
}
function palette() {
return {
plane: css("--fx-plane", "#79ff73"),
planeMuted: css("--fx-plane-muted", "rgba(121,255,115,.42)"),
beam: css("--fx-beam", "#52ff65"),
beamGlow: css("--fx-beam-glow", "rgba(82,255,101,.28)"),
reflection: css("--fx-reflection", "#d2ffc8"),
trail: css("--fx-trail", "rgba(121,255,115,.17)"),
grid: css("--fx-grid", "rgba(121,255,115,.055)")
};
}
function roundedRect(x, y, width, height, radius) {
const r = Math.min(radius, width / 2, height / 2);
ctx.beginPath();
ctx.moveTo(x + r, y);
ctx.arcTo(x + width, y, x + width, y + height, r);
ctx.arcTo(x + width, y + height, x, y + height, r);
ctx.arcTo(x, y + height, x, y, r);
ctx.arcTo(x, y, x + width, y, r);
ctx.closePath();
}
function resize() {
const rect = hero.getBoundingClientRect();
state.width = Math.max(1, Math.round(rect.width));
state.height = Math.max(1, Math.round(rect.height));
state.dpr = Math.min(devicePixelRatio || 1, 1.5);
canvas.width = Math.round(state.width * state.dpr);
canvas.height = Math.round(state.height * state.dpr);
canvas.style.width = `${state.width}px`;
canvas.style.height = `${state.height}px`;
ctx.setTransform(state.dpr, 0, 0, state.dpr, 0, 0);
if (!state.pointer.active) {
state.pointer.x = state.width * 0.55;
state.pointer.y = state.height * 0.42;
}
}
function stations() {
const targetX = state.width * 0.54;
const targetY = state.height * 0.43;
const left = { x: state.width * 0.075, y: state.height * 0.82, label: "JO51IJ" };
const right = { x: state.width * 0.925, y: state.height * 0.80, label: "JN49FL" };
left.angle = Math.atan2(targetY - left.y, targetX - left.x);
right.angle = Math.atan2(targetY - right.y, targetX - right.x);
return [left, right];
}
function planeLimit() {
if (coarsePointer.matches) return 5;
return state.width < 900 ? 7 : 12;
}
function createPlane() {
const margin = 55;
const edge = Math.floor(Math.random() * 4);
let x;
let y;
if (edge === 0) {
x = random(0, state.width);
y = -margin;
} else if (edge === 1) {
x = state.width + margin;
y = random(0, state.height);
} else if (edge === 2) {
x = random(0, state.width);
y = state.height + margin;
} else {
x = -margin;
y = random(0, state.height);
}
const tx = state.pointer.active ? state.pointer.x : state.width * random(0.38, 0.72);
const ty = state.pointer.active ? state.pointer.y : state.height * random(0.20, 0.72);
const angle = Math.atan2(ty - y, tx - x);
const speed = random(18, 34);
return {
x, y, angle,
vx: Math.cos(angle) * speed,
vy: Math.sin(angle) * speed,
size: random(5.5, 9),
age: 0,
maxAge: random(12, 20),
steering: random(0.65, 1.2),
wobble: random(0, Math.PI * 2),
wobbleSpeed: random(0.7, 1.4),
hit: 0
};
}
function updatePlane(plane, dt) {
plane.age += dt;
plane.wobble += dt * plane.wobbleSpeed;
const tx = state.pointer.active ? state.pointer.x : state.width * 0.56;
const ty = state.pointer.active ? state.pointer.y : state.height * 0.44;
const desired = Math.atan2(ty - plane.y, tx - plane.x);
let diff = desired - plane.angle;
while (diff > Math.PI) diff -= Math.PI * 2;
while (diff < -Math.PI) diff += Math.PI * 2;
plane.angle += diff * plane.steering * dt;
const speed = Math.hypot(plane.vx, plane.vy);
const wobble = Math.sin(plane.wobble) * 0.14;
plane.vx = Math.cos(plane.angle + wobble) * speed;
plane.vy = Math.sin(plane.angle + wobble) * speed;
plane.x += plane.vx * dt;
plane.y += plane.vy * dt;
plane.hit = Math.max(0, plane.hit - dt * 1.8);
}
function expired(plane) {
const margin = 180;
return plane.age > plane.maxAge || plane.x < -margin || plane.x > state.width + margin || plane.y < -margin || plane.y > state.height + margin;
}
function beamTarget() {
if (!state.planes.length) return null;
const tx = state.pointer.active ? state.pointer.x : state.width * 0.56;
const ty = state.pointer.active ? state.pointer.y : state.height * 0.44;
const nearby = state.planes
.map(plane => ({ plane, distance: Math.hypot(plane.x - tx, plane.y - ty) }))
.filter(item => item.distance < 280)
.sort((a, b) => a.distance - b.distance);
return nearby[0]?.plane || state.planes[Math.floor(Math.random() * state.planes.length)];
}
function createBeam(target) {
const source = stations()
.map(station => ({ station, distance: Math.hypot(target.x - station.x, target.y - station.y) }))
.sort((a, b) => a.distance - b.distance)[0].station;
const angle = Math.atan2(target.y - source.y, target.x - source.x);
const tip = 45;
state.beams.push({
startX: source.x + Math.cos(angle) * tip,
startY: source.y + Math.sin(angle) * tip,
endX: target.x,
endY: target.y,
age: 0,
maxAge: 0.72
});
target.hit = 1;
const values = [50, 75, 100];
state.reflections.push({
x: target.x,
y: target.y,
age: 0,
maxAge: 1.25,
radius: random(8, 13),
probability: values[Math.floor(Math.random() * values.length)]
});
}
function updateEffects(dt) {
state.beams.forEach(beam => beam.age += dt);
state.beams = state.beams.filter(beam => beam.age < beam.maxAge);
state.reflections.forEach(r => {
r.age += dt;
r.radius += dt * 30;
});
state.reflections = state.reflections.filter(r => r.age < r.maxAge);
}
function drawGrid(p) {
ctx.save();
ctx.strokeStyle = p.grid;
ctx.lineWidth = 1;
const spacing = 54;
for (let x = spacing; x < state.width; x += spacing) {
ctx.beginPath();
ctx.moveTo(x, 0);
ctx.lineTo(x, state.height);
ctx.stroke();
}
for (let y = spacing; y < state.height; y += spacing) {
ctx.beginPath();
ctx.moveTo(0, y);
ctx.lineTo(state.width, y);
ctx.stroke();
}
ctx.restore();
}
function drawRadar(p) {
const x = state.pointer.active ? state.pointer.x : state.width * 0.56;
const y = state.pointer.active ? state.pointer.y : state.height * 0.44;
ctx.save();
ctx.strokeStyle = p.planeMuted;
ctx.lineWidth = 1;
for (const radius of [24, 48, 82]) {
ctx.globalAlpha = 0.24 - radius / 500;
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2);
ctx.stroke();
}
ctx.globalAlpha = 0.2;
ctx.beginPath();
ctx.moveTo(x - 100, y);
ctx.lineTo(x + 100, y);
ctx.moveTo(x, y - 100);
ctx.lineTo(x, y + 100);
ctx.stroke();
ctx.restore();
}
function drawYagi(station, p) {
ctx.save();
ctx.translate(station.x, station.y);
ctx.rotate(station.angle);
ctx.strokeStyle = p.plane;
ctx.fillStyle = p.plane;
ctx.lineWidth = 1.5;
ctx.lineCap = "round";
ctx.shadowColor = p.beamGlow;
ctx.shadowBlur = 9;
ctx.beginPath();
ctx.moveTo(-30, 26);
ctx.lineTo(-30, -5);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(-32, 0);
ctx.lineTo(43, 0);
ctx.stroke();
for (const element of [
{ x: -27, length: 34 },
{ x: -12, length: 28 },
{ x: 2, length: 22 },
{ x: 14, length: 19 },
{ x: 25, length: 16 },
{ x: 35, length: 13 }
]) {
ctx.beginPath();
ctx.moveTo(element.x, -element.length / 2);
ctx.lineTo(element.x, element.length / 2);
ctx.stroke();
}
ctx.beginPath();
ctx.arc(-12, 0, 3.2, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
ctx.save();
ctx.font = "700 11px Inter, system-ui, sans-serif";
const width = ctx.measureText(station.label).width + 14;
const x = station.x - width / 2;
const y = station.y + 32;
ctx.fillStyle = "rgba(6,18,10,.86)";
ctx.strokeStyle = p.planeMuted;
roundedRect(x, y, width, 23, 6);
ctx.fill();
ctx.stroke();
ctx.fillStyle = p.plane;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(station.label, station.x, y + 11.5);
ctx.restore();
}
function drawPlane(plane, p) {
ctx.save();
ctx.translate(plane.x, plane.y);
ctx.rotate(plane.angle);
ctx.globalAlpha = clamp(Math.min(plane.age * 1.8, (plane.maxAge - plane.age) * 1.8), 0, 1);
ctx.strokeStyle = p.trail;
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(-plane.size * 4.5, 0);
ctx.lineTo(-plane.size * 1.4, 0);
ctx.stroke();
ctx.fillStyle = plane.hit > 0 ? p.reflection : p.plane;
ctx.shadowColor = plane.hit > 0 ? p.reflection : p.beamGlow;
ctx.shadowBlur = plane.hit > 0 ? 16 : 5;
const s = plane.size;
ctx.beginPath();
ctx.moveTo(s * 1.65, 0);
ctx.lineTo(-s * 0.7, s * 0.34);
ctx.lineTo(-s * 0.15, s * 1.05);
ctx.lineTo(-s * 0.65, s * 1.08);
ctx.lineTo(-s * 1.35, s * 0.3);
ctx.lineTo(-s * 1.7, s * 0.28);
ctx.lineTo(-s * 1.12, 0);
ctx.lineTo(-s * 1.7, -s * 0.28);
ctx.lineTo(-s * 1.35, -s * 0.3);
ctx.lineTo(-s * 0.65, -s * 1.08);
ctx.lineTo(-s * 0.15, -s * 1.05);
ctx.lineTo(-s * 0.7, -s * 0.34);
ctx.closePath();
ctx.fill();
ctx.restore();
}
function drawBeam(beam, p) {
const progress = beam.age / beam.maxAge;
const alpha = Math.sin(progress * Math.PI);
ctx.save();
ctx.globalAlpha = alpha;
ctx.strokeStyle = p.beamGlow;
ctx.lineWidth = 8;
ctx.shadowColor = p.beam;
ctx.shadowBlur = 15;
ctx.setLineDash([10, 6]);
ctx.lineDashOffset = -progress * 36;
ctx.beginPath();
ctx.moveTo(beam.startX, beam.startY);
ctx.lineTo(beam.endX, beam.endY);
ctx.stroke();
ctx.setLineDash([]);
ctx.strokeStyle = p.beam;
ctx.lineWidth = 1.8;
ctx.shadowBlur = 5;
ctx.beginPath();
ctx.moveTo(beam.startX, beam.startY);
ctx.lineTo(beam.endX, beam.endY);
ctx.stroke();
ctx.restore();
}
function drawReflection(r, p) {
const progress = r.age / r.maxAge;
const alpha = 1 - progress;
ctx.save();
ctx.translate(r.x, r.y);
ctx.globalAlpha = alpha;
ctx.strokeStyle = p.reflection;
ctx.lineWidth = 1.6;
ctx.shadowColor = p.beam;
ctx.shadowBlur = 18;
for (const scale of [1, 1.65]) {
ctx.globalAlpha = alpha * (scale === 1 ? 1 : 0.55);
ctx.beginPath();
ctx.arc(0, 0, r.radius * scale, 0, Math.PI * 2);
ctx.stroke();
}
ctx.globalAlpha = alpha * 0.8;
const cross = r.radius * 1.25;
ctx.beginPath();
ctx.moveTo(-cross, 0);
ctx.lineTo(cross, 0);
ctx.moveTo(0, -cross);
ctx.lineTo(0, cross);
ctx.stroke();
ctx.globalAlpha = alpha;
ctx.fillStyle = p.reflection;
ctx.beginPath();
ctx.arc(0, 0, 3.8, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
ctx.save();
const label = `${r.probability}%`;
ctx.font = "800 12px Inter, system-ui, sans-serif";
const width = ctx.measureText(label).width + 16;
const height = 25;
const x = r.x + r.radius + 12;
const y = r.y - r.radius - 17;
ctx.globalAlpha = clamp(alpha * 1.25, 0, 1);
ctx.fillStyle = "rgba(6,18,10,.91)";
ctx.strokeStyle = p.plane;
ctx.shadowColor = p.beamGlow;
ctx.shadowBlur = 10;
roundedRect(x, y, width, height, 6);
ctx.fill();
ctx.stroke();
ctx.shadowBlur = 0;
ctx.fillStyle = p.reflection;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(label, x + width / 2, y + height / 2);
ctx.restore();
}
function draw(staticOnly = false) {
const p = palette();
ctx.clearRect(0, 0, state.width, state.height);
drawGrid(p);
drawRadar(p);
stations().forEach(station => drawYagi(station, p));
if (staticOnly) return;
state.planes.forEach(plane => drawPlane(plane, p));
state.beams.forEach(beam => drawBeam(beam, p));
state.reflections.forEach(r => drawReflection(r, p));
}
function animate(timestamp) {
if (!state.running) return;
const dt = clamp((timestamp - state.lastFrame) / 1000 || 0, 0, 0.05);
state.lastFrame = timestamp;
if (!state.visible || document.hidden) {
state.frameId = requestAnimationFrame(animate);
return;
}
state.spawnTime += dt;
state.beamTime += dt;
const spawnInterval = coarsePointer.matches ? 2.2 : 1.15;
const beamInterval = coarsePointer.matches ? 3.3 : 1.8;
if (state.spawnTime >= spawnInterval && state.planes.length < planeLimit()) {
state.spawnTime = 0;
state.planes.push(createPlane());
}
if (state.beamTime >= beamInterval && state.planes.length) {
state.beamTime = 0;
const target = beamTarget();
if (target) createBeam(target);
}
state.planes.forEach(plane => updatePlane(plane, dt));
state.planes = state.planes.filter(plane => !expired(plane));
updateEffects(dt);
draw(false);
state.frameId = requestAnimationFrame(animate);
}
function start() {
cancelAnimationFrame(state.frameId);
resize();
if (reducedMotion.matches) {
state.running = false;
draw(true);
return;
}
state.running = true;
state.lastFrame = performance.now();
if (!state.planes.length) {
const count = coarsePointer.matches ? 2 : 5;
for (let i = 0; i < count; i++) {
const plane = createPlane();
plane.age = Math.random() * 2;
state.planes.push(plane);
}
}
state.frameId = requestAnimationFrame(animate);
}
hero.addEventListener("pointermove", event => {
const rect = hero.getBoundingClientRect();
state.pointer.x = clamp(event.clientX - rect.left, 0, rect.width);
state.pointer.y = clamp(event.clientY - rect.top, 0, rect.height);
state.pointer.active = true;
}, { passive: true });
hero.addEventListener("pointerleave", () => state.pointer.active = false);
addEventListener("resize", resize, { passive: true });
document.addEventListener("visibilitychange", () => state.lastFrame = performance.now());
reducedMotion.addEventListener("change", start);
new ResizeObserver(() => {
resize();
if (reducedMotion.matches) draw(true);
}).observe(hero);
new IntersectionObserver(entries => {
state.visible = entries[0]?.isIntersecting ?? true;
state.lastFrame = performance.now();
}, { threshold: 0.05 }).observe(hero);
start();
})();
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

+125
View File
@@ -0,0 +1,125 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Contact | KST4Contest</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="Contact options for KST4Contest.">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/contact/">
<meta property="og:type" content="website">
<meta property="og:title" content="Contact | KST4Contest">
<meta property="og:description" content="Contact options for KST4Contest.">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/contact/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Contact | KST4Contest">
<meta name="twitter:description" content="Contact options for KST4Contest.">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="hero">
<p class="badge">Contact</p>
<h1>Contact</h1>
<p class="lead">Get in touch, report issues or contribute to KST4Contest.</p>
</section>
<section class="section">
<div class="grid">
<article class="card">
<h3>GitHub Issues</h3>
<p>Report bugs, request features or discuss technical problems.</p>
<a href="https://github.com/praktimarc/kst4contest/issues">Open issues →</a>
</article>
<article class="card">
<h3>GitHub Repository</h3>
<p>Browse source code, releases and documentation.</p>
<a href="https://github.com/praktimarc/kst4contest">Open repository →</a>
</article>
<article class="card">
<h3>Email</h3>
<p>For legal or website-related contact.</p>
<a href="https://groups.google.com/g/kst4contest">Join the mailing list →</a>
</article>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
+282
View File
@@ -0,0 +1,282 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Download KST4Contest</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="Download the latest stable KST4Contest packages for Windows, Linux and macOS. The required Java runtime is included.">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/download/">
<meta property="og:type" content="website">
<meta property="og:title" content="Download KST4Contest">
<meta property="og:description" content="Download the latest stable KST4Contest packages for Windows, Linux and macOS. The required Java runtime is included.">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/download/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Download KST4Contest">
<meta name="twitter:description" content="Download the latest stable KST4Contest packages for Windows, Linux and macOS. The required Java runtime is included.">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="hero">
<p class="badge">Stable release</p>
<h1>Download KST4Contest</h1>
<p class="lead">
Choose the package for your operating system. Official builds are published through GitHub Releases,
and the required Java runtime is already included.
</p>
<div class="actions">
<a class="button" href="https://github.com/praktimarc/kst4contest/releases/latest">Latest release on GitHub</a>
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases">All releases</a>
</div>
</section>
<section class="section">
<div class="section-heading">
<p class="eyebrow">Packages by platform</p>
<h2>Choose the format that fits your system</h2>
</div>
<div class="grid">
<article class="card download-card">
<div class="feature-icon">🪟</div>
<p class="badge">Default choice</p>
<h3>Windows</h3>
<p><strong>ZIP x64</strong></p>
<p>Extract the complete archive, then start praktiKST.exe. No separate Java installation is required.</p>
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.1/praktiKST-v1.41.1-windows-x64.zip">Download →</a>
</article>
<article class="card download-card">
<div class="feature-icon">🐧</div>
<p class="badge">Default choice</p>
<h3>Linux</h3>
<p><strong>Flatpak (.flatpakref)</strong></p>
<p>Installs through Flatpak and can be updated through Flatpak or the desktop software centre.</p>
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.1/de.x08.KST4Contest.flatpakref">Download →</a>
</article>
<article class="card download-card">
<div class="feature-icon">🐧</div>
<h3>Linux</h3>
<p><strong>AppImage x86_64</strong></p>
<p>Portable build without package installation. Make the downloaded file executable before the first launch.</p>
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.1/KST4Contest-v1.41.1-linux-x86_64.AppImage">Download →</a>
</article>
<article class="card download-card">
<div class="feature-icon">📦</div>
<h3>Debian / Ubuntu</h3>
<p><strong>DEB amd64</strong></p>
<p>Native package for Debian, Ubuntu and distributions based on them.</p>
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.1/KST4Contest-v1.41.1-debian-amd64.deb">Download →</a>
</article>
<article class="card download-card">
<div class="feature-icon">📦</div>
<h3>Fedora</h3>
<p><strong>RPM x86_64</strong></p>
<p>Native package built for Fedora and compatible RPM-based systems.</p>
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.1/KST4Contest-v1.41.1-fedora-x86_64.rpm">Download →</a>
</article>
<article class="card download-card">
<div class="feature-icon">📦</div>
<h3>Arch Linux</h3>
<p><strong>pkg.tar.zst</strong></p>
<p>Release package for direct installation with pacman. AUR alternatives are described in the installation guide.</p>
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.1/KST4Contest-v1.41.1-archlinux-x86_64.pkg.tar.zst">Download →</a>
</article>
<article class="card download-card">
<div class="feature-icon">🍎</div>
<h3>macOS Apple Silicon</h3>
<p><strong>DMG arm64</strong></p>
<p>Best-effort build for Apple Silicon Macs. The application is not currently notarized by Apple.</p>
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.1/KST4Contest-v1.41.1-macos-arm64.dmg">Download →</a>
</article>
<article class="card download-card">
<div class="feature-icon">🍎</div>
<h3>macOS Intel</h3>
<p><strong>DMG x86_64</strong></p>
<p>Best-effort build for Intel Macs. The application is not currently notarized by Apple.</p>
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.1/KST4Contest-v1.41.1-macos-x86_64.dmg">Download →</a>
</article>
<article class="card download-card">
<div class="feature-icon">📘</div>
<h3>Manual English</h3>
<p><strong>PDF</strong></p>
<p>English PDF manual included with the Stable release.</p>
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.1/KST4Contest-v1.41.1-manual-en.pdf">Download →</a>
</article>
<article class="card download-card">
<div class="feature-icon">📘</div>
<h3>Manual German</h3>
<p><strong>PDF</strong></p>
<p>German PDF manual included with the Stable release.</p>
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.1/KST4Contest-v1.41.1-manual-de.pdf">Download →</a>
</article>
</div>
</section>
<section class="section">
<div class="cta-panel">
<p class="eyebrow">Choosing a package</p>
<h2>Which file should I use?</h2>
<p>
Windows users normally need the x64 ZIP package. On Linux, Flatpak is the practical choice when
updates should be managed through the desktop software centre or the Flatpak command line. The
AppImage is useful when a portable file is preferred, while DEB, RPM and Arch packages integrate
with their respective package managers.
</p>
<p>
macOS packages are provided for Apple Silicon and Intel systems on a best-effort basis. They are
not currently notarized by Apple. The installation guide covers the first launch, updates, the
Stable, Beta and Nightly channels, and the location of the settings directory.
</p>
<div class="actions">
<a class="button" href="/manual/en/installation/">Read the installation guide</a>
<a class="button secondary" href="/faq/">Open the FAQ</a>
</div>
</div>
</section>
<section class="section">
<div class="card content-card">
<h2>Development and infrastructure</h2>
<p>
KST4Contest is developed independently. If it is useful in your contest workflow and you want to
help cover continued development, testing and infrastructure costs, the support page explains
what project contributions are used for.
</p>
<div class="actions">
<a class="button" href="/support/">Support the project</a>
</div>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
+168
View File
@@ -0,0 +1,168 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>KST4Contest FAQ</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="Frequently asked questions about KST4Contest, ON4KST contest operation, AirScout integration and VHF/UHF/SHF contest workflow.">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/faq/">
<meta property="og:type" content="website">
<meta property="og:title" content="KST4Contest FAQ">
<meta property="og:description" content="Frequently asked questions about KST4Contest, ON4KST contest operation, AirScout integration and VHF/UHF/SHF contest workflow.">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/faq/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="KST4Contest FAQ">
<meta name="twitter:description" content="Frequently asked questions about KST4Contest, ON4KST contest operation, AirScout integration and VHF/UHF/SHF contest workflow.">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="hero">
<h1>Frequently asked questions</h1>
<p>
Answers about KST4Contest, ON4KST contest operation, downloads,
AirScout integration and supported platforms.
</p>
</section>
<section class="section">
<div class="card">
<h2>What is KST4Contest?</h2>
<p>
KST4Contest is a contest-optimized ON4KST chat client for VHF, UHF and SHF ham radio contest operation.
</p>
<h2>Is KST4Contest a replacement for wtKST, KST2Me or KSTChat?</h2>
<p>
KST4Contest follows a different approach. It is focused on contest workflow, priority candidates,
sked handling, AirScout support, log synchronization and operator decision support.
</p>
<h2>Which platforms are supported?</h2>
<p>
KST4Contest provides release artifacts for Windows, Linux and macOS through GitHub Releases.
</p>
<h2>Does KST4Contest support AirScout?</h2>
<p>
Yes. KST4Contest is designed to integrate AirScout-related workflow information into contest operation.
</p>
<h2>Where can I download KST4Contest?</h2>
<p>
Official builds are available on the GitHub Releases page.
</p>
</div>
</section>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "What is KST4Contest?",
"acceptedAnswer": {
"@type": "Answer",
"text": "KST4Contest is a contest-optimized ON4KST chat client for VHF, UHF and SHF ham radio contest operation."
}
},
{
"@type": "Question",
"name": "Is KST4Contest a replacement for wtKST, KST2Me or KSTChat?",
"acceptedAnswer": {
"@type": "Answer",
"text": "KST4Contest follows a different approach and focuses on contest workflow, priority candidates, sked handling, AirScout support, log synchronization and operator decision support."
}
},
{
"@type": "Question",
"name": "Which platforms are supported?",
"acceptedAnswer": {
"@type": "Answer",
"text": "KST4Contest provides release artifacts for Windows, Linux and macOS through GitHub Releases."
}
}
]
}
</script></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
+223
View File
@@ -0,0 +1,223 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>AirScout Integration</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest receives aircraft scatter information from AirScout and relates AP timing to active ON4KST stations.">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/features/airscout/">
<meta property="og:type" content="website">
<meta property="og:title" content="AirScout Integration">
<meta property="og:description" content="KST4Contest receives aircraft scatter information from AirScout and relates AP timing to active ON4KST stations.">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/features/airscout/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="AirScout Integration">
<meta name="twitter:description" content="KST4Contest receives aircraft scatter information from AirScout and relates AP timing to active ON4KST stations.">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="hero">
<p class="badge">Aircraft Scatter · since 1.26</p>
<h1>AirScout Integration</h1>
<p class="lead">Use AirScout AP predictions in candidate evaluation, the timeline and sked planning.</p>
</section>
<section class="section narrow">
<article class="card content-card">
<div class="feature-icon large">✈️</div>
<h2>Airplane scatter in the operator workflow</h2>
<p>Aircraft reflections can create short but valuable contact opportunities.</p>
<p>KST4Contest helps combine ON4KST chat activity with AirScout-based propagation awareness.</p>
<h2>From candidate to sked decision</h2>
<p>AirScout information can support the decision whether a candidate station should be called immediately, scheduled later or monitored for a better window.</p>
<h2>Keywords</h2>
<div class="tag-list">
<span>AirScout</span>
<span>airplane scatter</span>
<span>aircraft scatter</span>
<span>VHF contest</span>
</div>
<h2>Related features</h2>
<div class="actions">
<a class="button secondary" href="/features/timeline/">Timeline View</a>
<a class="button secondary" href="/features/priority-score/">Priority Score System</a>
<a class="button secondary" href="/features/sked-reminder/">Sked Reminder</a>
</div>
</article>
</section>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "TechArticle",
"headline": "AirScout Integration",
"description": "Use AirScout AP predictions in candidate evaluation, the timeline and sked planning.",
"about": "KST4Contest",
"url": "https://kst4contest.hamradioonline.de/features/airscout/",
"author": {
"@type": "Person",
"name": "Praktimarc"
},
"publisher": {
"@type": "Organization",
"name": "KST4Contest"
}
}
</script></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
+199
View File
@@ -0,0 +1,199 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Dual Chat Categories</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest combines two ON4KST chat categories while retaining the category required for messages and station context.">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/features/dual-chat/">
<meta property="og:type" content="website">
<meta property="og:title" content="Dual Chat Categories">
<meta property="og:description" content="KST4Contest combines two ON4KST chat categories while retaining the category required for messages and station context.">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/features/dual-chat/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Dual Chat Categories">
<meta name="twitter:description" content="KST4Contest combines two ON4KST chat categories while retaining the category required for messages and station context.">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="hero">
<p class="badge">ON4KST Chat · since 1.26</p>
<h1>Dual Chat Categories</h1>
<p class="lead">Log in to two ON4KST categories and handle both message streams in one station list and interface.</p>
</section>
<section class="section narrow">
<article class="card content-card">
<div class="feature-icon large">💬</div>
<h2>Two categories, one workflow</h2>
<p>KST4Contest can operate with two ON4KST chat categories at once.</p>
<p>This is useful when contest activity spans VHF/UHF and microwave operation.</p>
<h2>Less window switching</h2>
<p>The operator can keep more information visible without constantly changing tools.</p>
<h2>Keywords</h2>
<div class="tag-list">
<span>ON4KST</span>
<span>dual chat</span>
<span>microwave contest</span>
</div>
<h2>Related features</h2>
<div class="actions">
<a class="button secondary" href="/features/priority-score/">Priority Score System</a>
<a class="button secondary" href="/features/log-sync/">Log Synchronization</a>
</div>
</article>
</section>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "TechArticle",
"headline": "Dual Chat Categories",
"description": "Log in to two ON4KST categories and handle both message streams in one station list and interface.",
"about": "KST4Contest",
"url": "https://kst4contest.hamradioonline.de/features/dual-chat/",
"author": {
"@type": "Person",
"name": "Praktimarc"
},
"publisher": {
"@type": "Organization",
"name": "KST4Contest"
}
}
</script></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
@@ -0,0 +1,198 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>DXCluster Server</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="The built-in DX Cluster server forwards KST4Contest direction warnings and known frequency information to compatible contest loggers.">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/features/dx-cluster/">
<meta property="og:type" content="website">
<meta property="og:title" content="DXCluster Server">
<meta property="og:description" content="The built-in DX Cluster server forwards KST4Contest direction warnings and known frequency information to compatible contest loggers.">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/features/dx-cluster/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="DXCluster Server">
<meta name="twitter:description" content="The built-in DX Cluster server forwards KST4Contest direction warnings and known frequency information to compatible contest loggers.">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="hero">
<p class="badge">Radio Workflow · since 1.23</p>
<h1>DXCluster Server</h1>
<p class="lead">Send direction warnings as DX Cluster spots to compatible logging software when a usable QRG is known.</p>
</section>
<section class="section narrow">
<article class="card content-card">
<div class="feature-icon large">📡</div>
<h2>More situational awareness</h2>
<p>DXCluster information can support contest operators by adding another source of activity information.</p>
<h2>Integrated workflow</h2>
<p>The goal is not to open another isolated tool, but to connect activity information with the wider KST4Contest workflow.</p>
<h2>Keywords</h2>
<div class="tag-list">
<span>DXCluster</span>
<span>ham radio</span>
<span>contest</span>
</div>
<h2>Related features</h2>
<div class="actions">
<a class="button secondary" href="/features/log-sync/">Log Synchronization</a>
<a class="button secondary" href="/features/priority-score/">Priority Score System</a>
</div>
</article>
</section>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "TechArticle",
"headline": "DXCluster Server",
"description": "Send direction warnings as DX Cluster spots to compatible logging software when a usable QRG is known.",
"about": "KST4Contest",
"url": "https://kst4contest.hamradioonline.de/features/dx-cluster/",
"author": {
"@type": "Person",
"name": "Praktimarc"
},
"publisher": {
"@type": "Organization",
"name": "KST4Contest"
}
}
</script></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
+184
View File
@@ -0,0 +1,184 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>KST4Contest Features</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="Contest-optimized ON4KST features for VHF, UHF and SHF operation.">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/features/">
<meta property="og:type" content="website">
<meta property="og:title" content="KST4Contest Features">
<meta property="og:description" content="Contest-optimized ON4KST features for VHF, UHF and SHF operation.">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/features/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="KST4Contest Features">
<meta name="twitter:description" content="Contest-optimized ON4KST features for VHF, UHF and SHF operation.">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="hero">
<p class="badge">Features</p>
<h1>Contest tools, not just chat windows.</h1>
<p class="lead">
KST4Contest combines ON4KST chat, candidate scoring, AirScout workflow,
sked handling, log synchronization and operator decision support.
</p>
</section>
<section class="section">
<div class="grid">
<article class="card feature-card">
<div class="feature-icon">✈️</div>
<p class="eyebrow">Aircraft Scatter</p>
<h3><a href="/features/airscout/">AirScout Integration</a></h3>
<p>Use AirScout AP predictions in candidate evaluation, the timeline and sked planning.</p>
<a href="/features/airscout/">Learn more →</a>
</article>
<article class="card feature-card">
<div class="feature-icon">💬</div>
<p class="eyebrow">ON4KST Chat</p>
<h3><a href="/features/dual-chat/">Dual Chat Categories</a></h3>
<p>Log in to two ON4KST categories and handle both message streams in one station list and interface.</p>
<a href="/features/dual-chat/">Learn more →</a>
</article>
<article class="card feature-card">
<div class="feature-icon">📡</div>
<p class="eyebrow">Radio Workflow</p>
<h3><a href="/features/dx-cluster/">DXCluster Server</a></h3>
<p>Send direction warnings as DX Cluster spots to compatible logging software when a usable QRG is known.</p>
<a href="/features/dx-cluster/">Learn more →</a>
</article>
<article class="card feature-card">
<div class="feature-icon"></div>
<p class="eyebrow"></p>
<h3><a href="/features/">KST4Contest Features</a></h3>
<p></p>
<a href="/features/">Learn more →</a>
</article>
<article class="card feature-card">
<div class="feature-icon">🔄</div>
<p class="eyebrow">Logger Integration</p>
<h3><a href="/features/log-sync/">Log Synchronization</a></h3>
<p>Import worked stations and current frequencies from supported contest loggers so filters and band information follow the log.</p>
<a href="/features/log-sync/">Learn more →</a>
</article>
<article class="card feature-card">
<div class="feature-icon"></div>
<p class="eyebrow">Operator Speed</p>
<h3><a href="/features/macros/">Macros and Variables</a></h3>
<p>Build recurring chat messages from configurable text blocks and variables such as the current QRG or locator.</p>
<a href="/features/macros/">Learn more →</a>
</article>
<article class="card feature-card">
<div class="feature-icon">🎯</div>
<p class="eyebrow">Contest Workflow</p>
<h3><a href="/features/priority-score/">Priority Score System</a></h3>
<p>Rank active stations from known context such as direction, activity, band, QRG, AP and sked information.</p>
<a href="/features/priority-score/">Learn more →</a>
</article>
<article class="card feature-card">
<div class="feature-icon">🔔</div>
<p class="eyebrow">Sked Management</p>
<h3><a href="/features/sked-reminder/">Sked Reminder</a></h3>
<p>Store planned contacts and issue configurable chat messages plus local alerts before the agreed time.</p>
<a href="/features/sked-reminder/">Learn more →</a>
</article>
<article class="card feature-card">
<div class="feature-icon">⏱️</div>
<p class="eyebrow">Contest Awareness</p>
<h3><a href="/features/timeline/">Timeline View</a></h3>
<p>Show AP-based priority candidates and scheduled contacts on a shared timeline.</p>
<a href="/features/timeline/">Learn more →</a>
</article>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
+199
View File
@@ -0,0 +1,199 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Log Synchronization</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest receives worked-station and, where supported, frequency data from UCXLog, N1MM+, QARTest, DXLog.net and Win-Test through file and UDP interfaces.">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/features/log-sync/">
<meta property="og:type" content="website">
<meta property="og:title" content="Log Synchronization">
<meta property="og:description" content="KST4Contest receives worked-station and, where supported, frequency data from UCXLog, N1MM+, QARTest, DXLog.net and Win-Test through file and UDP interfaces.">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/features/log-sync/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Log Synchronization">
<meta name="twitter:description" content="KST4Contest receives worked-station and, where supported, frequency data from UCXLog, N1MM+, QARTest, DXLog.net and Win-Test through file and UDP interfaces.">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="hero">
<p class="badge">Logger Integration · since 1.31</p>
<h1>Log Synchronization</h1>
<p class="lead">Import worked stations and current frequencies from supported contest loggers so filters and band information follow the log.</p>
</section>
<section class="section narrow">
<article class="card content-card">
<div class="feature-icon large">🔄</div>
<h2>Connect chat and logging</h2>
<p>Contest operation is faster when chat information and log state are connected.</p>
<p>KST4Contest can use logger information to improve workflow awareness.</p>
<h2>Worked and band awareness</h2>
<p>Log synchronization helps the client understand which stations and bands are relevant.</p>
<h2>Keywords</h2>
<div class="tag-list">
<span>Win-Test</span>
<span>UCXLog</span>
<span>contest logger</span>
</div>
<h2>Related features</h2>
<div class="actions">
<a class="button secondary" href="/features/priority-score/">Priority Score System</a>
<a class="button secondary" href="/features/dual-chat/">Dual Chat Categories</a>
</div>
</article>
</section>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "TechArticle",
"headline": "Log Synchronization",
"description": "Import worked stations and current frequencies from supported contest loggers so filters and band information follow the log.",
"about": "KST4Contest",
"url": "https://kst4contest.hamradioonline.de/features/log-sync/",
"author": {
"@type": "Person",
"name": "Praktimarc"
},
"publisher": {
"@type": "Organization",
"name": "KST4Contest"
}
}
</script></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
+198
View File
@@ -0,0 +1,198 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Macros and Variables</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest macros combine reusable message text with values taken from the current station, frequency and operating context.">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/features/macros/">
<meta property="og:type" content="website">
<meta property="og:title" content="Macros and Variables">
<meta property="og:description" content="KST4Contest macros combine reusable message text with values taken from the current station, frequency and operating context.">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/features/macros/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Macros and Variables">
<meta name="twitter:description" content="KST4Contest macros combine reusable message text with values taken from the current station, frequency and operating context.">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="hero">
<p class="badge">Operator Speed · since 1.0</p>
<h1>Macros and Variables</h1>
<p class="lead">Build recurring chat messages from configurable text blocks and variables such as the current QRG or locator.</p>
</section>
<section class="section narrow">
<article class="card content-card">
<div class="feature-icon large"></div>
<h2>Faster messages</h2>
<p>Macros reduce repetitive typing during active contest operation.</p>
<h2>More consistent operation</h2>
<p>Variables help keep messages structured and reduce manual errors.</p>
<h2>Keywords</h2>
<div class="tag-list">
<span>macros</span>
<span>ON4KST</span>
<span>operator workflow</span>
</div>
<h2>Related features</h2>
<div class="actions">
<a class="button secondary" href="/features/sked-reminder/">Sked Reminder</a>
<a class="button secondary" href="/features/dual-chat/">Dual Chat Categories</a>
</div>
</article>
</section>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "TechArticle",
"headline": "Macros and Variables",
"description": "Build recurring chat messages from configurable text blocks and variables such as the current QRG or locator.",
"about": "KST4Contest",
"url": "https://kst4contest.hamradioonline.de/features/macros/",
"author": {
"@type": "Person",
"name": "Praktimarc"
},
"publisher": {
"@type": "Organization",
"name": "KST4Contest"
}
}
</script></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
@@ -0,0 +1,227 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Priority Score System</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="The Priority Score System combines available contest information to populate a separate list of currently relevant candidates.">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/features/priority-score/">
<meta property="og:type" content="website">
<meta property="og:title" content="Priority Score System">
<meta property="og:description" content="The Priority Score System combines available contest information to populate a separate list of currently relevant candidates.">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/features/priority-score/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Priority Score System">
<meta name="twitter:description" content="The Priority Score System combines available contest information to populate a separate list of currently relevant candidates.">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="hero">
<p class="badge">Contest Workflow · since 1.40</p>
<h1>Priority Score System</h1>
<p class="lead">Rank active stations from known context such as direction, activity, band, QRG, AP and sked information.</p>
</section>
<section class="section narrow">
<article class="card content-card">
<div class="feature-icon large">🎯</div>
<h2>Why it matters</h2>
<p>During active VHF, UHF and microwave contests, relevant stations can disappear quickly in busy ON4KST chat traffic.</p>
<p>The Priority Score System helps operators focus on stations that are more likely to be useful during contest operation.</p>
<h2>Built for contest decisions</h2>
<p>KST4Contest is not just a chat viewer. It evaluates contest-relevant context and helps turn chat activity into better operating decisions.</p>
<h2>Keywords</h2>
<div class="tag-list">
<span>ON4KST</span>
<span>VHF</span>
<span>UHF</span>
<span>SHF</span>
<span>contest</span>
<span>priority candidates</span>
</div>
<h2>Related features</h2>
<div class="actions">
<a class="button secondary" href="/features/timeline/">Timeline View</a>
<a class="button secondary" href="/features/airscout/">AirScout Integration</a>
<a class="button secondary" href="/features/sked-reminder/">Sked Reminder</a>
</div>
</article>
</section>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "TechArticle",
"headline": "Priority Score System",
"description": "Rank active stations from known context such as direction, activity, band, QRG, AP and sked information.",
"about": "KST4Contest",
"url": "https://kst4contest.hamradioonline.de/features/priority-score/",
"author": {
"@type": "Person",
"name": "Praktimarc"
},
"publisher": {
"@type": "Organization",
"name": "KST4Contest"
}
}
</script></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
@@ -0,0 +1,221 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Sked Reminder</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="Sked Reminder keeps scheduled contacts visible and provides automatic advance messages together with acoustic and visual operator alerts.">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/features/sked-reminder/">
<meta property="og:type" content="website">
<meta property="og:title" content="Sked Reminder">
<meta property="og:description" content="Sked Reminder keeps scheduled contacts visible and provides automatic advance messages together with acoustic and visual operator alerts.">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/features/sked-reminder/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Sked Reminder">
<meta name="twitter:description" content="Sked Reminder keeps scheduled contacts visible and provides automatic advance messages together with acoustic and visual operator alerts.">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="hero">
<p class="badge">Sked Management · since 1.40</p>
<h1>Sked Reminder</h1>
<p class="lead">Store planned contacts and issue configurable chat messages plus local alerts before the agreed time.</p>
</section>
<section class="section narrow">
<article class="card content-card">
<div class="feature-icon large">🔔</div>
<h2>Never lose important skeds</h2>
<p>During active contests, it is easy to miss a planned contact while handling chat traffic, logging and band changes.</p>
<p>Sked Reminder keeps scheduled contacts visible.</p>
<h2>Built for real contest pressure</h2>
<p>The workflow supports time-critical operation where missing a few minutes can mean missing a QSO.</p>
<h2>Keywords</h2>
<div class="tag-list">
<span>sked</span>
<span>ON4KST</span>
<span>contest reminder</span>
</div>
<h2>Related features</h2>
<div class="actions">
<a class="button secondary" href="/features/priority-score/">Priority Score System</a>
<a class="button secondary" href="/features/airscout/">AirScout Integration</a>
<a class="button secondary" href="/features/timeline/">Timeline View</a>
</div>
</article>
</section>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "TechArticle",
"headline": "Sked Reminder",
"description": "Store planned contacts and issue configurable chat messages plus local alerts before the agreed time.",
"about": "KST4Contest",
"url": "https://kst4contest.hamradioonline.de/features/sked-reminder/",
"author": {
"@type": "Person",
"name": "Praktimarc"
},
"publisher": {
"@type": "Organization",
"name": "KST4Contest"
}
}
</script></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
+199
View File
@@ -0,0 +1,199 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Timeline View</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="The Timeline View places upcoming aircraft scatter candidates and planned skeds into a common time-based overview.">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/features/timeline/">
<meta property="og:type" content="website">
<meta property="og:title" content="Timeline View">
<meta property="og:description" content="The Timeline View places upcoming aircraft scatter candidates and planned skeds into a common time-based overview.">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/features/timeline/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Timeline View">
<meta name="twitter:description" content="The Timeline View places upcoming aircraft scatter candidates and planned skeds into a common time-based overview.">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="hero">
<p class="badge">Contest Awareness · since 1.40</p>
<h1>Timeline View</h1>
<p class="lead">Show AP-based priority candidates and scheduled contacts on a shared timeline.</p>
</section>
<section class="section narrow">
<article class="card content-card">
<div class="feature-icon large">⏱️</div>
<h2>Timing matters</h2>
<p>Many VHF/UHF/SHF opportunities are short-lived.</p>
<p>The Timeline View helps operators see upcoming timing windows instead of keeping everything in mind manually.</p>
<h2>Designed for fast awareness</h2>
<p>The timeline supports quick decisions during busy contest operation.</p>
<h2>Keywords</h2>
<div class="tag-list">
<span>timeline</span>
<span>AP windows</span>
<span>airplane scatter</span>
</div>
<h2>Related features</h2>
<div class="actions">
<a class="button secondary" href="/features/airscout/">AirScout Integration</a>
<a class="button secondary" href="/features/priority-score/">Priority Score System</a>
</div>
</article>
</section>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "TechArticle",
"headline": "Timeline View",
"description": "Show AP-based priority candidates and scheduled contacts on a shared timeline.",
"about": "KST4Contest",
"url": "https://kst4contest.hamradioonline.de/features/timeline/",
"author": {
"@type": "Person",
"name": "Praktimarc"
},
"publisher": {
"@type": "Organization",
"name": "KST4Contest"
}
}
</script></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
+35
View File
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>KST4Contest News</title>
<link>https://kst4contest.hamradioonline.de/</link>
<description>News and release updates for KST4Contest.</description>
<language>en</language>
<item>
<title>AUR Packages now live of kst4contest</title>
<link>https://kst4contest.hamradioonline.de/news/2026-07-15-AUR-Packages/</link>
<guid>https://kst4contest.hamradioonline.de/news/2026-07-15-AUR-Packages/</guid>
<pubDate>Wed, 15 Jul 2026 00:00:00 GMT</pubDate>
<description>We now uploaded the packages of kst4contest to the AUR</description>
</item>
<item>
<title>Hotfix Version 1.41.1</title>
<link>https://kst4contest.hamradioonline.de/news/2026-07-08-hotfix-version-1-41-1/</link>
<guid>https://kst4contest.hamradioonline.de/news/2026-07-08-hotfix-version-1-41-1/</guid>
<pubDate>Wed, 08 Jul 2026 00:00:00 GMT</pubDate>
<description>Hotfix of a bug in Version 1.41</description>
</item>
<item>
<title>KST4Contest Website Launch</title>
<link>https://kst4contest.hamradioonline.de/news/2026-07-website-launch/</link>
<guid>https://kst4contest.hamradioonline.de/news/2026-07-website-launch/</guid>
<pubDate>Tue, 07 Jul 2026 00:00:00 GMT</pubDate>
<description>The new KST4Contest website is being built as a static, SEO-friendly product portal with GitHub-based documentation.</description>
</item>
</channel>
</rss>
+366
View File
@@ -0,0 +1,366 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>KST4Contest ON4KST Contest Client for VHF, UHF and SHF</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest combines ON4KST chat, candidate prioritisation, sked planning, AirScout data and logger integration in one desktop client.">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/">
<meta property="og:type" content="website">
<meta property="og:title" content="KST4Contest ON4KST Contest Client for VHF, UHF and SHF">
<meta property="og:description" content="KST4Contest combines ON4KST chat, candidate prioritisation, sked planning, AirScout data and logger integration in one desktop client.">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="KST4Contest ON4KST Contest Client for VHF, UHF and SHF">
<meta name="twitter:description" content="KST4Contest combines ON4KST chat, candidate prioritisation, sked planning, AirScout data and logger integration in one desktop client.">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="hero hero-split">
<canvas class="hero-radio-fx" data-hero-radio-fx aria-hidden="true"></canvas>
<div class="hero-fx-vignette" aria-hidden="true"></div>
<div class="hero-copy">
<p class="badge">ON4KST contest workflow for 144 MHz and above</p>
<h1>KST4Contest</h1>
<p class="lead">
ON4KST shows you the traffic. KST4Contest helps turn it into an operating
decision by combining chat, candidate prioritisation, sked planning,
AirScout data and logger integration in one desktop client.
</p>
<p>
The available information is filtered, related to active stations and
presented in a contest-oriented workflow. The final decision still
belongs to the operator.
</p>
<div class="actions">
<a class="button" href="/download/">Download KST4Contest</a>
<a class="button secondary" href="/manual/">Read the manual</a>
<a class="button ghost" href="https://github.com/praktimarc/kst4contest">View source code</a>
</div>
</div>
<div class="hero-panel">
<div class="terminal-bar">
<span></span><span></span><span></span>
<strong>Functions sharing the same station context</strong>
</div>
<div class="mock-grid">
<div class="mini-card">
<strong>✈️ AirScout Integration</strong>
<small>Use AirScout AP predictions in candidate evaluation, the timeline and sked planning.</small>
</div>
<div class="mini-card">
<strong>💬 Dual Chat Categories</strong>
<small>Log in to two ON4KST categories and handle both message streams in one station list and interface.</small>
</div>
<div class="mini-card">
<strong>📡 DXCluster Server</strong>
<small>Send direction warnings as DX Cluster spots to compatible logging software when a usable QRG is known.</small>
</div>
<div class="mini-card">
<strong> KST4Contest Features</strong>
<small></small>
</div>
<div class="mini-card">
<strong>🔄 Log Synchronization</strong>
<small>Import worked stations and current frequencies from supported contest loggers so filters and band information follow the log.</small>
</div>
<div class="mini-card">
<strong>⚡ Macros and Variables</strong>
<small>Build recurring chat messages from configurable text blocks and variables such as the current QRG or locator.</small>
</div>
</div>
</div>
</section>
<section class="section">
<div class="section-heading">
<p class="eyebrow">The operating problem</p>
<h2>The useful station is rarely the only station in the chat</h2>
<p>
During an active contest, messages, sked requests, frequency information
and band changes arrive continuously. The task is to identify which part
of that traffic matters now, which candidate should be monitored and
which contact is better scheduled for later.
</p>
</div>
<div class="grid">
<article class="card">
<h3>Observe</h3>
<p>
Messages, locators, detected frequencies and known band activity are
assigned to stations across as many as two ON4KST chat categories.
</p>
</article>
<article class="card">
<h3>Evaluate</h3>
<p>
Direction, distance, worked status, NOT-QRV information, chat activity,
sked context and aircraft scatter data feed filters and candidate scores.
</p>
</article>
<article class="card">
<h3>Act</h3>
<p>
Candidates can be contacted, scheduled or monitored. Skeds remain
visible, while supported loggers and station interfaces receive the
information required for the next operating step.
</p>
</article>
</div>
</section>
<section class="section">
<div class="section-heading">
<p class="eyebrow">Functions</p>
<h2>One workflow, shared context</h2>
<p>
The individual functions are not isolated tools. They use the same
station, message, band and timing information, so that a change in one
part of the workflow can also affect filters, priorities and reminders.
</p>
</div>
<div class="grid">
<article class="card feature-card">
<div class="feature-icon">✈️</div>
<p class="eyebrow">Aircraft Scatter</p>
<h3><a href="/features/airscout/">AirScout Integration</a></h3>
<p>Use AirScout AP predictions in candidate evaluation, the timeline and sked planning.</p>
<a href="/features/airscout/">Read how it works →</a>
</article>
<article class="card feature-card">
<div class="feature-icon">💬</div>
<p class="eyebrow">ON4KST Chat</p>
<h3><a href="/features/dual-chat/">Dual Chat Categories</a></h3>
<p>Log in to two ON4KST categories and handle both message streams in one station list and interface.</p>
<a href="/features/dual-chat/">Read how it works →</a>
</article>
<article class="card feature-card">
<div class="feature-icon">📡</div>
<p class="eyebrow">Radio Workflow</p>
<h3><a href="/features/dx-cluster/">DXCluster Server</a></h3>
<p>Send direction warnings as DX Cluster spots to compatible logging software when a usable QRG is known.</p>
<a href="/features/dx-cluster/">Read how it works →</a>
</article>
<article class="card feature-card">
<div class="feature-icon"></div>
<p class="eyebrow"></p>
<h3><a href="/features/">KST4Contest Features</a></h3>
<p></p>
<a href="/features/">Read how it works →</a>
</article>
<article class="card feature-card">
<div class="feature-icon">🔄</div>
<p class="eyebrow">Logger Integration</p>
<h3><a href="/features/log-sync/">Log Synchronization</a></h3>
<p>Import worked stations and current frequencies from supported contest loggers so filters and band information follow the log.</p>
<a href="/features/log-sync/">Read how it works →</a>
</article>
<article class="card feature-card">
<div class="feature-icon"></div>
<p class="eyebrow">Operator Speed</p>
<h3><a href="/features/macros/">Macros and Variables</a></h3>
<p>Build recurring chat messages from configurable text blocks and variables such as the current QRG or locator.</p>
<a href="/features/macros/">Read how it works →</a>
</article>
<article class="card feature-card">
<div class="feature-icon">🎯</div>
<p class="eyebrow">Contest Workflow</p>
<h3><a href="/features/priority-score/">Priority Score System</a></h3>
<p>Rank active stations from known context such as direction, activity, band, QRG, AP and sked information.</p>
<a href="/features/priority-score/">Read how it works →</a>
</article>
<article class="card feature-card">
<div class="feature-icon">🔔</div>
<p class="eyebrow">Sked Management</p>
<h3><a href="/features/sked-reminder/">Sked Reminder</a></h3>
<p>Store planned contacts and issue configurable chat messages plus local alerts before the agreed time.</p>
<a href="/features/sked-reminder/">Read how it works →</a>
</article>
<article class="card feature-card">
<div class="feature-icon">⏱️</div>
<p class="eyebrow">Contest Awareness</p>
<h3><a href="/features/timeline/">Timeline View</a></h3>
<p>Show AP-based priority candidates and scheduled contacts on a shared timeline.</p>
<a href="/features/timeline/">Read how it works →</a>
</article>
</div>
</section>
<section class="section">
<div class="cta-panel">
<p class="eyebrow">Limits</p>
<h2>A priority score is not a propagation forecast</h2>
<p>
KST4Contest can only evaluate the information it knows. Scores, AP
windows, filters and path profiles support the operator's decision; they
do not guarantee a contact. If the input data is incomplete or outdated,
the result can be incomplete or outdated as well.
</p>
<div class="actions">
<a class="button" href="/features/">Explore the functions</a>
<a class="button secondary" href="/manual/">Read the technical details</a>
</div>
</div>
</section>
<section class="section">
<div class="cta-panel">
<p class="eyebrow">Project status</p>
<h2>Stable for operation, Nightly for testing</h2>
<p>
KST4Contest is open-source software. The current stable release is the
normal choice for contest operation. Nightly builds follow ongoing
development and are useful when a particular fix or feature needs
testing. A few minutes before a contest is not the ideal time to discover
what changed.
</p>
<div class="actions">
<a class="button" href="/download/">Download the stable release</a>
<a class="button secondary" href="/roadmap/">Development status</a>
<a class="button ghost" href="/support/">Support development</a>
</div>
</div>
</section>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "KST4Contest",
"applicationCategory": "CommunicationApplication",
"operatingSystem": "Windows, Linux, macOS",
"url": "https://kst4contest.hamradioonline.de/",
"downloadUrl": "https://github.com/praktimarc/kst4contest/releases/latest",
"description": "KST4Contest combines ON4KST chat, candidate prioritisation, sked planning, AirScout data and logger integration for VHF, UHF and SHF contest operation.",
"license": "https://github.com/praktimarc/kst4contest/blob/main/LICENSE"
}
</script></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
<script src="/assets/js/hero-radio-fx.js?v=1784595000789" defer></script>
</body>
</html>
+538
View File
@@ -0,0 +1,538 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<praktiKST>
<latestVersion>
<versionNumber>1.411</versionNumber>
<semanticVersion>1.41.1</semanticVersion>
<adminMessage></adminMessage>
<majorChanges>- Score of Top-Priority Candidates in the user section
- Broadcast Messages (To ALL Station in Contest) in seperate Window</majorChanges>
<latestVersionPathOnWebserver>https://github.com/praktimarc/kst4contest/releases/tag/v1.41.1</latestVersionPathOnWebserver>
</latestVersion>
<needUpdateSinceLastVersion>
<filename>nothing</filename>
</needUpdateSinceLastVersion>
<roadmap>
<featurerequest>
<featureDescription>Cyclic update of own name in chat to actual QRG</featureDescription>
<requestDate>2024-02</requestDate>
<state>open</state>
</featurerequest>
<featurerequest>
<featureDescription>Acoustic warnings</featureDescription>
<requestDate>2023-12</requestDate>
<state>added</state>
</featurerequest>
<featurerequest>
<featureDescription>Airscout support</featureDescription>
<requestDate>2023-03</requestDate>
<state>added</state>
</featurerequest>
<featurerequest>
<featureDescription>cyclic beacon messages in public chat</featureDescription>
<requestDate>2023-03</requestDate>
<state>added</state>
</featurerequest>
</roadmap>
<bugsReported>
<bug>
<bugdescription>
stations like ol7c-7 and ol7c-2 will not be marked as worked if only "ol7c"
is in the log. Need to interprete that. May ignore suffix starting with "-"</bugdescription>
<state>solved</state>
</bug>
<bug>
<bugdescription>
worked callsigns table is updated only once after connected to chat
Should be available directly after program started.
But Reset works all time</bugdescription>
<state>open</state>
</bug>
<bug>
<bugdescription>feature request: language-specific strings, maybe based to an xml file
</bugdescription>
<state>open</state>
</bug>
<bug>
<bugdescription>feature request: Macros
</bugdescription>
<state>added</state>
</bug>
<bug>
<bugdescription>feature request:
Automatic elimination of calls already connected from the log
</bugdescription>
<state>added</state>
</bug>
<bug>
<bugdescription>feature request:
Limitation of users beyond a certain QRB
</bugdescription>
<state>added</state>
</bug>
<bug>
<bugdescription>feature request:
User division for QTF perhaps settable based on the antenna lobe
</bugdescription>
<state>added</state>
</bug>
<bug>
<bugdescription>feature request:
Notification of new incoming users</bugdescription>
<state>added</state>
</bug>
<bug>
<bugdescription>feature request:
Evidence of a call which was written but not responded to.
</bugdescription>
<state>added</state>
</bug>
<bug>
<bugdescription>feature request:
direction based reachable-warnings:
if the chatclient detects a realised qso between two stations which both must have
directed their beams to my station, there should be an instant warning to me for
working at least one of the stations at the detected qrg</bugdescription>
<state>open</state>
</bug>
<bug>
<bugdescription>feature request:
implement ASShowpath message to airacout;
by doubleclicking a callsign in the chatmember list, the path and plane state should be
provided by airscout </bugdescription>
<state>open</state>
</bug>
<bug>
<bugdescription>feature request:
make chatlines copyable to the clipboard...</bugdescription>
<state>open</state>
</bug>
<bug>
<bugdescription>feature request:
adding an activity detection for sensing if another chatmembers alive-state</bugdescription>
<state>added</state>
</bug>
<bug>
<bugdescription>On sql error close the connection to make a clean exit</bugdescription>
<state>open</state>
</bug>
<bug>
<bugdescription>SETNAME /MYQRG in options menu doesnt work</bugdescription>
<state>solved</state>
</bug>
<bug>
<bugdescription>Disconnect button does not work (DL5ZK)</bugdescription>
<state>solved</state>
</bug>
<bug>
<bugdescription>Password-wrong error not displayed (DO5SA)</bugdescription>
<state>solved</state>
</bug>
<bug>
<bugdescription>/CQ isnt written on own PMs</bugdescription>
<state>solved</state>
</bug>
<bug>
<bugdescription>rightclick-textsnippets arent available in cq-table</bugdescription>
<state>solved</state>
</bug>
</bugsReported>
<changeLog>
<changedVersionNumber>1.41.1</changedVersionNumber>
<date>2026-07-08</date>
<description>Release v1.41.1</description>
<added></added>
<changed>Hotfix of Bug #56</changed>
<fixed></fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>1.41.0</changedVersionNumber>
<date>2026-07-01</date>
<description>Release v1.41.0</description>
<added>- Score of Top-Priority Candidates in the user section
- Broadcast Messages (To ALL Station in Contest) in seperate Window</added>
<changed>Migration to Github
- Band and Frequency Detection per Chatmember — KST4Contest identifies which bands or frequencies a station appears active or reachable on based on chat data. This information is integrated into the display and prioritization.
- Band Alert — If a logged station could be of interest on other locally active bands, KST14Contest can alert the user.
- Sked Reminder ALERT — New reminder function for planned Skeds to ensure that agreed contacts are not forgotten during contest operation.
- Skedfail Button — Failed Skeds can be marked; this allows the station to be handled differently in terms of score and workflow.
- Win-Test SKED Push via UDP — Skeds can be passed to Win-Test via a LOCKSKED/ADDSKED/UNLOCKSKED sequence. This feature is configurable in the preferences and disabled by default.
- Win-Test Broadcast Defaults and SKed Workflow — Improved broadcast addresses, frequency formats, mode selection, and notes including locator/azimuth.
- PSTRotator Interface — KST4Contest received an interface to PSTRoter to better integrate antenna direction and rotator workflow.
- QSO /-Callsign Sniffer — Callsigns or QSO-relevant information can be detected and utilized for further workflow.
- Chat History at Startup — Historical chat data can be loaded upon startup, allowing the client to quickly gain relevant context for scoring, activity, and station identification.
- Station Map / Map View — New map view with station markers, your own location, locator/Maidenhead reference, connection line, and antenna/beam representation.
- Local Leaflet /-TileProxy Backend — The map function utilizes embedded Leaflet resources and a local TileProxy approach, making the map more portable and independent.
- Maidenhead /-Grid Overlay — The map can display locator/grid information; recently added Grid-Square coloring.
- Path /-Terrain /-Horizon Profile — Map documentation describes a path profile with terrain, Fresnel, and horizon information for the selected link.
- Tropo /-AS Reachability Filters — New filters and sorting were added for Tropospheric reachability, AirScoop availability, large locator fields, and priority.
- Reachability Band Selector — Added a band selection for range/Troposphere calculations.
- 4-Char Locator Filter — Locator evaluations can be reduced to 4-character fields; this improves overview and performance.
- KST Testserver Support — A KST server test server was added into the Source.
@praktimarc and @Rsclub22</changed>
<fixed>- [BUG]
- [BUG] Programmstart kann ohne selektieren keine Nachrichten senden
- KST4Contest crashes after to many messages or to much RAM Usage
- Scaling Problem at 1280x800 screen resolution</fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>1.40</changedVersionNumber>
<date>2026-02-16</date>
<description>Much changes and fixes</description>
<added>
- win-test support (not deactivable yet, beta)
- QSO sniffer which filters changable callsigns lists messages to your pm window
- Chatmember Score system. Each chatmember gets a score depending to antenna direction, activity time,
activity msgcount, positive signals, active bands, active frequencies, his sked direction (degrees),
self handed rate, sked-made-rate and some others
- Chatmember Band and frequency recognition: now we list all active bands of each other chatmember
- Band alert for logged stations
- Sked reminder ALERT with automatic messages in 2+1 / 5+2+1 / 10+5+2+1 minutes
- PSTRotator interface
- AirPlane Timeline
- Skedfail button in furtherinfo panel
- Wintest logsynch interface can now be activated and deactivated in the preferences
- load chat history on startup
</added>
<changed>
- added save option: ServerDNS / Port
- added save option: activate/deactivate pstRotator interface
- added save option: activate/deactivate wintest interface
- added save option: callsign sniffer
- added save option: boolean GUI_darkModeActiveByDefault = false
- added AP notes at the internal DX cluster spots
- Generic Autoanswer fires maximum once in 45 seconds per rx callsign
</changed>
<fixed>
- Userlist sort automatically on new member signon
- Posonpill-messages now kills only exactly one Client instance (bugreport 9A2HM)
- Crash of wtkst by disconnection of kst4Contest
- wtKST crashes when kst4contest is running (many reporters)
- wintest: logged per band excludes pre worked band (bugreport SM6VTZ)
- PSTRotator SOCKET Close on DISCONNECT BUTTON works now
- AirScout Map had not been updated (bugreport SM0RJV)
- QTFDefault had been not saved correctly (bugreport SM0RJV)
- Show path in AS button worked only with fixed server Strings (bugreport 9A2HM)
- Version number had been displayed wrong
- suffixes like /p, -2, etc. problem now fixed everywhere
- Dark mode: passing for qrg fields fix
</fixed>
<removed>
- No more date display. Not needed. Saving space, only time is important
</removed>
</changeLog>
<changeLog>
<changedVersionNumber>1.31</changedVersionNumber>
<date>2025-12-13</date>
<description>Much changes and a hotfix</description>
<added>
- win-test support (not deactivable yet, beta)
- pstRotator support (not deactivable yet, beta)
- airScout fix (calculations depends to cpu load now)
- QSO sniffer
</added>
<changed>
- DNS from www.on4kst.info to www.on4kst.org (hotfix, now configurable in preferences)
</changed>
<fixed>
- Endless loop in error case lets freeze the client
- PSTRotator SOCKET Close on DISCONNECT BUTTON
- Dark mode: passing for qrg fields fix
</fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>1.266</changedVersionNumber>
<date>2025-10-03</date>
<description>Airscout interface did not work with multi-signons</description>
<added>nothing</added>
<changed>nothing</changed>
<fixed>
Fixed by using raw callsign (without -2 suffix etc.) when communicating with AirScout.
Thank you very much for testing this, Kreso 9A2HM!
</fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>1.265</changedVersionNumber>
<date>2025-09-28</date>
<description>Direction buttons stay now colored, if activated</description>
<added>nothing</added>
<changed>nothing</changed>
<fixed>The buttons stay now colored, if activated</fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>1.264</changedVersionNumber>
<date>2025-08-02</date>
<description>Changed the callsign recognition pattern for Simplelogfile</description>
<added>nothing</added>
<changed>nothing</changed>
<fixed>
Callsigns like S53CC, S51A etc. are now correctly marked as worked in SimpleLogFile.txt.
(bugreport Boris, S53CC)
</fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>1.263</changedVersionNumber>
<date>2025-06-08</date>
<description>Airscout communication and Loginname</description>
<added>nothing</added>
<changed>
Only entries with QRB lower than max-QRB are sent to AirScout in 60s intervals (was 12s for all).
</changed>
<fixed>
- AS communication message count hugely reduced
- Name in chat is now saveable
- Fixed AS client name (was hard-wired to "KST")
73 / DO5AMF
</fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>1.262</changedVersionNumber>
<date>2025-05-21</date>
<description>Freezes caused by getting messages before user login should be fixed now</description>
<added>nothing</added>
<changed>nothing</changed>
<fixed>
ON4KST delivers messages of stations not yet logged in. That caused a freeze at the message
processing engine which is now fixed.
</fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>1.26</changedVersionNumber>
<date>2025-05</date>
<description>Login to multiple Channels via single signon / spend some colors</description>
<added>
1. UI: Dark mode. Switch in "Window -> use dark mode"
2. Usage of two Chatcategories at the same time
3. opposite station multi-callsign login-tagging
73 / DO5AMF
</added>
<changed>
- Coloring mechanic of the software. Modify colors via css by yourself...
</changed>
<fixed>
- Station tagging fixed completely
</fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>1.251</changedVersionNumber>
<date>2025-02</date>
<description>BUGFIX of 1.25, tnx Steve Clements!</description>
<added>
- Steve spotted a problem in udp broadcast spot info reading, its now fixed!
73 / DO5AMF
</added>
<changed></changed>
<fixed>- Station tagging</fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>1.25</changedVersionNumber>
<date>2025-02</date>
<description>Wishlist-time</description>
<added>
- New configuration Tab: Messagehandling (auto-answering, CQ qrg auto-answer)
- Coloured lines: new pm rows appear in red, fade rainbow-like to white over 30s (tnx Gianluca)
73 / DO5AMF
</added>
<changed></changed>
<fixed>
- Users with suffixes like "-2 and -70" are now correctly marked as worked
</fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>1.24</changedVersionNumber>
<date>2024-11</date>
<description>Wishlist-time</description>
<added>
- Button to show qrz.com profile of a selected station
- Button to show qrzcq.com profile of a selected station
</added>
<changed></changed>
<fixed></fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>1.23</changedVersionNumber>
<date>2024-10</date>
<description>DXCluster Server is now implemented</description>
<added>
- DXCluster Server (tnx OMAAO): KST4Contest now provides a DXCluster server to feed
your log client with station-reachable warnings.
</added>
<changed></changed>
<fixed></fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>1.22</changedVersionNumber>
<date>2024-05</date>
<description>Increase usability, fixed AS button</description>
<added>- Variables (tnx OMAAO): MYLOCATORSHORT, MYQRGSHORT, QRZNAME</added>
<changed>- Sendtext-field focus on callsign click</changed>
<fixed>
- Worked-station-filter (tnx Gianluca): filter is now live
- Chatters list sorting by QRB (tnx Alessandro): fixed to numeric sort
- Airscout showpath button now maximizes AS and shows the path
</fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>1.21</changedVersionNumber>
<date>2024-04</date>
<description>Increase usability</description>
<added></added>
<changed>
- Window sizes and divider positions are now stored and restored on next startup
- Filters section is now a flowpane for lower resolutions
</changed>
<fixed></fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>1.2</changedVersionNumber>
<date>2024-04</date>
<description>Increase usability</description>
<added>
- Selectable bands
- Unworkable tags for each callsign per band
- QTF-Arrow on the "show path in AS" button
</added>
<changed></changed>
<fixed></fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>1.1</changedVersionNumber>
<date>2024-03</date>
<description>Increased workflow</description>
<added>
- Reachable warning function
- Variables FIRSTAP and SECONDAP for predefined texts
- Marking new connected stations (bold) and away-state (brackets)
- Activity-timer since last message of a chatter
</added>
<changed>- QRB/QTF info in pm-window</changed>
<fixed>
- Behaviour of messagefilter-radiobutton corrected (tnx Gian)
- Error sending macros on selected stations in pm window (tnx Gian)
</fixed>
<removed>- boot sound</removed>
</changeLog>
<changeLog>
<changedVersionNumber>1.0</changedVersionNumber>
<date>2024-02</date>
<description>First stable release</description>
<added>
- audio notification support
- update-available warning
- changelog displaying
- known-bugs displaying
- message filters for selected station
- stationlist-filters (show by qtf / textstring, hide by qrb, qtf, workedstate)
- 10 macros (textsnippets available by hitting strg+numberkey)
</added>
<changed></changed>
<fixed></fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>0.9</changedVersionNumber>
<date>2024-02</date>
<description>Now the chat is disconnectable without closing it</description>
<added></added>
<changed></changed>
<fixed>disconnect-button, Textsnippets in CQ Window, "/CQ" at click on own sendtexts,
setname "qrg" works now</fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>0.8</changedVersionNumber>
<date>2023-10</date>
<description>savesettings function and disconnect function added. MYCALL-Highlighting fixed</description>
<added>savesettings function, disconnect function</added>
<changed></changed>
<fixed>MYCALL-Highlighting</fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>0.7</changedVersionNumber>
<date>2023-07</date>
<description>Internal database for worked stations, shortcut and textsnippet editor</description>
<added>database, shortcut-editor, textsnipped-editor</added>
<changed></changed>
<fixed></fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>0.6</changedVersionNumber>
<date>2023-07</date>
<description>Added periodically sent beacon function</description>
<added>beacon to public channel</added>
<changed></changed>
<fixed></fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>0.5</changedVersionNumber>
<date>2023-02</date>
<description>Airscout interface, UDP interfaces for worked-station data and TRX info, shortcuts</description>
<added>Airscout-interface, packetreceiver for ucxlog, n1mm, qartest</added>
<changed></changed>
<fixed></fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>0.4</changedVersionNumber>
<date>2022-12</date>
<description>Worked info by logfile via universal pattern matching logfile interpreter</description>
<added>simple-logfile</added>
<changed></changed>
<fixed></fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>0.3</changedVersionNumber>
<date>2022-10</date>
<description>Added a GUI, chat was text based only</description>
<added>Graphical user interface</added>
<changed></changed>
<fixed></fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>0.2</changedVersionNumber>
<date>2022-10</date>
<description>Pattern matching system for frequency information, frequency collection per chatmember</description>
<added>frequency-extraction for every callsign</added>
<changed></changed>
<fixed></fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>0.15</changedVersionNumber>
<date>2022-09</date>
<description>Researched the Chatprotocol and developed the base communication with the chatserver</description>
<added></added>
<changed></changed>
<fixed></fixed>
<removed></removed>
</changeLog>
<changeLog>
<changedVersionNumber>0.1</changedVersionNumber>
<date>2022-09</date>
<description>Primary architecture of the chat, message bus system for handling the message queues</description>
<added></added>
<changed></changed>
<fixed></fixed>
<removed></removed>
</changeLog>
</praktiKST>
+135
View File
@@ -0,0 +1,135 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Legal Notice | KST4Contest</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="Legal notice for the KST4Contest website.">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/legal-notice/">
<meta property="og:type" content="website">
<meta property="og:title" content="Legal Notice | KST4Contest">
<meta property="og:description" content="Legal notice for the KST4Contest website.">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/legal-notice/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Legal Notice | KST4Contest">
<meta name="twitter:description" content="Legal notice for the KST4Contest website.">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="hero">
<p class="badge">Legal Notice</p>
<h1>Legal Notice</h1>
<p class="lead">Information according to § 5 DDG.</p>
</section>
<section class="section narrow">
<article class="card content-card">
<h2>Provider</h2>
<p>
Marc Fröhlich<br>
Rheingoldstr. 6<br>
68199 Mannheim<br>
Germany
</p>
<h2>Contact</h2>
<p>
Email: <a href="mailto:praktimarc+kst4contest@gmail.com">praktimarc+kst4contest@gmail.com</a>
</p>
<h2>Responsible for content</h2>
<p>
Marc Fröhlich<br>
Rheingoldstr. 6<br>
68199 Mannheim<br>
Germany
</p>
<h2>Project</h2>
<p>
KST4Contest is an open-source ON4KST contest client.
Source code and releases are available on
<a href="https://github.com/praktimarc/kst4contest">GitHub</a>.
</p>
</article>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

@@ -0,0 +1,209 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ manual.title }} | KST4Contest Manual</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest manual page: {{ manual.title }}">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/manual/de/airscout-integration/">
<meta property="og:type" content="website">
<meta property="og:title" content="{{ manual.title }} | KST4Contest Manual">
<meta property="og:description" content="KST4Contest manual page: {{ manual.title }}">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/manual/de/airscout-integration/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="section">
<div class="card manual-content">
<p><a href="/manual/de/">← Back to manual overview</a></p>
<h1>AirScout-Integration</h1>
<h1 id="airscout-integration" tabindex="-1"><a class="header-anchor" href="#airscout-integration">AirScout-Integration</a></h1>
<blockquote>
<p>🇬🇧 <a href="/manual/en/airscout-integration/">English version</a> | 🇩🇪 Du liest gerade die deutsche Version</p>
</blockquote>
<p>AirScout (von DL2ALF) ist ein Programm zur Erkennung von Flugzeugen für den Aircraft-Scatter-Betrieb. KST4Contest ist eng mit AirScout integriert und zeigt reflektierbare Flugzeuge direkt in der Benutzerliste an.</p>
<blockquote>
<p><strong>Aircraft Scatter</strong> ermöglicht sehr weitreichende Verbindungen auf VHF und höher auch für Stationen mit geringer Höhe über NN oder ungünstigen topografischen Verhältnissen.</p>
</blockquote>
<hr>
<h2 id="airscout-herunterladen" tabindex="-1"><a class="header-anchor" href="#airscout-herunterladen">AirScout herunterladen</a></h2>
<p>Download von AirScout:</p>
<ul>
<li><a href="http://airscout.eu/index.php/download">http://airscout.eu/index.php/download</a></li>
</ul>
<hr>
<h2 id="flugzeugdaten-feeds-(adsb)" tabindex="-1"><a class="header-anchor" href="#flugzeugdaten-feeds-(adsb)">Flugzeugdaten-Feeds (ADSB)</a></h2>
<p>Öffentliche Flugzeugdaten-Feeds im Internet sind oft unzuverlässig und begrenzt nutzbar. Eine empfohlene Alternative bietet <strong>OV3T (Thomas)</strong> mit einem dedizierten ADSB-Feed-Dienst:</p>
<ul>
<li><a href="https://airscatter.dk/">https://airscatter.dk/</a></li>
<li><a href="https://www.facebook.com/groups/825093981868542">https://www.facebook.com/groups/825093981868542</a></li>
</ul>
<p>Für diesen Dienst ist ein Account erforderlich. Bitte eine Spende für Thomas in Betracht ziehen der Server-Betrieb ist nicht kostenlos!</p>
<hr>
<h2 id="airscout-einrichten" tabindex="-1"><a class="header-anchor" href="#airscout-einrichten">AirScout einrichten</a></h2>
<h3 id="schritt-1%3A-adsb-feed-in-airscout-konfigurieren" tabindex="-1"><a class="header-anchor" href="#schritt-1%3A-adsb-feed-in-airscout-konfigurieren">Schritt 1: ADSB-Feed in AirScout konfigurieren</a></h3>
<ol>
<li>AirScout starten.</li>
<li>In den AirScout-Einstellungen den OV3T-Feed-Account eintragen (Benutzername, Passwort, URL).</li>
</ol>
<p><img src="/manual/assets/as_plane_feed_1.png" alt="AirscoutSchritt1">
<img src="/manual/assets/as_plane_feed_2.png" alt="AirscoutSchritt2"></p>
<ol start="3">
<li>Verbindung testen.</li>
</ol>
<h3 id="schritt-2%3A-udp-kommunikation-f%C3%BCr-kst4contest-aktivieren" tabindex="-1"><a class="header-anchor" href="#schritt-2%3A-udp-kommunikation-f%C3%BCr-kst4contest-aktivieren">Schritt 2: UDP-Kommunikation für KST4Contest aktivieren</a></h3>
<p>In AirScout die UDP-Schnittstelle aktivieren:</p>
<ul>
<li>In den AirScout-Einstellungen die entsprechende Checkbox aktivieren (nur eine Checkbox notwendig).</li>
<li>Standard-Ports nicht ändern, wenn kein besonderer Grund vorliegt.</li>
</ul>
<h3 id="schritt-3%3A-kst4contest-einstellungen" tabindex="-1"><a class="header-anchor" href="#schritt-3%3A-kst4contest-einstellungen">Schritt 3: KST4Contest-Einstellungen</a></h3>
<p>In den KST4Contest-Preferences → <strong>AirScout Settings</strong>:</p>
<ul>
<li>AirScout-Kommunikation aktivieren</li>
<li>IP und Port auf Standardwerte lassen (sofern nicht geändert)</li>
</ul>
<p><img src="/manual/assets/as_plane_feed_3.png" alt="AirscoutSchritt3">{ width=85% }</p>
<hr>
<h2 id="kommunikation-zwischen-kst4contest-und-airscout-(ab-v1.263)" tabindex="-1"><a class="header-anchor" href="#kommunikation-zwischen-kst4contest-und-airscout-(ab-v1.263)">Kommunikation zwischen KST4Contest und AirScout (ab v1.263)</a></h2>
<p><strong>Verbesserung in v1.263</strong>: KST4Contest sendet nur noch Stationen an AirScout, deren QRB (Entfernung) kleiner als das eingestellte <strong>Maximum-QRB</strong> ist. Das Abfrageintervall wurde von 12 Sekunden auf <strong>60 Sekunden</strong> verlängert.</p>
<p><strong>Vorteile:</strong></p>
<ul>
<li>Deutlich weniger Berechnungsaufwand für AirScout</li>
<li>Deutlich weniger Nachrichtenverkehr</li>
<li>Das Tracking-Problem mit dem „Show Path in AirScout&quot;-Button wurde dadurch deutlich verbessert</li>
<li>Weniger Rechenleistung insgesamt</li>
</ul>
<p>Außerdem: Der Name des KST4Contest-Clients und des AirScout-Servers war früher hartcodiert (<code>KST</code> und <code>AS</code>). Ab v1.263 werden die in den Preferences eingetragenen Namen verwendet.</p>
<hr>
<h2 id="mehrere-kst4contest-instanzen-und-airscout" tabindex="-1"><a class="header-anchor" href="#mehrere-kst4contest-instanzen-und-airscout">Mehrere KST4Contest-Instanzen und AirScout</a></h2>
<blockquote>
<p><strong>Achtung</strong>: Wenn mehrere KST4Contest-Instanzen gleichzeitig betrieben werden und bei beiden die AirScout-Kommunikation aktiviert ist, antwortet AirScout <strong>an beide Instanzen</strong>.</p>
</blockquote>
<p>Das ist unproblematisch, wenn:</p>
<ul>
<li>Beide Instanzen denselben Locator verwenden, <strong>oder</strong></li>
<li>Beide Instanzen unterschiedliche Login-Rufzeichen haben.</li>
</ul>
<p>Andernfalls kann es zu fehlerhaften AP-Daten kommen.</p>
<hr>
<h2 id="ap-spalte-in-der-benutzerliste" tabindex="-1"><a class="header-anchor" href="#ap-spalte-in-der-benutzerliste">AP-Spalte in der Benutzerliste</a></h2>
<p>Nach der Einrichtung erscheint in der Benutzerliste eine <strong>AP-Spalte</strong> mit bis zu zwei reflektierbaren Flugzeugen pro Station.</p>
<p>Beispiel-Darstellung:</p>
<table>
<thead>
<tr>
<th>Station</th>
<th>AP-Info</th>
</tr>
</thead>
<tbody>
<tr>
<td>DF9QX</td>
<td>2 Planes: 0 min / 0 min, je 100%</td>
</tr>
<tr>
<td>F5DYD</td>
<td>2 Planes: 14 min / 31 min, je 50%</td>
</tr>
</tbody>
</table>
<p>Die AP-Informationen sind auch im <strong>Privatnachrichten-Fenster</strong> verfügbar.</p>
<p>Die Prozentzahl gibt das Reflexionspotenzial an (Größe des Flugzeugs, Höhe, Entfernung).</p>
<hr>
<h2 id="ap-variablen-in-nachrichten" tabindex="-1"><a class="header-anchor" href="#ap-variablen-in-nachrichten">AP-Variablen in Nachrichten</a></h2>
<p>Die Flugzeugdaten können direkt in Nachrichten eingefügt werden:</p>
<ul>
<li><code>FIRSTAP</code> → z. B. <code>a very big AP in 1 min</code></li>
<li><code>SECONDAP</code> → z. B. <code>Next big AP in 9 min</code></li>
</ul>
<p>Details: <a href="Makros-und-Variablen#variablen">Makros und Variablen</a></p>
<hr>
<h2 id="%E2%80%9Eshow-path-in-airscout%22-button" tabindex="-1"><a class="header-anchor" href="#%E2%80%9Eshow-path-in-airscout%22-button">„Show Path in AirScout&quot;-Button</a></h2>
<p>In der Benutzerliste gibt es einen Button mit einem Pfeil, der die Richtung (QTF) zur ausgewählten Station anzeigt. Ein Klick maximiert AirScout und zeigt den Pfad mit reflektierbaren Flugzeugen zum ausgewählten Gesprächspartner.</p>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
@@ -0,0 +1,211 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ manual.title }} | KST4Contest Manual</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest manual page: {{ manual.title }}">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/manual/de/benutzeroberflaeche/">
<meta property="og:type" content="website">
<meta property="og:title" content="{{ manual.title }} | KST4Contest Manual">
<meta property="og:description" content="KST4Contest manual page: {{ manual.title }}">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/manual/de/benutzeroberflaeche/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="section">
<div class="card manual-content">
<p><a href="/manual/de/">← Back to manual overview</a></p>
<h1>Benutzeroberfläche</h1>
<h1 id="benutzeroberfl%C3%A4che" tabindex="-1"><a class="header-anchor" href="#benutzeroberfl%C3%A4che">Benutzeroberfläche</a></h1>
<blockquote>
<p>🇬🇧 <a href="/manual/en/user-interface/">English version</a> | 🇩🇪 Du liest gerade die deutsche Version</p>
</blockquote>
<h2 id="verbinden-mit-dem-chat" tabindex="-1"><a class="header-anchor" href="#verbinden-mit-dem-chat">Verbinden mit dem Chat</a></h2>
<ol>
<li>Im Einstellungsfenster eine <strong>Chat-Kategorie</strong> auswählen (z. B. 144 MHz VHF, 432 MHz UHF, …).</li>
<li><strong>Connect</strong>-Button klicken.</li>
<li>Warten bis die Verbindung aufgebaut ist.</li>
</ol>
<blockquote>
<p>Trennen und Neu-Verbinden ist nur über das Einstellungsfenster möglich. Es empfiehlt sich daher, das Einstellungsfenster geöffnet zu lassen.</p>
</blockquote>
<hr>
<h2 id="hauptfenster-%C3%BCberblick" tabindex="-1"><a class="header-anchor" href="#hauptfenster-%C3%BCberblick">Hauptfenster-Überblick</a></h2>
<p>Das Hauptfenster besteht aus mehreren Bereichen:</p>
<h3 id="pm-fenster-(oben-links)" tabindex="-1"><a class="header-anchor" href="#pm-fenster-(oben-links)">PM-Fenster (oben links)</a></h3>
<p>Zeigt alle empfangenen <strong>Privatnachrichten</strong> sowie abgefangene öffentliche Nachrichten, die das eigene Rufzeichen enthalten. Neue Nachrichten erscheinen in <strong>Rot</strong> und faden alle 30 Sekunden über Gelb bis Weiß ab.</p>
<h3 id="benutzerliste-(chat-members)" tabindex="-1"><a class="header-anchor" href="#benutzerliste-(chat-members)">Benutzerliste (Chat Members)</a></h3>
<p>Die zentrale Tabelle aller aktuell aktiven Chat-Nutzer. Spalten (je nach Konfiguration):</p>
<table>
<thead>
<tr>
<th>Spalte</th>
<th>Inhalt</th>
</tr>
</thead>
<tbody>
<tr>
<td>Call</td>
<td>Rufzeichen der Station</td>
</tr>
<tr>
<td>Name</td>
<td>Name aus dem Chat-Namenfeld</td>
</tr>
<tr>
<td>Loc</td>
<td>Maidenhead-Locator</td>
</tr>
<tr>
<td>QRB</td>
<td>Entfernung in km</td>
</tr>
<tr>
<td>QTF</td>
<td>Richtung in Grad</td>
</tr>
<tr>
<td>QRG</td>
<td>Automatisch erkannte Frequenz</td>
</tr>
<tr>
<td>AP</td>
<td>AirScout-Flugzeugdaten (wenn aktiv)</td>
</tr>
<tr>
<td>Band-Farben</td>
<td>Worked/NOT-QRV-Status pro Band</td>
</tr>
</tbody>
</table>
<p><strong>Sortierung</strong>: Klick auf Spaltenköpfe. QRB-Sortierung arbeitet numerisch (ab v1.22 korrigiert).</p>
<h3 id="sendfeld" tabindex="-1"><a class="header-anchor" href="#sendfeld">Sendfeld</a></h3>
<p>Texteingabe für ausgehende Nachrichten. Nach Klick auf ein Rufzeichen in der Benutzerliste erhält das Sendfeld automatisch den Fokus sofort tippen ohne Doppelklick (ab v1.22).</p>
<h3 id="myqrg-feld" tabindex="-1"><a class="header-anchor" href="#myqrg-feld">MYQRG-Feld</a></h3>
<p>Rechts neben dem Sendbutton. Zeigt die aktuelle eigene QRG an, kann auch manuell eingetragen werden.</p>
<h3 id="myqtf-feld-(f%C3%BCr-v1.3)" tabindex="-1"><a class="header-anchor" href="#myqtf-feld-(f%C3%BCr-v1.3)">MYQTF-Feld <em>(für v1.3)</em></a></h3>
<p>Eingabefeld für die aktuelle Antennenrichtung. Wird für die geplante <code>MYQTF</code>-Variable verwendet.</p>
<hr>
<h2 id="filter" tabindex="-1"><a class="header-anchor" href="#filter">Filter</a></h2>
<p>Die Filter-Leiste (ab v1.21 als Flowpane für kleine Bildschirme):</p>
<ul>
<li><strong>Show only QTF</strong>: Richtungsfilter aktivieren (Buttons N/NE/E/… oder Grad-Eingabe)</li>
<li><strong>Show only QRB [km] &lt;=</strong>: Entfernungsfilter aktivieren (Toggle-Button)</li>
<li><strong>Hide Worked [Band]</strong>: Gearbeitete Stationen pro Band ausblenden (je ein Toggle pro Band)</li>
<li><strong>Hide NOT-QRV [Band]</strong>: NOT-QRV-markierte Stationen pro Band ausblenden</li>
</ul>
<hr>
<h2 id="stationsinfo-panel-(further-info)" tabindex="-1"><a class="header-anchor" href="#stationsinfo-panel-(further-info)">Stationsinfo-Panel (Further Info)</a></h2>
<p>Rechts unten: Zeigt alle Nachrichten einer ausgewählten Station (CQ-Nachrichten und PMs in einem Panel). Ein Nachrichtenfilter lässt sich über den Standard-Filter in den Preferences vorbelegen.</p>
<p>Hier können auch <strong>Sked-Erinnerungen</strong> aktiviert werden.</p>
<hr>
<h2 id="priorit%C3%A4tsliste" tabindex="-1"><a class="header-anchor" href="#priorit%C3%A4tsliste">Prioritätsliste</a></h2>
<p>Zeigt die vom Score-Service berechneten Top-Kandidaten. Aktualisiert sich automatisch im Hintergrund basierend auf Richtung, Entfernung und AP-Verfügbarkeit.</p>
<hr>
<h2 id="cluster-%26-qso-der-anderen" tabindex="-1"><a class="header-anchor" href="#cluster-%26-qso-der-anderen">Cluster &amp; QSO der anderen</a></h2>
<p>Separates Fenster (kann miniaturisiert werden). Zeigt den Kommunikationsfluss zwischen anderen Stationen interessant in ruhigeren Phasen.</p>
<hr>
<h2 id="men%C3%BC" tabindex="-1"><a class="header-anchor" href="#men%C3%BC">Menü</a></h2>
<h3 id="window" tabindex="-1"><a class="header-anchor" href="#window">Window</a></h3>
<ul>
<li><strong>Use Dark Mode</strong> (ab v1.26): Dunkles Farbschema aktivieren/deaktivieren.</li>
</ul>
<hr>
<h2 id="fenstergr%C3%B6%C3%9Fen-und-divider" tabindex="-1"><a class="header-anchor" href="#fenstergr%C3%B6%C3%9Fen-und-divider">Fenstergrößen und Divider</a></h2>
<p>Ab <strong>v1.21</strong> werden beim Klick auf <strong>„Save Settings&quot;</strong> auch Fenstergrößen und Divider-Positionen aller Panels in der Konfigurationsdatei gespeichert und beim nächsten Start wiederhergestellt.</p>
<p>Bei Problemen mit der Darstellung: Konfigurationsdatei löschen → KST4Contest erstellt neue Standardwerte.</p>
<hr>
<h2 id="tipps-zur-bedienung" tabindex="-1"><a class="header-anchor" href="#tipps-zur-bedienung">Tipps zur Bedienung</a></h2>
<ul>
<li><strong>Einstellungsfenster geöffnet lassen</strong>: Schneller Zugriff auf Beacon-Aktivierung/Deaktivierung.</li>
<li><strong>Rechtsklick in der Benutzerliste</strong>: Öffnet das Snippet-Menü und weitere Aktionen (QRZ.com-Profil, NOT-QRV-Tags setzen).</li>
<li><strong>Enter aus dem Chat heraus</strong>: Wenn im Sendfeld Text steht, sendet Enter direkt auch wenn der Fokus woanders liegt.</li>
<li><strong>Beacon stoppen</strong>: Beim Scannen von Frequenzen den Beacon ausschalten, damit der Chat nicht mit Meldungen überflutet wird.</li>
</ul>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
@@ -0,0 +1,346 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ manual.title }} | KST4Contest Manual</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest manual page: {{ manual.title }}">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/manual/de/changelog/">
<meta property="og:type" content="website">
<meta property="og:title" content="{{ manual.title }} | KST4Contest Manual">
<meta property="og:description" content="KST4Contest manual page: {{ manual.title }}">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/manual/de/changelog/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="section">
<div class="card manual-content">
<p><a href="/manual/de/">← Back to manual overview</a></p>
<h1>Changelog</h1>
<h1 id="changelog" tabindex="-1"><a class="header-anchor" href="#changelog">Changelog</a></h1>
<blockquote>
<p>🇬🇧 <a href="/manual/en/changelog/">English version</a> | 🇩🇪 Du liest gerade die deutsche Version</p>
</blockquote>
<p>Versionsverlauf von KST4Contest / PraktiKST.</p>
<hr>
<p>letzter Changelog bitte aus GitHub entnehmen. Der bisherige Changelog</p>
<h2 id="v1.41" tabindex="-1"><a class="header-anchor" href="#v1.41">v1.41</a></h2>
<p><strong>Stationskarte, Performance, Reaktionsfähiges UI</strong></p>
<p><strong>Neu:</strong></p>
<ul>
<li><strong>Stationskarte</strong>: Interaktive OpenStreetMap-Karte zeigt die geografische Position aller aktiven Chatmember. Enthält Stationsmarker, Antennen-Kegel, Verbindungslinie zur ausgewählten Station, Maidenhead-Raster-Overlay und ein Wegprofil-Diagramm mit Geländehöhen-Analyse (Fresnel-Zonen, Horizonterkennung). Geländedaten aus Copernicus GLO-30, Open-Meteo API oder Offline-DEM-Import. Aircraft-Scatter-Weganalyse integriert. Funktioniert in AppImage und Flatpak ohne externe CDN-Verbindung (lokaler Tile-Proxy, eingebettetes Leaflet.js).</li>
</ul>
<p><strong>Geändert:</strong></p>
<ul>
<li><strong>Nachrichten-Tabellen-Limit auf 30.000 erhöht</strong>: Chat- und Nachrichtentabellen sind auf 30.000 Einträge begrenzt. Ältere Nachrichten werden automatisch verworfen, was die Performance bei mehrtägigem Contest-Betrieb stabil hält.</li>
<li><strong>Bildschirmgerechte Fenstergröße</strong>: Beim Start wird das Hauptfenster auf den aktuellen Bildschirm angepasst. Wenn KST4Contest zuletzt auf einem größeren Monitor betrieben wurde, wird das Fenster automatisch verkleinert. Das UI-Layout ist kompakter und reaktionsfähiger auf kleineren Bildschirmen.</li>
</ul>
<hr>
<h2 id="v1.40-(2026-02-16)" tabindex="-1"><a class="header-anchor" href="#v1.40-(2026-02-16)">v1.40 (2026-02-16)</a></h2>
<p><strong>Großes Feature-Release: Score-System, AP-Timeline, Win-Test, PSTRotator</strong></p>
<p><strong>Neu:</strong></p>
<ul>
<li><strong>Chatmember Score-System</strong>: Jeder Chatmember erhält automatisch eine Prioritätsbewertung anhand von Antennenrichtung, Aktivitätszeit, Nachrichtenanzahl, aktiven Bändern, Frequenzen, Sked-Richtung und anderen Faktoren. Die Top-Kandidaten werden in einer eigenen Liste hervorgehoben.</li>
<li><strong>AP-Timeline</strong>: Für jeden möglichen AP-Ankunftsminuten-Slot werden bis zu 4 hochbewertete Stationen angezeigt, die erreichbar wären. Bevorzugt werden APs mit dem höchsten Potenzial, nicht die schnellste Ankunft. Stationen, auf die die eigene Antenne nicht zeigt, werden transparent dargestellt.</li>
<li><strong>Win-Test-Unterstützung</strong> (ab v1.31 als Beta, jetzt vollständig konfigurierbar): Log-Synchronisation, Frequenzauswertung und <strong>Sked-Übergabe via UDP</strong> vollständig integriert. In den Preferences aktivier-/deaktivierbar.</li>
<li><strong>PSTRotator-Interface</strong> (ab v1.31 als Beta, jetzt vollständig konfigurierbar): Aktualisierung der Rotatorposition direkt aus KST4Contest. In den Preferences aktivier-/deaktivierbar.</li>
<li><strong>QSO-Sniffer</strong>: Nachrichten von konfigurierbaren Rufzeichen-Listen werden automatisch in das PM-Fenster weitergeleitet.</li>
<li><strong>Band-Alert bei gearbeiteten Stationen</strong>: Wenn eine Station geloggt wird, erscheint ein Hinweis, wenn diese Station ein weiteres Band aktiv hat, auf dem man selbst ebenfalls QRV ist.</li>
<li><strong>Sked-Erinnerungs-ALERT</strong>: Pro Chatmember kann ein Sked-Alarm mit automatischen Nachrichten in konfigurierbaren Intervallen (2+1 / 5+2+1 / 10+5+2+1 Minuten vor dem Sked) eingerichtet werden, plus akustische und optische Benachrichtigung.</li>
<li><strong>Chat-Historie beim Start laden</strong>: Beim Verbindungsaufbau wird die Serverhistorie geladen, um aktive Chatmember und letzte Nachrichten sofort sichtbar zu machen.</li>
<li><strong>Skedfail-Button</strong>: Im FurtherInfo-Panel kann ein Sked-Misserfolg für einen Chatmember markiert werden, was dessen Score senkt.</li>
</ul>
<p><strong>Geändert:</strong></p>
<ul>
<li>AP-Notizen in DX-Cluster-Spots integriert.</li>
<li>Scrolling der Chatmember-Tabelle folgt automatisch der aktuellen Nachrichtenauswahl.</li>
<li>Generic Auto-Antwort und QRG-Auto-Antwort senden max. einmal pro 45 Sekunden pro Rufzeichen (verhindert Spam-Schleifen).</li>
<li>Speicherbare Einstellungen erweitert: ServerDNS/Port, PSTRotator-Interface, Win-Test-Interface, Callsign-Sniffer, Dark-Mode-Standard.</li>
<li>Datum in der Chat-Tabelle entfernt (nur Uhrzeit verbleibt spart Platz).</li>
</ul>
<p><strong>Behoben:</strong></p>
<ul>
<li>Benutzerliste wird jetzt bei jedem Neu-Login automatisch sortiert.</li>
<li>Posonpill-Nachrichten beenden jetzt nur genau eine Client-Instanz (nicht alle und nicht wtKST).</li>
<li>wtKST: Absturz bei KST4Contest-Trennung behoben.</li>
<li>Mehrere Probleme mit Rufzeichen-Suffixen wie <code>/p</code>, <code>-2</code> etc. behoben.</li>
<li><code>QTFDefault</code> wurde nicht korrekt gespeichert → behoben.</li>
<li>AirScout-Watchlist (ASWATCHLIST) wurde nicht korrekt aktualisiert → behoben.</li>
<li>Dark Mode: QRG-Felder wurden nicht vollständig angezeigt → behoben.</li>
<li>Versionsnummer-Anzeige korrigiert.</li>
</ul>
<hr>
<h2 id="v1.31-(2025-12-13)" tabindex="-1"><a class="header-anchor" href="#v1.31-(2025-12-13)">v1.31 (2025-12-13)</a></h2>
<p><strong>Win-Test + PSTRotator Beta, QSO-Sniffer, DNS-Hotfix</strong></p>
<p><strong>Neu:</strong></p>
<ul>
<li><strong>Win-Test-Unterstützung</strong> (Beta, noch nicht deaktivierbar): Log-Synchronisation und Frequenzauswertung.</li>
<li><strong>PSTRotator-Unterstützung</strong> (Beta, noch nicht deaktivierbar).</li>
<li><strong>QSO-Sniffer</strong>: Nachrichten von konfigurierbaren Rufzeichen werden ins PM-Fenster weitergeleitet.</li>
</ul>
<p><strong>Geändert:</strong></p>
<ul>
<li><strong>DNS-Server geändert</strong>: Von <code>www.on4kst.info</code> auf <code>www.on4kst.org</code> (Hotfix). Der DNS-Server ist ab sofort in den Preferences änderbar.</li>
</ul>
<p><strong>Behoben:</strong></p>
<ul>
<li>Endlosschleife im Fehlerfall friert den Client ein → behoben.</li>
</ul>
<hr>
<h2 id="v1.266-(2025-10-03)" tabindex="-1"><a class="header-anchor" href="#v1.266-(2025-10-03)">v1.266 (2025-10-03)</a></h2>
<p><strong>AirScout-Fix für Rufzeichen mit Suffix</strong></p>
<p><strong>Behoben:</strong></p>
<ul>
<li>AirScout-Interface funktionierte nicht, wenn das Login-Rufzeichen einen Suffix enthielt (z. B. <code>9A1W-2</code>). AirScout kann mit diesem Format nicht umgehen es wird jetzt nur noch das Basis-Rufzeichen ohne Suffix an AirScout übergeben.</li>
</ul>
<p><em>(Fehler gemeldet und getestet von 9A2HM / Kreso herzlichen Dank!)</em></p>
<hr>
<h2 id="v1.265-(2025-09-28)" tabindex="-1"><a class="header-anchor" href="#v1.265-(2025-09-28)">v1.265 (2025-09-28)</a></h2>
<p><strong>Richtungs-Buttons bleiben aktiviert eingefärbt</strong></p>
<p><strong>Behoben:</strong></p>
<ul>
<li>Richtungs-Buttons (N / NE / E usw.) behalten jetzt ihre Farbe, wenn sie aktiviert sind, sodass der Aktivierungsstatus auf einen Blick erkennbar ist.</li>
</ul>
<hr>
<h2 id="v1.264-(2025-08-02)" tabindex="-1"><a class="header-anchor" href="#v1.264-(2025-08-02)">v1.264 (2025-08-02)</a></h2>
<p><strong>Simplelogfile: Rufzeichen-Erkennung verbessert</strong></p>
<p><strong>Behoben:</strong></p>
<ul>
<li>Rufzeichen wie <code>S53CC</code>, <code>S51A</code> usw. wurden in der SimpleLogFile-Auswertung nicht als gearbeitet markiert → Erkennungsmuster verbessert.</li>
</ul>
<p><em>(Fehler gemeldet von Boris, S53CC danke!)</em></p>
<hr>
<h2 id="v1.263-(2025-06-08)" tabindex="-1"><a class="header-anchor" href="#v1.263-(2025-06-08)">v1.263 (2025-06-08)</a></h2>
<p><strong>AirScout-Kommunikation und Login-Name</strong></p>
<p><strong>Geändert:</strong></p>
<ul>
<li>AirScout-Kommunikation grundlegend überarbeitet: Nur noch Stationen mit QRB &lt; max-QRB werden an AirScout gesendet.</li>
<li>Abfrage-Intervall von 12 Sekunden auf <strong>60 Sekunden</strong> erhöht.</li>
<li>Deutlich weniger Berechnungsaufwand und Nachrichtenverkehr → Stabileres AirScout-Tracking.</li>
<li>Name des AS-Clients und AS-Servers ist jetzt aus den Preferences konfigurierbar (war vorher hartcodiert auf „KST&quot; / „AS&quot;).</li>
</ul>
<p><strong>Behoben:</strong></p>
<ul>
<li>„Track in AirScout&quot;-Button war sehr träge → durch neue Kommunikationslogik deutlich verbessert.</li>
<li>Name im Chat ist jetzt speicherbar (Fehler behoben).</li>
<li>Visuelle Korrekturen vor und nach dem Login.</li>
<li>Fehler behoben, der von 9A2HM (Kreso) gemeldet wurde.</li>
</ul>
<hr>
<h2 id="v1.262-(2025-05-21)" tabindex="-1"><a class="header-anchor" href="#v1.262-(2025-05-21)">v1.262 (2025-05-21)</a></h2>
<p><strong>Freeze-Fix bei vorzeitiger Nachrichtenlieferung</strong></p>
<p><strong>Behoben:</strong></p>
<ul>
<li>ON4KST liefert manchmal Nachrichten, bevor der Login abgeschlossen ist. Das verursachte Fehler in der Nachrichtenverarbeitung → jetzt behoben.</li>
</ul>
<hr>
<h2 id="v1.26-(2025-05)" tabindex="-1"><a class="header-anchor" href="#v1.26-(2025-05)">v1.26 (2025-05)</a></h2>
<p><strong>Multi-Channel-Login und Dark Mode</strong></p>
<p><strong>Neu:</strong></p>
<ul>
<li><strong>Dark Mode</strong>: Umschaltbar über <code>Window → Use Dark Mode</code>.</li>
<li><strong>Multi-Channel-Login</strong>: Gleichzeitiger Login in zwei Chat-Kategorien.</li>
<li><strong>Opposite Station Multi-Callsign Login-Tagging</strong>: Unterstützung für Stationen mit mehreren Rufzeichen.</li>
</ul>
<p><strong>Geändert:</strong></p>
<ul>
<li>Farbgebungs-Mechanismus überarbeitet: Farben können jetzt über CSS angepasst werden.</li>
</ul>
<p><strong>Behoben:</strong></p>
<ul>
<li>Stationsmarkierung komplett überarbeitet und korrekt gestellt.</li>
</ul>
<hr>
<h2 id="v1.251-(2025-02)" tabindex="-1"><a class="header-anchor" href="#v1.251-(2025-02)">v1.251 (2025-02)</a></h2>
<p><strong>Bugfix für UDP-Broadcast-Spot-Info</strong></p>
<p><strong>Behoben:</strong></p>
<ul>
<li>Problem beim Lesen von UDP-Broadcast-Spot-Informationen behoben (gemeldet von Steve Clements danke!).</li>
<li>Stationsmarkierung (erneut verbessert).</li>
</ul>
<hr>
<h2 id="v1.25-(2025-02)" tabindex="-1"><a class="header-anchor" href="#v1.25-(2025-02)">v1.25 (2025-02)</a></h2>
<p><strong>Wunschliste umgesetzt</strong></p>
<p><strong>Neu:</strong></p>
<ul>
<li><strong>Neuer Einstellungs-Tab: Messagehandling</strong>
<ul>
<li>Auto-Antwort auf eingehende Nachrichten konfigurierbar.</li>
<li>Automatische Antwort mit eigener CQ-QRG, wenn jemand danach fragt.</li>
<li>Konfigurierbarer Standard-Filter für das Userinfo-Fenster <em>(für Gianluca :-) )</em>.</li>
</ul>
</li>
<li><strong>Farbige PM-Zeilen</strong>: Neue Privatnachrichten erscheinen rot und faden alle 30 Sekunden über Gelb bis Weiß ab <em>(Idee von IU3OAR, Gianluca)</em>.</li>
</ul>
<p><strong>Behoben:</strong></p>
<ul>
<li>Stationen mit Suffixen wie „-2&quot; und „-70&quot; wurden nicht als gearbeitet markiert → werden jetzt ignoriert, Station wird korrekt markiert.</li>
</ul>
<hr>
<h2 id="v1.24-(2024-11)" tabindex="-1"><a class="header-anchor" href="#v1.24-(2024-11)">v1.24 (2024-11)</a></h2>
<p><strong>Wunschliste + DX-Cluster-Spots</strong></p>
<p><strong>Neu:</strong></p>
<ul>
<li>Button zum Öffnen des <strong>QRZ.com-Profils</strong> der ausgewählten Station.</li>
<li>Button zum Öffnen des <strong>QRZ-CQ-Profils</strong> der ausgewählten Station.</li>
<li><strong>DX-Cluster-Server-Integration</strong>: Richtungs-Warnungen werden als Spots an das Logprogramm gesendet (wenn QRG bekannt).</li>
</ul>
<p><em>(Zusätzlich wurden Farbgebungen der PM-Zeilen hinzugefügt tnx Gianluca)</em></p>
<hr>
<h2 id="v1.23-(2024-10)" tabindex="-1"><a class="header-anchor" href="#v1.23-(2024-10)">v1.23 (2024-10)</a></h2>
<p><strong>Integrierter DX-Cluster-Server</strong></p>
<p><strong>Neu:</strong></p>
<ul>
<li>KST4Contest enthält jetzt einen <strong>integrierten DX-Cluster-Server</strong>.</li>
<li>Generiert DX-Cluster-Spots und sendet sie an das Logprogramm, wenn eine Richtungs-Warnung ausgelöst und eine QRG bekannt ist.</li>
<li>Spotter-Rufzeichen muss sich vom Contest-Rufzeichen unterscheiden (für korrekte Filterung im Logprogramm).</li>
</ul>
<p><em>(Idee von OM0AAO, Viliam Petrik danke!)</em></p>
<hr>
<h2 id="v1.22-(2024-05)" tabindex="-1"><a class="header-anchor" href="#v1.22-(2024-05)">v1.22 (2024-05)</a></h2>
<p><strong>Usability-Verbesserungen und AirScout-Button-Fix</strong></p>
<p><strong>Neu:</strong></p>
<ul>
<li>Neue Variablen (tnx OM0AAO, Viliam Petrik):
<ul>
<li><code>MYLOCATORSHORT</code></li>
<li><code>MYQRGSHORT</code></li>
<li><code>QRZNAME</code></li>
</ul>
</li>
</ul>
<p><strong>Geändert:</strong></p>
<ul>
<li>Sendfeld-Fokus: Nach Klick auf Rufzeichen in der Benutzerliste erhält das Sendfeld sofort den Fokus kein Doppelklick notwendig <em>(tnx Gianluca)</em>.</li>
</ul>
<p><strong>Behoben:</strong></p>
<ul>
<li>Worked-Station-Filter ist jetzt live-aktiv: Gearbeitete Stationen verschwinden sofort nach Aktivierung des Filters <em>(tnx Gianluca)</em>.</li>
<li>QRB-Sortierung war lexikografisch → jetzt numerisch <em>(tnx Alessandro Murador)</em>.</li>
<li>AirScout-„Show Path&quot;-Button: Klick maximiert AirScout und zeigt den Pfad korrekt an.</li>
</ul>
<hr>
<h2 id="v1.21-(2024-04)" tabindex="-1"><a class="header-anchor" href="#v1.21-(2024-04)">v1.21 (2024-04)</a></h2>
<p><strong>Usability-Verbesserungen</strong></p>
<p><strong>Geändert:</strong></p>
<ul>
<li>Fenstergrößen und Divider-Positionen werden beim Klick auf „Save Settings&quot; in der Konfigurationsdatei gespeichert und beim Start wiederhergestellt.</li>
<li>Filter-Bereich als Flowpane → bessere Darstellung auf kleineren Bildschirmen.</li>
</ul>
<hr>
<h2 id="v1.2-(2024-04)" tabindex="-1"><a class="header-anchor" href="#v1.2-(2024-04)">v1.2 (2024-04)</a></h2>
<p><strong>Bandselektion und NOT-QRV-Tags</strong></p>
<p><strong>Neu:</strong></p>
<ul>
<li><strong>Bandselektion</strong>: In den Preferences auswählbar, welche Bänder aktiv sind. Nur für gewählte Bänder erscheinen Buttons und Felder in der UI. Speichern und Neustart erforderlich.</li>
<li><strong>NOT-QRV-Tags pro Station und Band</strong>: Stationen können für jedes Band als „nicht QRV&quot; markiert werden. Kombinierbar mit dem Userlist-Filter.</li>
<li><strong>QTF-Pfeil</strong>: Der „Show path in AS&quot;-Button zeigt jetzt einen Pfeil mit dem QTF der ausgewählten Station an.</li>
</ul>
<hr>
<h2 id="fr%C3%BChere-versionen" tabindex="-1"><a class="header-anchor" href="#fr%C3%BChere-versionen">Frühere Versionen</a></h2>
<h3 id="v1.1" tabindex="-1"><a class="header-anchor" href="#v1.1">v1.1</a></h3>
<p>Erste öffentlich veröffentlichte Version. Grundfunktionen:</p>
<ul>
<li>Worked-Markierung via Simplelogfile und UDP</li>
<li>Sked-Richtungs-Hervorhebung</li>
<li>QRG-Erkennung</li>
<li>Text-Snippets und Shortcuts</li>
<li>AirScout-Interface (erste Version)</li>
<li>Intervall-Beacon</li>
<li>PM-Abfang für öffentliche Nachrichten mit eigenem Rufzeichen</li>
<li>Update-Hinweis-Dienst</li>
</ul>
<hr>
<h2 id="geplante-features" tabindex="-1"><a class="header-anchor" href="#geplante-features">Geplante Features</a></h2>
<ul>
<li><code>MYQTF</code>-Variable (eigene Antennenrichtung als Text)</li>
<li><s>Lebensdauer für den Worked-Status (automatisches Zurücksetzen)</s><strong>Umgesetzt in v1.40</strong> (3-Tage-Lebensdauer, kein manuelles Zurücksetzen mehr nötig)</li>
<li>Filterung des „Cluster &amp; QSO der anderen&quot;-Fensters auf eigenes QTF</li>
<li>Weitere Topografie-basierte Berechnungen für die Richtungswarnung</li>
</ul>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
@@ -0,0 +1,173 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ manual.title }} | KST4Contest Manual</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest manual page: {{ manual.title }}">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/manual/de/dx-cluster-server/">
<meta property="og:type" content="website">
<meta property="og:title" content="{{ manual.title }} | KST4Contest Manual">
<meta property="og:description" content="KST4Contest manual page: {{ manual.title }}">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/manual/de/dx-cluster-server/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="section">
<div class="card manual-content">
<p><a href="/manual/de/">← Back to manual overview</a></p>
<h1>Integrierter DX-Cluster-Server</h1>
<h1 id="integrierter-dx-cluster-server" tabindex="-1"><a class="header-anchor" href="#integrierter-dx-cluster-server">Integrierter DX-Cluster-Server</a></h1>
<blockquote>
<p>🇬🇧 <a href="/manual/en/dx-cluster-server/">English version</a> | 🇩🇪 Du liest gerade die deutsche Version</p>
</blockquote>
<p>Ab <strong>Version 1.23</strong> enthält KST4Contest einen integrierten DX-Cluster-Server. Dieser sendet Spots direkt an das Logprogramm, wenn eine Richtungs-Warnung ausgelöst wird.</p>
<p><em>(Idee von OM0AAO, Viliam Petrik danke!)</em></p>
<hr>
<h2 id="wozu-dient-der-integrierte-dx-cluster-server%3F" tabindex="-1"><a class="header-anchor" href="#wozu-dient-der-integrierte-dx-cluster-server%3F">Wozu dient der integrierte DX-Cluster-Server?</a></h2>
<p>Wenn KST4Contest erkennt, dass eine Station aus der eigenen Richtung ein Sked anfragt und gleichzeitig eine QRG bekannt ist, wird <strong>automatisch ein DX-Cluster-Spot generiert</strong> und an den Cluster-Client des Logprogramms gesendet.</p>
<p>Das Logprogramm zeigt den Spot in der Bandkarte an. Ein Klick auf den Spot stellt Frequenz und Mode des Transceivers direkt ein ohne manuelles Eintippen.</p>
<hr>
<h2 id="einrichtung" tabindex="-1"><a class="header-anchor" href="#einrichtung">Einrichtung</a></h2>
<h3 id="in-kst4contest" tabindex="-1"><a class="header-anchor" href="#in-kst4contest">In KST4Contest</a></h3>
<p>In den Preferences → <strong>DX-Cluster-Server-Einstellungen</strong>:</p>
<ol>
<li><strong>Port</strong> des internen Servers eintragen (z. B. 7300 oder 8000 muss mit dem Logprogramm übereinstimmen).</li>
<li><strong>Spotter-Rufzeichen</strong> eintragen <strong>unbedingt ein anderes Rufzeichen als das Contest-Rufzeichen verwenden!</strong>
<ul>
<li>Grund: Logprogramme filtern Spots, die vom eigenen Rufzeichen stammen, als „gearbeitet&quot; heraus. Wenn der Spotter dasselbe Rufzeichen hat, werden die Spots nicht angezeigt.</li>
</ul>
</li>
<li><strong>Angenommene MHz</strong> eintragen: Bei Frequenzangaben wie „.205&quot; im Chat muss KST4Contest entscheiden, ob 144.205, 432.205 oder 1296.205 gemeint ist. Bei Einband-Contests einfach die entsprechende Bandmitte eintragen. Vollständige Frequenzangaben wie „144.205&quot; oder „1296.338&quot; im Chat werden immer korrekt erkannt.</li>
</ol>
<h3 id="in-ucxlog" tabindex="-1"><a class="header-anchor" href="#in-ucxlog">In UCXLog</a></h3>
<ul>
<li>Verbindung zu einem DX-Cluster-Server konfigurieren:
<ul>
<li>Host: <code>127.0.0.1</code> (oder IP des KST4Contest-Computers)</li>
<li>Port: Wie in KST4Contest konfiguriert</li>
<li>Passwort: kann leer bleiben</li>
</ul>
</li>
<li>Über die Schaltfläche <strong>„Send a test message to your log&quot;</strong> kann die Verbindung getestet werden.</li>
</ul>
<h3 id="in-n1mm%2B" tabindex="-1"><a class="header-anchor" href="#in-n1mm%2B">In N1MM+</a></h3>
<p>Ähnliche Einstellungen:</p>
<ul>
<li>Host: <code>127.0.0.1</code> (oder IP des KST4Contest-Computers)</li>
<li>Port: Wie in KST4Contest konfiguriert</li>
</ul>
<hr>
<h2 id="funktionsweise" tabindex="-1"><a class="header-anchor" href="#funktionsweise">Funktionsweise</a></h2>
<p>Ein Spot wird generiert, wenn <strong>beide</strong> Bedingungen erfüllt sind:</p>
<ol>
<li>Eine <strong>Richtungs-Warnung</strong> wurde ausgelöst (Station macht ein Sked in die eigene Richtung).</li>
<li><strong>QRG der Station ist bekannt</strong> (aus dem Chat ausgelesen oder manuell eingetragen).</li>
</ol>
<p>Der generierte Spot enthält:</p>
<ul>
<li>Rufzeichen der Station</li>
<li>Frequenz</li>
<li>Spotterzeit</li>
</ul>
<p>Das Logprogramm kann den Spot dann in der Bandkarte anzeigen und den TRX per Mausklick auf die Frequenz abstimmen.</p>
<hr>
<h2 id="multi-computer-setup" tabindex="-1"><a class="header-anchor" href="#multi-computer-setup">Multi-Computer-Setup</a></h2>
<p>Wenn KST4Contest auf einem separaten Computer läuft (nicht auf dem Log-Computer):</p>
<ul>
<li>Host im Logprogramm: IP des KST4Contest-Computers (nicht <code>127.0.0.1</code>)</li>
<li>Entspricht der Konfiguration der QSO-UDP-Broadcast-Pakete (siehe <a href="/manual/de/log-synchronisation/">Log-Synchronisation</a>)</li>
</ul>
<hr>
<h2 id="getestete-logprogramme" tabindex="-1"><a class="header-anchor" href="#getestete-logprogramme">Getestete Logprogramme</a></h2>
<ul>
<li><strong>UCXLog</strong></li>
<li><strong>N1MM+</strong></li>
</ul>
<p>Weitere Testergebnisse sind willkommen bitte per E-Mail an DO5AMF melden.</p>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
@@ -0,0 +1,295 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ manual.title }} | KST4Contest Manual</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest manual page: {{ manual.title }}">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/manual/de/funktionen/">
<meta property="og:type" content="website">
<meta property="og:title" content="{{ manual.title }} | KST4Contest Manual">
<meta property="og:description" content="KST4Contest manual page: {{ manual.title }}">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/manual/de/funktionen/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="section">
<div class="card manual-content">
<p><a href="/manual/de/">← Back to manual overview</a></p>
<h1>Funktionen</h1>
<h1 id="funktionen" tabindex="-1"><a class="header-anchor" href="#funktionen">Funktionen</a></h1>
<blockquote>
<p>🇬🇧 <a href="/manual/en/features/">English version</a> | 🇩🇪 Du liest gerade die deutsche Version</p>
</blockquote>
<p>Übersicht aller Hauptfunktionen von KST4Contest.</p>
<hr>
<h2 id="sked-richtungs-hervorhebung" tabindex="-1"><a class="header-anchor" href="#sked-richtungs-hervorhebung">Sked-Richtungs-Hervorhebung</a></h2>
<p>Eine der Kernfunktionen: Wenn eine Station ein Sked in die <strong>eigene Richtung</strong> sendet, wird sie in der Benutzerliste <strong>grün und fett</strong> hervorgehoben.</p>
<h3 id="wie-funktioniert-das%3F" tabindex="-1"><a class="header-anchor" href="#wie-funktioniert-das%3F">Wie funktioniert das?</a></h3>
<p>Die Berechnung basiert auf folgender Logik:</p>
<ul>
<li>Wenn Station A eine Sked-Anfrage an Station B sendet, wird angenommen, dass A ihre Antenne auf B ausrichtet.</li>
<li>Wenn die daraus resultierende Richtung von A zur eigenen Station innerhalb des halben Öffnungswinkels der eigenen Antenne liegt, wird A hervorgehoben.</li>
</ul>
<p><strong>Beispiel</strong> (Öffnungswinkel 69°, Halbwinkel 34,5°):</p>
<table>
<thead>
<tr>
<th>Situation</th>
<th>Ergebnis für DO5AMF in JN49</th>
</tr>
</thead>
<tbody>
<tr>
<td>Sked von F5FEN → DM5M</td>
<td>✅ Hervorhebung (F5FEN zeigt Richtung DM5M, das liegt nahe JN49)</td>
</tr>
<tr>
<td>Sked von DM5M → F5FEN</td>
<td>✅ Hervorhebung (DM5M antwortet in Richtung F5FEN)</td>
</tr>
<tr>
<td>F1DBN ist unbeteiligt</td>
<td>❌ Keine Hervorhebung</td>
</tr>
<tr>
<td>DO5AMF/P (anderer Standort)</td>
<td>❌ Keine Hervorhebung für Sked-Antwort</td>
</tr>
</tbody>
</table>
<p>Die Berechnung berücksichtigt keine topografischen Wegberechnungen das ist eine bewusste Vereinfachung. Möglicherweise wird das in einer späteren Version ergänzt.</p>
<blockquote>
<p>Konfiguration: <a href="Konfiguration#antennen-%C3%B6ffnungswinkel-antenna-beamwidth">Konfiguration Antennen-Öffnungswinkel</a></p>
</blockquote>
<hr>
<h2 id="sked-richtungs-spots-(integrierter-dx-cluster)" tabindex="-1"><a class="header-anchor" href="#sked-richtungs-spots-(integrierter-dx-cluster)">Sked-Richtungs-Spots (Integrierter DX-Cluster)</a></h2>
<p>Ab <strong>v1.23</strong>: Richtungs-Warnungen werden als DX-Cluster-Spots an das Logprogramm weitergeleitet, wenn eine QRG bekannt ist. Details: <a href="/manual/de/dx-cluster-server/">DX-Cluster-Server</a>.</p>
<hr>
<h2 id="qrg-erkennung-(qrg-reading)" tabindex="-1"><a class="header-anchor" href="#qrg-erkennung-(qrg-reading)">QRG-Erkennung (QRG Reading)</a></h2>
<p>KST4Contest verarbeitet jede Chat-Nachricht und extrahiert automatisch <strong>Frequenzangaben</strong>. Diese werden in der Benutzerliste in der <strong>QRG-Spalte</strong> angezeigt.</p>
<p>Erkannte Formate: <code>144.205</code>, <code>432.088</code>, <code>.205</code> (mit konfigurierter Bandannahme), etc.</p>
<p><strong>Nutzen</strong>: Ohne nachzufragen kann man direkt auf die QRG einer Station schauen und entscheiden, ob eine Verbindung möglich ist.</p>
<hr>
<h2 id="worked-markierung" tabindex="-1"><a class="header-anchor" href="#worked-markierung">Worked-Markierung</a></h2>
<p>Gearbeitete Stationen werden in der Benutzerliste visuell markiert pro Band. Grundlage ist die <a href="/manual/de/log-synchronisation/">Log-Synchronisation</a> via UDP oder Simplelogfile.</p>
<p>Vor jedem Contest die Datenbank zurücksetzen: <a href="Konfiguration#worked-station-database-settings">Konfiguration Worked Station Database Settings</a>.</p>
<hr>
<h2 id="not-qrv-tags-(ab-v1.2)" tabindex="-1"><a class="header-anchor" href="#not-qrv-tags-(ab-v1.2)">NOT-QRV-Tags (ab v1.2)</a></h2>
<p>Wenn eine Station mitteilt, dass sie auf einem bestimmten Band nicht QRV ist, kann dies manuell markiert werden:</p>
<ol>
<li>Station in der Benutzerliste auswählen.</li>
<li>Rechtsklick → NOT-QRV für das entsprechende Band setzen.</li>
</ol>
<p>Diese Tags werden in der internen Datenbank gespeichert und bleiben nach einem Neustart von KST4Contest erhalten. Zurücksetzen über die Einstellungen möglich.</p>
<p><strong>Nutzen</strong>: Verhindert wiederholte Sked-Anfragen auf Bändern, auf denen die Station nicht QRV ist schont sowohl die eigenen Nerven als auch die der Gegenstation.</p>
<hr>
<h2 id="richtungsfilter-(direction-filter)" tabindex="-1"><a class="header-anchor" href="#richtungsfilter-(direction-filter)">Richtungsfilter (Direction Filter)</a></h2>
<p>Zeigt in der Benutzerliste nur Stationen an, die sich in einer bestimmten Richtung befinden. Aktivierbar über die Buttons N / NE / E / SE / S / SW / W / NW oder durch manuelle Eingabe von Grad.</p>
<p>Sinnvoll: Während man CQ in eine bestimmte Richtung ruft, nur Stationen in dieser Richtung anzeigen.</p>
<hr>
<h2 id="entfernungsfilter-(distance-filter)" tabindex="-1"><a class="header-anchor" href="#entfernungsfilter-(distance-filter)">Entfernungsfilter (Distance Filter)</a></h2>
<p>Stationen jenseits einer maximalen Entfernung ausblenden. Schaltfläche <strong>„Show only QRB [km] &lt;=&quot;</strong> ist ein Toggle-Button.</p>
<hr>
<h2 id="worked--und-not-qrv-filter" tabindex="-1"><a class="header-anchor" href="#worked--und-not-qrv-filter">Worked- und NOT-QRV-Filter</a></h2>
<p>Toggle-Buttons (einer pro Band) zum Ausblenden bereits gearbeiteter Stationen und/oder NOT-QRV-markierter Stationen. Der Filter wirkt <strong>sofort</strong> ohne manuelles Neu-Aktivieren (ab v1.22 live).</p>
<hr>
<h2 id="farbige-pm-zeilen-(ab-v1.25)" tabindex="-1"><a class="header-anchor" href="#farbige-pm-zeilen-(ab-v1.25)">Farbige PM-Zeilen (ab v1.25)</a></h2>
<p>Neue Privatnachrichten erscheinen in <strong>Rot</strong>. Die Farbe wechselt alle 30 Sekunden über Gelb bis Weiß wie ein Regenbogen-Fade. So ist auf einen Blick erkennbar, wie aktuell eine Nachricht ist.</p>
<p><em>(Idee von IU3OAR, Gianluca Costantino danke!)</em></p>
<hr>
<h2 id="pm-abfang-(catching-personal-messages)" tabindex="-1"><a class="header-anchor" href="#pm-abfang-(catching-personal-messages)">PM-Abfang (Catching Personal Messages)</a></h2>
<p>Manche Nutzer senden Direktnachrichten versehentlich öffentlich, z. B.:</p>
<pre><code>(DM5M) pse ur qrg
</code></pre>
<p>KST4Contest erkennt solche Nachrichten, die das eigene Rufzeichen enthalten, und sortiert sie automatisch in die <strong>Privatnachrichten-Tabelle</strong> ein. So gehen keine Nachrichten verloren.</p>
<hr>
<h2 id="multi-channel-login-(ab-v1.26)" tabindex="-1"><a class="header-anchor" href="#multi-channel-login-(ab-v1.26)">Multi-Channel-Login (ab v1.26)</a></h2>
<p>Gleichzeitiger Login in <strong>zwei Chat-Kategorien</strong> (z. B. 144 MHz und 432 MHz). Beide Chats werden parallel überwacht.</p>
<hr>
<h2 id="dark-mode-(ab-v1.26)" tabindex="-1"><a class="header-anchor" href="#dark-mode-(ab-v1.26)">Dark Mode (ab v1.26)</a></h2>
<p>Aktivierbar über: <strong>Window → Use Dark Mode</strong></p>
<p>Für individuelle Farbanpassungen: CSS-Datei bearbeiten (Pfad in den Programmunterlagen).</p>
<hr>
<h2 id="opposite-station-multi-callsign-login-tagging-(ab-v1.26)" tabindex="-1"><a class="header-anchor" href="#opposite-station-multi-callsign-login-tagging-(ab-v1.26)">Opposite Station Multi-Callsign Login-Tagging (ab v1.26)</a></h2>
<p>Unterstützung für Stationen, die mit mehreren Rufzeichen gleichzeitig im Chat aktiv sind (z. B. Expedition-Setups).</p>
<hr>
<h2 id="qrz.com-und-qrz-cq-profil-buttons-(ab-v1.24)" tabindex="-1"><a class="header-anchor" href="#qrz.com-und-qrz-cq-profil-buttons-(ab-v1.24)"><a href="http://QRZ.com">QRZ.com</a> und QRZ-CQ Profil-Buttons (ab v1.24)</a></h2>
<p>Für ausgewählte Stationen in der Benutzerliste gibt es direkte Buttons, um das <strong>QRZ.com-Profil</strong> und das <strong>QRZ-CQ-Profil</strong> im Browser zu öffnen.</p>
<hr>
<h2 id="sked-erinnerungen-mit-alert-(ab-v1.40)" tabindex="-1"><a class="header-anchor" href="#sked-erinnerungen-mit-alert-(ab-v1.40)">Sked-Erinnerungen mit ALERT (ab v1.40)</a></h2>
<p>Für jeden Chatmember kann ein Sked-Erinnerungsdienst mit automatischen Nachrichten aktiviert werden. Konfigurierbare Intervallmuster:</p>
<ul>
<li><strong>2+1 Minuten</strong>: Nachrichten bei 2 min und 1 min vor dem Sked.</li>
<li><strong>5+2+1 Minuten</strong>: Nachrichten bei 5, 2 und 1 min vor dem Sked.</li>
<li><strong>10+5+2+1 Minuten</strong>: Nachrichten bei 10, 5, 2 und 1 min vor dem Sked.</li>
</ul>
<p>Zusätzlich zu den Nachrichten an die Gegenstation gibt es eine <strong>akustische und optische Benachrichtigung</strong> für den eigenen Operator, sodass kein Sked vergessen wird.</p>
<p>Aktivierung: FurtherInfo-Panel der entsprechenden Station.</p>
<hr>
<h2 id="qso-sniffer-(ab-v1.31)" tabindex="-1"><a class="header-anchor" href="#qso-sniffer-(ab-v1.31)">QSO-Sniffer (ab v1.31)</a></h2>
<p>Der QSO-Sniffer überwacht den Chat auf Nachrichten von einer konfigurierbaren Rufzeichen-Liste und leitet diese automatisch in das <strong>PM-Fenster</strong> weiter. So gehen keine relevanten Nachrichten im allgemeinen Chat-Rauschen unter.</p>
<p>Konfiguration: <a href="de-Konfiguration#sniffer-einstellungen-ab-v131">Konfiguration Sniffer-Einstellungen</a></p>
<hr>
<h2 id="win-test-integration-(ab-v1.31%2C-vollst%C3%A4ndig-ab-v1.40)" tabindex="-1"><a class="header-anchor" href="#win-test-integration-(ab-v1.31%2C-vollst%C3%A4ndig-ab-v1.40)">Win-Test-Integration (ab v1.31, vollständig ab v1.40)</a></h2>
<p>KST4Contest unterstützt <a href="https://www.win-test.com/">Win-Test</a> vollständig als Logprogramm:</p>
<ul>
<li><strong>Log-Synchronisation</strong>: Gearbeitete Stationen werden automatisch aus Win-Test übernommen und in der Benutzerliste markiert.</li>
<li><strong>Frequenz-Auswertung</strong>: Die aktuelle TRX-Frequenz wird aus Win-Test-UDP-Paketen ausgewertet und befüllt die <code>MYQRG</code>-Variable.</li>
<li><strong>Sked-Übergabe (SKED Push via UDP)</strong>: Vereinbarte Skeds aus KST4Contest können direkt an Win-Test übertragen werden, sodass das Rufzeichen der Gegenstation im Win-Test-Sked-Fenster erscheint.</li>
</ul>
<p>Details zur Konfiguration: <a href="de-Konfiguration#win-test-netzwerk-listener">Konfiguration Win-Test-Netzwerk-Listener</a></p>
<hr>
<h2 id="pstrotator-interface-(ab-v1.31%2C-vollst%C3%A4ndig-ab-v1.40)" tabindex="-1"><a class="header-anchor" href="#pstrotator-interface-(ab-v1.31%2C-vollst%C3%A4ndig-ab-v1.40)">PSTRotator-Interface (ab v1.31, vollständig ab v1.40)</a></h2>
<p>KST4Contest kann die Antennenrichtung direkt über <strong>PSTRotator</strong> steuern. Wenn in der Benutzerliste eine Station ausgewählt wird, kann der Rotator automatisch auf den QTF zur ausgewählten Station gedreht werden.</p>
<p>Konfiguration: <a href="de-Konfiguration#pstrotator-einstellungen-ab-v131">Konfiguration PSTRotator-Einstellungen</a></p>
<hr>
<h2 id="band-alert-bei-neuen-qsos-(ab-v1.40)" tabindex="-1"><a class="header-anchor" href="#band-alert-bei-neuen-qsos-(ab-v1.40)">Band-Alert bei neuen QSOs (ab v1.40)</a></h2>
<p>Wenn eine Station geloggt wird, prüft KST4Contest automatisch, ob diese Station im Chat weitere aktive Bänder angezeigt hat, auf denen man selbst ebenfalls QRV ist. Falls ja, erscheint ein <strong>Hinweis-Alert</strong>, damit keine Multi-Band-Möglichkeit übersehen wird.</p>
<hr>
<h2 id="worked-tag-lebensdauer-(ab-v1.40)" tabindex="-1"><a class="header-anchor" href="#worked-tag-lebensdauer-(ab-v1.40)">Worked-Tag-Lebensdauer (ab v1.40)</a></h2>
<p>Gearbeitete Stationen werden nach <strong>3 Tagen</strong> automatisch aus der Datenbank entfernt. Ein manuelles Zurücksetzen der Worked-Datenbank vor jedem Contest ist damit nicht mehr zwingend notwendig die Datenbank hält sich selbst aktuell.</p>
<hr>
<h2 id="chatmember-score-system-%2F-priorit%C3%A4tsliste-(ab-v1.40)" tabindex="-1"><a class="header-anchor" href="#chatmember-score-system-%2F-priorit%C3%A4tsliste-(ab-v1.40)">Chatmember Score-System / Prioritätsliste (ab v1.40)</a></h2>
<p>KST4Contest berechnet automatisch eine <strong>Prioritätsbewertung</strong> für jeden aktiven Chatmember. Der Score setzt sich zusammen aus:</p>
<ul>
<li>Antennenrichtung der Gegenstation (zeigt sie auf mich?)</li>
<li>QRB (Entfernung)</li>
<li>Aktivitätszeit und Nachrichtenanzahl</li>
<li>Aktive Bänder und Frequenzen</li>
<li>AP-Verfügbarkeit (AirScout)</li>
<li>Sked-Richtung</li>
<li>Sked-Erfolgsrate und Skedfail-Markierungen</li>
</ul>
<p>Die Top-Kandidaten werden in einer eigenen Prioritätsliste hervorgehoben und helfen, im Contest-Stress die wichtigsten Stationen nicht zu übersehen.</p>
<p>Stationen, bei denen ein Sked gescheitert ist, können über den <strong>Skedfail-Button</strong> im FurtherInfo-Panel markiert werden das senkt ihren Score vorübergehend.</p>
<hr>
<h2 id="ap-timeline-(ab-v1.40)" tabindex="-1"><a class="header-anchor" href="#ap-timeline-(ab-v1.40)">AP-Timeline (ab v1.40)</a></h2>
<p>Eine visuelle Zeitleiste zeigt für jeden möglichen AP-Ankunftsminuten-Slot bis zu 4 hochbewertete Stationen, die per Aircraft Scatter erreichbar wären. Priorisierungskriterien:</p>
<ul>
<li>Bevorzugt werden APs mit dem <strong>höchsten Reflexionspotenzial</strong> (nicht unbedingt die schnellste Ankunft).</li>
<li>Stationen, auf die die eigene Antenne nicht zeigt, werden <strong>transparent</strong> dargestellt.</li>
</ul>
<p>So kann der Contest-Operator auf einem Blick sehen, welche Stationen wann und über welche Flugzeuge erreichbar sein werden.</p>
<hr>
<h2 id="intervall-beacon" tabindex="-1"><a class="header-anchor" href="#intervall-beacon">Intervall-Beacon</a></h2>
<p>Automatische CQ-Meldungen im öffentlichen Kanal in konfigurierbarem Intervall. Empfohlene Verwendung mit der Variable <code>MYQRG</code> für aktuelle Frequenzangabe. Details: <a href="Konfiguration#beacon-settings-automatischer-beacon">Konfiguration Beacon Settings</a>.</p>
<hr>
<h2 id="simplelogfile" tabindex="-1"><a class="header-anchor" href="#simplelogfile">Simplelogfile</a></h2>
<p>Dateibasierte Log-Auswertung per Regex. Details: <a href="Log-Synchronisation#methode-1-universal-file-based-callsign-interpreter-simplelogfile">Log-Synchronisation</a>.</p>
<hr>
<h2 id="cluster-%26-qso-der-anderen" tabindex="-1"><a class="header-anchor" href="#cluster-%26-qso-der-anderen">Cluster &amp; QSO der anderen</a></h2>
<p>Ein separates Fenster zeigt den QSO-Fluss zwischen anderen Stationen. Besonders interessant in ruhigeren Nacht-Stunden während des Contests, wenn weniger Verkehr herrscht.</p>
<p>Dieses Fenster kann miniaturisiert werden, wenn es nicht benötigt wird. Zukünftig geplant: Filterung auf Stationen im ausgewählten QTF.</p>
<hr>
<h2 id="stationskarte-(ab-v1.41)" tabindex="-1"><a class="header-anchor" href="#stationskarte-(ab-v1.41)">Stationskarte (ab v1.41)</a></h2>
<p>Eine interaktive OpenStreetMap-Karte zeigt die geografische Position aller aktiven Chatmember.</p>
<p><strong>Funktionen:</strong></p>
<ul>
<li>Stationsmarker mit Rufzeichen-Labels, farblich nach Aktivität und Sked-Status</li>
<li><strong>Antennen-Kegel</strong> für die eigene Station</li>
<li><strong>Verbindungslinie</strong> zur aktuell ausgewählten Station</li>
<li><strong>Maidenhead-Raster</strong> (QRA-Locator-Gitter als Overlay)</li>
<li><strong>Wegprofil-Diagramm</strong>: Geländehöhen-Querschnitt zwischen eigener und ausgewählter Station, inklusive Fresnel-Zonen-Analyse und Horizonterkennung</li>
<li>Mehrere Terrainquellen: <strong>Copernicus GLO-30</strong> (hochauflösendes DEM), <strong>Open-Meteo API</strong>, synthetischer Fallback und <strong>Offline-DEM-Import</strong> für den Betrieb ohne Internetverbindung</li>
<li>Aircraft-Scatter-Weganalyse verknüpft mit den Geländedaten</li>
</ul>
<p>Die Karte funktioniert in gepackten Umgebungen (AppImage, Flatpak) ohne Zugriff auf externe CDNs: Die Kartenkacheln werden über einen lokalen Tile-Proxy abgerufen, die Leaflet.js-Bibliothek ist in der Anwendung eingebettet.</p>
<hr>
<h2 id="optimierte-nachrichtenverarbeitung-%2F-30.000-nachrichten-limit-(ab-v1.41)" tabindex="-1"><a class="header-anchor" href="#optimierte-nachrichtenverarbeitung-%2F-30.000-nachrichten-limit-(ab-v1.41)">Optimierte Nachrichtenverarbeitung / 30.000-Nachrichten-Limit (ab v1.41)</a></h2>
<p>Die internen Chat- und Nachrichtentabellen sind auf <strong>30.000 Einträge</strong> begrenzt. Ältere Nachrichten werden automatisch verworfen, sobald das Limit erreicht wird. Damit bleiben Speicherverbrauch und Darstellungsperformance auch bei mehrtägigen Contest-Betrieb stabil.</p>
<hr>
<h2 id="bildschirmgerechte-fenstergr%C3%B6%C3%9Fe-(ab-v1.41)" tabindex="-1"><a class="header-anchor" href="#bildschirmgerechte-fenstergr%C3%B6%C3%9Fe-(ab-v1.41)">Bildschirmgerechte Fenstergröße (ab v1.41)</a></h2>
<p>Beim Programmstart berechnet KST4Contest eine bildschirmgerechte Startgröße für das Hauptfenster:</p>
<ul>
<li>Die gespeicherte Fenstergröße aus der letzten Session wird verwendet aber <strong>niemals größer als der aktuelle Bildschirm</strong>.</li>
<li>Wenn KST4Contest zuletzt auf einem größeren Monitor betrieben wurde, wird das Fenster automatisch auf die aktuelle Anzeige verkleinert.</li>
<li>Das UI-Layout ist <strong>kompakter und reaktionsfähiger auf kleineren Bildschirmen</strong>.</li>
</ul>
<p>Damit werden unbrauchbare, abgeschnittene Fenster beim Wechsel zwischen Geräten oder Monitoren verhindert.</p>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
+249
View File
@@ -0,0 +1,249 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ manual.title }} | KST4Contest Manual</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest manual page: {{ manual.title }}">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/manual/de/home/">
<meta property="og:type" content="website">
<meta property="og:title" content="{{ manual.title }} | KST4Contest Manual">
<meta property="og:description" content="KST4Contest manual page: {{ manual.title }}">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/manual/de/home/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="section">
<div class="card manual-content">
<p><a href="/manual/de/">← Back to manual overview</a></p>
<h1>KST4Contest Handbuch</h1>
<h1 id="kst4contest-%E2%80%93-handbuch" tabindex="-1"><a class="header-anchor" href="#kst4contest-%E2%80%93-handbuch">KST4Contest Handbuch</a></h1>
<blockquote>
<p><a href="/manual/en/home/">English version</a> | Du liest gerade die deutsche Version</p>
</blockquote>
<p>KST4Contest ist ein Desktop-Client für den <a href="https://www.on4kst.org/chat/login.php">ON4KST-Chat</a>, der für den Contest-Betrieb auf den VHF-, UHF- und SHF-Bändern entwickelt wurde. Er verbindet Chat, Stationsauswahl, Sked-Planung, Aircraft-Scatter-Daten und die Anbindung an weitere Programme in einer gemeinsamen Arbeitsoberfläche.</p>
<p>Entwickelt wird KST4Contest von <strong>DO5AMF (Marc Fröhlich)</strong>, Operator bei DM5M und (seit Mai 2025) <strong>DN9APW (Philipp Wagner)</strong>. Der Quellcode ist öffentlich auf <a href="https://github.com/praktimarc/kst4contest">GitHub</a> verfügbar.</p>
<hr>
<h2 id="wozu-braucht-man-einen-eigenen-on4kst-client%3F" tabindex="-1"><a class="header-anchor" href="#wozu-braucht-man-einen-eigenen-on4kst-client%3F">Wozu braucht man einen eigenen ON4KST-Client?</a></h2>
<p>Der ON4KST-Chat liefert während eines Contests eine große Menge an Informationen: aktive Stationen, Locator, Frequenzen, Sked-Anfragen und Hinweise auf aktuelle Aktivität. Das eigentliche Problem besteht nicht darin, diese Daten zu sehen. Man muss daraus rechtzeitig die nächste sinnvolle Verbindung ableiten.</p>
<p>KST4Contest wertet die verfügbaren Informationen aus, ordnet sie und stellt sie in einem contestgerechten Arbeitsablauf dar. Dabei werden unter anderem Antennenrichtung, Entfernung, bekannte Bänder und Frequenzen, bereits gearbeitete Stationen, Chat-Aktivität und Aircraft-Scatter-Zeiten berücksichtigt.</p>
<p>Das Programm entscheidet jedoch nicht, welches QSO tatsächlich möglich ist. Der Prioritätsscore, die AP-Timeline und die verschiedenen Hervorhebungen sind Entscheidungshilfen. Die endgültige Beurteilung bleibt beim Operator schon deshalb, weil auch ein recht überzeugender Computerbildschirm noch keine Funkverbindung herstellt.</p>
<hr>
<h2 id="was-kst4contest-im-contest-unterst%C3%BCtzt" tabindex="-1"><a class="header-anchor" href="#was-kst4contest-im-contest-unterst%C3%BCtzt">Was KST4Contest im Contest unterstützt</a></h2>
<ul>
<li>
<p><strong>Chat beobachten und einordnen:</strong> KST4Contest kann zwei ON4KST-Chat-Kategorien gleichzeitig darstellen. Nachrichten, Frequenzangaben und bekannte Bandaktivitäten werden den jeweiligen Stationen zugeordnet.</p>
</li>
<li>
<p><strong>Relevante Stationen herausfiltern:</strong> Richtungs-, Entfernungs-, Worked- und NOT-QRV-Filter reduzieren die Benutzerliste auf die Stationen, die für den aktuellen Betriebszustand tatsächlich interessant sind.</p>
</li>
<li>
<p><strong>Kandidaten priorisieren:</strong> Das Score-System bewertet aktive Chatmember anhand mehrerer bekannter Kriterien. Die derzeit relevantesten Kandidaten erscheinen zusätzlich in einer eigenen Prioritätsliste.</p>
</li>
<li>
<p><strong>Skeds vorbereiten und im Blick behalten:</strong> Sked-Erinnerungen, automatische Vorwarnungen und die AP-Timeline helfen dabei, vereinbarte Verbindungen nicht zwischen Chat, Log und laufendem CQ-Betrieb zu verlieren.</p>
</li>
<li>
<p><strong>Aircraft Scatter einbeziehen:</strong> Über die AirScout-Schnittstelle werden geeignete Flugzeuge und erwartete Reflexionszeiten in die Stationsbewertung und Zeitplanung übernommen.</p>
</li>
<li>
<p><strong>Log und Funkstation anbinden:</strong> KST4Contest synchronisiert gearbeitete Stationen und Frequenzinformationen mit unterstützten Logprogrammen. Zusätzlich stehen Schnittstellen zu Win-Test, PSTRotator und ein integrierter DX-Cluster-Server zur Verfügung.</p>
</li>
<li>
<p><strong>Stationen und Funkwege darstellen:</strong> Die Stationskarte zeigt aktive Chatmember, Locator-Felder, Antennenrichtungen und den Weg zur ausgewählten Station. Für ausgewählte Verbindungen kann außerdem ein Geländeprofil berechnet werden.</p>
</li>
</ul>
<p>Die Funktionen greifen ineinander. Eine erkannte Frequenz kann beispielsweise einem aktiven Band zugeordnet werden, der Worked-Status stammt aus dem Log, Aircraft-Scatter-Daten ergänzen die zeitliche Bewertung und der daraus berechnete Score beeinflusst die Prioritätsliste. Fehlende oder veraltete Eingangsdaten können deshalb auch das Ergebnis beeinflussen.</p>
<hr>
<h2 id="voraussetzungen" tabindex="-1"><a class="header-anchor" href="#voraussetzungen">Voraussetzungen</a></h2>
<p>Für die Anmeldung ist ein registrierter ON4KST-Account erforderlich. Registrierung und Login sind über die <a href="https://www.on4kst.org/chat/login.php">offizielle ON4KST-Anmeldeseite</a> erreichbar.</p>
<p>Die offizielle Sprache im ON4KST-Chat ist Englisch. Das gilt auch für Nachrichten an Stationen aus dem eigenen Land. Übliche Amateurfunk-Abkürzungen wie <code>pse</code>, <code>agn</code>, <code>qrg</code>, <code>dir</code>, <code>rrr</code>, <code>tnx</code> oder <code>73</code> sind dabei normal und meistens erheblich schneller als ausformulierte Prosa.</p>
<p>Download, unterstützte Betriebssysteme und Installationswege sind im Kapitel <a href="/manual/de/installation/">Installation</a> beschrieben.</p>
<hr>
<h2 id="versionsstand-dieses-handbuchs" tabindex="-1"><a class="header-anchor" href="#versionsstand-dieses-handbuchs">Versionsstand dieses Handbuchs</a></h2>
<p>Dieses Handbuch beschreibt die stabile Version <strong>v1.41.1</strong>.</p>
<p>Funktionen oder Änderungen, die nur im aktuellen Entwicklungsstand enthalten sind, werden ausdrücklich als <strong>Nightly / v1.42</strong> gekennzeichnet. Fehlt eine solche Kennzeichnung, bezieht sich die Beschreibung auf die stabile Version.</p>
<ul>
<li><a href="https://github.com/praktimarc/kst4contest/releases/latest">Aktuelle stabile Version herunterladen</a></li>
<li><a href="https://github.com/praktimarc/kst4contest/actions">Nightly-Builds und automatisierte Builds</a></li>
<li><a href="/manual/de/changelog/">Versionsgeschichte</a></li>
</ul>
<p>Für einen Contest ist grundsätzlich die stabile Version zu empfehlen. Nightly-Builds enthalten neuere Korrekturen und Funktionen, können sich aber zwischen zwei Builds verändern. Sie sind sinnvoll, wenn eine bestimmte Änderung getestet werden soll weniger sinnvoll ist der erste Versuch zehn Minuten vor Contestbeginn.</p>
<hr>
<h2 id="schnellnavigation" tabindex="-1"><a class="header-anchor" href="#schnellnavigation">Schnellnavigation</a></h2>
<table>
<thead>
<tr>
<th>Seite</th>
<th>Inhalt</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="/manual/de/installation/">Installation</a></td>
<td>ON4KST-Account, Download, Installation und Updates</td>
</tr>
<tr>
<td><a href="/manual/de/konfiguration/">Konfiguration</a></td>
<td>Login, Station, Bänder, Benutzeroberfläche und externe Schnittstellen</td>
</tr>
<tr>
<td><a href="/manual/de/log-synchronisation/">Log-Synchronisation</a></td>
<td>Simplelogfile, UCXLog, N1MM+, QARTest, <a href="http://DXLog.net">DXLog.net</a> und Win-Test</td>
</tr>
<tr>
<td><a href="/manual/de/airscout-integration/">AirScout-Integration</a></td>
<td>Verbindung zu AirScout und Auswertung von Aircraft-Scatter-Zeiten</td>
</tr>
<tr>
<td><a href="/manual/de/dx-cluster-server/">DX-Cluster-Server</a></td>
<td>Übergabe erkannter Möglichkeiten an das Logprogramm</td>
</tr>
<tr>
<td><a href="/manual/de/funktionen/">Funktionen</a></td>
<td>Arbeitsweise, Herleitung und Grenzen der einzelnen Funktionen</td>
</tr>
<tr>
<td><a href="/manual/de/makros-und-variablen/">Makros und Variablen</a></td>
<td>Wiederverwendbare Texte, Shortcuts und automatisch ersetzte Werte</td>
</tr>
<tr>
<td><a href="/manual/de/benutzeroberflaeche/">Benutzeroberfläche</a></td>
<td>Aufbau der Oberfläche und Bedienung im Contest</td>
</tr>
<tr>
<td><a href="/manual/de/changelog/">Changelog</a></td>
<td>Releases, Nightly-Änderungen und behobene Fehler</td>
</tr>
</tbody>
</table>
<hr>
<h2 id="kontakt-und-support" tabindex="-1"><a class="header-anchor" href="#kontakt-und-support">Kontakt und Support</a></h2>
<ul>
<li><strong>Download:</strong> <a href="https://github.com/praktimarc/kst4contest/releases/latest">Aktuelle stabile Version</a></li>
<li><strong>Quellcode:</strong> <a href="https://github.com/praktimarc/kst4contest">praktimarc/kst4contest</a></li>
<li><strong>Fehler und Funktionswünsche:</strong> <a href="https://github.com/praktimarc/kst4contest/issues">GitHub Issues</a></li>
<li><strong>E-Mail:</strong> <a href="mailto:praktimarc+kst4contest@gmail.com">praktimarc+kst4contest@gmail.com</a><br>
Bitte nur für Themen verwenden, die KST4Contest betreffen.</li>
</ul>
<h3 id="einen-fehler-melden" tabindex="-1"><a class="header-anchor" href="#einen-fehler-melden">Einen Fehler melden</a></h3>
<p>Ein Fehler lässt sich wesentlich schneller nachvollziehen, wenn die Meldung mindestens folgende Angaben enthält:</p>
<ol>
<li>verwendete KST4Contest-Version,</li>
<li>Betriebssystem und Installationsart,</li>
<li>genaue Schritte bis zum Fehler,</li>
<li>erwartetes und tatsächlich beobachtetes Verhalten,</li>
<li>gegebenenfalls einen Screenshot,</li>
<li>die Fehler-Logdatei.</li>
</ol>
<p>Die Fehler-Logdatei wird hier gespeichert:</p>
<table>
<thead>
<tr>
<th>Betriebssystem</th>
<th>Pfad</th>
</tr>
</thead>
<tbody>
<tr>
<td>Linux / macOS</td>
<td><code>~/.praktiKST/kst4contest-errors.log</code></td>
</tr>
<tr>
<td>Windows</td>
<td><code>C:\Users\&lt;Benutzername&gt;\.praktiKST\kst4contest-errors.log</code></td>
</tr>
</tbody>
</table>
<p>Vor dem Hochladen sollte die Datei kurz geprüft werden. Ein Fehlerprotokoll enthält überwiegend technische Informationen, kann abhängig vom Fehler aber beispielsweise lokale Dateipfade oder weitere Kontextdaten enthalten.</p>
<p>In Datei- und Verzeichnisnamen wird teilweise noch der technische Name <code>praktiKST</code> verwendet. Gemeint ist dasselbe Programm.</p>
<hr>
<h2 id="danksagungen" tabindex="-1"><a class="header-anchor" href="#danksagungen">Danksagungen</a></h2>
<p>KST4Contest wurde durch Rückmeldungen aus dem praktischen Contest-Betrieb wesentlich verbessert.</p>
<p>Besonderer Dank gilt Gianluca Costantino (IU3OAR), Alessandro Murador (IZ3VTH), Reczetár István (HA1FV), Viliam Petrik (OM0AAO, Idee zum DX-Cluster), Konrad Neitzel (DC9DJ, Projektstruktur), Andreas (DO5ALF, Webmaster von <a href="http://funkerportal.de">funkerportal.de</a>), Franz van Velzen (PE0WGA, Tester), DN9APW als neuem Entwickler im Team und Master über die CI/CD pipelines sowie allen weiteren Testern und Ideengebern.</p>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
+218
View File
@@ -0,0 +1,218 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>KST4Contest Deutsches Handbuch</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="Deutsches Benutzerhandbuch für KST4Contest.">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/manual/de/">
<meta property="og:type" content="website">
<meta property="og:title" content="KST4Contest Deutsches Handbuch">
<meta property="og:description" content="Deutsches Benutzerhandbuch für KST4Contest.">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/manual/de/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="KST4Contest Deutsches Handbuch">
<meta name="twitter:description" content="Deutsches Benutzerhandbuch für KST4Contest.">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="hero">
<h1>Deutsches Handbuch</h1>
<p>Das Handbuch wird zentral in GitHub gepflegt und als Wiki, PDF und Online-Dokumentation veröffentlicht.</p>
</section>
<section class="section">
<div class="grid">
<div class="card">
<h3><a href="/manual/de/home/">KST4Contest Handbuch</a></h3>
<p>KST4Contest ist ein Desktop-Client für den ON4KST-Chat, der für den Contest-Betrieb auf den VHF-, UHF- und SHF-Bändern entwickelt wurde. Er verbindet Chat, Stationsauswahl, Sked-Planung, Aircraft-Scatter-Daten und die Anbindung an weitere Programme in einer gemeinsamen Arbeitsoberfläche.</p>
</div>
<div class="card">
<h3><a href="/manual/de/installation/">Installation</a></h3>
<p>KST4Contest wird für Windows, Linux und macOS als fertiges Programmpaket bereitgestellt. Für die offiziellen Release-Pakete muss Java nicht separat installiert werden: Die benötigte Java-Laufzeitumgebung ist bereits enthalten.</p>
</div>
<div class="card">
<h3><a href="/manual/de/konfiguration/">Konfiguration</a></h3>
<p>Nach dem ersten Start öffnet sich das Einstellungsfenster dieses ist der zentrale Ausgangspunkt für alle Konfigurationen. Es empfiehlt sich, das Einstellungsfenster während des Betriebs geöffnet zu lassen (z. B. um den Beacon schnell ein- und auszuschalten).</p>
</div>
<div class="card">
<h3><a href="/manual/de/log-synchronisation/">Log-Synchronisation</a></h3>
<p>KST4Contest markiert gearbeitete Stationen automatisch in der Chat-Benutzerliste. Dafür gibt es zwei grundlegende Methoden:</p>
</div>
<div class="card">
<h3><a href="/manual/de/airscout-integration/">AirScout-Integration</a></h3>
<p>AirScout (von DL2ALF) ist ein Programm zur Erkennung von Flugzeugen für den Aircraft-Scatter-Betrieb. KST4Contest ist eng mit AirScout integriert und zeigt reflektierbare Flugzeuge direkt in der Benutzerliste an.</p>
</div>
<div class="card">
<h3><a href="/manual/de/dx-cluster-server/">Integrierter DX-Cluster-Server</a></h3>
<p>Ab Version 1.23 enthält KST4Contest einen integrierten DX-Cluster-Server. Dieser sendet Spots direkt an das Logprogramm, wenn eine Richtungs-Warnung ausgelöst wird.</p>
</div>
<div class="card">
<h3><a href="/manual/de/funktionen/">Funktionen</a></h3>
<p>Übersicht aller Hauptfunktionen von KST4Contest.</p>
</div>
<div class="card">
<h3><a href="/manual/de/makros-und-variablen/">Makros und Variablen</a></h3>
<p>KST4Contest bietet ein flexibles System aus Text-Snippets, Shortcuts und eingebauten Variablen, die den Chat-Workflow im Contest erheblich beschleunigen.</p>
</div>
<div class="card">
<h3><a href="/manual/de/benutzeroberflaeche/">Benutzeroberfläche</a></h3>
<p>Das Hauptfenster besteht aus mehreren Bereichen:</p>
</div>
<div class="card">
<h3><a href="/manual/de/changelog/">Changelog</a></h3>
<p>Versionsverlauf von KST4Contest / PraktiKST.</p>
</div>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
@@ -0,0 +1,503 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ manual.title }} | KST4Contest Manual</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest manual page: {{ manual.title }}">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/manual/de/installation/">
<meta property="og:type" content="website">
<meta property="og:title" content="{{ manual.title }} | KST4Contest Manual">
<meta property="og:description" content="KST4Contest manual page: {{ manual.title }}">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/manual/de/installation/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="section">
<div class="card manual-content">
<p><a href="/manual/de/">← Back to manual overview</a></p>
<h1>Installation</h1>
<h1 id="installation" tabindex="-1"><a class="header-anchor" href="#installation">Installation</a></h1>
<blockquote>
<p>🇬🇧 <a href="/manual/en/installation/">English version</a> | 🇩🇪 Du liest gerade die deutsche Version</p>
</blockquote>
<p>KST4Contest wird für Windows, Linux und macOS als fertiges Programmpaket bereitgestellt. Für die offiziellen Release-Pakete muss Java nicht separat installiert werden: Die benötigte Java-Laufzeitumgebung ist bereits enthalten.</p>
<p>Benötigt werden damit im Wesentlichen ein unterstütztes Betriebssystem, eine Internetverbindung und ein ON4KST-Account. Das klingt zunächst überschaubar und ist es normalerweise auch.</p>
<h2 id="voraussetzungen" tabindex="-1"><a class="header-anchor" href="#voraussetzungen">Voraussetzungen</a></h2>
<h3 id="on4kst-account" tabindex="-1"><a class="header-anchor" href="#on4kst-account">ON4KST-Account</a></h3>
<p>KST4Contest ist ein eigenständiger Client für den ON4KST-Chat, ersetzt aber nicht den dazugehörigen Benutzeraccount.</p>
<p>Falls noch kein Account vorhanden ist, kann er über die offizielle ON4KST-Seite angelegt werden:</p>
<ul>
<li><a href="https://www.on4kst.org/chat/login.php">ON4KST-Anmeldung und Registrierung</a></li>
</ul>
<p>ON4KST gibt Englisch als gemeinsame Sprache im Chat vor. Das gilt auch dann, wenn beide beteiligten Stationen dieselbe Muttersprache sprechen. Im Contestbetrieb werden häufig die üblichen Amateurfunk-Abkürzungen wie <code>pse</code>, <code>agn</code>, <code>qrg</code>, <code>dir</code>, <code>rrr</code>, <code>tnx</code> oder <code>73</code> verwendet.</p>
<p>Die eigentliche Bedienung des Chats und das Senden persönlicher Nachrichten werden im Kapitel zur Benutzeroberfläche beschrieben. Für die Installation ist zunächst nur wichtig, dass der Account funktioniert.</p>
<h3 id="bildschirmgr%C3%B6%C3%9Fe" tabindex="-1"><a class="header-anchor" href="#bildschirmgr%C3%B6%C3%9Fe">Bildschirmgröße</a></h3>
<p>Eine nutzbare Bildschirmfläche von ungefähr <strong>1200 × 720 Pixeln</strong> oder mehr wird empfohlen.</p>
<p>KST4Contest passt das Hauptfenster automatisch an die verfügbare Fläche des primären Bildschirms an. Das Programm kann deshalb auch auf kleineren Bildschirmen gestartet werden. Weniger Platz bleibt allerdings weniger Platz: In diesem Fall können nicht alle Tabellen, Filter und Zusatzinformationen gleichzeitig in sinnvoller Größe dargestellt werden.</p>
<h3 id="java" tabindex="-1"><a class="header-anchor" href="#java">Java</a></h3>
<p>Für die fertigen Pakete aus den <a href="https://github.com/praktimarc/kst4contest/releases/latest">GitHub Releases</a> ist keine separate Java-Installation erforderlich. Die benötigte Laufzeitumgebung wird zusammen mit KST4Contest ausgeliefert.</p>
<p>Eine Java-Entwicklungsumgebung wird nur benötigt, wenn KST4Contest selbst aus dem Quellcode gebaut werden soll. Bei den AUR-Paketen <code>kst4contest</code> und <code>kst4contest-git</code> werden Java 21 und Maven als Build-Abhängigkeiten durch den Paketmanager berücksichtigt.</p>
<hr>
<h2 id="stable%2C-beta-oder-nightly%3F" tabindex="-1"><a class="header-anchor" href="#stable%2C-beta-oder-nightly%3F">Stable, Beta oder Nightly?</a></h2>
<p>KST4Contest wird in drei Entwicklungsständen bereitgestellt:</p>
<table>
<thead>
<tr>
<th>Kanal</th>
<th>Geeignet für</th>
<th>Einordnung</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Stable</strong></td>
<td>Normaler Contestbetrieb</td>
<td>Veröffentlichte und für den regulären Einsatz vorgesehene Version</td>
</tr>
<tr>
<td><strong>Beta</strong></td>
<td>Gezielte Tests vor einem Stable-Release</td>
<td>Vorabversion mit weitgehend festgelegtem Funktionsumfang</td>
</tr>
<tr>
<td><strong>Nightly</strong></td>
<td>Frühe Tests neuer Funktionen</td>
<td>Aktueller Entwicklungsstand aus dem <code>main</code>-Branch</td>
</tr>
</tbody>
</table>
<p>Für den normalen Einsatz wird die <strong>Stable-Version</strong> empfohlen.</p>
<p>Beta- und Nightly-Versionen können Funktionen enthalten, die im Stable-Release noch nicht verfügbar sind. Sie können aber ebenso unfertige Bedienabläufe, geänderte Einstellungen oder neue Fehler enthalten. Das ist kein ungewöhnlicher Defekt im Veröffentlichungsverfahren, sondern der Zweck eines Entwicklungskanals.</p>
<p>Wenn in diesem Manual eine Funktion ausdrücklich mit <strong>Nightly</strong> gekennzeichnet ist, gehört sie noch nicht zwingend zum aktuellen Stable-Release.</p>
<hr>
<h2 id="download" tabindex="-1"><a class="header-anchor" href="#download">Download</a></h2>
<p>Die aktuelle Stable-Version ist hier verfügbar:</p>
<ul>
<li><a href="https://github.com/praktimarc/kst4contest/releases/latest">Aktuelles KST4Contest-Release</a></li>
<li><a href="https://github.com/praktimarc/kst4contest/releases">Alle veröffentlichten Versionen</a></li>
</ul>
<p>Die Release-Seite enthält die Programmpakete sowie die deutschen und englischen PDF-Handbücher.</p>
<h3 id="welches-paket-wird-ben%C3%B6tigt%3F" tabindex="-1"><a class="header-anchor" href="#welches-paket-wird-ben%C3%B6tigt%3F">Welches Paket wird benötigt?</a></h3>
<table>
<thead>
<tr>
<th>Betriebssystem</th>
<th>Paket</th>
<th>Typischer Dateiname</th>
</tr>
</thead>
<tbody>
<tr>
<td>Windows x64</td>
<td>ZIP-Paket</td>
<td><code>praktiKST-v&lt;Version&gt;-windows-x64.zip</code></td>
</tr>
<tr>
<td>Linux x86_64</td>
<td>AppImage</td>
<td><code>KST4Contest-v&lt;Version&gt;-linux-x86_64.AppImage</code></td>
</tr>
<tr>
<td>Debian/Ubuntu amd64</td>
<td>DEB-Paket</td>
<td><code>KST4Contest-v&lt;Version&gt;-debian-amd64.deb</code></td>
</tr>
<tr>
<td>Fedora/RPM x86_64</td>
<td>RPM-Paket</td>
<td><code>KST4Contest-v&lt;Version&gt;-fedora-x86_64.rpm</code></td>
</tr>
<tr>
<td>Arch Linux x86_64</td>
<td>Arch-Paket</td>
<td><code>KST4Contest-v&lt;Version&gt;-archlinux-x86_64.pkg.tar.zst</code></td>
</tr>
<tr>
<td>Linux mit Flatpak</td>
<td>Flatpak-Referenz</td>
<td><code>de.x08.KST4Contest.flatpakref</code></td>
</tr>
<tr>
<td>macOS Apple Silicon</td>
<td>DMG für ARM64</td>
<td><code>KST4Contest-v&lt;Version&gt;-macos-arm64.dmg</code></td>
</tr>
<tr>
<td>macOS Intel</td>
<td>DMG für x86_64</td>
<td><code>KST4Contest-v&lt;Version&gt;-macos-x86_64.dmg</code></td>
</tr>
</tbody>
</table>
<p>Lade Programmpakete nur aus den offiziellen GitHub Releases, dem KST4Contest-Flatpak-Repository oder den verlinkten AUR-Paketen herunter. Dateien aus anderen Quellen können anders gebaut, veraltet oder verändert worden sein.</p>
<hr>
<h2 id="installation-unter-windows" tabindex="-1"><a class="header-anchor" href="#installation-unter-windows">Installation unter Windows</a></h2>
<p>KST4Contest wird unter Windows als ZIP-Paket bereitgestellt. Ein klassischer Installer ist nicht erforderlich.</p>
<ol>
<li>Lade <code>praktiKST-v&lt;Version&gt;-windows-x64.zip</code> aus dem aktuellen Release herunter.</li>
<li>Entpacke die ZIP-Datei vollständig in einen eigenen Ordner.</li>
<li>Öffne den entpackten Ordner.</li>
<li>Starte <code>praktiKST.exe</code>.</li>
</ol>
<p>Starte das Programm nicht direkt aus der noch komprimierten ZIP-Datei. KST4Contest besteht aus mehreren Dateien und einer mitgelieferten Laufzeitumgebung. Windows kann diese Struktur nur zuverlässig verwenden, wenn das Archiv vorher vollständig entpackt wurde.</p>
<p>Die Programmeinstellungen befinden sich nicht im entpackten Programmordner, sondern im Benutzerverzeichnis:</p>
<pre><code class="language-text">%USERPROFILE%\.praktiKST\preferences.xml
</code></pre>
<p>Dadurch können neue Programmversionen in einen anderen Ordner entpackt werden, ohne dass die vorhandenen Einstellungen verloren gehen.</p>
<hr>
<h2 id="installation-unter-linux" tabindex="-1"><a class="header-anchor" href="#installation-unter-linux">Installation unter Linux</a></h2>
<p>Unter Linux stehen mehrere Paketformate zur Verfügung. Welches davon sinnvoll ist, hängt weniger von KST4Contest als von der verwendeten Distribution und der gewünschten Update-Methode ab.</p>
<table>
<thead>
<tr>
<th>Installationsart</th>
<th>Sinnvoll, wenn …</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Flatpak</strong></td>
<td>Updates zentral verwaltet werden sollen und Flatpak bereits verwendet wird</td>
</tr>
<tr>
<td><strong>AppImage</strong></td>
<td>KST4Contest ohne Installation als einzelne portable Datei gestartet werden soll</td>
</tr>
<tr>
<td><strong>DEB/RPM</strong></td>
<td>die Paketverwaltung der Distribution verwendet werden soll</td>
</tr>
<tr>
<td><strong>Arch-Paket/AUR</strong></td>
<td>Arch Linux, Manjaro oder EndeavourOS eingesetzt wird</td>
</tr>
</tbody>
</table>
<h3 id="flatpak" tabindex="-1"><a class="header-anchor" href="#flatpak">Flatpak</a></h3>
<p>Flatpak ist für die meisten Linux-Anwender der einfachste Weg, KST4Contest installiert und aktualisierbar zu halten. Das KST4Contest-Repository ist GPG-signiert und enthält die Kanäle Stable, Beta und Nightly.</p>
<h4 id="stable-%C3%BCber-die-release-datei-installieren" tabindex="-1"><a class="header-anchor" href="#stable-%C3%BCber-die-release-datei-installieren">Stable über die Release-Datei installieren</a></h4>
<p>Lade <code>de.x08.KST4Contest.flatpakref</code> aus dem aktuellen Release herunter und öffne die Datei mit der Softwareverwaltung der verwendeten Desktop-Umgebung.</p>
<p>Alternativ kann sie im Terminal installiert werden:</p>
<pre><code class="language-bash">flatpak install ./de.x08.KST4Contest.flatpakref
</code></pre>
<h4 id="kst4contest-repository-hinzuf%C3%BCgen" tabindex="-1"><a class="header-anchor" href="#kst4contest-repository-hinzuf%C3%BCgen">KST4Contest-Repository hinzufügen</a></h4>
<p>Das Repository muss nur einmal hinzugefügt werden:</p>
<pre><code class="language-bash">flatpak remote-add --if-not-exists kst4contest \
https://praktimarc.github.io/kst4contest/kst4contest.flatpakrepo
</code></pre>
<p>Anschließend kann die Stable-Version installiert werden:</p>
<pre><code class="language-bash">flatpak install kst4contest de.x08.KST4Contest//stable
</code></pre>
<h4 id="beta-installieren" tabindex="-1"><a class="header-anchor" href="#beta-installieren">Beta installieren</a></h4>
<pre><code class="language-bash">flatpak install kst4contest de.x08.KST4Contest//beta
</code></pre>
<h4 id="nightly-installieren" tabindex="-1"><a class="header-anchor" href="#nightly-installieren">Nightly installieren</a></h4>
<pre><code class="language-bash">flatpak install kst4contest de.x08.KST4Contest//nightly
</code></pre>
<p>KST4Contest verwendet für alle drei Kanäle dieselbe App-ID. Eine parallele Installation mehrerer KST4Contest-Kanäle ist deshalb nicht vorgesehen.</p>
<p>Zum Wechsel von Stable auf Nightly beispielsweise:</p>
<pre><code class="language-bash">flatpak uninstall de.x08.KST4Contest//stable
flatpak install kst4contest de.x08.KST4Contest//nightly
</code></pre>
<p>Die persönlichen Einstellungen im Verzeichnis <code>~/.praktiKST</code> werden dabei nicht automatisch gelöscht.</p>
<p>Installierte Flatpak-Anwendungen können mit folgendem Befehl aktualisiert werden:</p>
<pre><code class="language-bash">flatpak update de.x08.KST4Contest
</code></pre>
<p>Je nach Desktop-Umgebung kann die grafische Softwareverwaltung verfügbare Flatpak-Updates ebenfalls anzeigen oder automatisch installieren. Der Befehl <code>flatpak update</code> selbst führt das Update aus; er verspricht nicht, irgendwann von allein vorbeizukommen.</p>
<h3 id="appimage" tabindex="-1"><a class="header-anchor" href="#appimage">AppImage</a></h3>
<p>Das AppImage benötigt keine klassische Installation.</p>
<ol>
<li>Lade <code>KST4Contest-v&lt;Version&gt;-linux-x86_64.AppImage</code> herunter.</li>
<li>Öffne ein Terminal im Download-Verzeichnis.</li>
<li>Mache die Datei ausführbar:</li>
</ol>
<pre><code class="language-bash">chmod +x KST4Contest-v&lt;Version&gt;-linux-x86_64.AppImage
</code></pre>
<ol start="4">
<li>Starte KST4Contest:</li>
</ol>
<pre><code class="language-bash">./KST4Contest-v&lt;Version&gt;-linux-x86_64.AppImage
</code></pre>
<p>Das AppImage kann anschließend an einen anderen Ort verschoben werden, beispielsweise nach <code>~/Applications</code>.</p>
<h3 id="debian-und-ubuntu" tabindex="-1"><a class="header-anchor" href="#debian-und-ubuntu">Debian und Ubuntu</a></h3>
<p>Installiere das DEB-Paket mit:</p>
<pre><code class="language-bash">sudo apt install ./KST4Contest-v&lt;Version&gt;-debian-amd64.deb
</code></pre>
<p>Alternativ kann die Datei in einer grafischen Paketverwaltung geöffnet werden.</p>
<h3 id="fedora-und-kompatible-rpm-systeme" tabindex="-1"><a class="header-anchor" href="#fedora-und-kompatible-rpm-systeme">Fedora und kompatible RPM-Systeme</a></h3>
<p>Installiere das RPM-Paket mit:</p>
<pre><code class="language-bash">sudo dnf install ./KST4Contest-v&lt;Version&gt;-fedora-x86_64.rpm
</code></pre>
<h3 id="arch-linux%3A-fertiges-release-paket" tabindex="-1"><a class="header-anchor" href="#arch-linux%3A-fertiges-release-paket">Arch Linux: fertiges Release-Paket</a></h3>
<p>Das aus dem GitHub Release heruntergeladene Arch-Paket kann direkt installiert werden:</p>
<pre><code class="language-bash">sudo pacman -U KST4Contest-v&lt;Version&gt;-archlinux-x86_64.pkg.tar.zst
</code></pre>
<h3 id="arch-linux%3A-installation-%C3%BCber-den-aur" tabindex="-1"><a class="header-anchor" href="#arch-linux%3A-installation-%C3%BCber-den-aur">Arch Linux: Installation über den AUR</a></h3>
<p>Im AUR stehen drei Varianten bereit:</p>
<table>
<thead>
<tr>
<th>Paket</th>
<th>Inhalt</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://aur.archlinux.org/packages/kst4contest-bin"><code>kst4contest-bin</code></a></td>
<td>Vorgefertigtes Paket des aktuellen Stable-Releases</td>
</tr>
<tr>
<td><a href="https://aur.archlinux.org/packages/kst4contest"><code>kst4contest</code></a></td>
<td>Stable-Release, das lokal aus dem Quellcode gebaut wird</td>
</tr>
<tr>
<td><a href="https://aur.archlinux.org/packages/kst4contest-git"><code>kst4contest-git</code></a></td>
<td>Aktueller Entwicklungsstand aus dem <code>main</code>-Branch</td>
</tr>
</tbody>
</table>
<p>Für die meisten Anwender ist <code>kst4contest-bin</code> die naheliegende Variante:</p>
<pre><code class="language-bash">yay -S kst4contest-bin
</code></pre>
<p>Stable aus dem Quellcode bauen:</p>
<pre><code class="language-bash">yay -S kst4contest
</code></pre>
<p>Aktuellen Entwicklungsstand bauen:</p>
<pre><code class="language-bash">yay -S kst4contest-git
</code></pre>
<p>Die drei Pakete stellen dieselbe Anwendung bereit und sind deshalb als gegenseitige Konflikte definiert. Installiere nur eine Variante gleichzeitig.</p>
<p>AUR-Updates werden berücksichtigt, wenn der verwendete AUR-Helper nach Paketaktualisierungen sucht, beispielsweise mit:</p>
<pre><code class="language-bash">yay -Syu
</code></pre>
<p>Sie erfolgen nicht allein deshalb automatisch, weil das Paket aus dem AUR stammt.</p>
<hr>
<h2 id="installation-unter-macos" tabindex="-1"><a class="header-anchor" href="#installation-unter-macos">Installation unter macOS</a></h2>
<blockquote>
<p><strong>Best-Effort-Support:</strong> Die macOS-Pakete werden zusammen mit den übrigen Releases gebaut, aber nicht in demselben Umfang getestet wie die Windows- und Linux-Versionen. Rückmeldungen sind willkommen; eine vollständig geprüfte Unterstützung aller macOS-Versionen und Hardwarevarianten kann derzeit jedoch nicht zugesagt werden.</p>
</blockquote>
<p>Für Apple-Silicon-Macs wird das Paket mit <code>arm64</code> benötigt. Für Intel-Macs ist das Paket mit <code>x86_64</code> vorgesehen.</p>
<ol>
<li>Lade die passende DMG-Datei herunter.</li>
<li>Öffne die DMG-Datei.</li>
<li>Ziehe <code>KST4Contest.app</code> in den Ordner <strong>Programme</strong>.</li>
<li>Starte KST4Contest aus dem Programme-Ordner oder über das Launchpad.</li>
</ol>
<p>Die Anwendung ist derzeit nicht von Apple notarisiert. macOS kann den ersten Start deshalb blockieren.</p>
<p>Falls die Anwendung aus dem offiziellen GitHub Release stammt:</p>
<ol>
<li>Öffne den Programme-Ordner im Finder.</li>
<li>Klicke mit der rechten Maustaste oder mit gedrückter Ctrl-Taste auf <code>KST4Contest.app</code>.</li>
<li>Wähle <strong>Öffnen</strong>.</li>
<li>Bestätige den Start im angezeigten Dialog.</li>
</ol>
<p>Alternativ kann macOS unter <strong>Systemeinstellungen → Datenschutz &amp; Sicherheit</strong> die Schaltfläche <strong>Trotzdem öffnen</strong> anbieten.</p>
<hr>
<h2 id="wo-werden-die-einstellungen-gespeichert%3F" tabindex="-1"><a class="header-anchor" href="#wo-werden-die-einstellungen-gespeichert%3F">Wo werden die Einstellungen gespeichert?</a></h2>
<p>KST4Contest speichert seine Einstellungen und weitere lokale Arbeitsdateien im Benutzerverzeichnis. Der Programmordner und das Datenverzeichnis sind voneinander getrennt.</p>
<table>
<thead>
<tr>
<th>Betriebssystem</th>
<th>Datenverzeichnis</th>
<th>Einstellungsdatei</th>
</tr>
</thead>
<tbody>
<tr>
<td>Windows</td>
<td><code>%USERPROFILE%\.praktiKST\</code></td>
<td><code>%USERPROFILE%\.praktiKST\preferences.xml</code></td>
</tr>
<tr>
<td>Linux</td>
<td><code>~/.praktiKST/</code></td>
<td><code>~/.praktiKST/preferences.xml</code></td>
</tr>
<tr>
<td>macOS</td>
<td><code>~/.praktiKST/</code></td>
<td><code>~/.praktiKST/preferences.xml</code></td>
</tr>
</tbody>
</table>
<p>Beachte die Schreibweise <code>.praktiKST</code> mit großem <code>KST</code>. Unter Linux und macOS wird zwischen Groß- und Kleinschreibung unterschieden. <code>.praktikst</code> wäre dort schlicht ein anderes Verzeichnis.</p>
<p>Ein Programmupdate entfernt dieses Verzeichnis nicht. Trotzdem ist es sinnvoll, vor größeren Versionswechseln oder umfangreichen Änderungen an der Konfiguration eine Sicherung davon anzulegen.</p>
<hr>
<h2 id="updates" tabindex="-1"><a class="header-anchor" href="#updates">Updates</a></h2>
<p>KST4Contest prüft beim Start, ob ein neueres Stable-Release verfügbar ist. Wenn eine neuere Version gefunden wird, erscheint ein Informationsfenster mit:</p>
<ul>
<li>der installierten Version,</li>
<li>der aktuellen Stable-Version,</li>
<li>einer kurzen Übersicht wesentlicher Änderungen,</li>
<li>dem Changelog,</li>
<li>bekannten Problemen,</li>
<li>einem Link zur passenden GitHub-Release-Seite.</li>
</ul>
<p><img src="/manual/assets/update_window.png" alt="Update-Hinweis von KST4Contest"></p>
<p>Der Update-Checker installiert nichts selbst. Er informiert über die neue Version und öffnet die plattformneutrale Release-Seite. Dort muss das passende Paket für Windows, Linux oder macOS ausgewählt werden.</p>
<h3 id="windows-aktualisieren" tabindex="-1"><a class="header-anchor" href="#windows-aktualisieren">Windows aktualisieren</a></h3>
<ol>
<li>Beende KST4Contest.</li>
<li>Lade das neue Windows-ZIP herunter.</li>
<li>Entpacke es in einen neuen oder leeren Ordner.</li>
<li>Starte die neue Version.</li>
<li>Prüfe, ob die bisherigen Einstellungen geladen wurden.</li>
<li>Entferne den alten Programmordner erst danach.</li>
</ol>
<p>Die Einstellungen bleiben erhalten, weil sie unter <code>%USERPROFILE%\.praktiKST</code> und nicht im Programmordner gespeichert werden.</p>
<h3 id="appimage-aktualisieren" tabindex="-1"><a class="header-anchor" href="#appimage-aktualisieren">AppImage aktualisieren</a></h3>
<ol>
<li>Lade das neue AppImage herunter.</li>
<li>Mache es ausführbar.</li>
<li>Starte die neue Datei.</li>
<li>Entferne das bisherige AppImage erst, wenn die neue Version funktioniert.</li>
</ol>
<h3 id="debian-und-ubuntu-aktualisieren" tabindex="-1"><a class="header-anchor" href="#debian-und-ubuntu-aktualisieren">Debian und Ubuntu aktualisieren</a></h3>
<pre><code class="language-bash">sudo apt install ./KST4Contest-v&lt;Version&gt;-debian-amd64.deb
</code></pre>
<h3 id="fedora-aktualisieren" tabindex="-1"><a class="header-anchor" href="#fedora-aktualisieren">Fedora aktualisieren</a></h3>
<pre><code class="language-bash">sudo dnf upgrade ./KST4Contest-v&lt;Version&gt;-fedora-x86_64.rpm
</code></pre>
<h3 id="arch-paket-aktualisieren" tabindex="-1"><a class="header-anchor" href="#arch-paket-aktualisieren">Arch-Paket aktualisieren</a></h3>
<pre><code class="language-bash">sudo pacman -U KST4Contest-v&lt;Version&gt;-archlinux-x86_64.pkg.tar.zst
</code></pre>
<h3 id="aur-paket-aktualisieren" tabindex="-1"><a class="header-anchor" href="#aur-paket-aktualisieren">AUR-Paket aktualisieren</a></h3>
<p>Aktualisiere das installierte Paket über den verwendeten AUR-Helper, beispielsweise:</p>
<pre><code class="language-bash">yay -Syu
</code></pre>
<h3 id="flatpak-aktualisieren" tabindex="-1"><a class="header-anchor" href="#flatpak-aktualisieren">Flatpak aktualisieren</a></h3>
<pre><code class="language-bash">flatpak update de.x08.KST4Contest
</code></pre>
<h3 id="macos-aktualisieren" tabindex="-1"><a class="header-anchor" href="#macos-aktualisieren">macOS aktualisieren</a></h3>
<ol>
<li>Lade die neue DMG-Datei für die vorhandene Architektur herunter.</li>
<li>Beende KST4Contest.</li>
<li>Öffne die DMG-Datei.</li>
<li>Ersetze <code>KST4Contest.app</code> im Programme-Ordner.</li>
<li>Starte die neue Version und prüfe die vorhandenen Einstellungen.</li>
</ol>
<p>Die Konfiguration unter <code>~/.praktiKST</code> bleibt davon unberührt.</p>
<hr>
<h2 id="probleme-beim-ersten-start" tabindex="-1"><a class="header-anchor" href="#probleme-beim-ersten-start">Probleme beim ersten Start</a></h2>
<h3 id="windows-meldet-eine-unbekannte-anwendung" tabindex="-1"><a class="header-anchor" href="#windows-meldet-eine-unbekannte-anwendung">Windows meldet eine unbekannte Anwendung</a></h3>
<p>KST4Contest ist derzeit nicht mit einem kommerziellen Windows-Code-Signing-Zertifikat signiert. Windows oder ein zusätzlich installiertes Sicherheitsprodukt kann deshalb vor einer unbekannten oder selten heruntergeladenen Anwendung warnen.</p>
<p>Prüfe in diesem Fall zuerst:</p>
<ul>
<li>Stammt die Datei aus dem <a href="https://github.com/praktimarc/kst4contest/releases/latest">offiziellen KST4Contest-Release</a>?</li>
<li>Passt der Dateiname zum veröffentlichten Release?</li>
<li>Wurde die Datei vollständig heruntergeladen?</li>
<li>Nennt das Sicherheitsprogramm einen konkreten Erkennungsnamen oder nur eine allgemeine Reputationswarnung?</li>
</ul>
<p>Ein Warnhinweis ist allein weder ein sicherer Beweis für Schadsoftware noch automatisch ein Fehlalarm. Wenn die Herkunft der Datei unklar ist, sollte sie nicht gestartet oder aus der Quarantäne wiederhergestellt werden.</p>
<p>Einige Anwender haben insbesondere Quarantäne-Meldungen von Norton 360 gemeldet. Wenn sich eine Meldung reproduzieren lässt, erstelle bitte einen <a href="https://github.com/praktimarc/kst4contest/issues">GitHub-Issue</a> und nenne:</p>
<ul>
<li>die KST4Contest-Version,</li>
<li>den vollständigen Dateinamen,</li>
<li>das verwendete Sicherheitsprodukt und dessen Version,</li>
<li>den angezeigten Erkennungsnamen,</li>
<li>möglichst einen Screenshot der Meldung.</li>
</ul>
<h3 id="das-appimage-startet-nicht" tabindex="-1"><a class="header-anchor" href="#das-appimage-startet-nicht">Das AppImage startet nicht</a></h3>
<p>Prüfe zuerst das Ausführungsrecht:</p>
<pre><code class="language-bash">chmod +x KST4Contest-v&lt;Version&gt;-linux-x86_64.AppImage
</code></pre>
<p>Starte die Datei anschließend aus einem Terminal. Fehlermeldungen sind dort meist aussagekräftiger als ein Doppelklick, der lediglich nichts Sichtbares tut.</p>
<h3 id="macos-blockiert-die-anwendung" tabindex="-1"><a class="header-anchor" href="#macos-blockiert-die-anwendung">macOS blockiert die Anwendung</a></h3>
<p>Verwende die unter <a href="#installation-unter-macos">Installation unter macOS</a> beschriebene Funktion <strong>Öffnen</strong> im Kontextmenü. Prüfe vorher, ob die DMG-Datei aus dem offiziellen GitHub Release stammt.</p>
<h3 id="das-problem-bleibt-bestehen" tabindex="-1"><a class="header-anchor" href="#das-problem-bleibt-bestehen">Das Problem bleibt bestehen</a></h3>
<p>Prüfe zunächst, ob das Problem bereits unter <a href="https://github.com/praktimarc/kst4contest/issues">GitHub Issues</a> beschrieben wurde. Falls nicht, erstelle einen neuen Issue mit:</p>
<ul>
<li>Betriebssystem und Version,</li>
<li>verwendeter KST4Contest-Version,</li>
<li>Installationsart,</li>
<li>genauer Fehlermeldung,</li>
<li>den Schritten, mit denen sich das Problem reproduzieren lässt.</li>
</ul>
<p>„Geht nicht“ beschreibt den Zustand meistens korrekt, hilft bei der Fehlersuche aber nur begrenzt.</p>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
@@ -0,0 +1,253 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ manual.title }} | KST4Contest Manual</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest manual page: {{ manual.title }}">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/manual/de/konfiguration/">
<meta property="og:type" content="website">
<meta property="og:title" content="{{ manual.title }} | KST4Contest Manual">
<meta property="og:description" content="KST4Contest manual page: {{ manual.title }}">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/manual/de/konfiguration/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="section">
<div class="card manual-content">
<p><a href="/manual/de/">← Back to manual overview</a></p>
<h1>Konfiguration</h1>
<h1 id="konfiguration" tabindex="-1"><a class="header-anchor" href="#konfiguration">Konfiguration</a></h1>
<blockquote>
<p>🇬🇧 <a href="/manual/en/configuration/">English version</a> | 🇩🇪 Du liest gerade die deutsche Version</p>
</blockquote>
<p>Nach dem ersten Start öffnet sich das <strong>Einstellungsfenster</strong> dieses ist der zentrale Ausgangspunkt für alle Konfigurationen. Es empfiehlt sich, das Einstellungsfenster während des Betriebs geöffnet zu lassen (z. B. um den Beacon schnell ein- und auszuschalten).</p>
<blockquote>
<p><strong>Wichtig</strong>: Nach jeder Änderung unbedingt <strong>„Save Settings&quot;</strong> klicken! Die Einstellungen werden unter Linux in <code>~/.praktikst/preferences.xml</code> und unter Windows in <code>%USERPROFILE%\.praktikst\preferences.xml</code> (bzw. <code>C:\Users\&lt;Benutzername&gt;\.praktikst\preferences.xml</code>) gespeichert. Ab v1.21 werden auch Fenstergrößen und Divider-Positionen beim Speichern gesichert.</p>
</blockquote>
<hr>
<h2 id="station-settings-(stationseinstellungen)" tabindex="-1"><a class="header-anchor" href="#station-settings-(stationseinstellungen)">Station Settings (Stationseinstellungen)</a></h2>
<p><img src="/manual/assets/client_settings_window_station.png" alt="Stationseinstellungen"></p>
<h3 id="login-und-chat-kategorien" tabindex="-1"><a class="header-anchor" href="#login-und-chat-kategorien">Login und Chat-Kategorien</a></h3>
<p>Hier werden die Zugangsdaten für den ON4KST-Chat eingetragen (Rufzeichen und Passwort).
Zudem wird die <strong>primäre Chat-Kategorie</strong> (z. B. IARU Region 1 VHF/Microwave) ausgewählt.</p>
<p>Mit der Option für einen <strong>zweiten Chat</strong> (Multi-Channel-Login) kann man sich gleichzeitig in eine weitere Kategorie (z. B. UHF/SHF) einloggen. Beide Chats werden dann parallel überwacht. Hier kann optional auch ein abweichender Login-Name für den zweiten Chat vergeben werden (nützlich für Opposite Station Multi-Callsign Logging).</p>
<h3 id="rufzeichen-und-locator" tabindex="-1"><a class="header-anchor" href="#rufzeichen-und-locator">Rufzeichen und Locator</a></h3>
<p>Eigenes Rufzeichen und Maidenhead-Locator (6-stellig, z. B. <code>JN49IJ</code>) eintragen. Diese Werte werden für Distanz- und Richtungsberechnungen benötigt.</p>
<h3 id="aktivierte-b%C3%A4nder" tabindex="-1"><a class="header-anchor" href="#aktivierte-b%C3%A4nder">Aktivierte Bänder</a></h3>
<p>Über die <strong>„my station uses band&quot;</strong>-Checkboxen werden die aktiven Bänder ausgewählt. Nur für ausgewählte Bänder erscheinen Schaltflächen und Tabellenzeilen in der Benutzeroberfläche. Nach Änderungen muss die Software neu gestartet werden.</p>
<h3 id="antennen-%C3%B6ffnungswinkel-(antenna-beamwidth)" tabindex="-1"><a class="header-anchor" href="#antennen-%C3%B6ffnungswinkel-(antenna-beamwidth)">Antennen-Öffnungswinkel (Antenna Beamwidth)</a></h3>
<p>Einen realistischen Wert für den Öffnungswinkel der eigenen Antenne eintragen (in Grad). Dieser Wert wird für die <a href="Funktionen#sked-richtungs-hervorhebung">Sked-Richtungs-Hervorhebung</a> verwendet. Ein Testwert von 50° hat sich bewährt; DM5M nutzt Quads mit 69°.</p>
<blockquote>
<p><strong>Keinesfalls</strong> Fantasy-Werte eintragen die Richtungsberechnungen werden sonst unbrauchbar.</p>
</blockquote>
<h3 id="standard-maximum-qrb" tabindex="-1"><a class="header-anchor" href="#standard-maximum-qrb">Standard-Maximum-QRB</a></h3>
<p>Maximale Entfernung (in km), für die Richtungs-Warnungen ausgelöst werden sollen. Realistischer Wert für DM5M: 900 km. Stationen, die weiter entfernt sind, werden für Highlighting-Zwecke ignoriert.</p>
<hr>
<h2 id="server-einstellungen-(ab-v1.31)" tabindex="-1"><a class="header-anchor" href="#server-einstellungen-(ab-v1.31)">Server-Einstellungen (ab v1.31)</a></h2>
<p>Der Chat-Server-DNS und -Port sind in den Preferences konfigurierbar:</p>
<ul>
<li><strong>Server-DNS</strong>: Standard <code>www.on4kst.org</code> (ab v1.31 geändert von <code>www.on4kst.info</code>).</li>
<li><strong>Port</strong>: Standardport des ON4KST-Servers.</li>
</ul>
<p>Eine Änderung ist nur notwendig, wenn der Server umzieht oder ein alternativer Endpunkt genutzt wird.</p>
<hr>
<h2 id="log-sync-einstellungen" tabindex="-1"><a class="header-anchor" href="#log-sync-einstellungen">Log-Sync-Einstellungen</a></h2>
<p>Drei Methoden stehen zur Verfügung, um gearbeitete Stationen automatisch zu markieren. Details: <a href="/manual/de/log-synchronisation/">Log-Synchronisation</a>.</p>
<h3 id="universal-file-based-callsign-interpreter-(simplelogfile)" tabindex="-1"><a class="header-anchor" href="#universal-file-based-callsign-interpreter-(simplelogfile)">Universal File Based Callsign Interpreter (Simplelogfile)</a></h3>
<p>Interpretiert beliebige Log-Dateien per Regex nach Rufzeichen-Mustern. Keine Bandinformation möglich. Geeignet als Fallback oder für nicht direkt unterstützte Logprogramme.</p>
<h3 id="netzwerk-listener-f%C3%BCr-qso-udp-broadcast" tabindex="-1"><a class="header-anchor" href="#netzwerk-listener-f%C3%BCr-qso-udp-broadcast">Netzwerk-Listener für QSO-UDP-Broadcast</a></h3>
<p><strong>Empfohlene Methode.</strong> KST4Contest hört auf UDP-Pakete, die das Logprogramm beim Speichern eines QSOs an die Broadcast-Adresse sendet. Die Stationen werden mit Bandinformation markiert. UDP-Port: Standard <strong>12060</strong>. (Wird z. B. von UCXLog, N1MM+, QARTest, <a href="http://DXLog.net">DXLog.net</a> genutzt).</p>
<h3 id="win-test-network-listener-(zus%C3%A4tzlicher-udp-listener)" tabindex="-1"><a class="header-anchor" href="#win-test-network-listener-(zus%C3%A4tzlicher-udp-listener)">Win-Test Network-Listener (Zusätzlicher UDP-Listener)</a></h3>
<p>Dedizierter Netzwerk-Erkenner für Win-Test. KST4Contest empfängt und verarbeitet Win-Test-spezifische UDP-Pakete (inkl. Sked-Übergabe) auf dem dafür konfigurierten Port.</p>
<hr>
<h2 id="trx-sync-einstellungen" tabindex="-1"><a class="header-anchor" href="#trx-sync-einstellungen">TRX-Sync-Einstellungen</a></h2>
<p>Empfängt die aktuelle Frequenz des Transceivers vom Logprogramm via UDP. Ermöglicht die automatische Befüllung der Variable <code>MYQRG</code>. Nützlich für:</p>
<ul>
<li>Schnelles Einfügen der eigenen QRG in Chat-Nachrichten.</li>
<li>Automatische CQ-Baken mit aktueller Frequenz.</li>
</ul>
<blockquote>
<p><strong>Hinweis für Multi-Setup</strong>: Wenn zwei Logprogramme an zwei Computern betrieben werden, aber nur eine KST4Contest-Instanz, darf nur ein Logprogramm die Frequenzpakete senden. KST4Contest kann nicht zwischen den Quellen unterscheiden.</p>
</blockquote>
<hr>
<h2 id="airscout-einstellungen" tabindex="-1"><a class="header-anchor" href="#airscout-einstellungen">AirScout-Einstellungen</a></h2>
<p>Konfiguration der Schnittstelle zu AirScout für die Flugzeug-Scatter-Erkennung. Details: <a href="/manual/de/airscout-integration/">AirScout-Integration</a>.</p>
<hr>
<h2 id="notification-settings-(benachrichtigungen)" tabindex="-1"><a class="header-anchor" href="#notification-settings-(benachrichtigungen)">Notification Settings (Benachrichtigungen)</a></h2>
<p>Drei Benachrichtigungstypen stehen zur Wahl:</p>
<ol>
<li><strong>Einfache Sounds</strong>: TADA-Sound für eingehende Nachrichten, Tick für Sked-Richtungserkennung usw.</li>
<li><strong>CW-Ansage</strong>: Das Rufzeichen einer Station, die eine Privatnachricht sendet, wird als CW-Signal ausgegeben.</li>
<li><strong>Phonetische Ansage</strong>: Das Rufzeichen wird phonetisch ausgesprochen.</li>
</ol>
<hr>
<h2 id="shortcut-settings-(schnellzugriff-schaltfl%C3%A4chen)" tabindex="-1"><a class="header-anchor" href="#shortcut-settings-(schnellzugriff-schaltfl%C3%A4chen)">Shortcut Settings (Schnellzugriff-Schaltflächen)</a></h2>
<p>Konfiguration von Schnellzugriff-Schaltflächen, die direkt im Hauptfenster erscheinen. Ein Klick auf eine Schaltfläche fügt den konfigurierten Text in das Sendfeld ein. Alle <a href="Makros-und-Variablen#variablen">Variablen</a> können verwendet werden.</p>
<hr>
<h2 id="snippet-settings-(text-snippets)" tabindex="-1"><a class="header-anchor" href="#snippet-settings-(text-snippets)">Snippet Settings (Text-Snippets)</a></h2>
<p>Text-Snippets sind über folgende Wege abrufbar:</p>
<ul>
<li><strong>Rechtsklick</strong> auf ein Rufzeichen in der Benutzerliste</li>
<li><strong>Rechtsklick</strong> in der CQ-Nachrichtentabelle</li>
<li><strong>Rechtsklick</strong> in der PM-Nachrichtentabelle</li>
<li><strong>Tastenkombinationen</strong>: <code>Ctrl+1</code> bis <code>Ctrl+0</code> für die ersten 10 Snippets</li>
</ul>
<p>Wenn in der Benutzerliste ein Rufzeichen ausgewählt ist, wird der Snippet als Direktnachricht adressiert:
<code>/CQ RUFZEICHEN &lt;Snippet-Text&gt;</code></p>
<hr>
<h2 id="beacon-settings-(automatischer-beacon)" tabindex="-1"><a class="header-anchor" href="#beacon-settings-(automatischer-beacon)">Beacon Settings (Automatischer Beacon)</a></h2>
<p>Konfiguration eines automatischen Intervall-Beacons im öffentlichen Chat-Kanal. Empfohlen: Variable <code>MYQRG</code> im Text verwenden, damit die aktuelle Frequenz immer aktuell ist. Intervall und Text sind frei konfigurierbar.</p>
<blockquote>
<p><strong>Tipp</strong>: Beacon beim CQ-Rufen aktivieren und im Einstellungsfenster schnell deaktivieren, wenn kein CQ gerufen wird.</p>
</blockquote>
<hr>
<h2 id="messagehandling-settings-(ab-v1.25)" tabindex="-1"><a class="header-anchor" href="#messagehandling-settings-(ab-v1.25)">Messagehandling Settings (ab v1.25)</a></h2>
<p>Neuer Einstellungsbereich mit folgenden Optionen:</p>
<ul>
<li><strong>Auto-Antwort auf alle eingehenden Nachrichten</strong>: Automatische Antwort auf Privatnachrichten konfigurierbar.</li>
<li><strong>Auto-Antwort mit eigener CQ-QRG</strong>: Wenn jemand nach der eigenen QRG fragt, antwortet KST4Contest automatisch mit dem Inhalt der <code>MYQRG</code>-Variable.</li>
<li><strong>Standard-Filter für das Userinfo-Fenster</strong>: Voreingestellter Nachrichtenfilter für das Stationsinfo-Fenster konfigurierbar <em>(für Gianluca :-) )</em>.</li>
</ul>
<hr>
<h2 id="win-test-netzwerk-listener-(ab-v1.31)" tabindex="-1"><a class="header-anchor" href="#win-test-netzwerk-listener-(ab-v1.31)">Win-Test-Netzwerk-Listener (ab v1.31)</a></h2>
<p>Dedizierter Empfänger für Win-Test-spezifische UDP-Pakete. Ermöglicht:</p>
<ul>
<li><strong>Log-Synchronisation</strong>: Gearbeitete Stationen werden aus Win-Test übernommen und in der Benutzerliste markiert.</li>
<li><strong>Frequenz-Auswertung</strong>: Die aktuelle TRX-Frequenz aus Win-Test befüllt die <code>MYQRG</code>-Variable.</li>
<li><strong>Sked-Übergabe (SKED Push)</strong>: Skeds aus KST4Contest werden via UDP direkt an Win-Test übergeben. Der UDP-Broadcast-Standardport von Win-Test (9871) wird verwendet.</li>
</ul>
<p>Einstellungen:</p>
<ul>
<li><strong>Aktivieren/Deaktivieren</strong>: Checkbox in den Preferences (ab v1.40).</li>
<li><strong>Port</strong>: Konfigurierbarer UDP-Port für den Win-Test-Listener.</li>
<li><strong>Sked-UDP-Adresse und Port</strong>: Zieladresse und Port für die SKED-Übergabe an Win-Test.</li>
</ul>
<blockquote>
<p><strong>Hinweis</strong>: Der Win-Test-Listener ist ein <strong>zusätzlicher</strong> Listener der Standard-QSO-UDP-Broadcast-Listener auf Port 12060 bleibt davon unabhängig.</p>
</blockquote>
<hr>
<h2 id="pstrotator-einstellungen-(ab-v1.31)" tabindex="-1"><a class="header-anchor" href="#pstrotator-einstellungen-(ab-v1.31)">PSTRotator-Einstellungen (ab v1.31)</a></h2>
<p>KST4Contest kann die Antennenrichtung über PSTRotator steuern.</p>
<p>Einstellungen:</p>
<ul>
<li><strong>Aktivieren/Deaktivieren</strong>: Checkbox in den Preferences (ab v1.40).</li>
<li><strong>IP-Adresse</strong>: IP-Adresse des PSTRotator-Rechners (Standard: <code>127.0.0.1</code> bei Betrieb auf demselben PC).</li>
<li><strong>Port</strong>: Kommunikationsport von PSTRotator.</li>
</ul>
<blockquote>
<p><strong>Hinweis</strong>: Nach einem Klick auf den Richtungs-Button wartet KST4Contest kurz auf die Rotatorantwort. Bei langsamen Rotoren (z. B. SPID) kann es zu einer kleinen Verzögerung kommen.</p>
</blockquote>
<hr>
<h2 id="sniffer-einstellungen-(ab-v1.31)" tabindex="-1"><a class="header-anchor" href="#sniffer-einstellungen-(ab-v1.31)">Sniffer-Einstellungen (ab v1.31)</a></h2>
<p>Der QSO-Sniffer filtert Chat-Nachrichten von konfigurierbaren Rufzeichen und leitet sie ins PM-Fenster weiter.</p>
<p>Einstellungen:</p>
<ul>
<li><strong>Rufzeichen-Liste</strong>: Kommagetrennte Liste von Rufzeichen, deren Nachrichten immer in das PM-Fenster weitergeleitet werden sollen.</li>
</ul>
<p>Anwendungsfall: Wichtige Stationen (z. B. DX-Peditionen oder feste Verbündete im Contest) im Auge behalten, ohne den Haupt-Chat ständig zu beobachten.</p>
<hr>
<h2 id="worked-station-database-settings-(gearbeitete-stationen-datenbank)" tabindex="-1"><a class="header-anchor" href="#worked-station-database-settings-(gearbeitete-stationen-datenbank)">Worked Station Database Settings (Gearbeitete-Stationen-Datenbank)</a></h2>
<p>Die interne Worked-Datenbank enthält:</p>
<ul>
<li>Worked-Status aller Stationen (pro Band)</li>
<li>NOT-QRV-Tags (seit v1.2)</li>
</ul>
<p><strong>Ab v1.40</strong>: Einträge haben eine automatische Lebensdauer von <strong>3 Tagen</strong> ein manuelles Zurücksetzen vor jedem Contest ist nicht mehr zwingend notwendig. Für ein vollständiges Reset kann trotzdem die Schaltfläche <strong>„Reinitialize&quot;</strong> verwendet werden.</p>
<hr>
<h2 id="dark-mode-(ab-v1.26)" tabindex="-1"><a class="header-anchor" href="#dark-mode-(ab-v1.26)">Dark Mode (ab v1.26)</a></h2>
<p>Umschaltbar über das Menü: <strong>Window → Use Dark Mode</strong>. Die Farben können über CSS individuell angepasst werden.</p>
<hr>
<h2 id="einstellungen-speichern" tabindex="-1"><a class="header-anchor" href="#einstellungen-speichern">Einstellungen speichern</a></h2>
<p>Nach <strong>jeder</strong> Änderung <strong>„Save Settings&quot;</strong> klicken! Ohne Speichern gehen alle Änderungen beim nächsten Start verloren.</p>
<ul>
<li>Speicherort: unter Linux <code>~/.praktikst/preferences.xml</code> und unter Windows <code>%USERPROFILE%\.praktikst\preferences.xml</code> (bzw. <code>C:\Users\&lt;Benutzername&gt;\.praktikst\preferences.xml</code>)</li>
<li>Ab v1.21: Fenstergrößen und Divider-Positionen werden ebenfalls gespeichert.</li>
<li>Bei Problemen: Konfigurationsdatei löschen → KST4Contest erstellt eine neue mit Standardwerten.</li>
</ul>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
@@ -0,0 +1,231 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ manual.title }} | KST4Contest Manual</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest manual page: {{ manual.title }}">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/manual/de/log-synchronisation/">
<meta property="og:type" content="website">
<meta property="og:title" content="{{ manual.title }} | KST4Contest Manual">
<meta property="og:description" content="KST4Contest manual page: {{ manual.title }}">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/manual/de/log-synchronisation/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="section">
<div class="card manual-content">
<p><a href="/manual/de/">← Back to manual overview</a></p>
<h1>Log-Synchronisation</h1>
<h1 id="log-synchronisation" tabindex="-1"><a class="header-anchor" href="#log-synchronisation">Log-Synchronisation</a></h1>
<blockquote>
<p>🇬🇧 <a href="/manual/en/log-sync/">English version</a> | 🇩🇪 Du liest gerade die deutsche Version</p>
</blockquote>
<p>KST4Contest markiert gearbeitete Stationen automatisch in der Chat-Benutzerliste. Dafür gibt es zwei grundlegende Methoden:</p>
<hr>
<p><img src="/manual/assets/client_settings_window_logsync.png" alt="Log-Synchronisation Einstellungsfenster"></p>
<h2 id="methode-1%3A-universal-file-based-callsign-interpreter-(simplelogfile)" tabindex="-1"><a class="header-anchor" href="#methode-1%3A-universal-file-based-callsign-interpreter-(simplelogfile)">Methode 1: Universal File Based Callsign Interpreter (Simplelogfile)</a></h2>
<p>KST4Contest liest eine Log-Datei und sucht mittels regulärem Ausdruck nach Rufzeichen-Mustern. Dabei werden auch binäre Logdateien unterstützt unlesbarer Binärinhalt wird einfach ignoriert.</p>
<p><strong>Vorteil</strong>: Funktioniert mit nahezu jedem Logprogramm, das eine Datei schreibt.
<strong>Nachteil</strong>: Keine Bandinformation möglich es wird nur „gearbeitet&quot; markiert, nicht auf welchem Band.</p>
<p>Pfad der Log-Datei in den Preferences eintragen. Die Datei wird nur gelesen, nie verändert (read-only).</p>
<blockquote>
<p><strong>Tipp</strong>: Die Simplelogfile-Funktion kann auch genutzt werden, um Stationen zu markieren, die definitiv nicht erreichbar sind (z. B. eigene Notizen). Das wird in einer späteren Version durch ein besseres Tagging-System ersetzt.</p>
</blockquote>
<hr>
<h2 id="methode-2%3A-netzwerk-listener-(udp-broadcast)-%E2%80%93-empfohlen" tabindex="-1"><a class="header-anchor" href="#methode-2%3A-netzwerk-listener-(udp-broadcast)-%E2%80%93-empfohlen">Methode 2: Netzwerk-Listener (UDP-Broadcast) Empfohlen</a></h2>
<p>Das Logprogramm sendet beim Speichern eines QSOs ein UDP-Paket an die Broadcast-Adresse des Heimnetzwerks. KST4Contest empfängt dieses Paket und markiert die Station inklusive <strong>Bandinformation</strong> in der internen SQLite-Datenbank.</p>
<blockquote>
<p><strong>Wichtig</strong>: KST4Contest muss <strong>parallel zum Logprogramm laufen</strong>. QSOs, die während einer Abwesenheit von KST4Contest geloggt werden, werden nicht erfasst außer bei QARTest (kann das komplette Log senden).</p>
</blockquote>
<p><strong>Standard UDP-Port</strong>: 12060 (entspricht dem Standard der meisten Logprogramme)</p>
<hr>
<h2 id="unterst%C3%BCtzte-logprogramme" tabindex="-1"><a class="header-anchor" href="#unterst%C3%BCtzte-logprogramme">Unterstützte Logprogramme</a></h2>
<h3 id="ucxlog-(dl7ucx)" tabindex="-1"><a class="header-anchor" href="#ucxlog-(dl7ucx)">UCXLog (DL7UCX)</a></h3>
<p><img src="/manual/assets/ucxlog_logsync.png" alt="UCXLog Konfiguration"></p>
<p>UCXLog sendet QSO-UDP-Pakete und Transceiver-Frequenzpakete.</p>
<p><strong>Einstellungen in UCXLog:</strong></p>
<ul>
<li>UDP-Broadcast aktivieren</li>
<li>IP-Adresse des KST4Contest-Computers eintragen (bei lokalem Betrieb: <code>127.0.0.1</code>)</li>
<li>Port: 12060 (Standard)</li>
</ul>
<p>Grün markierte Felder in den UCXLog-Einstellungen beachten: IP und Port müssen eingetragen werden.</p>
<p>Hinweis für Multi-Setup (2 Computer, 2 Radios, eine KST4Contest-Instanz): Beide Logprogramme müssen die QSO-Pakete an die IP des KST4Contest-Computers senden. Dann ist mindestens eine IP nicht <code>127.0.0.1</code>.</p>
<h3 id="qartest-(ik3qar)" tabindex="-1"><a class="header-anchor" href="#qartest-(ik3qar)">QARTest (IK3QAR)</a></h3>
<p><img src="/manual/assets/qartest_logsync.png" alt="QARTest Konfiguration"></p>
<p><strong>Besonderheit</strong>: QARTest kann das <strong>vollständige Log</strong> an KST4Contest senden (Schaltfläche „Invia log completo&quot; in den QARTest-Einstellungen). Damit werden auch QSOs erfasst, die vor dem Start von KST4Contest geloggt wurden.</p>
<p><strong>Einstellungen in QARTest:</strong></p>
<ul>
<li>UDP-Broadcast und IP/Port wie UCXLog konfigurieren</li>
<li>„Invia log completo&quot; für den vollständigen Log-Upload verwenden</li>
</ul>
<p><em>(„Buona funzionalità caro IK3QAR!&quot; DO5AMF)</em></p>
<h3 id="n1mm%2B" tabindex="-1"><a class="header-anchor" href="#n1mm%2B">N1MM+</a></h3>
<p><strong>Einstellungen in N1MM+:</strong></p>
<p>In N1MM+ unter <code>Config → Configure Ports, Mode Control, Winkey, etc. → Broadcast Data</code>:</p>
<ul>
<li><code>Radio Info</code> aktivieren (für TRX-Sync/QRG)</li>
<li><code>Contact Info</code> aktivieren (für QSO-Sync)</li>
<li>IP: <code>127.0.0.1</code> (oder IP des KST4Contest-Computers)</li>
<li>Port: 12060</li>
</ul>
<p>Für den integrierten DX-Cluster-Server: N1MM+ als DX-Cluster-Client konfigurieren (Server: <code>127.0.0.1</code>, Port wie in KST4Contest eingestellt).</p>
<h3 id="dxlog.net" tabindex="-1"><a class="header-anchor" href="#dxlog.net"><a href="http://DXLog.net">DXLog.net</a></a></h3>
<p><img src="/manual/assets/dxlog_net_logsync.png" alt="DXLog.net Konfiguration"></p>
<p><strong>Einstellungen in <a href="http://DXLog.net">DXLog.net</a>:</strong></p>
<ul>
<li>UDP-Broadcast aktivieren</li>
<li>IP des KST4Contest-Computers eintragen (grün markierte Felder)</li>
<li>Port: 12060</li>
</ul>
<h3 id="win-test" tabindex="-1"><a class="header-anchor" href="#win-test">Win-Test</a></h3>
<p>Win-Test wird mit einem dedizierten UDP-Netzwerk-Listener unterstützt, der das native Win-Test Netzwerkprotokoll versteht.</p>
<p><strong>Vorteile der Win-Test Integration:</strong></p>
<ul>
<li>Automatische QSO-Synchronisation zur Markierung gearbeiteter Stationen.</li>
<li><strong>Sked-Übergabe (ADDSKED):</strong> Über den Button “Create sked” im Stationsinfo-Panel wird nicht nur in KST4Contest ein Sked angelegt, sondern dieser auch <em>direkt per UDP an das Win-Test Netzwerk als ADDSKED-Paket gesendet</em> automatisch, sobald der Listener aktiv ist.</li>
<li>Es kann zwischen den Sked-Modi “AUTO”, “SSB” oder “CW” gewählt werden.</li>
<li><strong>Automatische QRG-Auflösung für SKEDs:</strong> KST4Contest wählt die Sked-Frequenz intelligent:
<ol>
<li>Hat die Gegenstation in einer Chat-Nachricht ihre QRG genannt, wird diese verwendet.</li>
<li>Sonst wird die eigene aktuelle QRG verwendet (aus Win-Test STATUS oder manueller Eingabe).</li>
</ol>
</li>
</ul>
<p><strong>Einstellungen im Reiter „Log-Synchronisation&quot;:</strong></p>
<ul>
<li><code>Receive Win-Test network based UDP log messages</code> aktivieren.</li>
<li><code>UDP-Port for Win-Test listener</code> (Standard: 9871).</li>
<li><code>KST station name in Win-Test network (src of SKED packets)</code>: Legt fest, unter welchem Stationsnamen KST4Contest im WT-Netzwerk auftritt (z.B. “KST”).</li>
<li><code>Win-Test network broadcast address</code>: Wird i.d.R. automatisch erkannt; erforderlich für das Senden von Sked-Paketen.</li>
</ul>
<p><strong>Einstellungen im Reiter „TRX-Synchronisation&quot;:</strong></p>
<ul>
<li><code>Win-Test STATUS QRG Sync</code>: Wenn aktiviert, übernimmt KST4Contest die aktuelle Transceiverfrequenz aus dem Win-Test STATUS-Paket als eigene QRG (MYQRG).</li>
<li><code>Use pass frequency from Win-Test STATUS</code>: Statt der eigenen TRX-QRG wird die im STATUS-Paket enthaltene Pass-Frequenz als MYQRG verwendet (für Multi-Op-Setups, bei denen mit einer Pass-QRG gearbeitet wird).</li>
<li><code>Win-Test station name filter</code>: Wird hier ein Name eingetragen (z.B. “STN1”), verarbeitet KST4Contest nur Pakete dieser Win-Test-Instanz. Leer lassen, um alle zu akzeptieren.</li>
</ul>
<p><strong>Einstellungen in Win-Test:</strong></p>
<ul>
<li>Das Netzwerk in Win-Test muss aktiv sein.</li>
<li>Win-Test muss so konfiguriert sein, dass es seine Broadcasts an den entsprechenden Port (Standard 9871) sendet bzw. empfängt.</li>
</ul>
<hr>
<h2 id="trx-frequenz-synchronisation" tabindex="-1"><a class="header-anchor" href="#trx-frequenz-synchronisation">TRX-Frequenz-Synchronisation</a></h2>
<p>Neben der QSO-Synchronisation übertragen UCXLog und andere Programme auch die <strong>aktuelle Transceiverfrequenz</strong> via UDP. KST4Contest verarbeitet diese Information und stellt sie als Variable <code>MYQRG</code> bereit.</p>
<p><img src="/manual/assets/qrg_buttons.png" alt="FrequenzButtons"></p>
<p><strong>Ergebnis</strong>: Die eigene QRG muss im Chat nie mehr manuell eingegeben werden ein Klick auf den MYQRG-Button oder die Verwendung der Variable im Beacon genügt.</p>
<p><strong>Quellen für die eigene QRG (MYQRG):</strong></p>
<ul>
<li>UCXLog, N1MM+, <a href="http://DXLog.net">DXLog.net</a>, QARTest via UDP-Port 12060</li>
<li>Win-Test STATUS-Paket (optional, konfigurierbar im Reiter „TRX-Synchronisation&quot; unter „Win-Test STATUS QRG Sync&quot;)</li>
<li>Manuelle Eingabe im QRG-Feld</li>
</ul>
<blockquote>
<p><strong>Hinweis für Multi-Setup</strong>: Bei zwei Logprogrammen an zwei Computern sollte nur <strong>eines</strong> die Frequenzpakete senden. KST4Contest kann nicht zwischen den Quellen unterscheiden und verarbeitet alle eingehenden Pakete.</p>
</blockquote>
<hr>
<h2 id="multi-setup%3A-2-radios%2C-2-computer" tabindex="-1"><a class="header-anchor" href="#multi-setup%3A-2-radios%2C-2-computer">Multi-Setup: 2 Radios, 2 Computer</a></h2>
<p>Für DM5M-typische Setups (2 Radios, 2 Computer, eine KST4Contest-Instanz oder zwei separate):</p>
<p><strong>Variante A Eine gemeinsame KST4Contest-Instanz:</strong></p>
<ul>
<li>Beide Logprogramme senden QSO-Pakete an die IP des KST4Contest-Computers</li>
<li>Nur ein Logprogramm sendet Frequenzpakete (empfohlen: das VHF-Logprogramm)</li>
</ul>
<p><strong>Variante B Zwei separate KST4Contest-Instanzen (empfohlen):</strong></p>
<ul>
<li>Jedes Logprogramm kommuniziert mit seiner eigenen KST4Contest-Instanz via <code>127.0.0.1</code></li>
<li>Zwei separate Chat-Logins</li>
<li>Bessere Trennung und weniger Konflikte</li>
</ul>
<hr>
<h2 id="interne-datenbank" tabindex="-1"><a class="header-anchor" href="#interne-datenbank">Interne Datenbank</a></h2>
<p>KST4Contest speichert die Worked-Information in einer internen <strong>SQLite-Datenbank</strong>. Diese ist von der Logprogramm-Datenbank unabhängig und wird nur über den UDP-Broadcast befüllt.</p>
<p>Vor jedem neuen Contest: Datenbank zurücksetzen! → <a href="Konfiguration#worked-station-database-settings">Konfiguration Worked Station Database Settings</a></p>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
@@ -0,0 +1,242 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ manual.title }} | KST4Contest Manual</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest manual page: {{ manual.title }}">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/manual/de/makros-und-variablen/">
<meta property="og:type" content="website">
<meta property="og:title" content="{{ manual.title }} | KST4Contest Manual">
<meta property="og:description" content="KST4Contest manual page: {{ manual.title }}">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/manual/de/makros-und-variablen/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="section">
<div class="card manual-content">
<p><a href="/manual/de/">← Back to manual overview</a></p>
<h1>Makros und Variablen</h1>
<h1 id="makros-und-variablen" tabindex="-1"><a class="header-anchor" href="#makros-und-variablen">Makros und Variablen</a></h1>
<blockquote>
<p>🇬🇧 <a href="/manual/en/macros-and-variables/">English version</a> | 🇩🇪 Du liest gerade die deutsche Version</p>
</blockquote>
<p>KST4Contest bietet ein flexibles System aus Text-Snippets, Shortcuts und eingebauten Variablen, die den Chat-Workflow im Contest erheblich beschleunigen.</p>
<hr>
<h2 id="%C3%BCberblick" tabindex="-1"><a class="header-anchor" href="#%C3%BCberblick">Überblick</a></h2>
<table>
<thead>
<tr>
<th>Typ</th>
<th>Aufruf</th>
<th>Zweck</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Shortcuts</strong></td>
<td>Button in der Toolbar</td>
<td>Schneller Text-Insert ins Sendfeld</td>
</tr>
<tr>
<td><strong>Snippets</strong></td>
<td>Rechtsklick / Ctrl+1…0</td>
<td>Text-Bausteine, optionaler PM-Versand</td>
</tr>
<tr>
<td><strong>Variablen</strong></td>
<td>In allen Text-Feldern verwendbar</td>
<td>Dynamische Werte (QRG, Locator, AP-Daten)</td>
</tr>
</tbody>
</table>
<hr>
<h2 id="shortcuts-(schnellzugriff-schaltfl%C3%A4chen)" tabindex="-1"><a class="header-anchor" href="#shortcuts-(schnellzugriff-schaltfl%C3%A4chen)">Shortcuts (Schnellzugriff-Schaltflächen)</a></h2>
<p>Konfigurierbar in den Preferences → <strong>Shortcut Settings</strong>.</p>
<ul>
<li>Jeder konfigurierte Text erzeugt <strong>einen Button</strong> in der Benutzeroberfläche.</li>
<li>Ein Klick fügt den Text in das <strong>Sendfeld</strong> ein.</li>
<li><strong>Alle Variablen</strong> können in Shortcuts verwendet werden und werden beim Einfügen sofort aufgelöst.</li>
<li>Auch längere Texte möglich.</li>
</ul>
<p><strong>Tipp</strong>: Häufig verwendete Abkürzungen wie „pse&quot;, „rrr&quot;, „tnx&quot;, „73&quot; als Shortcuts anlegen.</p>
<hr>
<h2 id="snippets-(text-bausteine)" tabindex="-1"><a class="header-anchor" href="#snippets-(text-bausteine)">Snippets (Text-Bausteine)</a></h2>
<p>Konfigurierbar in den Preferences → <strong>Snippet Settings</strong>.</p>
<h3 id="aufruf" tabindex="-1"><a class="header-anchor" href="#aufruf">Aufruf</a></h3>
<ul>
<li><strong>Rechtsklick</strong> auf ein Rufzeichen in der Benutzerliste</li>
<li><strong>Rechtsklick</strong> in der CQ-Nachrichtentabelle</li>
<li><strong>Rechtsklick</strong> in der PM-Nachrichtentabelle</li>
<li><strong>Tastaturkürzel</strong>: <code>Ctrl+1</code> bis <code>Ctrl+0</code> für die ersten 10 Snippets</li>
</ul>
<h3 id="verhalten-mit-ausgew%C3%A4hltem-rufzeichen" tabindex="-1"><a class="header-anchor" href="#verhalten-mit-ausgew%C3%A4hltem-rufzeichen">Verhalten mit ausgewähltem Rufzeichen</a></h3>
<p>Wenn in der Benutzerliste ein Rufzeichen ausgewählt ist, wird der Snippet als <strong>Privatnachricht</strong> adressiert:</p>
<pre><code>/CQ RUFZEICHEN &lt;Snippet-Text&gt;
</code></pre>
<p>Anschließend kann mit <strong>Enter</strong> direkt gesendet werden auch wenn das Sendfeld nicht den Fokus hat.</p>
<h3 id="hardware-makro-tastatur" tabindex="-1"><a class="header-anchor" href="#hardware-makro-tastatur">Hardware-Makro-Tastatur</a></h3>
<p><em>(Idee von IU3OAR, Gianluca Costantino)</em></p>
<p>Die Tastenkombinationen <code>Ctrl+1</code> bis <code>Ctrl+0</code> können auf einer programmierbaren Makro-Tastatur belegt werden. Ein weiterer Tastendruck (auf eine „Enter&quot;-Taste) sendet den Text sofort. Im Contest-Betrieb spart das erheblich Zeit.</p>
<h3 id="vordefinierte-standard-snippets" tabindex="-1"><a class="header-anchor" href="#vordefinierte-standard-snippets">Vordefinierte Standard-Snippets</a></h3>
<p>Beim ersten Start werden einige Snippets vorbelegt, z. B.:</p>
<ul>
<li><code>Hi OM, try sked?</code></li>
<li><code>I am calling cq ur dir, pse lsn to me at MYQRG</code></li>
<li><code>pse ur qrg?</code></li>
<li><code>rrr, I move to your qrg nw, pse ant dir me</code></li>
</ul>
<p>Diese können in den Preferences angepasst oder gelöscht werden.</p>
<hr>
<h2 id="variablen" tabindex="-1"><a class="header-anchor" href="#variablen">Variablen</a></h2>
<p>Variablen werden in geschriebenen Texten (Snippets, Shortcuts, Beacon, Sendfeld) durch ihre aktuellen Werte ersetzt. Einfach den Variablennamen <strong>großgeschrieben</strong> in den Text einfügen.</p>
<h3 id="myqrg" tabindex="-1"><a class="header-anchor" href="#myqrg">MYQRG</a></h3>
<p>Wird durch die aktuelle Transceiverfrequenz ersetzt.</p>
<ul>
<li>Quelle: TRX-Sync via UDP vom Logprogramm (wenn aktiviert)</li>
<li>Fallback: Manuell eingetragener Wert im MYQRG-Textfeld rechts neben dem Sendbutton</li>
<li>Format: <code>144.388.03</code></li>
</ul>
<p><strong>Beispiel</strong>: <code>calling cq at MYQRG</code><code>calling cq at 144.388.03</code></p>
<h3 id="myqrgshort" tabindex="-1"><a class="header-anchor" href="#myqrgshort">MYQRGSHORT</a></h3>
<p>Wie MYQRG, aber nur die ersten 7 Zeichen.</p>
<ul>
<li>Format: <code>144.388</code></li>
</ul>
<p><strong>Beispiel</strong>: <code>qrg: MYQRGSHORT</code><code>qrg: 144.388</code></p>
<h3 id="mylocator" tabindex="-1"><a class="header-anchor" href="#mylocator">MYLOCATOR</a></h3>
<p>Wird durch den eigenen Maidenhead-Locator (6-stellig) ersetzt.</p>
<ul>
<li>Format: <code>JO51IJ</code></li>
</ul>
<p><strong>Beispiel</strong>: <code>my loc: MYLOCATOR</code><code>my loc: JO51IJ</code></p>
<h3 id="mylocatorshort" tabindex="-1"><a class="header-anchor" href="#mylocatorshort">MYLOCATORSHORT</a></h3>
<p>Wie MYLOCATOR, aber nur die ersten 4 Zeichen.</p>
<ul>
<li>Format: <code>JO51</code></li>
</ul>
<p><strong>Beispiel</strong>: <code>loc: MYLOCATORSHORT</code><code>loc: JO51</code></p>
<h3 id="qrzname" tabindex="-1"><a class="header-anchor" href="#qrzname">QRZNAME</a></h3>
<p>Wird durch den <strong>Namen</strong> der aktuell ausgewählten Station aus dem Chat-Namenfeld ersetzt.</p>
<p><strong>Beispiel</strong>: <code>Hi QRZNAME, sked?</code><code>Hi Gianluca, sked?</code></p>
<h3 id="firstap" tabindex="-1"><a class="header-anchor" href="#firstap">FIRSTAP</a></h3>
<p>Wird durch Daten des ersten reflektierbaren Flugzeugs zur ausgewählten Station ersetzt (sofern vorhanden).</p>
<ul>
<li>Bedingung: AirScout ist aktiv und ein Flugzeug ist verfügbar.</li>
<li>Format-Beispiel: <code>a very big AP in 1 min</code></li>
</ul>
<p><strong>Beispiel</strong>: <code>AP info: FIRSTAP</code><code>AP info: a very big AP in 1 min</code></p>
<h3 id="secondap" tabindex="-1"><a class="header-anchor" href="#secondap">SECONDAP</a></h3>
<p>Wie FIRSTAP, aber für das zweite verfügbare Flugzeug.</p>
<ul>
<li>Format-Beispiel: <code>Next big AP in 9 min</code></li>
</ul>
<p><strong>Beispiel</strong>: <code>also: SECONDAP</code><code>also: Next big AP in 9 min</code></p>
<h3 id="myqtf-(geplant-f%C3%BCr-v1.3)" tabindex="-1"><a class="header-anchor" href="#myqtf-(geplant-f%C3%BCr-v1.3)">MYQTF <em>(geplant für v1.3)</em></a></h3>
<p>Wird durch die aktuelle Antennenrichtung in Worten ersetzt (z. B. <code>north</code>, <code>north east</code>, <code>east</code>, …).</p>
<ul>
<li>Quelle: Winkelwert im MYQTF-Eingabefeld (rechts neben dem MYQRG-Feld)</li>
</ul>
<hr>
<h2 id="variablen-im-beacon" tabindex="-1"><a class="header-anchor" href="#variablen-im-beacon">Variablen im Beacon</a></h2>
<p>Alle Variablen können auch im <strong>automatischen Beacon</strong> (Intervall-Nachrichten) verwendet werden. Empfohlene Beacon-Konfiguration:</p>
<pre><code>calling cq at MYQRG, loc MYLOCATOR, GL all!
</code></pre>
<p>Da KST4Contest QRG-Daten automatisch aus Chat-Nachrichten ausliest: Wenn andere Stationen ebenfalls KST4Contest nutzen, sehen sie die eigene QRG sofort in der QRG-Spalte der Benutzerliste.</p>
<hr>
<h2 id="beispiel-workflow-mit-makros-im-contest" tabindex="-1"><a class="header-anchor" href="#beispiel-workflow-mit-makros-im-contest">Beispiel-Workflow mit Makros im Contest</a></h2>
<ol>
<li>Station in der Benutzerliste auswählen → Rufzeichen ist nun vorausgewählt.</li>
<li><code>Ctrl+1</code> drücken → Snippet „Hi OM, try sked?&quot; wird als PM adressiert.</li>
<li>Enter drücken → Nachricht wird gesendet.</li>
<li>Station antwortet mit Frequenz → QRG-Spalte wird automatisch befüllt.</li>
<li><code>Ctrl+2</code> → Snippet „I am calling cq ur dir, pse lsn to me at 144.388&quot; (MYQRG aufgelöst).</li>
<li>Enter → Gesendet.</li>
</ol>
<p>Ohne manuelle Tipparbeit, ohne Fehler, ohne Unterbrechung des CQ-Rufens.</p>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
@@ -0,0 +1,209 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ manual.title }} | KST4Contest Manual</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest manual page: {{ manual.title }}">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/manual/en/airscout-integration/">
<meta property="og:type" content="website">
<meta property="og:title" content="{{ manual.title }} | KST4Contest Manual">
<meta property="og:description" content="KST4Contest manual page: {{ manual.title }}">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/manual/en/airscout-integration/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="section">
<div class="card manual-content">
<p><a href="/manual/en/">← Back to manual overview</a></p>
<h1>AirScout Integration</h1>
<h1 id="airscout-integration" tabindex="-1"><a class="header-anchor" href="#airscout-integration">AirScout Integration</a></h1>
<blockquote>
<p>🇬🇧 You are reading the English version | 🇩🇪 <a href="/manual/de/airscout-integration/">Deutsche Version</a></p>
</blockquote>
<p>AirScout (by DL2ALF) is a program for detecting aircraft for aircraft scatter operation. KST4Contest is tightly integrated with AirScout and shows reflectable aircraft directly in the user list.</p>
<blockquote>
<p><strong>Aircraft Scatter</strong> enables very long-distance communication on VHF and higher even for stations with low altitude above sea level or unfavourable topographic conditions.</p>
</blockquote>
<hr>
<h2 id="downloading-airscout" tabindex="-1"><a class="header-anchor" href="#downloading-airscout">Downloading AirScout</a></h2>
<p>Download AirScout from:</p>
<ul>
<li><a href="http://airscout.eu/index.php/download">http://airscout.eu/index.php/download</a></li>
</ul>
<hr>
<h2 id="aircraft-data-feeds-(adsb)" tabindex="-1"><a class="header-anchor" href="#aircraft-data-feeds-(adsb)">Aircraft Data Feeds (ADSB)</a></h2>
<p>Public aircraft data feeds on the internet are often unreliable and limited in use. A recommended alternative is the dedicated ADSB feed service provided by <strong>OV3T (Thomas)</strong>:</p>
<ul>
<li><a href="https://airscatter.dk/">https://airscatter.dk/</a></li>
<li><a href="https://www.facebook.com/groups/825093981868542">https://www.facebook.com/groups/825093981868542</a></li>
</ul>
<p>An account is required for this service. Please consider donating to Thomas the server costs are not free!</p>
<hr>
<h2 id="setting-up-airscout" tabindex="-1"><a class="header-anchor" href="#setting-up-airscout">Setting Up AirScout</a></h2>
<h3 id="step-1%3A-configure-the-adsb-feed-in-airscout" tabindex="-1"><a class="header-anchor" href="#step-1%3A-configure-the-adsb-feed-in-airscout">Step 1: Configure the ADSB Feed in AirScout</a></h3>
<ol>
<li>Start AirScout.</li>
<li>Enter your OV3T feed account details (username, password, URL) in the AirScout settings.</li>
</ol>
<p><img src="/manual/assets/as_plane_feed_1.png" alt="AirscoutStep1">
<img src="/manual/assets/as_plane_feed_2.png" alt="AirscoutStep2"></p>
<ol start="3">
<li>Test the connection.</li>
</ol>
<h3 id="step-2%3A-enable-udp-communication-for-kst4contest" tabindex="-1"><a class="header-anchor" href="#step-2%3A-enable-udp-communication-for-kst4contest">Step 2: Enable UDP Communication for KST4Contest</a></h3>
<p>In AirScout, enable the UDP interface:</p>
<ul>
<li>Activate the corresponding checkbox in the AirScout settings (only one checkbox needed).</li>
<li>Do not change the default ports unless there is a specific reason.</li>
</ul>
<h3 id="step-3%3A-kst4contest-settings" tabindex="-1"><a class="header-anchor" href="#step-3%3A-kst4contest-settings">Step 3: KST4Contest Settings</a></h3>
<p>In KST4Contest Preferences → <strong>AirScout Settings</strong>:</p>
<ul>
<li>Enable AirScout communication</li>
<li>Leave IP and port at their default values (unless changed)</li>
</ul>
<p><img src="/manual/assets/as_plane_feed_3.png" alt="AirscoutStep3">{ width=85% }</p>
<hr>
<h2 id="communication-between-kst4contest-and-airscout-(from-v1.263)" tabindex="-1"><a class="header-anchor" href="#communication-between-kst4contest-and-airscout-(from-v1.263)">Communication Between KST4Contest and AirScout (from v1.263)</a></h2>
<p><strong>Improvement in v1.263</strong>: KST4Contest now only sends stations to AirScout whose QRB (distance) is less than the configured <strong>maximum QRB</strong>. The query interval has been extended from 12 seconds to <strong>60 seconds</strong>.</p>
<p><strong>Benefits:</strong></p>
<ul>
<li>Significantly less computation load for AirScout</li>
<li>Significantly less message traffic</li>
<li>The tracking issue with the “Show Path in AirScout” button is greatly improved</li>
<li>Less overall CPU usage</li>
</ul>
<p>Additionally: The name of the KST4Contest client and AirScout server was previously hardcoded (<code>KST</code> and <code>AS</code>). From v1.263, the names configured in the Preferences are used.</p>
<hr>
<h2 id="multiple-kst4contest-instances-and-airscout" tabindex="-1"><a class="header-anchor" href="#multiple-kst4contest-instances-and-airscout">Multiple KST4Contest Instances and AirScout</a></h2>
<blockquote>
<p><strong>Note</strong>: If multiple KST4Contest instances are running simultaneously and AirScout communication is enabled on both, AirScout will respond <strong>to both instances</strong>.</p>
</blockquote>
<p>This is not a problem if:</p>
<ul>
<li>Both instances use the same locator, <strong>or</strong></li>
<li>Both instances have different login callsigns.</li>
</ul>
<p>Otherwise, it may result in incorrect AP data.</p>
<hr>
<h2 id="ap-column-in-the-user-list" tabindex="-1"><a class="header-anchor" href="#ap-column-in-the-user-list">AP Column in the User List</a></h2>
<p>After setup, an <strong>AP column</strong> appears in the user list showing up to two reflectable aircraft per station.</p>
<p>Example display:</p>
<table>
<thead>
<tr>
<th>Station</th>
<th>AP Info</th>
</tr>
</thead>
<tbody>
<tr>
<td>DF9QX</td>
<td>2 Planes: 0 min / 0 min, 100% each</td>
</tr>
<tr>
<td>F5DYD</td>
<td>2 Planes: 14 min / 31 min, 50% each</td>
</tr>
</tbody>
</table>
<p>AP information is also available in the <strong>private messages window</strong>.</p>
<p>The percentage indicates the reflection potential (aircraft size, altitude, distance).</p>
<hr>
<h2 id="ap-variables-in-messages" tabindex="-1"><a class="header-anchor" href="#ap-variables-in-messages">AP Variables in Messages</a></h2>
<p>Aircraft data can be inserted directly into messages:</p>
<ul>
<li><code>FIRSTAP</code> → e.g. <code>a very big AP in 1 min</code></li>
<li><code>SECONDAP</code> → e.g. <code>Next big AP in 9 min</code></li>
</ul>
<p>Details: <a href="Macros-and-Variables#variables">Macros and Variables</a></p>
<hr>
<h2 id="%E2%80%9Cshow-path-in-airscout%E2%80%9D-button" tabindex="-1"><a class="header-anchor" href="#%E2%80%9Cshow-path-in-airscout%E2%80%9D-button">“Show Path in AirScout” Button</a></h2>
<p>In the user list there is a button with an arrow showing the direction (QTF) to the selected station. Clicking it maximises AirScout and shows the path with reflectable aircraft to the selected contact.</p>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
@@ -0,0 +1,346 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ manual.title }} | KST4Contest Manual</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest manual page: {{ manual.title }}">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/manual/en/changelog/">
<meta property="og:type" content="website">
<meta property="og:title" content="{{ manual.title }} | KST4Contest Manual">
<meta property="og:description" content="KST4Contest manual page: {{ manual.title }}">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/manual/en/changelog/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="section">
<div class="card manual-content">
<p><a href="/manual/en/">← Back to manual overview</a></p>
<h1>Changelog</h1>
<h1 id="changelog" tabindex="-1"><a class="header-anchor" href="#changelog">Changelog</a></h1>
<blockquote>
<p>🇬🇧 You are reading the English version | 🇩🇪 <a href="/manual/de/changelog/">Deutsche Version</a></p>
</blockquote>
<p>Version history of KST4Contest / PraktiKST.</p>
<hr>
<p>For the latest changelog, please refer to GitHub. The previous changelog is below.</p>
<h2 id="v1.41" tabindex="-1"><a class="header-anchor" href="#v1.41">v1.41</a></h2>
<p><strong>Station Map, Performance, Responsive UI</strong></p>
<p><strong>New:</strong></p>
<ul>
<li><strong>Station Map</strong>: Interactive OpenStreetMap-based map showing the geographic position of all active chat members. Includes station markers, antenna beam cone, connection line to the selected station, Maidenhead grid overlay, and a path profile chart with terrain elevation analysis (Fresnel zones, horizon detection). Terrain data from Copernicus GLO-30, Open-Meteo API, or offline DEM import. Aircraft scatter path analysis integrated. Works in AppImage and Flatpak without external CDN access (local tile proxy, bundled Leaflet.js).</li>
</ul>
<p><strong>Changed:</strong></p>
<ul>
<li><strong>Message table limit raised to 30,000</strong>: Chat and message tables are capped at 30,000 entries. Older messages are automatically discarded, keeping performance stable during multi-day contest operations.</li>
<li><strong>Screen-aware window sizing</strong>: On startup, the main window is sized to fit the current screen. If KST4Contest was last used on a larger monitor, the window is automatically scaled down. The UI layout is more compact and responsive on smaller screens.</li>
</ul>
<hr>
<h2 id="v1.40-(2026-02-16)" tabindex="-1"><a class="header-anchor" href="#v1.40-(2026-02-16)">v1.40 (2026-02-16)</a></h2>
<p><strong>Major Feature Release: Score System, AP Timeline, Win-Test, PSTRotator</strong></p>
<p><strong>New:</strong></p>
<ul>
<li><strong>Chatmember Score System</strong>: Every chat member is automatically scored based on antenna direction, activity time, message count, active bands, frequencies, sked direction (degrees), and other factors. Top candidates are highlighted in a dedicated list.</li>
<li><strong>AP Timeline</strong>: For each minute of possible aircraft arrival, up to 4 highly-scored stations are shown that should be workable. Aircraft with the highest potential are preferred over the fastest arrival. Chat members whose antenna is not pointing towards you are shown transparently.</li>
<li><strong>Win-Test Support</strong> (Beta since v1.31, now fully configurable): Log synchronisation, frequency parsing and <strong>sked handover via UDP</strong> fully integrated. Can be enabled/disabled in Preferences.</li>
<li><strong>PSTRotator Interface</strong> (Beta since v1.31, now fully configurable): Rotator position updates directly from KST4Contest. Can be enabled/disabled in Preferences.</li>
<li><strong>QSO Sniffer</strong>: Messages from configurable callsign lists are automatically forwarded to the PM window.</li>
<li><strong>Band Alert for logged stations</strong>: When a station is logged, a hint appears if that station has another active band that you are also QRV on.</li>
<li><strong>Sked Reminder ALERT</strong>: A sked alarm with automatic messages in configurable intervals (2+1 / 5+2+1 / 10+5+2+1 minutes before the sked) can be set up for each chat member, plus acoustic and visual notification.</li>
<li><strong>Load chat history on startup</strong>: Chat server history is loaded on connect to immediately see active members and recent messages.</li>
<li><strong>Skedfail button</strong>: In the FurtherInfo panel, a sked failure can be marked for a chat member, which lowers their priority score.</li>
</ul>
<p><strong>Changed:</strong></p>
<ul>
<li>AP notes added to internal DX cluster spots.</li>
<li>Chat member table scrolling follows the current message selection automatically.</li>
<li>Generic auto-reply and QRG auto-reply now fire a maximum of once every 45 seconds per callsign (prevents spam and message ping-pong).</li>
<li>New saveable settings: ServerDNS/Port, PSTRotator interface, Win-Test interface, callsign sniffer, Dark Mode on by default.</li>
<li>Date column removed from chat table (time only saves space).</li>
</ul>
<p><strong>Fixed:</strong></p>
<ul>
<li>User list now automatically sorted on every new member sign-on.</li>
<li>Posonpill messages now terminate exactly one client instance (no longer affects all instances or wtKST).</li>
<li>wtKST: crash on KST4Contest disconnection fixed.</li>
<li>Multiple issues with callsign suffixes like <code>/p</code>, <code>-2</code>, etc. fixed throughout.</li>
<li><code>QTFDefault</code> was not saved correctly → fixed.</li>
<li>AirScout watchlist (ASWATCHLIST) was not being updated → fixed.</li>
<li>Dark Mode: QRG fields not displayed at full size → fixed.</li>
<li>Version number display corrected.</li>
</ul>
<hr>
<h2 id="v1.31-(2025-12-13)" tabindex="-1"><a class="header-anchor" href="#v1.31-(2025-12-13)">v1.31 (2025-12-13)</a></h2>
<p><strong>Win-Test + PSTRotator Beta, QSO Sniffer, DNS Hotfix</strong></p>
<p><strong>New:</strong></p>
<ul>
<li><strong>Win-Test support</strong> (Beta, not yet deactivatable): Log synchronisation and frequency parsing.</li>
<li><strong>PSTRotator support</strong> (Beta, not yet deactivatable).</li>
<li><strong>QSO Sniffer</strong>: Messages from configurable callsigns are forwarded to the PM window.</li>
</ul>
<p><strong>Changed:</strong></p>
<ul>
<li><strong>DNS server changed</strong>: From <code>www.on4kst.info</code> to <code>www.on4kst.org</code> (hotfix). The DNS server is now configurable in Preferences.</li>
</ul>
<p><strong>Fixed:</strong></p>
<ul>
<li>Endless loop in error case freezes the client → fixed.</li>
</ul>
<hr>
<h2 id="v1.266-(2025-10-03)" tabindex="-1"><a class="header-anchor" href="#v1.266-(2025-10-03)">v1.266 (2025-10-03)</a></h2>
<p><strong>AirScout Fix for Callsigns with Suffix</strong></p>
<p><strong>Fixed:</strong></p>
<ul>
<li>AirScout interface did not work when the login callsign contained a suffix (e.g. <code>9A1W-2</code>). AirScout cannot handle this format only the base callsign without suffix is now passed to AirScout.</li>
</ul>
<p><em>(Bug reported and tested by 9A2HM / Kreso many thanks!)</em></p>
<hr>
<h2 id="v1.265-(2025-09-28)" tabindex="-1"><a class="header-anchor" href="#v1.265-(2025-09-28)">v1.265 (2025-09-28)</a></h2>
<p><strong>Direction Buttons Stay Coloured When Active</strong></p>
<p><strong>Fixed:</strong></p>
<ul>
<li>Direction buttons (N / NE / E etc.) now keep their highlight colour when activated, making the active state immediately visible.</li>
</ul>
<hr>
<h2 id="v1.264-(2025-08-02)" tabindex="-1"><a class="header-anchor" href="#v1.264-(2025-08-02)">v1.264 (2025-08-02)</a></h2>
<p><strong>Simplelogfile: Improved Callsign Recognition</strong></p>
<p><strong>Fixed:</strong></p>
<ul>
<li>Callsigns like <code>S53CC</code>, <code>S51A</code>, etc. were not being marked as worked in the SimpleLogFile interpreter → recognition pattern improved.</li>
</ul>
<p><em>(Bug reported by Boris, S53CC thank you!)</em></p>
<hr>
<h2 id="v1.263-(2025-06-08)" tabindex="-1"><a class="header-anchor" href="#v1.263-(2025-06-08)">v1.263 (2025-06-08)</a></h2>
<p><strong>AirScout Communication and Login Name</strong></p>
<p><strong>Changed:</strong></p>
<ul>
<li>AirScout communication fundamentally revised: Only stations with QRB &lt; max-QRB are now sent to AirScout.</li>
<li>Query interval extended from 12 seconds to <strong>60 seconds</strong>.</li>
<li>Significantly less computation load and message traffic → more stable AirScout tracking.</li>
<li>Name of the AS client and AS server is now configurable from the Preferences (was previously hardcoded to “KST” / “AS”).</li>
</ul>
<p><strong>Fixed:</strong></p>
<ul>
<li>“Track in AirScout” button was very sluggish → greatly improved by new communication logic.</li>
<li>Name in chat is now saveable (bug fixed).</li>
<li>Visual corrections before and after login.</li>
<li>Bug fixed that was reported by 9A2HM (Kreso).</li>
</ul>
<hr>
<h2 id="v1.262-(2025-05-21)" tabindex="-1"><a class="header-anchor" href="#v1.262-(2025-05-21)">v1.262 (2025-05-21)</a></h2>
<p><strong>Freeze Fix for Early Message Delivery</strong></p>
<p><strong>Fixed:</strong></p>
<ul>
<li>ON4KST sometimes delivers messages before login is complete. This caused errors in the message processing engine → now fixed.</li>
</ul>
<hr>
<h2 id="v1.26-(2025-05)" tabindex="-1"><a class="header-anchor" href="#v1.26-(2025-05)">v1.26 (2025-05)</a></h2>
<p><strong>Multi-Channel Login and Dark Mode</strong></p>
<p><strong>New:</strong></p>
<ul>
<li><strong>Dark Mode</strong>: Toggle via <code>Window → Use Dark Mode</code>.</li>
<li><strong>Multi-channel login</strong>: Simultaneous login to two chat categories.</li>
<li><strong>Opposite station multi-callsign login tagging</strong>: Support for stations with multiple callsigns.</li>
</ul>
<p><strong>Changed:</strong></p>
<ul>
<li>Colouring mechanism revised: Colours can now be customised via CSS.</li>
</ul>
<p><strong>Fixed:</strong></p>
<ul>
<li>Station tagging completely revised and corrected.</li>
</ul>
<hr>
<h2 id="v1.251-(2025-02)" tabindex="-1"><a class="header-anchor" href="#v1.251-(2025-02)">v1.251 (2025-02)</a></h2>
<p><strong>Bugfix for UDP Broadcast Spot Info</strong></p>
<p><strong>Fixed:</strong></p>
<ul>
<li>Problem reading UDP broadcast spot information fixed (reported by Steve Clements thank you!).</li>
<li>Station tagging (further improved).</li>
</ul>
<hr>
<h2 id="v1.25-(2025-02)" tabindex="-1"><a class="header-anchor" href="#v1.25-(2025-02)">v1.25 (2025-02)</a></h2>
<p><strong>Wishlist Time</strong></p>
<p><strong>New:</strong></p>
<ul>
<li><strong>New settings tab: Messagehandling</strong>
<ul>
<li>Auto-reply to incoming messages configurable.</li>
<li>Automatic reply with own CQ QRG when someone asks for it.</li>
<li>Configurable default filter for the userinfo window <em>(for Gianluca :-) )</em>.</li>
</ul>
</li>
<li><strong>Coloured PM rows</strong>: New private messages appear red and fade every 30 seconds from yellow to white <em>(idea by IU3OAR, Gianluca)</em>.</li>
</ul>
<p><strong>Fixed:</strong></p>
<ul>
<li>Stations with suffixes like “-2” and “-70” were not being marked as worked → now ignored, station is correctly marked.</li>
</ul>
<hr>
<h2 id="v1.24-(2024-11)" tabindex="-1"><a class="header-anchor" href="#v1.24-(2024-11)">v1.24 (2024-11)</a></h2>
<p><strong>Wishlist + DX Cluster Spots</strong></p>
<p><strong>New:</strong></p>
<ul>
<li>Button to open the <strong><a href="http://QRZ.com">QRZ.com</a> profile</strong> of the selected station.</li>
<li>Button to open the <strong>QRZ-CQ profile</strong> of the selected station.</li>
<li><strong>DX Cluster Server integration</strong>: Direction warnings are sent as spots to the logging software (when QRG is known).</li>
</ul>
<p><em>(Coloured PM row feature also added tnx Gianluca)</em></p>
<hr>
<h2 id="v1.23-(2024-10)" tabindex="-1"><a class="header-anchor" href="#v1.23-(2024-10)">v1.23 (2024-10)</a></h2>
<p><strong>Built-in DX Cluster Server</strong></p>
<p><strong>New:</strong></p>
<ul>
<li>KST4Contest now contains a <strong>built-in DX cluster server</strong>.</li>
<li>Generates DX cluster spots and sends them to the logging software when a direction warning is triggered and a QRG is known.</li>
<li>Spotter callsign must differ from the contest callsign (for correct filtering in the logging software).</li>
</ul>
<p><em>(Idea by OM0AAO, Viliam Petrik thank you!)</em></p>
<hr>
<h2 id="v1.22-(2024-05)" tabindex="-1"><a class="header-anchor" href="#v1.22-(2024-05)">v1.22 (2024-05)</a></h2>
<p><strong>Usability Improvements and AirScout Button Fix</strong></p>
<p><strong>New:</strong></p>
<ul>
<li>New variables (tnx OM0AAO, Viliam Petrik):
<ul>
<li><code>MYLOCATORSHORT</code></li>
<li><code>MYQRGSHORT</code></li>
<li><code>QRZNAME</code></li>
</ul>
</li>
</ul>
<p><strong>Changed:</strong></p>
<ul>
<li>Send field focus: After clicking a callsign in the user list, the send field immediately receives focus no double-click needed <em>(tnx Gianluca)</em>.</li>
</ul>
<p><strong>Fixed:</strong></p>
<ul>
<li>Worked-station filter is now live: Worked stations disappear immediately when the filter is activated <em>(tnx Gianluca)</em>.</li>
<li>QRB sorting was lexicographic → now numeric <em>(tnx Alessandro Murador)</em>.</li>
<li>AirScout “Show Path” button: Click now maximises AirScout and correctly shows the path.</li>
</ul>
<hr>
<h2 id="v1.21-(2024-04)" tabindex="-1"><a class="header-anchor" href="#v1.21-(2024-04)">v1.21 (2024-04)</a></h2>
<p><strong>Usability Improvements</strong></p>
<p><strong>Changed:</strong></p>
<ul>
<li>Window sizes and divider positions are saved in the configuration file when clicking “Save Settings” and restored on startup.</li>
<li>Filter section as flowpane → better display on smaller screens.</li>
</ul>
<hr>
<h2 id="v1.2-(2024-04)" tabindex="-1"><a class="header-anchor" href="#v1.2-(2024-04)">v1.2 (2024-04)</a></h2>
<p><strong>Band Selection and NOT-QRV Tags</strong></p>
<p><strong>New:</strong></p>
<ul>
<li><strong>Band selection</strong>: Selectable in Preferences which bands are active. Only buttons and fields for selected bands appear in the UI. Save and restart required.</li>
<li><strong>NOT-QRV tags per station and band</strong>: Stations can be marked as “not QRV” for each band. Combinable with the user list filter.</li>
<li><strong>QTF arrow</strong>: The “Show path in AS” button now shows an arrow with the QTF of the selected station.</li>
</ul>
<hr>
<h2 id="earlier-versions" tabindex="-1"><a class="header-anchor" href="#earlier-versions">Earlier Versions</a></h2>
<h3 id="v1.1" tabindex="-1"><a class="header-anchor" href="#v1.1">v1.1</a></h3>
<p>First publicly released version. Core features:</p>
<ul>
<li>Worked marking via Simplelogfile and UDP</li>
<li>Sked direction highlighting</li>
<li>QRG detection</li>
<li>Text snippets and shortcuts</li>
<li>AirScout interface (first version)</li>
<li>Interval beacon</li>
<li>PM catching for public messages containing your own callsign</li>
<li>Update notification service</li>
</ul>
<hr>
<h2 id="planned-features" tabindex="-1"><a class="header-anchor" href="#planned-features">Planned Features</a></h2>
<ul>
<li><code>MYQTF</code> variable (own antenna direction as text)</li>
<li><s>Lifetime for worked status (automatic reset)</s><strong>Implemented in v1.40</strong> (3-day lifetime, no manual reset needed anymore)</li>
<li>Filtering the “Cluster &amp; QSO of others” window to own QTF</li>
<li>Further topography-based calculations for direction warnings</li>
</ul>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
@@ -0,0 +1,253 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ manual.title }} | KST4Contest Manual</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest manual page: {{ manual.title }}">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/manual/en/configuration/">
<meta property="og:type" content="website">
<meta property="og:title" content="{{ manual.title }} | KST4Contest Manual">
<meta property="og:description" content="KST4Contest manual page: {{ manual.title }}">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/manual/en/configuration/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="section">
<div class="card manual-content">
<p><a href="/manual/en/">← Back to manual overview</a></p>
<h1>Configuration</h1>
<h1 id="configuration" tabindex="-1"><a class="header-anchor" href="#configuration">Configuration</a></h1>
<blockquote>
<p>🇬🇧 You are reading the English version | 🇩🇪 <a href="/manual/de/konfiguration/">Deutsche Version</a></p>
</blockquote>
<p>After the first start, the <strong>settings window</strong> opens this is the central starting point for all configuration. It is recommended to keep the settings window open during operation (e.g. to quickly toggle the beacon on and off).</p>
<blockquote>
<p><strong>Important</strong>: Always click <strong>“Save Settings”</strong> after any change! Settings are stored in <code>~/.praktikst/preferences.xml</code> on Linux and in <code>%USERPROFILE%\.praktikst\preferences.xml</code> (or <code>C:\Users\&lt;Username&gt;\.praktikst\preferences.xml</code>) on Windows. From v1.21 onwards, window sizes and divider positions are also saved when you click Save.</p>
</blockquote>
<hr>
<h2 id="station-settings" tabindex="-1"><a class="header-anchor" href="#station-settings">Station Settings</a></h2>
<p><img src="/manual/assets/client_settings_window_station.png" alt="Station Settings"></p>
<h3 id="login-and-chat-categories" tabindex="-1"><a class="header-anchor" href="#login-and-chat-categories">Login and Chat Categories</a></h3>
<p>Enter your ON4KST chat credentials here (callsign and password).
Also, select the <strong>primary chat category</strong> (e.g., IARU Region 1 VHF/Microwave).</p>
<p>With the option for a <strong>second chat</strong> (Multi-Channel Login), you can log in to another category simultaneously (e.g., UHF/SHF). Both chats will then be monitored in parallel. You can optionally specify a different login name for the second chat (useful for Opposite Station Multi-Callsign Logging).</p>
<h3 id="callsign-and-locator" tabindex="-1"><a class="header-anchor" href="#callsign-and-locator">Callsign and Locator</a></h3>
<p>Enter your own callsign and Maidenhead locator (6 characters, e.g., <code>JN49IJ</code>). These values are needed for distance and direction calculations.</p>
<h3 id="active-bands" tabindex="-1"><a class="header-anchor" href="#active-bands">Active Bands</a></h3>
<p>Use the <strong>“my station uses band”</strong> checkboxes to select the active bands. Buttons and table rows will only appear in the user interface for selected bands. The software must be restarted after making changes.</p>
<h3 id="antenna-beamwidth" tabindex="-1"><a class="header-anchor" href="#antenna-beamwidth">Antenna Beamwidth</a></h3>
<p>Enter a realistic value for your antennas beamwidth (in degrees). This value is used for the <a href="Features#sked-direction-highlighting">Sked Direction Highlighting</a>. A test value of 50° has proven effective; DM5M uses quads with 69°.</p>
<blockquote>
<p><strong>Do not</strong> enter fantasy values the direction calculations will become useless.</p>
</blockquote>
<h3 id="default-maximum-qrb" tabindex="-1"><a class="header-anchor" href="#default-maximum-qrb">Default Maximum QRB</a></h3>
<p>Maximum distance (in km) for which direction warnings should be triggered. A realistic value for DM5M is 900 km. Stations farther away are ignored for highlighting purposes.</p>
<hr>
<h2 id="server-settings-(from-v1.31)" tabindex="-1"><a class="header-anchor" href="#server-settings-(from-v1.31)">Server Settings (from v1.31)</a></h2>
<p>The chat server DNS and port are configurable in the Preferences:</p>
<ul>
<li><strong>Server DNS</strong>: Default <code>www.on4kst.org</code> (changed from <code>www.on4kst.info</code> in v1.31 hotfix).</li>
<li><strong>Port</strong>: Default port of the ON4KST server.</li>
</ul>
<p>A change is only needed if the server moves or an alternative endpoint is used.</p>
<hr>
<h2 id="log-sync-settings" tabindex="-1"><a class="header-anchor" href="#log-sync-settings">Log Sync Settings</a></h2>
<p>Three methods are available for automatically marking worked stations. Details: <a href="/manual/en/log-sync/">Log Synchronisation</a>.</p>
<h3 id="universal-file-based-callsign-interpreter-(simplelogfile)" tabindex="-1"><a class="header-anchor" href="#universal-file-based-callsign-interpreter-(simplelogfile)">Universal File Based Callsign Interpreter (Simplelogfile)</a></h3>
<p>Interprets any log file using regex for callsign patterns. No band information is available. Suitable as a fallback or for log programs that are not directly supported.</p>
<h3 id="network-listener-for-logger%E2%80%99s-qso-udp-broadcast" tabindex="-1"><a class="header-anchor" href="#network-listener-for-logger%E2%80%99s-qso-udp-broadcast">Network Listener for Loggers QSO UDP Broadcast</a></h3>
<p><strong>Recommended method.</strong> KST4Contest listens for UDP packets sent by the logging software to the broadcast address when a QSO is saved. Stations are marked with band information. UDP port: default <strong>12060</strong>. (Used by UCXLog, N1MM+, QARTest, <a href="http://DXLog.net">DXLog.net</a>, etc.).</p>
<h3 id="win-test-network-listener-(additional-udp-listener)" tabindex="-1"><a class="header-anchor" href="#win-test-network-listener-(additional-udp-listener)">Win-Test Network Listener (Additional UDP Listener)</a></h3>
<p>A dedicated network listener for Win-Test. KST4Contest receives and processes Win-Test-specific UDP packets (including sked handovers) on the configured port.</p>
<hr>
<h2 id="trx-sync-settings" tabindex="-1"><a class="header-anchor" href="#trx-sync-settings">TRX Sync Settings</a></h2>
<p>Receives the current transceiver frequency from the logging software via UDP. This enables the automatic population of the <code>MYQRG</code> variable. Useful for:</p>
<ul>
<li>Quickly inserting your own QRG into chat messages.</li>
<li>Automatic CQ beacon with current frequency.</li>
</ul>
<blockquote>
<p><strong>Note for multi-setup</strong>: When running two logging programs on two computers but only one KST4Contest instance, only one logging program should send frequency packets. KST4Contest cannot distinguish between sources.</p>
</blockquote>
<hr>
<h2 id="airscout-settings" tabindex="-1"><a class="header-anchor" href="#airscout-settings">AirScout Settings</a></h2>
<p>Configuration of the interface to AirScout for aircraft scatter detection. Details: <a href="/manual/en/airscout-integration/">AirScout Integration</a>.</p>
<hr>
<h2 id="notification-settings" tabindex="-1"><a class="header-anchor" href="#notification-settings">Notification Settings</a></h2>
<p>Three notification types are available:</p>
<ol>
<li><strong>Simple sounds</strong>: TADA sound for incoming messages, tick for sked direction detection, etc.</li>
<li><strong>CW announcement</strong>: The callsign of a station sending a private message is output as a CW signal.</li>
<li><strong>Phonetic announcement</strong>: The callsign is pronounced phonetically.</li>
</ol>
<hr>
<h2 id="shortcut-settings" tabindex="-1"><a class="header-anchor" href="#shortcut-settings">Shortcut Settings</a></h2>
<p>Configuration of quick-access buttons that appear directly in the main window. Clicking a button inserts the configured text into the send field. All <a href="Macros-and-Variables#variables">variables</a> can be used.</p>
<hr>
<h2 id="snippet-settings" tabindex="-1"><a class="header-anchor" href="#snippet-settings">Snippet Settings</a></h2>
<p>Text snippets are accessible via:</p>
<ul>
<li><strong>Right-click</strong> on a callsign in the user list</li>
<li><strong>Right-click</strong> in the CQ message table</li>
<li><strong>Right-click</strong> in the PM message table</li>
<li><strong>Keyboard shortcuts</strong>: <code>Ctrl+1</code> to <code>Ctrl+0</code> for the first 10 snippets</li>
</ul>
<p>If a callsign is selected in the user list, the snippet is addressed as a direct message:
<code>/CQ CALLSIGN &lt;snippet text&gt;</code></p>
<hr>
<h2 id="beacon-settings" tabindex="-1"><a class="header-anchor" href="#beacon-settings">Beacon Settings</a></h2>
<p>Configuration of an automatic interval beacon in the public chat channel. Recommended: use the <code>MYQRG</code> variable in the text so the current frequency is always up to date. Interval and text are freely configurable.</p>
<blockquote>
<p><strong>Tip</strong>: Enable the beacon when calling CQ and quickly disable it in the settings window when not calling.</p>
</blockquote>
<hr>
<h2 id="messagehandling-settings-(from-v1.25)" tabindex="-1"><a class="header-anchor" href="#messagehandling-settings-(from-v1.25)">Messagehandling Settings (from v1.25)</a></h2>
<p>New settings section with the following options:</p>
<ul>
<li><strong>Auto-reply to all incoming messages</strong>: Configurable automatic reply to private messages.</li>
<li><strong>Auto-reply with own CQ QRG</strong>: When someone asks for your QRG, KST4Contest automatically replies with the content of the <code>MYQRG</code> variable.</li>
<li><strong>Default filter for the userinfo window</strong>: Pre-configured message filter for the station info window <em>(for Gianluca :-) )</em>.</li>
</ul>
<hr>
<h2 id="win-test-network-listener-(from-v1.31)" tabindex="-1"><a class="header-anchor" href="#win-test-network-listener-(from-v1.31)">Win-Test Network Listener (from v1.31)</a></h2>
<p>A dedicated listener for Win-Test-specific UDP packets. Enables:</p>
<ul>
<li><strong>Log synchronisation</strong>: Worked stations are retrieved from Win-Test and marked in the user list.</li>
<li><strong>Frequency parsing</strong>: The current TRX frequency from Win-Test populates the <code>MYQRG</code> variable.</li>
<li><strong>Sked handover (SKED push)</strong>: Skeds from KST4Contest are passed directly to Win-Test via UDP. Win-Tests default UDP broadcast port (9871) is used.</li>
</ul>
<p>Settings:</p>
<ul>
<li><strong>Enable/Disable</strong>: Checkbox in Preferences (from v1.40).</li>
<li><strong>Port</strong>: Configurable UDP port for the Win-Test listener.</li>
<li><strong>Sked UDP address and port</strong>: Target address and port for SKED handover to Win-Test.</li>
</ul>
<blockquote>
<p><strong>Note</strong>: The Win-Test listener is an <strong>additional</strong> listener the standard QSO UDP broadcast listener on port 12060 remains independent.</p>
</blockquote>
<hr>
<h2 id="pstrotator-settings-(from-v1.31)" tabindex="-1"><a class="header-anchor" href="#pstrotator-settings-(from-v1.31)">PSTRotator Settings (from v1.31)</a></h2>
<p>KST4Contest can control antenna direction via PSTRotator.</p>
<p>Settings:</p>
<ul>
<li><strong>Enable/Disable</strong>: Checkbox in Preferences (from v1.40).</li>
<li><strong>IP address</strong>: IP address of the PSTRotator computer (default: <code>127.0.0.1</code> when running on the same PC).</li>
<li><strong>Port</strong>: Communication port of PSTRotator.</li>
</ul>
<blockquote>
<p><strong>Note</strong>: After clicking a direction button, KST4Contest waits briefly for the rotator response. With slow rotors (e.g. SPID) there may be a small delay.</p>
</blockquote>
<hr>
<h2 id="sniffer-settings-(from-v1.31)" tabindex="-1"><a class="header-anchor" href="#sniffer-settings-(from-v1.31)">Sniffer Settings (from v1.31)</a></h2>
<p>The QSO sniffer filters chat messages from configurable callsigns and forwards them to the PM window.</p>
<p>Settings:</p>
<ul>
<li><strong>Callsign list</strong>: Comma-separated list of callsigns whose messages are always forwarded to the PM window.</li>
</ul>
<p>Use case: Keep track of important stations (e.g. DX expeditions or trusted contest allies) without constantly monitoring the main chat.</p>
<hr>
<h2 id="worked-station-database-settings" tabindex="-1"><a class="header-anchor" href="#worked-station-database-settings">Worked Station Database Settings</a></h2>
<p>The internal worked database contains:</p>
<ul>
<li>Worked status of all stations (per band)</li>
<li>NOT-QRV tags (since v1.2)</li>
</ul>
<p><strong>From v1.40</strong>: Entries have an automatic lifetime of <strong>3 days</strong> manually resetting before each contest is no longer strictly necessary. For a full reset, the <strong>“Reinitialize”</strong> button is still available.</p>
<hr>
<h2 id="dark-mode-(from-v1.26)" tabindex="-1"><a class="header-anchor" href="#dark-mode-(from-v1.26)">Dark Mode (from v1.26)</a></h2>
<p>Toggle via the menu: <strong>Window → Use Dark Mode</strong>. The colors can be individually customized via CSS.</p>
<hr>
<h2 id="saving-settings" tabindex="-1"><a class="header-anchor" href="#saving-settings">Saving Settings</a></h2>
<p>Click <strong>“Save Settings”</strong> after <strong>every</strong> change! Without saving, all changes will be lost on the next start.</p>
<ul>
<li>Storage location: <code>~/.praktikst/preferences.xml</code> on Linux and <code>%USERPROFILE%\.praktikst\preferences.xml</code> (or <code>C:\Users\&lt;Username&gt;\.praktikst\preferences.xml</code>) on Windows</li>
<li>From v1.21: Window sizes and divider positions are also saved.</li>
<li>If you encounter problems: delete the configuration file → KST4Contest will create a new one with default values.</li>
</ul>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
@@ -0,0 +1,173 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ manual.title }} | KST4Contest Manual</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest manual page: {{ manual.title }}">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/manual/en/dx-cluster-server/">
<meta property="og:type" content="website">
<meta property="og:title" content="{{ manual.title }} | KST4Contest Manual">
<meta property="og:description" content="KST4Contest manual page: {{ manual.title }}">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/manual/en/dx-cluster-server/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="section">
<div class="card manual-content">
<p><a href="/manual/en/">← Back to manual overview</a></p>
<h1>Built-in DX Cluster Server</h1>
<h1 id="built-in-dx-cluster-server" tabindex="-1"><a class="header-anchor" href="#built-in-dx-cluster-server">Built-in DX Cluster Server</a></h1>
<blockquote>
<p>🇬🇧 You are reading the English version | 🇩🇪 <a href="/manual/de/dx-cluster-server/">Deutsche Version</a></p>
</blockquote>
<p>From <strong>version 1.23</strong>, KST4Contest includes a built-in DX cluster server. It sends spots directly to the logging software whenever a direction warning is triggered.</p>
<p><em>(Idea by OM0AAO, Viliam Petrik thank you!)</em></p>
<hr>
<h2 id="what-is-the-built-in-dx-cluster-server-for%3F" tabindex="-1"><a class="header-anchor" href="#what-is-the-built-in-dx-cluster-server-for%3F">What is the Built-in DX Cluster Server For?</a></h2>
<p>When KST4Contest detects that a station is requesting a sked from your direction and a QRG is known, it <strong>automatically generates a DX cluster spot</strong> and feeds it directly to the logging softwares cluster client / band map.</p>
<p>The logging software then displays the spot in the band map. Clicking the spot sets the transceivers frequency and mode directly without any manual typing.</p>
<hr>
<h2 id="setup" tabindex="-1"><a class="header-anchor" href="#setup">Setup</a></h2>
<h3 id="in-kst4contest" tabindex="-1"><a class="header-anchor" href="#in-kst4contest">In KST4Contest</a></h3>
<p>In Preferences → <strong>DX Cluster Server Settings</strong>:</p>
<ol>
<li>Enter the <strong>port</strong> of the internal server (e.g. 7300 or 8000 must match the logging software).</li>
<li>Enter a <strong>spotter callsign</strong> <strong>this must be a different callsign than your contest callsign!</strong>
<ul>
<li>Reason: Logging programs filter spots from your own callsign as “already worked”. If the spotter uses the same callsign, the spots will not be displayed.</li>
</ul>
</li>
<li>Enter the <strong>assumed MHz</strong>: For frequency references like “.205” in the chat, KST4Contest needs to decide whether 144.205, 432.205 or 1296.205 is meant. For single-band contests, simply enter the corresponding band centre. Full frequency references like “144.205” or “1296.338” in the chat are always correctly identified.</li>
</ol>
<h3 id="in-ucxlog" tabindex="-1"><a class="header-anchor" href="#in-ucxlog">In UCXLog</a></h3>
<ul>
<li>Configure a DX cluster server connection:
<ul>
<li>Host: <code>127.0.0.1</code> (or IP of the KST4Contest computer)</li>
<li>Port: As configured in KST4Contest</li>
<li>Password: can be left empty</li>
</ul>
</li>
<li>Use the <strong>“Send a test message to your log”</strong> button to test the connection.</li>
</ul>
<h3 id="in-n1mm%2B" tabindex="-1"><a class="header-anchor" href="#in-n1mm%2B">In N1MM+</a></h3>
<p>Similar settings:</p>
<ul>
<li>Host: <code>127.0.0.1</code> (or IP of the KST4Contest computer)</li>
<li>Port: As configured in KST4Contest</li>
</ul>
<hr>
<h2 id="how-it-works" tabindex="-1"><a class="header-anchor" href="#how-it-works">How It Works</a></h2>
<p>A spot is generated when <strong>both</strong> conditions are met:</p>
<ol>
<li>A <strong>direction warning</strong> has been triggered (station is making a sked in your direction).</li>
<li>The <strong>stations QRG is known</strong> (read from the chat or manually entered).</li>
</ol>
<p>The generated spot contains:</p>
<ul>
<li>Stations callsign</li>
<li>Frequency</li>
<li>Spot time</li>
</ul>
<p>The logging software can then display the spot in the band map and tune the TRX to that frequency with a mouse click.</p>
<hr>
<h2 id="multi-computer-setup" tabindex="-1"><a class="header-anchor" href="#multi-computer-setup">Multi-Computer Setup</a></h2>
<p>If KST4Contest runs on a separate computer (not the logging computer):</p>
<ul>
<li>Host in the logging software: IP of the KST4Contest computer (not <code>127.0.0.1</code>)</li>
<li>Same configuration as for the QSO UDP broadcast packets (see <a href="/manual/en/log-sync/">Log Synchronisation</a>)</li>
</ul>
<hr>
<h2 id="tested-logging-software" tabindex="-1"><a class="header-anchor" href="#tested-logging-software">Tested Logging Software</a></h2>
<ul>
<li><strong>UCXLog</strong></li>
<li><strong>N1MM+</strong></li>
</ul>
<p>Further test reports are welcome please send by email to DO5AMF.</p>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
+294
View File
@@ -0,0 +1,294 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ manual.title }} | KST4Contest Manual</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest manual page: {{ manual.title }}">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/manual/en/features/">
<meta property="og:type" content="website">
<meta property="og:title" content="{{ manual.title }} | KST4Contest Manual">
<meta property="og:description" content="KST4Contest manual page: {{ manual.title }}">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/manual/en/features/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="section">
<div class="card manual-content">
<p><a href="/manual/en/">← Back to manual overview</a></p>
<h1>Features</h1>
<h1 id="features" tabindex="-1"><a class="header-anchor" href="#features">Features</a></h1>
<blockquote>
<p>🇬🇧 You are reading the English version | 🇩🇪 <a href="/manual/de/funktionen/">Deutsche Version</a></p>
</blockquote>
<p>Overview of all main features of KST4Contest.</p>
<hr>
<h2 id="sked-direction-highlighting" tabindex="-1"><a class="header-anchor" href="#sked-direction-highlighting">Sked Direction Highlighting</a></h2>
<p>One of the core features: when a station makes a sked request <strong>towards your direction</strong>, it is highlighted <strong>green and bold</strong> in the user list.</p>
<h3 id="how-does-it-work%3F" tabindex="-1"><a class="header-anchor" href="#how-does-it-work%3F">How does it work?</a></h3>
<p>The calculation is based on the following logic:</p>
<ul>
<li>When station A sends a sked request to station B, it is assumed that A is pointing its antenna towards B.</li>
<li>If the resulting direction from A to your own station is within half the beamwidth of your own antenna, A is highlighted.</li>
</ul>
<p><strong>Example</strong> (beamwidth 69°, half-angle 34.5°):</p>
<table>
<thead>
<tr>
<th>Situation</th>
<th>Result for DO5AMF in JN49</th>
</tr>
</thead>
<tbody>
<tr>
<td>Sked from F5FEN → DM5M</td>
<td>✅ Highlighted (F5FEN points towards DM5M, close to JN49)</td>
</tr>
<tr>
<td>Sked from DM5M → F5FEN</td>
<td>✅ Highlighted (DM5M replies towards F5FEN)</td>
</tr>
<tr>
<td>F1DBN is uninvolved</td>
<td>❌ No highlighting</td>
</tr>
<tr>
<td>DO5AMF/P (different location)</td>
<td>❌ No highlighting for sked reply</td>
</tr>
</tbody>
</table>
<p>The calculation does not include topographic path calculations this is a deliberate simplification. It may be added in a future version.</p>
<blockquote>
<p>Configuration: <a href="Configuration#antenna-beamwidth">Configuration Antenna Beamwidth</a></p>
</blockquote>
<hr>
<h2 id="sked-direction-spots-(built-in-dx-cluster)" tabindex="-1"><a class="header-anchor" href="#sked-direction-spots-(built-in-dx-cluster)">Sked Direction Spots (Built-in DX Cluster)</a></h2>
<p>From <strong>v1.23</strong>: Direction warnings are forwarded as DX cluster spots to the logging software when a QRG is known. Details: <a href="/manual/en/dx-cluster-server/">DX Cluster Server</a>.</p>
<hr>
<h2 id="qrg-detection-(qrg-reading)" tabindex="-1"><a class="header-anchor" href="#qrg-detection-(qrg-reading)">QRG Detection (QRG Reading)</a></h2>
<p>KST4Contest processes every line of text flowing through the channel and automatically extracts <strong>frequency references</strong>. These are displayed in the user list in the <strong>QRG column</strong>.</p>
<p>Recognised formats: <code>144.205</code>, <code>432.088</code>, <code>.205</code> (with configured band assumption), etc.</p>
<p><strong>Benefit</strong>: Without asking, you can directly look up a stations calling frequency and decide whether a contact is possible.</p>
<hr>
<h2 id="worked-marking" tabindex="-1"><a class="header-anchor" href="#worked-marking">Worked Marking</a></h2>
<p>Worked stations are visually marked in the user list per band. Based on <a href="/manual/en/log-sync/">Log Synchronisation</a> via UDP or Simplelogfile.</p>
<p>Reset the database before each contest: <a href="Configuration#worked-station-database-settings">Configuration Worked Station Database Settings</a>.</p>
<hr>
<h2 id="not-qrv-tags-(from-v1.2)" tabindex="-1"><a class="header-anchor" href="#not-qrv-tags-(from-v1.2)">NOT-QRV Tags (from v1.2)</a></h2>
<p>When a station indicates it is not QRV on a specific band, this can be manually marked:</p>
<ol>
<li>Select the station in the user list.</li>
<li>Right-click → Set NOT-QRV for the appropriate band.</li>
</ol>
<p>These tags are stored in the internal database and persist after a KST4Contest restart. Can be reset via the settings.</p>
<p><strong>Benefit</strong>: Prevents repeated sked requests on bands where the station is not active saves time for both sides.</p>
<hr>
<h2 id="direction-filter" tabindex="-1"><a class="header-anchor" href="#direction-filter">Direction Filter</a></h2>
<p>Shows only stations in the user list that are located in a specific direction. Toggle using the N / NE / E / SE / S / SW / W / NW buttons or by entering degrees manually.</p>
<p>Useful: While calling CQ in a specific direction, only show stations in that direction.</p>
<hr>
<h2 id="distance-filter" tabindex="-1"><a class="header-anchor" href="#distance-filter">Distance Filter</a></h2>
<p>Hide stations beyond a maximum distance. The <strong>“Show only QRB [km] &lt;=”</strong> button is a toggle.</p>
<hr>
<h2 id="worked-and-not-qrv-filter" tabindex="-1"><a class="header-anchor" href="#worked-and-not-qrv-filter">Worked and NOT-QRV Filter</a></h2>
<p>Toggle buttons (one per band) to hide already-worked stations and/or NOT-QRV-tagged stations. The filter takes effect <strong>immediately</strong> without manually reactivating (live since v1.22).</p>
<hr>
<h2 id="coloured-pm-rows-(from-v1.25)" tabindex="-1"><a class="header-anchor" href="#coloured-pm-rows-(from-v1.25)">Coloured PM Rows (from v1.25)</a></h2>
<p>New private messages appear in <strong>red</strong>. The colour fades every 30 seconds from yellow to white like a rainbow fade. This makes it immediately clear how recent a message is.</p>
<p><em>(Idea by IU3OAR, Gianluca Costantino thank you!)</em></p>
<hr>
<h2 id="pm-catching" tabindex="-1"><a class="header-anchor" href="#pm-catching">PM Catching</a></h2>
<p>Some users accidentally post direct messages publicly, e.g.:</p>
<pre><code>(DM5M) pse ur qrg
</code></pre>
<p>KST4Contest detects such messages that contain your own callsign and automatically sorts them into the <strong>private messages table</strong>. No messages are missed this way.</p>
<hr>
<h2 id="multi-channel-login-(from-v1.26)" tabindex="-1"><a class="header-anchor" href="#multi-channel-login-(from-v1.26)">Multi-Channel Login (from v1.26)</a></h2>
<p>Simultaneous login to <strong>two chat categories</strong> (e.g. 144 MHz and 432 MHz). Both chats are monitored in parallel.</p>
<hr>
<h2 id="dark-mode-(from-v1.26)" tabindex="-1"><a class="header-anchor" href="#dark-mode-(from-v1.26)">Dark Mode (from v1.26)</a></h2>
<p>Toggle via: <strong>Window → Use Dark Mode</strong></p>
<p>For individual colour adjustments: edit the CSS file (path in the program settings).</p>
<hr>
<h2 id="opposite-station-multi-callsign-login-tagging-(from-v1.26)" tabindex="-1"><a class="header-anchor" href="#opposite-station-multi-callsign-login-tagging-(from-v1.26)">Opposite Station Multi-Callsign Login Tagging (from v1.26)</a></h2>
<p>Support for stations that are active in the chat with multiple callsigns simultaneously (e.g. expedition setups).</p>
<hr>
<h2 id="qrz.com-and-qrz-cq-profile-buttons-(from-v1.24)" tabindex="-1"><a class="header-anchor" href="#qrz.com-and-qrz-cq-profile-buttons-(from-v1.24)"><a href="http://QRZ.com">QRZ.com</a> and QRZ-CQ Profile Buttons (from v1.24)</a></h2>
<p>For selected stations in the user list, there are direct buttons to open the <strong><a href="http://QRZ.com">QRZ.com</a> profile</strong> and the <strong>QRZ-CQ profile</strong> in the browser.</p>
<hr>
<h2 id="sked-reminders-with-alert-(from-v1.40)" tabindex="-1"><a class="header-anchor" href="#sked-reminders-with-alert-(from-v1.40)">Sked Reminders with ALERT (from v1.40)</a></h2>
<p>A sked reminder service with automatic messages can be activated for each chat member. Configurable interval patterns:</p>
<ul>
<li><strong>2+1 minutes</strong>: Messages at 2 min and 1 min before the sked.</li>
<li><strong>5+2+1 minutes</strong>: Messages at 5, 2 and 1 min before the sked.</li>
<li><strong>10+5+2+1 minutes</strong>: Messages at 10, 5, 2 and 1 min before the sked.</li>
</ul>
<p>In addition to the automated messages to the remote station, there is an <strong>acoustic and visual notification</strong> for your own operator so no sked is ever missed.</p>
<p>Activate from the FurtherInfo panel of the corresponding station.</p>
<hr>
<h2 id="qso-sniffer-(from-v1.31)" tabindex="-1"><a class="header-anchor" href="#qso-sniffer-(from-v1.31)">QSO Sniffer (from v1.31)</a></h2>
<p>The QSO sniffer monitors the chat for messages from a configurable callsign list and automatically forwards them to the <strong>PM window</strong>. This prevents relevant messages from being lost in the general chat traffic.</p>
<p>Configuration: <a href="en-Configuration#sniffer-settings-from-v131">Configuration Sniffer Settings</a></p>
<hr>
<h2 id="win-test-integration-(from-v1.31%2C-fully-configurable-from-v1.40)" tabindex="-1"><a class="header-anchor" href="#win-test-integration-(from-v1.31%2C-fully-configurable-from-v1.40)">Win-Test Integration (from v1.31, fully configurable from v1.40)</a></h2>
<p>KST4Contest fully supports <a href="https://www.win-test.com/">Win-Test</a> as a logging programme:</p>
<ul>
<li><strong>Log synchronisation</strong>: Worked stations are automatically retrieved from Win-Test and marked in the user list.</li>
<li><strong>Frequency parsing</strong>: The current TRX frequency is read from Win-Test UDP packets and populates the <code>MYQRG</code> variable.</li>
<li><strong>Sked handover (SKED push via UDP)</strong>: Agreed skeds from KST4Contest can be pushed directly to Win-Test, so the remote callsign appears in Win-Tests sked window.</li>
</ul>
<p>Details: <a href="en-Configuration#win-test-network-listener">Configuration Win-Test Network Listener</a></p>
<hr>
<h2 id="pstrotator-interface-(from-v1.31%2C-fully-configurable-from-v1.40)" tabindex="-1"><a class="header-anchor" href="#pstrotator-interface-(from-v1.31%2C-fully-configurable-from-v1.40)">PSTRotator Interface (from v1.31, fully configurable from v1.40)</a></h2>
<p>KST4Contest can control antenna direction directly via <strong>PSTRotator</strong>. When a station is selected in the user list, the rotator can automatically be turned to the QTF of the selected station.</p>
<p>Configuration: <a href="en-Configuration#pstrotator-settings-from-v131">Configuration PSTRotator Settings</a></p>
<hr>
<h2 id="band-alert-for-new-qsos-(from-v1.40)" tabindex="-1"><a class="header-anchor" href="#band-alert-for-new-qsos-(from-v1.40)">Band Alert for New QSOs (from v1.40)</a></h2>
<p>When a station is logged, KST4Contest automatically checks whether that station has shown any other active bands in the chat that you are also QRV on. If so, a <strong>hint alert</strong> appears so no multi-band opportunity is missed.</p>
<hr>
<h2 id="worked-tag-lifetime-(from-v1.40)" tabindex="-1"><a class="header-anchor" href="#worked-tag-lifetime-(from-v1.40)">Worked Tag Lifetime (from v1.40)</a></h2>
<p>Worked stations are automatically removed from the database after <strong>3 days</strong>. Manually resetting the worked database before each contest is therefore no longer strictly necessary the database keeps itself up to date.</p>
<hr>
<h2 id="chatmember-score-system-%2F-priority-list-(from-v1.40)" tabindex="-1"><a class="header-anchor" href="#chatmember-score-system-%2F-priority-list-(from-v1.40)">Chatmember Score System / Priority List (from v1.40)</a></h2>
<p>KST4Contest automatically calculates a <strong>priority score</strong> for each active chat member. The score is derived from:</p>
<ul>
<li>Antenna direction of the remote station (is it pointing towards me?)</li>
<li>QRB (distance)</li>
<li>Activity time and message count</li>
<li>Active bands and frequencies</li>
<li>AP availability (AirScout)</li>
<li>Sked direction (degrees)</li>
<li>Sked success rate and skedfail markings</li>
</ul>
<p>The top candidates are highlighted in a dedicated priority list, helping you not to miss the most important contacts during contest stress.</p>
<p>Stations with a failed sked can be marked using the <strong>Skedfail button</strong> in the FurtherInfo panel this temporarily lowers their score.</p>
<hr>
<h2 id="ap-timeline-(from-v1.40)" tabindex="-1"><a class="header-anchor" href="#ap-timeline-(from-v1.40)">AP Timeline (from v1.40)</a></h2>
<p>A visual timeline shows up to 4 highly-scored stations per minute slot that should be workable via aircraft scatter. Prioritisation criteria:</p>
<ul>
<li><strong>Highest reflection potential</strong> is preferred (not necessarily the fastest arrival).</li>
<li>Stations towards which your antenna is not pointing are shown <strong>transparently</strong>.</li>
</ul>
<p>This gives the contest operator a quick overview of which stations will be reachable via which aircraft and at what time.</p>
<hr>
<h2 id="interval-beacon" tabindex="-1"><a class="header-anchor" href="#interval-beacon">Interval Beacon</a></h2>
<p>Automatic CQ messages in the public channel at a configurable interval. Recommended: use the <code>MYQRG</code> variable so the current frequency is always accurate. Details: <a href="Configuration#beacon-settings">Configuration Beacon Settings</a>.</p>
<hr>
<h2 id="simplelogfile" tabindex="-1"><a class="header-anchor" href="#simplelogfile">Simplelogfile</a></h2>
<p>File-based log evaluation using regex. Details: <a href="Log-Sync#method-1-universal-file-based-callsign-interpreter-simplelogfile">Log Synchronisation</a>.</p>
<hr>
<h2 id="cluster-%26-qso-of-others" tabindex="-1"><a class="header-anchor" href="#cluster-%26-qso-of-others">Cluster &amp; QSO of Others</a></h2>
<p>A separate window showing the QSO flow between other stations. Particularly interesting during quieter night-time hours of a contest. This window can be minimised when not needed. Future plan: filtering to stations in your selected QTF.</p>
<hr>
<h2 id="station-map-(from-v1.41)" tabindex="-1"><a class="header-anchor" href="#station-map-(from-v1.41)">Station Map (from v1.41)</a></h2>
<p>An interactive OpenStreetMap-based map showing the geographic position of all active chat members.</p>
<p><strong>Features:</strong></p>
<ul>
<li>Station markers with callsign labels, coloured by activity and sked state</li>
<li>Antenna <strong>beam cone</strong> visualisation for the own station</li>
<li><strong>Connection line</strong> to the currently selected station</li>
<li><strong>Maidenhead grid</strong> overlay (QRA locator grid)</li>
<li><strong>Path profile chart</strong>: Terrain elevation cross-section between own station and the selected station, including Fresnel zone analysis and obstruction/horizon detection</li>
<li>Multiple terrain data sources: <strong>Copernicus GLO-30</strong> (high-resolution DEM), <strong>Open-Meteo API</strong>, synthetic fallback, and <strong>offline DEM import</strong> for air-gapped use</li>
<li>Aircraft scatter path analysis integrated with the terrain data</li>
</ul>
<p>The map works in packaged environments (AppImage, Flatpak) without internet access to external CDNs: map tiles are fetched via a local tile proxy, and the Leaflet.js library is bundled inside the application.</p>
<hr>
<h2 id="optimised-message-handling-%2F-30%2C000-message-limit-(from-v1.41)" tabindex="-1"><a class="header-anchor" href="#optimised-message-handling-%2F-30%2C000-message-limit-(from-v1.41)">Optimised Message Handling / 30,000 Message Limit (from v1.41)</a></h2>
<p>The internal chat and message tables are capped at <strong>30,000 entries</strong>. Older messages are automatically discarded when the limit is reached. This keeps memory usage and rendering performance stable during multi-day contest operations.</p>
<hr>
<h2 id="screen-aware-window-sizing-(from-v1.41)" tabindex="-1"><a class="header-anchor" href="#screen-aware-window-sizing-(from-v1.41)">Screen-Aware Window Sizing (from v1.41)</a></h2>
<p>On startup, KST4Contest calculates a screen-aware size for the main window:</p>
<ul>
<li>The stored window size from the previous session is used but <strong>never larger than the current screen</strong>.</li>
<li>If KST4Contest was last used on a larger monitor, the window is automatically scaled down to fit the current display without clipping.</li>
<li>The UI layout is more <strong>compact and responsive on smaller screens</strong>, showing the same information in less space.</li>
</ul>
<p>This prevents unusable oversized windows when switching between machines or monitors.</p>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
+249
View File
@@ -0,0 +1,249 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ manual.title }} | KST4Contest Manual</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest manual page: {{ manual.title }}">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/manual/en/home/">
<meta property="og:type" content="website">
<meta property="og:title" content="{{ manual.title }} | KST4Contest Manual">
<meta property="og:description" content="KST4Contest manual page: {{ manual.title }}">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/manual/en/home/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="section">
<div class="card manual-content">
<p><a href="/manual/en/">← Back to manual overview</a></p>
<h1>KST4Contest User Manual</h1>
<h1 id="kst4contest-%E2%80%93-user-manual" tabindex="-1"><a class="header-anchor" href="#kst4contest-%E2%80%93-user-manual">KST4Contest User Manual</a></h1>
<blockquote>
<p>You are reading the English version | <a href="/manual/de/home/">Deutsche Version</a></p>
</blockquote>
<p>KST4Contest is a desktop client for the <a href="https://www.on4kst.org/chat/login.php">ON4KST Chat</a>, developed for VHF, UHF and SHF contest operation. It brings chat, candidate selection, sked planning, aircraft scatter data and external station software together in a single operating interface.</p>
<p>KST4Contest is developed by <strong>DO5AMF (Marc Fröhlich)</strong>, operator at DM5M and (since May 2025) <strong>DN9APW (Philipp Wagner)</strong>. The source code is publicly available on <a href="https://github.com/praktimarc/kst4contest">GitHub</a>.</p>
<hr>
<h2 id="why-use-a-dedicated-on4kst-client%3F" tabindex="-1"><a class="header-anchor" href="#why-use-a-dedicated-on4kst-client%3F">Why use a dedicated ON4KST client?</a></h2>
<p>During a contest, the ON4KST Chat provides a considerable amount of information: active stations, locators, frequencies, sked requests and indications of current activity. The actual problem is not seeing this data. It is turning it into the next useful contact in time.</p>
<p>KST4Contest evaluates the available information, puts it into context and presents it as part of a contest-oriented workflow. This includes antenna direction, distance, known bands and frequencies, worked status, chat activity and aircraft scatter timing.</p>
<p>The program does not decide which QSO is actually possible. Priority scores, the AP timeline and visual highlights are decision aids. The final judgement remains with the operator not least because even a very convincing computer screen cannot complete a radio contact.</p>
<hr>
<h2 id="how-kst4contest-supports-contest-operation" tabindex="-1"><a class="header-anchor" href="#how-kst4contest-supports-contest-operation">How KST4Contest supports contest operation</a></h2>
<ul>
<li>
<p><strong>Observe and organise chat activity:</strong> KST4Contest can display two ON4KST chat categories at the same time. Messages, frequency information and known band activity are assigned to the corresponding stations.</p>
</li>
<li>
<p><strong>Reduce the station list:</strong> Direction, distance, worked and NOT-QRV filters help limit the user list to stations that are relevant to the current operating situation.</p>
</li>
<li>
<p><strong>Prioritise candidates:</strong> The score system evaluates active chat members using several known criteria. The currently most relevant candidates are also shown in a separate priority list.</p>
</li>
<li>
<p><strong>Prepare skeds and keep them visible:</strong> Sked reminders, automatic advance messages and the AP timeline help prevent scheduled contacts from disappearing somewhere between chat, logging and ongoing CQ operation.</p>
</li>
<li>
<p><strong>Include aircraft scatter information:</strong> The AirScout interface brings suitable aircraft and expected reflection times into candidate evaluation and sked planning.</p>
</li>
<li>
<p><strong>Connect the logger and station equipment:</strong> KST4Contest synchronises worked stations and frequency information with supported logging software. It also provides interfaces for Win-Test, PSTRotator and a built-in DX Cluster server.</p>
</li>
<li>
<p><strong>Display stations and radio paths:</strong> The station map shows active chat members, locator squares, antenna directions and the path to the selected station. A terrain profile can also be calculated for selected paths.</p>
</li>
</ul>
<p>These functions share information. A detected frequency can indicate an active band, worked status comes from the logger, aircraft scatter data adds timing information and the resulting score affects the priority list. Missing or outdated input data can therefore affect the result as well.</p>
<hr>
<h2 id="requirements" tabindex="-1"><a class="header-anchor" href="#requirements">Requirements</a></h2>
<p>A registered ON4KST account is required. Registration and login are available from the <a href="https://www.on4kst.org/chat/login.php">official ON4KST login page</a>.</p>
<p>English is the official language of the ON4KST Chat. This also applies when communicating with stations from your own country. Common amateur radio abbreviations such as <code>pse</code>, <code>agn</code>, <code>qrg</code>, <code>dir</code>, <code>rrr</code>, <code>tnx</code> and <code>73</code> are normal and usually considerably faster than carefully written prose.</p>
<p>Downloads, supported operating systems and installation methods are described in <a href="/manual/en/installation/">Installation</a>.</p>
<hr>
<h2 id="manual-version" tabindex="-1"><a class="header-anchor" href="#manual-version">Manual version</a></h2>
<p>This manual describes the stable release <strong>v1.41.1</strong>.</p>
<p>Features or changes that are only available in the current development version are explicitly marked as <strong>Nightly / v1.42</strong>. If no such label is present, the description refers to the stable release.</p>
<ul>
<li><a href="https://github.com/praktimarc/kst4contest/releases/latest">Download the current stable release</a></li>
<li><a href="https://github.com/praktimarc/kst4contest/actions">Nightly and automated builds</a></li>
<li><a href="/manual/en/changelog/">Version history</a></li>
</ul>
<p>For contest operation, the stable release is generally the appropriate choice. Nightly builds contain newer fixes and features, but may change between builds. They are useful when a particular change needs testing. Trying one for the first time ten minutes before a contest is less useful.</p>
<hr>
<h2 id="quick-navigation" tabindex="-1"><a class="header-anchor" href="#quick-navigation">Quick navigation</a></h2>
<table>
<thead>
<tr>
<th>Page</th>
<th>Contents</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="/manual/en/installation/">Installation</a></td>
<td>ON4KST account, downloads, installation and updates</td>
</tr>
<tr>
<td><a href="/manual/en/configuration/">Configuration</a></td>
<td>Login, station, bands, user interface and external connections</td>
</tr>
<tr>
<td><a href="/manual/en/log-sync/">Log Synchronisation</a></td>
<td>Simplelogfile, UCXLog, N1MM+, QARTest, <a href="http://DXLog.net">DXLog.net</a> and Win-Test</td>
</tr>
<tr>
<td><a href="/manual/en/airscout-integration/">AirScout Integration</a></td>
<td>Connecting AirScout and evaluating aircraft scatter timing</td>
</tr>
<tr>
<td><a href="/manual/en/dx-cluster-server/">DX Cluster Server</a></td>
<td>Passing detected opportunities to logging software</td>
</tr>
<tr>
<td><a href="/manual/en/features/">Features</a></td>
<td>Operation, reasoning and limitations of individual functions</td>
</tr>
<tr>
<td><a href="/manual/en/macros-and-variables/">Macros and Variables</a></td>
<td>Reusable messages, shortcuts and automatically substituted values</td>
</tr>
<tr>
<td><a href="/manual/en/user-interface/">User Interface</a></td>
<td>Interface layout and operation during a contest</td>
</tr>
<tr>
<td><a href="/manual/en/changelog/">Changelog</a></td>
<td>Releases, Nightly changes and resolved issues</td>
</tr>
</tbody>
</table>
<hr>
<h2 id="contact-and-support" tabindex="-1"><a class="header-anchor" href="#contact-and-support">Contact and support</a></h2>
<ul>
<li><strong>Download:</strong> <a href="https://github.com/praktimarc/kst4contest/releases/latest">Current stable release</a></li>
<li><strong>Source code:</strong> <a href="https://github.com/praktimarc/kst4contest">praktimarc/kst4contest</a></li>
<li><strong>Bug reports and feature requests:</strong> <a href="https://github.com/praktimarc/kst4contest/issues">GitHub Issues</a></li>
<li><strong>Email:</strong> <a href="mailto:praktimarc+kst4contest@gmail.com">praktimarc+kst4contest@gmail.com</a><br>
Please use this address only for KST4Contest-related topics.</li>
</ul>
<h3 id="reporting-a-bug" tabindex="-1"><a class="header-anchor" href="#reporting-a-bug">Reporting a bug</a></h3>
<p>A problem is considerably easier to reproduce when the report contains at least:</p>
<ol>
<li>the KST4Contest version,</li>
<li>the operating system and installation method,</li>
<li>the exact steps leading to the problem,</li>
<li>the expected and observed behaviour,</li>
<li>a screenshot where appropriate,</li>
<li>the error log file.</li>
</ol>
<p>The error log is stored at:</p>
<table>
<thead>
<tr>
<th>Operating system</th>
<th>Path</th>
</tr>
</thead>
<tbody>
<tr>
<td>Linux / macOS</td>
<td><code>~/.praktiKST/kst4contest-errors.log</code></td>
</tr>
<tr>
<td>Windows</td>
<td><code>C:\Users\&lt;YourName&gt;\.praktiKST\kst4contest-errors.log</code></td>
</tr>
</tbody>
</table>
<p>Please inspect the file briefly before uploading it. An error log mainly contains technical information, but depending on the problem it may also include local file paths or other contextual data.</p>
<p>Some file and directory names still use the technical name <code>praktiKST</code>. They refer to the same program.</p>
<hr>
<h2 id="acknowledgements" tabindex="-1"><a class="header-anchor" href="#acknowledgements">Acknowledgements</a></h2>
<p>KST4Contest has benefited considerably from feedback gathered during actual contest operation.</p>
<p>Special thanks go to Gianluca Costantino (IU3OAR), Alessandro Murador (IZ3VTH), Reczetár István (HA1FV), Viliam Petrik (OM0AAO, DX Cluster idea), Konrad Neitzel (DC9DJ, project structure), Andreas (DO5ALF, webmaster of <a href="http://funkerportal.de">funkerportal.de</a>), Franz van Velzen (PE0WGA, testing), and all other testers and contributors.</p>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
+218
View File
@@ -0,0 +1,218 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>KST4Contest English Manual</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="English user manual for KST4Contest.">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/manual/en/">
<meta property="og:type" content="website">
<meta property="og:title" content="KST4Contest English Manual">
<meta property="og:description" content="English user manual for KST4Contest.">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/manual/en/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="KST4Contest English Manual">
<meta name="twitter:description" content="English user manual for KST4Contest.">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="hero">
<h1>English Manual</h1>
<p>The manual is maintained centrally in GitHub and published as Wiki, PDF and online documentation.</p>
</section>
<section class="section">
<div class="grid">
<div class="card">
<h3><a href="/manual/en/home/">KST4Contest User Manual</a></h3>
<p>KST4Contest is a desktop client for the ON4KST Chat, developed for VHF, UHF and SHF contest operation. It brings chat, candidate selection, sked planning, aircraft scatter data and external station software together in a single operating interface.</p>
</div>
<div class="card">
<h3><a href="/manual/en/installation/">Installation</a></h3>
<p>KST4Contest is distributed as a ready-to-run application package for Windows, Linux and macOS. The official release packages do not require a separate Java installation: the required Java runtime is already included.</p>
</div>
<div class="card">
<h3><a href="/manual/en/configuration/">Configuration</a></h3>
<p>After the first start, the settings window opens this is the central starting point for all configuration. It is recommended to keep the settings window open during operation (e.g. to quickly toggle the beacon on and off).</p>
</div>
<div class="card">
<h3><a href="/manual/en/log-sync/">Log Synchronisation</a></h3>
<p>KST4Contest automatically marks worked stations in the chat user list. Two basic methods are available:</p>
</div>
<div class="card">
<h3><a href="/manual/en/airscout-integration/">AirScout Integration</a></h3>
<p>AirScout (by DL2ALF) is a program for detecting aircraft for aircraft scatter operation. KST4Contest is tightly integrated with AirScout and shows reflectable aircraft directly in the user list.</p>
</div>
<div class="card">
<h3><a href="/manual/en/dx-cluster-server/">Built-in DX Cluster Server</a></h3>
<p>From version 1.23, KST4Contest includes a built-in DX cluster server. It sends spots directly to the logging software whenever a direction warning is triggered.</p>
</div>
<div class="card">
<h3><a href="/manual/en/features/">Features</a></h3>
<p>Overview of all main features of KST4Contest.</p>
</div>
<div class="card">
<h3><a href="/manual/en/macros-and-variables/">Macros and Variables</a></h3>
<p>KST4Contest offers a flexible system of text snippets, shortcuts and built-in variables that significantly speed up the chat workflow during contests.</p>
</div>
<div class="card">
<h3><a href="/manual/en/user-interface/">User Interface</a></h3>
<p>The main window consists of several areas:</p>
</div>
<div class="card">
<h3><a href="/manual/en/changelog/">Changelog</a></h3>
<p>Version history of KST4Contest / PraktiKST.</p>
</div>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
@@ -0,0 +1,503 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ manual.title }} | KST4Contest Manual</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest manual page: {{ manual.title }}">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/manual/en/installation/">
<meta property="og:type" content="website">
<meta property="og:title" content="{{ manual.title }} | KST4Contest Manual">
<meta property="og:description" content="KST4Contest manual page: {{ manual.title }}">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/manual/en/installation/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="section">
<div class="card manual-content">
<p><a href="/manual/en/">← Back to manual overview</a></p>
<h1>Installation</h1>
<h1 id="installation" tabindex="-1"><a class="header-anchor" href="#installation">Installation</a></h1>
<blockquote>
<p>🇬🇧 You are reading the English version | 🇩🇪 <a href="/manual/de/installation/">Deutsche Version</a></p>
</blockquote>
<p>KST4Contest is distributed as a ready-to-run application package for Windows, Linux and macOS. The official release packages do not require a separate Java installation: the required Java runtime is already included.</p>
<p>In practical terms, you need a supported operating system, an internet connection and an ON4KST account. That sounds manageable—and usually it is.</p>
<h2 id="requirements" tabindex="-1"><a class="header-anchor" href="#requirements">Requirements</a></h2>
<h3 id="on4kst-account" tabindex="-1"><a class="header-anchor" href="#on4kst-account">ON4KST account</a></h3>
<p>KST4Contest is an independent client for the ON4KST chat, but it does not replace the corresponding user account.</p>
<p>If you do not have an account yet, you can create one on the official ON4KST website:</p>
<ul>
<li><a href="https://www.on4kst.org/chat/login.php">ON4KST login and registration</a></li>
</ul>
<p>ON4KST specifies English as the common language for the chat. This also applies when both stations happen to share another language. During contests, the usual amateur radio abbreviations such as <code>pse</code>, <code>agn</code>, <code>qrg</code>, <code>dir</code>, <code>rrr</code>, <code>tnx</code> and <code>73</code> are widely used.</p>
<p>Using the chat and sending personal messages are covered in the user interface chapter. For the installation, the only thing that matters at this point is that the account works.</p>
<h3 id="screen-size" tabindex="-1"><a class="header-anchor" href="#screen-size">Screen size</a></h3>
<p>A usable screen area of approximately <strong>1200 × 720 pixels</strong> or more is recommended.</p>
<p>KST4Contest automatically adapts the main window to the available area of the primary screen. The application can therefore also be started on smaller displays. Less space is still less space, however: not all tables, filters and additional information can then be displayed at a useful size at the same time.</p>
<h3 id="java" tabindex="-1"><a class="header-anchor" href="#java">Java</a></h3>
<p>The ready-made packages from the <a href="https://github.com/praktimarc/kst4contest/releases/latest">GitHub Releases</a> do not require a separate Java installation. The required runtime is distributed with KST4Contest.</p>
<p>A Java development environment is only required if you want to build KST4Contest from source. For the AUR packages <code>kst4contest</code> and <code>kst4contest-git</code>, Java 21 and Maven are handled as build dependencies by the package manager.</p>
<hr>
<h2 id="stable%2C-beta-or-nightly%3F" tabindex="-1"><a class="header-anchor" href="#stable%2C-beta-or-nightly%3F">Stable, Beta or Nightly?</a></h2>
<p>KST4Contest is distributed through three development channels:</p>
<table>
<thead>
<tr>
<th>Channel</th>
<th>Intended use</th>
<th>Classification</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Stable</strong></td>
<td>Normal contest operation</td>
<td>Published version intended for regular use</td>
</tr>
<tr>
<td><strong>Beta</strong></td>
<td>Focused testing before a Stable release</td>
<td>Pre-release version with a largely defined feature set</td>
</tr>
<tr>
<td><strong>Nightly</strong></td>
<td>Early testing of new features</td>
<td>Current development state from the <code>main</code> branch</td>
</tr>
</tbody>
</table>
<p>The <strong>Stable version</strong> is recommended for normal operation.</p>
<p>Beta and Nightly builds may contain features that are not yet available in the Stable release. They may also contain unfinished workflows, changed settings or new defects. That is not an unusual failure of the release process; it is the purpose of a development channel.</p>
<p>If a function in this manual is explicitly marked as <strong>Nightly</strong>, it is not necessarily part of the current Stable release yet.</p>
<hr>
<h2 id="download" tabindex="-1"><a class="header-anchor" href="#download">Download</a></h2>
<p>The current Stable version is available here:</p>
<ul>
<li><a href="https://github.com/praktimarc/kst4contest/releases/latest">Latest KST4Contest release</a></li>
<li><a href="https://github.com/praktimarc/kst4contest/releases">All published releases</a></li>
</ul>
<p>The release page contains the application packages as well as the English and German PDF manuals.</p>
<h3 id="which-package-do-i-need%3F" tabindex="-1"><a class="header-anchor" href="#which-package-do-i-need%3F">Which package do I need?</a></h3>
<table>
<thead>
<tr>
<th>Operating system</th>
<th>Package</th>
<th>Typical filename</th>
</tr>
</thead>
<tbody>
<tr>
<td>Windows x64</td>
<td>ZIP package</td>
<td><code>praktiKST-v&lt;version&gt;-windows-x64.zip</code></td>
</tr>
<tr>
<td>Linux x86_64</td>
<td>AppImage</td>
<td><code>KST4Contest-v&lt;version&gt;-linux-x86_64.AppImage</code></td>
</tr>
<tr>
<td>Debian/Ubuntu amd64</td>
<td>DEB package</td>
<td><code>KST4Contest-v&lt;version&gt;-debian-amd64.deb</code></td>
</tr>
<tr>
<td>Fedora/RPM x86_64</td>
<td>RPM package</td>
<td><code>KST4Contest-v&lt;version&gt;-fedora-x86_64.rpm</code></td>
</tr>
<tr>
<td>Arch Linux x86_64</td>
<td>Arch package</td>
<td><code>KST4Contest-v&lt;version&gt;-archlinux-x86_64.pkg.tar.zst</code></td>
</tr>
<tr>
<td>Linux with Flatpak</td>
<td>Flatpak reference</td>
<td><code>de.x08.KST4Contest.flatpakref</code></td>
</tr>
<tr>
<td>macOS Apple Silicon</td>
<td>DMG for ARM64</td>
<td><code>KST4Contest-v&lt;version&gt;-macos-arm64.dmg</code></td>
</tr>
<tr>
<td>macOS Intel</td>
<td>DMG for x86_64</td>
<td><code>KST4Contest-v&lt;version&gt;-macos-x86_64.dmg</code></td>
</tr>
</tbody>
</table>
<p>Only download application packages from the official GitHub Releases, the KST4Contest Flatpak repository or the linked AUR packages. Files from other sources may have been built differently, may be outdated or may have been modified.</p>
<hr>
<h2 id="installing-on-windows" tabindex="-1"><a class="header-anchor" href="#installing-on-windows">Installing on Windows</a></h2>
<p>KST4Contest is distributed as a ZIP package for Windows. A conventional installer is not required.</p>
<ol>
<li>Download <code>praktiKST-v&lt;version&gt;-windows-x64.zip</code> from the latest release.</li>
<li>Extract the ZIP file completely into a dedicated folder.</li>
<li>Open the extracted folder.</li>
<li>Start <code>praktiKST.exe</code>.</li>
</ol>
<p>Do not start the application directly from the compressed ZIP file. KST4Contest consists of several files and a bundled runtime. Windows can only use this structure reliably after the archive has been extracted completely.</p>
<p>The application settings are not stored in the extracted program directory. They are stored in your user profile:</p>
<pre><code class="language-text">%USERPROFILE%\.praktiKST\preferences.xml
</code></pre>
<p>This allows a new application version to be extracted into a different directory without losing the existing settings.</p>
<hr>
<h2 id="installing-on-linux" tabindex="-1"><a class="header-anchor" href="#installing-on-linux">Installing on Linux</a></h2>
<p>Several Linux package formats are available. The appropriate choice depends less on KST4Contest itself than on your distribution and the way you prefer to manage updates.</p>
<table>
<thead>
<tr>
<th>Installation method</th>
<th>Useful when …</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Flatpak</strong></td>
<td>updates should be managed centrally and Flatpak is already in use</td>
</tr>
<tr>
<td><strong>AppImage</strong></td>
<td>KST4Contest should run as a portable file without package installation</td>
</tr>
<tr>
<td><strong>DEB/RPM</strong></td>
<td>the distributions native package manager should be used</td>
</tr>
<tr>
<td><strong>Arch package/AUR</strong></td>
<td>Arch Linux, Manjaro or EndeavourOS is being used</td>
</tr>
</tbody>
</table>
<h3 id="flatpak" tabindex="-1"><a class="header-anchor" href="#flatpak">Flatpak</a></h3>
<p>For most Linux users, Flatpak is the simplest way to keep KST4Contest installed and manageable through the systems update tools. The KST4Contest repository is GPG-signed and contains the Stable, Beta and Nightly channels.</p>
<h4 id="installing-stable-from-the-release-file" tabindex="-1"><a class="header-anchor" href="#installing-stable-from-the-release-file">Installing Stable from the release file</a></h4>
<p>Download <code>de.x08.KST4Contest.flatpakref</code> from the latest release and open it with the software manager provided by your desktop environment.</p>
<p>Alternatively, install it from a terminal:</p>
<pre><code class="language-bash">flatpak install ./de.x08.KST4Contest.flatpakref
</code></pre>
<h4 id="adding-the-kst4contest-repository" tabindex="-1"><a class="header-anchor" href="#adding-the-kst4contest-repository">Adding the KST4Contest repository</a></h4>
<p>The repository only needs to be added once:</p>
<pre><code class="language-bash">flatpak remote-add --if-not-exists kst4contest \
https://praktimarc.github.io/kst4contest/kst4contest.flatpakrepo
</code></pre>
<p>You can then install the Stable version:</p>
<pre><code class="language-bash">flatpak install kst4contest de.x08.KST4Contest//stable
</code></pre>
<h4 id="installing-beta" tabindex="-1"><a class="header-anchor" href="#installing-beta">Installing Beta</a></h4>
<pre><code class="language-bash">flatpak install kst4contest de.x08.KST4Contest//beta
</code></pre>
<h4 id="installing-nightly" tabindex="-1"><a class="header-anchor" href="#installing-nightly">Installing Nightly</a></h4>
<pre><code class="language-bash">flatpak install kst4contest de.x08.KST4Contest//nightly
</code></pre>
<p>All three KST4Contest channels use the same application ID. Installing multiple KST4Contest channels in parallel is therefore not supported.</p>
<p>For example, to switch from Stable to Nightly:</p>
<pre><code class="language-bash">flatpak uninstall de.x08.KST4Contest//stable
flatpak install kst4contest de.x08.KST4Contest//nightly
</code></pre>
<p>This does not automatically remove the personal settings stored in <code>~/.praktiKST</code>.</p>
<p>Installed Flatpak applications can be updated with:</p>
<pre><code class="language-bash">flatpak update de.x08.KST4Contest
</code></pre>
<p>Depending on the desktop environment, the graphical software manager may also display or automatically install available Flatpak updates. The <code>flatpak update</code> command itself performs an update; it does not promise to turn up and run by itself one day.</p>
<h3 id="appimage" tabindex="-1"><a class="header-anchor" href="#appimage">AppImage</a></h3>
<p>The AppImage does not require a conventional installation.</p>
<ol>
<li>Download <code>KST4Contest-v&lt;version&gt;-linux-x86_64.AppImage</code>.</li>
<li>Open a terminal in the download directory.</li>
<li>Make the file executable:</li>
</ol>
<pre><code class="language-bash">chmod +x KST4Contest-v&lt;version&gt;-linux-x86_64.AppImage
</code></pre>
<ol start="4">
<li>Start KST4Contest:</li>
</ol>
<pre><code class="language-bash">./KST4Contest-v&lt;version&gt;-linux-x86_64.AppImage
</code></pre>
<p>The AppImage can then be moved to another location, such as <code>~/Applications</code>.</p>
<h3 id="debian-and-ubuntu" tabindex="-1"><a class="header-anchor" href="#debian-and-ubuntu">Debian and Ubuntu</a></h3>
<p>Install the DEB package with:</p>
<pre><code class="language-bash">sudo apt install ./KST4Contest-v&lt;version&gt;-debian-amd64.deb
</code></pre>
<p>Alternatively, open the file with a graphical package manager.</p>
<h3 id="fedora-and-compatible-rpm-systems" tabindex="-1"><a class="header-anchor" href="#fedora-and-compatible-rpm-systems">Fedora and compatible RPM systems</a></h3>
<p>Install the RPM package with:</p>
<pre><code class="language-bash">sudo dnf install ./KST4Contest-v&lt;version&gt;-fedora-x86_64.rpm
</code></pre>
<h3 id="arch-linux%3A-installing-the-release-package" tabindex="-1"><a class="header-anchor" href="#arch-linux%3A-installing-the-release-package">Arch Linux: installing the release package</a></h3>
<p>The Arch package downloaded from the GitHub Release can be installed directly:</p>
<pre><code class="language-bash">sudo pacman -U KST4Contest-v&lt;version&gt;-archlinux-x86_64.pkg.tar.zst
</code></pre>
<h3 id="arch-linux%3A-installing-from-the-aur" tabindex="-1"><a class="header-anchor" href="#arch-linux%3A-installing-from-the-aur">Arch Linux: installing from the AUR</a></h3>
<p>Three variants are available in the AUR:</p>
<table>
<thead>
<tr>
<th>Package</th>
<th>Content</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://aur.archlinux.org/packages/kst4contest-bin"><code>kst4contest-bin</code></a></td>
<td>Pre-built package from the current Stable release</td>
</tr>
<tr>
<td><a href="https://aur.archlinux.org/packages/kst4contest"><code>kst4contest</code></a></td>
<td>Stable release built locally from source</td>
</tr>
<tr>
<td><a href="https://aur.archlinux.org/packages/kst4contest-git"><code>kst4contest-git</code></a></td>
<td>Current development state from the <code>main</code> branch</td>
</tr>
</tbody>
</table>
<p>For most users, <code>kst4contest-bin</code> is the straightforward option:</p>
<pre><code class="language-bash">yay -S kst4contest-bin
</code></pre>
<p>To build the Stable release from source:</p>
<pre><code class="language-bash">yay -S kst4contest
</code></pre>
<p>To build the current development state:</p>
<pre><code class="language-bash">yay -S kst4contest-git
</code></pre>
<p>All three packages provide the same application and are therefore defined as conflicting with one another. Install only one variant at a time.</p>
<p>AUR updates are included when the selected AUR helper checks for package updates, for example:</p>
<pre><code class="language-bash">yay -Syu
</code></pre>
<p>They do not happen automatically merely because the package came from the AUR.</p>
<hr>
<h2 id="installing-on-macos" tabindex="-1"><a class="header-anchor" href="#installing-on-macos">Installing on macOS</a></h2>
<blockquote>
<p><strong>Best-effort support:</strong> The macOS packages are built together with the other releases, but they are not tested to the same extent as the Windows and Linux versions. Feedback is welcome; fully tested support for every macOS version and hardware variant cannot currently be guaranteed.</p>
</blockquote>
<p>Apple Silicon Macs require the package marked <code>arm64</code>. Intel Macs require the package marked <code>x86_64</code>.</p>
<ol>
<li>Download the appropriate DMG file.</li>
<li>Open the DMG file.</li>
<li>Drag <code>KST4Contest.app</code> into the <strong>Applications</strong> folder.</li>
<li>Start KST4Contest from the Applications folder or Launchpad.</li>
</ol>
<p>The application is not currently notarized by Apple. macOS may therefore block the first launch.</p>
<p>If the application came from the official GitHub Release:</p>
<ol>
<li>Open the Applications folder in Finder.</li>
<li>Right-click or Control-click <code>KST4Contest.app</code>.</li>
<li>Select <strong>Open</strong>.</li>
<li>Confirm the launch in the dialog that appears.</li>
</ol>
<p>Alternatively, macOS may provide an <strong>Open Anyway</strong> button under <strong>System Settings → Privacy &amp; Security</strong>.</p>
<hr>
<h2 id="where-are-the-settings-stored%3F" tabindex="-1"><a class="header-anchor" href="#where-are-the-settings-stored%3F">Where are the settings stored?</a></h2>
<p>KST4Contest stores its settings and other local working files in the users home directory. The application directory and the data directory are separate.</p>
<table>
<thead>
<tr>
<th>Operating system</th>
<th>Data directory</th>
<th>Settings file</th>
</tr>
</thead>
<tbody>
<tr>
<td>Windows</td>
<td><code>%USERPROFILE%\.praktiKST\</code></td>
<td><code>%USERPROFILE%\.praktiKST\preferences.xml</code></td>
</tr>
<tr>
<td>Linux</td>
<td><code>~/.praktiKST/</code></td>
<td><code>~/.praktiKST/preferences.xml</code></td>
</tr>
<tr>
<td>macOS</td>
<td><code>~/.praktiKST/</code></td>
<td><code>~/.praktiKST/preferences.xml</code></td>
</tr>
</tbody>
</table>
<p>Note the spelling <code>.praktiKST</code> with an uppercase <code>KST</code>. Linux and macOS distinguish between uppercase and lowercase letters. <code>.praktikst</code> would simply be a different directory.</p>
<p>An application update does not remove this directory. Even so, creating a backup before a major version change or extensive configuration work is sensible.</p>
<hr>
<h2 id="updates" tabindex="-1"><a class="header-anchor" href="#updates">Updates</a></h2>
<p>When KST4Contest starts, it checks whether a newer Stable release is available. If it finds one, it displays an information window containing:</p>
<ul>
<li>the installed version,</li>
<li>the latest Stable version,</li>
<li>a short overview of the main changes,</li>
<li>the changelog,</li>
<li>known issues,</li>
<li>a link to the corresponding GitHub Release page.</li>
</ul>
<p><img src="/manual/assets/update_window.png" alt="KST4Contest update notification"></p>
<p>The update checker does not install anything. It reports the new version and opens the platform-neutral release page. From there, you must select the appropriate package for Windows, Linux or macOS.</p>
<h3 id="updating-windows" tabindex="-1"><a class="header-anchor" href="#updating-windows">Updating Windows</a></h3>
<ol>
<li>Close KST4Contest.</li>
<li>Download the new Windows ZIP package.</li>
<li>Extract it into a new or empty directory.</li>
<li>Start the new version.</li>
<li>Check that the existing settings have been loaded.</li>
<li>Remove the old application directory only after that.</li>
</ol>
<p>The settings are preserved because they are stored under <code>%USERPROFILE%\.praktiKST</code>, not in the application directory.</p>
<h3 id="updating-an-appimage" tabindex="-1"><a class="header-anchor" href="#updating-an-appimage">Updating an AppImage</a></h3>
<ol>
<li>Download the new AppImage.</li>
<li>Make it executable.</li>
<li>Start the new file.</li>
<li>Remove the previous AppImage only after the new version works.</li>
</ol>
<h3 id="updating-debian-and-ubuntu" tabindex="-1"><a class="header-anchor" href="#updating-debian-and-ubuntu">Updating Debian and Ubuntu</a></h3>
<pre><code class="language-bash">sudo apt install ./KST4Contest-v&lt;version&gt;-debian-amd64.deb
</code></pre>
<h3 id="updating-fedora" tabindex="-1"><a class="header-anchor" href="#updating-fedora">Updating Fedora</a></h3>
<pre><code class="language-bash">sudo dnf upgrade ./KST4Contest-v&lt;version&gt;-fedora-x86_64.rpm
</code></pre>
<h3 id="updating-the-arch-package" tabindex="-1"><a class="header-anchor" href="#updating-the-arch-package">Updating the Arch package</a></h3>
<pre><code class="language-bash">sudo pacman -U KST4Contest-v&lt;version&gt;-archlinux-x86_64.pkg.tar.zst
</code></pre>
<h3 id="updating-an-aur-package" tabindex="-1"><a class="header-anchor" href="#updating-an-aur-package">Updating an AUR package</a></h3>
<p>Update the installed package through the selected AUR helper, for example:</p>
<pre><code class="language-bash">yay -Syu
</code></pre>
<h3 id="updating-flatpak" tabindex="-1"><a class="header-anchor" href="#updating-flatpak">Updating Flatpak</a></h3>
<pre><code class="language-bash">flatpak update de.x08.KST4Contest
</code></pre>
<h3 id="updating-macos" tabindex="-1"><a class="header-anchor" href="#updating-macos">Updating macOS</a></h3>
<ol>
<li>Download the new DMG file for the appropriate architecture.</li>
<li>Close KST4Contest.</li>
<li>Open the DMG file.</li>
<li>Replace <code>KST4Contest.app</code> in the Applications folder.</li>
<li>Start the new version and check the existing settings.</li>
</ol>
<p>The configuration under <code>~/.praktiKST</code> is not affected.</p>
<hr>
<h2 id="problems-during-the-first-launch" tabindex="-1"><a class="header-anchor" href="#problems-during-the-first-launch">Problems during the first launch</a></h2>
<h3 id="windows-reports-an-unknown-application" tabindex="-1"><a class="header-anchor" href="#windows-reports-an-unknown-application">Windows reports an unknown application</a></h3>
<p>KST4Contest is not currently signed with a commercial Windows code-signing certificate. Windows or an additional security product may therefore warn about an unknown or rarely downloaded application.</p>
<p>Check the following first:</p>
<ul>
<li>Did the file come from the <a href="https://github.com/praktimarc/kst4contest/releases/latest">official KST4Contest release</a>?</li>
<li>Does the filename match the published release?</li>
<li>Was the file downloaded completely?</li>
<li>Does the security product report a specific detection name or only a general reputation warning?</li>
</ul>
<p>A warning alone is neither reliable proof of malware nor automatically a false positive. If the origin of the file is unclear, do not run it or restore it from quarantine.</p>
<p>Some users have reported quarantine messages from Norton 360 in particular. If the warning can be reproduced, please create a <a href="https://github.com/praktimarc/kst4contest/issues">GitHub issue</a> and include:</p>
<ul>
<li>the KST4Contest version,</li>
<li>the complete filename,</li>
<li>the security product and its version,</li>
<li>the reported detection name,</li>
<li>a screenshot of the warning, if possible.</li>
</ul>
<h3 id="the-appimage-does-not-start" tabindex="-1"><a class="header-anchor" href="#the-appimage-does-not-start">The AppImage does not start</a></h3>
<p>Check the executable permission first:</p>
<pre><code class="language-bash">chmod +x KST4Contest-v&lt;version&gt;-linux-x86_64.AppImage
</code></pre>
<p>Then start the file from a terminal. Error messages shown there are usually more useful than a double-click that simply produces no visible result.</p>
<h3 id="macos-blocks-the-application" tabindex="-1"><a class="header-anchor" href="#macos-blocks-the-application">macOS blocks the application</a></h3>
<p>Use the <strong>Open</strong> function described under <a href="#installing-on-macos">Installing on macOS</a>. Before doing so, verify that the DMG file came from the official GitHub Release.</p>
<h3 id="the-problem-remains" tabindex="-1"><a class="header-anchor" href="#the-problem-remains">The problem remains</a></h3>
<p>First check whether the problem has already been reported under <a href="https://github.com/praktimarc/kst4contest/issues">GitHub Issues</a>. If it has not, create a new issue containing:</p>
<ul>
<li>the operating system and version,</li>
<li>the KST4Contest version,</li>
<li>the installation method,</li>
<li>the exact error message,</li>
<li>the steps required to reproduce the problem.</li>
</ul>
<p>“It does not work” usually describes the situation accurately, but it is of limited value during diagnosis.</p>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
+231
View File
@@ -0,0 +1,231 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ manual.title }} | KST4Contest Manual</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest manual page: {{ manual.title }}">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/manual/en/log-sync/">
<meta property="og:type" content="website">
<meta property="og:title" content="{{ manual.title }} | KST4Contest Manual">
<meta property="og:description" content="KST4Contest manual page: {{ manual.title }}">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/manual/en/log-sync/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="section">
<div class="card manual-content">
<p><a href="/manual/en/">← Back to manual overview</a></p>
<h1>Log Synchronisation</h1>
<h1 id="log-synchronisation" tabindex="-1"><a class="header-anchor" href="#log-synchronisation">Log Synchronisation</a></h1>
<blockquote>
<p>🇬🇧 You are reading the English version | 🇩🇪 <a href="/manual/de/log-synchronisation/">Deutsche Version</a></p>
</blockquote>
<p>KST4Contest automatically marks worked stations in the chat user list. Two basic methods are available:</p>
<hr>
<p><img src="/manual/assets/client_settings_window_logsync.png" alt="Log Sync Settings Window"></p>
<h2 id="method-1%3A-universal-file-based-callsign-interpreter-(simplelogfile)" tabindex="-1"><a class="header-anchor" href="#method-1%3A-universal-file-based-callsign-interpreter-(simplelogfile)">Method 1: Universal File Based Callsign Interpreter (Simplelogfile)</a></h2>
<p>KST4Contest reads a log file and searches for callsign patterns using a regular expression. Binary log files are also supported unreadable binary content is simply ignored.</p>
<p><strong>Advantage</strong>: Works with almost any logging program that writes a file.
<strong>Disadvantage</strong>: No band information available stations are only marked as “worked”, not on which band.</p>
<p>Enter the path to the log file in the Preferences. The file is only read, never modified (read-only).</p>
<blockquote>
<p><strong>Tip</strong>: The Simplelogfile function can also be used to mark stations that are definitely unreachable (e.g. personal notes). This will be replaced in a later version by a better tagging system.</p>
</blockquote>
<hr>
<h2 id="method-2%3A-network-listener-(udp-broadcast)-%E2%80%93-recommended" tabindex="-1"><a class="header-anchor" href="#method-2%3A-network-listener-(udp-broadcast)-%E2%80%93-recommended">Method 2: Network Listener (UDP Broadcast) Recommended</a></h2>
<p>When saving a QSO, the logging software sends a UDP packet to the broadcast address of the home network. KST4Contest receives this packet and marks the station including <strong>band information</strong> in its internal SQLite database.</p>
<blockquote>
<p><strong>Important</strong>: KST4Contest must be <strong>running in parallel with the logging software</strong>. QSOs logged while KST4Contest is not running will not be captured except with QARTest (which can send the complete log).</p>
</blockquote>
<p><strong>Default UDP port</strong>: 12060 (matches the default of most logging programs)</p>
<hr>
<h2 id="supported-logging-software" tabindex="-1"><a class="header-anchor" href="#supported-logging-software">Supported Logging Software</a></h2>
<h3 id="ucxlog-(dl7ucx)" tabindex="-1"><a class="header-anchor" href="#ucxlog-(dl7ucx)">UCXLog (DL7UCX)</a></h3>
<p><img src="/manual/assets/ucxlog_logsync.png" alt="UCXLog Configuration"></p>
<p>UCXLog sends QSO UDP packets and transceiver frequency packets.</p>
<p><strong>Settings in UCXLog:</strong></p>
<ul>
<li>Enable UDP broadcast</li>
<li>Enter the IP address of the KST4Contest computer (for local operation: <code>127.0.0.1</code>)</li>
<li>Port: 12060 (default)</li>
</ul>
<p>Note the green-highlighted fields in the UCXLog settings: IP and port must be filled in.</p>
<p>Note for multi-setup (2 computers, 2 radios, one KST4Contest instance): Both logging programs must send QSO packets to the IP of the KST4Contest computer. In this case, at least one IP is not <code>127.0.0.1</code>.</p>
<h3 id="qartest-(ik3qar)" tabindex="-1"><a class="header-anchor" href="#qartest-(ik3qar)">QARTest (IK3QAR)</a></h3>
<p><img src="/manual/assets/qartest_logsync.png" alt="QARTest Configuration"></p>
<p><strong>Special feature</strong>: QARTest can send the <strong>complete log</strong> to KST4Contest (button “Invia log completo” in the QARTest settings). This means QSOs logged before KST4Contest was started are also captured.</p>
<p><strong>Settings in QARTest:</strong></p>
<ul>
<li>Configure UDP broadcast and IP/port as with UCXLog</li>
<li>Use “Invia log completo” for a full log upload</li>
</ul>
<p><em>(„Buona funzionalità caro IK3QAR!&quot; DO5AMF)</em></p>
<h3 id="n1mm%2B" tabindex="-1"><a class="header-anchor" href="#n1mm%2B">N1MM+</a></h3>
<p><strong>Settings in N1MM+:</strong></p>
<p>In N1MM+ under <code>Config → Configure Ports, Mode Control, Winkey, etc. → Broadcast Data</code>:</p>
<ul>
<li>Enable <code>Radio Info</code> (for TRX sync / QRG)</li>
<li>Enable <code>Contact Info</code> (for QSO sync)</li>
<li>IP: <code>127.0.0.1</code> (or IP of the KST4Contest computer)</li>
<li>Port: 12060</li>
</ul>
<p>For the built-in DX cluster server: configure N1MM+ as a DX cluster client (server: <code>127.0.0.1</code>, port as set in KST4Contest).</p>
<h3 id="dxlog.net" tabindex="-1"><a class="header-anchor" href="#dxlog.net"><a href="http://DXLog.net">DXLog.net</a></a></h3>
<p><img src="/manual/assets/dxlog_net_logsync.png" alt="DXLog.net Configuration"></p>
<p><strong>Settings in <a href="http://DXLog.net">DXLog.net</a>:</strong></p>
<ul>
<li>Enable UDP broadcast</li>
<li>Enter the IP of the KST4Contest computer (green-highlighted fields)</li>
<li>Port: 12060</li>
</ul>
<h3 id="win-test" tabindex="-1"><a class="header-anchor" href="#win-test">Win-Test</a></h3>
<p>Win-Test is supported with a dedicated UDP network listener that understands the native Win-Test network protocol.</p>
<p><strong>Advantages of Win-Test Integration:</strong></p>
<ul>
<li>Automatic QSO synchronization to mark worked stations.</li>
<li><strong>Sked Handover (ADDSKED):</strong> Using the “Create sked” button in the station info panel not only creates a sked in KST4Contest but also <em>sends it directly via UDP to the Win-Test network as an ADDSKED packet</em> automatically, as soon as the listener is active. No separate toggle is needed.</li>
<li>You can choose between “AUTO”, “SSB”, or “CW” sked modes.</li>
<li><strong>Automatic QRG resolution for SKEDs:</strong> KST4Contest selects the sked frequency intelligently:
<ol>
<li>If the other station mentioned their QRG in a recent chat message, that frequency is used.</li>
<li>Otherwise, your own current QRG is used (from Win-Test STATUS or manual entry).</li>
</ol>
</li>
</ul>
<p><strong>Settings in the “Log Synchronisation” tab:</strong></p>
<ul>
<li>Enable <code>Receive Win-Test network based UDP log messages</code>.</li>
<li><code>UDP-Port for Win-Test listener</code> (default: 9871).</li>
<li><code>KST station name in Win-Test network (src of SKED packets)</code>: Defines the station name KST4Contest uses in the WT network (e.g. “KST”).</li>
<li><code>Win-Test network broadcast address</code>: Usually detected automatically; required to send sked packets to the network.</li>
</ul>
<p><strong>Settings in the “TRX Synchronisation” tab:</strong></p>
<ul>
<li><code>Win-Test STATUS QRG Sync</code>: When enabled, KST4Contest takes the current transceiver frequency from the Win-Test STATUS packet and uses it as your own QRG (MYQRG).</li>
<li><code>Use pass frequency from Win-Test STATUS</code>: Instead of the main TRX frequency, the pass frequency contained in the STATUS packet is used as MYQRG (useful for multi-op setups that operate with a dedicated pass QRG).</li>
<li><code>Win-Test station name filter</code>: If a name is entered here (e.g. “STN1”), KST4Contest only processes packets from that specific Win-Test instance. Leave empty to accept all.</li>
</ul>
<p><strong>Settings in Win-Test:</strong></p>
<ul>
<li>The network in Win-Test must be active.</li>
<li>Win-Test must be configured to send/receive its broadcasts on the corresponding port (default 9871).</li>
</ul>
<hr>
<h2 id="trx-frequency-synchronisation" tabindex="-1"><a class="header-anchor" href="#trx-frequency-synchronisation">TRX Frequency Synchronisation</a></h2>
<p>In addition to QSO synchronisation, UCXLog and other programs also transmit the <strong>current transceiver frequency</strong> via UDP. KST4Contest processes this information and makes it available as the <code>MYQRG</code> variable.</p>
<p><img src="/manual/assets/qrg_buttons.png" alt="Frequency Buttons"></p>
<p><strong>Result</strong>: Your own QRG never needs to be typed manually in the chat clicking the MYQRG button or using the variable in the beacon is sufficient.</p>
<p><strong>Sources for your own QRG (MYQRG):</strong></p>
<ul>
<li>UCXLog, N1MM+, <a href="http://DXLog.net">DXLog.net</a>, QARTest via UDP port 12060</li>
<li>Win-Test STATUS packet (optional, configurable in the “TRX Synchronisation” tab under “Win-Test STATUS QRG Sync”)</li>
<li>Manual entry in the QRG field</li>
</ul>
<blockquote>
<p><strong>Note for multi-setup</strong>: With two logging programs on two computers, only <strong>one</strong> should send frequency packets. KST4Contest cannot distinguish between sources and processes all incoming packets.</p>
</blockquote>
<hr>
<h2 id="multi-setup%3A-2-radios%2C-2-computers" tabindex="-1"><a class="header-anchor" href="#multi-setup%3A-2-radios%2C-2-computers">Multi-Setup: 2 Radios, 2 Computers</a></h2>
<p>For DM5M-style setups (2 radios, 2 computers, one KST4Contest instance or two separate):</p>
<p><strong>Option A One shared KST4Contest instance:</strong></p>
<ul>
<li>Both logging programs send QSO packets to the IP of the KST4Contest computer</li>
<li>Only one logging program sends frequency packets (recommended: the VHF logging program)</li>
</ul>
<p><strong>Option B Two separate KST4Contest instances (recommended):</strong></p>
<ul>
<li>Each logging program communicates with its own KST4Contest instance via <code>127.0.0.1</code></li>
<li>Two separate chat logins</li>
<li>Better separation and fewer conflicts</li>
</ul>
<hr>
<h2 id="internal-database" tabindex="-1"><a class="header-anchor" href="#internal-database">Internal Database</a></h2>
<p>KST4Contest stores worked information in an internal <strong>SQLite database</strong>. This is independent of the logging programs database and is only populated via the UDP broadcast.</p>
<p>Before each new contest: reset the database! → <a href="Configuration#worked-station-database-settings">Configuration Worked Station Database Settings</a></p>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
@@ -0,0 +1,242 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ manual.title }} | KST4Contest Manual</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest manual page: {{ manual.title }}">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/manual/en/macros-and-variables/">
<meta property="og:type" content="website">
<meta property="og:title" content="{{ manual.title }} | KST4Contest Manual">
<meta property="og:description" content="KST4Contest manual page: {{ manual.title }}">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/manual/en/macros-and-variables/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="section">
<div class="card manual-content">
<p><a href="/manual/en/">← Back to manual overview</a></p>
<h1>Macros and Variables</h1>
<h1 id="macros-and-variables" tabindex="-1"><a class="header-anchor" href="#macros-and-variables">Macros and Variables</a></h1>
<blockquote>
<p>🇬🇧 You are reading the English version | 🇩🇪 <a href="/manual/de/makros-und-variablen/">Deutsche Version</a></p>
</blockquote>
<p>KST4Contest offers a flexible system of text snippets, shortcuts and built-in variables that significantly speed up the chat workflow during contests.</p>
<hr>
<h2 id="overview" tabindex="-1"><a class="header-anchor" href="#overview">Overview</a></h2>
<table>
<thead>
<tr>
<th>Type</th>
<th>Access</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Shortcuts</strong></td>
<td>Button in the toolbar</td>
<td>Quick text insert into the send field</td>
</tr>
<tr>
<td><strong>Snippets</strong></td>
<td>Right-click / Ctrl+1…0</td>
<td>Text building blocks, optional PM sending</td>
</tr>
<tr>
<td><strong>Variables</strong></td>
<td>Usable in all text fields</td>
<td>Dynamic values (QRG, locator, AP data)</td>
</tr>
</tbody>
</table>
<hr>
<h2 id="shortcuts-(quick-access-buttons)" tabindex="-1"><a class="header-anchor" href="#shortcuts-(quick-access-buttons)">Shortcuts (Quick-Access Buttons)</a></h2>
<p>Configurable in Preferences → <strong>Shortcut Settings</strong>.</p>
<ul>
<li>Each configured text creates <strong>one button</strong> in the user interface.</li>
<li>Clicking a button inserts the text into the <strong>send field</strong>.</li>
<li><strong>All variables</strong> can be used in shortcuts and are resolved immediately when inserted.</li>
<li>Longer texts are also possible.</li>
</ul>
<p><strong>Tip</strong>: Set up frequently used abbreviations like “pse”, “rrr”, “tnx”, “73” as shortcuts.</p>
<hr>
<h2 id="snippets-(text-building-blocks)" tabindex="-1"><a class="header-anchor" href="#snippets-(text-building-blocks)">Snippets (Text Building Blocks)</a></h2>
<p>Configurable in Preferences → <strong>Snippet Settings</strong>.</p>
<h3 id="access" tabindex="-1"><a class="header-anchor" href="#access">Access</a></h3>
<ul>
<li><strong>Right-click</strong> on a callsign in the user list</li>
<li><strong>Right-click</strong> in the CQ message table</li>
<li><strong>Right-click</strong> in the PM message table</li>
<li><strong>Keyboard shortcuts</strong>: <code>Ctrl+1</code> to <code>Ctrl+0</code> for the first 10 snippets</li>
</ul>
<h3 id="behaviour-with-a-selected-callsign" tabindex="-1"><a class="header-anchor" href="#behaviour-with-a-selected-callsign">Behaviour with a Selected Callsign</a></h3>
<p>When a callsign is selected in the user list, the snippet is addressed as a <strong>private message</strong>:</p>
<pre><code>/CQ CALLSIGN &lt;snippet text&gt;
</code></pre>
<p>Then <strong>Enter</strong> can be pressed to send directly even if the send field does not have focus.</p>
<h3 id="hardware-macro-keyboard" tabindex="-1"><a class="header-anchor" href="#hardware-macro-keyboard">Hardware Macro Keyboard</a></h3>
<p><em>(Idea by IU3OAR, Gianluca Costantino)</em></p>
<p>The key combinations <code>Ctrl+1</code> to <code>Ctrl+0</code> can be assigned to a programmable macro keyboard. One key press triggers the snippet, another press (mapped to Enter) sends it immediately. In contest operation this saves considerable time.</p>
<h3 id="predefined-default-snippets" tabindex="-1"><a class="header-anchor" href="#predefined-default-snippets">Predefined Default Snippets</a></h3>
<p>On first start, some snippets are pre-configured, e.g.:</p>
<ul>
<li><code>Hi OM, try sked?</code></li>
<li><code>I am calling cq ur dir, pse lsn to me at MYQRG</code></li>
<li><code>pse ur qrg?</code></li>
<li><code>rrr, I move to your qrg nw, pse ant dir me</code></li>
</ul>
<p>These can be customised or deleted in the Preferences.</p>
<hr>
<h2 id="variables" tabindex="-1"><a class="header-anchor" href="#variables">Variables</a></h2>
<p>Variables in written texts (snippets, shortcuts, beacon, send field) are replaced by their current values at runtime. Simply type the variable name in <strong>uppercase</strong> in the text.</p>
<h3 id="myqrg" tabindex="-1"><a class="header-anchor" href="#myqrg">MYQRG</a></h3>
<p>Replaced by the current transceiver frequency.</p>
<ul>
<li>Source: TRX sync via UDP from the logging software (if enabled)</li>
<li>Fallback: Manually entered value in the MYQRG text field to the right of the send button</li>
<li>Format: <code>144.388.03</code></li>
</ul>
<p><strong>Example</strong>: <code>calling cq at MYQRG</code><code>calling cq at 144.388.03</code></p>
<h3 id="myqrgshort" tabindex="-1"><a class="header-anchor" href="#myqrgshort">MYQRGSHORT</a></h3>
<p>Like MYQRG, but only the first 7 characters.</p>
<ul>
<li>Format: <code>144.388</code></li>
</ul>
<p><strong>Example</strong>: <code>qrg: MYQRGSHORT</code><code>qrg: 144.388</code></p>
<h3 id="mylocator" tabindex="-1"><a class="header-anchor" href="#mylocator">MYLOCATOR</a></h3>
<p>Replaced by your own Maidenhead locator (6 characters).</p>
<ul>
<li>Format: <code>JO51IJ</code></li>
</ul>
<p><strong>Example</strong>: <code>my loc: MYLOCATOR</code><code>my loc: JO51IJ</code></p>
<h3 id="mylocatorshort" tabindex="-1"><a class="header-anchor" href="#mylocatorshort">MYLOCATORSHORT</a></h3>
<p>Like MYLOCATOR, but only the first 4 characters.</p>
<ul>
<li>Format: <code>JO51</code></li>
</ul>
<p><strong>Example</strong>: <code>loc: MYLOCATORSHORT</code><code>loc: JO51</code></p>
<h3 id="qrzname" tabindex="-1"><a class="header-anchor" href="#qrzname">QRZNAME</a></h3>
<p>Replaced by the <strong>name</strong> of the currently selected station from the chat name field.</p>
<p><strong>Example</strong>: <code>Hi QRZNAME, sked?</code><code>Hi Gianluca, sked?</code></p>
<h3 id="firstap" tabindex="-1"><a class="header-anchor" href="#firstap">FIRSTAP</a></h3>
<p>Replaced by data of the first reflectable aircraft to the selected station (if available).</p>
<ul>
<li>Condition: AirScout is active and an aircraft is available.</li>
<li>Example format: <code>a very big AP in 1 min</code></li>
</ul>
<p><strong>Example</strong>: <code>AP info: FIRSTAP</code><code>AP info: a very big AP in 1 min</code></p>
<h3 id="secondap" tabindex="-1"><a class="header-anchor" href="#secondap">SECONDAP</a></h3>
<p>Like FIRSTAP, but for the second available aircraft.</p>
<ul>
<li>Example format: <code>Next big AP in 9 min</code></li>
</ul>
<p><strong>Example</strong>: <code>also: SECONDAP</code><code>also: Next big AP in 9 min</code></p>
<h3 id="myqtf-(planned-for-v1.3)" tabindex="-1"><a class="header-anchor" href="#myqtf-(planned-for-v1.3)">MYQTF <em>(planned for v1.3)</em></a></h3>
<p>Replaced by the current antenna direction in words (e.g. <code>north</code>, <code>north east</code>, <code>east</code>, …).</p>
<ul>
<li>Source: Degree value in the MYQTF input field (to the right of the MYQRG field)</li>
</ul>
<hr>
<h2 id="variables-in-the-beacon" tabindex="-1"><a class="header-anchor" href="#variables-in-the-beacon">Variables in the Beacon</a></h2>
<p>All variables can also be used in the <strong>automatic beacon</strong> (interval messages). Recommended beacon configuration:</p>
<pre><code>calling cq at MYQRG, loc MYLOCATOR, GL all!
</code></pre>
<p>Since KST4Contest automatically reads QRG data from chat messages: if other stations also use KST4Contest, they will immediately see your QRG in the QRG column of their user list.</p>
<hr>
<h2 id="example-contest-workflow-with-macros" tabindex="-1"><a class="header-anchor" href="#example-contest-workflow-with-macros">Example Contest Workflow with Macros</a></h2>
<ol>
<li>Select a station in the user list → callsign is now pre-selected.</li>
<li>Press <code>Ctrl+1</code> → Snippet “Hi OM, try sked?” is addressed as a PM.</li>
<li>Press Enter → Message sent.</li>
<li>Station replies with frequency → QRG column is automatically filled.</li>
<li>Press <code>Ctrl+2</code> → Snippet “I am calling cq ur dir, pse lsn to me at 144.388” (MYQRG resolved).</li>
<li>Press Enter → Sent.</li>
</ol>
<p>No manual typing, no errors, no interruption to CQ calling.</p>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
@@ -0,0 +1,211 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ manual.title }} | KST4Contest Manual</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest manual page: {{ manual.title }}">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/manual/en/user-interface/">
<meta property="og:type" content="website">
<meta property="og:title" content="{{ manual.title }} | KST4Contest Manual">
<meta property="og:description" content="KST4Contest manual page: {{ manual.title }}">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/manual/en/user-interface/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="section">
<div class="card manual-content">
<p><a href="/manual/en/">← Back to manual overview</a></p>
<h1>User Interface</h1>
<h1 id="user-interface" tabindex="-1"><a class="header-anchor" href="#user-interface">User Interface</a></h1>
<blockquote>
<p>🇬🇧 You are reading the English version | 🇩🇪 <a href="/manual/de/benutzeroberflaeche/">Deutsche Version</a></p>
</blockquote>
<h2 id="connecting-to-the-chat" tabindex="-1"><a class="header-anchor" href="#connecting-to-the-chat">Connecting to the Chat</a></h2>
<ol>
<li>Select a <strong>chat category</strong> in the settings window (e.g. 144 MHz VHF, 432 MHz UHF, …).</li>
<li>Click the <strong>Connect</strong> button.</li>
<li>Wait for the connection to be established.</li>
</ol>
<blockquote>
<p>Disconnecting and reconnecting is only possible via the settings window. It is therefore recommended to keep the settings window open.</p>
</blockquote>
<hr>
<h2 id="main-window-overview" tabindex="-1"><a class="header-anchor" href="#main-window-overview">Main Window Overview</a></h2>
<p>The main window consists of several areas:</p>
<h3 id="pm-window-(top-left)" tabindex="-1"><a class="header-anchor" href="#pm-window-(top-left)">PM Window (top left)</a></h3>
<p>Shows all received <strong>private messages</strong> as well as intercepted public messages containing your own callsign. New messages appear in <strong>red</strong> and fade every 30 seconds from yellow to white.</p>
<h3 id="user-list-(chat-members)" tabindex="-1"><a class="header-anchor" href="#user-list-(chat-members)">User List (Chat Members)</a></h3>
<p>The central table of all currently active chat users. Columns (depending on configuration):</p>
<table>
<thead>
<tr>
<th>Column</th>
<th>Content</th>
</tr>
</thead>
<tbody>
<tr>
<td>Call</td>
<td>Stations callsign</td>
</tr>
<tr>
<td>Name</td>
<td>Name from the chat name field</td>
</tr>
<tr>
<td>Loc</td>
<td>Maidenhead locator</td>
</tr>
<tr>
<td>QRB</td>
<td>Distance in km</td>
</tr>
<tr>
<td>QTF</td>
<td>Direction in degrees</td>
</tr>
<tr>
<td>QRG</td>
<td>Automatically detected frequency</td>
</tr>
<tr>
<td>AP</td>
<td>AirScout aircraft data (when active)</td>
</tr>
<tr>
<td>Band colours</td>
<td>Worked / NOT-QRV status per band</td>
</tr>
</tbody>
</table>
<p><strong>Sorting</strong>: Click column headers. QRB sorting is numerical (corrected in v1.22).</p>
<h3 id="send-field" tabindex="-1"><a class="header-anchor" href="#send-field">Send Field</a></h3>
<p>Text input for outgoing messages. After clicking a callsign in the user list, the send field automatically receives focus start typing immediately without double-clicking (from v1.22).</p>
<h3 id="myqrg-field" tabindex="-1"><a class="header-anchor" href="#myqrg-field">MYQRG Field</a></h3>
<p>To the right of the send button. Shows the current own QRG, can also be entered manually.</p>
<h3 id="myqtf-field-(for-v1.3)" tabindex="-1"><a class="header-anchor" href="#myqtf-field-(for-v1.3)">MYQTF Field <em>(for v1.3)</em></a></h3>
<p>Input field for the current antenna direction. Used for the planned <code>MYQTF</code> variable.</p>
<hr>
<h2 id="filters" tabindex="-1"><a class="header-anchor" href="#filters">Filters</a></h2>
<p>The filter bar (from v1.21 as a flowpane for small screens):</p>
<ul>
<li><strong>Show only QTF</strong>: Activate direction filter (N/NE/E/… buttons or degree input)</li>
<li><strong>Show only QRB [km] &lt;=</strong>: Activate distance filter (toggle button)</li>
<li><strong>Hide Worked [Band]</strong>: Hide worked stations per band (one toggle per band)</li>
<li><strong>Hide NOT-QRV [Band]</strong>: Hide NOT-QRV-tagged stations per band</li>
</ul>
<hr>
<h2 id="station-info-panel-(further-info)" tabindex="-1"><a class="header-anchor" href="#station-info-panel-(further-info)">Station Info Panel (Further Info)</a></h2>
<p>Bottom right: Shows all messages of a selected station (CQ messages and PMs in one panel). A message filter can be pre-configured via the default filter in the Preferences.</p>
<p><strong>Sked reminders</strong> can also be activated here.</p>
<hr>
<h2 id="priority-list" tabindex="-1"><a class="header-anchor" href="#priority-list">Priority List</a></h2>
<p>Shows the top candidates calculated by the Score Service. Updates automatically in the background based on direction, distance and AP availability.</p>
<hr>
<h2 id="cluster-%26-qso-of-others" tabindex="-1"><a class="header-anchor" href="#cluster-%26-qso-of-others">Cluster &amp; QSO of Others</a></h2>
<p>Separate window (can be minimised). Shows the communication flow between other stations interesting during quieter contest periods.</p>
<hr>
<h2 id="menu" tabindex="-1"><a class="header-anchor" href="#menu">Menu</a></h2>
<h3 id="window" tabindex="-1"><a class="header-anchor" href="#window">Window</a></h3>
<ul>
<li><strong>Use Dark Mode</strong> (from v1.26): Toggle dark colour scheme on/off.</li>
</ul>
<hr>
<h2 id="window-sizes-and-dividers" tabindex="-1"><a class="header-anchor" href="#window-sizes-and-dividers">Window Sizes and Dividers</a></h2>
<p>From <strong>v1.21</strong>, clicking <strong>“Save Settings”</strong> also saves window sizes and divider positions of all panels in the configuration file, which are restored on the next start.</p>
<p>If you encounter display problems: delete the configuration file → KST4Contest creates new default values.</p>
<hr>
<h2 id="operating-tips" tabindex="-1"><a class="header-anchor" href="#operating-tips">Operating Tips</a></h2>
<ul>
<li><strong>Keep the settings window open</strong>: Quick access to enable/disable the beacon.</li>
<li><strong>Right-click in the user list</strong>: Opens the snippet menu and further actions (<a href="http://QRZ.com">QRZ.com</a> profile, set NOT-QRV tags).</li>
<li><strong>Enter from anywhere</strong>: When text is in the send field, Enter sends directly even if the focus is elsewhere.</li>
<li><strong>Stop the beacon</strong>: Switch off the beacon while scanning frequencies to avoid flooding the chat with messages.</li>
</ul>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
+110
View File
@@ -0,0 +1,110 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>KST4Contest Manual</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="Online manual for KST4Contest, the contest-optimized ON4KST chat client.">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/manual/">
<meta property="og:type" content="website">
<meta property="og:title" content="KST4Contest Manual">
<meta property="og:description" content="Online manual for KST4Contest, the contest-optimized ON4KST chat client.">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/manual/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="KST4Contest Manual">
<meta name="twitter:description" content="Online manual for KST4Contest, the contest-optimized ON4KST chat client.">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="hero">
<h1>KST4Contest Manual</h1>
<p>
User documentation for installation, configuration, features,
AirScout integration, log synchronization and contest workflow.
</p>
<div class="actions">
<a class="button" href="/manual/en/">English Manual</a>
<a class="button secondary" href="/manual/de/">Deutsches Handbuch</a>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
@@ -0,0 +1,111 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Hotfix Version 1.41.1</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest connects ON4KST chat, candidate selection, sked planning and station software for VHF, UHF and SHF contest operation.">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/news/2026-07-08-hotfix-version-1-41-1/">
<meta property="og:type" content="website">
<meta property="og:title" content="Hotfix Version 1.41.1">
<meta property="og:description" content="ON4KST chat, candidate selection, sked planning and station software in one VHF, UHF and SHF contest workflow.">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/news/2026-07-08-hotfix-version-1-41-1/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Hotfix Version 1.41.1">
<meta name="twitter:description" content="ON4KST chat, candidate selection, sked planning and station software in one VHF, UHF and SHF contest workflow.">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="hero">
<p class="badge">News · July 8, 2026</p>
<h1>Hotfix Version 1.41.1</h1>
<p class="lead">Hotfix of a bug in Version 1.41</p>
</section>
<section class="section narrow">
<article class="card content-card">
<h2>Version 1.41.1</h2>
<p>We had a bug, where KST4Contest would clear out the text field, where you would send your messages after a period. It also happend to set your Cursor back to the Sending Field, when you were filtering for a station. We fixed this bug today. The new release is <a href="https://github.com/praktimarc/kst4contest/releases/tag/v1.41.1">here</a>. You can also download the artifacts as always via the <a href="/download/">Downloads-Page</a>.</p>
</article>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
@@ -0,0 +1,120 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>AUR Packages now live of kst4contest</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest connects ON4KST chat, candidate selection, sked planning and station software for VHF, UHF and SHF contest operation.">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/news/2026-07-15-AUR-Packages/">
<meta property="og:type" content="website">
<meta property="og:title" content="AUR Packages now live of kst4contest">
<meta property="og:description" content="ON4KST chat, candidate selection, sked planning and station software in one VHF, UHF and SHF contest workflow.">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/news/2026-07-15-AUR-Packages/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="AUR Packages now live of kst4contest">
<meta name="twitter:description" content="ON4KST chat, candidate selection, sked planning and station software in one VHF, UHF and SHF contest workflow.">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="hero">
<p class="badge">News · July 15, 2026</p>
<h1>AUR Packages now live of kst4contest</h1>
<p class="lead">We now uploaded the packages of kst4contest to the AUR</p>
</section>
<section class="section narrow">
<article class="card content-card">
<h2>AUR Packages now live of KST4Contest</h2>
<p>We now have uploaded kst4contest as multiple Arch User Repository Packages. This allows yet another integration into Package Managers for easier updating toall Archlinux Users of our software. This one of many more repositories for our linux users to come. It is an continous effort. You can see the progress of making updating KST4Contest for our users easier <a href="https://github.com/praktimarc/kst4contest/issues/61">here</a>.</p>
<h3>AUR DISCLAIMER</h3>
<p>Before you use the AUR (if you did not use the AUR before) please read <a href="https://wiki.archlinux.org/title/Arch_User_Repository">this entry in the Arch wiki and the disclaimer</a> about security in the AUR.</p>
<h3>Packages provided to the AUR:</h3>
<ul>
<li><a href="https://aur.archlinux.org/packages/kst4contest">kst4contest</a>: This is the latest Release Build. If you install this package, you will compile the source code on your own machine. We recommend an JDK21 Enviroment for doing this</li>
<li><a href="https://aur.archlinux.org/packages/kst4contest-bin">kst4contest-bin</a>: This is the precompiled Binary, which is the same as the binary on the Github release page.</li>
<li><a href="https://aur.archlinux.org/packages/kst4contest-git">kstcontest-git</a>: This is the latest devolopment state of kst4contest. This is recommend for testers only, as things might break.</li>
</ul>
<p>Have fun with these packages. 73</p>
</article>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
@@ -0,0 +1,115 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>KST4Contest Website Launch</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="KST4Contest connects ON4KST chat, candidate selection, sked planning and station software for VHF, UHF and SHF contest operation.">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/news/2026-07-website-launch/">
<meta property="og:type" content="website">
<meta property="og:title" content="KST4Contest Website Launch">
<meta property="og:description" content="ON4KST chat, candidate selection, sked planning and station software in one VHF, UHF and SHF contest workflow.">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/news/2026-07-website-launch/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="KST4Contest Website Launch">
<meta name="twitter:description" content="ON4KST chat, candidate selection, sked planning and station software in one VHF, UHF and SHF contest workflow.">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="hero">
<p class="badge">News · July 7, 2026</p>
<h1>KST4Contest Website Launch</h1>
<p class="lead">The new KST4Contest website is being built as a static, SEO-friendly product portal with GitHub-based documentation.</p>
</section>
<section class="section narrow">
<article class="card content-card">
<h2>A new home for KST4Contest</h2>
<p>KST4Contest now has its own website at <code>kst4contest.hamradioonline.de</code>.</p>
<p>The site is built with Eleventy, generated from version-controlled Markdown and deployed as a fast static website.</p>
<h2>Why this matters</h2>
<p>The goal is to make KST4Contest easier to discover, easier to document and easier to maintain.</p>
<p>Documentation, release information, feature pages and future updates can now grow from a shared content model.</p>
</article>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
+132
View File
@@ -0,0 +1,132 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>KST4Contest News</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="News, release updates and development notes for KST4Contest.">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/news/">
<meta property="og:type" content="website">
<meta property="og:title" content="KST4Contest News">
<meta property="og:description" content="News, release updates and development notes for KST4Contest.">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/news/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="KST4Contest News">
<meta name="twitter:description" content="News, release updates and development notes for KST4Contest.">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="hero">
<p class="badge">News</p>
<h1>Development updates and release notes.</h1>
<p class="lead">
Updates about KST4Contest releases, website improvements and contest workflow development.
</p>
</section>
<section class="section">
<div class="grid">
<article class="card">
<p class="eyebrow">July 15, 2026</p>
<h3><a href="/news/2026-07-15-AUR-Packages/">AUR Packages now live of kst4contest</a></h3>
<p>We now uploaded the packages of kst4contest to the AUR</p>
<a href="/news/2026-07-15-AUR-Packages/">Read more →</a>
</article>
<article class="card">
<p class="eyebrow">July 8, 2026</p>
<h3><a href="/news/2026-07-08-hotfix-version-1-41-1/">Hotfix Version 1.41.1</a></h3>
<p>Hotfix of a bug in Version 1.41</p>
<a href="/news/2026-07-08-hotfix-version-1-41-1/">Read more →</a>
</article>
<article class="card">
<p class="eyebrow">July 7, 2026</p>
<h3><a href="/news/2026-07-website-launch/">KST4Contest Website Launch</a></h3>
<p>The new KST4Contest website is being built as a static, SEO-friendly product portal with GitHub-based documentation.</p>
<a href="/news/2026-07-website-launch/">Read more →</a>
</article>
</div>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>
+166
View File
@@ -0,0 +1,166 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Privacy Policy | KST4Contest</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08110b">
<meta name="description" content="Privacy policy for the KST4Contest website.">
<link rel="canonical" href="https://kst4contest.hamradioonline.de/privacy/">
<meta property="og:type" content="website">
<meta property="og:title" content="Privacy Policy | KST4Contest">
<meta property="og:description" content="Privacy policy for the KST4Contest website.">
<meta property="og:url" content="https://kst4contest.hamradioonline.de/privacy/">
<meta property="og:site_name" content="KST4Contest">
<meta property="og:locale" content="en_GB">
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Privacy Policy | KST4Contest">
<meta name="twitter:description" content="Privacy policy for the KST4Contest website.">
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
<link rel="stylesheet" href="/assets/css/main.css?v=1784595000789">
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
</head>
<body>
<div class="site-bg" aria-hidden="true"></div>
<header class="site-header">
<a class="brand" href="/" aria-label="KST4Contest home">
<span class="brand-mark" aria-hidden="true"></span>
<span>
<strong>KST4Contest</strong>
<small>ON4KST Contest Client</small>
</span>
</a>
<nav class="site-nav" aria-label="Main navigation">
<a href="/">Home</a>
<a href="/features/">Features</a>
<a href="/screenshots/">Screenshots</a>
<a href="/manual/">Manual</a>
<a href="/news/">News</a>
<a href="/roadmap/">Roadmap</a>
<a href="/about/">About</a>
<a href="/faq/">FAQ</a>
<a href="/support/">Support</a>
<a class="nav-cta" href="/download/">Download</a>
</nav>
</header>
<main>
<section class="hero">
<p class="badge">Privacy</p>
<h1>Privacy Policy</h1>
<p class="lead">Information about data processing on this static website.</p>
</section>
<section class="section narrow">
<article class="card content-card">
<h2>Controller</h2>
<p>
Marc Fröhlich<br>
Rheingoldstr. 6<br>
68199 Mannheim<br>
Germany
</p>
<h2>Access logs</h2>
<p>
When this website is accessed, the web server may process technical access data such as
IP address, requested URL, date and time, user agent and referrer.
This processing is used to provide the website, maintain security and investigate technical issues.
</p>
<h2>Legal basis</h2>
<p>
The legal basis is Art. 6(1)(f) GDPR: legitimate interest in secure and reliable operation
of the website.
</p>
<h2>Cookies and tracking</h2>
<p>
This website currently does not use cookies, analytics tracking, advertising pixels or user profiling.
</p>
<h2>External links</h2>
<p>
This website links to GitHub for source code, releases and downloads. When you follow these links,
GitHub is responsible for its own data processing.
</p>
<h2>
Support via Ko-fi
</h2>
<p>
This website links to Ko-fi for voluntary financial support.
Payments are processed entirely by Ko-fi and its payment providers.
KST4Contest itself never receives or processes payment information.
</p>
<h2>Your rights</h2>
<p>
You may have the right to access, rectification, erasure, restriction of processing,
data portability and objection under the GDPR.
</p>
<h2>Supervisory authority</h2>
<p>
You have the right to lodge a complaint with a competent data protection supervisory authority.
</p>
</article>
</section></main>
<footer class="site-footer">
<div class="footer-grid">
<div>
<strong>KST4Contest</strong>
<p>ON4KST chat, candidate selection and sked planning for VHF, UHF and SHF contest operation.</p>
</div>
<div>
<strong>Project</strong>
<p><a href="/features/">Features</a></p>
<p><a href="/download/">Download</a></p>
<p><a href="/manual/">Manual</a></p>
<p><a href="/roadmap/">Roadmap</a></p>
</div>
<div>
<strong>Community</strong>
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
<p><a href="/contact/">Contact</a></p>
<p><a href="/support/">❤️ Support KST4Contest</a></p>
</div>
<div>
<strong>Legal</strong>
<p><a href="/legal-notice/">Legal Notice</a></p>
<p><a href="/privacy/">Privacy Policy</a></p>
</div>
</div>
</footer>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More