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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions .github/workflows/diagnostic-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: Diagnostic build

on:
pull_request:
workflow_dispatch:

jobs:
build-wotmod:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Prepare diagnostic build tree
shell: bash
run: |
set -euo pipefail
VERSION="0.1.0-diagnostic-${GITHUB_SHA::7}"
echo "SMARTRECONNECT_VERSION=$VERSION" >> "$GITHUB_ENV"

rm -rf build
mkdir -p build
cp -r res build/

perl -i -pe "s/\{\{VERSION\}\}/$VERSION/g" \
build/res/scripts/client/gui/mods/smartReconnect/Config.py

META=$(<meta.xml)
META="${META/\{\{VERSION\}\}/$VERSION}"
printf '%s\n' "$META" > build/meta.xml

- name: Compile WoT mod with Python 2.7
shell: bash
run: |
set -euo pipefail
docker run --rm \
-v "$PWD:/work" \
-w /work \
python:2.7 \
python -m compileall ./build/res

- name: Verify compiled payload
shell: bash
run: |
set -euo pipefail
test -f build/res/scripts/client/gui/mods/mod_smartReconnect.pyc
test -f build/res/scripts/client/gui/mods/smartReconnect/SmartReconnect.pyc
test -f build/res/scripts/client/gui/mods/smartReconnect/ConnectionMonitor.pyc
test -f build/res/scripts/client/gui/mods/smartReconnect/ReconnectController.pyc
test -f build/res/scripts/client/gui/mods/smartReconnect/Config.pyc

if grep -R "{{VERSION}}" build/res build/meta.xml; then
echo "Unresolved version placeholder found"
exit 1
fi

- name: Package .wotmod
shell: bash
run: |
set -euo pipefail
OUTPUT="mewt0.smartReconnect_${SMARTRECONNECT_VERSION}.wotmod"
cd build
zip -r -0 -X "$OUTPUT" res -i '*.pyc'
zip -r -0 -X "$OUTPUT" meta.xml
mv "$OUTPUT" ../
cd ..
echo "SMARTRECONNECT_ARTIFACT=$OUTPUT" >> "$GITHUB_ENV"

- name: Inspect archive
shell: bash
run: |
set -euo pipefail
unzip -l "$SMARTRECONNECT_ARTIFACT"

if unzip -l "$SMARTRECONNECT_ARTIFACT" | grep -E '\.py($| )'; then
echo "Source .py file unexpectedly packaged"
exit 1
fi

- name: Upload diagnostic .wotmod
uses: actions/upload-artifact@v4
with:
name: SmartReconnect-diagnostic-${{ github.sha }}
path: ${{ env.SMARTRECONNECT_ARTIFACT }}
if-no-files-found: error
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
build/
*.wotmod
*.mtmod
*.pyc
__pycache__/
.DS_Store
88 changes: 87 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,87 @@
# SmartReconnect
# SmartReconnect

SmartReconnect is an experimental World of Tanks client mod intended to shorten recovery from a dead battle connection.

## Current milestone

**v0.1 is diagnostic-only. It does not disconnect or reconnect automatically.**

The first build validates the same lag signal used by WoT's battle debug panel before any connection-changing action is enabled.

It polls:

- `BigWorld.statLagDetected()`
- `BigWorld.statPing()`

Default behavior:

1. Normal connection -> monitor remains idle.
2. Lag indicator becomes red -> start a timer.
3. Indicator returns to normal -> reset the timer.
4. Indicator remains red for 3 seconds -> write `WOULD RECONNECT` to `python.log`.
5. No network action is performed in diagnostic mode.

`Ctrl+K` is also detected as a manual reconnect request, but in diagnostic mode it only logs `WOULD RECONNECT`.

## Planned reconnect path

`RED -> grace period -> goToLoginByDisconnectRQ() -> LOGIN state -> WGC login -> ongoing battle`

The reconnect controller will use WoT's own gameplay and login services rather than terminating the process or manipulating sockets directly.

## Project layout

```text
SmartReconnect/
├── README.md
├── .gitignore
├── meta.xml
├── build.sh
├── docs/
│ └── ARCHITECTURE.md
└── res/scripts/client/gui/mods/
├── mod_smartReconnect.py
└── smartReconnect/
├── __init__.py
├── Config.py
├── ConnectionMonitor.py
├── ReconnectController.py
└── SmartReconnect.py
```

