Skip to content

Commit 97aa06e

Browse files
authored
Merge pull request #1 from TISUnion/MCDR
MCDR compatibility
2 parents d2e39b1 + 5a58309 commit 97aa06e

File tree

13 files changed

+881
-201
lines changed

13 files changed

+881
-201
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
seen.json
22
.vscode/settings.json
33
.idea
4+
5+
*.mcdr

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
a plugin for MCDaemon
1+
a plugin for MCDR v2.0

lang/en_us.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
mcd_seen.help_msg: |
2+
------ MCDR {3} v{4} ------
3+
A plugin to query players online and offline time.
4+
§d【Command Help】§r
5+
§7{0}§r Show this message.
6+
§7{0}§r §e<player>§r Query player's on/offline time.
7+
§7{1}§r Show the rank of offline time
8+
§7{2}§r Show the rank of online time.
9+
§d【Additional Arguments】§r
10+
You can add more arguments when showing the ranks.
11+
The data will not include bot if no more arguments given.
12+
§e(Shadowing player will be proccessed as bot too.)§r
13+
§6There is following arguments available:§6
14+
The argument in same color mustn't be given in 1 command.
15+
§6-all§r Show all the data.
16+
§6-merge§r Show all the data (merging bot and player data)
17+
§6-bot§r Show bot data only.
18+
§e-full§r Can only be used on offline rank, Show all the data instead of top 10, §ebut may show too much message sometimes.
19+
20+
# Plain text
21+
mcd_seen.text.reg_help_msg: View laziness & hardworking rank
22+
mcd_seen.text.player: player
23+
mcd_seen.text.bot: bot
24+
mcd_seen.text.seen: have been offline for
25+
mcd_seen.text.player_liver: have been online for
26+
mcd_seen.text.bot_liver: have been online for
27+
mcd_seen.text.top_normal: §dplayer only§r
28+
mcd_seen.text.top_bot: §5bot only§r
29+
mcd_seen.text.top_merge: §7all players§r/§emerged§r
30+
mcd_seen.text.top_all: §7all players§r
31+
mcd_seen.text.reloaded: Plugin reloaded
32+
33+
# Hover texts
34+
mcd_seen.hover.help_msg_suggest: "Click to fill {}"
35+
mcd_seen.hover.query_player: "Click to query player {}"
36+
mcd_seen.hover.show_help: "Click to show help"
37+
38+
# Format texts
39+
mcd_seen.fmt.time_seen: "sec min hrs day"
40+
mcd_seen.fmt.seen_top: "Here are the {num} players §cofflined§r for the longest time({arg}):"
41+
mcd_seen.fmt.seen_top_full: "Here are all the players' offline time data({arg})"
42+
mcd_seen.fmt.liver_top: "Here are the players §acurrently online§r({arg}):"
43+
44+
# Error texts
45+
mcd_seen.error.player_data_not_found: Player data not found! Click here for help
46+
mcd_seen.error.cmd_error: Command error! Click here for help

