Skip to main content

A MUD client core written in Python

Project description

PyMudClient: 用 Python 開發的 MUD Client 核心

這是什麼?

  • MUD, Multi-User Dungeon,是多人即時虛擬類遊戲,通常以文字描述為基礎。
  • 此 library 的目的是提供一個 MUD Client 核心,讓人可透過 Python 方便的使用 Trigger, Timer, Alias, Variable 功能來遊玩 MUD game。

支援功能

  • Terminal 的 encoding 使用 UTF-8,不需要特別調整。
  • 連線:根據輸入的 host 跟 port 進行連線。
  • 斷線重連:發生異常、server 重新啟動導致的斷線,會自動重新連線。
  • 顯示:顯示 server 回傳的內容。
    • 有處理輸入中文的顯示問題。
    • 只針對萬王之王 (kk.muds.idv.tw:4000) 進行測試過。
  • 輸入介面:支援中文輸入、剪貼簿操作、游標移動、指令編輯等功能。
  • Alias:建立指令別名,可以把複雜的指令簡化成短指令,送出指令或者執行 function,支援參數替換。
  • Trigger:觸發器。從 server 接收到的內容中有符合 regex 的話,可以自動傳送指令或者執行 function。
  • Timer:固定秒數送出指令或者執行 function。
  • Variable:可以建立常用變數,在 Trigger, Alias, Timer 內要送指令到 server 時使用。
  • color_print: 可以印出帶有顏色的文字的 function,使用 MUD 的顏色字串,可搭配 MudColorAlias 使用。
  • MudColorAlias: 提供在 MUD 內常用來定義顏色的字串。

安裝

pip install pymudclient

使用範例

import settings
from aliases import ALIAS_LIST
from pymudclient import PyMudClient
from timers import TIMER_LIST
from triggers import TRIGGER_LIST
from variable_map import VARIABLE_MAP


def main():
    mud = PyMudClient(
        host=settings.HOST,
        port=settings.PORT,
        account=settings.ACCOUNT,
        password=settings.PASSWORD,
        alias_list=ALIAS_LIST,
        trigger_list=TRIGGER_LIST,
        timer_list=TIMER_LIST,
        variable_map=VARIABLE_MAP,
        encoding='big5hkscs',
    )
    mud.run()


if __name__ == '__main__':
    main()

輸入介面

  • 可輸入中文字。
  • 從剪貼簿貼上可正常使用。
  • 輸入的文字會固定出現在最後一行,此時按下 Enter 可以再次送出。
  • 可使用 左/右/Home/End 移動位置。
  • 可使用 Backspace/Ctrl-H 刪除游標位置前面的字元。
  • 可使用 Delete 刪除游標位置後面的字元。
  • 可使用 Ctrl-W 刪除前面一個 word (仿照 terminal 中操作的方式)。
  • 按下 Enter 送出後,會記住最後一次送出的文字,可以進行編輯,或直接按 Enter 再送一次。

API Reference

PyMudClient

  • PyMudClient 的主體
PyMudClient.__init__(
    self,
    host: str,
    port: int,
    account: str | None = None,
    password: str | None = None,
    alias_list: list[Alias] | None = None,
    trigger_list: list[Trigger] | None = None,
    timer_list: list[Timer] | None = None,
    variable_map: dict[str, str] | None = None,
    pre_process_recv_content_func: Callable[[str], str] | None = None,
    encoding: str = 'latin1',
)
  • host: 連線的主機網址或 IP。
  • port: 連線的主機 port。
  • account: (optional) 帳號,會以 'ACCOUNT' 加入 variable_map,可在 trigger 用來送出帳號。
  • password: (optional) 密碼,會以 'PASSWORD' 加入 variable_map,可在 trigger 用來送出密碼。
  • alias_list: (optional) Alias 清單,參考 Alias
  • trigger_list: (optional) Trigger 清單,參考 Trigger
  • timer_list: (optional) Timer 清單,參考 Timer
  • variable_map: (optional) 變數 dict,參考 Variable Map
  • pre_process_recv_content_func: (optional) 從 server 接收到內容後會先呼叫這個 function 再根據回傳的結果顯示到畫面上,參考 pre_process_recv_content_func
  • encoding: (optional) server 內容的編碼,例如 big5hkscs

pre_process_recv_content_func

function prototype

