Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
af244d5
- Hotkey support for client
Kaspar-Metsa Dec 15, 2025
e248f51
Removed debug statements
Kaspar-Metsa Dec 15, 2025
a926724
Fixes
Kaspar-Metsa Dec 16, 2025
74cf049
Move _hotkey command from InputWidget to parser system
Kaspar-Metsa Dec 16, 2025
44282d1
Fixes for formatting
Kaspar-Metsa Dec 16, 2025
0d3db28
Fixed pipeline errors:
Kaspar-Metsa Dec 17, 2025
cd66844
Fixed appx error
Kaspar-Metsa Dec 17, 2025
32db382
Fixed appx error#2
Kaspar-Metsa Dec 17, 2025
7707f04
Added tests, fixed code quality issues
Kaspar-Metsa Dec 17, 2025
7c3d9b6
Fixed code quality issues
Kaspar-Metsa Dec 17, 2025
c9bd7fd
Fixed code quality issues
Kaspar-Metsa Dec 17, 2025
4e0069c
Fixed code quality issues
Kaspar-Metsa Dec 17, 2025
048209b
Fixed code quality issues
Kaspar-Metsa Dec 17, 2025
8cd4b7b
Fixed code quality issues
Kaspar-Metsa Dec 17, 2025
7a26d27
Fixed code quality issues
Kaspar-Metsa Dec 17, 2025
a1f8e48
Fixed code quality issues
Kaspar-Metsa Dec 17, 2025
fc29fb2
Fixed code quality issues
Kaspar-Metsa Dec 17, 2025
4ce7911
fix test
Kaspar-Metsa Dec 17, 2025
b52dabd
Optimized Hotkey Lookup
Kaspar-Metsa Dec 18, 2025
63c6b59
New path for WASM script
Kaspar-Metsa Dec 18, 2025
ca47e59
Editing with _config edit is done everything together now
Kaspar-Metsa Dec 18, 2025
f34c1ab
Added _help commands for _hotkey and _config. removed import/export tab
Kaspar-Metsa Dec 18, 2025
3f0458c
clang formatter fix
Kaspar-Metsa Dec 18, 2025
794907b
Updated proxy.cpp to use HotkeyManager methods properly:
Kaspar-Metsa Dec 19, 2025
13fab88
use stdlib containers and keep QString conversions
Kaspar-Metsa Dec 19, 2025
22b189a
Fixed tests
Kaspar-Metsa Dec 19, 2025
2db63d9
Fixed formatting
Kaspar-Metsa Dec 19, 2025
e27fe3d
Merge branch 'MUME:master' into master
KasparMetsa Dec 19, 2025
cd16d44
Fixed formatting
Kaspar-Metsa Dec 19, 2025
5f91acc
Code review fixes
Kaspar-Metsa Dec 19, 2025
a1b23de
Merge branch 'MUME:master' into master
KasparMetsa Dec 19, 2025
431f9a5
Revert appx fix
Kaspar-Metsa Dec 19, 2025
87781fa
Fixed tests
Kaspar-Metsa Dec 19, 2025
084589e
appx fix
Kaspar-Metsa Dec 20, 2025
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ CMakeUserPresets.json
CMakeSettings.json
cmake-build-debug/

# Qt installation from aqtinstall
6.5.3/


# snapcraft
parts/
Expand Down
29 changes: 29 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,32 @@ To enable fast, cached builds, the following steps are **required**:
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
... [Other flags from BUILD.md]
```

---

## Code Formatting (clang-format)

CI uses Ubuntu clang-format 18.1.8 via Docker. To run the exact same check locally:

```bash
# Check a specific file
docker run --platform linux/amd64 --rm -v "$(pwd)":/src --entrypoint /bin/sh \
ghcr.io/jidicula/clang-format:18 -c \
"clang-format --dry-run -Werror -style=file /src/tests/TestHotkeyManager.cpp && echo '✓ Formatting OK'" \
|| echo '✗ Formatting errors found'

# Auto-fix a file
docker run --platform linux/amd64 --rm -v "$(pwd)":/src --entrypoint /bin/sh \
ghcr.io/jidicula/clang-format:18 -c \
"clang-format -i -style=file /src/tests/TestHotkeyManager.cpp && echo '✓ File formatted'"

