aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/tests/examples/ndice/src/ndice.py
blob: 082de9f8a01bda428ae392a7cec4b160274a071b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# Initialized `__init__.py` generated by ipm.
# Documents at https://ipm.hydroroll.team/

from infini.register import Register
from infini.router import Startswith
from infini.input import Input
from infini.output import Output
from .dicer import Dicer

import re

register = Register()
register.register_textevent(
    "ndice.roll",
    "[{{ username }}]掷骰: "
    "{% if descs|length == 1 %}"
    "{{ descs[0] }}"
    "{% else %}"
    "{{ db }}=[...]="
    "{% for outcome in outcomes %}"
    "{{ outcome }}"
    "{% if not loop.last %}, {% endif %}"
    "{% endfor %}"
    "{% endif %}",
)
register.register_textevent(
    "ndice.error.bad_roll_string", "[{{ username }}]掷骰时出现异常, 疑似掷骰表达式错误."
)
register.register_textevent("ndice.error.too_much_round", "[{{ username }}]给入的掷骰轮数超出预期.")
register.register_textevent(
    "ndice.error.unknown",
    "未知错误: {{ error }}, 可能是掷骰语法异常.\nBUG提交: https://gitee.com/unvisitor/issues",
)
register.register_textevent("ndice.error.bad_round", "多轮检定的轮数应当是整型数.")
register.register_textevent("ndice.error.too_much_round", "多轮检定的轮数超出预期.")


def translate_punctuation(string: str) -> str:
    punctuation_mapping = {
        ",": ",",
        "。": ".",
        "!": "!",
        "?": "?",
        ";": ";",
        ":": ":",
        "“": '"',
        "”": '"',
        "‘": "'",
        "’": "'",
        "(": "(",
        ")": ")",
        "【": "[",
        "】": "]",
        "《": "<",
        "》": ">",
    }
    for ch_punct, en_punct in punctuation_mapping.items():
        string = string.replace(ch_punct, en_punct)
    return string


def format_str(message: str, begin=None, lower=True) -> str:
    regex = r"[<\[](.*?)[\]>]"
    message = str(message).lower() if lower else str(message)
    msg = translate_punctuation(
        re.sub("\s+", " ", re.sub(regex, "", message)).strip(" ")
    )
    if msg.startswith("/"):
        msg = "." + msg[1:]

    if begin:
        if isinstance(begin, str):
            begin = [
                begin,
            ]
        elif isinstance(begin, tuple):
            begin = list(begin)

        begin.sort(reverse=True)
        for b in begin:
            msg = msg.replace(b, "").lstrip(" ")

    return msg


def roll(_: Input, args: str, name: str = None) -> str:
    time = 1
    if "#" in args:
        args = args.split("#")

        try:
            time = int(args[0].strip())
            if time > 20:
                return Output(
                    "text", "ndice.error.too_much_round", variables={"username": name}
                )
        except ValueError:
            return Output("text", "ndice.error.bad_round", variables={"username": name})

        if len(args) == 1:
            args = "1d100"
        else:
            args = args[1]
    else:
        args = args.strip()

    args = args.split()
    if len(args) > 1:
        reason = args[1]
    else:
        reason = None

    roll_string = args[0]
    descs = []
    outcomes = []

    try:
        dice = Dicer(roll_string).roll()
        descs.append(dice.description())
        outcomes.append(dice.outcome)

        for _ in range(time - 1):
            dice.roll()
            descs.append(dice.description())
            outcomes.append(dice.outcome)
    except ValueError:
        return Output(
            "text",
            "ndice.error.bad_roll_string",
            status=1,
            variables={"username": name},
        )

    return Output(
        "text",
        "ndice.roll",
        variables={
            "username": name,
            "descs": descs,
            "outcomes": outcomes,
            "db": dice.db,
        },
    )


@register.handler(router=Startswith(".r"), priority=0)
def roll_handler(input: Input):
    args = format_str(input.get_plain_text(), begin=(".r", ".roll"))
    name = input.variables.get("nickname") or "苏向夜"
    if not args:
        return roll(input, "1d100", name=name)

    try:
        return roll(input, args, name=name)
    except Exception as error:
        return Output("text", "ndice.error.unknown", variables={"error": str(error)})