Skip to content

Commit

Permalink
cli stop command now stops auto-restart, fixed some pycraft packets d…
Browse files Browse the repository at this point in the history
…on't recognized as entity packet

including `EntityPositionDeltaPacket` and `EntityVelocityPacket`
and corresponding packets defined by pcrc are commented out
  • Loading branch information
Fallen-Breath committed Mar 11, 2022
1 parent a567108 commit 9fc650c
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 44 deletions.
1 change: 1 addition & 0 deletions pcrc/cli_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def start():


def stop():
pcrc.interrupt_auto_restart()
if is_working():
pcrc.stop(block=True)
else:
Expand Down
64 changes: 34 additions & 30 deletions pcrc/packets/s2c/entity_packet.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,26 @@ def get_id(cls, context):
packet_name = 'Entity Movement'


class EntityPositionPacket(AbstractEntityPacket):
"""
wiki.vg names:
- 1.12: "Entity Relative Move"
- >1.12: "Entity Position"
"""
@classmethod
def get_id(cls, context):
return \
41 if context.protocol_later_eq(756) else \
39 if context.protocol_later_eq(754) else \
39 if context.protocol_later_eq(736) else \
41 if context.protocol_later_eq(578) else \
40 if context.protocol_later_eq(498) else \
38 if context.protocol_later_eq(335) else \
-1

packet_name = 'Entity Position'
# see pycraft minecraft.networking.packets.clientbound.play.EntityPositionDeltaPacket
#
# class EntityPositionPacket(AbstractEntityPacket):
# """
# wiki.vg names:
# - 1.12: "Entity Relative Move"
# - >1.12: "Entity Position"
# """
# @classmethod
# def get_id(cls, context):
# return \
# 41 if context.protocol_later_eq(756) else \
# 39 if context.protocol_later_eq(754) else \
# 39 if context.protocol_later_eq(736) else \
# 41 if context.protocol_later_eq(578) else \
# 40 if context.protocol_later_eq(498) else \
# 38 if context.protocol_later_eq(335) else \
# -1
#
# packet_name = 'Entity Position'


class EntityPositionAndRotationPacket(AbstractEntityPacket):
Expand Down Expand Up @@ -170,18 +172,20 @@ def get_id(cls, context):
packet_name = 'Entity Metadata'


class EntityVelocityPacket(AbstractEntityPacket):
@classmethod
def get_id(cls, context):
return \
79 if context.protocol_later_eq(756) else \
70 if context.protocol_later_eq(578) else \
69 if context.protocol_later_eq(498) else \
62 if context.protocol_later_eq(340) else \
61 if context.protocol_later_eq(335) else \
-1

packet_name = 'Entity Velocity'
# see pycraft minecraft.networking.packets.clientbound.play.EntityVelocityPacket
#
# class EntityVelocityPacket(AbstractEntityPacket):
# @classmethod
# def get_id(cls, context):
# return \
# 79 if context.protocol_later_eq(756) else \
# 70 if context.protocol_later_eq(578) else \
# 69 if context.protocol_later_eq(498) else \
# 62 if context.protocol_later_eq(340) else \
# 61 if context.protocol_later_eq(335) else \
# -1
#
# packet_name = 'Entity Velocity'


class EntityEquipmentPacket(AbstractEntityPacket):
Expand Down
26 changes: 16 additions & 10 deletions pcrc/pcrc_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ def __init__(self, *, input_manager: Optional[InputManager] = None):
self.__connection: Optional[PcrcConnection] = None
self.__connection_state = ConnectionState.disconnected
self.__flag_stopping = False
self.__flag_stop_by_user = False
self.__flag_auto_restart: bool = False
self.mc_protocol: Optional[int] = None
self.mc_version: Optional[str] = None
Expand Down Expand Up @@ -184,7 +183,6 @@ def __start(self) -> bool:

