
    1jf/                       U d Z ddlmZ ddlZddlZddlmZ ddlmZm	Z	 ddl
mZ ddlmZmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZmZ  ed          Z ee                                          j        d         ZdZdZ da!de"d<   da#de"d<   d#dZ$ G d d          Z% G d de          Z&d$d!Z'e(d"k    r e'             dS dS )%u  多世界平台服务:落地页选世界 + 每世界独立邀请码(隔离)+ cookie 会话 + 离开暂停续播。

运行(部署):
  ~/miniconda3/envs/genesis-world/bin/python -m genesis.server.live_server
为某个世界生成邀请码(一码一会话,绑定该世界):
  ~/miniconda3/envs/genesis-world/bin/python -m genesis.server.live_server gen soldierisland 20

鉴权模型:静态资源公开;凡触发引擎的 /api/* 都要 cookie 里的有效会话,没有就回 401 {need_invite:true}。
邀请码与世界一一绑定:激活某码 → 会话绑到该码的世界 → 该会话之后所有 /api/* 都路由到那个世界的引擎池。
世界之间完全隔离:各自的邀请码、各自的会话、各自的引擎池与存档。
    )annotationsN)SimpleCookie)SimpleHTTPRequestHandlerThreadingHTTPServer)Path)parse_qsurlparse)WorldBuilder)
get_logger)EngineManager)SessionStore)discover_worldsvalidate_worldzserver.live_server   z"/src/genesis/viz/web/platform.htmlz!/src/genesis/viz/web/mystery.htmlz'Platform | None'	_platformzSessionStore | None_storebuilderr
   vizdict | Nonereturndictc                    d  j                                         D             } fd j                                        D             }t	          d  j                                         D             d           }||||dS )Nc                    g | ]C}|j         |j        |j        |j        t	          |d d          |j        r|j        j        nddg dDS )	backstory N)nameagembti
occupationr   
sprite_dir	life_goal	sub_goals)r   r   r   r   getattrartsprite_path.0cms     5/root/genesis-world/src/genesis/server/live_server.py
<listcomp>z_stage.<locals>.<listcomp>&   sj     - - -  r}Rb11,.F<bf((2\^  - - -    c                \    g | ](\  }}||j         |j        g fd |j        D             d)S )c                F    g | ]}|j         v j         |         j        S  )placesr   )r'   ar   s     r)   r*   z%_stage.<locals>.<listcomp>.<listcomp>,   s1    ___q1PWP^K^K^GN1-2K^K^K^r+   )idr   	geographyobjectsadjacent)r   r2   r4   )r'   pidpmr   s      r)   r*   z_stage.<locals>.<listcomp>+   s]     5 5 5#r "'QS____BK___a a 5 5 5r+   c              3  N   K   | ] }d t          |dd          pdv |j        V  !dS )u   凶手roler   N)r#   r   r&   s     r)   	<genexpr>z_stage.<locals>.<genexpr>.   sO       C Cr72vr#:#:#@bAA 7AAAAC Cr+   )r/   
characterskillerr   )r:   valuesr/   itemsnext)r   r   r:   r/   r;   s   `    r)   _stager?   %   s    - - "))++	- - -J
5 5 5 5$^11335 5 5F  C CW%7%>%>%@%@ C C CDHJ JFJ&QTUUUr+   c                  :    e Zd ZdZddZedd            ZddZdS )Platformuo   多世界平台:发现所有合规世界,各自一套 viz/stage/引擎池,共享一个邀请码/会话 store。storer   brainstrratefloatmax_enginesintidle_timeoutr   Nonec                  || _         i | _        t          t          t          dz                      D ]/}t          dz  |z  }t          d t          |          D                       rt                              d|           R|dz  }	|		                                slt          j        |	                    d                    }
t          t          j        t          |                    |
          }t!          ||||
|||||	  	        }|
|||                     ||
|          d| j        |<   t                              d	||
                    d
|                     1d S )Nworldsc              3  @   K   | ]}|                     d           V  dS )z[E]N)
startswith)r'   is     r)   r9   z$Platform.__init__.<locals>.<genexpr><   s.      EE11<<&&EEEEEEr+   u   世界 %s 校验未过,跳过zviz.jsonutf-8)encoding)rG   rI   rC   rE   )r   stagemgrmetau   已装载世界 [%s]:%stitle)rB   rL   r   rD   ROOTanyr   loggerwarningexistsjsonloads	read_textr?   r
   from_directoryr   _metainfoget)selfrB   
shared_llmrC   rE   rG   rI   widwdirvpr   rR   rS   s                r)   __init__zPlatform.__init__6   sj   
')"3th#7#788 	O 	OC(?S(DEEt0D0DEEEEE >DDD
"B99;; *R\\7\;;<<C<6s4yyAA3GGEeZe,7lZ_fjl l lC'*U3PTPZPZ[^`cejPkPkllDKKK138M8MNNNN	O 	Or+   rd   r   r   rR   c                B   |                     d          pg }|                     d          p,|r)|d                              d          r|d         d         nd }|rd|                    d          z   }|                     d          pg }| |                     d          p|                     dd	          |                     d
          pd	|r|d         nd	|t          |                     d          pg           t          |                     d          pg           dS )Nmapscoverr   map/introrU    r   subtitler:   r/   )r1   rU   ro   blurbrj   rosterr/   )ra   lstripreplacelen)rd   r   rR   ri   rj   rm   s         r)   r_   zPlatform._metaI   s   wwv$"  ]t%\QE@R@R%\T!WU^^X\ 	,%,,s+++E  &Bggg&&-#66sB??
++1r!&.U1XXB%))L117R88%))H--344
 
 	
r+   sidc                    | j                             |          }| j                            |          }|r||d         |d         fndS )uK   会话 → (world_id, manager, stage);找不到返回 (None, None, None)。rS   rR   NNN)rB   session_worldrL   ra   )rb   ru   rd   ws       r)   mgr_forzPlatform.mgr_forZ   sJ    j&&s++KOOC  ./GQuXqz**5GGr+   N)rB   r   rC   rD   rE   rF   rG   rH   rI   rF   r   rJ   )rd   rD   r   r   rR   r   r   r   )ru   rD   )__name__
__module____qualname____doc__rg   staticmethodr_   rz   r.   r+   r)   rA   rA   3   sl        yyO O O O& 
 
 
 \
 H H H H H Hr+   rA   c                  `     e Zd Z fdZd Z fdZddZddd
ZddZddZ	 fdZ
d Z xZS )Handlerc                b     t                      j        |dt          t                    i| d S )N	directory)superrg   rD   rV   )rb   r0   k	__class__s      r)   rg   zHandler.__init__b   s0    !6s4yy6A66666r+   c                    d S )Nr.   )rb   r0   s     r)   log_messagezHandler.log_messagee   s    r+   c                t    |                      dd           t                                                       d S )NzCache-Controlz#no-store, no-cache, must-revalidate)send_headerr   end_headers)rb   r   s    r)   r   zHandler.end_headersh   s6    *OPPPr+   r   
str | Nonec                    | j                             d          }|sd S 	 t          |          }d|v r|d         j        nd }n# t          $ r Y d S w xY w|rt
                              |          r|nd S )NCookiegsid)headersra   r   value	Exceptionr   session_exists)rb   rawckru   s       r)   _sidzHandler._sidm   s    lx(( 	4	c""B&,ll"V*""CC 	 	 	44	Dv44S99DssDs   "A 
AA   Nset_sidc                   t          j        |d                              d          }|                     |           |                     dd           |                     dt          t          |                               |r|                     dd| d	           |                                  | j        	                    |           d S )
NF)ensure_asciirP   zContent-Typezapplication/json; charset=utf-8Content-Lengthz
Set-Cookiezgsid=z2; Path=/; Max-Age=31536000; HttpOnly; SameSite=Lax)
r[   dumpsencodesend_responser   rD   rt   r   wfilewrite)rb   objcoder   bodys        r)   _jsonzHandler._jsonx   s    z#E22299'BB4   )JKKK)3s4yy>>::: 	b\`W```b b b
r+   torD   c                    |                      d           |                     d|           |                                  d S )Ni.  Location)r   r   r   )rb   r   s     r)   	_redirectzHandler._redirect   sD    3R(((r+   r   c                    	 t          | j                            dd                    }|r.t          j        | j                            |          pd          ni S # t          $ r i cY S w xY w)Nr   r   z{})rH   r   ra   r[   r\   rfilereadr   )rb   ns     r)   
_body_jsonzHandler._body_json   sx    	DL$$%5q99::A=>F4:djooa008D999BF 	 	 	III	s   AA A+*A+c           
     L   t          | j                  j        }|dk    r+|                     d           |                                  d S |dv r|                     t
                     d S |dk    r?|                     dd t          j        	                                D             i           d S |dk    rL| 
                                }|                     |d u|rt                              |          nd d           d S |d	k    r| 
                                }||                     d
did           d S t                              |          \  }}}||                     d
did           d S |                    |          }||                     d||d           d S |j        |j                                        nd }|j        5  |                     |||j        d         |j        d         |j        d         |d           d d d            n# 1 swxY w Y   d S |dk    r| 
                                }|rt                              |          nd\  }}}||                     d
did           d S t'          t          | j                  j                  }	|                     |                    |          j                            |	                    ddg          d                              d S t1                                                       d S )Nz/favicon.ico   )rl   z/index.htmlz/api/worldsrL   c                    g | ]
}|d          S )rT   r.   )r'   ry   s     r)   r*   z"Handler.do_GET.<locals>.<listcomp>   s    "P"P"P1V9"P"P"Pr+   z	/api/auth)authedworldz
/api/stateneed_inviteT  r   )	suspendedrR   r   framerunningstep)rR   r   r   r   r   costz
/api/agentrw   r   r   r   )r	   pathr   r   r   LANDINGr   r   rL   r<   r   r   rx   rz   ra   llmstatslockstater   queryensureengineagent_detailr   do_GET)rb   r   ru   rd   rS   rR   lsr   _qr   s             r)   r   zHandler.do_GET   se   	""'>!!s###T%5%5%7%7%7'''NN7###VV=  JJ"P"Pi6F6M6M6O6O"P"P"PQRRRF;))++CJJ#T/Y\<fF<P<PQT<U<U<UbfgghhhF<))++C{

M40s
;;;VV'//44OCe{

M40s
;;;VVBz

LLMMMvv%'V%726<<>>>TD e e

US28GCT')x	':BHVDT^bd d e e ee e e e e e e e e e e e e e e F<))++C47O)++C000=OKCa{

M40s
;;;VV$),,233AJJszz#-::155";N;Nq;QRRSSSFs   >HH"Hc           
     	   t          | j                  }t          |j                  }|j        dk    r|                                                     d          p|                    ddg          d         }t                              |          }||                     dddd	           nw|\  }}t          j
                            |          }||                     dd
dd	           d S |d                             |           |                     d|d|           d S |                                 }|rt                              |          nd\  }}	}
|	|                     ddid	           d S |j        dk    r.|	                    |           |                     ddi           d S |j        dk    r.|	                    |           |                     ddi           d S |j        dk    r.|	                    |           |                     ddi           d S |	                    |          }|j        }|j        dk    r#d|j        d<   |                     ddi           d S |j        dk    r#d|j        d<   |                     ddi           d S |j        dk    rXt%          |                    ddg          d                   }|                    |           |                     d|i           d S |j        dk    r9d|_        |j                                         |                     ddi           d S |j        dk    rd|                     d|                    |                    d dg          d         |                    d!dg          d                   d"           d S |j        d#k    rI|                    |                    d$d%g          d                    |                     ddi           d S |j        d&k    rI|                    |                    d'dg          d                    |                     ddi           d S |j        d(k    rc|                     d|                    |                    d)dg          d         |                    d'dg          d                   i           d S |                     d*           d S )+Nz/api/activater   r   r   Fu   邀请码无效或已被使用)okerrori  r   u$   该邀请码所属世界暂不可用i  rS   T)r   r   )r   rw   r   r   z/api/heartbeatr   z/api/suspendz/api/resume_sessionz
/api/pauser   z/api/resumez	/api/ratex30rE   z/api/restartz
/api/eventdescplace)r   reachedz/api/weatherry   u   暴雨z	/api/goaltextz/api/whisperr   i  )r	   r   r   r   r   ra   r   activate_inviter   r   rL   r   r   rz   	heartbeatsuspendr   r   rF   set_base_rate_restartschedstopinject_eventset_weatherset_world_goalwhisper
send_error)rb   pr   r   resru   r   ry   rd   rS   r   r   engrs                 r)   do_POSTzHandler.do_POST   s   TYQW6_$$OO%%))&11KQUU6B45H5H5KD((..C{

%2RSSZ]
^^^^ 
U$((//9JJe6\]]dgJhhhjpjp%$$$

$77
EEEFiikk03Ki'',,,9KS!;JJt,3J7776%%%MM#

D$< 8 8 8&&6^##KKdjj$6666***JJsOOOTZZt555vvZZ__i6\!!"'BHYY4F)G)G)G)G)GV}$$"&BHY

It3D(E(E(E(E(EV{""aeeC$((+,,Ac.?.?.B.B.BDJJPVXY{D[D[D[D[D[V~%%BK	 0 0 0$**dD\2J2J2J2J2JV|##JJds/?/?frd@S@STU@VXYX]X]^ehjgkXlXlmnXo/p/pqqrrrrrV~%%OOAEE#z2215666

D$<8P8P8P8P8PV{""quuVbT2215666

D$<8P8P8P8P8PV~%%JJckk!%%*=*=a*@!%%QSPTBUBUVWBXYYZ[[[[[OOC     r+   )r   r   )r   N)r   r   )r   rD   )r   r   )r{   r|   r}   rg   r   r   r   r   r   r   r   r   __classcell__)r   s   @r)   r   r   a   s        7 7 7 7 7      
	E 	E 	E 	E	 	 	 	 	   
   $ $ $ $ $N-! -! -! -! -! -! -!r+   r   rJ   c                 R   dd l } t          j                            dt	          t
          dz  dz                      }t          |          at          | j	                  dk    r
| j	        d         dk    rt          | j	                  dk     rIt          d	d
                    t          t	          t
          dz                                z              d S | j	        d         }t          | j	                  dk    rt          | j	        d                   nd}t                              ||          }t          d                    |                     t          d| d| d|            d S d }t          j                            dd          dk    rddlm}  |            }t#          t          |t          j                            dd          t%          t          j                            dd                    t          t          j                            dd                    t%          t          j                            dd                              at&          j        st          d           d S t          j                            dd          }t          t          j                            dd                    }t          d | d!| d"d
                    t&          j                   d#           t+          ||ft,                                                     d S )$Nr   
GENESIS_DBrL   zplatform_sessions.db      genr   u'   用法:gen <world_id> [n]
可用世界:u   、
   
u   
✅ 为世界 [u	   ] 生成 u    个邀请码 → GENESIS_BRAINr   stub)LiteLLMClientGENESIS_RATEr   GENESIS_MAX_ENGINES8GENESIS_IDLE_TIMEOUT90)rC   rE   rG   rI   uA   ⚠️ 没有发现可玩世界(worlds/ 下需有合规世界包)GENESIS_HOSTz0.0.0.0GENESIS_PORT8000u&   🌐 多世界平台启动 → http://:u   /  (世界:))sysosenvironra   rD   rV   r   r   rt   argvprintjoinr   rH   gen_invitesgenesis.llm.clientr   rA   rF   r   rL   r   r   serve_forever)	r   dbr   r   codesrc   r   hostports	            r)   mainr     s   JJJ	c$/<R*R&S&S	T	TB"F
38}}chqkU22sx==1<uzz/Z]^bem^mZnZnJoJo?p?ppqqqF #CH 1 1Cr""1e,,diiK%KK!KKrKKLLLJ	z~~ou--77444444"]__

jnn_e442:>>.$7788
'<cBBCC2:>>*@$GGHHJ J JI  [QRRRTZTZ:>>.)44Drz~~nf5566D	
j4
j
j$
j
j5::V_VfKgKg
j
j
jkkktg..<<>>>>>r+   __main__)r   r
   r   r   r   r   )r   rJ   ))r~   
__future__r   r[   r   http.cookiesr   http.serverr   r   pathlibr   urllib.parser   r	   genesis.manifest.builderr
   genesis.obs.logging_setupr   genesis.server.engine_poolr   genesis.server.storer   genesis.world.packr   r   rX   __file__resolveparentsrV   r   GAMEr   __annotations__r   r?   rA   r   r  r{   r.   r+   r)   <module>r     s  
 
 
 # " " " " "  				 % % % % % % E E E E E E E E       + + + + + + + + 1 1 1 1 1 1 0 0 0 0 0 0 4 4 4 4 4 4 - - - - - - > > > > > > > >	(	)	)tH~~'*
.*#	 # # # #" " " " "V V V V+H +H +H +H +H +H +H +H\C! C! C! C! C!& C! C! C!L!? !? !? !?H zDFFFFF r+   