634 |
635 | This program is free software: you can redistribute it and/or modify
636 | it under the terms of the GNU Affero General Public License as published
637 | by the Free Software Foundation, either version 3 of the License, or
638 | (at your option) any later version.
639 |
640 | This program is distributed in the hope that it will be useful,
641 | but WITHOUT ANY WARRANTY; without even the implied warranty of
642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
643 | GNU Affero General Public License for more details.
644 |
645 | You should have received a copy of the GNU Affero General Public License
646 | along with this program. If not, see .
647 |
648 | Also add information on how to contact you by electronic and paper mail.
649 |
650 | If your software can interact with users remotely through a computer
651 | network, you should also make sure that it provides a way for users to
652 | get its source. For example, if your program is a web application, its
653 | interface could display a "Source" link that leads users to an archive
654 | of the code. There are many ways you could offer source, and different
655 | solutions will be better for different programs; see section 13 for the
656 | specific requirements.
657 |
658 | You should also get your employer (if you work as a programmer) or school,
659 | if any, to sign a "copyright disclaimer" for the program, if necessary.
660 | For more information on this, and how to apply and follow the GNU AGPL, see
661 | .
662 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Mephisto
4 |
5 | > _孤身一人的乐团,为寂静之地带来新声。_
6 |
7 | [](https://www.gnu.org/licenses/agpl-3.0)
8 | [](https://github.com/psf/black)
9 | [](https://pycqa.github.io/isort/)
10 | 
11 |
12 |
13 |
14 | ## 目录
15 | * [目录](#目录)
16 | * [参与贡献](#参与贡献)
17 | * [许可证](#许可证)
18 | * [鸣谢](#鸣谢)
19 |
20 | ## 参与贡献
21 |
22 | 你可以通过以下方式参与到本项目中:
23 |
24 | * 提交 [Issue](https://github.com/nullqwertyuiop/Mephisto/issues)
25 | * 提交 [Pull Request](https://github.com/nullqwertyuiop/Mephisto/pulls)
26 |
27 | ## 许可证
28 |
29 | Copyright (C) 2023 nullqwertyuiop
30 |
31 | This program is free software: you can redistribute it and/or modify
32 | it under the terms of the GNU Affero General Public License as published
33 | by the Free Software Foundation, either version 3 of the License, or
34 | (at your option) any later version.
35 |
36 | This program is distributed in the hope that it will be useful,
37 | but WITHOUT ANY WARRANTY; without even the implied warranty of
38 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 | GNU Affero General Public License for more details.
40 |
41 | You should have received a copy of the GNU Affero General Public License
42 | along with this program. If not, see .
43 |
44 | ## 鸣谢
45 |
46 | [//]: # ( * [Uberto]() - 某恋妹男提供的命名灵感)
47 |
48 | ### 框架
49 |
50 | * [Avilla](https://github.com/GraiaProject/Avilla) - The next-gen framework for IM development.
51 |
52 | ### Bot 项目
53 |
54 | * [Eric](https://github.com/ProjectNu11/Project-Null) - 本项目的前身
55 |
--------------------------------------------------------------------------------
/chitung/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/__init__.py
--------------------------------------------------------------------------------
/chitung/assets/blackjack/instructions.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/blackjack/instructions.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/101.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/101.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/102.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/102.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/103.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/103.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/104.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/104.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/105.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/105.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/106.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/106.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/107.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/107.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/108.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/108.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/109.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/109.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/110.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/110.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/111.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/111.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/112.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/112.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/113.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/113.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/114.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/115.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/115.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/116.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/116.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/201.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/201.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/202.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/202.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/203.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/203.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/204.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/204.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/205.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/205.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/206.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/206.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/207.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/207.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/208.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/208.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/209.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/209.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/210.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/210.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/211.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/211.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/212.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/212.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/213.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/213.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/214.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/214.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/215.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/215.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/216.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/216.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/301.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/301.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/302.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/302.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/303.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/303.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/304.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/304.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/305.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/305.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/306.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/306.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/307.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/307.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/308.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/308.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/309.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/309.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/310.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/310.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/311.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/311.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/312.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/312.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/313.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/313.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/314.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/314.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/315.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/315.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/316.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/316.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/401.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/401.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/402.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/402.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/403.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/403.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/404.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/404.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/405.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/405.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/406.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/406.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/407.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/407.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/408.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/408.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/409.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/409.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/410.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/410.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/411.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/411.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/412.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/412.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/413.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/413.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/414.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/414.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/415.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/415.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/416.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/416.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/417.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/417.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/418.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/418.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/419.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/419.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/420.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/420.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/421.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/421.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/422.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/422.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/423.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/423.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/DarkFish/424.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/DarkFish/424.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/FishingList.json:
--------------------------------------------------------------------------------
1 | {
2 | "fishingList": [
3 | {
4 | "code": 101,
5 | "name": "红海星",
6 | "price": 100,
7 | "time": "Day"
8 | },
9 | {
10 | "code": 102,
11 | "name": "蓝海星",
12 | "price": 120,
13 | "time": "Day"
14 | },
15 | {
16 | "code": 103,
17 | "name": "海胆",
18 | "price": 130,
19 | "time": "All"
20 | },
21 | {
22 | "code": 104,
23 | "name": "金面花鲈",
24 | "price": 120,
25 | "time": "All"
26 | },
27 | {
28 | "code": 105,
29 | "name": "蓝副鮗",
30 | "price": 120,
31 | "time": "All"
32 | },
33 | {
34 | "code": 106,
35 | "name": "火神仙",
36 | "price": 340,
37 | "time": "All"
38 | },
39 | {
40 | "code": 107,
41 | "name": "蓝神仙",
42 | "price": 300,
43 | "time": "Night"
44 | },
45 | {
46 | "code": 108,
47 | "name": "帝王神仙",
48 | "price": 500,
49 | "time": "Night"
50 | },
51 | {
52 | "code": 109,
53 | "name": "多色神仙",
54 | "price": 300,
55 | "time": "Day"
56 | },
57 | {
58 | "code": 110,
59 | "name": "黑白神仙",
60 | "price": 180,
61 | "time": "Day"
62 | },
63 | {
64 | "code": 111,
65 | "name": "绿雀鲷",
66 | "price": 200,
67 | "time": "All"
68 | },
69 | {
70 | "code": 112,
71 | "name": "灰雀鲷",
72 | "price": 180,
73 | "time": "All"
74 | },
75 | {
76 | "code": 113,
77 | "name": "鲸鱼",
78 | "price": 500,
79 | "time": "All"
80 | },
81 | {
82 | "code": 114,
83 | "name": "海豚",
84 | "price": 450,
85 | "time": "All"
86 | },
87 | {
88 | "code": 115,
89 | "name": "剑鱼",
90 | "price": 300,
91 | "time": "Night"
92 | },
93 | {
94 | "code": 116,
95 | "name": "海马",
96 | "price": 320,
97 | "time": "Night"
98 | },
99 | {
100 | "code": 201,
101 | "name": "螃蟹",
102 | "price": 350,
103 | "time": "Day"
104 | },
105 | {
106 | "code": 202,
107 | "name": "淡黑镊丽鱼",
108 | "price": 250,
109 | "time": "Day"
110 | },
111 | {
112 | "code": 203,
113 | "name": "蓝清道夫",
114 | "price": 200,
115 | "time": "All"
116 | },
117 | {
118 | "code": 204,
119 | "name": "绿清道夫",
120 | "price": 225,
121 | "time": "All"
122 | },
123 | {
124 | "code": 205,
125 | "name": "白清道夫",
126 | "price": 250,
127 | "time": "All"
128 | },
129 | {
130 | "code": 206,
131 | "name": "沙丁鱼",
132 | "price": 80,
133 | "time": "All"
134 | },
135 | {
136 | "code": 207,
137 | "name": "拟黄鲫",
138 | "price": 80,
139 | "time": "Night"
140 | },
141 | {
142 | "code": 208,
143 | "name": "小丑鱼",
144 | "price": 180,
145 | "time": "Night"
146 | },
147 | {
148 | "code": 209,
149 | "name": "银鲑",
150 | "price": 190,
151 | "time": "Day"
152 | },
153 | {
154 | "code": 210,
155 | "name": "红鲑鱼",
156 | "price": 190,
157 | "time": "Day"
158 | },
159 | {
160 | "code": 211,
161 | "name": "粉珍珠",
162 | "price": 480,
163 | "time": "All"
164 | },
165 | {
166 | "code": 212,
167 | "name": "猩红扇贝",
168 | "price": 320,
169 | "time": "All"
170 | },
171 | {
172 | "code": 213,
173 | "name": "粉红扇贝",
174 | "price": 280,
175 | "time": "All"
176 | },
177 | {
178 | "code": 214,
179 | "name": "火红珍珠",
180 | "price": 500,
181 | "time": "All"
182 | },
183 | {
184 | "code": 215,
185 | "name": "鲀鱼",
186 | "price": 180,
187 | "time": "Night"
188 | },
189 | {
190 | "code": 216,
191 | "name": "水母",
192 | "price": 80,
193 | "time": "Night"
194 | },
195 | {
196 | "code": 301,
197 | "name": "中华绒螯蟹",
198 | "price": 120,
199 | "time": "Day"
200 | },
201 | {
202 | "code": 302,
203 | "name": "金鱼",
204 | "price": 80,
205 | "time": "Day"
206 | },
207 | {
208 | "code": 303,
209 | "name": "白斑锦鲤",
210 | "price": 350,
211 | "time": "All"
212 | },
213 | {
214 | "code": 304,
215 | "name": "橙斑锦鲤",
216 | "price": 340,
217 | "time": "All"
218 | },
219 | {
220 | "code": 305,
221 | "name": "杂色锦鲤",
222 | "price": 300,
223 | "time": "All"
224 | },
225 | {
226 | "code": 306,
227 | "name": "黄神仙",
228 | "price": 250,
229 | "time": "All"
230 | },
231 | {
232 | "code": 307,
233 | "name": "窜条鱼",
234 | "price": 60,
235 | "time": "Night"
236 | },
237 | {
238 | "code": 308,
239 | "name": "鲨鱼",
240 | "price": 500,
241 | "time": "Night"
242 | },
243 | {
244 | "code": 309,
245 | "name": "蓝海马",
246 | "price": 250,
247 | "time": "Day"
248 | },
249 | {
250 | "code": 310,
251 | "name": "紫章鱼",
252 | "price": 200,
253 | "time": "Day"
254 | },
255 | {
256 | "code": 311,
257 | "name": "树蛙",
258 | "price": 80,
259 | "time": "All"
260 | },
261 | {
262 | "code": 312,
263 | "name": "海龟",
264 | "price": 200,
265 | "time": "All"
266 | },
267 | {
268 | "code": 313,
269 | "name": "深海鳐鱼",
270 | "price": 250,
271 | "time": "All"
272 | },
273 | {
274 | "code": 314,
275 | "name": "蓝色龙虾",
276 | "price": 530,
277 | "time": "All"
278 | },
279 | {
280 | "code": 315,
281 | "name": "小青龙",
282 | "price": 480,
283 | "time": "Night"
284 | },
285 | {
286 | "code": 316,
287 | "name": "虎纹虾",
288 | "price": 220,
289 | "time": "Night"
290 | },
291 | {
292 | "code": 401,
293 | "name": "割喉鳟",
294 | "price": 120,
295 | "time": "Day"
296 | },
297 | {
298 | "code": 402,
299 | "name": "褐鳟",
300 | "price": 100,
301 | "time": "Day"
302 | },
303 | {
304 | "code": 403,
305 | "name": "彩虹鳟",
306 | "price": 140,
307 | "time": "All"
308 | },
309 | {
310 | "code": 404,
311 | "name": "乔克非鲫",
312 | "price": 110,
313 | "time": "All"
314 | },
315 | {
316 | "code": 405,
317 | "name": "鲈鱼",
318 | "price": 85,
319 | "time": "All"
320 | },
321 | {
322 | "code": 406,
323 | "name": "蓝鳍金枪鱼",
324 | "price": 145,
325 | "time": "All"
326 | },
327 | {
328 | "code": 407,
329 | "name": "大口鲈鱼",
330 | "price": 90,
331 | "time": "Night"
332 | },
333 | {
334 | "code": 408,
335 | "name": "帝王鲑",
336 | "price": 80,
337 | "time": "Night"
338 | },
339 | {
340 | "code": 409,
341 | "name": "三间魔",
342 | "price": 80,
343 | "time": "Day"
344 | },
345 | {
346 | "code": 410,
347 | "name": "横带刺尾鱼",
348 | "price": 100,
349 | "time": "Day"
350 | },
351 | {
352 | "code": 411,
353 | "name": "鳎鱼",
354 | "price": 80,
355 | "time": "All"
356 | },
357 | {
358 | "code": 412,
359 | "name": "阿穆尔鲤",
360 | "price": 80,
361 | "time": "All"
362 | },
363 | {
364 | "code": 413,
365 | "name": "金目鲷",
366 | "price": 90,
367 | "time": "All"
368 | },
369 | {
370 | "code": 414,
371 | "name": "银鳊鱼",
372 | "price": 80,
373 | "time": "All"
374 | },
375 | {
376 | "code": 415,
377 | "name": "红绿灯",
378 | "price": 85,
379 | "time": "Night"
380 | },
381 | {
382 | "code": 416,
383 | "name": "雪卡鱼",
384 | "price": 80,
385 | "time": "Night"
386 | },
387 | {
388 | "code": 417,
389 | "name": "红章鱼",
390 | "price": 180,
391 | "time": "Day"
392 | },
393 | {
394 | "code": 418,
395 | "name": "蝠鲼",
396 | "price": 250,
397 | "time": "Day"
398 | },
399 | {
400 | "code": 419,
401 | "name": "蓝色寄居蟹",
402 | "price": 250,
403 | "time": "All"
404 | },
405 | {
406 | "code": 420,
407 | "name": "寄居蟹",
408 | "price": 200,
409 | "time": "All"
410 | },
411 | {
412 | "code": 421,
413 | "name": "十角海星",
414 | "price": 100,
415 | "time": "All"
416 | },
417 | {
418 | "code": 422,
419 | "name": "小海星",
420 | "price": 80,
421 | "time": "All"
422 | },
423 | {
424 | "code": 423,
425 | "name": "海鳗鱼",
426 | "price": 80,
427 | "time": "Night"
428 | },
429 | {
430 | "code": 424,
431 | "name": "乌贼",
432 | "price": 100,
433 | "time": "Night"
434 | }
435 | ]
436 | }
437 |
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/101.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/101.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/102.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/102.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/103.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/103.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/104.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/104.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/105.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/105.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/106.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/106.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/107.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/107.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/108.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/108.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/109.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/109.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/110.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/110.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/111.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/111.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/112.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/112.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/113.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/113.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/114.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/115.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/115.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/116.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/116.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/201.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/201.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/202.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/202.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/203.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/203.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/204.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/204.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/205.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/205.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/206.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/206.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/207.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/207.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/208.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/208.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/209.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/209.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/210.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/210.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/211.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/211.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/212.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/212.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/213.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/213.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/214.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/214.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/215.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/215.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/216.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/216.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/301.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/301.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/302.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/302.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/303.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/303.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/304.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/304.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/305.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/305.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/306.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/306.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/307.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/307.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/308.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/308.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/309.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/309.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/310.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/310.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/311.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/311.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/312.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/312.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/313.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/313.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/314.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/314.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/315.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/315.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/316.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/316.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/401.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/401.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/402.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/402.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/403.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/403.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/404.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/404.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/405.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/405.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/406.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/406.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/407.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/407.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/408.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/408.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/409.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/409.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/410.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/410.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/411.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/411.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/412.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/412.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/413.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/413.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/414.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/414.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/415.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/415.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/416.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/416.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/417.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/417.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/418.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/418.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/419.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/419.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/420.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/420.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/421.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/421.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/422.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/422.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/423.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/423.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/NormalFish/424.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/NormalFish/424.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/fishinfo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/fishinfo.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/handbook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/handbook.png
--------------------------------------------------------------------------------
/chitung/assets/fishing/handbookTemplate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/fishing/handbookTemplate.png
--------------------------------------------------------------------------------
/chitung/assets/help/funct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/help/funct.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/一条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/一条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/一筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/一筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/一萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/一萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/七条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/七条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/七筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/七筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/七萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/七萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/三条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/三条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/三筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/三筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/三萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/三萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/九条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/九条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/九筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/九筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/九萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/九萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/二条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/二条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/二筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/二筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/二萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/二萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/五条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/五条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/五筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/五筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/五萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/五萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/八条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/八条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/八筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/八筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/八萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/八萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/六条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/六条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/六筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/六筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/六萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/六萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/北风.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/北风.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/南风.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/南风.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/四条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/四条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/四筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/四筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/四萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/四萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/无字.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/无字.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/東风.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/東风.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/發财.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/發财.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/白板.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/白板.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/红中.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/红中.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/花牌(兰).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/花牌(兰).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/花牌(冬).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/花牌(冬).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/花牌(夏).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/花牌(夏).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/花牌(春).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/花牌(春).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/花牌(梅).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/花牌(梅).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/花牌(秋).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/花牌(秋).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/花牌(竹).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/花牌(竹).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/花牌(菊).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/花牌(菊).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Red/西风.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Red/西风.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/一条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/一条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/一筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/一筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/一萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/一萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/七条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/七条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/七筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/七筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/七萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/七萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/三条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/三条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/三筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/三筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/三萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/三萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/九条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/九条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/九筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/九筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/九萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/九萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/二条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/二条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/二筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/二筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/二萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/二萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/五条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/五条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/五筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/五筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/五萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/五萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/八条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/八条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/八筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/八筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/八萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/八萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/六条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/六条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/六筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/六筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/六萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/六萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/北风.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/北风.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/南风.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/南风.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/四条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/四条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/四筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/四筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/四萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/四萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/无字.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/无字.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/東风.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/東风.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/發财.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/發财.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/白板.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/白板.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/红中.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/红中.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/花牌(兰).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/花牌(兰).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/花牌(冬).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/花牌(冬).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/花牌(夏).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/花牌(夏).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/花牌(春).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/花牌(春).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/花牌(梅).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/花牌(梅).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/花牌(秋).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/花牌(秋).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/花牌(竹).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/花牌(竹).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/花牌(菊).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/花牌(菊).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Transparent/西风.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Transparent/西风.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/一条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/一条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/一筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/一筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/一萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/一萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/七条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/七条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/七筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/七筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/七萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/七萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/三条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/三条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/三筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/三筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/三萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/三萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/九条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/九条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/九筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/九筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/九萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/九萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/二条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/二条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/二筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/二筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/二萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/二萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/五条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/五条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/五筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/五筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/五萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/五萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/八条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/八条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/八筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/八筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/八萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/八萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/六条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/六条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/六筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/六筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/六萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/六萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/北风.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/北风.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/南风.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/南风.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/四条.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/四条.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/四筒.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/四筒.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/四萬.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/四萬.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/无字.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/无字.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/東风.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/東风.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/發财.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/發财.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/白板.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/白板.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/红中.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/红中.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/花牌(兰).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/花牌(兰).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/花牌(冬).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/花牌(冬).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/花牌(夏).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/花牌(夏).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/花牌(春).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/花牌(春).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/花牌(梅).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/花牌(梅).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/花牌(秋).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/花牌(秋).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/花牌(竹).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/花牌(竹).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/花牌(菊).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/花牌(菊).png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/Yellow/西风.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/Yellow/西风.png
--------------------------------------------------------------------------------
/chitung/assets/mahjong/寄.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/mahjong/寄.jpg
--------------------------------------------------------------------------------
/chitung/assets/winner/wanted.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/assets/winner/wanted.jpg
--------------------------------------------------------------------------------
/chitung/library/__init__.py:
--------------------------------------------------------------------------------
1 | import kayaku
2 | from creart import it
3 | from graia.amnesia.builtins.asgi import UvicornASGIService
4 | from launart import Launart
5 |
6 |
7 | def launch():
8 | kayaku.initialize({"{**}": "./config/{**}"})
9 |
10 | from chitung.library.model.config import ChitungConfig
11 | from chitung.library.service import (
12 | BankService,
13 | ChitungService,
14 | ConfigService,
15 | MessageCacheService,
16 | ModuleService,
17 | ProtocolService,
18 | SessionService,
19 | )
20 |
21 | kayaku.create(ChitungConfig)
22 |
23 | mgr = it(Launart)
24 | mgr.add_component(
25 | UvicornASGIService(
26 | "127.0.0.1", kayaku.create(ChitungConfig).advanced.uvicorn_port
27 | )
28 | )
29 | mgr.add_component(BankService())
30 | mgr.add_component(MessageCacheService())
31 | mgr.add_component(ConfigService())
32 | mgr.add_component(ModuleService())
33 | mgr.add_component(ProtocolService())
34 | mgr.add_component(SessionService())
35 | mgr.add_component(ChitungService())
36 | mgr.launch_blocking()
37 |
--------------------------------------------------------------------------------
/chitung/library/const.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 | from typing import Final
3 |
4 | CHITUNG_ROOT: Final[Path] = Path(__file__).parent.parent.resolve()
5 | PROJECT_ROOT: Final[Path] = CHITUNG_ROOT.parent.resolve()
6 | DATA_ROOT: Final[Path] = CHITUNG_ROOT / "data"
7 | ASSETS_ROOT: Final[Path] = CHITUNG_ROOT / "assets"
8 |
--------------------------------------------------------------------------------
/chitung/library/model/config.py:
--------------------------------------------------------------------------------
1 | from dataclasses import dataclass, field
2 |
3 | from kayaku import config
4 |
5 |
6 | @dataclass
7 | class ChitungNetworkConfig:
8 | proxy: str = ""
9 | timeout: int = 30
10 |
11 |
12 | @dataclass
13 | class ChitungAdvancedConfig:
14 | debug: bool = False
15 | log_rotate: int = 7
16 | message_cache_size: int = 5000
17 | uvicorn_port: int = 8000
18 |
19 |
20 | @config("library.main")
21 | class ChitungConfig:
22 | name: str = "Chitung"
23 | description: str = "Public Version of Chitung rewritten in Python"
24 | network: ChitungNetworkConfig = field(default_factory=ChitungNetworkConfig)
25 | advanced: ChitungAdvancedConfig = field(default_factory=ChitungAdvancedConfig)
26 |
--------------------------------------------------------------------------------
/chitung/library/model/exception.py:
--------------------------------------------------------------------------------
1 | class RequirementResolveFailed(Exception):
2 | pass
3 |
--------------------------------------------------------------------------------
/chitung/library/model/metadata.py:
--------------------------------------------------------------------------------
1 | from functools import partial
2 | from typing import Annotated, Literal
3 |
4 | from packaging.version import Version
5 | from pydantic import AfterValidator, BaseModel
6 |
7 |
8 | def _version_validator(v: str):
9 | Version(v)
10 | return v
11 |
12 |
13 | def _identifier_validator(scope: str, v: str):
14 | if not v.startswith(f"{scope}.") and not v.startswith(f"library.{scope}."):
15 | raise ValueError(f'{scope.capitalize()} identifier must start with "{scope}."')
16 | if not v.lstrip("library.").lstrip(f"{scope}."):
17 | raise ValueError(f"{scope.capitalize()} identifier cannot be empty")
18 | if v[0].isdigit():
19 | raise ValueError(f"{scope.capitalize()} identifier cannot start with a digit")
20 | if [
21 | char
22 | for char in v.lstrip("library.").lstrip(f"{scope}.")
23 | if not char.isalnum() and char not in ["_", "."]
24 | ]:
25 | raise ValueError(f"{scope.capitalize()} identifier invalid")
26 | return v
27 |
28 |
29 | _module_identifier_validator = partial(_identifier_validator, "module")
30 |
31 |
32 | class ChitungMetadata(BaseModel):
33 | type: str
34 | identifier: str
35 | name: str = ""
36 | version: Annotated[str, AfterValidator(_version_validator)] = "0.1.0"
37 | description: str = ""
38 | author: list[str] = []
39 |
40 | def __hash__(self):
41 | return hash(self.__class__.__name__ + self.identifier)
42 |
43 |
44 | class ModuleMetadata(ChitungMetadata):
45 | type: Literal["module"] = "module"
46 | identifier: Annotated[str, AfterValidator(_module_identifier_validator)]
47 | dependencies: list["ModuleMetadata"] = []
48 |
--------------------------------------------------------------------------------
/chitung/library/model/protocol.py:
--------------------------------------------------------------------------------
1 | from typing import Literal
2 |
3 | from avilla.core import BaseProtocol
4 | from avilla.onebot.v11 import (
5 | OneBot11ForwardConfig,
6 | OneBot11Protocol,
7 | OneBot11ReverseConfig,
8 | )
9 | from avilla.telegram.protocol import (
10 | TelegramLongPollingConfig,
11 | TelegramProtocol,
12 | TelegramWebhookConfig,
13 | )
14 | from pydantic import AnyHttpUrl, BaseModel, ValidationError
15 | from yarl import URL
16 |
17 |
18 | class ProtocolConfig(BaseModel):
19 | protocol: str
20 | enabled: bool = True
21 |
22 | @property
23 | def id(self):
24 | return ...
25 |
26 | def to_protocol(self) -> BaseProtocol:
27 | pass
28 |
29 | @classmethod
30 | def resolve(cls, data: dict) -> "ProtocolConfig":
31 | for sub in cls.__subclasses__():
32 | try:
33 | return sub(**data)
34 | except ValidationError:
35 | continue
36 | raise ValueError(f"Unknown protocol: {data.get('protocol')!r}")
37 |
38 |
39 | class TelegramBotLongPollingProtocolConfig(ProtocolConfig):
40 | protocol: Literal["telegram_long_polling"] = "telegram_long_polling"
41 | token: str
42 | base_url: AnyHttpUrl = "https://api.telegram.org/bot"
43 | base_file_url: AnyHttpUrl = "https://api.telegram.org/file/bot"
44 | timeout: int = 15
45 |
46 | def to_protocol(self) -> TelegramProtocol:
47 | return TelegramProtocol().configure(
48 | TelegramLongPollingConfig(
49 | token=self.token,
50 | base_url=URL(str(self.base_url)),
51 | file_base_url=URL(str(self.base_file_url)),
52 | timeout=self.timeout,
53 | )
54 | )
55 |
56 | @property
57 | def id(self):
58 | return self.token.split(":")[0]
59 |
60 |
61 | class TelegramBotWebhookProtocolConfig(ProtocolConfig):
62 | protocol: Literal["telegram_webhook"] = "telegram_webhook"
63 | token: str
64 | webhook_url: AnyHttpUrl
65 | secret_token: str | None = None
66 | drop_pending_updates: bool = False
67 | base_url: AnyHttpUrl = "https://api.telegram.org/bot"
68 | base_file_url: AnyHttpUrl = "https://api.telegram.org/file/bot"
69 |
70 | def to_protocol(self) -> TelegramProtocol:
71 | return TelegramProtocol().configure(
72 | TelegramWebhookConfig(
73 | token=self.token,
74 | webhook_url=URL(str(self.webhook_url)),
75 | secret_token=self.secret_token,
76 | drop_pending_updates=self.drop_pending_updates,
77 | base_url=URL(str(self.base_url)),
78 | file_base_url=URL(str(self.base_file_url)),
79 | )
80 | )
81 |
82 | @property
83 | def id(self):
84 | return self.token.split(":")[0]
85 |
86 |
87 | class OneBotV11ProtocolFwdConfig(ProtocolConfig):
88 | protocol: Literal["onebot_v11_forward"] = "onebot_v11_forward"
89 | endpoint: AnyHttpUrl
90 | access_token: str | None = None
91 |
92 | def to_protocol(self) -> OneBot11Protocol:
93 | return OneBot11Protocol().configure(
94 | OneBot11ForwardConfig(
95 | endpoint=URL(str(self.endpoint)), access_token=self.access_token
96 | )
97 | )
98 |
99 | @property
100 | def id(self):
101 | return f"{self.endpoint.host}_{self.endpoint.port}"
102 |
103 |
104 | class OneBotV11ProtocolRevConfig(ProtocolConfig):
105 | protocol: Literal["onebot_v11_reverse"] = "onebot_v11_reverse"
106 | endpoint: str
107 | access_token: str | None = None
108 |
109 | def to_protocol(self) -> OneBot11Protocol:
110 | return OneBot11Protocol().configure(
111 | OneBot11ReverseConfig(
112 | endpoint=self.endpoint, access_token=self.access_token
113 | )
114 | )
115 |
116 | @property
117 | def id(self):
118 | return self.endpoint.replace("/", "_")
119 |
120 |
121 | class ElizabethProtocolConfig(ProtocolConfig):
122 | protocol: Literal["mirai-api-http"] = "mirai-api-http"
123 |
--------------------------------------------------------------------------------
/chitung/library/module/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/library/module/__init__.py
--------------------------------------------------------------------------------
/chitung/library/module/essential/__init__.py:
--------------------------------------------------------------------------------
1 | from avilla.core import Context
2 | from avilla.standard.core.message import MessageReceived
3 | from avilla.twilight.twilight import FullMatch, Twilight
4 | from graia.amnesia.message import MessageChain, Text
5 | from graia.broadcast import PropagationCancelled
6 | from graia.saya import Channel, Saya
7 | from graia.saya.builtins.broadcast.shortcut import dispatch, listen, priority
8 | from loguru import logger
9 |
10 | _saya = Saya.current()
11 |
12 |
13 | @listen(MessageReceived)
14 | @dispatch(
15 | Twilight(
16 | FullMatch("/ping"),
17 | )
18 | )
19 | async def ping(ctx: Context):
20 | await ctx.scene.send_message(MessageChain([Text("pong")]))
21 |
22 |
23 | @listen(MessageReceived)
24 | @priority(0)
25 | async def ignore_self_message(ctx: Context):
26 | if ctx.client.to_selector() == ctx.self.to_selector():
27 | logger.debug("ignored self message")
28 | raise PropagationCancelled()
29 |
--------------------------------------------------------------------------------
/chitung/library/module/essential/metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "identifier": "library.module.essential",
3 | "name": "核心组件",
4 | "version": "0.1.0",
5 | "description": "维持 Chitung 的基本服务正常运行",
6 | "author": [
7 | "nullqwertyuiop"
8 | ],
9 | "dependencies": [],
10 | "standards": []
11 | }
12 |
--------------------------------------------------------------------------------
/chitung/library/service/__init__.py:
--------------------------------------------------------------------------------
1 | from .bank import BankService
2 | from .cache import MessageCacheService
3 | from .config import ConfigService
4 | from .essential import ChitungService
5 | from .module import ModuleService
6 | from .protocol import ProtocolService
7 | from .session import SessionService
8 |
--------------------------------------------------------------------------------
/chitung/library/service/bank.py:
--------------------------------------------------------------------------------
1 | from asyncio import Lock
2 | from contextlib import asynccontextmanager
3 | from datetime import datetime, timezone
4 | from enum import Enum
5 | from pathlib import Path
6 | from typing import Final
7 |
8 | from avilla.core import Selector
9 | from launart import Launart, Service
10 | from loguru import logger
11 | from pydantic import BaseModel
12 |
13 | from chitung.library.const import DATA_ROOT
14 |
15 | DATA_PATH: Final[Path] = DATA_ROOT / "bank_record.json"
16 |
17 |
18 | class CurrencyFullName(str, Enum):
19 | PUMPKIN_PESO = "南瓜比索"
20 | AKAONI = "赤鬼金币"
21 | ANTONINIANUS = "安东尼银币"
22 | ADVENTURER_S = "冒险家铜币"
23 |
24 | def shortname(self) -> "Currency":
25 | return Currency[self.name]
26 |
27 |
28 | class Currency(str, Enum):
29 | PUMPKIN_PESO = "pk"
30 | AKAONI = "ak"
31 | ANTONINIANUS = "an"
32 | ADVENTURER_S = "ad"
33 |
34 | def fullname(self) -> "CurrencyFullName":
35 | return CurrencyFullName[self.name]
36 |
37 |
38 | class VaultAccount(BaseModel):
39 | balance: dict[Currency, int]
40 |
41 | def deposit(self, currency: Currency, amount: int):
42 | self.balance[currency] += amount
43 |
44 | def withdraw(self, currency: Currency, amount: int):
45 | self.balance[currency] -= amount
46 |
47 | def get_balance(self, currency: Currency) -> int:
48 | return self.balance.setdefault(currency, 0)
49 |
50 | def set_balance(self, currency: Currency, amount: int):
51 | self.balance[currency] = amount
52 |
53 | def has_enough(self, currency: Currency, amount: int) -> bool:
54 | return self.get_balance(currency) >= amount
55 |
56 |
57 | class VaultLand(BaseModel):
58 | accounts: dict[str, VaultAccount]
59 |
60 | def get_account(self, target: Selector) -> VaultAccount:
61 | return self.accounts.setdefault(
62 | target.last_value,
63 | VaultAccount(balance={currency: 0 for currency in Currency}),
64 | )
65 |
66 |
67 | class SimpleVault(BaseModel):
68 | vault: dict[str, VaultLand]
69 |
70 | def __init__(self, **kwargs):
71 | super().__init__(**kwargs)
72 | self.__lock: dict[Selector, Lock] = {}
73 |
74 | @asynccontextmanager
75 | async def _lock(self, target: Selector):
76 | async with self.__lock.setdefault(target, Lock()):
77 | yield
78 |
79 | def get_land(self, target: Selector) -> VaultLand:
80 | return self.vault.setdefault(target.pattern["land"], VaultLand(accounts={}))
81 |
82 | def get_account(self, target: Selector) -> VaultAccount:
83 | return self.get_land(target).get_account(target)
84 |
85 | async def deposit(self, target: Selector, currency: Currency, amount: int):
86 | async with self._lock(target):
87 | self.get_account(target).deposit(currency, amount)
88 |
89 | async def withdraw(self, target: Selector, currency: Currency, amount: int):
90 | async with self._lock(target):
91 | self.get_account(target).withdraw(currency, amount)
92 |
93 | async def get_balance(self, target: Selector, currency: Currency) -> int:
94 | async with self._lock(target):
95 | return self.get_account(target).get_balance(currency)
96 |
97 | async def set_balance(self, target: Selector, currency: Currency, amount: int):
98 | async with self._lock(target):
99 | self.get_account(target).set_balance(currency, amount)
100 |
101 | async def has_enough(
102 | self, target: Selector, currency: Currency, amount: int
103 | ) -> bool:
104 | async with self._lock(target):
105 | return self.get_account(target).has_enough(currency, amount)
106 |
107 |
108 | class BankService(Service):
109 | id = "chitung.service/bank"
110 | vault: SimpleVault
111 |
112 | @property
113 | def required(self):
114 | return {"chitung.service/essential"}
115 |
116 | @property
117 | def stages(self):
118 | return {"preparing", "cleanup"}
119 |
120 | async def launch(self, _: Launart):
121 | async with self.stage("preparing"):
122 | try:
123 | if DATA_PATH.is_file():
124 | self.vault = SimpleVault.model_validate_json(DATA_PATH.read_text())
125 | else:
126 | logger.warning("bank data not found, loading empty vault")
127 | self.vault = SimpleVault(vault={})
128 | except Exception as err:
129 | logger.error(f"failed to load bank data: {err}")
130 | bak = DATA_PATH.rename(
131 | DATA_PATH.with_suffix(
132 | f"{datetime.now(timezone.utc).timestamp()}.bak"
133 | )
134 | )
135 | logger.warning(f"backup bank data to {bak}")
136 | self.vault = SimpleVault(vault={})
137 |
138 | async with self.stage("cleanup"):
139 | DATA_PATH.write_text(self.vault.model_dump_json(include={"vault"}))
140 | logger.success(f"[{self.id}] saved bank data to {DATA_PATH}")
141 |
--------------------------------------------------------------------------------
/chitung/library/service/cache.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | from datetime import timedelta
3 | from heapq import heappop
4 | from time import time
5 | from typing import Any
6 |
7 | from avilla.core import Message, Selector
8 | from avilla.standard.core.message import MessageReceived
9 | from graia.amnesia.builtins.memcache import Memcache
10 | from kayaku import create
11 | from launart import Launart, Service
12 | from loguru import logger
13 |
14 | from chitung.library.model.config import ChitungConfig
15 |
16 |
17 | class MessageCacheService(Service):
18 | id = "chitung.service/cache"
19 |
20 | interval: float
21 | size: int
22 | lifespan: timedelta
23 | _cache: dict[str, tuple[float | None, Any]]
24 | expire: list[tuple[float, str]]
25 |
26 | __KEY_TEMPLATE = "chitung.service/cache::{key}"
27 |
28 | def __init__(
29 | self,
30 | interval: float = 0.1,
31 | size: int = None,
32 | lifespan: timedelta = timedelta(hours=1),
33 | cache: dict[str, tuple[float | None, Any]] = None,
34 | expire: list[tuple[float, str]] = None,
35 | ):
36 | self.interval = interval
37 | if size is None:
38 | size: int = create(ChitungConfig).advanced.message_cache_size
39 | self.size = size
40 | self.lifespan = lifespan
41 | self._cache = cache or {}
42 | self.expire = expire or []
43 | super().__init__()
44 |
45 | @property
46 | def required(self):
47 | return {"chitung.service/config"}
48 |
49 | @property
50 | def stages(self):
51 | return {"blocking"}
52 |
53 | @property
54 | def cache(self):
55 | return Memcache(self._cache, self.expire)
56 |
57 | async def add(self, message: Message):
58 | selector = message.to_selector()
59 | key = self.__KEY_TEMPLATE.format(key=selector.display)
60 | await self.cache.set(key, message, self.lifespan)
61 |
62 | async def get(self, selector: Selector) -> Message:
63 | key = self.__KEY_TEMPLATE.format(key=selector.display)
64 | return await self.cache.get(key)
65 |
66 | async def launch(self, manager: Launart):
67 | from chitung.library.service import ChitungService
68 |
69 | logger.info(f"[MessageCacheService] Initialized with {self.size} cache size")
70 | broadcast = manager.get_component(ChitungService).broadcast
71 |
72 | @broadcast.receiver(MessageReceived)
73 | async def cache_message(event: MessageReceived):
74 | await manager.get_component(MessageCacheService).add(event.message)
75 |
76 | async with self.stage("blocking"):
77 | while not manager.status.exiting:
78 | while self.expire and (
79 | self.expire[0][0] <= time() or len(self.expire) > self.size
80 | ):
81 | _, key = heappop(self.expire)
82 | self._cache.pop(key, None)
83 | await asyncio.sleep(self.interval)
84 |
--------------------------------------------------------------------------------
/chitung/library/service/config.py:
--------------------------------------------------------------------------------
1 | import kayaku
2 | from launart import Launart, Service
3 | from loguru import logger
4 |
5 |
6 | class ConfigService(Service):
7 | id = "chitung.service/config"
8 |
9 | @property
10 | def required(self):
11 | return set()
12 |
13 | @property
14 | def stages(self):
15 | return {"preparing", "cleanup"}
16 |
17 | async def launch(self, manager: Launart):
18 | async with self.stage("preparing"):
19 | # TODO: Implement database initialization
20 | # logger.success("[ConfigService] Initialized database")
21 |
22 | kayaku.bootstrap()
23 | kayaku.save_all()
24 | logger.success("[ConfigService] Initialized all configurations")
25 |
26 | async with self.stage("cleanup"):
27 | kayaku.save_all()
28 | logger.success("[ConfigService] Saved all configurations")
29 |
--------------------------------------------------------------------------------
/chitung/library/service/essential.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 |
3 | from avilla.core import Avilla
4 | from launart import Launart, Service
5 | from loguru import logger
6 |
7 | from chitung.library.const import CHITUNG_ROOT
8 |
9 |
10 | class ChitungService(Service):
11 | id = "chitung.service/essential"
12 | avilla: Avilla
13 |
14 | @property
15 | def broadcast(self):
16 | return self.avilla.broadcast
17 |
18 | def __init__(self):
19 | self.avilla = Avilla()
20 | super().__init__()
21 |
22 | @property
23 | def required(self):
24 | return {
25 | "chitung.service/config",
26 | "chitung.service/module",
27 | "chitung.service/protocol",
28 | }
29 |
30 | @property
31 | def stages(self):
32 | return {"preparing", "cleanup"}
33 |
34 | @staticmethod
35 | def ensure_path(path: str):
36 | if not (p := Path(CHITUNG_ROOT, path)).is_dir():
37 | p.mkdir(parents=True)
38 |
39 | async def launch(self, manager: Launart):
40 | self.ensure_path("config")
41 | self.ensure_path("data")
42 | self.ensure_path("module")
43 | logger.success("[ChitungService] Ensured all paths")
44 |
45 | async with self.stage("preparing"):
46 | logger.info("[ChitungService] Current stage: preparing")
47 |
48 | async with self.stage("cleanup"):
49 | logger.info("[ChitungService] Current stage: cleanup")
50 |
--------------------------------------------------------------------------------
/chitung/library/service/module.py:
--------------------------------------------------------------------------------
1 | import json
2 | import pkgutil
3 | from json import JSONDecodeError
4 | from pathlib import Path
5 |
6 | from creart import it
7 | from graia.saya import Saya
8 | from launart import Launart, Service
9 | from loguru import logger
10 | from pydantic import ValidationError
11 |
12 | from chitung.library.model.exception import RequirementResolveFailed
13 | from chitung.library.model.metadata import ModuleMetadata
14 | from chitung.library.const import CHITUNG_ROOT
15 |
16 |
17 | class ModuleStore:
18 | modules: set[ModuleMetadata]
19 | enabled: set[ModuleMetadata]
20 |
21 | def __init__(self, modules: set[ModuleMetadata], enabled: set[ModuleMetadata]):
22 | self.modules = modules
23 | self.enabled = enabled
24 |
25 | @property
26 | def disabled(self):
27 | return self.modules - self.enabled
28 |
29 |
30 | class ModuleService(Service):
31 | id = "chitung.service/module"
32 | modules: set[ModuleMetadata]
33 | enabled: set[ModuleMetadata]
34 |
35 | def __init__(self):
36 | self.modules = set()
37 | self.enabled = set()
38 | super().__init__()
39 |
40 | @property
41 | def required(self):
42 | return set()
43 |
44 | @property
45 | def stages(self):
46 | return {"preparing"}
47 |
48 | @staticmethod
49 | def parse_metadata(module: Path) -> ModuleMetadata:
50 | try:
51 | return ModuleMetadata.model_validate_json(
52 | (module / "metadata.json").read_text()
53 | )
54 | except ValidationError as e:
55 | logger.error(f"[ModuleService] {module.name} metadata is invalid")
56 | raise e
57 |
58 | @staticmethod
59 | def generate_metadata(module: Path) -> ModuleMetadata:
60 | module = module.resolve().relative_to(CHITUNG_ROOT)
61 | name = module.parts[-1]
62 | identifier = ".".join(module.parts)
63 | return ModuleMetadata(identifier=identifier, name=name)
64 |
65 | @staticmethod
66 | def write_metadata(metadata: ModuleMetadata):
67 | module_path = Path(metadata.identifier.replace(".", "/"))
68 | with (module_path / "metadata.json").open("w", encoding="utf-8") as f:
69 | f.write(
70 | json.dumps(
71 | metadata.model_dump(exclude={"type"}), indent=4, ensure_ascii=False
72 | )
73 | )
74 | f.write("\n")
75 |
76 | @staticmethod
77 | def standardize(module: Path) -> Path:
78 | if module.is_dir():
79 | return module
80 | new_path = module.parent / module.stem
81 | new_path.mkdir(exist_ok=True)
82 | module.rename(new_path / "__init__.py")
83 | logger.info(f"[ModuleService] Standardized {module} to {new_path}")
84 | return new_path
85 |
86 | def prepare_metadata(self, *paths: Path) -> list[ModuleMetadata]:
87 | prepared: list[ModuleMetadata] = []
88 | for path in paths:
89 | if not path.is_dir():
90 | continue
91 | for module in pkgutil.iter_modules([str(path)]):
92 | module_path = self.standardize(path / module.name)
93 | try:
94 | metadata = self.parse_metadata(module_path)
95 | prepared.append(metadata)
96 | except (ValidationError, FileNotFoundError, JSONDecodeError):
97 | metadata = self.generate_metadata(module_path)
98 | self.write_metadata(metadata)
99 | prepared.append(metadata)
100 | return prepared
101 |
102 | @staticmethod
103 | def resolve(*modules: ModuleMetadata) -> list[ModuleMetadata]:
104 | resolved: set[str] = set()
105 | unresolved: set[ModuleMetadata] = set(modules)
106 | result: list[ModuleMetadata] = []
107 |
108 | logger.info("[ModuleService] Resolving module dependencies")
109 | layer_count = 0
110 | while unresolved:
111 | layer = {
112 | module
113 | for module in unresolved
114 | if {dep.identifier for dep in module.dependencies} <= resolved
115 | }
116 | if not layer:
117 | logger.error(
118 | "[ModuleService] Failed to resolve module dependencies, "
119 | "the following modules are unresolved:\n"
120 | + ", ".join(module.identifier for module in unresolved)
121 | )
122 | raise RequirementResolveFailed(unresolved)
123 | layer_count += 1
124 | logger.info(
125 | f"[ModuleService] Resolved {len(layer)} modules in layer {layer_count}"
126 | )
127 | unresolved -= layer
128 | resolved |= {module.identifier for module in layer}
129 | result.extend(sorted(layer, key=lambda m: m.identifier))
130 |
131 | logger.success("[ModuleService] Resolved module dependencies")
132 | return result
133 |
134 | def require_modules(self, *paths: Path):
135 | saya = it(Saya)
136 | prepared = self.prepare_metadata(*paths)
137 | resolved = self.resolve(*prepared)
138 | with saya.module_context():
139 | for module in resolved:
140 | saya.require(module.identifier)
141 | self.modules |= set(resolved)
142 |
143 | @property
144 | def store(self):
145 | return ModuleStore(self.modules, self.enabled)
146 |
147 | async def launch(self, manager: Launart):
148 | self.require_modules(Path("library") / "module", Path("module"))
149 |
150 | async with self.stage("preparing"):
151 | logger.success("[ModuleService] Required all modules")
152 |
--------------------------------------------------------------------------------
/chitung/library/service/protocol.py:
--------------------------------------------------------------------------------
1 | import json
2 | import os
3 | from pathlib import Path
4 | from typing import Final
5 |
6 | from avilla.console.protocol import ConsoleProtocol
7 | from avilla.core import BaseProtocol
8 | from launart import Launart, Service
9 | from loguru import logger
10 |
11 | from chitung.library.model.protocol import ProtocolConfig
12 | from chitung.library.service import ChitungService
13 | from chitung.library.const import CHITUNG_ROOT
14 |
15 | _PROTOCOL_CREDENTIAL_PATH: Final[Path] = Path(
16 | CHITUNG_ROOT, "config", "library", "credentials"
17 | )
18 |
19 |
20 | class ProtocolService(Service):
21 | id = "chitung.service/protocol"
22 |
23 | @property
24 | def required(self):
25 | return set()
26 |
27 | @property
28 | def stages(self):
29 | return {"preparing"}
30 |
31 | def _load_console(self):
32 | if os.environ.get("CHITUNG_NO_CONSOLE") != "1":
33 | self.apply_protocols(ConsoleProtocol())
34 | else:
35 | logger.warning("[ProtocolService] Console protocol disabled")
36 |
37 | def apply_protocols(self, *protocols: BaseProtocol):
38 | self.manager.get_component(ChitungService).avilla.apply_protocols(*protocols)
39 |
40 | def _load_protocols(self):
41 | configs: list[ProtocolConfig] = []
42 | for file in _PROTOCOL_CREDENTIAL_PATH.rglob("*.json"):
43 | with file.open("r") as f:
44 | protocol = ProtocolConfig.resolve(json.load(f))
45 | if protocol.enabled:
46 | configs.append(protocol)
47 | if not configs:
48 | return
49 | logger.success(f"[ProtocolService] Loaded {len(configs)} registered protocols")
50 | self.apply_protocols(*(config.to_protocol() for config in configs))
51 |
52 | def register_protocol(self, config: ProtocolConfig):
53 | protocol_dir = _PROTOCOL_CREDENTIAL_PATH / config.protocol
54 | if not protocol_dir.exists():
55 | protocol_dir.mkdir(parents=True)
56 | with (protocol_dir / f"{config.id}.json").open("w") as f:
57 | f.write(config.model_dump_json(indent=4))
58 | self.apply_protocols(config.to_protocol())
59 |
60 | async def launch(self, manager: Launart):
61 | async with self.stage("preparing"):
62 | self._load_console()
63 | self._load_protocols()
64 |
--------------------------------------------------------------------------------
/chitung/library/service/session.py:
--------------------------------------------------------------------------------
1 | from contextlib import suppress
2 | from typing import Set
3 |
4 | from aiohttp import ClientSession
5 | from launart import Launart, Service
6 | from launart.status import Phase
7 | from loguru import logger
8 |
9 |
10 | class SessionService(Service):
11 | id = "chitung.service/session"
12 |
13 | @property
14 | def required(self) -> Set[str]:
15 | return set()
16 |
17 | @property
18 | def stages(self) -> Set[Phase]:
19 | return {"preparing", "cleanup"}
20 |
21 | _session: dict[str, ClientSession] = {}
22 |
23 | def get(
24 | self,
25 | name: str = "universal",
26 | flush: bool = False,
27 | base_url: str = None,
28 | /,
29 | **kwargs,
30 | ) -> ClientSession:
31 | if flush or name not in self._session or self._session[name].closed:
32 | self._session[name] = ClientSession(base_url=base_url, **kwargs)
33 | logger.success(f"[SessionService] Created session {name!r}")
34 | return self._session[name]
35 |
36 | async def close(self, name: str):
37 | if name in self._session.copy():
38 | await self._session[name].close()
39 | del self._session[name]
40 | logger.success(f"[SessionService] Closed session {name!r}")
41 |
42 | async def close_all(self):
43 | for name in self._session.copy():
44 | with suppress(Exception):
45 | await self.close(name)
46 |
47 | async def launch(self, manager: Launart):
48 | async with self.stage("preparing"):
49 | self.get()
50 | logger.success("[SessionService] Default session created")
51 |
52 | async with self.stage("cleanup"):
53 | await self.close_all()
54 | logger.success("[SessionService] All sessions closed")
55 |
--------------------------------------------------------------------------------
/chitung/library/util.py:
--------------------------------------------------------------------------------
1 | from datetime import time
2 | from pathlib import Path
3 |
4 | import richuru
5 | from loguru import logger
6 |
7 |
8 | def setup_logger(sink: Path, log_rotate: int, no_store_log: bool = False):
9 | if not no_store_log:
10 | logger.add(
11 | sink / "{time:YYYY-MM-DD}" / "common.log",
12 | level="INFO",
13 | retention=f"{log_rotate} days" if log_rotate else None,
14 | encoding="utf-8",
15 | rotation=time(),
16 | )
17 | logger.add(
18 | sink / "{time:YYYY-MM-DD}" / "error.log",
19 | level="ERROR",
20 | retention=f"{log_rotate} days" if log_rotate else None,
21 | encoding="utf-8",
22 | rotation=time(),
23 | )
24 | richuru.install()
25 |
--------------------------------------------------------------------------------
/chitung/module/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullqwertyuiop/Chitung-python/58882c5a8dcbb1e7ba81442aae110f28bdce4b3c/chitung/module/__init__.py
--------------------------------------------------------------------------------
/chitung/module/bank/__init__.py:
--------------------------------------------------------------------------------
1 | from avilla.core import Avilla, Context
2 | from avilla.standard.core.message import MessageReceived
3 | from avilla.twilight.twilight import FullMatch, Twilight
4 | from graia.amnesia.message import MessageChain, Text
5 | from graia.saya.builtins.broadcast.shortcut import dispatch, listen
6 |
7 | from chitung.library.service.bank import BankService, Currency
8 |
9 |
10 | @listen(MessageReceived)
11 | @dispatch(Twilight(FullMatch("/bank")))
12 | async def get_bank(avilla: Avilla, ctx: Context):
13 | vault = avilla.launch_manager.get_component(BankService).vault
14 | currency = Currency.PUMPKIN_PESO
15 | balance = await vault.get_balance(ctx.client, currency)
16 | await ctx.scene.send_message(
17 | MessageChain([Text(f"您的余额为 {balance} {currency.fullname()}")])
18 | )
19 |
--------------------------------------------------------------------------------
/chitung/module/bank/metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "identifier": "module.bank",
3 | "name": "bank",
4 | "version": "0.1.0",
5 | "description": "",
6 | "author": [],
7 | "dependencies": []
8 | }
9 |
--------------------------------------------------------------------------------
/chitung/module/blackjack/__init__.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 |
3 | from avilla.core import Context, Message, Notice, Picture, Selector
4 | from avilla.standard.core.message import MessageReceived
5 | from avilla.twilight.twilight import (
6 | FullMatch,
7 | MatchResult,
8 | RegexMatch,
9 | Twilight,
10 | UnionMatch,
11 | )
12 | from graia.amnesia.message import MessageChain, Text
13 | from graia.saya.builtins.broadcast.shortcut import dispatch, listen
14 | from launart import Launart
15 |
16 | from chitung.library.const import ASSETS_ROOT
17 | from chitung.library.service import BankService
18 | from chitung.library.service.bank import Currency
19 |
20 | from .blackjack import (
21 | BOOKMAKER_SELECTOR,
22 | BlackJackData,
23 | BlackJackPhase,
24 | BlackJackPlayer,
25 | )
26 |
27 |
28 | @listen(MessageReceived)
29 | @dispatch(
30 | Twilight(
31 | [
32 | UnionMatch(
33 | "/deal",
34 | "/fold",
35 | "/split",
36 | "/double",
37 | "/pair",
38 | "/assurance",
39 | "/surrender",
40 | "要牌",
41 | "停牌",
42 | "分牌",
43 | "双倍下注",
44 | "下注对子",
45 | "买保险",
46 | "投降",
47 | )
48 | @ "function",
49 | ]
50 | )
51 | )
52 | async def chitung_blackjack_ops_handler(ctx: Context, msg: Message):
53 | function = str(msg.content)
54 | try:
55 | if function in {"/deal", "要牌"}:
56 | await deal(ctx)
57 | elif function in {"/fold", "停牌"}:
58 | await fold(ctx)
59 | elif function in {"/split", "分牌"}:
60 | await split(ctx)
61 | elif function in {"/double", "双倍下注"}:
62 | await double_bet(ctx)
63 | elif function in {"/pair", "下注对子"}:
64 | await pair(ctx)
65 | elif function in {"/assurance", "买保险"}:
66 | await assurance(ctx)
67 | elif function in {"/surrender", "投降"}:
68 | await surrender(ctx)
69 |
70 | bjd, _ = get_valid_game_and_player(ctx)
71 | if bjd.check_all_fold():
72 | await checkout_game(ctx)
73 | except ValueError:
74 | return
75 |
76 |
77 | @listen(MessageReceived)
78 | @dispatch(
79 | Twilight(
80 | FullMatch("/bet"),
81 | RegexMatch(r"\s*[0-9]*") @ "amount",
82 | )
83 | )
84 | async def chitung_blackjack_bet_handler(
85 | ctx: Context,
86 | amount: MatchResult,
87 | ):
88 | bets = int(str(amount.result).strip())
89 | await bet(ctx, bets)
90 |
91 |
92 | @listen(MessageReceived)
93 | @dispatch(Twilight(UnionMatch("/blackjack", "二十一点")))
94 | async def chitung_blackjack_handler(ctx: Context):
95 | if ctx.scene in blackjack_sessions:
96 | return await send_message(ctx, MessageChain("游戏正在进行中。"))
97 | reply_msg = "里格斯公司邀请您参与本局 Blackjack,请在60秒之内输入 /bet+数字 参与游戏。"
98 | reply_msg += Picture(ASSETS_ROOT / "blackjack" / "instructions.png")
99 | await send_message(ctx, MessageChain(reply_msg), False)
100 | bjd = BlackJackData(ctx.scene)
101 | blackjack_sessions[ctx.scene] = bjd
102 | await asyncio.sleep(60)
103 | if bjd.phase != BlackJackPhase.Callin:
104 | return
105 | blackjack_sessions.pop(ctx.scene)
106 | await send_message(ctx, MessageChain("本局 Blackjack 已经取消。"))
107 |
108 |
109 | async def bet(ctx: Context, bets: int):
110 | bjd = get_game_data(ctx.scene)
111 | if bjd is None:
112 | return
113 | if bets <= 0:
114 | raise ValueError
115 |
116 | if await purchase(ctx.client, bets):
117 | if bjd.phase == BlackJackPhase.Callin:
118 | bjd.phase = BlackJackPhase.Bet
119 | if ctx.client.pattern == bjd.scene.pattern:
120 | asyncio.create_task(end_bet_phase(ctx, 0))
121 | else:
122 | await send_message(
123 | ctx,
124 | MessageChain("Bet 阶段已经开始,预计在 60 秒之内结束。可以通过 /bet+金额 反复追加 bet。"),
125 | False,
126 | )
127 | asyncio.create_task(end_bet_phase(ctx))
128 | if bjd.black_jack_players.get(ctx.client) is None:
129 | # 新玩家
130 | prompt = f"已收到下注 {bets} 南瓜比索。"
131 | else:
132 | prompt = f"共收到下注 {bets + bjd.black_jack_players.get(ctx.client).bet} 南瓜比索。"
133 | bjd.bet(ctx.client, bets)
134 | await send_message(ctx, MessageChain(prompt))
135 | else:
136 | await send_message(ctx, MessageChain("操作失败,请检查您的南瓜比索数量。"))
137 |
138 |
139 | async def end_bet_phase(ctx: Context, time_out: int = 60):
140 | await asyncio.sleep(time_out)
141 | bjd = get_game_data(ctx.scene)
142 | if bjd is None:
143 | return
144 | bjd.end_bet()
145 | await send_message(ctx, MessageChain("Bet 阶段已经结束。"), notice=False)
146 | reply_msg = MessageChain("抽牌情况如下:\n")
147 | reply_msg += f"庄家的牌是:\n{bjd.black_jack_players[BOOKMAKER_SELECTOR].cards[0]} 暗牌"
148 | for player in bjd.black_jack_players.values():
149 | if player.client.pattern == BOOKMAKER_SELECTOR.pattern:
150 | continue
151 | if ctx.scene != ctx.client: # 判断是不是群
152 | reply_msg += MessageChain(["\n\n", Notice(player.client), " 的牌是:\n"])
153 | else:
154 | reply_msg += MessageChain("\n\n你的牌是:\n")
155 | reply_msg += f" {player.cards[0]} {player.cards[1]}"
156 | await send_message(ctx, reply_msg, notice=False)
157 | await send_message(
158 | ctx,
159 | MessageChain("现在可以进行操作,请在 60 秒之内完成。功能列表请参考说明书。"),
160 | notice=False,
161 | )
162 | await end_operate_phase(ctx)
163 |
164 |
165 | async def end_operate_phase(ctx: Context):
166 | await asyncio.sleep(60)
167 | bjd = get_game_data(ctx.scene)
168 | if bjd is None:
169 | # 提前结束
170 | return
171 | bjd.fold_all()
172 | await checkout_game(ctx)
173 |
174 |
175 | async def checkout_game(ctx: Context):
176 | bjd = get_game_data(ctx.scene)
177 | # 庄家操作
178 | bookmaker_pile_msg = bjd.bookmaker_operate()
179 | await send_message(ctx, MessageChain(bookmaker_pile_msg), False)
180 | reply_msg = MessageChain("本局游戏已经结束,里格斯公司感谢您的参与。如下为本局玩家获得的南瓜比索:\n")
181 | result = bjd.check()
182 | for player in bjd.black_jack_players.values():
183 | if player.is_bookmaker:
184 | continue
185 | if ctx.client.pattern == bjd.scene.pattern:
186 | reply_msg += f"\n您获得了 {result[player.client]} 南瓜比索。"
187 | else:
188 | reply_msg += MessageChain(
189 | [
190 | "\n",
191 | Notice(player.client),
192 | f" 获得了 {result[player.client]} 南瓜比索。",
193 | ]
194 | )
195 | await exchange(ctx.client, result[player.client])
196 | blackjack_sessions.pop(ctx.scene)
197 | await send_message(ctx, reply_msg, notice=False)
198 |
199 |
200 | async def deal(ctx: Context):
201 | bjd, player = get_valid_game_and_player(ctx)
202 | if player.can_operate:
203 | deal_result = bjd.deal(ctx.client)
204 | await send_message(ctx, MessageChain(f"您抽到的牌是:{deal_result[0]}"))
205 | if not deal_result[1]:
206 | await send_message(ctx, MessageChain("您爆牌了。"))
207 | bjd.busted(player.client)
208 |
209 |
210 | async def fold(ctx: Context):
211 | bjd, player = get_valid_game_and_player(ctx)
212 | if player.can_operate:
213 | bjd.fold(player.client)
214 | await send_message(ctx, MessageChain("您已经停牌。"))
215 | if bjd.check_all_fold():
216 | await checkout_game(ctx)
217 |
218 |
219 | async def split(ctx: Context):
220 | bjd, player = get_valid_game_and_player(ctx)
221 | if not player.can_operate:
222 | return
223 | if not player.can_split():
224 | return
225 | if not purchase(ctx.client, player.bet):
226 | await send_message(ctx, MessageChain("操作失败,请检查您的南瓜比索数量。"))
227 | return
228 | raw_cards, piles = bjd.split(player.client)
229 | reply_msg = MessageChain(
230 | f"您的原始牌堆为:\n{raw_cards[0]}{raw_cards[1]}\n您两个牌堆抽到的牌分别是:\n牌堆I:"
231 | )
232 | for card in piles[0]:
233 | reply_msg += f" {card}"
234 | reply_msg += "\n牌堆II:"
235 | for card in piles[1]:
236 | reply_msg += f" {card}"
237 | await send_message(ctx, reply_msg, ctx.client != ctx.scene)
238 |
239 |
240 | async def double_bet(ctx: Context):
241 | bjd, player = get_valid_game_and_player(ctx)
242 | if not player.can_operate:
243 | return
244 | if not player.can_double_bet():
245 | await send_message(ctx, MessageChain("您的牌无法双倍下注。"))
246 | return
247 | if not purchase(ctx.client, player.bet):
248 | await send_message(ctx, MessageChain("操作失败,请检查您的南瓜比索数量。"))
249 | return
250 | bjd.double_bet(player.client)
251 |
252 |
253 | async def assurance(ctx: Context):
254 | bjd, player = get_valid_game_and_player(ctx)
255 | if not player.can_operate:
256 | return
257 | if bjd.assurance(player.client):
258 | await send_message(ctx, MessageChain("您已经购买保险。"))
259 | else:
260 | await send_message(ctx, MessageChain("目前的牌局无法购买保险。"))
261 |
262 |
263 | async def pair(ctx: Context):
264 | bjd, player = get_valid_game_and_player(ctx)
265 | if not player.can_operate:
266 | return
267 | if not purchase(ctx.client, player.bet):
268 | await send_message(ctx, MessageChain("操作失败,请检查您的南瓜比索数量。"))
269 | return
270 | if bjd.bet_pair(player.client):
271 | await send_message(ctx, MessageChain("您已经下注对子。"))
272 | else:
273 | await send_message(ctx, MessageChain("无法重复下注对子。"))
274 |
275 |
276 | async def surrender(ctx: Context):
277 | bjd, player = get_valid_game_and_player(ctx)
278 | if not player.can_operate:
279 | return
280 | bjd.surrender(player.client)
281 | await send_message(ctx, MessageChain("您投降了,将会返还您一半的赌注。"))
282 |
283 |
284 | def get_valid_game_and_player(ctx: Context) -> tuple[BlackJackData, BlackJackPlayer]:
285 | bjd = get_game_data(ctx.scene)
286 | if bjd is None:
287 | raise ValueError
288 | player = bjd.black_jack_players[ctx.client]
289 | if player is None:
290 | raise ValueError
291 | return bjd, player
292 |
293 |
294 | async def purchase(target: Selector, cost: int) -> bool:
295 | vault = Launart.current().get_component(BankService).vault
296 | if await vault.has_enough(target, Currency.PUMPKIN_PESO, cost):
297 | await vault.withdraw(target, Currency.PUMPKIN_PESO, cost)
298 | return True
299 | return False
300 |
301 |
302 | async def exchange(target: Selector, num: int):
303 | vault = Launart.current().get_component(BankService).vault
304 | await vault.deposit(target, Currency.PUMPKIN_PESO, num)
305 |
306 |
307 | async def send_message(ctx: Context, msg: MessageChain, notice: bool = True):
308 | if notice:
309 | msg.content.insert(0, Notice(ctx.client))
310 | msg.content.insert(1, Text(" "))
311 | await ctx.scene.send_message(msg)
312 |
313 |
314 | def get_game_data(scene: Selector) -> BlackJackData | None:
315 | return blackjack_sessions[scene] if scene in blackjack_sessions else None
316 |
317 |
318 | blackjack_sessions: dict[Selector, BlackJackData] = {}
319 |
--------------------------------------------------------------------------------
/chitung/module/blackjack/blackjack.py:
--------------------------------------------------------------------------------
1 | import itertools
2 | import random
3 | from datetime import datetime, timezone
4 | from enum import Enum, auto
5 | from typing import Final
6 |
7 | from avilla.core import Selector
8 |
9 | DECK_NUM: int = 4
10 | BOOKMAKER_SELECTOR: Final[Selector] = Selector()
11 |
12 |
13 | class BlackJackPhase(Enum):
14 | Callin = auto()
15 | Bet = auto()
16 | Operation = auto()
17 |
18 |
19 | class PokerSuit(str, Enum):
20 | Diamond = "♦"
21 | Club = "♣"
22 | Heart = "♥"
23 | Spade = "♠"
24 |
25 | @staticmethod
26 | def get(index: int):
27 | return [PokerSuit.Diamond, PokerSuit.Club, PokerSuit.Heart, PokerSuit.Spade][
28 | index
29 | ]
30 |
31 |
32 | class Poker:
33 | _poker_name: Final[str] = [
34 | "A",
35 | "2",
36 | "3",
37 | "4",
38 | "5",
39 | "6",
40 | "7",
41 | "8",
42 | "9",
43 | "10",
44 | "J",
45 | "Q",
46 | "K",
47 | ]
48 |
49 | def __init__(self, number: int, suit: PokerSuit):
50 | self.number = number
51 | self.suit = suit
52 | self.point = min(number + 1, 10)
53 |
54 | def __str__(self):
55 | return str(self.suit.value) + self._poker_name[self.number]
56 |
57 | def __eq__(self, other):
58 | if not isinstance(other, Poker):
59 | return False
60 | return self.point == other.point and self.suit == other.suit
61 |
62 | def __hash__(self):
63 | return hash(self._poker_name)
64 |
65 |
66 | class BlackJackPlayer:
67 | client: Selector
68 | is_bookmaker: bool
69 | bet: int
70 | cards: list[Poker]
71 | bet_pair: bool
72 | has_split: bool
73 | can_operate: bool
74 | is_double: bool
75 | has_assurance: bool
76 | has_busted: bool
77 | has_surrendered: bool
78 |
79 | def __init__(self, player: Selector, bet: int = 0, is_bookmaker: bool = False):
80 | self.client = player
81 | self.is_bookmaker = is_bookmaker
82 | self.bet = bet
83 | self.cards = []
84 | self.bet_pair = False
85 | self.has_split = False
86 | self.can_operate = False
87 | self.is_double = False
88 | self.has_assurance = False
89 | self.has_busted = False
90 | self.has_surrendered = False
91 |
92 | def draw_card(self, *cards: Poker):
93 | self.cards.extend(cards)
94 |
95 | def calculate_point(self) -> int:
96 | return self.calculate_cards_point(*self.cards)
97 |
98 | @staticmethod
99 | def calculate_cards_point(*cards: Poker):
100 | point = 0
101 | for card in sorted(cards, key=lambda x: x.point, reverse=True):
102 | if card.point == 1:
103 | point += 11 if point <= 10 else 1
104 | else:
105 | point += card.point
106 | return point
107 |
108 | def can_double_bet(self) -> bool:
109 | if len(self.cards) != 2:
110 | return False
111 | return self.calculate_point() in [11, 21] and not self.is_double
112 |
113 | def can_split(self) -> bool:
114 | return False if len(self.cards) != 2 else self.cards[0] == self.cards[1]
115 |
116 |
117 | class BlackJackData:
118 | def __init__(self, scene: Selector):
119 | self.scene = scene
120 | self.black_jack_players: dict[Selector, BlackJackPlayer] = {}
121 | self.phase: BlackJackPhase = BlackJackPhase.Callin
122 | self.card_number: int = 0
123 | self.card_pile: list[Poker] = []
124 | self.create_card_pile()
125 | self.shuffle_card_pile()
126 |
127 | def __eq__(self, other):
128 | return (
129 | False
130 | if isinstance(other, BlackJackData)
131 | else self.scene.pattern == other.scene.pattern
132 | )
133 |
134 | def __hash__(self):
135 | return hash(self.scene)
136 |
137 | def create_card_pile(self):
138 | for _, i in itertools.product(range(DECK_NUM), range(52)):
139 | number = i // 4
140 | suit = list(PokerSuit.__members__.values())[i % 4]
141 | card = Poker(number, suit)
142 | self.card_pile.append(card)
143 | self.shuffle_card_pile()
144 |
145 | def shuffle_card_pile(self):
146 | random.Random(datetime.now(timezone.utc).timestamp()).shuffle(self.card_pile)
147 |
148 | def bet(self, player: Selector, bet_num: int):
149 | self.black_jack_players.setdefault(
150 | player, BlackJackPlayer(player, bet=0)
151 | ).bet += bet_num
152 |
153 | def end_bet(self):
154 | self.phase = BlackJackPhase.Operation
155 | self.black_jack_players[BOOKMAKER_SELECTOR] = BlackJackPlayer(
156 | BOOKMAKER_SELECTOR, 0, True
157 | ) # 添加一位庄家
158 | for player in self.black_jack_players.values():
159 | player.draw_card(self.card_pile.pop(), self.card_pile.pop())
160 | player.can_operate = True
161 |
162 | def deal(self, player: Selector):
163 | player = self.black_jack_players[player]
164 | card = self.card_pile.pop()
165 | player.draw_card(card)
166 | return card, player.calculate_point() <= 21
167 |
168 | def assurance(self, player: Selector):
169 | if self.black_jack_players[BOOKMAKER_SELECTOR].cards[0].number == 0:
170 | self.black_jack_players[player].has_assurance = True
171 | return True
172 | return False
173 |
174 | def double_bet(self, player: Selector):
175 | player = self.black_jack_players[player]
176 | player.bet *= 2
177 | player.can_operate = False
178 |
179 | def fold(self, player: Selector):
180 | self.black_jack_players[player].can_operate = False
181 |
182 | def bet_pair(self, player: Selector):
183 | player = self.black_jack_players[player]
184 | if not player.bet_pair:
185 | player.bet_pair = True
186 | return True
187 | return False
188 |
189 | def split(self, player: Selector):
190 | player = self.black_jack_players[player]
191 | player.has_split = True
192 | player.can_operate = False
193 | piles = [[player.cards[0]], [player.cards[1]]]
194 | for pile in piles:
195 | while player.calculate_cards_point(*pile) < 17:
196 | poker = self.card_pile.pop()
197 | pile.append(poker)
198 | raw_cards = player.cards
199 | player.cards = piles
200 | return raw_cards, piles
201 |
202 | def surrender(self, player: Selector):
203 | self.black_jack_players[player].can_operate = False
204 | self.black_jack_players[player].has_surrendered = True
205 |
206 | def busted(self, player: Selector):
207 | player = self.black_jack_players[player]
208 | player.can_operate = False
209 | player.has_busted = True
210 |
211 | def check_all_fold(self):
212 | return not [
213 | player
214 | for player in self.black_jack_players.values()
215 | if player.client != BOOKMAKER_SELECTOR and player.can_operate
216 | ]
217 |
218 | def fold_all(self):
219 | for player in self.black_jack_players:
220 | self.fold(player)
221 |
222 | def bookmaker_operate(self):
223 | bookmaker = self.black_jack_players[BOOKMAKER_SELECTOR]
224 | while bookmaker.calculate_point() < 17:
225 | self.deal(BOOKMAKER_SELECTOR)
226 | msg = "庄家开的牌组是:\n"
227 | for card in bookmaker.cards:
228 | msg += f" {card}"
229 | return msg
230 |
231 | def check(self):
232 | return {
233 | player: int(self.calculate_bet(player))
234 | for player in self.black_jack_players
235 | if not self.black_jack_players[player].is_bookmaker
236 | }
237 |
238 | def calculate_bet(self, player: Selector):
239 | player = self.black_jack_players[player]
240 | coefficient = (
241 | (1 - int(player.has_assurance) * 0.5) * self.normal_point(player.client)
242 | + self.pair_point(player.client)
243 | + self.special_pattern_point(player.client)
244 | + int(player.has_assurance) * self.assurance_point(player.client)
245 | )
246 | return player.bet * coefficient
247 |
248 | def normal_point(self, player: Selector):
249 | player = self.black_jack_players[player]
250 | if player.has_surrendered:
251 | return 0.5
252 | if player.has_split:
253 | point_1 = player.calculate_cards_point(player.cards[0])
254 | if point_1 > 21:
255 | point_1 = 0
256 | point_2 = player.calculate_cards_point(player.cards[1])
257 | if point_2 > 21:
258 | point_2 = 0
259 | return self.compare_with_bookmaker(point_1) + self.compare_with_bookmaker(
260 | point_2
261 | )
262 | if player.has_busted:
263 | return 0
264 | return self.compare_with_bookmaker(player.calculate_point())
265 |
266 | def pair_point(self, player: Selector):
267 | player = self.black_jack_players[player]
268 | if not player.bet_pair:
269 | return 0
270 | bookmaker = self.black_jack_players[BOOKMAKER_SELECTOR]
271 | return 11 if bookmaker.cards[0] == bookmaker.cards[1] else 0
272 |
273 | def assurance_point(self, player: Selector):
274 | player = self.black_jack_players[player]
275 | if not player.has_assurance:
276 | return 0
277 | bookmaker = self.black_jack_players[BOOKMAKER_SELECTOR]
278 | return int(bookmaker.cards[1] == 10) * (1 + int(player.has_split))
279 |
280 | def special_pattern_point(self, player: Selector):
281 | player = self.black_jack_players[player]
282 | cards = player.cards
283 | if len(cards) != 3:
284 | return 0
285 | cards_point = [card.point for card in cards]
286 | if all(_ == 7 for _ in cards_point) or {6, 7, 8}.issubset(set(cards_point)):
287 | return 3
288 | return 0
289 |
290 | def compare_with_bookmaker(self, point):
291 | bookmaker = self.black_jack_players[BOOKMAKER_SELECTOR]
292 | bookmaker_point = bookmaker.calculate_point()
293 | if bookmaker_point > 21:
294 | bookmaker_point = 1
295 | if bookmaker_point > point:
296 | return 0
297 | elif bookmaker_point == point:
298 | return 1
299 | else:
300 | return 2
301 |
--------------------------------------------------------------------------------
/chitung/module/blackjack/metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "identifier": "module.blackjack",
3 | "name": "blackjack",
4 | "version": "0.1.0",
5 | "description": "",
6 | "author": [],
7 | "dependencies": []
8 | }
9 |
--------------------------------------------------------------------------------
/chitung/module/fortune_teller/__init__.py:
--------------------------------------------------------------------------------
1 | import random
2 | from contextlib import contextmanager
3 | from datetime import datetime
4 | from hashlib import md5
5 | from pathlib import Path
6 |
7 | from avilla.core import Context, Picture, Selector
8 | from avilla.standard.core.message import MessageReceived
9 | from avilla.twilight.twilight import Twilight, UnionMatch, WildcardMatch
10 | from graia.amnesia.message import MessageChain, Text
11 | from graia.saya.builtins.broadcast.shortcut import dispatch, listen
12 |
13 | from .const import (
14 | ASSETS_DIR,
15 | CHINESE_NUM,
16 | FENG_XIANG,
17 | HUA_PAI,
18 | LUCK,
19 | SAYING,
20 | ZHONG_FA_BAI,
21 | )
22 |
23 |
24 | @contextmanager
25 | def seed(target: Selector):
26 | now = datetime.now()
27 | hashed = int(md5(target.last_value.encode()).hexdigest(), 16)
28 | random.seed(int(f"{hashed}{now.year * 1000}{now.month * 100}{now.day}"))
29 | yield
30 | random.seed()
31 |
32 |
33 | def build_chain(target: Selector) -> MessageChain:
34 | if random.random() <= 0.02:
35 | return MessageChain(
36 | [
37 | Text("今天的占卜麻将牌是: 寄\n运势是: 寄吧\n是寄吧,寄吧寄吧寄吧"),
38 | Picture(Path(ASSETS_DIR / "寄.jpg")),
39 | ]
40 | )
41 |
42 | with seed(target):
43 | mahjong_of_the_day = random.randint(1, 144)
44 | if mahjong_of_the_day < 36:
45 | mahjong_num = mahjong_of_the_day % 9
46 | mahjong = f"{CHINESE_NUM[mahjong_of_the_day % 9]}筒"
47 | elif mahjong_of_the_day < 72:
48 | mahjong_num = (mahjong_of_the_day - 36) % 9 + 9
49 | mahjong = f"{CHINESE_NUM[mahjong_of_the_day % 9]}条"
50 | elif mahjong_of_the_day < 108:
51 | mahjong_num = (mahjong_of_the_day - 72) % 9 + 18
52 | mahjong = f"{CHINESE_NUM[mahjong_of_the_day % 9]}萬"
53 | elif mahjong_of_the_day < 124:
54 | mahjong_num = (mahjong_of_the_day - 108) % 4 + 27
55 | mahjong = f"{FENG_XIANG[mahjong_of_the_day % 4]}风"
56 | elif mahjong_of_the_day < 136:
57 | mahjong_num = (mahjong_of_the_day - 124) % 3 + 31
58 | mahjong = ZHONG_FA_BAI[mahjong_of_the_day % 3]
59 | else:
60 | mahjong_num = mahjong_of_the_day - 102
61 | mahjong = f"花牌({HUA_PAI[mahjong_of_the_day - 136]})"
62 | colour = "Red" if random.randrange(2) else "Yellow"
63 | return MessageChain(
64 | [
65 | Text(
66 | f"今天的占卜麻将牌是: {mahjong}\n运势是: "
67 | f"{LUCK[mahjong_num]}\n{SAYING[mahjong_num]}"
68 | ),
69 | Picture(Path(ASSETS_DIR / colour / f"{mahjong}.png")),
70 | ]
71 | )
72 |
73 |
74 | @listen(MessageReceived)
75 | @dispatch(Twilight(WildcardMatch(), UnionMatch("求签", "麻将"), WildcardMatch()))
76 | async def fortune_teller(ctx: Context):
77 | await ctx.scene.send_message(build_chain(ctx.client))
78 |
--------------------------------------------------------------------------------
/chitung/module/fortune_teller/const.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 | from typing import Final
3 |
4 | from chitung.library.const import ASSETS_ROOT
5 |
6 | CHINESE_NUM: Final[list[str]] = ["一", "二", "三", "四", "五", "六", "七", "八", "九"]
7 | FENG_XIANG: Final[list[str]] = ["東", "南", "西", "北"]
8 | ZHONG_FA_BAI: Final[list[str]] = ["红中", "發财", "白板"]
9 | HUA_PAI: Final[list[str]] = ["春", "夏", "秋", "冬", "梅", "兰", "竹", "菊"]
10 | LUCK: Final[list[str]] = [
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 | SAYING: Final[list[str]] = [
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 | ASSETS_DIR: Final[Path] = ASSETS_ROOT / "mahjong"
100 |
--------------------------------------------------------------------------------
/chitung/module/fortune_teller/metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "identifier": "module.fortune_teller",
3 | "name": "fortune_teller",
4 | "version": "0.1.0",
5 | "description": "",
6 | "author": [],
7 | "dependencies": []
8 | }
9 |
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | import argparse
2 | import os
3 |
4 | from loguru import logger
5 |
6 |
7 | parser = argparse.ArgumentParser()
8 | parser.add_argument("--no-console", action="store_true")
9 | parser.add_argument("--no-store-log", action="store_true")
10 | args = parser.parse_args()
11 |
12 |
13 | if __name__ == "__main__":
14 | if args.no_console:
15 | os.environ["CHITUNG_NO_CONSOLE"] = "1"
16 |
17 | import sys
18 |
19 | from chitung.library import launch
20 | from chitung.library.const import CHITUNG_ROOT
21 | from chitung.library.util import setup_logger
22 |
23 | os.chdir("chitung")
24 | sys.path.append(os.path.join(os.getcwd()))
25 |
26 | setup_logger(CHITUNG_ROOT / "log", 7, no_store_log=args.no_store_log)
27 | logger.info("Launching Chitung...")
28 | launch()
29 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [project]
2 | name = "Chitung"
3 | version = "0.1.0"
4 | description = "Public Version of Chitung rewritten in Python"
5 | authors = [
6 | {name = "nullqwertyuiop", email = "null@member.fsf.org"},
7 | {name = "yhluk", email = "luyinhao@outlook.com"},
8 | {name = "MarbleGate", email = "marblegatekeeper@outlook.com"},
9 | ]
10 | dependencies = [
11 | "toml>=0.10.2",
12 | "pydantic>=2.5.3",
13 | "uvicorn>=0.24.0.post1",
14 | "psutil>=5.9.6",
15 | "graia-broadcast>=0.23.4",
16 | "avilla-core>=1.0.0a17",
17 | "graia-saya>=0.0.19",
18 | "aiohttp>=3.9.1",
19 | "avilla-twilight>=0.3.1",
20 | "avilla-console>=1.0.0a19",
21 | "kayaku>=0.5.4",
22 | "avilla-onebot-v11>=1.0.0a19",
23 | "richuru>=0.1.1",
24 | "lxml>=5.1.0",
25 | ]
26 | requires-python = ">=3.11"
27 | readme = "README.md"
28 | license = {text = "AGPL-3.0 License"}
29 |
30 | [tool.pdm.build]
31 | includes = []
32 |
33 | [build-system]
34 | requires = ["pdm-backend"]
35 | build-backend = "pdm.backend"
36 |
37 | [tool.isort]
38 | profile = "black"
39 |
40 | [project.optional-dependencies]
41 | dev = [
42 | "pre-commit>=3.5.0",
43 | "flake8>=6.1.0",
44 | "isort>=5.12.0",
45 | "black>=23.11.0",
46 | ]
47 |
--------------------------------------------------------------------------------