## Build

Requires a Python 2 environment compatible with the WoT client mod pipeline plus `zip` and a POSIX shell.

```bash
./build.sh -v 0.1.0
```

The result is written to the repository root as:

```text
mewt0.smartReconnect_0.1.0.wotmod
```

Copy it into:

```text
World_of_Tanks/mods/<current-game-version>/
```

Then inspect `python.log` for lines beginning with `[SmartReconnect]`.

## Diagnostic test

A successful first test should look roughly like this:

```text
[SmartReconnect] battle monitor started
[SmartReconnect] RED started ping=...
[SmartReconnect] RED elapsed=1.0s ping=...
[SmartReconnect] RED elapsed=2.0s ping=...
[SmartReconnect] RED threshold reached elapsed=3.0s
[SmartReconnect] WOULD RECONNECT reason=auto-lag
```

If the indicator returns to normal before the threshold, the timer resets and no reconnect request is produced.
43 changes: 43 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/bin/bash
set -e

MOD_NAME="mewt0.smartReconnect"
VERSION=""

while getopts "v:" flag; do
case "${flag}" in
v) VERSION=${OPTARG} ;;
esac
done

if [ -z "$VERSION" ]; then
echo "Usage: ./build.sh -v <version>"
exit 1
fi

rm -rf ./build
mkdir -p ./build
cp -r ./res ./build/

CONFIG_PATH="./build/res/scripts/client/gui/mods/smartReconnect/Config.py"
perl -i -pe "s/\{\{VERSION\}\}/$VERSION/g" "$CONFIG_PATH"

python2 -m compileall ./build/res

META=$(<meta.xml)
META="${META/\{\{VERSION\}\}/$VERSION}"

cd ./build
echo "$META" > ./meta.xml

OUTPUT="${MOD_NAME}_${VERSION}.wotmod"
rm -f "$OUTPUT"

zip -r -0 -X "$OUTPUT" res -i "*.pyc"
zip -r -0 -X "$OUTPUT" meta.xml

cd ..
cp "./build/$OUTPUT" "./$OUTPUT"
rm -rf ./build

echo "Built $OUTPUT"
61 changes: 61 additions & 0 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# SmartReconnect architecture

## Problem

During a dead World of Tanks battle connection the client can show the red network/lag indicator while the battle appears frozen, then wait for its normal timeout before returning the player to login.

SmartReconnect aims to shorten that recovery path without patching the executable, manipulating packets, or replacing the game's connection stack.

## Detector

WoT's own battle debug controller reads:

```python
isLaggingNow = BigWorld.statLagDetected()
ping = BigWorld.statPing()
```

SmartReconnect deliberately uses the same native lag signal instead of external ICMP/HTTP probes.

Polling interval: `0.2s`.

## State model

```text
IDLE
-> MONITORING
-> LAG_SUSPECTED
-> RECONNECT_REQUESTED
```

v0.1 stops at `RECONNECT_REQUESTED` and writes `WOULD RECONNECT` to the log.

Future reconnect flow:

```text
RECONNECT_REQUESTED
-> goToLoginByDisconnectRQ()
-> wait for LOGIN gameplay state
-> WGC login on the selected server
-> WoT rejoins the ongoing arena using its normal reconnect path
```

## False-positive protection

Automatic reconnect must not fire on a brief lag spike. The detector therefore requires a continuous lag state for `LAG_GRACE_PERIOD` seconds. Any healthy sample resets the timer.

The first live validation build intentionally has all network-changing actions disabled.

## Manual fallback

`Ctrl+K` produces a manual reconnect request. In v0.1 it is also diagnostic-only.

## Next milestone

After validating logs on the target client:

1. add a guarded real disconnect through `IGameplayLogic.goToLoginByDisconnectRQ()`;
2. observe `GameplayStateID.LOGIN` rather than sleeping for a guessed delay;
3. start WGC login through the existing login manager;
4. add single-flight protection so one outage cannot start multiple reconnects;
5. stop automatic retries after a failed login until behavior is measured.
Loading
Loading