lang/zh_cn.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
mcd_seen.help_msg: |
2+
§7-----§r MCDR {3} v{4} §7-----§r
3+
一个查看服务器玩家在线(爆肝)和下线(摸鱼)时间的插件
4+
§d【指令说明】§r
5+
§7{0}§r 显示帮助信息
6+
§7{0}§r §e<玩家>§r 查看玩家摸鱼/爆肝时长
7+
§7{1}§r 查看摸鱼榜
8+
§7{2}§r 查看爆肝榜
9+
§d【额外参数说明】§r
10+
查看爆肝摸鱼榜时可添加额外参数
11+
在不添加参数的情况下默认统计非假人玩家数据
12+
(玩家shadow也算作假人处理)
13+
参数如下所示:
14+
同种颜色标注的参数不可叠加使用
15+
§6-all§r 显示全部玩家统计数据(玩家同名假人会独立显示)
16+
§6-merge§r 显示全部玩家统计数据(玩家和同名假人会合并显示)
17+
§6-bot§r 仅显示假人的统计数据
18+
§e-full§r 用于摸鱼榜,显示完整榜单(会刷屏, 慎用)
19+
20+
# Plain text
21+
mcd_seen.text.reg_help_msg: 显示爆肝/摸鱼榜
22+
mcd_seen.text.player: 玩家
23+
mcd_seen.text.bot: 假人
24+
mcd_seen.text.seen: 已经摸了
25+
mcd_seen.text.player_liver: 已经肝了
26+
mcd_seen.text.bot_liver: 已经被压榨了
27+
mcd_seen.text.top_normal: §d仅真人玩家§r
28+
mcd_seen.text.top_bot: §5仅假人§r
29+
mcd_seen.text.top_merge: §7所有玩家§r/§e合并显示§r
30+
mcd_seen.text.top_all: §7所有玩家§r
31+
mcd_seen.text.reloaded: 插件已重载
32+
33+
# Hover texts
34+
mcd_seen.hover.help_msg_suggest: "点击以填入§7{}§r"
35+
mcd_seen.hover.query_player: "点击以查询玩家§e{}§r的数据"
36+
mcd_seen.hover.show_help: "点击以获取插件帮助信息"
37+
38+
# Format texts
39+
mcd_seen.fmt.time_seen: "秒 分 小时 天"
40+
mcd_seen.fmt.seen_top: "摸鱼榜前§6{num}§r的§c鸽子§r({arg})如下: "
41+
mcd_seen.fmt.seen_top_full: "摸鱼榜全部§c鸽子§r({arg})如下: "
42+
mcd_seen.fmt.liver_top: "当前在线的§a肝帝§r({arg})如下: "
43+
44+
# Error texts
45+
mcd_seen.error.player_data_not_found: 没有该玩家的数据
46+
mcd_seen.error.cmd_error: 指令有误! 点此获取帮助信息

mcd_seen/__init__.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
from parse import parse
2+
from mcdreforged.api.types import Info, PluginServerInterface
3+
from mcdreforged.api.decorator import new_thread
4+
5+
from mcd_seen.utils import verify_player_name, bot_name, tr, logger, psi
6+
from mcd_seen.storage import storage, bot_list
7+
from mcd_seen.config import config
8+
from mcd_seen.interface import register_command
9+
10+
11+
def on_info(server: PluginServerInterface, info: Info) -> None:
12+
if info.is_from_server and config.identify_bot:
13+
logger.debug('Join event found with on_info')
14+
psd = parse('{name}[{ip}] logged in with entity id {id} at {loc}', info.content)
15+
if psd is not None and verify_player_name(psd['name']):
16+
player_name = bot_name(psd['name']) if psd['ip'] == 'local' else psd['name']
17+
storage.player_joined(player_name)
18+
19+
20+
def on_player_joined(server: PluginServerInterface, player: str, info: Info = None):
21+
if not config.identify_bot:
22+
logger.debug('Join event found with on_player_joined')
23+
storage.player_joined(player)
24+
25+
26+
def on_player_left(server: PluginServerInterface, player: str):
27+
server.get_instance() # to satisfy pycharm >3
28+
storage.player_left(player)
29+
30+
31+
def on_server_stop(*args, **kwargs):
32+
list(args).clear() # to satisfy pycharm >3
33+
dict(kwargs).clear()
34+
storage.correct([])
35+
36+
37+
def on_unload(*args, **kwargs):
38+
logger.unset_file()
39+
40+
41+
@new_thread(psi.get_self_metadata().name + '_PluginLoad')
42+
def warn_first_load():
43+
logger.warning('Load Seen plugin when server is empty is suggested to make sure all the datas are right')
44+
45+
46+
def on_load(server: PluginServerInterface, prev_module):
47+
for prefix in config.seen_prefix:
48+
server.register_help_message(prefix, tr('mcd_seen.text.reg_help_msg'))
49+
register_command(server)
50+
if prev_module is not None:
51+
try:
52+
bot_list.clear()
53+
for player in prev_module.bot_list:
54+
bot_list.append(player)
55+
except AttributeError:
56+
logger.info('Seems upgraded from a old version, welcome!')
57+
else:
58+
if server.is_server_running():
59+
warn_first_load()

