Skip to content

About

A Robotic Process Automation (RPA) framework for Mahjong Soul (雀魂)

Topics

Resources

Stars

29 stars

Watchers

5 watching

Forks

Repository files navigation

MajsoulRPA

A Robotic Process Automation (RPA) framework for Mahjong Soul (雀魂)

This project is a fork of Cryolite's majsoul-rpa, but has been completely redesigned based on the proactor pattern. While some API names and design ideas were borrowed, the architecture and codebase are entirely new.

Note

This framework is intended to enable the participation of bots in friendly matches and tournaments where bot participation is agreed upon by all players involved.

This framework does not support the functionality to enter bots into open matches (including, but not limited to, ranked matches and special rooms within tournament matches). Furthermore, there is no intention to introduce such functionality in the future.

Warning

Users of this framework accept full responsibility for its use. The authors shall bear no liability whatsoever for any damages resulting from utilization of this framework, including, but not limited to, account suspension or legal repercussions.

🚧 Work in Progress

MajsoulRPA is currently in active development. Login, Home screen operations, friendly-room management, tournament-lobby entry, and in-match gameplay are available.

Workarounds for some in-match situations are still being developed, using the v1-develop branch as a reference for established behavior and match-flow knowledge.

Tournament-room operations remain unimplemented, so tournament matches cannot yet be automated end to end.

Key differences from the original project

  • ✅ Requires Python 3.12 or later
  • 🗑️ Removed dependencies on Docker, Redis, and mitmproxy
  • 🖥️ Supports moving browser window position after launch
  • 🖱️ Mouse can be used freely even while RPA is running
  • 📐 Supports browser viewport sizes other than 1920 × 1080
  • 🀄 Supports three-player mahjong

Because WebSocket capture no longer uses mitmproxy, installing a local CA certificate is no longer required.

Implementation concept diagram

implementation-concept-diagram

Installation

Remote browser host (the machine that will run the browser)

majsoulrpa$ pip install .[browser]
# Install Chromium browser binaries on the browser host
majsoulrpa$ playwright install chromium --with-deps

RPA client host (the machine running the RPA client which performs automation)

majsoulrpa$ pip install .[rpa]

Combined setup (browser and client on the same host)

majsoulrpa$ pip install .[browser,rpa]

Optional: fetch verification emails from AWS S3

majsoulrpa$ pip install .[s3]

Make AWS credentials available using one of the following methods:

  • Save them in ~/.aws/credentials

  • Set them via environment variables:

    export AWS_ACCESS_KEY_ID=...
    export AWS_SECRET_ACCESS_KEY=...
    export AWS_REGION=...

Usage

🌐 Remote browser

You can launch the remote browser directly from the command line:

majsoulrpa-browser

It can also be invoked from Python code:

import asyncio

from majsoulrpa import AppConfig
from majsoulrpa.browser import run_browser_host

asyncio.run(run_browser_host(AppConfig()))

🤖 RPA client

The RPA client is used from Python code. A typical flow looks like this:

import asyncio
from typing import Any

from majsoulrpa import AppConfig, RPAApp
from majsoulrpa.screens.home import HomeScreen
from majsoulrpa.screens.login import LoginScreen

rpa = RPAApp()


@rpa.on(LoginScreen)
async def on_login(screen: LoginScreen, data: Any) -> Any:
    ...
    return data


@rpa.on(HomeScreen)
async def on_home(screen: HomeScreen, data: Any) -> Any:
    ...
    return data


data = ...  # You can set any value here; it will be carried through the client
asyncio.run(rpa.run(AppConfig(), data))
  • Register callbacks with @rpa.on(Screen)
  • Only the registered Screens are subject to detection; unregistered ones are ignored
  • data can hold arbitrary values and is passed along within the client
  • Call rpa.run(...) to start execution

See examples/ for complete implementations.

Important

The email address you use must be linked to your Yostar ID.

Reporting an unsupported in-match layout

Some rare in-match layouts cannot be implemented safely until their click coordinates have been confirmed. MajsoulRPA stops without clicking a guessed position and raises ScreenNotImplementedOperationError. The exception carries the screenshot captured when the unsupported layout was encountered. You can save it as follows:

from pathlib import Path

from majsoulrpa.screens import ScreenNotImplementedOperationError

try:
    ...
except ScreenNotImplementedOperationError as error:
    error.save_screenshot(Path("screenshots"))
    # Saved as screenshots/YYYYMMDDTHHMMSSZ-ScreenNotImplementedOperationError.png
    raise

If you encounter this exception, please help us investigate the layout by opening an issue with:

  • the operation being attempted and the number and order of its candidates;
  • the saved screenshot; and
  • any relevant decoded Sniffer logs, after redacting account IDs and authentication information such as tokens.

Before sharing the screenshot, redact any account name or other personal information. Before sharing Sniffer logs, redact account IDs, tokens, cookies, and any other authentication information.

License

Licensed under the MIT license.

About

A Robotic Process Automation (RPA) framework for Mahjong Soul (雀魂)

Topics

Resources

Stars

29 stars

Watchers

5 watching

Forks

Releases

Packages

Used by

Contributors

Languages