a
    
i                     @   s   d Z ddlZddlZddlZddlZddlZddlZddlmZ ddlm	Z	 e
eZdZde Zdd Zd	d
 Zdd Zdd ZdS )aT  
Producer/Consumer Pattern for WebSocket Game Loop

This module implements the producer/consumer pattern for managing WebSocket
message flow and game loop execution with FPS control.

The producer generates game updates at a controlled frame rate (TARGET_FPS),
while the consumer processes incoming client messages and dispatches commands.
    N)config)RateLimiteri        ?c                    s   ddl m} || I dH  dS )z
    Produce game updates by calling the main game loop.

    Args:
        websocket: The WebSocket connection with userID attribute

    Returns:
        False to indicate completion
    r   )initLifeSimNF)game_loop.loop_managerr   )	websocketr    r   </var/www/lichun.app/lichun/ws/game_loop/producer_consumer.pyproducer   s    
r
   c              
      s  ddl m} ddlm} ddl}|j}t }d}z|| j}|r^|j	dkr^| jdkr^W qt }t
| I dH  t }	|	| }
|d7 }|	| }t|
 }|dkrtd	I dH  |	}d}|d
kr&|| j}|r&|| |_tdt||  d tt| d t|jj d t|jj  W q2 tjjy~ } z8tdt|  || I dH  W Y d}~qW Y d}~q2d}~0  ty } zFtdt   |  I dH  || I dH  W Y d}~qW Y d}~q2d}~0 0 q2dS )a
  
    Handle producer with FPS control and error catching.

    This continuously runs the producer at TARGET_FPS, tracking frame rate
    and handling disconnections/errors gracefully.

    Args:
        websocket: The WebSocket connection with userID attribute
    r   )shutdown)PlayerCacheNdisconnectedDUMMY_USER_ID   g?gMbP?r   zFPS:  z)producer:Client disconnected.  Do cleanupzError in producer_handler: )server.websocket_handlersr   player_cacher   appplayerRecordstimegetuserID
connectionr
   FRAME_DURATIONasynciosleepfpsprintstrtypec	firstnamelastname
websockets
exceptionsConnectionClosed	Exception	traceback
format_excclose)r   r   r   r   r   
start_timeZframe_countplayerZframe_start_timeZframe_end_timeZframe_durationZelapsed_timeZsleep_durationerrer   r   r	   producer_handler,   sF    


H"r.   c                    sp   ddl m} ttjdd}| 2 zJ3 dH W }|| jsXtd| j  || dI dH  qt|| I dH  q6 dS )a  
    Handle consumer with rate limiting and error catching.

    This listens for incoming WebSocket messages and processes them
    through the consumer, with rate limiting to prevent abuse.

    Args:
        websocket: The WebSocket connection with userID attribute
    r   )error<   )max_requestswindow_secondsNzRate limit exceeded for z&Rate limit exceeded. Please slow down.)	r   r/   r   r   !WEBSOCKET_MAX_MESSAGES_PER_MINUTE
is_allowedr   r   consumer)r   r/   rate_limitermessager   r   r	   consumer_handlerf   s    
r8   c           
         s  ddl m} ddlm} ddlm} ddl}|j}||j	}|j
|j|j|j|jj|jj|jj|jj|jj|jj|jj|jj|jj|jj|jj|jj|jd}| std dS t| tr| d	} td
|   t !| }	||	||I dH  ||||}|r|i kr|||I dH  dS )ay  
    Process incoming WebSocket messages and dispatch commands.

    This function uses a table-driven command dispatcher for clean, maintainable
    command handling with O(1) lookup time.

    Args:
        message: The incoming WebSocket message (string or bytes)
        websocket: The WebSocket connection

    Returns:
        True if successful, False if no message
    r   )dispatch_command)sendDict)handleUpdatesN)date	hourOfDayminuteOfHourweekDayTextenergy
calcEnergymoneydiamondsprestigestress	happiness
occupationlocation	schedulesintraDayMessage	dailyPlan	gameSpeedz
no messageFzutf-8ZreceivedT)"Zserver.command_dispatcherr9   server.websocket_messagingr:   	functionsr;   r   r   r   r   r<   r=   r>   r?   r    r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   r   
isinstancebytesdecodejsonloads)
r7   r   r9   r:   r;   r   r   r+   updateObjecteventr   r   r	   r5      sH    


r5   )__doc__r   rR   r   r'   r#   loggingr   r6   r   	getLogger__name__loggerZ
TARGET_FPSr   r
   r.   r8   r5   r   r   r   r	   <module>   s   

: