-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
breaking change: update plugins & dependencies
- Loading branch information
1 parent
1728b40
commit 17858c2
Showing
19 changed files
with
1,326 additions
and
1,537 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
# ----- Project ----- | ||
|
||
# .env.* | ||
.env.* | ||
.dockerignore | ||
Dockerfile | ||
docker-compose.yml | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
name: Docker Image CI | ||
|
||
on: | ||
push: | ||
branches: | ||
- "main" | ||
tags: | ||
- "v*" | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v3 | ||
|
||
- name: Log in to Docker Hub | ||
uses: docker/login-action@v2 | ||
with: | ||
username: ${{ secrets.DOCKERHUB_USERNAME }} | ||
password: ${{ secrets.DOCKERHUB_TOKEN }} | ||
|
||
- name: Extract metadata (tags, labels) for Docker | ||
id: meta | ||
uses: docker/metadata-action@v4 | ||
with: | ||
images: ${{ secrets.DOCKERHUB_USERNAME }}/ATRIbot | ||
tags: | | ||
type=ref,event=branch | ||
type=semver,pattern={{version}} | ||
type=semver,pattern={{major}}.{{minor}} | ||
- name: Build and push Docker image | ||
uses: docker/build-push-action@v4 | ||
with: | ||
context: . | ||
push: ${{ github.event_name != 'pull_request' }} | ||
tags: ${{ steps.meta.outputs.tags }} | ||
labels: ${{ steps.meta.outputs.labels }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
from typing import cast | ||
import socket | ||
import nonebot | ||
from mcstatus import JavaServer, BedrockServer | ||
from nonebot import get_bots | ||
from nonebot.adapters.onebot.v11 import ( | ||
Bot, | ||
GroupMessageEvent, | ||
MessageEvent, | ||
PrivateMessageEvent, | ||
) | ||
from nonebot.params import ShellCommandArgs | ||
from nonebot.plugin import on_shell_command, require | ||
|
||
from .data import Data, ServerList | ||
from .handle import Handle, query_players | ||
from .parser import ArgNamespace, mc_parser | ||
|
||
require("nonebot_plugin_apscheduler") | ||
from nonebot_plugin_apscheduler import scheduler | ||
|
||
# 注册 shell_like 事件响应器 | ||
mc = on_shell_command("mc", parser=mc_parser, priority=5) | ||
|
||
|
||
# 每分钟进行一次检测 | ||
@scheduler.scheduled_job("cron", minute="*/5", id="mcstatus") | ||
async def _(): | ||
data = Data() | ||
server_list = cast(ServerList, data.get_server_list()) | ||
bots = nonebot.get_bots() | ||
|
||
for type in server_list: | ||
for id in server_list[type]: | ||
for server in server_list[type][id]: | ||
try: | ||
status = (JavaServer.lookup(server.address).status() | ||
if server.server_type == "JE" else | ||
BedrockServer.lookup(server.address).status()) | ||
online = True | ||
retry = 0 | ||
players = (status.players.online if server.server_type | ||
== "JE" else status.players_online) | ||
|
||
except (socket.timeout, socket.gaierror): | ||
retry = server.retry + 1 | ||
if retry >= 3: | ||
online = False | ||
players = 0 | ||
else: | ||
online = server.online | ||
players = server.players | ||
|
||
if online != server.online or players != server.players: | ||
server.online = online | ||
server.players = players | ||
server.retry = retry | ||
data.remove_server( | ||
server.name, | ||
user_id=id if type == "user" else None, | ||
group_id=id if type == "group" else None, | ||
) | ||
data.add_server( | ||
server, | ||
user_id=id if type == "user" else None, | ||
group_id=id if type == "group" else None, | ||
) | ||
message = ( | ||
"【服务器状态发生变化】\n" + | ||
f"{server.name} ({server.address})\n" + | ||
f"Online: {online}" + | ||
(f"\nPlayers: {players}" if online else "") + | ||
(query_players(server, status) if online else "")) | ||
for bot in bots: | ||
await bots[bot].send_msg( | ||
user_id=id if type == "user" else None, | ||
group_id=id if type == "group" else None, | ||
message=message, | ||
) | ||
|
||
|
||
@mc.handle() | ||
async def _(bot: Bot, | ||
event: MessageEvent, | ||
args: ArgNamespace = ShellCommandArgs()): | ||
args.user_id = event.user_id if isinstance(event, | ||
PrivateMessageEvent) else None | ||
args.group_id = event.group_id if isinstance(event, | ||
GroupMessageEvent) else None | ||
args.is_admin = (event.sender.role in ["admin", "owner"] if isinstance( | ||
event, GroupMessageEvent) else False) | ||
if hasattr(args, "handle"): | ||
result = await getattr(Handle, args.handle)(args) | ||
if result: | ||
await bot.send(event, result) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
from pathlib import Path | ||
from typing import Dict, List, Optional, Union, cast | ||
|
||
import yaml | ||
from pydantic import BaseModel | ||
|
||
|
||
class Server(BaseModel): | ||
name: str | ||
address: str | ||
description: str | ||
server_type: str | ||
online: bool | ||
players: int | ||
retry: int | ||
|
||
|
||
ServerList = Dict[str, Dict[int, List[Server]]] | ||
|
||
|
||
class Data: | ||
__server_list: ServerList = {"user": {}, "group": {}} | ||
__path: Path | ||
|
||
def __init__(self, | ||
path: Path = Path() / "data" / "mcstatus" / | ||
"server_list.yml"): | ||
self.__path = path | ||
self.__load() | ||
|
||
def get_server_list( | ||
self, | ||
user_id: Optional[int] = None, | ||
group_id: Optional[int] = None) -> Union[ServerList, List[Server]]: | ||
|
||
server_list = self.__server_list | ||
|
||
if user_id: | ||
if user_id not in server_list["user"]: | ||
server_list["user"][user_id] = [] | ||
return server_list["user"][user_id] | ||
elif group_id: | ||
if group_id not in server_list["group"]: | ||
server_list["group"][group_id] = [] | ||
return server_list["group"][group_id] | ||
else: | ||
return server_list | ||
|
||
def add_server( | ||
self, | ||
server: Server, | ||
user_id: Optional[int] = None, | ||
group_id: Optional[int] = None, | ||
): | ||
server_list = cast(List[Server], | ||
self.get_server_list(user_id, group_id)) | ||
if server not in server_list: | ||
server_list.append(server) | ||
|
||
if user_id: | ||
self.__server_list["user"][user_id] = server_list | ||
elif group_id: | ||
self.__server_list["group"][group_id] = server_list | ||
|
||
self.__dump() | ||
|
||
def remove_server( | ||
self, | ||
name: str, | ||
user_id: Optional[int] = None, | ||
group_id: Optional[int] = None, | ||
): | ||
|
||
server_list = list( | ||
filter( | ||
lambda server: server.name != name, | ||
cast(List[Server], self.get_server_list(user_id, group_id)), | ||
)) | ||
|
||
if user_id: | ||
if server_list: | ||
self.__server_list["user"][user_id] = server_list | ||
else: | ||
self.__server_list["user"].pop(user_id) | ||
elif group_id: | ||
if server_list: | ||
self.__server_list["group"][group_id] = server_list | ||
else: | ||
self.__server_list["group"].pop(group_id) | ||
|
||
self.__dump() | ||
|
||
def __load(self): | ||
try: | ||
server_list = yaml.safe_load( | ||
self.__path.open("r", encoding="utf-8")) | ||
for type in server_list: | ||
for id in server_list[type]: | ||
self.__server_list[type][id] = [ | ||
Server(**server) for server in server_list[type][id] | ||
] | ||
except FileNotFoundError: | ||
self.__server_list = {"user": {}, "group": {}} | ||
|
||
def __dump(self): | ||
self.__path.parent.mkdir(parents=True, exist_ok=True) | ||
server_list = {"user": {}, "group": {}} | ||
for type in self.__server_list: | ||
for id in self.__server_list[type]: | ||
server_list[type][id] = [ | ||
server.dict() for server in self.__server_list[type][id] | ||
] | ||
yaml.dump( | ||
server_list, | ||
self.__path.open("w", encoding="utf-8"), | ||
allow_unicode=True, | ||
) |
Oops, something went wrong.