
    d{IgY/                        d Z ddlZddlZddlZddlmZ ddlmZ ddlmZmZ  G d de	          Z
 G d	 d
e          Z G d de          Z G d de          Z G d de          Z eeeg          Z	  G d de          ZdS )z
Handles a Minecraft world save using either the Anvil or McRegion format.

For more information about the world format:
https://minecraft.gamepedia.com/Level_format
    N   )region)chunk)InconceivedChunkLocationc                       e Zd ZdZddZdS )UnknownWorldFormatz Unknown or invalid world folder. c                     || _         d S N)msg)selfr   s     K/var/www/CMSBlueprintStation/venv/lib/python3.11/site-packages/nbt/world.py__init__zUnknownWorldFormat.__init__   s        N)r
   )__name__
__module____qualname____doc__r    r   r   r	   r	      s.        **     r   r	   c                       e Zd ZdZdZdZej        Zd Z	d Z
d Zd Zd Zd	 Zd
 ZddZd Zd Zd ZddZd ZddZd Zd Zd Zd ZdS )_BaseWorldFolderz
    Abstract class, representing either a McRegion or Anvil world folder.
    This class will use either Anvil or McRegion, with Anvil the preferred format.
    Simply calling WorldFolder() will do this automatically.
    Genericr
   c                     || _         i | _        i | _        d| _        t	          j        |           |                     |                                            dS )zInitialize a WorldFolder.N)worldfolderregionfilesregionschunksoslistdirset_regionfilesget_filenames)r   world_folders     r   r   z_BaseWorldFolder.__init__   sX    ' 	
<   T//1122222r   c           
          t          t          j        t          j                            | j        dd| j        z                                 S )zFind all matching file names in the world folder.
        
        This method is private, and it's use it deprecated. Use get_regionfiles() instead.r   zr.*.*.)listglobr   pathjoinr   	extensionr   s    r   r"   z_BaseWorldFolder.get_filenames(   s8    
 DIbgll4+;HXdnE\]]^^___r   c                 ,   |D ]}t          j        d| j        z   t          j                            |                    }|rEt          |                    d                    }t          |                    d                    }n	 || j        ||f<   dS )z
        This method directly sets the region files for this instance to use.
        It assumes the filenames are in the form r.<x-digit>.<z-digit>.<extension>
        zr.(\-?\d+).(\-?\d+).r      N)	rematchr)   r   r'   basenameintgroupr   )r   	filenamesfilenamemxzs         r   r!   z _BaseWorldFolder.set_regionfiles/   s    
 " 	/ 	/H0?AQAQRZA[A[\\A 

OO

