a
    ~iÛ  ã                   @   sŒ   d Z ddlmZmZmZ ddlZe e¡ZG dd„ de	ƒZ
G dd„ dƒZeƒ Zeeddœd	d
„Zeeeeeedœdd„Zeedœdd„ZdS )zg
Secure event handler registry.

Replaces dangerous eval() pattern with explicit handler registration.
é    )ÚCallableÚDictÚAnyNc                   @   s   e Zd ZdZdS )ÚInvalidEventErrorz<Raised when attempting to call invalid or unregistered eventN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__© r
   r
   ú//var/www/lichun.app/lichun/ws/event_handlers.pyr      s   r   c                   @   sd   e Zd ZdZdd„ Zeeddœdd„Zeeeeeedœd	d
„Z	ee
dœdd„Zee dœdd„ZdS )ÚEventHandlerRegistryzø
    Registry for secure event handler dispatch.

    Usage:
        registry = EventHandlerRegistry()
        registry.register("characterSetup", characterSetup)
        result = registry.call("characterSetup", player, "answer", key, message)
    c                 C   s
   i | _ d S )N©Ú	_handlers©Úselfr
   r
   r   Ú__init__   s    zEventHandlerRegistry.__init__N©Ú
event_typeÚhandlerÚreturnc                 C   s�   |rt |tƒstd|› �ƒ‚t|ƒs2td|› �ƒ‚d|v sD| d¡rRtd|› �ƒ‚|| jv rrt d|› d�¡ dS || j|< t d	|› �¡ dS )
z"Register an event handler functionúInvalid event type: zHandler must be callable: Ú__Ú_z.Event type cannot contain __ or start with _: zEvent handler z4 already registered, skipping duplicate registrationNzRegistered event handler: )Ú
isinstanceÚstrÚ
ValueErrorÚcallableÚ
startswithr   ÚloggerÚdebug)r   r   r   r
   r
   r   Úregister   s    

zEventHandlerRegistry.register©r   ÚplayerÚmodeÚkeyÚmessager   c              
   C   s´   |rt |tƒstd|› �ƒ‚d|v s.| d¡r<td|› �ƒ‚| j |¡}|du r^td|› �ƒ‚z|||||ƒW S  ty® } z(tjd|› d|› �d	d
� ‚ W Y d}~n
d}~0 0 dS )a¢  
        Safely call a registered event handler.

        Args:
            event_type: The event type to dispatch
            player: Player object
            mode: Mode string (usually "answer")
            key: Event key
            message: Event message

        Returns:
            Result from handler function

        Raises:
            InvalidEventError: If event type is not registered or invalid
        r   r   r   zDangerous event type rejected: Nz!No handler registered for event: zError calling handler z: T)Úexc_info)	r   r   r   r   r   ÚgetÚ	Exceptionr   Úerror)r   r   r"   r#   r$   r%   r   Úer
   r
   r   Úcall3   s    zEventHandlerRegistry.call©r   r   c                 C   s
   || j v S )z$Check if an event type is registeredr   )r   r   r
   r
   r   Úis_registeredX   s    z"EventHandlerRegistry.is_registered)r   c                 C   s   t | j ¡ ƒS )zList all registered event types)Úlistr   Úkeysr   r
   r
   r   Úlist_events\   s    z EventHandlerRegistry.list_events)r   r   r   r	   r   r   r   r    r   r+   Úboolr-   r.   r0   r
   r
   r
   r   r      s   	%r   r   c                 C   s   t  | |¡ dS )z0Register an event handler in the global registryN)Ú	_registryr    )r   r   r
   r
   r   Úregister_event_handlere   s    r3   r!   c                 C   s   t  | ||||¡S )z.Call an event handler from the global registry)r2   r+   )r   r"   r#   r$   r%   r
   r
   r   Úcall_event_handlerj   s    r4   r,   c                 C   s
   t  | ¡S )z6Check if an event is registered in the global registry)r2   r-   )r   r
   r
   r   Úis_event_registeredo   s    r5   )r	   Útypingr   r   r   ÚloggingÚ	getLoggerr   r   r(   r   r   r2   r   r3   r4   r1   r5   r
   r
   r
   r   Ú<module>   s   
P