brought features out of aiocraft, added game managers
This commit is contained in:
parent
b41f2f6074
commit
88bfadd8cd
7 changed files with 77 additions and 50 deletions
|
@ -1,3 +1,4 @@
|
||||||
from .chat import ChatEvent
|
from .chat import ChatEvent
|
||||||
from .join_game import JoinGameEvent
|
from .join_game import JoinGameEvent
|
||||||
from .death import DeathEvent
|
from .death import DeathEvent
|
||||||
|
from .system import ConnectedEvent, DisconnectedEvent
|
||||||
|
|
|
@ -1,25 +1,19 @@
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
from aiocraft.client import MinecraftClient
|
|
||||||
from aiocraft.mc.proto.play.clientbound import PacketChat as PacketChatMessage
|
from aiocraft.mc.proto.play.clientbound import PacketChat as PacketChatMessage
|
||||||
from aiocraft.mc.proto.play.serverbound import PacketChat
|
from aiocraft.mc.proto.play.serverbound import PacketChat
|
||||||
|
|
||||||
from ..events.chat import ChatEvent, MessageType
|
from ..events.chat import ChatEvent, MessageType
|
||||||
|
from ..scaffold import Scaffold
|
||||||
|
|
||||||
class GameChat(MinecraftClient):
|
class GameChat(Scaffold):
|
||||||
|
|
||||||
def on_chat(self, msg_type:Union[str, MessageType] = None):
|
def __init__(self, *args, **kwargs):
|
||||||
if isinstance(msg_type, str):
|
super().__init__(*args, **kwargs)
|
||||||
msg_type = MessageType(msg_type)
|
|
||||||
def wrapper(fun):
|
|
||||||
async def process_chat_packet(packet:PacketChatMessage):
|
|
||||||
msg = ChatEvent(packet.message)
|
|
||||||
if not msg_type or msg.type == msg_type:
|
|
||||||
return await fun(msg)
|
|
||||||
self.register(PacketChatMessage, process_chat_packet)
|
|
||||||
return fun
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
|
@self.on_packet(PacketChatMessage)
|
||||||
|
async def chat_event_callback(packet:PacketChatMessage):
|
||||||
|
self.run_callbacks(ChatEvent, ChatEvent(packet.message))
|
||||||
|
|
||||||
async def chat(self, message:str, whisper:str=None, wait:bool=False):
|
async def chat(self, message:str, whisper:str=None, wait:bool=False):
|
||||||
if whisper:
|
if whisper:
|
||||||
|
@ -32,5 +26,3 @@ class GameChat(MinecraftClient):
|
||||||
wait=wait
|
wait=wait
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from aiocraft.client import MinecraftClient
|
|
||||||
from aiocraft.mc.definitions import Item
|
from aiocraft.mc.definitions import Item
|
||||||
from aiocraft.mc.proto.play.clientbound import PacketSetSlot, PacketHeldItemSlot as PacketHeldItemChange
|
from aiocraft.mc.proto.play.clientbound import PacketSetSlot, PacketHeldItemSlot as PacketHeldItemChange
|
||||||
from aiocraft.mc.proto.play.serverbound import PacketHeldItemSlot
|
from aiocraft.mc.proto.play.serverbound import PacketHeldItemSlot
|
||||||
|
|
||||||
class GameInventory(MinecraftClient):
|
from ..scaffold import Scaffold
|
||||||
|
|
||||||
|
class GameInventory(Scaffold):
|
||||||
slot : int
|
slot : int
|
||||||
inventory : List[Item]
|
inventory : List[Item]
|
||||||
# TODO inventory
|
# TODO inventory
|
||||||
|
|
|
@ -2,13 +2,14 @@ import asyncio
|
||||||
import datetime
|
import datetime
|
||||||
import functools
|
import functools
|
||||||
|
|
||||||
from aiocraft.client import MinecraftClient
|
#from aiocraft.client import MinecraftClient
|
||||||
from aiocraft.mc.definitions import Gamemode, Dimension, Difficulty
|
from aiocraft.mc.definitions import Gamemode, Dimension, Difficulty
|
||||||
from aiocraft.mc.proto import PacketRespawn, PacketLogin, PacketUpdateHealth, PacketExperience, PacketSettings, PacketClientCommand
|
from aiocraft.mc.proto import PacketRespawn, PacketLogin, PacketUpdateHealth, PacketExperience, PacketSettings, PacketClientCommand
|
||||||
|
|
||||||
from ..events import JoinGameEvent, DeathEvent
|
from ..events import JoinGameEvent, DeathEvent, ConnectedEvent, DisconnectedEvent
|
||||||
|
from ..scaffold import Scaffold
|
||||||
|
|
||||||
class GameState(MinecraftClient):
|
class GameState(Scaffold):
|
||||||
hp : float
|
hp : float
|
||||||
food : float
|
food : float
|
||||||
xp : float
|
xp : float
|
||||||
|
@ -26,24 +27,6 @@ class GameState(MinecraftClient):
|
||||||
difficulty : Difficulty
|
difficulty : Difficulty
|
||||||
join_time : datetime.datetime
|
join_time : datetime.datetime
|
||||||
|
|
||||||
def on_death(self):
|
|
||||||
def decorator(fun):
|
|
||||||
@functools.wraps(fun)
|
|
||||||
async def wrapper():
|
|
||||||
event = DeathEvent()
|
|
||||||
return await fun(event)
|
|
||||||
return self.register(DeathEvent.SENTINEL, wrapper)
|
|
||||||
return decorator
|
|
||||||
|
|
||||||
def on_joined_world(self):
|
|
||||||
def decorator(fun):
|
|
||||||
@functools.wraps(fun)
|
|
||||||
async def wrapper():
|
|
||||||
event = JoinGameEvent()
|
|
||||||
return await fun(event)
|
|
||||||
return self.register(JoinGameEvent.SENTINEL, wrapper)
|
|
||||||
return decorator
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
@ -58,8 +41,8 @@ class GameState(MinecraftClient):
|
||||||
self.xp = 0.0
|
self.xp = 0.0
|
||||||
self.lvl = 0
|
self.lvl = 0
|
||||||
|
|
||||||
@self.on_disconnected()
|
@self.on(DisconnectedEvent)
|
||||||
async def disconnected_cb():
|
async def disconnected_cb(_):
|
||||||
self.in_game = False
|
self.in_game = False
|
||||||
|
|
||||||
@self.on_packet(PacketRespawn)
|
@self.on_packet(PacketRespawn)
|
||||||
|
|
|
@ -3,11 +3,13 @@ import datetime
|
||||||
|
|
||||||
from typing import Dict, List
|
from typing import Dict, List
|
||||||
|
|
||||||
from aiocraft.client import MinecraftClient
|
|
||||||
from aiocraft.mc.definitions import Item
|
from aiocraft.mc.definitions import Item
|
||||||
from aiocraft.mc.proto import PacketPlayerInfo
|
from aiocraft.mc.proto import PacketPlayerInfo
|
||||||
|
|
||||||
class GameTablist(MinecraftClient):
|
from ..scaffold import Scaffold
|
||||||
|
from ..events import ConnectedEvent
|
||||||
|
|
||||||
|
class GameTablist(Scaffold):
|
||||||
tablist : Dict[uuid.UUID, dict]
|
tablist : Dict[uuid.UUID, dict]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -15,8 +17,8 @@ class GameTablist(MinecraftClient):
|
||||||
|
|
||||||
self.tablist = {}
|
self.tablist = {}
|
||||||
|
|
||||||
@self.on_connected()
|
@self.on(ConnectedEvent)
|
||||||
async def connected_cb():
|
async def connected_cb(_):
|
||||||
self.tablist.clear()
|
self.tablist.clear()
|
||||||
|
|
||||||
@self.on_packet(PacketPlayerInfo)
|
@self.on_packet(PacketPlayerInfo)
|
||||||
|
|
|
@ -3,11 +3,13 @@ import datetime
|
||||||
|
|
||||||
from typing import Dict, List
|
from typing import Dict, List
|
||||||
|
|
||||||
from aiocraft.client import MinecraftClient
|
|
||||||
from aiocraft.mc.definitions import BlockPos
|
from aiocraft.mc.definitions import BlockPos
|
||||||
from aiocraft.mc.proto import PacketPosition, PacketTeleportConfirm
|
from aiocraft.mc.proto import PacketPosition, PacketTeleportConfirm
|
||||||
|
|
||||||
class GameWorld(MinecraftClient):
|
from ..scaffold import Scaffold
|
||||||
|
from ..events import ConnectedEvent
|
||||||
|
|
||||||
|
class GameWorld(Scaffold):
|
||||||
position : BlockPos
|
position : BlockPos
|
||||||
# TODO world
|
# TODO world
|
||||||
|
|
||||||
|
@ -16,8 +18,8 @@ class GameWorld(MinecraftClient):
|
||||||
|
|
||||||
self.position = BlockPos(0, 0, 0)
|
self.position = BlockPos(0, 0, 0)
|
||||||
|
|
||||||
@self.on_connected()
|
@self.on(ConnectedEvent)
|
||||||
async def connected_cb():
|
async def connected_cb(_):
|
||||||
self.tablist.clear()
|
self.tablist.clear()
|
||||||
|
|
||||||
@self.on_packet(PacketPosition)
|
@self.on_packet(PacketPosition)
|
||||||
|
|
|
@ -14,11 +14,19 @@ from configparser import ConfigParser
|
||||||
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
||||||
|
|
||||||
from aiocraft.client import MinecraftClient
|
from aiocraft.client import MinecraftClient
|
||||||
|
from aiocraft.util import helpers
|
||||||
from aiocraft.mc.packet import Packet
|
from aiocraft.mc.packet import Packet
|
||||||
|
from aiocraft.mc.definitions import ConnectionState
|
||||||
|
from aiocraft.mc.proto import PacketSetCompression, PacketKickDisconnect
|
||||||
|
from aiocraft.mc.proto.play.clientbound import PacketKeepAlive
|
||||||
|
from aiocraft.mc.proto.play.serverbound import PacketKeepAlive as PacketKeepAliveResponse
|
||||||
|
|
||||||
|
from .scaffold import Scaffold
|
||||||
|
from .events import ConnectedEvent, DisconnectedEvent
|
||||||
from .storage import Storage, SystemState
|
from .storage import Storage, SystemState
|
||||||
from .notifier import Notifier
|
from .notifier import Notifier
|
||||||
from .game import GameState, GameChat, GameInventory, GameTablist, GameWorld
|
from .game import GameState, GameChat, GameInventory, GameTablist, GameWorld
|
||||||
|
from .traits import CallbacksHolder, Runnable
|
||||||
|
|
||||||
REMOVE_COLOR_FORMATS = re.compile(r"§[0-9a-z]")
|
REMOVE_COLOR_FORMATS = re.compile(r"§[0-9a-z]")
|
||||||
|
|
||||||
|
@ -87,6 +95,8 @@ class Treepuncher(
|
||||||
modules : List[Addon]
|
modules : List[Addon]
|
||||||
ctx : Dict[Any, Any]
|
ctx : Dict[Any, Any]
|
||||||
|
|
||||||
|
_processing : bool
|
||||||
|
|
||||||
def __init__(self, name:str, *args, config_file:str=None, notifier:Notifier=None, **kwargs):
|
def __init__(self, name:str, *args, config_file:str=None, notifier:Notifier=None, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.ctx = dict()
|
self.ctx = dict()
|
||||||
|
@ -133,19 +143,55 @@ class Treepuncher(
|
||||||
self.storage._set_state(state)
|
self.storage._set_state(state)
|
||||||
|
|
||||||
async def start(self):
|
async def start(self):
|
||||||
|
# if self.started: # TODO readd check
|
||||||
|
# return
|
||||||
|
await super().start()
|
||||||
await self.notifier.initialize()
|
await self.notifier.initialize()
|
||||||
for m in self.modules:
|
for m in self.modules:
|
||||||
await m.initialize()
|
await m.initialize()
|
||||||
await super().start()
|
self._processing = True
|
||||||
|
self._worker = asyncio.get_event_loop().create_task(self._work())
|
||||||
self.scheduler.resume()
|
self.scheduler.resume()
|
||||||
|
self._logger.info("Treepuncher started")
|
||||||
|
|
||||||
async def stop(self, force:bool=False):
|
async def stop(self, force:bool=False):
|
||||||
|
self._processing = False
|
||||||
self.scheduler.pause()
|
self.scheduler.pause()
|
||||||
await super().stop(force=force)
|
if self.dispatcher.connected:
|
||||||
|
await self.dispatcher.disconnect(block=not force)
|
||||||
|
if not force:
|
||||||
|
await self._worker
|
||||||
|
await self.join_callbacks()
|
||||||
for m in self.modules:
|
for m in self.modules:
|
||||||
await m.cleanup()
|
await m.cleanup()
|
||||||
await self.notifier.cleanup()
|
await self.notifier.cleanup()
|
||||||
|
await super().stop()
|
||||||
|
self._logger.info("Treepuncher stopped")
|
||||||
|
|
||||||
def install(self, module:Type[Addon]) -> Type[Addon]:
|
def install(self, module:Type[Addon]) -> Type[Addon]:
|
||||||
self.modules.append(module(self))
|
self.modules.append(module(self))
|
||||||
return module
|
return module
|
||||||
|
|
||||||
|
async def _work(self):
|
||||||
|
try:
|
||||||
|
server_data = await self.info(host=self.host, port=self.port)
|
||||||
|
except Exception:
|
||||||
|
return self._logger.exception("exception while pinging server")
|
||||||
|
while self._processing:
|
||||||
|
try:
|
||||||
|
await self.join(
|
||||||
|
host=self.host,
|
||||||
|
port=self.port,
|
||||||
|
proto=server_data['version']['protocol'],
|
||||||
|
packet_whitelist=self.callback_keys(filter=Packet),
|
||||||
|
)
|
||||||
|
except ConnectionRefusedError:
|
||||||
|
self._logger.error("Server rejected connection")
|
||||||
|
except OSError as e:
|
||||||
|
self._logger.error("Connection error : %s", str(e))
|
||||||
|
except Exception:
|
||||||
|
self._logger.exception("Unhandled exception")
|
||||||
|
break
|
||||||
|
await asyncio.sleep(5) # TODO setting
|
||||||
|
if self._processing:
|
||||||
|
await self.stop(force=True)
|
||||||
|
|
Loading…
Reference in a new issue