# Check all src and tests files
docker run --platform linux/amd64 --rm -v "$(pwd)":/src --entrypoint /bin/sh \
ghcr.io/jidicula/clang-format:18 -c \
"find /src/src /src/tests -name '*.cpp' -o -name '*.h' | xargs clang-format --dry-run -Werror -style=file && echo '✓ All files OK'" \
|| echo '✗ Formatting errors found'
```

Note: `--platform linux/amd64` is required on ARM Macs for x86 emulation.

Alternative (faster but may differ slightly): `brew install llvm@18` then use `/opt/homebrew/opt/llvm@18/bin/clang-format`
121 changes: 121 additions & 0 deletions docs/WEBASSEMBLY_BUILD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
---
layout: default
title: WebAssembly Build Guide
---

## WebAssembly Build Guide

### First-Time Setup: 1. Install Emscripten SDK

```bash
cd ~/dev # or any directory you prefer
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install 3.1.25
./emsdk activate 3.1.25
```

### 2. Install Qt WebAssembly

```bash
brew install aqtinstall
cd <MMAPPER_ROOT> # your MMapper source directory
aqt install-qt mac desktop 6.5.3 wasm_multithread -m qtwebsockets -O .
```

### 3. Build script

The build script is located at `scripts/build-wasm.sh`:

```bash
#!/bin/bash
set -e

# Source Emscripten environment
# Adjust path if you installed emsdk elsewhere
source "$HOME/dev/emsdk/emsdk_env.sh"

# Paths - adjust these to match your setup
MMAPPER_SRC="<MMAPPER_ROOT>" # e.g., /Users/yourname/dev/MMapper
QT_WASM="$MMAPPER_SRC/6.5.3/wasm_multithread"
QT_HOST="$MMAPPER_SRC/6.5.3/macos"

"$QT_WASM/bin/qt-cmake" \
-S "$MMAPPER_SRC" \
-B "$MMAPPER_SRC/build-wasm" \
-DQT_HOST_PATH="$QT_HOST" \
-DWITH_OPENSSL=OFF \
-DWITH_TESTS=OFF \
-DWITH_WEBSOCKET=ON \
-DWITH_UPDATER=OFF \
-DCMAKE_BUILD_TYPE=Release

# Build with limited parallelism to avoid system slowdown
# --parallel N uses N CPU cores. Omit the number to use all cores.
# Reduce N if your system becomes unresponsive during build.
cmake --build "$MMAPPER_SRC/build-wasm" --parallel 4
```

### 4. Server script

The server script is located at `scripts/server.py`:

```python
import http.server
import socketserver

PORT = 9742

class MyHandler(http.server.SimpleHTTPRequestHandler):
def end_headers(self):
# Required headers for SharedArrayBuffer (WASM multithreading)
self.send_header("Cross-Origin-Opener-Policy", "same-origin")
self.send_header("Cross-Origin-Embedder-Policy", "require-corp")
http.server.SimpleHTTPRequestHandler.end_headers(self)