def pre_process_recv_content_func(content: str) -> str:
    ...
  • 從 server 接收到內容後會先呼叫這個 function 再根據回傳的結果顯示到畫面上。
  • 傳入 content,回傳修改後的 content。
  • 舉例來說,KK 的 server 有時會有 \x1B[1m 的文字插在 big5hkscs 中文字的 2 個 bytes 之間,導致中文字沒辦法被正確的處理,可以利用這個 function 移除。

使用範例

def remove_strange_color_code(content: str) -> str:
    '''移除中文字 2 個 byte 中間會被插入的 \x1B[1m (會導致中文字變亂碼)'''
    new_content = ''

    status = 0
    content_length = len(content)
    for i in range(content_length):
        if status == 0:
            new_content += content[i]
            # Big5 的範圍才要處理
            value = ord(content[i])
            if 0x81 <= value and value <= 0xFE:
                status = 1

        elif status == 1:
            if (i + 3 < content_length and all([
                    ord(content[i]) == 0x1B,
                    ord(content[i + 1]) == ord('['),
                    ord(content[i + 2]) == ord('1'),
                    ord(content[i + 3]) == ord('m'),
            ])):
                status = 2
                skip = 3
            else:
                new_content += content[i]
                status = 0

        elif status == 2:
            skip -= 1
            if skip == 0:
                status = 0

    return new_content

Alias

Alias class 說明

@dataclass
class Alias:

    start_text: str
    pattern: str | None = None
    func: Callable | None = None
  • start_text: Alias 的指令,可以包含空格。
  • pattern: (optional) 要替換的指令,會傳到 server。
  • func: (optional) 要呼叫的 function。
    • function prototype:
      def func(text: str) -> str or None:
        ...
      
    • text 參數會把除了 start_text 外的後面的文字全部傳入。
    • 如果 function 有回傳文字,會傳給 server;如果沒有要傳送給 server 的指令,不要回傳就好。

pattern 跟 func 2 選 1。

使用範例

from pymudclient import Alias

ALIAS_LIST = [
    Alias('kk', pattern='kingdom %0'),
    Alias('c', pattern='cast %1 on %2'),
    Alias('draw', pattern='draw %1 %-1'),
]
  • pattern 中的 %0 為全部參數。以上面的例子,kk 安安 你好 123%0 就是 安安 你好 123
  • pattern 中的 %1 ~ %n 為第 1 ~ 第 n 個參數。以上面的例子,c fire stone%1 就是 fire%2 就是 stone
  • pattern 中的 %-1 為去掉第 1 個參數後的其他所有參數;%-2 為去掉第 2 個參數後的其他所有參數;以此類推。以上面的例子,draw board ABCD 1234%-1 就是 ABCD 1234

Trigger

Trigger class 說明

@dataclass
class Trigger:

    pattern: str
    data: str | None = None
    func: Callable | None = None
  • pattern: 觸發的 pattern,使用 regex。
  • data: (optional) 要直接送出的文字,如果是固定文字用這個就好。
  • func: (optional) 要呼叫的 function。
    • function prototype:
      def func(text: str, match_group: list) -> str or None:
          ...
      
    • text 參數會把有符合 trigger 條件的整行文字傳入。
    • match_group 參數會把 regex match 到的 match.groups() 傳入
    • 如果 function 有回傳文字,會傳給 server;如果沒有要傳送給 server 的指令,不要回傳就好。
  • data 跟 func 2 選 1。

使用範例

from pymudclient import Trigger

def summon(text, match_group):
    return f'summon {match_group[0]}'

TRIGGER_LIST = [
    Trigger(r"^您的英文名字\(新人物請輸入\'new\'\) :$", data='${ACCOUNT}'),
    Trigger(r"^請輸入密碼﹕$", data='${PASSWORD}'),
    Trigger(r'\(([a-zA-Z]+)\)告訴你﹕sum$', func=summon),
]
  • 前面 2 個是輸入帳號密碼的 trigger,裡面的 ${ACCOUNT} 及 ${PASSWORD} 會使用傳給 PyMudClient 的 account 及 password。
  • 第 3 個是幫忙把人招喚過來的 trigger,有抓取角色 id ([a-zA-Z]+)

Timer

Timer class 說明

@dataclass
class Timer:

    seconds: int
    data: str | None = None
    func: Callable | None = None
  • seconds: 多久執行一次,單位是秒。
  • data: (optional) 要直接送出的文字,如果是固定文字用這個就好。
  • func: (optional) 要呼叫的 function。
    • function prototype:
      def func() -> str or None:
        ...
      
    • 如果 function 有回傳文字,會傳給 server;如果沒有要傳送給 server 的指令,不要回傳就好。
  • data 跟 func 2 選 1。

使用範例

from datetime import datetime

from pymudclient import (
    MudColorAlias,
    Timer,
    color_print,
)


def print_time():
    color_print(f'{MudColorAlias.HIGH_CYAN}{datetime.now()}{MudColorAlias.NORMAL}')

TIMER_LIST = [
    Timer(900, data='save'),
    Timer(60, func=print_time),
]
  • 第一個 Timer 是每 900 秒傳送一個 save 到 server。
  • 第二個 Timer 是每 60 秒呼叫一次 print_time 這個 function。
    • print_time 內使用到的 color_print 以及 MudColorAlias 的目的是印出帶有顏色的文字,參考下面的 color_printMudColorAlias 說明。

Variable Map

  • 型別:dict[str, str]
  • 可以建立常用變數,在 Trigger, Alias, Timer 內要送指令到 server 時使用。
  • 變數使用格式:${變數名},例如 ${ACCOUNT} 會被替換為對應的值。

使用範例

VARIABLE_MAP = {
    'DO_RE_MI': '霹靂卡霹靂拉拉波波力那貝貝魯多'
}

ALIAS_LIST = [
    Alias('doremi', pattern='sing ${DO_RE_MI}'),
]
  • 當輸入 doremi 時,就會傳送 sing 霹靂卡霹靂拉拉波波力那貝貝魯多 到 server

color_print

  • 可以印出帶有顏色的文字,可搭配 MudColorAlias 使用。

使用範例

from datetime import datetime

from pymudclient import (
    MudColorAlias,
    color_print,
)


color_print(f'$HIY${datetime.now()}$NOR$')
  • 這邊的 $HIY$$NOR$ 是 MUD 內常用來定義顏色的字串,雖然不難記,但也可以直接使用 MudColorAlias
  • 開頭使用 $HIY$ 讓顏色切換成高亮黃色,所以接下來的文字都會變成高亮黃色顯示,結尾的 $NOR$ 是讓顏色變回預設顏色。

MudColorAlias

  • 提供在 MUD 內常用來定義顏色的字串。

常數

  • NORMAL: 重置為正常顏色
  • BLACK: 黑色
  • RED: 紅色
  • GREEN: 綠色
  • YELLOW: 黃色
  • BLUE: 藍色
  • MAGENTA: 洋紅色
  • CYAN: 青色
  • WHITE: 白色
  • HIGH_RED: 高亮紅色
  • HIGH_GREEN: 高亮綠色
  • HIGH_YELLOW: 高亮黃色
  • HIGH_BLUE: 高亮藍色
  • HIGH_MAGENTA: 高亮洋紅色
  • HIGH_CYAN: 高亮青色
  • HIGH_WHITE: 高亮白色

alt text

使用範例

from datetime import datetime

from pymudclient import (
    MudColorAlias,
    color_print,
)


color_print(f'{MudColorAlias.HIGH_CYAN}{datetime.now()}{MudColorAlias.NORMAL}')

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pymudclient-1.0.0.tar.gz (20.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pymudclient-1.0.0-py3-none-any.whl (19.0 kB view details)

Uploaded Python 3

File details

Details for the file pymudclient-1.0.0.tar.gz.

File metadata

  • Download URL: pymudclient-1.0.0.tar.gz
  • Upload date:
  • Size: 20.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.5

File hashes

Hashes for pymudclient-1.0.0.tar.gz
Algorithm Hash digest
SHA256 f9eaadf3b307a42a9cfd77991d2702ac8b95f319df717be36c420050b701f28b
MD5 7c916f691b35649fa8e307592bf0ea27
BLAKE2b-256 a353df54ec7b1f2a5290d38bfd86d931c6467f0428a2faf0e575e802d2beda21

See more details on using hashes here.

File details

Details for the file pymudclient-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: pymudclient-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 19.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.5

File hashes

Hashes for pymudclient-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 222e257b4b177a174398c2c8e04a7a97f34b1047a4615d47fef3b594e4226311
MD5 e43ca48f9097837de3669d3dd29df9ac
BLAKE2b-256 ca2d28eaa72cc1b0d47601ff55346701d1d6573d549544333284ac60e398d891

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page