def __stop(self, by_user: bool, *, auto_restart: bool = False, callback: Callable[[], Any]) -> bool:
"""
:param by_user: If it's stopped by user, connection error due to disconnecting will be suppressed
:param auto_restart: If PCRC should try to auto restart (auto_relogin_attempts option will be considered)
:param callback: The optional callback method to be called after fully stopped
"""
Expand All @@ -194,7 +192,6 @@ def __stop(self, by_user: bool, *, auto_restart: bool = False, callback: Callabl
self.logger.info('Stopping PCRC, auto restart = {}, by_user = {}'.format(auto_restart, by_user))
self.chat(self.tr('chat.stopping'))
self.__flag_stopping = True
self.__flag_stop_by_user = by_user
if auto_restart:
if self.retry_counter.can_retry():
self.retry_counter.consume_retry_attempt()
Expand All @@ -204,19 +201,26 @@ def __stop(self, by_user: bool, *, auto_restart: bool = False, callback: Callabl
self.recorder.stop_recording(callback)
return True

def stop(self, auto_restart: bool = False, callback: Optional[Callable[[], Any]] = None, block: bool = False):
def stop(self, callback: Optional[Callable[[], Any]] = None, block: bool = False) -> bool:
"""
Stop PCRC by user
"""
event = Event()
callback = misc_util.chain_callback(callback, lambda: event.set())
executed = self.__stop(by_user=True, auto_restart=auto_restart, callback=callback)
executed = self.__stop(by_user=True, callback=callback)
if executed and block:
event.wait()
return executed

def __stop_by_external_force(self):
self.__stop(by_user=False, auto_restart=self.config.get('auto_relogin'), callback=lambda: 0)

def restart(self):
self.stop(callback=self.__start)

def interrupt_auto_restart(self):
self.__flag_auto_restart = False

def discard(self):
self.authenticator.interrupt_refresh()

Expand All @@ -227,10 +231,10 @@ def discard(self):
def on_connection_exception(self, exception: Exception, exc_info):
log = self.logger.debug if self.has_started_disconnecting() else self.logger.exception
log('Exception in network thread: {} ({})'.format(exception, getattr(type(exception), '__name__')))
self.__connection_state = ConnectionState.disconnected
if not self.__flag_stop_by_user:
if log == self.logger.debug:
self.logger.debug(traceback.format_exc())
self.__stop_by_external_force()
self.__connection_state = ConnectionState.disconnected
self.__stop_by_external_force()

# called when there's only 1 protocol version in allowed_proto_versions in pycraft connection
def on_protocol_version_decided(self, protocol_version):
Expand All @@ -244,7 +248,6 @@ def on_switched_to_playing_reactor(self):
def __on_connecting(self):
self.__connection_state = ConnectionState.logging_in
self.__flag_stopping = False
self.__flag_stop_by_user = False
self.__flag_auto_restart = False

def __on_connected(self):
Expand Down Expand Up @@ -273,7 +276,10 @@ def on_fully_stopped(self):
for i in range(3):
self.logger.info('PCRC restarting in {}s'.format(3 - i))
time.sleep(1)
self.__start()
if self.__flag_auto_restart:
self.__start()
else:
self.logger.warning('PCRC auto-restart interrupted by user')

def on_replay_file_saved(self):
if self.is_online():
Expand Down
3 changes: 2 additions & 1 deletion pcrc/recording/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ def stop(self):
if current_thread() == self.__thread:
raise RuntimeError('Cannot invoke ChatManager.stop on its chat thread')
self.__running = False
self.__thread.join()
if self.__thread is not None:
self.__thread.join()
while True:
try:
self.__message_queue.get_nowait()
Expand Down
5 changes: 3 additions & 2 deletions pcrc/recording/packet_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
from minecraft.networking.packets.clientbound.play import TimeUpdatePacket, SpawnPlayerPacket, SpawnObjectPacket, RespawnPacket
from minecraft.networking.types import PositionAndLook, GameMode
from pcrc.packets.s2c import DestroyEntitiesPacket, ChangeGameStatePacket, SpawnLivingEntityPacket
from pcrc.packets.s2c.entity_packet import AbstractEntityPacket
from pcrc.protocol import MobTypeIds
from pcrc.recording.player_list import PlayerListManager
from pcrc.utils import packet_util

if TYPE_CHECKING:
from pcrc.recording.recorder import Recorder
Expand Down Expand Up @@ -119,7 +119,8 @@ def process_destroy_entities():

# Detecting player activity to continue recording and remove items or bats
def process_entity_packets():
if isinstance(packet, AbstractEntityPacket):
if packet_util.is_entity_packet(packet):
# noinspection PyUnresolvedReferences
entity_id = packet.entity_id
if entity_id in self.entity_id_to_player_uuid.keys():
player_uuid = self.entity_id_to_player_uuid[entity_id]
Expand Down
2 changes: 1 addition & 1 deletion pcrc/recording/recorder.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ def on_packet(self, packet: Packet):
self.logger.debug('PCRC is afking but {} is an important packet so PCRC recorded it'.format(packet_name))
else:
pass
# self.logger.debug('{} recorded'.format(packet_name))
self.logger.debug('{} recorded'.format(packet_name))
else:
self.logger.debug('{} ignore due to being afk'.format(packet_name))

Expand Down
9 changes: 9 additions & 0 deletions pcrc/utils/packet_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from typing import Iterable, Any, Set, Type

from minecraft.networking.packets import Packet, PlayerListItemPacket
from minecraft.networking.packets.clientbound.play import EntityPositionDeltaPacket, EntityVelocityPacket

IMPORTANT_PACKETS = (
PlayerListItemPacket
Expand All @@ -15,3 +16,11 @@ def is_important(packet: Packet):
def gather_all_packet_classes(global_values: Iterable[Any]) -> Set[Type[Packet]]:
return set(filter(lambda o: isinstance(o, type) and o != Packet and issubclass(o, Packet) and not inspect.isabstract(o), global_values))


def is_entity_packet(packet: Packet) -> bool:
from pcrc.packets.s2c.entity_packet import AbstractEntityPacket
return hasattr(packet, 'entity_id') and isinstance(packet, (
AbstractEntityPacket,
EntityPositionDeltaPacket,
EntityVelocityPacket
))

0 comments on commit 9fc650c

Please sign in to comment.