with socketserver.TCPServer(("", PORT), MyHandler) as httpd:
print(f"Serving at http://localhost:{PORT}/mmapper.html")
httpd.serve_forever()
```

---

## Daily Use (Everything Installed)

### Build

```bash
cd <MMAPPER_ROOT>
./scripts/build-wasm.sh
```

### Run

```bash
cd build-wasm/src
python3 ../../scripts/server.py
```

### Open

```text
http://localhost:9742/mmapper.html
```

### Clean rebuild

```bash
rm -rf build-wasm && ./scripts/build-wasm.sh
```

---

## Path Reference

- **`<MMAPPER_ROOT>`**: MMapper source directory
(e.g., `/Users/yourname/dev/MMapper`)
- **`$HOME/dev/emsdk`**: Emscripten SDK location (`~/dev/emsdk`)
- **`6.5.3/wasm_multithread`**: Qt WASM installed by aqt
(inside `<MMAPPER_ROOT>`)
- **`6.5.3/macos`**: Qt native macOS host tools
(inside `<MMAPPER_ROOT>`)
31 changes: 31 additions & 0 deletions scripts/build-wasm.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/bin/bash
set -e

# Source Emscripten environment
# IMPORTANT: Change this path to match your emsdk installation location
source "$HOME/dev/emsdk/emsdk_env.sh"

# Paths - automatically detect project root (parent of scripts directory)
MMAPPER_SRC="$(cd "$(dirname "$0")/.." && pwd)"
QT_WASM="$MMAPPER_SRC/6.5.3/wasm_multithread"
QT_HOST="$MMAPPER_SRC/6.5.3/macos"

# Configure with qt-cmake
"$QT_WASM/bin/qt-cmake" \
-S "$MMAPPER_SRC" \
-B "$MMAPPER_SRC/build-wasm" \
-DQT_HOST_PATH="$QT_HOST" \
-DWITH_OPENSSL=OFF \
-DWITH_TESTS=OFF \
-DWITH_WEBSOCKET=ON \
-DWITH_UPDATER=OFF \
-DCMAKE_BUILD_TYPE=Release

# Build (limited to 4 cores to avoid system slowdown)
cmake --build "$MMAPPER_SRC/build-wasm" --parallel 4

echo ""
echo "Build complete!"
echo "To run:"
echo " cd $MMAPPER_SRC/build-wasm/src && python3 $MMAPPER_SRC/scripts/server.py"
echo "Then open: http://localhost:9742/mmapper.html"
15 changes: 15 additions & 0 deletions scripts/server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import http.server
import socketserver

PORT = 9742

class MyHandler(http.server.SimpleHTTPRequestHandler):
def end_headers(self):
self.send_header("Cross-Origin-Opener-Policy", "same-origin")
self.send_header("Cross-Origin-Embedder-Policy", "require-corp")
http.server.SimpleHTTPRequestHandler.end_headers(self)

with socketserver.TCPServer(("", PORT), MyHandler) as httpd:
print(f"Serving MMapper WASM at http://localhost:{PORT}/mmapper.html")
print("Press Ctrl+C to stop")
httpd.serve_forever()
10 changes: 10 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ set(mmapper_SRCS
configuration/PasswordConfig.h
configuration/configuration.cpp
configuration/configuration.h
configuration/HotkeyManager.cpp
configuration/HotkeyManager.h
display/CanvasMouseModeEnum.h
display/Characters.cpp
display/Characters.h
Expand Down Expand Up @@ -432,6 +434,7 @@ set(mmapper_SRCS
parser/AbstractParser-Commands.h
parser/AbstractParser-Config.cpp
parser/AbstractParser-Group.cpp
parser/AbstractParser-Hotkey.cpp
parser/AbstractParser-Mark.cpp
parser/AbstractParser-Room.cpp
parser/AbstractParser-Timer.cpp
Expand Down Expand Up @@ -867,6 +870,13 @@ set(CPACK_PACKAGE_VERSION_MAJOR ${CMAKE_MATCH_1})
set(CPACK_PACKAGE_VERSION_MINOR ${CMAKE_MATCH_2})
set(CPACK_PACKAGE_VERSION_PATCH ${CMAKE_MATCH_3})
set(CPACK_PACKAGE_VERSION_TWEAK ${CMAKE_MATCH_4})
# If parsing failed (e.g., version is just a commit hash), fall back to MMAPPER_VERSION
if(NOT CPACK_PACKAGE_VERSION_MAJOR)
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+).*$" _ "${MMAPPER_VERSION}")
set(CPACK_PACKAGE_VERSION_MAJOR ${CMAKE_MATCH_1})
set(CPACK_PACKAGE_VERSION_MINOR ${CMAKE_MATCH_2})
set(CPACK_PACKAGE_VERSION_PATCH ${CMAKE_MATCH_3})
endif()
if(NOT CPACK_PACKAGE_VERSION_TWEAK)
# Set to 0 if the commit count is missing
set(CPACK_PACKAGE_VERSION_TWEAK 0)
Expand Down
16 changes: 16 additions & 0 deletions src/client/ClientWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ ClientWidget::ClientWidget(ConnectionListener &listener, QWidget *const parent)

ClientWidget::~ClientWidget() = default;

void ClientWidget::playMume()
{
qDebug() << "[ClientWidget::playMume] Auto-starting client and connecting to MUME";
getUi().parent->setCurrentIndex(1);
getTelnet().connectToHost(m_listener);
}

ClientWidget::Pipeline::~Pipeline()
{
objs.clientTelnet.reset();
Expand Down Expand Up @@ -112,6 +119,15 @@ void ClientWidget::initStackedInputWidget()
getSelf().slot_onShowMessage(msg);
}
void virt_requestPassword() final { getSelf().getInput().requestPassword(); }
void virt_scrollDisplay(bool pageUp) final
{
auto *scrollBar = getDisplay().verticalScrollBar();
if (scrollBar) {
int pageStep = scrollBar->pageStep();
int delta = pageUp ? -pageStep : pageStep;
scrollBar->setValue(scrollBar->value() + delta);
}
}
};
auto &out = m_pipeline.outputs.stackedInputWidgetOutputs;
out = std::make_unique<LocalStackedInputWidgetOutputs>(*this);
Expand Down
1 change: 1 addition & 0 deletions src/client/ClientWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class NODISCARD_QOBJECT ClientWidget final : public QWidget
public:
NODISCARD bool isUsingClient() const;
void displayReconnectHint();
void playMume();

private:
void relayMessage(const QString &msg) { emit sig_relayMessage(msg); }
Expand Down
Loading