mcd_seen/config.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import json
2+
3+
from typing import Union, List
4+
from mcdreforged.api.utils import Serializable
5+
from mcdreforged.api.types import ServerInterface
6+
7+
from mcd_seen.constants import CONFIG_FILE
8+
9+
10+
psi = ServerInterface.get_instance().as_plugin_server_interface()
11+
12+
13+
class Config(Serializable):
14+
primary_prefix: Union[str, List[str]] = '!!seen'
15+
primary_rank_prefix: Union[str, List[str]] = '!!seen-top'
16+
secondary_rank_prefix: Union[str, List[str]] = '!!liver-top'
17+
seen_top_max: int = 10
18+
player_prior_in_merge: bool = True
19+
log_seens: bool = True
20+
identify_bot: bool = True
21+
bot_list_delay: float = 0.3
22+
verbosity: bool
23+
debug_commands: bool
24+
debug_prefixes: Union[str, List[str]]
25+
26+
@staticmethod
27+
def get_iterable(original: Union[str, List[str]]) -> List[str]:
28+
if isinstance(original, str):
29+
return [original]
30+
return original
31+
32+
@property
33+
def seen_prefix(self):
34+
return self.get_iterable(self.primary_prefix)
35+
36+
@property
37+
def seen_top_prefix(self):
38+
return self.get_iterable(self.primary_rank_prefix)
39+
40+
@property
41+
def liver_top_prefix(self):
42+
return self.get_iterable(self.secondary_rank_prefix)
43+
44+
@property
45+
def debug_prefix(self):
46+
return self.get_iterable(self.serialize().get('debug_prefixes', '!!liver'))
47+
48+
@property
49+
def prefixes(self):
50+
result = []
51+
for item in [self.seen_prefix, self.seen_top_prefix, self.liver_top_prefix]:
52+
result += item
53+
return result
54+
55+
@property
56+
def verbose_mode(self):
57+
return self.serialize().get('verbosity', False)
58+
59+
@property
60+
def debug(self):
61+
return self.serialize().get('debug_commands', False)
62+
63+
def save(self) -> None:
64+
with open(CONFIG_FILE, 'w', encoding='UTF-8') as f:
65+
json.dump(self.serialize(), f, indent=4, ensure_ascii=False)
66+
67+
@classmethod
68+
def load(cls) -> 'Config':
69+
return psi.load_config_simple(
70+
CONFIG_FILE,
71+
default_config=cls.get_default().serialize(),
72+
in_data_folder=False,
73+
echo_in_console=True,
74+
target_class=cls
75+
)
76+
77+
78+
config = Config.load()

mcd_seen/constants.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import os
2+
3+
4+
def ensure(folder: str):
5+
if not os.path.isdir(folder):
6+
os.makedirs(folder)
7+
return folder
8+
9+
10+
# Seen file storage
11+
DATA_FOLDER = ensure('config/seen')
12+
CONFIG_FILE = os.path.join(DATA_FOLDER, 'config.json')
13+
SEENS_FILE = os.path.join(DATA_FOLDER, 'seen.json')
14+
LOG_FILE = os.path.join(DATA_FOLDER, 'logs', 'seen.log')
15+
SEENS_PATH_OLD = ['seen.json', 'config/seen.json']
16+
OLD_LOG_FILE = os.path.join(DATA_FOLDER, 'player_seens.log')
17+
NEW_LOG_PATH = os.path.join(DATA_FOLDER, 'logs', 'old_seens.log')

0 commit comments

Comments
 (0)