OO &.DaU##	/ 	/r   c                 N    t          | j                                                  S )z/Return a list of full path of all region files.)r%   r   valuesr*   s    r   get_regionfilesz _BaseWorldFolder.get_regionfilesE   s    D$++--...r   c                 2    t          | j                  dk    S )z&Return True is the world is non-empty.r   )lenr   r*   s    r   nonemptyz_BaseWorldFolder.nonemptyI   s    4#$$q((r   c                 L   ||f| j         vs| j         ||f         j        rw||f| j        v r,t          j        | j        ||f                   | j         ||f<   nt          j                    | j         ||f<   t          ||          | j         ||f         _        | j         ||f         S )z>Get a region using x,z coordinates of a region. Cache results.r5   r6   )r   closedr   r   
RegionFiler   locr   r5   r6   s      r   
get_regionz_BaseWorldFolder.get_regionM   s    a5$$QqS(9(@$!u(((&,&78H!A8O&P&PaU## '-&7&9&9aU#&.Q&7&7&7DL!A#|QqE""r   c              #   p  K   | j                                         D ]\  }}d}||f| j        v r| j        ||f         }n@t          j        | j         ||f         | j                  }t          ||          |_        d}	 |V  |r|                                 ~# |r|                                 w w xY wdS )z
        Return an iterable list of all region files. Use this function if you only
        want to loop through each region files once, and do not want to cache the results.
        F)
chunkclassr>   TN)	r   keysr   r   r@   rE   r   rA   close)r   r5   r6   close_after_use
regionfiles        r   iter_regionsz_BaseWorldFolder.iter_regions\   s       #((** 	' 	'CAa#O!u$$!\1Q%0

 $.t/?1/FUYUdeee
!)A!2!2!2
"&'    " '$$&&& # '$$&&&&'	' 	's   ?BB3Nc                     t                      )a1  
        Return an iterable that calls callback_function for each region file 
        in the world. This is equivalent to:
        ```
        for the_region in iter_regions():
                yield callback_function(the_region)
        ````
        
        This function is threaded. It uses pickle to pass values between threads.
        See [What can be pickled and unpickled?](https://docs.python.org/library/pickle.html#what-can-be-pickled-and-unpickled) in the Python documentation
        for limitation on the output of `callback_function()`.
        NotImplementedErrorr   callback_functionboundingboxs      r   call_for_each_regionz%_BaseWorldFolder.call_for_each_regions        "###r   c                    t          |d          \  }}t          |d          \  }}||f| j        vr!||f| j        vrt          d|d|d          |                     ||                              ||          }|dk    sJ |S )z
        Return a NBT specified by the chunk coordinates x,z. Raise InconceivedChunk
        if the NBT file is not yet generated. To get a Chunk object, use get_chunk.
            zChunk ,z is not present in worldN)divmodr   r   r   rC   get_nbt)r   r5   r6   rxcxrzcznbts           r   rW   z_BaseWorldFolder.get_nbt   s    
 q2q2r7$,&&Br7$:J+J+J""AAAaaa#PQQQoob$$,,R33d{{{{
r   c                     t                      )a  
        Set a chunk. Overrides the NBT if it already existed. If the NBT did not exists,
        adds it to the Regionfile. May create a new Regionfile if that did not exist yet.
        nbt must be a nbt.NBTFile instance, not a Chunk or regular TAG_Compound object.
        rL   )r   r5   r6   r\   s       r   set_nbtz_BaseWorldFolder.set_nbt   s     "###r   c              #   d   K   |                                  D ]} |j                    D ]}|V  dS )z
        Return an iterable list of all NBT. Use this function if you only
        want to loop through the chunks once, and don't need the block or data arrays.
        N)rJ   iter_chunks)r   r   cs      r   iter_nbtz_BaseWorldFolder.iter_nbt   sW       '')) 	 	F'V'))  	 	r   c                     t                      )a)  
        Return an iterable that calls callback_function for each NBT structure 
        in the world. This is equivalent to:
        ```
        for the_nbt in iter_nbt():
                yield callback_function(the_nbt)
        ````
        
        This function is threaded. It uses pickle to pass values between threads.
        See [What can be pickled and unpickled?](https://docs.python.org/library/pickle.html#what-can-be-pickled-and-unpickled) in the Python documentation
        for limitation on the output of `callback_function()`.
        rL   rN   s      r   call_for_each_nbtz"_BaseWorldFolder.call_for_each_nbt   rR   r   c                 T    |                      |                     ||                    S )z
        Return a chunk specified by the chunk coordinates x,z. Raise InconceivedChunk
        if the chunk is not yet generated. To get the raw NBT data, use get_nbt.
        )rE   rW   rB   s      r   	get_chunkz_BaseWorldFolder.get_chunk   s$    
 t||Aq11222r   c                 r    | j         dk    r&t          |                                           | _         | j         S )z
        Return a list of all chunks. Use this function if you access the chunk
        list frequently and want to cache the result.
        Use iter_chunks() if you only want to loop through the chunks once or have a
        very large world.
        N)r   r%   r`   )r   rP   s     r   
get_chunksz_BaseWorldFolder.get_chunks   s4     ;$t//1122DK{r   c              #   f   K   |                                  D ]}|                     |          V  dS )ag  
        Return an iterable list of all chunks. Use this function if you only
        want to loop through the chunks once or have a very large world.
        Use get_chunks() if you access the chunk list frequently and want to cache
        the results. Use iter_nbt() if you are concerned about speed and don't want
        to parse the block data.
        N)rb   rE   )r   ra   s     r   r`   z_BaseWorldFolder.iter_chunks   sD        	% 	%A//!$$$$$$	% 	%r   c                 f    d}|                                  D ]}||                                z  }|S )z2Return a count of the chunks in this world folder.r   )rJ   chunk_count)r   ra   rs      r   rk   z_BaseWorldFolder.chunk_count   s;    ""$$ 	! 	!A AAr   c                    t                      }| j                                        D ]d\  }}|                     ||          }d|z  d|z  }} |j                    D ]/}||d         z   ||d         z   }}|                    |d|           0e|S )zs
        Return minimum and maximum x and z coordinates of the chunks that
        make up this world save
        rT   r5   r6   N)BoundingBoxr   rF   rC   get_chunk_coordsexpand)r   brX   rZ   r   ccr5   r6   s           r   get_boundingboxz _BaseWorldFolder.get_boundingbox   s    
 MM%**,, 	# 	#EBr__R++FrE"R%rB-f-// # #"S'z"RW*!4""""# r   c                 0    | j         j        d| j        dS )N())	__class__r   r   r*   s    r   __repr__z_BaseWorldFolder.__repr__   s!    >22243C3C3CDDr   r   )r   r   r   r   typer)   r   ChunkrE   r   r"   r!   r9   r<   rC   rJ   rQ   rW   r^   rb   rd   rf   rh   r`   rk   rs   rx   r   r   r   r   r      sV        
 DIJ	3 	3 	3` ` `/ / /,/ / /) ) )# # #' ' '.$ $ $ $  $ $ $	 	 	$ $ $ $3 3 3	 	 	 	% % %    E E E E Er   r   c                   (    e Zd ZdZdZdZej        ZdS )McRegionWorldFolderz6Represents a world save using the old McRegion format.McRegionmcrN)	r   r   r   r   ry   r)   r   McRegionChunkrE   r   r   r   r|   r|      s&        @@DI$JJJr   r|   c                   (    e Zd ZdZdZdZej        ZdS )AnvilWorldFolderz3Represents a world save using the new Anvil format.AnvilmcaN)	r   r   r   r   ry   r)   r   
AnvilChunkrE   r   r   r   r   r      s&        ==DI!JJJr   r   c                       e Zd ZdZd Zd ZdS )_WorldFolderFactoryzFactory class: instantiate the subclassses in order, and the first instance 
    whose nonempty() method returns True is returned. If no nonempty() returns True,
    a UnknownWorldFormat exception is raised.c                     || _         d S r   )
subclasses)r   r   s     r   r   z_WorldFolderFactory.__init__   s    $r   c                 t    | j         D ]"} ||i |}|                                r|c S #t          d          )NzEmpty world or unknown format)r   r<   r	   )r   argskwargsclswfs        r   __call__z_WorldFolderFactory.__call__   sT    ? 	 	Cd%f%%B{{}} 			 !@AAAr   N)r   r   r   r   r   r   r   r   r   r   r      sA        1 1% % %B B B B Br   r   c                   8    e Zd ZdZd	dZd Zd Zd Zd Zd Z	dS )
rn   z$A bounding box of x,y,z coordinates.Nc                 `    ||c| _         | _        ||c| _        | _        ||c| _        | _        d S r   minxmaxxminymaxyminzmaxz)r   r   r   r   r   r   r   s          r   r   zBoundingBox.__init__  s6    "D	$)"D	$)"D	$)))r   c                 ^   |dk    r2| j         || j         k     r|| _         | j        || j        k    r|| _        |dk    r2| j        || j        k     r|| _        | j        || j        k    r|| _        |dk    r4| j        || j        k     r|| _        | j        || j        k    r|| _        dS dS dS )z&
        Expands the bounding
        Nr   )r   r5   yr6   s       r   rp   zBoundingBox.expand  s     99y A	MM	y A	MM	99y A	MM	y A	MM	99y A	MM	y A	MM				 9 %2Mr   c                 F    | j         | j        dS | j         | j        z
  dz   S Nr   r   )r   r   r*   s    r   lenxzBoundingBox.lenx&  *    9	 11y"1$$r   c                 F    | j         | j        dS | j         | j        z
  dz   S r   )r   r   r*   s    r   lenyzBoundingBox.leny*  r   r   c                 F    | j         | j        dS | j         | j        z
  dz   S r   )r   r   r*   s    r   lenzzBoundingBox.lenz.  r   r   c                     | j         j        d| j        d| j        d| j        d| j        d| j        d| j        dS )Nru   rU   rv   )rw   r   r   r   r   r   r   r   r*   s    r   rx   zBoundingBox.__repr__2  sK    *..*A*A*A$)))DIII			$)))DIIIdiii9 	9r   )NNNNNN)
r   r   r   r   r   rp   r   r   r   rx   r   r   r   rn   rn     sy        ..) ) ) )  &% % %% % %% % %9 9 9 9 9r   rn   )r   r   r&   r-   r
   r   r   r   r   	Exceptionr	   objectr   r|   r   r   WorldFolderrn   r   r   r   <module>r      s                            . . . . . . . .       TE TE TE TE TEv TE TE TEn% % % % %* % % %" " " " "' " " "B B B B B& B B B "!#35H"IJJ'9 '9 '9 '9 '9& '9 '9 '9 '9 '9r   