Skip to content

Commit

Permalink
breaking change: update plugins & dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
Misaka13514 committed Jul 30, 2023
1 parent 1728b40 commit 17858c2
Show file tree
Hide file tree
Showing 19 changed files with 1,326 additions and 1,537 deletions.
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ----- Project -----

# .env.*
.env.*
.dockerignore
Dockerfile
docker-compose.yml
Expand Down
39 changes: 39 additions & 0 deletions .github/workflows/docker-image.yml
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 }}
95 changes: 95 additions & 0 deletions atribot/plugins/nonebot_plugin_mcstatus/__init__.py
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)
117 changes: 117 additions & 0 deletions atribot/plugins/nonebot_plugin_mcstatus/data.py
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,
)
Loading

0 comments on commit 17858c2

Please sign in to comment.